Files
svgedit/test/test1.html
Philip Rogers 7e3f9e037d Add pathseg.js, a polyfill for the SVGPathSeg API
The SVGPathSeg API is being removed from the spec [1] and is being
removed in Chromium 47 [2]. I implemented a drop-in polyfill[3] so
svg-edit users are not broken as browsers migrate away from the
path seg api.

This patch simply imports the upstream pathseg.js and updates all
dependencies. With this change all tests pass in Chrome 46 (with
the path seg api), Chrome 47 (without the path seg api), and
there are no changes to tests in Safari 9.01 or Firefox 43. I
also manually tested svg-edit while developing the polyfill and
could not find any broken features.

[1] https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html
[2] https://groups.google.com/a/chromium.org/d/msg/blink-dev/EDC3cBg9mCU/OvElJgOWCgAJ
[3] https://github.com/progers/pathseg
2015-11-04 19:25:30 -08:00

290 lines
13 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Unit Tests for SvgCanvas</title>
<link rel="stylesheet" href="qunit/qunit.css" type="text/css"/>
<script src="../editor/jquery.js"></script>
<script src="../editor/jquerybbq/jquery.bbq.min.js"></script>
<script src="../editor/jquery-ui/jquery-ui-1.8.custom.min.js"></script>
<script src="../editor/svgedit.js"></script>
<script src="../editor/svgicons/jquery.svgicons.js"></script>
<script src="../editor/pathseg.js"></script>
<script src="../editor/browser.js"></script>
<script src="../editor/svgtransformlist.js"></script>
<script src="../editor/math.js"></script>
<script src="../editor/units.js"></script>
<script src="../editor/svgutils.js"></script>
<script src="../editor/sanitize.js"></script>
<script src="../editor/history.js"></script>
<script src='../editor/coords.js'></script>
<script src="../editor/recalculate.js"></script>
<script src="../editor/select.js"></script>
<script src="../editor/draw.js"></script>
<script src="../editor/path.js"></script>
<script src="../editor/svgcanvas.js"></script>
<script src="../editor/svg-editor.js"></script>
<script src="../editor/locale/locale.js"></script>
<script src="qunit/qunit.js"></script>
<script>
$(function() {
// log function
QUnit.log = function(details) {
if (window.console && window.console.log) {
window.console.log(details.result +' :: '+ details.message);
}
};
// helper functions
var isIdentity = function(m) {
return (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0);
};
var matrixString = function(m) {
return [m.a,m.b,m.c,m.d,m.e,m.f].join(',');
}
var svgCanvas = new $.SvgCanvas(document.getElementById("svgcanvas"), {
canvas_expansion: 3,
dimensions: [640,480],
initFill: {
color: 'FF0000', // solid red
opacity: 1
},
initStroke: {
width: 5,
color: '000000', // solid black
opacity: 1
},
initOpacity: 1,
imgPath: 'images/',
langPath: 'locale/',
extPath: 'extensions/',
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js'],
initTool: 'select',
wireframe: false
}),
svgroot = document.getElementById("svgroot"),
svgdoc = svgroot.documentElement,
svgns = "http://www.w3.org/2000/svg",
xlinkns = "http://www.w3.org/1999/xlink";
module("Basic Module");
test("Test existence of SvgCanvas object", function() {
expect(1);
equal(typeof {}, typeof svgCanvas);
});
module("Path Module");
test("Test path conversion from absolute to relative", function() {
expect(6);
var convert = svgCanvas.pathActions.convertPath;
// TODO: Test these paths:
// "m400.00491,625.01379a1.78688,1.78688 0 1 1-3.57373,0a1.78688,1.78688 0 1 13.57373,0z"
// "m36.812,15.8566c-28.03099,0 -26.28099,12.15601 -26.28099,12.15601l0.03099,12.59399h26.75v3.781h-37.37399c0,0 -17.938,-2.034 -133.00001,26.25c115.06201,28.284 130.71801,27.281 130.71801,27.281h9.34399v-13.125c0,0 -0.504,-15.656 15.40601,-15.656h26.532c0,0 14.90599,0.241 14.90599,-14.406v-24.219c0,0 2.263,-14.65601 -27.032,-14.65601zm-14.75,8.4684c2.662,0 4.813,2.151 4.813,4.813c0,2.661 -2.151,4.812 -4.813,4.812c-2.661,0 -4.812,-2.151 -4.812,-4.812c0,-2.662 2.151,-4.813 4.812,-4.813z"
// "m 0,0 l 200,0 l 0,100 L 0,100"
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' width='400' x='300'>" +
"<path id='p1' d='M100,100 L200,100 L100,100Z'/>" +
"<path id='p2' d='m 0,0 l 200,0 l 0,100 L 0,100'/>" +
"</svg>");
var p1 = document.getElementById("p1"),
p2 = document.getElementById("p2"),
d_abs = p1.getAttribute("d"),
seglist = p1.pathSegList,
curseg = null;
equal(p1.nodeName, "path", "Expected 'path', got");
equal(seglist.numberOfItems, 4, "Number of segments before conversion");
// verify segments before conversion
curseg = seglist.getItem(0);
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "M", "Before conversion, segment #1 type");
curseg = seglist.getItem(1);
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "L", "Before conversion, segment #2 type");
curseg = seglist.getItem(3);
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "Z", "Before conversion, segment #3 type" + d_abs);
// convert and verify segments
var d = convert(p1, true);
equal(d, "m100,100l100,0l-100,0z", "Converted path to relative string");
// TODO: see why this isn't working in SVG-edit
d = convert(p2, true);
QUnit.log({result: d});
d = convert(p2, false);
QUnit.log({result: d});
});
module("Import Module");
test("Test import use", function() {
expect(3);
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='400' x='300'>" +
"<rect id='the-rect' width='200' height='200'/>" +
"<use id='the-use' xlink:href='#the-rect'/>" +
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
"<use id='no-use'/>" +
"</svg>");
var u = document.getElementById("the-use"),
fu = document.getElementById("foreign-use"),
nfu = document.getElementById("no-use");
equal((u && u.nodeName == "use"), true, "Did not import <use> element");
equal(fu, null, "Removed <use> element that had a foreign href");
equal(nfu, null, "Removed <use> element that had no href");
});
// This test shows that an element with an invalid attribute is still parsed in properly
// and only the attribute is not imported
test("Test invalid attribute", function() {
expect(2);
svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
'<text x="182.75" y="173.5" id="the-text" fill="#008000" font-size="150" font-family="serif" text-anchor="middle" d="M116,222 L110,108">words</text>' +
'</svg>');
var t = document.getElementById("the-text");
equal(true, (t && t.nodeName == "text"), "Did not import <text> element");
equal(null, t.getAttribute("d"), "Imported a <text> with a d attribute");
});
// This test makes sure import/export properly handles namespaced attributes
test("Test importing/exporting namespaced attributes", function() {
expect(5);
var setStr = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com" xmlns:foo="http://example.com">'+
'<image xlink:href="../editor/images/logo.png"/>' +
'<polyline id="se_test_elem" se:foo="bar" foo:bar="baz"/>' +
'</svg>');
var attrVal = document.getElementById('se_test_elem').getAttributeNS("http://svg-edit.googlecode.com", "foo");
equal(attrVal === "bar", true, "Preserved namespaced attribute on import");
//
//console.log('getSvgString' in svgCanvas)
var output = svgCanvas.getSvgString();
//} catch(e) {console.log(e)}
//console.log('output',output);
var has_xlink = output.indexOf('xmlns:xlink="http://www.w3.org/1999/xlink"') !== -1;
var has_se = output.indexOf('xmlns:se=') !== -1;
var has_foo = output.indexOf('xmlns:foo=') !== -1;
var has_attr = output.indexOf('se:foo="bar"') !== -1;
equal(has_attr, true, "Preserved namespaced attribute on export");
equal(has_xlink, true, "Included xlink: xmlns");
equal(has_se, true, "Included se: xmlns");
equal(has_foo, false, "Did not include foo: xmlns");
});
test("Test import math elements inside a foreignObject", function() {
expect(4);
var set = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:se="http://svg-edit.googlecode.com" xmlns:xlink="http://www.w3.org/1999/xlink">'+
'<foreignObject id="fo" width="24" height="26" font-size="24"><math id="m" display="inline" xmlns="http://www.w3.org/1998/Math/MathML">'+
'<msub>'+
'<mi>A</mi>'+
'<mn>0</mn>'+
'</msub>'+
'</math>'+
'</foreignObject>'+
'</svg>');
var fo = document.getElementById('fo');
// we cannot use getElementById('math') because not all browsers understand MathML and do not know to use the @id attribute
// see Bug https://bugs.webkit.org/show_bug.cgi?id=35042
var math = fo.firstChild;
equal(!!math, true, "Math element exists");
equal(math.nodeName, 'math', "Math element has the proper nodeName");
equal(math.getAttribute('id'), 'm', "Math element has an id");
equal(math.namespaceURI, "http://www.w3.org/1998/Math/MathML", "Preserved MathML namespace");
});
test("Test importing SVG into existing drawing", function() {
expect(3);
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
'<g><title>Layer 1</title>'+
'<circle cx="200" cy="200" r="50" fill="blue"/>'+
'<ellipse cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
'</g>'+
'</svg>');
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">'+
'<circle cx="50" cy="50" r="40" fill="yellow"/>'+
'<rect width="20" height="20" fill="blue"/>'+
'</svg>');
var svgcontent = document.getElementById("svgcontent"),
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse");
equal(circles.length, 2, "Found two circles upon importing");
equal(rects.length, 1, "Found one rectangle upon importing");
equal(ellipses.length, 1, "Found one ellipse upon importing");
});
test("Test importing SVG remaps IDs", function() {
expect(6);
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
'<g><title>Layer 1</title>'+
'<ellipse id="svg_1" cx="200" cy="200" rx="50" ry="20" fill="blue"/>'+
'<ellipse id="svg_2" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
'<ellipse id="svg_3" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
'</g>'+
'</svg>');
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink">'+
'<defs>'+
'<linearGradient id="svg_2">'+
'<stop stop-color="red" offset="0"/>'+
'<stop stop-color="green" offset="1"/>'+
'</linearGradient>'+
'<rect id="svg_3" width="20" height="20" fill="blue" stroke="url(#svg_2)"/>'+
'</defs>'+
'<circle id="svg_1" cx="50" cy="50" r="40" fill="url(#svg_2)"/>'+
'<use id="svg_4" width="30" height="30" xl:href="#svg_3"/>'+
'</svg>');
var svgcontent = document.getElementById("svgcontent"),
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse"),
defs = svgcontent.getElementsByTagNameNS(svgns, "defs"),
grads = svgcontent.getElementsByTagNameNS(svgns, "linearGradient"),
uses = svgcontent.getElementsByTagNameNS(svgns, "use");
notEqual(circles.item(0).id, "svg_1", "Circle not re-identified");
notEqual(rects.item(0).id, "svg_3", "Rectangle not re-identified");
// TODO: determine why this test fails in WebKit browsers
//equal(grads.length, 1, "Linear gradient imported");
var grad = defs.item(0).firstChild;
notEqual(grad.id, "svg_2", "Linear gradient not re-identified");
notEqual(circles.item(0).getAttribute("fill"), "url(#svg_2)", "Circle fill value not remapped");
notEqual(rects.item(0).getAttribute("stroke"), "url(#svg_2)", "Rectangle stroke value not remapped");
notEqual(uses.item(0).getAttributeNS(xlinkns, "href"), "#svg_3");
});
});
</script>
</head>
<body>
<h1 id="qunit-header">Unit Tests for SvgCanvas</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="svg_editor">
<div id="workarea">
<div id="svgcanvas" style="visibility:hidden"></div>
</div>
<div id="tools_left"></div>
<div class="tools_flyout"></div>
</div>
</body>
</html>