From b0503cf709c848631c81780baa6181eaf2ff9089 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Sun, 13 Oct 2013 20:14:31 +0100 Subject: [PATCH] Fixes to make SVG and MathML elements work properly --- core/modules/new_widgets/element.js | 14 +++++++++++++- core/modules/new_widgets/widget.js | 5 +++-- core/modules/utils/fakedom.js | 5 +++-- editions/test/tiddlers/tests/test-widget.js | 16 ++++++++++++++-- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/core/modules/new_widgets/element.js b/core/modules/new_widgets/element.js index 99215a3cd..034490bb9 100755 --- a/core/modules/new_widgets/element.js +++ b/core/modules/new_widgets/element.js @@ -30,7 +30,7 @@ ElementWidget.prototype.render = function(parent,nextSibling) { this.parentDomNode = parent; this.computeAttributes(); this.execute(); - var domNode = this.document.createElement(this.parseTreeNode.tag); + var domNode = this.document.createElementNS(this.namespace,this.parseTreeNode.tag); this.assignAttributes(domNode); parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); @@ -41,6 +41,18 @@ ElementWidget.prototype.render = function(parent,nextSibling) { Compute the internal state of the widget */ ElementWidget.prototype.execute = function() { + // Select the namespace for the tag + var tagNamespaces = { + svg: "http://www.w3.org/2000/svg", + math: "http://www.w3.org/1998/Math/MathML" + }; + this.namespace = tagNamespaces[this.parseTreeNode.tag]; + if(this.namespace) { + this.setVariable("namespace",this.namespace); + } else { + this.namespace = this.getVariable("namespace",null,"http://www.w3.org/1999/xhtml"); + } + // Make the child widgets this.makeChildWidgets(); }; diff --git a/core/modules/new_widgets/widget.js b/core/modules/new_widgets/widget.js index c02bc391d..72b0f4049 100755 --- a/core/modules/new_widgets/widget.js +++ b/core/modules/new_widgets/widget.js @@ -74,14 +74,15 @@ Get the prevailing value of a context variable name: name of variable params: array of {name:, value:} for each parameter */ -Widget.prototype.getVariable = function(name,params) { +Widget.prototype.getVariable = function(name,params,defaultValue) { + params = params || []; // Search up the widget tree for the variable name var node = this; while(node && !$tw.utils.hop(node.variables,name)) { node = node.parentWidget; } if(!node) { - return undefined; + return defaultValue; } // Get the value var value = node.variables[name].value; diff --git a/core/modules/utils/fakedom.js b/core/modules/utils/fakedom.js index 8231f3cde..fd9be9e90 100755 --- a/core/modules/utils/fakedom.js +++ b/core/modules/utils/fakedom.js @@ -26,12 +26,13 @@ var TW_TextNode = function(text) { this.textContent = text; }; -var TW_Element = function(tag) { +var TW_Element = function(tag,namespace) { bumpSequenceNumber(this); this.tag = tag; this.attributes = {}; this.isRaw = false; this.children = []; + this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml"; }; TW_Element.prototype.setAttribute = function(name,value) { @@ -160,7 +161,7 @@ var document = { sequenceNumber = value; }, createElementNS: function(namespace,tag) { - return new TW_Element(tag); + return new TW_Element(tag,namespace); }, createElement: function(tag) { return new TW_Element(tag); diff --git a/editions/test/tiddlers/tests/test-widget.js b/editions/test/tiddlers/tests/test-widget.js index bf3068962..470ba7ee7 100755 --- a/editions/test/tiddlers/tests/test-widget.js +++ b/editions/test/tiddlers/tests/test-widget.js @@ -24,8 +24,8 @@ describe("Widget module", function() { }); } - function parseText(text,wiki) { - var parser = wiki.new_parseText("text/vnd.tiddlywiki",text); + function parseText(text,wiki,options) { + var parser = wiki.new_parseText("text/vnd.tiddlywiki",text,options); return parser ? {type: "widget", children: parser.tree} : undefined; } @@ -169,6 +169,18 @@ describe("Widget module", function() { }); + it("should deal with SVG elements", function() { + var wiki = new $tw.Wiki(); + // Construct the widget node + var text = "\n"; + var widgetNode = createWidgetNode(parseText(text,wiki,{parseAsInline:true}),wiki); + // Render the widget node to the DOM + var wrapper = renderWidgetNode(widgetNode); + // Test the rendering + expect(wrapper.innerHTML).toBe("\n\n\n"); + expect(wrapper.firstChild.namespaceURI).toBe("http://www.w3.org/2000/svg"); + }); + it("should parse and render transclusions", function() { var wiki = new $tw.Wiki(); // Add a tiddler