From ca6e32bd5aa8461610f915f65b6fc45caa9c56c8 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Sun, 15 Jan 2012 13:29:16 +0000 Subject: [PATCH] Refactor link handling to use a link macro Instead of the special case handling for tags --- js/App.js | 1 + js/WikiTextParseTree.js | 29 +++++----------------------- js/WikiTextRules.js | 31 +++++++++++++++++++----------- js/macros/link.js | 35 ++++++++++++++++++++++++++++++++++ tiddlywiki5/tiddlywiki5.recipe | 1 + 5 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 js/macros/link.js diff --git a/js/App.js b/js/App.js index 4ffac0442..034d5ef92 100644 --- a/js/App.js +++ b/js/App.js @@ -90,6 +90,7 @@ var App = function() { // Bit of a hack to set up the macros this.store.installMacro(require("./macros/echo.js").macro); this.store.installMacro(require("./macros/info.js").macro); + this.store.installMacro(require("./macros/link.js").macro); this.store.installMacro(require("./macros/list.js").macro); this.store.installMacro(require("./macros/story.js").macro); this.store.installMacro(require("./macros/tiddler.js").macro); diff --git a/js/WikiTextParseTree.js b/js/WikiTextParseTree.js index d6f3316be..a9e0d82d8 100644 --- a/js/WikiTextParseTree.js +++ b/js/WikiTextParseTree.js @@ -132,15 +132,15 @@ WikiTextParseTree.prototype.compileMacroCall = function(type,name,params) { value: n }); } + var wrapperTag = macro.wrapperTag || "div"; if(type === "text/html") { - this.pushString(utils.stitchElement("div",{ - "data-tw-macro": name, - "data-tw-params": JSON.stringify(params) + this.pushString(utils.stitchElement(wrapperTag,{ + "data-tw-macro": name })); } this.output.push(macroCall); if(type === "text/html") { - this.pushString(""); + this.pushString(""); } }; @@ -160,11 +160,7 @@ WikiTextParseTree.prototype.compileElementHtml = function(element, options) { tagBits.push(a + "=\"" + utils.htmlEncode(r) + "\""); } } - this.pushString("<" + tagBits.join(" ") + (options.selfClosing ? " /" : "")); - if(options.insertAfterAttributes) { - this.output.push(options.insertAfterAttributes); - } - this.pushString(">"); + this.pushString("<" + tagBits.join(" ") + (options.selfClosing ? " /" : "") + ">"); if(!options.selfClosing) { if(element.children) { this.compileSubTreeHtml(element.children); @@ -189,21 +185,6 @@ WikiTextParseTree.prototype.compileSubTreeHtml = function(tree) { case "macro": this.compileMacroCall("text/html",tree[t].name,tree[t].params); break; - case "a": - this.compileElementHtml(tree[t],{ - insertAfterAttributes: { - "type": "FunctionCall", - "name": { - "type": "PropertyAccess", - "base": { - "type": "Variable", - "name": "store"}, - "name": "classesForLink"}, - "arguments":[{ - "type": "StringLiteral", - "value": tree[t].attributes.href}]} - }); - break; default: this.compileElementHtml(tree[t]); break; diff --git a/js/WikiTextRules.js b/js/WikiTextRules.js index 5f770e765..1b3e1ac85 100755 --- a/js/WikiTextRules.js +++ b/js/WikiTextRules.js @@ -462,20 +462,23 @@ var rules = [ this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { - var e = {type: "a", children: []}; - var text = lookaheadMatch[1]; + var e = {type: "macro", name: "link", params: { + target: {type: "string", value: null}, + text: {type: "string", value: null} + }}, + text = lookaheadMatch[1]; if(lookaheadMatch[3]) { // Pretty bracketted link var link = lookaheadMatch[3]; - setAttr(e,"href",link); + e.params.target.value = link; w.addDependency(link); } else { // Simple bracketted link - setAttr(e,"href",text); + e.params.target.value = text; w.addDependency(text); } + e.params.text.value = text; w.output.push(e); - e.children.push({type: "text", value: text}); w.nextMatch = this.lookaheadRegExp.lastIndex; } } @@ -500,11 +503,14 @@ var rules = [ } } if(w.autoLinkWikiWords) { - var link = {type: "a", children: []}; - setAttr(link,"href",w.matchText); + var link = {type: "macro", name: "link", params: { + target: {type: "string", value: null}, + text: {type: "string", value: null} + }}; + link.params.target.value = w.matchText; + link.params.text.value = w.source.substring(w.matchStart,w.nextMatch); w.addDependency(w.matchText); w.output.push(link); - w.outputText(link.children,w.matchStart,w.nextMatch); } else { w.outputText(w.output,w.matchStart,w.nextMatch); } @@ -516,11 +522,14 @@ var rules = [ match: textPrimitives.urlPattern, handler: function(w) { - var e = {type: "a", children: []}; - setAttr(e,"href",w.matchText); + var e = {type: "macro", name: "link", params: { + target: {type: "string", value: null}, + text: {type: "string", value: null} + }}; + e.params.target.value = w.matchText; + e.params.text.value = w.source.substring(w.matchStart,w.nextMatch); w.addDependency(w.matchText); w.output.push(e); - w.outputText(e.children,w.matchStart,w.nextMatch); } }, diff --git a/js/macros/link.js b/js/macros/link.js new file mode 100644 index 000000000..93c57ce64 --- /dev/null +++ b/js/macros/link.js @@ -0,0 +1,35 @@ +/*\ +title: js/macros/link.js + +\*/ +(function(){ + +/*jslint node: true */ +"use strict"; + +var utils = require("../Utils.js"); + +exports.macro = { + name: "link", + wrapperTag: "span", + types: ["text/html","text/plain"], + params: { + target: {byName: "default", type: "tiddler", optional: false}, + text: {byName: true, type: "text", optional: true} + }, + handler: function(type,tiddler,store,params) { + var text = params.text || params.target; + if(type === "text/html") { + return utils.stitchElement("a",{ + href: params.target + },{ + content: utils.htmlEncode(text), + classNames: store.adjustClassesForLink([],params.target) + }); + } else if (type === "text/plain") { + return text; + } + } +}; + +})(); diff --git a/tiddlywiki5/tiddlywiki5.recipe b/tiddlywiki5/tiddlywiki5.recipe index 96e3b54a5..f3d8e6353 100644 --- a/tiddlywiki5/tiddlywiki5.recipe +++ b/tiddlywiki5/tiddlywiki5.recipe @@ -30,6 +30,7 @@ jsmodule: ../js/App.js jsmodule: ../js/macros/echo.js jsmodule: ../js/macros/info.js +jsmodule: ../js/macros/link.js jsmodule: ../js/macros/list.js jsmodule: ../js/macros/story.js jsmodule: ../js/macros/tiddler.js