Added ability to solve ids in cloned elements. New element methods and

master
Dmitry Baranovskiy 2013-09-11 13:17:32 +10:00
parent fd8db10bd3
commit be42ac9b88
5 changed files with 309 additions and 49 deletions

76
dist/reference.html vendored

File diff suppressed because one or more lines are too long

8
dist/savage-min.js vendored

File diff suppressed because one or more lines are too long

163
dist/savage.js vendored
View File

@ -28,7 +28,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// build: 2013-09-10 // build: 2013-09-11
// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
@ -714,7 +714,7 @@ var mina = (function (eve) {
return mina; return mina;
})(typeof eve == "undefined" ? function () {} : eve); })(typeof eve == "undefined" ? function () {} : eve);
/* /*
* Elemental 0.2.2 - Simple JavaScript Tag Parser * Elemental 0.2.4 - Simple JavaScript Tag Parser
* *
* Copyright (c) 2010 - 2013 Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) * Copyright (c) 2010 - 2013 Dmitry Baranovskiy (http://dmitry.baranovskiy.com/)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
@ -751,7 +751,7 @@ var mina = (function (eve) {
function event(name, data, extra) { function event(name, data, extra) {
if (typeof eve == "function") { if (typeof eve == "function") {
eve("elemental." + name + "." + data, null, data, extra || "", this.raw); eve("elemental." + name + (data ? "." + data : ""), null, data, extra || "", this.raw);
} }
var a = this.events && this.events[name], var a = this.events && this.events[name],
i = a && a.length; i = a && a.length;
@ -763,15 +763,40 @@ var mina = (function (eve) {
function end() { function end() {
step.call(this, "eof"); step.call(this, "eof");
// this._beforeEnd && this._beforeEnd();
// this.raw && this.event("text", this.raw);
// this.mode = "text";
// this.textchunk = "";
// delete this._beforeEnd;
this.event("eof"); this.event("eof");
} }
var whitespace = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]/, var entities = {
"lt": 60,
"lt;": 60,
"AMP;": 38,
"AMP": 38,
"GT;": 62,
"GT": 62,
"QUOT;": 34,
"QUOT": 34,
"apos;": 39,
"bull;": 8226,
"bullet;": 8226,
"copy;": 169,
"copy": 169,
"deg;": 176,
"deg": 176
},
whitespace = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]/,
notEntity = /[#\da-z]/i,
entity2text = function (entity) {
var code;
if (entity.charAt() == "#") {
if (entity.charAt(1).toLowerCase() == "x") {
code = parseInt(entity.substring(2), 16);
} else {
code = parseInt(entity.substring(1), 10);
}
}
code = entities[entity];
return code ? String.fromCharCode(code) : ("&" + entity);
},
fireAttrEvent = function () { fireAttrEvent = function () {
for (var key in this.attr) if (this.attr.hasOwnProperty(key)) { for (var key in this.attr) if (this.attr.hasOwnProperty(key)) {
this.event("attr", key, { this.event("attr", key, {
@ -794,11 +819,26 @@ var mina = (function (eve) {
this.raw += c; this.raw += c;
this.textchunk = ""; this.textchunk = "";
break; break;
case "&":
this.mode = "entity";
this.entity = "";
break;
default: default:
this.textchunk += c; this.textchunk += c;
break; break;
} }
}, },
entity: function (c, n, p) {
if (whitespace.test(c)) {
this.textchunk += entity2text(this.entity);
this.mode = "text";
} else if (c == ";") {
this.textchunk += entity2text(this.entity + c);
this.mode = "text";
} else {
this.entity += c;
}
},
special: function (c, n, p) { special: function (c, n, p) {
if (p == "!" && c == "-" && n == "-") { if (p == "!" && c == "-" && n == "-") {
this.mode = "comment start"; this.mode = "comment start";
@ -836,12 +876,12 @@ var mina = (function (eve) {
"comment start": function (c, n, p) { "comment start": function (c, n, p) {
if (n == ">" || c == "eof") { if (n == ">" || c == "eof") {
this.event("comment", ""); this.event("comment", "");
this.mode = "comment instant end"; this.mode = "skip";
} else { } else {
this.mode = "comment"; this.mode = "comment";
} }
}, },
"comment instant end": function (c, n, p) { "skip": function (c, n, p) {
this.mode = "text"; this.mode = "text";
}, },
comment: function (c, n, p) { comment: function (c, n, p) {
@ -926,6 +966,12 @@ var mina = (function (eve) {
this.event("tag", this.nodename); this.event("tag", this.nodename);
this.mode = "text"; this.mode = "text";
break; break;
case "/":
this.raw += n;
this.event("tag", this.nodename);
this.event("/tag", this.nodename);
this.mode = "skip";
break;
default: default:
this.nodename += c; this.nodename += c;
break; break;
@ -997,7 +1043,7 @@ var mina = (function (eve) {
act[this.mode].call(this, c, n, p); act[this.mode].call(this, c, n, p);
} }
function elemental(type) { function elemental(type, ent) {
var out = function (s) { var out = function (s) {
out.parse(s); out.parse(s);
}; };
@ -1009,9 +1055,12 @@ var mina = (function (eve) {
out.on = on; out.on = on;
out.event = event; out.event = event;
out.end = end; out.end = end;
if (ent) {
entities = ent;
}
return out; return out;
} }
elemental.version = "0.2.2"; elemental.version = "0.2.4";
(typeof exports == "undefined" ? this : exports).elemental = elemental; (typeof exports == "undefined" ? this : exports).elemental = elemental;
})(); })();
@ -2754,8 +2803,74 @@ function arrayFirstValue(arr) {
** **
= (Element) the clone = (Element) the clone
\*/ \*/
function fixids(el) {
var els = el.selectAll("*"),
it,
url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
ids = [],
uses = {};
function urltest(it, name) {
var val = $(it.node, name);
val = val && val.match(url);
val = val && val[2];
if (val && val.charAt() == "#") {
val = val.substring(1);
} else {
return;
}
if (val) {
uses[val] = (uses[val] || []).concat(function (id) {
var attr = {};
attr[name] = "url(#" + id + ")";
$(it.node, attr);
});
}
}
function linktest(it) {
var val = $(it.node, "xlink:href");
if (val && val.charAt() == "#") {
val = val.substring(1);
} else {
return;
}
if (val) {
uses[val] = (uses[val] || []).concat(function (id) {
it.attr("xlink:href", "#" + id);
});
}
}
for (var i = 0, ii = els.length; i < ii; i++) {
it = els[i];
urltest(it, "fill");
urltest(it, "stroke");
urltest(it, "filter");
urltest(it, "mask");
urltest(it, "clip-path");
linktest(it);
var oldid = $(it.node, "id");
if (oldid) {
$(it.node, {id: it.id});
ids.push({
old: oldid,
id: it.id
});
}
}
for (i = 0, ii = ids.length; i < ii; i++) {
var fs = uses[ids[i].old];
if (fs) {
for (var j = 0, jj = fs.length; j < jj; j++) {
fs[j](ids[i].id);
}
}
}
}
elproto.clone = function () { elproto.clone = function () {
var clone = wrap(this.node.cloneNode(true)); var clone = wrap(this.node.cloneNode(true));
if ($(clone.node, "id")) {
$(clone.node, {id: clone.id});
}
fixids(clone);
clone.insertAfter(this); clone.insertAfter(this);
return clone; return clone;
}; };
@ -3078,6 +3193,28 @@ function arrayFirstValue(arr) {
} }
return this; return this;
}; };
elproto.toString = function () {
var res = "<" + this.type,
attr = this.node.attributes,
chld = this.node.childNodes;
for (var i = 0, ii = attr.length; i < ii; i++) {
res += " " + attr[i].name + '="' + attr[i].value.replace(/"/g, '\\"') + '"';
}
if (chld.length) {
res += ">";
for (i = 0, ii = chld.length; i < ii; i++) {
if (chld[i].nodeType == 3) {
res += chld[i].nodeValue;
} else if (chld[i].nodeType == 1) {
res += wrap(chld[i]).toString();
}
}
res += "</" + this.type + ">";
} else {
res += "/>";
}
return res;
};
}(Element.prototype)); }(Element.prototype));
/*\ /*\
* Savage.parse * Savage.parse

View File

@ -16,7 +16,7 @@
"mocha": "*", "mocha": "*",
"expect.js": "*", "expect.js": "*",
"eve": "*", "eve": "*",
"elemental.js": "*", "elemental.js": "~0.2.4",
"dr.js": "*" "dr.js": "*"
} }
} }

View File

@ -1737,8 +1737,74 @@ function arrayFirstValue(arr) {
** **
= (Element) the clone = (Element) the clone
\*/ \*/
function fixids(el) {
var els = el.selectAll("*"),
it,
url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
ids = [],
uses = {};
function urltest(it, name) {
var val = $(it.node, name);
val = val && val.match(url);
val = val && val[2];
if (val && val.charAt() == "#") {
val = val.substring(1);
} else {
return;
}
if (val) {
uses[val] = (uses[val] || []).concat(function (id) {
var attr = {};
attr[name] = "url(#" + id + ")";
$(it.node, attr);
});
}
}
function linktest(it) {
var val = $(it.node, "xlink:href");
if (val && val.charAt() == "#") {
val = val.substring(1);
} else {
return;
}
if (val) {
uses[val] = (uses[val] || []).concat(function (id) {
it.attr("xlink:href", "#" + id);
});
}
}
for (var i = 0, ii = els.length; i < ii; i++) {
it = els[i];
urltest(it, "fill");
urltest(it, "stroke");
urltest(it, "filter");
urltest(it, "mask");
urltest(it, "clip-path");
linktest(it);
var oldid = $(it.node, "id");
if (oldid) {
$(it.node, {id: it.id});
ids.push({
old: oldid,
id: it.id
});
}
}
for (i = 0, ii = ids.length; i < ii; i++) {
var fs = uses[ids[i].old];
if (fs) {
for (var j = 0, jj = fs.length; j < jj; j++) {
fs[j](ids[i].id);
}
}
}
}
elproto.clone = function () { elproto.clone = function () {
var clone = wrap(this.node.cloneNode(true)); var clone = wrap(this.node.cloneNode(true));
if ($(clone.node, "id")) {
$(clone.node, {id: clone.id});
}
fixids(clone);
clone.insertAfter(this); clone.insertAfter(this);
return clone; return clone;
}; };
@ -2061,6 +2127,49 @@ function arrayFirstValue(arr) {
} }
return this; return this;
}; };
/*\
* Element.toString
[ method ]
**
* Returns SVG code of the element. Equivalent to `outerHTML` in HTML context.
= (string) SVG code of the element.
\*/
elproto.toString = toString(1);
/*\
* Element.innerSVG
[ method ]
**
* Returns SVG code of the element. Equivalent to `innerHTML` in HTML context.
= (string) SVG code of the element.
\*/
elproto.innerSVG = toString();
function toString(type) {
return function () {
var res = type ? "<" + this.type : "",
attr = this.node.attributes,
chld = this.node.childNodes;
if (type) {
for (var i = 0, ii = attr.length; i < ii; i++) {
res += " " + attr[i].name + '="' +
attr[i].value.replace(/"/g, '\\"') + '"';
}
}
if (chld.length) {
type && (res += ">");
for (i = 0, ii = chld.length; i < ii; i++) {
if (chld[i].nodeType == 3) {
res += chld[i].nodeValue;
} else if (chld[i].nodeType == 1) {
res += wrap(chld[i]).toString();
}
}
type && (res += "</" + this.type + ">");
} else {
type && (res += "/>");
}
return res;
};
}
}(Element.prototype)); }(Element.prototype));
/*\ /*\
* Savage.parse * Savage.parse