From f131c378934a86b741ab5b808437c95694dc5503 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Wed, 11 Jun 2014 23:04:58 +0100 Subject: [PATCH 1/3] Update HTML parser to use an IFRAME Gives us better sandboxing of unsafe HTML content --- core/modules/parsers/htmlparser.js | 13 +++++++++++-- themes/tiddlywiki/vanilla/base.tid | 9 +++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/modules/parsers/htmlparser.js b/core/modules/parsers/htmlparser.js index 7045c7f44..a42a22753 100644 --- a/core/modules/parsers/htmlparser.js +++ b/core/modules/parsers/htmlparser.js @@ -13,9 +13,18 @@ The HTML parser displays text as raw HTML "use strict"; var HtmlParser = function(type,text,options) { + var src; + if(options._canonical_uri) { + src = options._canonical_uri; + } else if(text) { + src = "data:text/html," + encodeURIComponent(text); + } this.tree = [{ - type: "raw", - html: text + type: "element", + tag: "iframe", + attributes: { + src: {type: "string", value: src} + } }]; }; diff --git a/themes/tiddlywiki/vanilla/base.tid b/themes/tiddlywiki/vanilla/base.tid index 632081fa9..da0b4af79 100644 --- a/themes/tiddlywiki/vanilla/base.tid +++ b/themes/tiddlywiki/vanilla/base.tid @@ -117,11 +117,16 @@ table tfoot tr td { white-space: nowrap; } -.tw-tiddler-frame img, .tw-tiddler-frame svg, .tw-tiddler-frame canvas, .tw-tiddler-frame embed { +.tw-tiddler-frame img, +.tw-tiddler-frame svg, +.tw-tiddler-frame canvas, +.tw-tiddler-frame embed, +.tw-tiddler-frame iframe { max-width: 100%; } -.tw-tiddler-frame embed { +.tw-tiddler-frame embed, +.tw-tiddler-frame iframe { width: 100%; height: 600px; } From 9547a1f01c144c604c294f394a68d7dc6dbe4e5d Mon Sep 17 00:00:00 2001 From: Jermolene Date: Thu, 12 Jun 2014 08:36:30 +0100 Subject: [PATCH 2/3] First pass at external image support A bunch of little changes that together enable external image support. Try: ``` tiddlywiki editions/tw5.com --verbose --build externalimages ``` Then open `externalimages.html`, look for the images in the more/types tab of the sidebar, open them and verify that they are set with an external SRC attribute, not a data URI. --- core/language/en-GB/EditTemplate.multids | 1 + core/modules/parsers/imageparser.js | 7 +- core/modules/widgets/image.js | 43 ++++++++---- core/modules/wiki.js | 9 ++- core/ui/EditTemplate/body.tid | 24 ++++++- .../tiddlers/concepts/ExternalImages.tid | 68 +++++++++++++++++++ .../tw5.com/tiddlers/widgets/ImageWidget.tid | 10 ++- editions/tw5.com/tiddlywiki.info | 5 ++ 8 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 editions/tw5.com/tiddlers/concepts/ExternalImages.tid diff --git a/core/language/en-GB/EditTemplate.multids b/core/language/en-GB/EditTemplate.multids index e5625c351..e703907c6 100644 --- a/core/language/en-GB/EditTemplate.multids +++ b/core/language/en-GB/EditTemplate.multids @@ -1,5 +1,6 @@ title: $:/language/EditTemplate/ +Body/External/Hint: This is an external tiddler stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself Body/Hint: Use [[wiki text|http://tiddlywiki.com/static/WikiText.html]] to add formatting, images, and dynamic features Body/Placeholder: Type the text for this tiddler Body/Preview/Button/Hide: hide preview diff --git a/core/modules/parsers/imageparser.js b/core/modules/parsers/imageparser.js index db532f11f..709c50ad9 100644 --- a/core/modules/parsers/imageparser.js +++ b/core/modules/parsers/imageparser.js @@ -19,7 +19,12 @@ var ImageParser = function(type,text,options) { attributes: {} }, src; - if(text) { + if(options._canonical_uri) { + element.attributes.src = {type: "string", value: options._canonical_uri}; + if(type === "application/pdf" || type === ".pdf") { + element.tag = "embed"; + } + } else if(text) { if(type === "application/pdf" || type === ".pdf") { element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text}; element.tag = "embed"; diff --git a/core/modules/widgets/image.js b/core/modules/widgets/image.js index 1ab024ef6..be2ea8b6f 100644 --- a/core/modules/widgets/image.js +++ b/core/modules/widgets/image.js @@ -56,20 +56,37 @@ ImageWidget.prototype.render = function(parent,nextSibling) { } else { // Check if it is an image tiddler if(this.wiki.isImageTiddler(this.imageSource)) { - // Render the appropriate element for the image type var type = tiddler.fields.type, - text = tiddler.fields.text; - switch(type) { - case "application/pdf": - tag = "embed"; - src = "data:application/pdf;base64," + text; - break; - case "image/svg+xml": - src = "data:image/svg+xml," + encodeURIComponent(text); - break; - default: - src = "data:" + type + ";base64," + text; - break; + text = tiddler.fields.text, + _canonical_uri = tiddler.fields._canonical_uri; + // If the tiddler has body text then it doesn't need to be lazily loaded + if(text) { + // Render the appropriate element for the image type + switch(type) { + case "application/pdf": + tag = "embed"; + src = "data:application/pdf;base64," + text; + break; + case "image/svg+xml": + src = "data:image/svg+xml," + encodeURIComponent(text); + break; + default: + src = "data:" + type + ";base64," + text; + break; + } + } else if(_canonical_uri) { + switch(type) { + case "application/pdf": + tag = "embed"; + src = _canonical_uri; + break; + case "image/svg+xml": + src = _canonical_uri; + break; + default: + src = _canonical_uri; + break; + } } } } diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 0bae67fca..8d142d8d0 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -711,6 +711,7 @@ Parse a block of text of a specified MIME type options: see below Options include: parseAsInline: if true, the text of the tiddler will be parsed as an inline run + _canonical_uri: optional string of the canonical URI of this content */ exports.old_parseText = function(type,text,options) { options = options || {}; @@ -728,7 +729,8 @@ exports.old_parseText = function(type,text,options) { // Return the parser instance return new Parser(type,text,{ parseAsInline: options.parseAsInline, - wiki: this + wiki: this, + _canonical_uri: options._canonical_uri }); }; @@ -736,11 +738,14 @@ exports.old_parseText = function(type,text,options) { Parse a tiddler according to its MIME type */ exports.old_parseTiddler = function(title,options) { - options = options || {}; + options = $tw.utils.extend({},options); var cacheType = options.parseAsInline ? "newInlineParseTree" : "newBlockParseTree", tiddler = this.getTiddler(title), self = this; return tiddler ? this.getCacheForTiddler(title,cacheType,function() { + if(tiddler.hasField("_canonical_uri")) { + options._canonical_uri = tiddler.fields._canonical_uri; + } return self.old_parseText(tiddler.fields.type,tiddler.fields.text,options); }) : null; }; diff --git a/core/ui/EditTemplate/body.tid b/core/ui/EditTemplate/body.tid index a5092e920..0c58fc600 100644 --- a/core/ui/EditTemplate/body.tid +++ b/core/ui/EditTemplate/body.tid @@ -1,10 +1,26 @@ title: $:/core/ui/EditTemplate/body tags: $:/tags/EditTemplate -\define lingo-base() $:/language/EditTemplate/ +\define lingo-base() $:/language/EditTemplate/Body/ +<$list filter="[is[current]has[_canonical_uri]]"> + +
+ +<> + +<$text text={{!!_canonical_uri}}/> + +<$edit-text field="_canonical_uri" class="tw-edit-fields"> + +
+ + + +<$list filter="[is[current]!has[_canonical_uri]]"> + <$reveal state="$:/state/showeditpreview" type="match" text="yes"> -<> <$button type="set" set="$:/state/showeditpreview" setTo="no"><> +<> <$button type="set" set="$:/state/showeditpreview" setTo="no"><>
@@ -24,7 +40,9 @@ tags: $:/tags/EditTemplate <$reveal state="$:/state/showeditpreview" type="nomatch" text="yes"> -<> <$button type="set" set="$:/state/showeditpreview" setTo="yes"><> +<> <$button type="set" set="$:/state/showeditpreview" setTo="yes"><> <$edit field="text" class="tw-edit-texteditor" placeholder={{$:/language/EditTemplate/Body/Placeholder}}/> + + diff --git a/editions/tw5.com/tiddlers/concepts/ExternalImages.tid b/editions/tw5.com/tiddlers/concepts/ExternalImages.tid new file mode 100644 index 000000000..87a952974 --- /dev/null +++ b/editions/tw5.com/tiddlers/concepts/ExternalImages.tid @@ -0,0 +1,68 @@ +created: 20140610213500000 +modified: 20140610213936575 +tags: concepts +title: ExternalImages +type: text/vnd.tiddlywiki + +External images in TiddlyWiki are tiddlers that point to the URI of an image, rather than embedding the full image data. They can perform better than embedded images, particularly with large numbers or sizes of images. However, using them breaks the single file pattern of TiddlyWiki. + +External images are used in the browser. They can be created by the Node.js configuration when it builds a TiddlyWiki, or they can be created manually within the browser. + +! What is an External Image + +An external image is an ordinary image tiddler that has a ''_canonical_uri'' field containing the URI of the image. The URI can be absoluate or relative to the HTML document. If the canonical URI is provided then the ''text'' field of the tiddler is ignored and so should be omitted. + +! Manually Creating External Images + +To manually create an external image just create the tiddler with the appropriate image content type, and add a ''_canonical_uri'' field with a URI pointing to the actual image location. + +! Creating external images under Node.js + +The following steps are used to create a static HTML file version of a wiki accompanied by an ''images'' folder containing the referenced external images: + +# Create image tiddlers in your TiddlyWikiFolders in the usual way +# Save the images as separate files (by convention, in a subfolder named ''images'') +# Externalise the image tiddlers by giving them a ''_canonical_uri'' field +# Save the main HTML file + +Note the image files must be saved before they are externalised. Externalising them destroys the ''text'' field within the in-memory copy of the wiki store, meaning that attempts to save them will fail. + +For an example see the ''externalimages'' build target of the demo ''tw5.com'' wiki: + +``` +--savetiddlers [is[image]] images +--setfield [is[image]] _canonical_uri $:/core/templates/canonical-uri text/plain +--setfield [is[image]] text "" text/plain +--rendertiddler $:/core/save/all externalimages.html text/plain +``` + +!! Saving Separate Image Files + +The following `--savetiddlers` command can be used to save the images of a wiki into an ''images'' subfolder: + +``` +--savetiddlers [is[image]] images +``` + +!! Externalising Image Tiddlers + +Two `--setfield` commands are used: the first sets the ''_canonical_uri'' field to a URI derived from the title of the tiddler, and the second clears the text field. + +``` +--setfield [is[image]] _canonical_uri $:/core/templates/canonical-uri text/plain +--setfield [is[image]] text "" text/plain +``` + +The template tiddler [[$:/core/templates/canonical-uri]] contains: + +
+
+<$view tiddler="$:/core/templates/canonical-uri" field="text" format="text"/>
+
+
+ +Note that these operations modify the tiddlers in the wiki store and so may affect the operation of subsequent commands. + +! Using External Images + +You can't edit an external image directly in the browser except by changing the URI field to point to a different image. diff --git a/editions/tw5.com/tiddlers/widgets/ImageWidget.tid b/editions/tw5.com/tiddlers/widgets/ImageWidget.tid index f616ea97d..6f1e1a694 100644 --- a/editions/tw5.com/tiddlers/widgets/ImageWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ImageWidget.tid @@ -1,6 +1,6 @@ title: ImageWidget created: 20140416160234142 -modified: 20140416160234142 +modified: 20140611160234142 tags: widget ! Introduction @@ -18,3 +18,11 @@ Any content of the `<$image>` widget is ignored. |tooltip |The tooltip to be displayed over the image | |class |CSS classes to be assigned to the `` element | +! External Images and the ''_canonical_uri'' field + +When used to display tiddler-based images, the image widget operates in two distinct modes: + +* If the ''_canonical_uri'' field is present then it is used as the ''src'' attribute of the generated `` element and the ''text'' field is ignored +* Without the ''_canonical_uri'' field, the image widget generates an `` element that embeds the image data directly using a `data:` URI. + +See ExternalImages for more details. diff --git a/editions/tw5.com/tiddlywiki.info b/editions/tw5.com/tiddlywiki.info index 14ef45476..8cd612e84 100644 --- a/editions/tw5.com/tiddlywiki.info +++ b/editions/tw5.com/tiddlywiki.info @@ -30,6 +30,11 @@ "build": { "index": [ "--rendertiddler","$:/core/save/all","index.html","text/plain"], + "externalimages": [ + "--savetiddlers","[is[image]] [type[text/html]]","images", + "--setfield","[is[image]] [type[text/html]]","_canonical_uri","$:/core/templates/canonical-uri","text/plain", + "--setfield","[is[image]]","text","","text/plain", + "--rendertiddler","$:/core/save/all","externalimages.html","text/plain"], "encrypted": [ "--password", "password", "--rendertiddler", "$:/core/save/all", "encrypted.html", "text/plain", From 0e09fbf46a7a56d467c0fffb2b9060a07b1c6433 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Thu, 12 Jun 2014 08:36:53 +0100 Subject: [PATCH 3/3] Start using the build command in batch files --- qbld.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qbld.sh b/qbld.sh index cd6c96000..a7a2d2534 100755 --- a/qbld.sh +++ b/qbld.sh @@ -26,6 +26,5 @@ node ./tiddlywiki.js \ ./editions/tw5.com \ --verbose \ --output $TW5_BUILD_OUTPUT \ - --rendertiddler $:/core/save/all index.html text/plain \ - --savetiddler $:/favicon.ico favicon.ico \ + --build index favicon \ || exit 1