diff --git a/examples/Node.js/SVGExport.js b/examples/Node.js/SvgExport.js similarity index 100% rename from examples/Node.js/SVGExport.js rename to examples/Node.js/SvgExport.js diff --git a/examples/Node.js/SVGImport.js b/examples/Node.js/SvgImport.js similarity index 100% rename from examples/Node.js/SVGImport.js rename to examples/Node.js/SvgImport.js diff --git a/src/core/PaperScript.js b/src/core/PaperScript.js index a1c7df0f..f1f90f3c 100644 --- a/src/core/PaperScript.js +++ b/src/core/PaperScript.js @@ -525,10 +525,13 @@ Base.exports.PaperScript = (function() { // same order the script tags appear. // If the async attribute is specified on the script element, // request the source asynchronously and execute as soon as - // it is retreived. - Http.request('get', src, function(code) { - execute(code, scope, src); - }, async); + // it is retrieved. + Http.request({ + url: src, async: async, + onLoad: function(code) { + execute(code, scope, src); + } + }); } else { // We can simply get the code form the script tag. execute(script.innerHTML, scope, script.baseURI); diff --git a/src/item/Item.js b/src/item/Item.js index 0dceac0e..65e2ac24 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -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 * SVG content is loaded from the given URL receiving two arguments: the * 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] * {Boolean} whether imported items should have their transformation * matrices applied to their contents or not diff --git a/src/item/Project.js b/src/item/Project.js index bb8b6bf5..67a2f552 100644 --- a/src/item/Project.js +++ b/src/item/Project.js @@ -775,10 +775,13 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{ * * @option [options.expandShapes=false] {Boolean} whether imported shape * items should be expanded to path items - * @option options.onLoad(item, svg) {Function} the callback function to - * call once the SVG content is loaded from the given URL receiving two - * arguments: the converted `item` and the original `svg` data as a - * string. Only required when loading from external files. + * @option options.onLoad {Function} the callback function to call once the + * SVG content is loaded from the given URL receiving two arguments: the + * converted `item` and the original `svg` data as a string. Only + * 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] * {Boolean} whether imported items should have their transformation * matrices applied to their contents or not diff --git a/src/net/Http.js b/src/net/Http.js index baeb0b60..eca54360 100644 --- a/src/net/Http.js +++ b/src/net/Http.js @@ -11,23 +11,32 @@ */ var Http = { - request: function(method, url, callback, async) { + request: function(options) { // Code borrowed from Coffee Script and extended: - async = (async === undefined) ? true : async; var ctor = window.ActiveXObject || window.XMLHttpRequest, 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) xhr.overrideMimeType('text/plain'); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var status = xhr.status; - if (status === 0 || status === 200) { - callback.call(xhr, xhr.responseText); - } else { - throw new Error('Could not load ' + url + ' (Error ' - + status + ')'); + xhr.onload = function() { + var status = xhr.status; + if (status === 0 || status === 200) { + if (options.onLoad) { + options.onLoad.call(xhr, xhr.responseText); } + } 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); diff --git a/src/svg/SvgImport.js b/src/svg/SvgImport.js index fd32a42c..1bbf6e17 100644 --- a/src/svg/SvgImport.js +++ b/src/svg/SvgImport.js @@ -635,7 +635,7 @@ new function() { return item; } - function importSVG(source, options, isRoot) { + function importSVG(source, options) { if (!source) return null; options = typeof options === 'function' ? { onLoad: options } @@ -644,51 +644,65 @@ new function() { // Remember current scope so we can restore it in onLoad. scope = paper; - function onLoadCallback(svg) { + function onLoad(svg) { paper = scope; - var item = importSVG(svg, options, isRoot), + var item = importSVG(svg, options, true), onLoad = options.onLoad; if (onLoad) onLoad.call(this, item, svg); } - if (isRoot) { - // 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' && !/^.*