From 9680ab74a3d0d09dad738c6085104b9f4f634a82 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Thu, 27 Sep 2018 18:42:34 +0100 Subject: [PATCH] All: Allow loading image resources in IMG html tags --- README.md | 4 +- ReactNativeClient/lib/MdToHtml.js | 71 +++++++++++++++++++++---------- docs/faq/index.html | 16 ++++++- docs/index.html | 5 ++- readme/faq.md | 37 ++++++++++++---- 5 files changed, 99 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index c607c85ce..0c7ef164b 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,9 @@ The checkboxes can then be ticked in the mobile and desktop applications. ## HTML support -Only the `
` tag is supported - it can be used to force a new line, which is convenient to insert new lines inside table cells. For security reasons, other HTML tags are not supported. +It is generally recommended to enter the notes as Markdown as it makes the notes easier to edit. However for cases where certain features aren't supported (such as strikethrough or to highlight text), you can also use HTML code directly. For example this would be a valid note: + + This is strikethrough text mixed with regular **Markdown**. # Donations diff --git a/ReactNativeClient/lib/MdToHtml.js b/ReactNativeClient/lib/MdToHtml.js index 7f2f937c4..d7c0f8fb0 100644 --- a/ReactNativeClient/lib/MdToHtml.js +++ b/ReactNativeClient/lib/MdToHtml.js @@ -73,31 +73,31 @@ class MdToHtml { return attrs; } - renderImage_(attrs, options) { - const loadResource = async (id) => { - // console.info('Loading resource: ' + id); + async loadResource(id, options) { + // console.info('Loading resource: ' + id); - // Initially set to to an empty object to make - // it clear that it is being loaded. Otherwise - // it sometimes results in multiple calls to - // loadResource() for the same resource. - this.loadedResources_[id] = {}; + // Initially set to to an empty object to make + // it clear that it is being loaded. Otherwise + // it sometimes results in multiple calls to + // loadResource() for the same resource. + this.loadedResources_[id] = {}; - const resource = await Resource.load(id); - //const resource = await this.modelCache_.load(Resource, id); + const resource = await Resource.load(id); + //const resource = await this.modelCache_.load(Resource, id); - if (!resource) { - // Can happen for example if an image is attached to a note, but the resource hasn't - // been downloaded from the sync target yet. - console.warn('Cannot load resource: ' + id); - return; - } - - this.loadedResources_[id] = resource; - - if (options.onResourceLoaded) options.onResourceLoaded(); + if (!resource) { + // Can happen for example if an image is attached to a note, but the resource hasn't + // been downloaded from the sync target yet. + console.warn('Cannot load resource: ' + id); + return; } + this.loadedResources_[id] = resource; + + if (options.onResourceLoaded) options.onResourceLoaded(); + } + + renderImage_(attrs, options) { const title = this.getAttr_(attrs, 'title'); const href = this.getAttr_(attrs, 'src'); @@ -108,7 +108,7 @@ class MdToHtml { const resourceId = Resource.urlToId(href); const resource = this.loadedResources_[resourceId]; if (!resource) { - loadResource(resourceId); + this.loadResource(resourceId, options); return ''; } @@ -125,6 +125,27 @@ class MdToHtml { return '[Image: ' + htmlentities(resource.title) + ' (' + htmlentities(mime) + ')]'; } + renderImageHtml_(before, src, after, options) { + const resourceId = Resource.urlToId(src); + const resource = this.loadedResources_[resourceId]; + if (!resource) { + this.loadResource(resourceId, options); + return ''; + } + + if (!resource.id) return ''; // Resource is being loaded + + const mime = resource.mime ? resource.mime.toLowerCase() : ''; + if (Resource.isSupportedImageMimeType(mime)) { + let newSrc = './' + Resource.filename(resource); + if (this.resourceBaseUrl_ !== null) newSrc = this.resourceBaseUrl_ + newSrc; + let output = ''; + return output; + } + + return '[Image: ' + htmlentities(resource.title) + ' (' + htmlentities(mime) + ')]'; + } + renderOpenLink_(attrs, options) { let href = this.getAttr_(attrs, 'href'); const text = this.getAttr_(attrs, 'text'); @@ -472,6 +493,12 @@ class MdToHtml { } } + renderedBody = renderedBody.replace(//g, (v, before, src, after) => { + if (!Resource.isResourceUrl(src)) return ''; + return this.renderImageHtml_(before, src, after, options); + }); + + // https://necolas.github.io/normalize.css/ const normalizeCss = ` html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} @@ -561,7 +588,7 @@ class MdToHtml { border-bottom: 1px solid ` + style.htmlDividerColor + `; } img { - width: auto; + /* width: auto; */ max-width: 100%; } .inline-code { diff --git a/docs/faq/index.html b/docs/faq/index.html index 4fd01b19c..56bce1c06 100644 --- a/docs/faq/index.html +++ b/docs/faq/index.html @@ -260,7 +260,7 @@
  • On your WebDAV service, copy all the Joplin files from the old location to the new one. Make sure to also copy the .resource directory as it contains your images and other attachments.
  • Once it's done, open Joplin again and change the WebDAV URL.
  • Synchronise to verify that everything is working.
  • -
  • Do step 4 and 5 for all the other Joplin clients you need to sync.
  • +
  • Do step 5 and 6 for all the other Joplin clients you need to sync.
  • How can I easily enter Markdown tags in Android?

    You may use a special keyboard such as Multiling O Keyboard, which has shortcuts to create Markdown tags. More information in this post.

    @@ -270,6 +270,20 @@

    Short answer: no. The end to end encryption that Joplin implements is to protect the data during transmission and on the cloud service so that only you can access it.

    On the local device it is assumed that the data is safe due to the OS built-in security features. If additional security is needed it's always possible to put the notes on an encrypted Truecrypt drive for instance.

    If someone that you don't trust has access to the computer, they can put a keylogger anyway so any local encryption or PIN access would not be useful.

    +

    WebDAV synchronisation is not working

    +

    "Forbidden" error in Strato

    +

    For example:

    +
    MKCOL .sync/: Unknown error 2 (403): <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    +<html><head>
    +<title>403 Forbidden</title>
    +</head><body>
    +<h1>Forbidden</h1>
    +<p>You don't have permission to access /.sync/
    +on this server.</p>
    +</body></html>
    +

    In this case, make sure you enter the correct WebDAV URL.

    +

    Nginx sync not working

    +

    As of now, Joplin is not compatible with the Nginx WebDAV server: https://github.com/laurent22/joplin/issues/808

    Why is it named Joplin?

    The name comes from the composer and pianist Scott Joplin, which I often listen to. His name is also easy to remember and type so it fell like a good choice. And, to quote a user on Hacker News, "though Scott Joplin's ragtime musical style has a lot in common with some very informal music, his own approach was more educated, sophisticated, and precise. Every note was in its place for a reason, and he was known to prefer his pieces to be performed exactly as written. So you could say that compared to the people who came before him, his notes were more organized".

    diff --git a/docs/index.html b/docs/index.html index 009a44934..6aba054cc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -469,8 +469,9 @@ $$ - [ ] Eggs

    The checkboxes can then be ticked in the mobile and desktop applications.

    HTML support

    -

    Only the <br> tag is supported - it can be used to force a new line, which is convenient to insert new lines inside table cells. For security reasons, other HTML tags are not supported.

    -

    Donations

    +

    It is generally recommended to enter the notes as Markdown as it makes the notes easier to edit. However for cases where certain features aren't supported (such as strikethrough or to highlight text), you can also use HTML code directly. For example this would be a valid note:

    +
    This is <s>strikethrough text</s> mixed with regular **Markdown**.
    +

    Donations

    Donations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.

    Please see the donation page for information on how to support the development of Joplin.

    Community

    diff --git a/readme/faq.md b/readme/faq.md index 82d62ec5f..e0fd9a878 100644 --- a/readme/faq.md +++ b/readme/faq.md @@ -6,13 +6,13 @@ It seems to be due to the setting `set term=ansi` in .vimrc. Removing it should When changing the WebDAV URL, make sure that the new location has the same exact content as the old location (i.e. copy all the Joplin data over to the new location). Otherwise, if there's nothing on the new location, Joplin is going to think that you have deleted all your data and will proceed to delete it locally too. So to change the WebDAV URL, please follow these steps: -0. Make a backup of your Joplin data in case something goes wrong. Export to a JEX archive for example. -1. Synchronise one last time all your data from a Joplin client (for example, from the desktop client) -2. Close the Joplin client. -3. On your WebDAV service, copy all the Joplin files from the old location to the new one. Make sure to also copy the `.resource` directory as it contains your images and other attachments. -4. Once it's done, open Joplin again and change the WebDAV URL. -5. Synchronise to verify that everything is working. -6. Do step 4 and 5 for all the other Joplin clients you need to sync. +1. Make a backup of your Joplin data in case something goes wrong. Export to a JEX archive for example. +2. Synchronise one last time all your data from a Joplin client (for example, from the desktop client) +3. Close the Joplin client. +4. On your WebDAV service, copy all the Joplin files from the old location to the new one. Make sure to also copy the `.resource` directory as it contains your images and other attachments. +5. Once it's done, open Joplin again and change the WebDAV URL. +6. Synchronise to verify that everything is working. +7. Do step 5 and 6 for all the other Joplin clients you need to sync. # How can I easily enter Markdown tags in Android? @@ -30,6 +30,27 @@ On the local device it is assumed that the data is safe due to the OS built-in s If someone that you don't trust has access to the computer, they can put a keylogger anyway so any local encryption or PIN access would not be useful. +# WebDAV synchronisation is not working + +## "Forbidden" error in Strato + +For example: + + MKCOL .sync/: Unknown error 2 (403): + + 403 Forbidden + +

    Forbidden

    +

    You don't have permission to access /.sync/ + on this server.

    + + +In this case, [make sure you enter the correct WebDAV URL](https://github.com/laurent22/joplin/issues/309). + +## Nginx sync not working + +As of now, Joplin is not compatible with the Nginx WebDAV server: https://github.com/laurent22/joplin/issues/808 + # Why is it named Joplin? -The name comes from the composer and pianist [Scott Joplin](https://en.wikipedia.org/wiki/Scott_Joplin), which I often listen to. His name is also easy to remember and type so it fell like a good choice. And, to quote a user on Hacker News, "though Scott Joplin's ragtime musical style has a lot in common with some very informal music, his own approach was more educated, sophisticated, and precise. Every note was in its place for a reason, and he was known to prefer his pieces to be performed exactly as written. So you could say that compared to the people who came before him, his notes were more organized". +The name comes from the composer and pianist [Scott Joplin](https://en.wikipedia.org/wiki/Scott_Joplin), which I often listen to. His name is also easy to remember and type so it fell like a good choice. And, to quote a user on Hacker News, "though Scott Joplin's ragtime musical style has a lot in common with some very informal music, his own approach was more educated, sophisticated, and precise. Every note was in its place for a reason, and he was known to prefer his pieces to be performed exactly as written. So you could say that compared to the people who came before him, his notes were more organized". \ No newline at end of file