mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
parent
79d446136a
commit
2025bd1a77
8 changed files with 92 additions and 67 deletions
|
@ -525,10 +525,13 @@ Base.exports.PaperScript = (function() {
|
||||||
// same order the script tags appear.
|
// same order the script tags appear.
|
||||||
// If the async attribute is specified on the script element,
|
// If the async attribute is specified on the script element,
|
||||||
// request the source asynchronously and execute as soon as
|
// request the source asynchronously and execute as soon as
|
||||||
// it is retreived.
|
// it is retrieved.
|
||||||
Http.request('get', src, function(code) {
|
Http.request({
|
||||||
execute(code, scope, src);
|
url: src, async: async,
|
||||||
}, async);
|
onLoad: function(code) {
|
||||||
|
execute(code, scope, src);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// We can simply get the code form the script tag.
|
// We can simply get the code form the script tag.
|
||||||
execute(script.innerHTML, scope, script.baseURI);
|
execute(script.innerHTML, scope, script.baseURI);
|
||||||
|
|
|
@ -2223,7 +2223,10 @@ new function() { // Injection scope for hit-test functions shared with project
|
||||||
* @option options.onLoad {Function} the callback function to call once the
|
* @option options.onLoad {Function} the callback function to call once the
|
||||||
* SVG content is loaded from the given URL receiving two arguments: the
|
* SVG content is loaded from the given URL receiving two arguments: the
|
||||||
* converted `item` and the original `svg` data as a string. Only
|
* converted `item` and the original `svg` data as a string. Only
|
||||||
* required when loading from external files.
|
* required when loading from external resources.
|
||||||
|
* @option options.onError {Function} the callback function to call if an
|
||||||
|
* error occurs during loading. Only required when loading from external
|
||||||
|
* resources.
|
||||||
* @option [options.applyMatrix={@link PaperScope#settings}.applyMatrix]
|
* @option [options.applyMatrix={@link PaperScope#settings}.applyMatrix]
|
||||||
* {Boolean} whether imported items should have their transformation
|
* {Boolean} whether imported items should have their transformation
|
||||||
* matrices applied to their contents or not
|
* matrices applied to their contents or not
|
||||||
|
|
|
@ -775,10 +775,13 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
||||||
*
|
*
|
||||||
* @option [options.expandShapes=false] {Boolean} whether imported shape
|
* @option [options.expandShapes=false] {Boolean} whether imported shape
|
||||||
* items should be expanded to path items
|
* items should be expanded to path items
|
||||||
* @option options.onLoad(item, svg) {Function} the callback function to
|
* @option options.onLoad {Function} the callback function to call once the
|
||||||
* call once the SVG content is loaded from the given URL receiving two
|
* SVG content is loaded from the given URL receiving two arguments: the
|
||||||
* arguments: the converted `item` and the original `svg` data as a
|
* converted `item` and the original `svg` data as a string. Only
|
||||||
* string. Only required when loading from external files.
|
* required when loading from external resources.
|
||||||
|
* @option options.onError {Function} the callback function to call if an
|
||||||
|
* error occurs during loading. Only required when loading from external
|
||||||
|
* resources.
|
||||||
* @option [options.applyMatrix={@link PaperScope#settings}.applyMatrix]
|
* @option [options.applyMatrix={@link PaperScope#settings}.applyMatrix]
|
||||||
* {Boolean} whether imported items should have their transformation
|
* {Boolean} whether imported items should have their transformation
|
||||||
* matrices applied to their contents or not
|
* matrices applied to their contents or not
|
||||||
|
|
|
@ -11,23 +11,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Http = {
|
var Http = {
|
||||||
request: function(method, url, callback, async) {
|
request: function(options) {
|
||||||
// Code borrowed from Coffee Script and extended:
|
// Code borrowed from Coffee Script and extended:
|
||||||
async = (async === undefined) ? true : async;
|
|
||||||
var ctor = window.ActiveXObject || window.XMLHttpRequest,
|
var ctor = window.ActiveXObject || window.XMLHttpRequest,
|
||||||
xhr = new ctor('Microsoft.XMLHTTP');
|
xhr = new ctor('Microsoft.XMLHTTP');
|
||||||
xhr.open(method.toUpperCase(), url, async);
|
xhr.open((options.method || 'get').toUpperCase(), options.url,
|
||||||
|
Base.pick(options.async, true));
|
||||||
if ('overrideMimeType' in xhr)
|
if ('overrideMimeType' in xhr)
|
||||||
xhr.overrideMimeType('text/plain');
|
xhr.overrideMimeType('text/plain');
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onload = function() {
|
||||||
if (xhr.readyState === 4) {
|
var status = xhr.status;
|
||||||
var status = xhr.status;
|
if (status === 0 || status === 200) {
|
||||||
if (status === 0 || status === 200) {
|
if (options.onLoad) {
|
||||||
callback.call(xhr, xhr.responseText);
|
options.onLoad.call(xhr, xhr.responseText);
|
||||||
} else {
|
|
||||||
throw new Error('Could not load ' + url + ' (Error '
|
|
||||||
+ status + ')');
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
xhr.onerror();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onerror = function() {
|
||||||
|
var status = xhr.status,
|
||||||
|
message = 'Could not load "' + options.url + '" (Status: '
|
||||||
|
+ status + ')';
|
||||||
|
if (options.onError) {
|
||||||
|
options.onError(message, status);
|
||||||
|
} else {
|
||||||
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return xhr.send(null);
|
return xhr.send(null);
|
||||||
|
|
|
@ -635,7 +635,7 @@ new function() {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function importSVG(source, options, isRoot) {
|
function importSVG(source, options) {
|
||||||
if (!source)
|
if (!source)
|
||||||
return null;
|
return null;
|
||||||
options = typeof options === 'function' ? { onLoad: options }
|
options = typeof options === 'function' ? { onLoad: options }
|
||||||
|
@ -644,51 +644,65 @@ new function() {
|
||||||
// Remember current scope so we can restore it in onLoad.
|
// Remember current scope so we can restore it in onLoad.
|
||||||
scope = paper;
|
scope = paper;
|
||||||
|
|
||||||
function onLoadCallback(svg) {
|
function onLoad(svg) {
|
||||||
paper = scope;
|
paper = scope;
|
||||||
var item = importSVG(svg, options, isRoot),
|
var item = importSVG(svg, options, true),
|
||||||
onLoad = options.onLoad;
|
onLoad = options.onLoad;
|
||||||
if (onLoad)
|
if (onLoad)
|
||||||
onLoad.call(this, item, svg);
|
onLoad.call(this, item, svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRoot) {
|
function onError(message, status) {
|
||||||
// Have the group not pass on all transformations to its children,
|
var onError = options.onError;
|
||||||
// as this is how SVG works too.
|
if (onError) {
|
||||||
// See if it's a string but handle markup separately
|
onError.call(this, message, status);
|
||||||
if (typeof source === 'string' && !/^.*</.test(source)) {
|
} else {
|
||||||
// First see if we're meant to import an element with the given
|
throw new Error(message);
|
||||||
// id.
|
|
||||||
node = document.getElementById(source);
|
|
||||||
// Check if the string does not represent SVG data, in which
|
|
||||||
// case it must be the URL of a SVG to be loaded.
|
|
||||||
if (node) {
|
|
||||||
source = null;
|
|
||||||
} else {
|
|
||||||
return Http.request('get', source, onLoadCallback);
|
|
||||||
}
|
|
||||||
} else if (typeof File !== 'undefined' && source instanceof File) {
|
|
||||||
// Load local file through FileReader
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onload = function() {
|
|
||||||
onLoadCallback(reader.result);
|
|
||||||
};
|
|
||||||
return reader.readAsText(source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Have the group not pass on all transformations to its children,
|
||||||
|
// as this is how SVG works too.
|
||||||
|
// See if it's a string but handle markup separately
|
||||||
|
if (typeof source === 'string' && !/^.*</.test(source)) {
|
||||||
|
// First see if we're meant to import an element with the given
|
||||||
|
// id.
|
||||||
|
node = document.getElementById(source);
|
||||||
|
// Check if the string does not represent SVG data, in which
|
||||||
|
// case it must be the URL of a SVG to be loaded.
|
||||||
|
if (node) {
|
||||||
|
source = null;
|
||||||
|
} else {
|
||||||
|
Http.request({
|
||||||
|
url: source, async: true,
|
||||||
|
onLoad: onLoad, onError: onError
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (typeof File !== 'undefined' && source instanceof File) {
|
||||||
|
// Load local file through FileReader
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function() {
|
||||||
|
onLoad(reader.result);
|
||||||
|
};
|
||||||
|
reader.onerror = function() {
|
||||||
|
onError(reader.error);
|
||||||
|
};
|
||||||
|
return reader.readAsText(source);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof source === 'string') {
|
if (typeof source === 'string') {
|
||||||
node = new window.DOMParser().parseFromString(source,
|
node = new window.DOMParser().parseFromString(source,
|
||||||
'image/svg+xml');
|
'image/svg+xml');
|
||||||
}
|
}
|
||||||
if (!node.nodeName)
|
if (!node.nodeName)
|
||||||
throw new Error('Unsupported SVG source: ' + source);
|
throw new Error('Unsupported SVG source: ' + source);
|
||||||
return importNode(node, options, isRoot);
|
return importNode(node, options, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Documentation is in Item#importSVG()
|
// NOTE: Documentation is in Item#importSVG()
|
||||||
Item.inject({
|
Item.inject({
|
||||||
importSVG: function(node, options) {
|
importSVG: function(node, options) {
|
||||||
return this.addChild(importSVG(node, options, true));
|
return this.addChild(importSVG(node, options));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -696,7 +710,7 @@ new function() {
|
||||||
Project.inject({
|
Project.inject({
|
||||||
importSVG: function(node, options) {
|
importSVG: function(node, options) {
|
||||||
this.activate();
|
this.activate();
|
||||||
return importSVG(node, options, true);
|
return importSVG(node, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,31 +122,18 @@ test('Import complex CompoundPath and clone', function() {
|
||||||
|
|
||||||
function importSVG(assert, url, message, options) {
|
function importSVG(assert, url, message, options) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
if (!message)
|
|
||||||
message = 'The imported SVG "' + url + '" should visually be the same '
|
|
||||||
+ 'as the rasterized original SVG data.';
|
|
||||||
project.importSVG(url, {
|
project.importSVG(url, {
|
||||||
onLoad: function(item, svg) {
|
onLoad: function(item, svg) {
|
||||||
function getValue(name) {
|
if (!message) {
|
||||||
return parseFloat(svg.getAttribute(name));
|
message = 'The imported SVG "' + url + '" should visually be '
|
||||||
|
+ 'the same as the rasterized original SVG data.';
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
var size = new Size(getValue('width'), getValue('height'));
|
|
||||||
var group = new Group({
|
|
||||||
children: [
|
|
||||||
new Shape.Rectangle({
|
|
||||||
clipMask: true,
|
|
||||||
size: size
|
|
||||||
}),
|
|
||||||
item
|
|
||||||
]
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
compareSVG(done, item, svg, message, options);
|
compareSVG(done, item, svg, message, options);
|
||||||
},
|
},
|
||||||
onError: function(error) {
|
onError: function(error) {
|
||||||
// TODO: Implement in SvgImport first!
|
var ok = !!(options && options.expectError);
|
||||||
pushFailure('Loading SVG from a valid URL should not give an error.');
|
QUnit.push(ok, false, !ok, ok && message
|
||||||
|
|| 'Loading SVG from a valid URL should not give an error.');
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -164,4 +151,10 @@ if (!isNode) {
|
||||||
importSVG(assert, 'assets/' + name);
|
importSVG(assert, 'assets/' + name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Import inexistent file', function(assert) {
|
||||||
|
importSVG(assert, 'assets/inexistent.svg',
|
||||||
|
'Load an inexistent SVG file should trigger an error',
|
||||||
|
{ expectError: true });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue