Fixed tests. Added new tests for class methods. Fix for bug #227

master
Dmitry Baranovskiy 2014-04-22 13:56:47 +10:00
parent bbc1d4d7f8
commit 51afce7824
8 changed files with 399 additions and 203 deletions

File diff suppressed because one or more lines are too long

102
dist/snap.svg.js vendored
View File

@ -14,7 +14,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: 2014-04-18 // build: 2014-04-22
// 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");
@ -1907,21 +1907,21 @@ function svgTransform2string(tstr) {
params.push(0, 0); params.push(0, 0);
} }
if (name == "scale") { if (name == "scale") {
if (params.length == 2) { if (params.length > 2) {
params = params.slice(0, 2);
} else if (params.length == 2) {
params.push(0, 0); params.push(0, 0);
} }
if (params.length == 1) { if (params.length == 1) {
params.push(params[0], 0, 0); params.push(params[0], 0, 0);
} }
if (params.length > 2) {
params = params.slice(0, 2);
}
} }
if (name == "skewX") { if (name == "skewX") {
res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]); res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]);
} else if (name == "skewY") { } else if (name == "skewY") {
res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]); res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]);
} else { } else {
console.log(params);
res.push([name.charAt(0)].concat(params)); res.push([name.charAt(0)].concat(params));
} }
return all; return all;
@ -2746,28 +2746,94 @@ function arrayFirstValue(arr) {
} }
} }
var rgNotSpace = /\S+/g, var rgNotSpace = /\S+/g,
rgBadSpace = /[\t\r\n\f]/g; rgBadSpace = /[\t\r\n\f]/g,
rgTrim = /(^\s+|\s+$)/g;
elproto.addClass = function (value) { elproto.addClass = function (value) {
var classes = (value || "").match(rgNotSpace) || [], var classes = (value || "").match(rgNotSpace) || [],
elem = this.node, elem = this.node,
cur = elem.className ? (" " + elem.className + " ").replace(rgBadSpace, " ") : " ", className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j, j,
pos,
clazz, clazz,
finalValue; finalValue;
if (cur) {
if (classes.length) {
j = 0; j = 0;
while ((clazz = classes[j++])) { while ((clazz = classes[j++])) {
if (cur.indexOf(" " + clazz + " ") < 0) { pos = curClasses.indexOf(clazz);
cur += clazz + " "; if (!~pos) {
curClasses.push(clazz);
} }
} }
finalValue = cur.replace(/(^\s+|\s+$)/g, ""); finalValue = curClasses.join(" ");
if (elem.className != finalValue) { if (className != finalValue) {
elem.className = finalValue; elem.className.baseVal = finalValue;
} }
} }
}; };
elproto.removeClass = function (value) {
var classes = (value || "").match(rgNotSpace) || [],
elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j,
pos,
clazz,
finalValue;
if (curClasses.length) {
j = 0;
while ((clazz = classes[j++])) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);
}
}
finalValue = curClasses.join(" ");
if (className != finalValue) {
elem.className.baseVal = finalValue;
}
}
};
elproto.hasClass = function (value) {
var elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [];
return !!~curClasses.indexOf(value);
};
elproto.toggleClass = function (value, flag) {
if (flag != null) {
if (flag) {
return this.addClass(value);
} else {
return this.removeClass(value);
}
}
var classes = (value || "").match(rgNotSpace) || [],
elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j,
pos,
clazz,
finalValue;
j = 0;
while ((clazz = classes[j++])) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);
} else {
curClasses.push(clazz);
}
}
finalValue = curClasses.join(" ");
if (className != finalValue) {
elem.className.baseVal = finalValue;
}
};
elproto.clone = function () { elproto.clone = function () {
var clone = wrap(this.node.cloneNode(true)); var clone = wrap(this.node.cloneNode(true));
if ($(clone.node, "id")) { if ($(clone.node, "id")) {
@ -2777,7 +2843,6 @@ function arrayFirstValue(arr) {
clone.insertAfter(this); clone.insertAfter(this);
return clone; return clone;
}; };
// SIERRA Element.toDefs(): If this _moves_ an element to the <defs> region, why is the return value a _clone_? Also unclear why it's called the _relative_ <defs> section. Perhaps _shared_?
/*\ /*\
* Element.toDefs * Element.toDefs
[ method ] [ method ]
@ -2791,8 +2856,6 @@ function arrayFirstValue(arr) {
defs.appendChild(this.node); defs.appendChild(this.node);
return this; return this;
}; };
// SIERRA Element.pattern(): x/y/width/height data types are listed as both String and Number. Is that an error, or does it mean strings are coerced?
// SIERRA Element.pattern(): clarify that x/y are offsets that e.g., may add gutters between the tiles.
/*\ /*\
* Element.pattern * Element.pattern
[ method ] [ method ]
@ -4090,6 +4153,10 @@ eve.on("snap.util.attr.path", function (value) {
eve.stop(); eve.stop();
this.attr({d: value}); this.attr({d: value});
})(-1); })(-1);
eve.on("snap.util.attr.class", function (value) {
eve.stop();
this.node.className.baseVal = value;
})(-1);
eve.on("snap.util.attr.viewBox", function (value) { eve.on("snap.util.attr.viewBox", function (value) {
var vb; var vb;
if (is(value, "object") && "x" in value) { if (is(value, "object") && "x" in value) {
@ -4378,6 +4445,9 @@ eve.on("snap.util.getattr.path", function () {
eve.stop(); eve.stop();
return p; return p;
}); });
eve.on("snap.util.getattr.class", function () {
return this.node.className.baseVal;
});
function getFontSize() { function getFontSize() {
eve.stop(); eve.stop();
return this.node.style.fontSize; return this.node.style.fontSize;

File diff suppressed because it is too large Load Diff

View File

@ -1149,21 +1149,21 @@ function svgTransform2string(tstr) {
params.push(0, 0); params.push(0, 0);
} }
if (name == "scale") { if (name == "scale") {
if (params.length == 2) { if (params.length > 2) {
params = params.slice(0, 2);
} else if (params.length == 2) {
params.push(0, 0); params.push(0, 0);
} }
if (params.length == 1) { if (params.length == 1) {
params.push(params[0], 0, 0); params.push(params[0], 0, 0);
} }
if (params.length > 2) {
params = params.slice(0, 2);
}
} }
if (name == "skewX") { if (name == "skewX") {
res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]); res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]);
} else if (name == "skewY") { } else if (name == "skewY") {
res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]); res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]);
} else { } else {
console.log(params);
res.push([name.charAt(0)].concat(params)); res.push([name.charAt(0)].concat(params));
} }
return all; return all;
@ -1988,28 +1988,94 @@ function arrayFirstValue(arr) {
} }
} }
var rgNotSpace = /\S+/g, var rgNotSpace = /\S+/g,
rgBadSpace = /[\t\r\n\f]/g; rgBadSpace = /[\t\r\n\f]/g,
rgTrim = /(^\s+|\s+$)/g;
elproto.addClass = function (value) { elproto.addClass = function (value) {
var classes = (value || "").match(rgNotSpace) || [], var classes = (value || "").match(rgNotSpace) || [],
elem = this.node, elem = this.node,
cur = elem.className ? (" " + elem.className + " ").replace(rgBadSpace, " ") : " ", className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j, j,
pos,
clazz, clazz,
finalValue; finalValue;
if (cur) {
if (classes.length) {
j = 0; j = 0;
while ((clazz = classes[j++])) { while ((clazz = classes[j++])) {
if (cur.indexOf(" " + clazz + " ") < 0) { pos = curClasses.indexOf(clazz);
cur += clazz + " "; if (!~pos) {
curClasses.push(clazz);
} }
} }
finalValue = cur.replace(/(^\s+|\s+$)/g, ""); finalValue = curClasses.join(" ");
if (elem.className != finalValue) { if (className != finalValue) {
elem.className = finalValue; elem.className.baseVal = finalValue;
} }
} }
}; };
elproto.removeClass = function (value) {
var classes = (value || "").match(rgNotSpace) || [],
elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j,
pos,
clazz,
finalValue;
if (curClasses.length) {
j = 0;
while ((clazz = classes[j++])) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);
}
}
finalValue = curClasses.join(" ");
if (className != finalValue) {
elem.className.baseVal = finalValue;
}
}
};
elproto.hasClass = function (value) {
var elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [];
return !!~curClasses.indexOf(value);
};
elproto.toggleClass = function (value, flag) {
if (flag != null) {
if (flag) {
return this.addClass(value);
} else {
return this.removeClass(value);
}
}
var classes = (value || "").match(rgNotSpace) || [],
elem = this.node,
className = elem.className.baseVal,
curClasses = className.match(rgNotSpace) || [],
j,
pos,
clazz,
finalValue;
j = 0;
while ((clazz = classes[j++])) {
pos = curClasses.indexOf(clazz);
if (~pos) {
curClasses.splice(pos, 1);
} else {
curClasses.push(clazz);
}
}
finalValue = curClasses.join(" ");
if (className != finalValue) {
elem.className.baseVal = finalValue;
}
};
elproto.clone = function () { elproto.clone = function () {
var clone = wrap(this.node.cloneNode(true)); var clone = wrap(this.node.cloneNode(true));
if ($(clone.node, "id")) { if ($(clone.node, "id")) {
@ -2019,7 +2085,6 @@ function arrayFirstValue(arr) {
clone.insertAfter(this); clone.insertAfter(this);
return clone; return clone;
}; };
// SIERRA Element.toDefs(): If this _moves_ an element to the <defs> region, why is the return value a _clone_? Also unclear why it's called the _relative_ <defs> section. Perhaps _shared_?
/*\ /*\
* Element.toDefs * Element.toDefs
[ method ] [ method ]
@ -2033,8 +2098,6 @@ function arrayFirstValue(arr) {
defs.appendChild(this.node); defs.appendChild(this.node);
return this; return this;
}; };
// SIERRA Element.pattern(): x/y/width/height data types are listed as both String and Number. Is that an error, or does it mean strings are coerced?
// SIERRA Element.pattern(): clarify that x/y are offsets that e.g., may add gutters between the tiles.
/*\ /*\
* Element.pattern * Element.pattern
[ method ] [ method ]
@ -3332,6 +3395,10 @@ eve.on("snap.util.attr.path", function (value) {
eve.stop(); eve.stop();
this.attr({d: value}); this.attr({d: value});
})(-1); })(-1);
eve.on("snap.util.attr.class", function (value) {
eve.stop();
this.node.className.baseVal = value;
})(-1);
eve.on("snap.util.attr.viewBox", function (value) { eve.on("snap.util.attr.viewBox", function (value) {
var vb; var vb;
if (is(value, "object") && "x" in value) { if (is(value, "object") && "x" in value) {
@ -3620,6 +3687,9 @@ eve.on("snap.util.getattr.path", function () {
eve.stop(); eve.stop();
return p; return p;
}); });
eve.on("snap.util.getattr.class", function () {
return this.node.className.baseVal;
});
function getFontSize() { function getFontSize() {
eve.stop(); eve.stop();
return this.node.style.fontSize; return this.node.style.fontSize;

View File

@ -80,7 +80,7 @@
{{~it.out :item:index}} {{~it.out :item:index}}
<article id="{{=item[0].title}}"> <article id="{{=item[0].title}}">
<header> <header>
<h3 class="{{=item[0].clas}}">{{=item[0].name}}<a href="#{{=item[0].title}}" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line {{=item[0].line}} in the source" href="https://github.com/adobe-webplatform/savage/blob/master/src/svg.js#{{=item[0].line}}">&#x27ad;</a></h3> <h3 class="{{=item[0].clas}}">{{=item[0].name}}<a href="#{{=item[0].title}}" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line {{=item[0].line}} in the source" href="https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js#L{{=item[0].line}}">&#x27ad;</a></h3>
</header> </header>
<section> <section>
<div class="extra" id="{{=item[0].title}}-extra"></div> <div class="extra" id="{{=item[0].title}}-extra"></div>

55
test/class.js Normal file
View File

@ -0,0 +1,55 @@
describe("Class methods", function () {
var s, r;
beforeEach(function () {
s = Snap(100, 100);
r = s.rect(10, 10, 50, 50);
});
afterEach(function () {
s.remove();
});
it("elproto.addClass one", function() {
r.addClass("one");
expect(r.node.className.baseVal).to.be("one");
});
it("elproto.addClass two", function() {
r.addClass("one two");
expect(r.node.className.baseVal).to.be("one two");
});
it("elproto.addClass two (spacing)", function() {
r.addClass("\tone two ");
expect(r.node.className.baseVal).to.be("one two");
});
it("elproto.addClass three", function() {
r.addClass("one two three");
expect(r.node.className.baseVal).to.be("one two three");
});
it("elproto.removeClass 1", function() {
r.addClass("one two three");
r.removeClass("two");
expect(r.node.className.baseVal).to.be("one three");
});
it("elproto.removeClass 2", function() {
r.addClass("one two three");
r.removeClass("two one");
expect(r.node.className.baseVal).to.be("three");
});
it("elproto.hasClass", function() {
r.addClass("one two three");
expect(r.hasClass("two")).to.be(true);
});
it("elproto.toggleClass 1", function() {
r.addClass("one two three");
r.toggleClass("two one");
expect(r.node.className.baseVal).to.be("three");
});
it("elproto.toggleClass 2", function() {
r.addClass("one three");
r.toggleClass("two one", false);
expect(r.node.className.baseVal).to.be("three");
});
it("elproto.toggleClass 3", function() {
r.addClass("one three");
r.toggleClass("two one", true);
expect(r.node.className.baseVal).to.be("one three two");
});
});

View File

@ -55,28 +55,28 @@ describe("Filter methods", function () {
}); });
it("Snap.filter.shadow - dx & dy", function() { it("Snap.filter.shadow - dx & dy", function() {
var str = Snap.filter.shadow(5, 5); var str = Snap.filter.shadow(5, 5);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3); str = Snap.filter.shadow(-1, 3);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
}); });
it("Snap.filter.shadow - dx & dy, blur", function() { it("Snap.filter.shadow - dx & dy, blur", function() {
var str = Snap.filter.shadow(5, 5, 5); var str = Snap.filter.shadow(5, 5, 5);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 10); str = Snap.filter.shadow(-1, 3, 10);
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="#000000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
}); });
it("Snap.filter.shadow - dx & dy, color", function() { it("Snap.filter.shadow - dx & dy, color", function() {
var str = Snap.filter.shadow(5, 5, '#F00'); var str = Snap.filter.shadow(5, 5, '#F00');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="#F00"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 'hsla(128deg, 50%, 50%, 0.8)'); str = Snap.filter.shadow(-1, 3, 'hsla(128deg, 50%, 50%, 0.8)');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="4"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="hsla(128deg, 50%, 50%, 0.8)"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
}); });
it("Snap.filter.shadow - dx & dy, blur & color", function() { it("Snap.filter.shadow - dx & dy, blur & color", function() {
var str = Snap.filter.shadow(5, 5, 5, '#F00'); var str = Snap.filter.shadow(5, 5, 5, '#F00');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="5"/><feOffset dx="5" dy="5" result="offsetblur"/><feFlood flood-color="#ff0000"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
str = Snap.filter.shadow(-1, 3, 10, 'hsla(128deg, 50%, 50%, 0.8)'); str = Snap.filter.shadow(-1, 3, 10, 'hsla(128deg, 50%, 50%, 0.8)');
expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>'); expect(str).to.be('<feGaussianBlur in="SourceAlpha" stdDeviation="10"/><feOffset dx="-1" dy="3" result="offsetblur"/><feFlood flood-color="rgba(64,191,81,0.8)"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="1"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>');
}); });

View File

@ -43,6 +43,7 @@
<script src="filter.js"></script> <script src="filter.js"></script>
<script src="matrix.js"></script> <script src="matrix.js"></script>
<script src="mina.js"></script> <script src="mina.js"></script>
<script src="class.js"></script>
<script> <script>
mocha.checkLeaks(); mocha.checkLeaks();
window.onload = function () { window.onload = function () {