From 6ccf02ed9678b9c485dd67683aa4fc15dc21d412 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Sat, 3 May 2014 12:20:28 +0100 Subject: [PATCH] Add support for onhashchange MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now we respond dynamically to changes in the location hash in the URL bar. It means that you can do links in HTML as `go` and in Markdown as `[example link](#HelloThere).` We still need to make startup.js more modular --- core/modules/startup.js | 91 ++++++++++++------- editions/markdowndemo/tiddlers/HelloThere.tid | 7 +- .../tw5.com/tiddlers/Release 5.0.11beta.tid | 1 + .../tw5.com/tiddlers/concepts/PermaLinks.tid | 14 +-- 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/core/modules/startup.js b/core/modules/startup.js index 49146d943..67d217141 100755 --- a/core/modules/startup.js +++ b/core/modules/startup.js @@ -76,38 +76,8 @@ exports.startup = function() { }); // Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup $tw.wiki.clearTiddlerEventQueue(); - // Decode the hash portion of our URL - var target, - storyFilter; - if($tw.locationHash.charAt(1) === "!") { - var hash = $tw.locationHash.substr(2), - split = hash.indexOf(":"); - if(split === -1) { - target = decodeURIComponent(hash.trim()); - } else { - target = decodeURIComponent(hash.substr(0,split - 1).trim()); - storyFilter = decodeURIComponent(hash.substr(split + 1).trim()); - } - } - // If a target tiddler was specified add it to the history stack - if(target && target !== "") { - // The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present - if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") { - target = target.substr(2,target.length - 4); - } - $tw.wiki.addToHistory(target); - } - // Use the story filter specified in the hash, or the default tiddlers - if(!storyFilter || storyFilter === "") { - storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE); - } - var storyList = $tw.wiki.filterTiddlers(storyFilter); - // If the target tiddler isn't included then splice it in at the top - if(target && storyList.indexOf(target) === -1) { - storyList.unshift(target); - } - // Save the story list - $tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields()); + // Open startup tiddlers + openStartupTiddlers(); // Set up the syncer object $tw.syncer = new $tw.Syncer({wiki: $tw.wiki}); // Host-specific startup @@ -229,6 +199,13 @@ exports.startup = function() { updateLocationHash(); } }); + // Listen for changes to the browser location hash + window.addEventListener("hashchange",function() { + if(window.location.hash !== $tw.locationHash) { + $tw.locationHash = window.location.hash; + openStartupTiddlers({defaultToCurrentStory: true}); + } + },false) // Set up the styles var styleTemplateTitle = "$:/core/ui/PageStylesheet", styleParser = $tw.wiki.parseTiddler(styleTemplateTitle); @@ -276,6 +253,51 @@ exports.startup = function() { } }; +/* +Process the location hash to open the specified tiddlers. Options: +defaultToCurrentStory: If true, the current story is retained as the default, instead of opening the default tiddlers +*/ +function openStartupTiddlers(options) { + options = options || {}; + // Decode the hash portion of our URL + var target, + storyFilter; + if($tw.locationHash.length > 1) { + var hash = $tw.locationHash.substr(1), + split = hash.indexOf(":"); + if(split === -1) { + target = decodeURIComponent(hash.trim()); + } else { + target = decodeURIComponent(hash.substr(0,split).trim()); + storyFilter = decodeURIComponent(hash.substr(split + 1).trim()); + } + } + // If a target tiddler was specified add it to the history stack + if(target && target !== "") { + // The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present + if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") { + target = target.substr(2,target.length - 4); + } + $tw.wiki.addToHistory(target); + } + // Use the story filter specified in the hash, or the default tiddlers + if(!storyFilter || storyFilter === "") { + if(options.defaultToCurrentStory) { + var currStoryList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE); + storyFilter = $tw.utils.stringifyList(currStoryList); + } else { + storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE); + } + } + var storyList = $tw.wiki.filterTiddlers(storyFilter); + // If the target tiddler isn't included then splice it in at the top + if(target && storyList.indexOf(target) === -1) { + storyList.unshift(target); + } + // Save the story list + $tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields()); +} + /* Helper to display the default tiddlers */ @@ -299,7 +321,10 @@ function updateLocationHash() { if(historyList.length > 0) { targetTiddler = historyList[historyList.length-1].title; } - location.hash = "#!" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); + $tw.locationHash = "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); + if(window.location.hash !== $tw.locationHash) { + window.location.hash = $tw.locationHash; + } } /* diff --git a/editions/markdowndemo/tiddlers/HelloThere.tid b/editions/markdowndemo/tiddlers/HelloThere.tid index 0af6f54ad..466d02f84 100644 --- a/editions/markdowndemo/tiddlers/HelloThere.tid +++ b/editions/markdowndemo/tiddlers/HelloThere.tid @@ -2,8 +2,13 @@ title: HelloThere This is a demo of TiddlyWiki5 incorporating a plugin for the [[markdown-js|https://github.com/evilstreak/markdown-js]] Markdown parser from Dominic Baggott. -The MarkdownExample tiddler below is written in Markdown. +The MarkdownExample tiddler below is written in Markdown. Create wiki links with the usual Markdown link syntax targeting `#` and the target tiddler title: + +``` +[link text](#TiddlerTitle) +``` To add the plugin to your own TiddlyWiki5, just drag this link to the browser window: [[$:/plugins/tiddlywiki/markdown]] + diff --git a/editions/tw5.com/tiddlers/Release 5.0.11beta.tid b/editions/tw5.com/tiddlers/Release 5.0.11beta.tid index b2f18acb4..70a5816cf 100644 --- a/editions/tw5.com/tiddlers/Release 5.0.11beta.tid +++ b/editions/tw5.com/tiddlers/Release 5.0.11beta.tid @@ -19,6 +19,7 @@ See [[Notes for upgrading to 5.0.11-beta]] for more details of these changes: !! Usability Improvements * Added support for PermaLinks and browser navigation buttons +* Added support for WikiLinks in Markdown via `[link text](#TiddlerTitle)` * [[Replaced|https://github.com/Jermolene/TiddlyWiki5/issues/580]] hamburger menu icon with double chevron icon * [[Enhance|https://github.com/Jermolene/TiddlyWiki5/commit/552657fc584dbb36754d3fcabca2cdef7e916ec9]] plain text parsing to use the CodeBlockWidget, and hence use syntax highlighting if the plugin is installed. This gives us syntax highlighting for JavaScript shadow tiddlers, amongst other things * Improvements to Chinese, Japanese and French translations diff --git a/editions/tw5.com/tiddlers/concepts/PermaLinks.tid b/editions/tw5.com/tiddlers/concepts/PermaLinks.tid index 2b29744d5..7ae3d4a8a 100644 --- a/editions/tw5.com/tiddlers/concepts/PermaLinks.tid +++ b/editions/tw5.com/tiddlers/concepts/PermaLinks.tid @@ -8,13 +8,13 @@ Permalinks allow direct links to individual tiddlers within a TiddlyWiki. ! Simple Permalinks -The simplest form of permalink is a single target tiddler title appended to the base URL with "#!": +The simplest form of permalink is a single target tiddler title appended to the base URL with `#`: -http://tiddlywiki.com/#!HelloThere +http://tiddlywiki.com/#HelloThere The tiddler title can contain spaces if required: -[[http://tiddlywiki.com/#!Using TiddlyWiki on Node.js]] +[[http://tiddlywiki.com/#Using TiddlyWiki on Node.js]] Note that double square brackets are not required around the target tiddler title; however, if present they are silently removed. @@ -22,17 +22,17 @@ Note that double square brackets are not required around the target tiddler titl The permalink can also specify the story list of tiddlers that should be opened alongside the target tiddler as a [[TiddlerFilter|TiddlerFilters]]: -[[http://tiddlywiki.com/#!TiddlerFields:Tiddlers TiddlerTags TiddlerFields ContentType]] +[[http://tiddlywiki.com/#TiddlerFields:Tiddlers TiddlerTags TiddlerFields ContentType]] If the target tiddler isn't present in the story list then it is automatically inserted at the top. This means that the following two examples both target the tiddler `Tiddlers` within the story sequence `Tiddlers`, `Tags`, `TiddlerFields`: -[[http://tiddlywiki.com/#!Tiddlers:Tags TiddlerFields]] +[[http://tiddlywiki.com/#Tiddlers:Tags TiddlerFields]] -[[http://tiddlywiki.com/#!Tiddlers:Tiddlers Tags TiddlerFields]] +[[http://tiddlywiki.com/#Tiddlers:Tiddlers Tags TiddlerFields]] It is also possible to specify a story filter without specifying a target tiddler for navigation: -~http://tiddlywiki.com/#!:[tags[task]] +~http://tiddlywiki.com/#:[tags[task]] ! About URL encoding