When the button is clicked, the /preview endpoint is used to render a
preview text. The preview is inserted and the preview button is
replaced by an edit button to go back to edit mode. Alternatively, the
use can click on the preview to edit.
Some small CSS modifications are done to accomodate the
modification. Also, the preview is wrapped into `.isso-common
.text-wrapper .text` to not make the CSS more complex.
When in preview mode, the background is stripped/greyish in case it's not easy
to make a difference between preview and not preview (due to
unformatted text). We avoid to modify borders/shadow boxes because it
would make the design "jumpy".
On server-side, this can be enabled by providing a base URL to use to
build the full URL. Limit also becomes configurable. On client-side,
we need to add a switch to know whatever or not the additional link
can be displayed.
"nofollow" is a deterrent for spammers: they cannot put links and hope
to increase their SEO when all these links have the nofollow
relationship.
"noopener" is a security for links opening a new window. They ensure
the target cannot control us.
Fix#373
Use of eval is handy when we need to automatically reload a
template. However, in production, this is slow and unsafe. Moreover,
when using CSP, we have to use 'unsafe-eval' which brings shame to
most of us. It appears use of eval() is not needed because the
template has already been translated to Javascript. We just need to
bind "jade" to its local scope.
So, we add an additional wrapper function binding "jade" to the local
scope. Moreover, when compiling the template, we add a flag to the
function to know it has already been compiled. In this case, we
execute it with "jade" in its scope. Otherwise, we keep using eval.
Quickly tested in both situations. Seem to work.
Fix#274.
Hex-digits with character count above 17 cannot be safely converted to an Integer, see [MAX_SAFE_INTEGER](https://medium.com/the-node-js-collection/javascripts-number-type-8d59199db1b6#53cd).
Therefore, when long keys (e.g. 32 characters) are passed into `generateIdenticon()`, and the modulus of 2^18 is performed, the result is 0 all the time. This means, the identicon will render as an empty svg image.
Here is a proof-of-concept (run in any modern browser):
```js
const key = '841b625dcf75413ff3ed5137a81ff1c3';
const int = parseInt(key, 16);
const hash = int % Math.pow(2, 18);
// throws, due to floating point conversion / integer overflow
console.assert(258499 === hash, "Modulus for 'hash' should be != 0");
const int2 = parseInt(key.substr(-16), 16);
const hash2 = int2 % Math.pow(2, 18);
// works as expected
console.assert(258048 === hash2, "Modulus 'hash2' should be != 0");
```
Truncating the passed in argument to a maximum of 16 characters solves the issue.
As a sidenote, the same code in Python will work correctly:
```python
key = '841b625dcf75413ff3ed5137a81ff1c3'
int = int(key, 16)
hash = int % pow(2, 18)
assert 258499 == hash
```