diff --git a/editor/browser.js b/editor/browser.js
index 8b5e5b4a..04a484a5 100644
--- a/editor/browser.js
+++ b/editor/browser.js
@@ -16,20 +16,20 @@
'use strict';
if (!svgedit.browser) {
- svgedit.browser = {};
+ svgedit.browser = {};
}
// alias
var NS = svgedit.NS;
var supportsSvg_ = (function () {
- return !!document.createElementNS && !!document.createElementNS(NS.SVG, 'svg').createSVGRect;
+ return !!document.createElementNS && !!document.createElementNS(NS.SVG, 'svg').createSVGRect;
}());
svgedit.browser.supportsSvg = function () { return supportsSvg_; };
if (!svgedit.browser.supportsSvg()) {
- window.location = 'browser-not-supported.html';
- return;
+ window.location = 'browser-not-supported.html';
+ return;
}
var userAgent = navigator.userAgent;
@@ -46,120 +46,120 @@ var isMac_ = userAgent.indexOf('Macintosh') >= 0;
var isTouch_ = 'ontouchstart' in window;
var supportsSelectors_ = (function () {
- return !!svg.querySelector;
+ return !!svg.querySelector;
}());
var supportsXpath_ = (function () {
- return !!document.evaluate;
+ return !!document.evaluate;
}());
// segList functions (for FF1.5 and 2.0)
var supportsPathReplaceItem_ = (function () {
- var path = document.createElementNS(NS.SVG, 'path');
- path.setAttribute('d', 'M0,0 10,10');
- var seglist = path.pathSegList;
- var seg = path.createSVGPathSegLinetoAbs(5, 5);
- try {
- seglist.replaceItem(seg, 1);
- return true;
- } catch (err) {}
- return false;
+ var path = document.createElementNS(NS.SVG, 'path');
+ path.setAttribute('d', 'M0,0 10,10');
+ var seglist = path.pathSegList;
+ var seg = path.createSVGPathSegLinetoAbs(5, 5);
+ try {
+ seglist.replaceItem(seg, 1);
+ return true;
+ } catch (err) {}
+ return false;
}());
var supportsPathInsertItemBefore_ = (function () {
- var path = document.createElementNS(NS.SVG, 'path');
- path.setAttribute('d', 'M0,0 10,10');
- var seglist = path.pathSegList;
- var seg = path.createSVGPathSegLinetoAbs(5, 5);
- try {
- seglist.insertItemBefore(seg, 1);
- return true;
- } catch (err) {}
- return false;
+ var path = document.createElementNS(NS.SVG, 'path');
+ path.setAttribute('d', 'M0,0 10,10');
+ var seglist = path.pathSegList;
+ var seg = path.createSVGPathSegLinetoAbs(5, 5);
+ try {
+ seglist.insertItemBefore(seg, 1);
+ return true;
+ } catch (err) {}
+ return false;
}());
// text character positioning (for IE9)
var supportsGoodTextCharPos_ = (function () {
- var svgroot = document.createElementNS(NS.SVG, 'svg');
- var svgcontent = document.createElementNS(NS.SVG, 'svg');
- document.documentElement.appendChild(svgroot);
- svgcontent.setAttribute('x', 5);
- svgroot.appendChild(svgcontent);
- var text = document.createElementNS(NS.SVG, 'text');
- text.textContent = 'a';
- svgcontent.appendChild(text);
- var pos = text.getStartPositionOfChar(0).x;
- document.documentElement.removeChild(svgroot);
- return (pos === 0);
+ var svgroot = document.createElementNS(NS.SVG, 'svg');
+ var svgcontent = document.createElementNS(NS.SVG, 'svg');
+ document.documentElement.appendChild(svgroot);
+ svgcontent.setAttribute('x', 5);
+ svgroot.appendChild(svgcontent);
+ var text = document.createElementNS(NS.SVG, 'text');
+ text.textContent = 'a';
+ svgcontent.appendChild(text);
+ var pos = text.getStartPositionOfChar(0).x;
+ document.documentElement.removeChild(svgroot);
+ return (pos === 0);
}());
var supportsPathBBox_ = (function () {
- var svgcontent = document.createElementNS(NS.SVG, 'svg');
- document.documentElement.appendChild(svgcontent);
- var path = document.createElementNS(NS.SVG, 'path');
- path.setAttribute('d', 'M0,0 C0,0 10,10 10,0');
- svgcontent.appendChild(path);
- var bbox = path.getBBox();
- document.documentElement.removeChild(svgcontent);
- return (bbox.height > 4 && bbox.height < 5);
+ var svgcontent = document.createElementNS(NS.SVG, 'svg');
+ document.documentElement.appendChild(svgcontent);
+ var path = document.createElementNS(NS.SVG, 'path');
+ path.setAttribute('d', 'M0,0 C0,0 10,10 10,0');
+ svgcontent.appendChild(path);
+ var bbox = path.getBBox();
+ document.documentElement.removeChild(svgcontent);
+ return (bbox.height > 4 && bbox.height < 5);
}());
// Support for correct bbox sizing on groups with horizontal/vertical lines
var supportsHVLineContainerBBox_ = (function () {
- var svgcontent = document.createElementNS(NS.SVG, 'svg');
- document.documentElement.appendChild(svgcontent);
- var path = document.createElementNS(NS.SVG, 'path');
- path.setAttribute('d', 'M0,0 10,0');
- var path2 = document.createElementNS(NS.SVG, 'path');
- path2.setAttribute('d', 'M5,0 15,0');
- var g = document.createElementNS(NS.SVG, 'g');
- g.appendChild(path);
- g.appendChild(path2);
- svgcontent.appendChild(g);
- var bbox = g.getBBox();
- document.documentElement.removeChild(svgcontent);
- // Webkit gives 0, FF gives 10, Opera (correctly) gives 15
- return (bbox.width === 15);
+ var svgcontent = document.createElementNS(NS.SVG, 'svg');
+ document.documentElement.appendChild(svgcontent);
+ var path = document.createElementNS(NS.SVG, 'path');
+ path.setAttribute('d', 'M0,0 10,0');
+ var path2 = document.createElementNS(NS.SVG, 'path');
+ path2.setAttribute('d', 'M5,0 15,0');
+ var g = document.createElementNS(NS.SVG, 'g');
+ g.appendChild(path);
+ g.appendChild(path2);
+ svgcontent.appendChild(g);
+ var bbox = g.getBBox();
+ document.documentElement.removeChild(svgcontent);
+ // Webkit gives 0, FF gives 10, Opera (correctly) gives 15
+ return (bbox.width === 15);
}());
var supportsEditableText_ = (function () {
- // TODO: Find better way to check support for this
- return isOpera_;
+ // TODO: Find better way to check support for this
+ return isOpera_;
}());
var supportsGoodDecimals_ = (function () {
- // Correct decimals on clone attributes (Opera < 10.5/win/non-en)
- var rect = document.createElementNS(NS.SVG, 'rect');
- rect.setAttribute('x', 0.1);
- var crect = rect.cloneNode(false);
- var retValue = (crect.getAttribute('x').indexOf(',') === -1);
- if (!retValue) {
- $.alert('NOTE: This version of Opera is known to contain bugs in SVG-edit.\n' +
- 'Please upgrade to the latest version in which the problems have been fixed.');
- }
- return retValue;
+ // Correct decimals on clone attributes (Opera < 10.5/win/non-en)
+ var rect = document.createElementNS(NS.SVG, 'rect');
+ rect.setAttribute('x', 0.1);
+ var crect = rect.cloneNode(false);
+ var retValue = (crect.getAttribute('x').indexOf(',') === -1);
+ if (!retValue) {
+ $.alert('NOTE: This version of Opera is known to contain bugs in SVG-edit.\n' +
+ 'Please upgrade to the latest version in which the problems have been fixed.');
+ }
+ return retValue;
}());
var supportsNonScalingStroke_ = (function () {
- var rect = document.createElementNS(NS.SVG, 'rect');
- rect.setAttribute('style', 'vector-effect:non-scaling-stroke');
- return rect.style.vectorEffect === 'non-scaling-stroke';
+ var rect = document.createElementNS(NS.SVG, 'rect');
+ rect.setAttribute('style', 'vector-effect:non-scaling-stroke');
+ return rect.style.vectorEffect === 'non-scaling-stroke';
}());
var supportsNativeSVGTransformLists_ = (function () {
- var rect = document.createElementNS(NS.SVG, 'rect');
- var rxform = rect.transform.baseVal;
- var t1 = svg.createSVGTransform();
- rxform.appendItem(t1);
- var r1 = rxform.getItem(0);
- return r1 instanceof SVGTransform && t1 instanceof SVGTransform &&
- r1.type === t1.type && r1.angle === t1.angle &&
- r1.matrix.a === t1.matrix.a &&
- r1.matrix.b === t1.matrix.b &&
- r1.matrix.c === t1.matrix.c &&
- r1.matrix.d === t1.matrix.d &&
- r1.matrix.e === t1.matrix.e &&
- r1.matrix.f === t1.matrix.f;
+ var rect = document.createElementNS(NS.SVG, 'rect');
+ var rxform = rect.transform.baseVal;
+ var t1 = svg.createSVGTransform();
+ rxform.appendItem(t1);
+ var r1 = rxform.getItem(0);
+ return r1 instanceof SVGTransform && t1 instanceof SVGTransform &&
+ r1.type === t1.type && r1.angle === t1.angle &&
+ r1.matrix.a === t1.matrix.a &&
+ r1.matrix.b === t1.matrix.b &&
+ r1.matrix.c === t1.matrix.c &&
+ r1.matrix.d === t1.matrix.d &&
+ r1.matrix.e === t1.matrix.e &&
+ r1.matrix.f === t1.matrix.f;
}());
// Public API
diff --git a/editor/config-sample.js b/editor/config-sample.js
index fc8c24f6..39ad9095 100644
--- a/editor/config-sample.js
+++ b/editor/config-sample.js
@@ -21,86 +21,86 @@ See svg-editor.js for documentation on using setConfig().
// URL OVERRIDE CONFIG
svgEditor.setConfig({
- /**
- To override the ability for URLs to set URL-based SVG content,
- uncomment the following:
- */
- // preventURLContentLoading: true,
- /**
- To override the ability for URLs to set other configuration (including
- extension config), uncomment the following:
- */
- // preventAllURLConfig: true,
- /**
- To override the ability for URLs to set their own extensions,
- uncomment the following (note that if setConfig() is used in
- extension code, it will still be additive to extensions,
- however):
- */
- // lockExtensions: true,
+ /**
+ To override the ability for URLs to set URL-based SVG content,
+ uncomment the following:
+ */
+ // preventURLContentLoading: true,
+ /**
+ To override the ability for URLs to set other configuration (including
+ extension config), uncomment the following:
+ */
+ // preventAllURLConfig: true,
+ /**
+ To override the ability for URLs to set their own extensions,
+ uncomment the following (note that if setConfig() is used in
+ extension code, it will still be additive to extensions,
+ however):
+ */
+ // lockExtensions: true,
});
svgEditor.setConfig({
- /*
- Provide default values here which differ from that of the editor but
- which the URL can override
- */
+ /*
+ Provide default values here which differ from that of the editor but
+ which the URL can override
+ */
}, {allowInitialUserOverride: true});
// EXTENSION CONFIG
svgEditor.setConfig({
- extensions: [
- // 'ext-overview_window.js', 'ext-markers.js', 'ext-connector.js', 'ext-eyedropper.js', 'ext-shapes.js', 'ext-imagelib.js', 'ext-grid.js', 'ext-polygon.js', 'ext-star.js', 'ext-panning.js', 'ext-storage.js'
- ]
- // , noDefaultExtensions: false, // noDefaultExtensions can only be meaningfully used in config.js or in the URL
+ extensions: [
+ // 'ext-overview_window.js', 'ext-markers.js', 'ext-connector.js', 'ext-eyedropper.js', 'ext-shapes.js', 'ext-imagelib.js', 'ext-grid.js', 'ext-polygon.js', 'ext-star.js', 'ext-panning.js', 'ext-storage.js'
+ ]
+ // , noDefaultExtensions: false, // noDefaultExtensions can only be meaningfully used in config.js or in the URL
});
// OTHER CONFIG
svgEditor.setConfig({
- // canvasName: 'default',
- // canvas_expansion: 3,
- // initFill: {
- // color: 'FF0000', // solid red
- // opacity: 1
- // },
- // initStroke: {
- // width: 5,
- // color: '000000', // solid black
- // opacity: 1
- // },
- // initOpacity: 1,
- // colorPickerCSS: null,
- // initTool: 'select',
- // exportWindowType: 'new', // 'same'
- // wireframe: false,
- // showlayers: false,
- // no_save_warning: false,
- // PATH CONFIGURATION
- // imgPath: 'images/',
- // langPath: 'locale/',
- // extPath: 'extensions/',
- // jGraduatePath: 'jgraduate/images/',
- /*
- Uncomment the following to allow at least same domain (embedded) access,
- including file:// access.
- Setting as `['*']` would allow any domain to access but would be unsafe to
- data privacy and integrity.
- */
- // allowedOrigins: [window.location.origin || 'null'], // May be 'null' (as a string) when used as a file:// URL
- // DOCUMENT PROPERTIES
- // dimensions: [640, 480],
- // EDITOR OPTIONS
- // gridSnapping: false,
- // gridColor: '#000',
- // baseUnit: 'px',
- // snappingStep: 10,
- // showRulers: true,
- // EXTENSION-RELATED (GRID)
- // showGrid: false, // Set by ext-grid.js
- // EXTENSION-RELATED (STORAGE)
- // noStorageOnLoad: false, // Some interaction with ext-storage.js; prevent even the loading of previously saved local storage
- // forceStorage: false, // Some interaction with ext-storage.js; strongly discouraged from modification as it bypasses user privacy by preventing them from choosing whether to keep local storage or not
- // emptyStorageOnDecline: true, // Used by ext-storage.js; empty any prior storage if the user declines to store
+ // canvasName: 'default',
+ // canvas_expansion: 3,
+ // initFill: {
+ // color: 'FF0000', // solid red
+ // opacity: 1
+ // },
+ // initStroke: {
+ // width: 5,
+ // color: '000000', // solid black
+ // opacity: 1
+ // },
+ // initOpacity: 1,
+ // colorPickerCSS: null,
+ // initTool: 'select',
+ // exportWindowType: 'new', // 'same'
+ // wireframe: false,
+ // showlayers: false,
+ // no_save_warning: false,
+ // PATH CONFIGURATION
+ // imgPath: 'images/',
+ // langPath: 'locale/',
+ // extPath: 'extensions/',
+ // jGraduatePath: 'jgraduate/images/',
+ /*
+ Uncomment the following to allow at least same domain (embedded) access,
+ including file:// access.
+ Setting as `['*']` would allow any domain to access but would be unsafe to
+ data privacy and integrity.
+ */
+ // allowedOrigins: [window.location.origin || 'null'], // May be 'null' (as a string) when used as a file:// URL
+ // DOCUMENT PROPERTIES
+ // dimensions: [640, 480],
+ // EDITOR OPTIONS
+ // gridSnapping: false,
+ // gridColor: '#000',
+ // baseUnit: 'px',
+ // snappingStep: 10,
+ // showRulers: true,
+ // EXTENSION-RELATED (GRID)
+ // showGrid: false, // Set by ext-grid.js
+ // EXTENSION-RELATED (STORAGE)
+ // noStorageOnLoad: false, // Some interaction with ext-storage.js; prevent even the loading of previously saved local storage
+ // forceStorage: false, // Some interaction with ext-storage.js; strongly discouraged from modification as it bypasses user privacy by preventing them from choosing whether to keep local storage or not
+ // emptyStorageOnDecline: true, // Used by ext-storage.js; empty any prior storage if the user declines to store
});
// PREF CHANGES
@@ -118,29 +118,29 @@ As with configuration, one may use allowInitialUserOverride, but
are hard-coded here regardless of URL or prior user storage setting.
*/
svgEditor.setConfig(
- {
- // lang: '', // Set dynamically within locale.js if not previously set
- // iconsize: '', // Will default to 's' if the window height is smaller than the minimum height and 'm' otherwise
- /**
- * When showing the preferences dialog, svg-editor.js currently relies
- * on curPrefs instead of $.pref, so allowing an override for bkgd_color
- * means that this value won't have priority over block auto-detection as
- * far as determining which color shows initially in the preferences
- * dialog (though it can be changed and saved).
- */
- // bkgd_color: '#FFF',
- // bkgd_url: '',
- // img_save: 'embed',
- // Only shows in UI as far as alert notices
- // save_notice_done: false,
- // export_notice_done: false
- }
+ {
+ // lang: '', // Set dynamically within locale.js if not previously set
+ // iconsize: '', // Will default to 's' if the window height is smaller than the minimum height and 'm' otherwise
+ /**
+ * When showing the preferences dialog, svg-editor.js currently relies
+ * on curPrefs instead of $.pref, so allowing an override for bkgd_color
+ * means that this value won't have priority over block auto-detection as
+ * far as determining which color shows initially in the preferences
+ * dialog (though it can be changed and saved).
+ */
+ // bkgd_color: '#FFF',
+ // bkgd_url: '',
+ // img_save: 'embed',
+ // Only shows in UI as far as alert notices
+ // save_notice_done: false,
+ // export_notice_done: false
+ }
);
svgEditor.setConfig(
- {
- // Indicate pref settings here if you wish to allow user storage or URL settings
- // to be able to override your default preferences (unless other config options
- // have already explicitly prevented one or the other)
- },
- {allowInitialUserOverride: true}
+ {
+ // Indicate pref settings here if you wish to allow user storage or URL settings
+ // to be able to override your default preferences (unless other config options
+ // have already explicitly prevented one or the other)
+ },
+ {allowInitialUserOverride: true}
);
diff --git a/editor/contextmenu.js b/editor/contextmenu.js
index 986c462c..0df08ab4 100644
--- a/editor/contextmenu.js
+++ b/editor/contextmenu.js
@@ -13,51 +13,51 @@ var svgedit = svgedit || {}; // eslint-disable-line no-use-before-define
(function () {
var self = this;
if (!svgedit.contextmenu) {
- svgedit.contextmenu = {};
+ svgedit.contextmenu = {};
}
self.contextMenuExtensions = {};
var menuItemIsValid = function (menuItem) {
- return menuItem && menuItem.id && menuItem.label && menuItem.action && typeof menuItem.action === 'function';
+ return menuItem && menuItem.id && menuItem.label && menuItem.action && typeof menuItem.action === 'function';
};
var addContextMenuItem = function (menuItem) {
- // menuItem: {id, label, shortcut, action}
- if (!menuItemIsValid(menuItem)) {
- console.error('Menu items must be defined and have at least properties: id, label, action, where action must be a function');
- return;
- }
- if (menuItem.id in self.contextMenuExtensions) {
- console.error('Cannot add extension "' + menuItem.id + '", an extension by that name already exists"');
- return;
- }
- // Register menuItem action, see below for deferred menu dom injection
- console.log('Registed contextmenu item: {id:' + menuItem.id + ', label:' + menuItem.label + '}');
- self.contextMenuExtensions[menuItem.id] = menuItem;
- // TODO: Need to consider how to handle custom enable/disable behavior
+ // menuItem: {id, label, shortcut, action}
+ if (!menuItemIsValid(menuItem)) {
+ console.error('Menu items must be defined and have at least properties: id, label, action, where action must be a function');
+ return;
+ }
+ if (menuItem.id in self.contextMenuExtensions) {
+ console.error('Cannot add extension "' + menuItem.id + '", an extension by that name already exists"');
+ return;
+ }
+ // Register menuItem action, see below for deferred menu dom injection
+ console.log('Registed contextmenu item: {id:' + menuItem.id + ', label:' + menuItem.label + '}');
+ self.contextMenuExtensions[menuItem.id] = menuItem;
+ // TODO: Need to consider how to handle custom enable/disable behavior
};
var hasCustomHandler = function (handlerKey) {
- return self.contextMenuExtensions[handlerKey] && true;
+ return self.contextMenuExtensions[handlerKey] && true;
};
var getCustomHandler = function (handlerKey) {
- return self.contextMenuExtensions[handlerKey].action;
+ return self.contextMenuExtensions[handlerKey].action;
};
var injectExtendedContextMenuItemIntoDom = function (menuItem) {
- if (Object.keys(self.contextMenuExtensions).length === 0) {
- // all menuItems appear at the bottom of the menu in their own container.
- // if this is the first extension menu we need to add the separator.
- $('#cmenu_canvas').append("
");
- }
- var shortcut = menuItem.shortcut || '';
- $('#cmenu_canvas').append(" " +
- menuItem.label + "" +
- shortcut + ' ');
+ if (Object.keys(self.contextMenuExtensions).length === 0) {
+ // all menuItems appear at the bottom of the menu in their own container.
+ // if this is the first extension menu we need to add the separator.
+ $('#cmenu_canvas').append("");
+ }
+ var shortcut = menuItem.shortcut || '';
+ $('#cmenu_canvas').append(" " +
+ menuItem.label + "" +
+ shortcut + ' ');
};
// Defer injection to wait out initial menu processing. This probably goes away once all context
// menu behavior is brought here.
svgEditor.ready(function () {
- var menuItem;
- for (menuItem in self.contextMenuExtensions) {
- injectExtendedContextMenuItemIntoDom(self.contextMenuExtensions[menuItem]);
- }
+ var menuItem;
+ for (menuItem in self.contextMenuExtensions) {
+ injectExtendedContextMenuItemIntoDom(self.contextMenuExtensions[menuItem]);
+ }
});
svgedit.contextmenu.resetCustomMenus = function () { self.contextMenuExtensions = {}; };
svgedit.contextmenu.add = addContextMenuItem;
diff --git a/editor/coords.js b/editor/coords.js
index 760e1e4c..682f2273 100644
--- a/editor/coords.js
+++ b/editor/coords.js
@@ -22,12 +22,12 @@ var svgedit = svgedit || {}; // eslint-disable-line no-use-before-define
'use strict';
if (!svgedit.coords) {
- svgedit.coords = {};
+ svgedit.coords = {};
}
// this is how we map paths to our preferred relative segment types
var pathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
- 'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
+ 'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
/**
* @typedef editorContext
@@ -41,7 +41,7 @@ var editorContext_ = null;
* @param {editorContext} editorContext
*/
svgedit.coords.init = function (editorContext) {
- editorContext_ = editorContext;
+ editorContext_ = editorContext;
};
/**
@@ -51,266 +51,266 @@ svgedit.coords.init = function (editorContext) {
* @param {SVGMatrix} m - Matrix object to use for remapping coordinates
*/
svgedit.coords.remapElement = function (selected, changes, m) {
- var i, type,
- remap = function (x, y) { return svgedit.math.transformPoint(x, y, m); },
- scalew = function (w) { return m.a * w; },
- scaleh = function (h) { return m.d * h; },
- doSnapping = editorContext_.getGridSnapping() && selected.parentNode.parentNode.localName === 'svg',
- finishUp = function () {
- var o;
- if (doSnapping) {
- for (o in changes) {
- changes[o] = svgedit.utilities.snapToGrid(changes[o]);
- }
- }
- svgedit.utilities.assignAttributes(selected, changes, 1000, true);
- },
- box = svgedit.utilities.getBBox(selected);
+ var i, type,
+ remap = function (x, y) { return svgedit.math.transformPoint(x, y, m); },
+ scalew = function (w) { return m.a * w; },
+ scaleh = function (h) { return m.d * h; },
+ doSnapping = editorContext_.getGridSnapping() && selected.parentNode.parentNode.localName === 'svg',
+ finishUp = function () {
+ var o;
+ if (doSnapping) {
+ for (o in changes) {
+ changes[o] = svgedit.utilities.snapToGrid(changes[o]);
+ }
+ }
+ svgedit.utilities.assignAttributes(selected, changes, 1000, true);
+ },
+ box = svgedit.utilities.getBBox(selected);
- for (i = 0; i < 2; i++) {
- type = i === 0 ? 'fill' : 'stroke';
- var attrVal = selected.getAttribute(type);
- if (attrVal && attrVal.indexOf('url(') === 0) {
- if (m.a < 0 || m.d < 0) {
- var grad = svgedit.utilities.getRefElem(attrVal);
- var newgrad = grad.cloneNode(true);
- if (m.a < 0) {
- // flip x
- var x1 = newgrad.getAttribute('x1');
- var x2 = newgrad.getAttribute('x2');
- newgrad.setAttribute('x1', -(x1 - 1));
- newgrad.setAttribute('x2', -(x2 - 1));
- }
+ for (i = 0; i < 2; i++) {
+ type = i === 0 ? 'fill' : 'stroke';
+ var attrVal = selected.getAttribute(type);
+ if (attrVal && attrVal.indexOf('url(') === 0) {
+ if (m.a < 0 || m.d < 0) {
+ var grad = svgedit.utilities.getRefElem(attrVal);
+ var newgrad = grad.cloneNode(true);
+ if (m.a < 0) {
+ // flip x
+ var x1 = newgrad.getAttribute('x1');
+ var x2 = newgrad.getAttribute('x2');
+ newgrad.setAttribute('x1', -(x1 - 1));
+ newgrad.setAttribute('x2', -(x2 - 1));
+ }
- if (m.d < 0) {
- // flip y
- var y1 = newgrad.getAttribute('y1');
- var y2 = newgrad.getAttribute('y2');
- newgrad.setAttribute('y1', -(y1 - 1));
- newgrad.setAttribute('y2', -(y2 - 1));
- }
- newgrad.id = editorContext_.getDrawing().getNextId();
- svgedit.utilities.findDefs().appendChild(newgrad);
- selected.setAttribute(type, 'url(#' + newgrad.id + ')');
- }
+ if (m.d < 0) {
+ // flip y
+ var y1 = newgrad.getAttribute('y1');
+ var y2 = newgrad.getAttribute('y2');
+ newgrad.setAttribute('y1', -(y1 - 1));
+ newgrad.setAttribute('y2', -(y2 - 1));
+ }
+ newgrad.id = editorContext_.getDrawing().getNextId();
+ svgedit.utilities.findDefs().appendChild(newgrad);
+ selected.setAttribute(type, 'url(#' + newgrad.id + ')');
+ }
- // Not really working :(
- // if (selected.tagName === 'path') {
- // reorientGrads(selected, m);
- // }
- }
- }
+ // Not really working :(
+ // if (selected.tagName === 'path') {
+ // reorientGrads(selected, m);
+ // }
+ }
+ }
- var elName = selected.tagName;
- var chlist, mt;
- if (elName === 'g' || elName === 'text' || elName === 'tspan' || elName === 'use') {
- // if it was a translate, then just update x,y
- if (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && (m.e !== 0 || m.f !== 0)) {
- // [T][M] = [M][T']
- // therefore [T'] = [M_inv][T][M]
- var existing = svgedit.math.transformListToTransform(selected).matrix,
- tNew = svgedit.math.matrixMultiply(existing.inverse(), m, existing);
- changes.x = parseFloat(changes.x) + tNew.e;
- changes.y = parseFloat(changes.y) + tNew.f;
- } else {
- // we just absorb all matrices into the element and don't do any remapping
- chlist = svgedit.transformlist.getTransformList(selected);
- mt = svgroot.createSVGTransform();
- mt.setMatrix(svgedit.math.matrixMultiply(svgedit.math.transformListToTransform(chlist).matrix, m));
- chlist.clear();
- chlist.appendItem(mt);
- }
- }
- var c, pt, pt1, pt2, len;
- // now we have a set of changes and an applied reduced transform list
- // we apply the changes directly to the DOM
- switch (elName) {
- case 'foreignObject':
- case 'rect':
- case 'image':
- // Allow images to be inverted (give them matrix when flipped)
- if (elName === 'image' && (m.a < 0 || m.d < 0)) {
- // Convert to matrix
- chlist = svgedit.transformlist.getTransformList(selected);
- mt = svgroot.createSVGTransform();
- mt.setMatrix(svgedit.math.matrixMultiply(svgedit.math.transformListToTransform(chlist).matrix, m));
- chlist.clear();
- chlist.appendItem(mt);
- } else {
- pt1 = remap(changes.x, changes.y);
- changes.width = scalew(changes.width);
- changes.height = scaleh(changes.height);
- changes.x = pt1.x + Math.min(0, changes.width);
- changes.y = pt1.y + Math.min(0, changes.height);
- changes.width = Math.abs(changes.width);
- changes.height = Math.abs(changes.height);
- }
- finishUp();
- break;
- case 'ellipse':
- c = remap(changes.cx, changes.cy);
- changes.cx = c.x;
- changes.cy = c.y;
- changes.rx = scalew(changes.rx);
- changes.ry = scaleh(changes.ry);
- changes.rx = Math.abs(changes.rx);
- changes.ry = Math.abs(changes.ry);
- finishUp();
- break;
- case 'circle':
- c = remap(changes.cx, changes.cy);
- changes.cx = c.x;
- changes.cy = c.y;
- // take the minimum of the new selected box's dimensions for the new circle radius
- var tbox = svgedit.math.transformBox(box.x, box.y, box.width, box.height, m);
- var w = tbox.tr.x - tbox.tl.x, h = tbox.bl.y - tbox.tl.y;
- changes.r = Math.min(w / 2, h / 2);
+ var elName = selected.tagName;
+ var chlist, mt;
+ if (elName === 'g' || elName === 'text' || elName === 'tspan' || elName === 'use') {
+ // if it was a translate, then just update x,y
+ if (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && (m.e !== 0 || m.f !== 0)) {
+ // [T][M] = [M][T']
+ // therefore [T'] = [M_inv][T][M]
+ var existing = svgedit.math.transformListToTransform(selected).matrix,
+ tNew = svgedit.math.matrixMultiply(existing.inverse(), m, existing);
+ changes.x = parseFloat(changes.x) + tNew.e;
+ changes.y = parseFloat(changes.y) + tNew.f;
+ } else {
+ // we just absorb all matrices into the element and don't do any remapping
+ chlist = svgedit.transformlist.getTransformList(selected);
+ mt = svgroot.createSVGTransform();
+ mt.setMatrix(svgedit.math.matrixMultiply(svgedit.math.transformListToTransform(chlist).matrix, m));
+ chlist.clear();
+ chlist.appendItem(mt);
+ }
+ }
+ var c, pt, pt1, pt2, len;
+ // now we have a set of changes and an applied reduced transform list
+ // we apply the changes directly to the DOM
+ switch (elName) {
+ case 'foreignObject':
+ case 'rect':
+ case 'image':
+ // Allow images to be inverted (give them matrix when flipped)
+ if (elName === 'image' && (m.a < 0 || m.d < 0)) {
+ // Convert to matrix
+ chlist = svgedit.transformlist.getTransformList(selected);
+ mt = svgroot.createSVGTransform();
+ mt.setMatrix(svgedit.math.matrixMultiply(svgedit.math.transformListToTransform(chlist).matrix, m));
+ chlist.clear();
+ chlist.appendItem(mt);
+ } else {
+ pt1 = remap(changes.x, changes.y);
+ changes.width = scalew(changes.width);
+ changes.height = scaleh(changes.height);
+ changes.x = pt1.x + Math.min(0, changes.width);
+ changes.y = pt1.y + Math.min(0, changes.height);
+ changes.width = Math.abs(changes.width);
+ changes.height = Math.abs(changes.height);
+ }
+ finishUp();
+ break;
+ case 'ellipse':
+ c = remap(changes.cx, changes.cy);
+ changes.cx = c.x;
+ changes.cy = c.y;
+ changes.rx = scalew(changes.rx);
+ changes.ry = scaleh(changes.ry);
+ changes.rx = Math.abs(changes.rx);
+ changes.ry = Math.abs(changes.ry);
+ finishUp();
+ break;
+ case 'circle':
+ c = remap(changes.cx, changes.cy);
+ changes.cx = c.x;
+ changes.cy = c.y;
+ // take the minimum of the new selected box's dimensions for the new circle radius
+ var tbox = svgedit.math.transformBox(box.x, box.y, box.width, box.height, m);
+ var w = tbox.tr.x - tbox.tl.x, h = tbox.bl.y - tbox.tl.y;
+ changes.r = Math.min(w / 2, h / 2);
- if (changes.r) { changes.r = Math.abs(changes.r); }
- finishUp();
- break;
- case 'line':
- pt1 = remap(changes.x1, changes.y1);
- pt2 = remap(changes.x2, changes.y2);
- changes.x1 = pt1.x;
- changes.y1 = pt1.y;
- changes.x2 = pt2.x;
- changes.y2 = pt2.y;
- // deliberately fall through here
- case 'text':
- case 'tspan':
- case 'use':
- finishUp();
- break;
- case 'g':
- var gsvg = $(selected).data('gsvg');
- if (gsvg) {
- svgedit.utilities.assignAttributes(gsvg, changes, 1000, true);
- }
- break;
- case 'polyline':
- case 'polygon':
- len = changes.points.length;
- for (i = 0; i < len; ++i) {
- pt = changes.points[i];
- pt = remap(pt.x, pt.y);
- changes.points[i].x = pt.x;
- changes.points[i].y = pt.y;
- }
+ if (changes.r) { changes.r = Math.abs(changes.r); }
+ finishUp();
+ break;
+ case 'line':
+ pt1 = remap(changes.x1, changes.y1);
+ pt2 = remap(changes.x2, changes.y2);
+ changes.x1 = pt1.x;
+ changes.y1 = pt1.y;
+ changes.x2 = pt2.x;
+ changes.y2 = pt2.y;
+ // deliberately fall through here
+ case 'text':
+ case 'tspan':
+ case 'use':
+ finishUp();
+ break;
+ case 'g':
+ var gsvg = $(selected).data('gsvg');
+ if (gsvg) {
+ svgedit.utilities.assignAttributes(gsvg, changes, 1000, true);
+ }
+ break;
+ case 'polyline':
+ case 'polygon':
+ len = changes.points.length;
+ for (i = 0; i < len; ++i) {
+ pt = changes.points[i];
+ pt = remap(pt.x, pt.y);
+ changes.points[i].x = pt.x;
+ changes.points[i].y = pt.y;
+ }
- len = changes.points.length;
- var pstr = '';
- for (i = 0; i < len; ++i) {
- pt = changes.points[i];
- pstr += pt.x + ',' + pt.y + ' ';
- }
- selected.setAttribute('points', pstr);
- break;
- case 'path':
- var seg;
- var segList = selected.pathSegList;
- len = segList.numberOfItems;
- changes.d = [];
- for (i = 0; i < len; ++i) {
- seg = segList.getItem(i);
- changes.d[i] = {
- type: seg.pathSegType,
- x: seg.x,
- y: seg.y,
- x1: seg.x1,
- y1: seg.y1,
- x2: seg.x2,
- y2: seg.y2,
- r1: seg.r1,
- r2: seg.r2,
- angle: seg.angle,
- largeArcFlag: seg.largeArcFlag,
- sweepFlag: seg.sweepFlag
- };
- }
+ len = changes.points.length;
+ var pstr = '';
+ for (i = 0; i < len; ++i) {
+ pt = changes.points[i];
+ pstr += pt.x + ',' + pt.y + ' ';
+ }
+ selected.setAttribute('points', pstr);
+ break;
+ case 'path':
+ var seg;
+ var segList = selected.pathSegList;
+ len = segList.numberOfItems;
+ changes.d = [];
+ for (i = 0; i < len; ++i) {
+ seg = segList.getItem(i);
+ changes.d[i] = {
+ type: seg.pathSegType,
+ x: seg.x,
+ y: seg.y,
+ x1: seg.x1,
+ y1: seg.y1,
+ x2: seg.x2,
+ y2: seg.y2,
+ r1: seg.r1,
+ r2: seg.r2,
+ angle: seg.angle,
+ largeArcFlag: seg.largeArcFlag,
+ sweepFlag: seg.sweepFlag
+ };
+ }
- len = changes.d.length;
- var firstseg = changes.d[0],
- currentpt = remap(firstseg.x, firstseg.y);
- changes.d[0].x = currentpt.x;
- changes.d[0].y = currentpt.y;
- for (i = 1; i < len; ++i) {
- seg = changes.d[i];
- type = seg.type;
- // if absolute or first segment, we want to remap x, y, x1, y1, x2, y2
- // if relative, we want to scalew, scaleh
- if (type % 2 === 0) { // absolute
- var thisx = (seg.x !== undefined) ? seg.x : currentpt.x, // for V commands
- thisy = (seg.y !== undefined) ? seg.y : currentpt.y; // for H commands
- pt = remap(thisx, thisy);
- pt1 = remap(seg.x1, seg.y1);
- pt2 = remap(seg.x2, seg.y2);
- seg.x = pt.x;
- seg.y = pt.y;
- seg.x1 = pt1.x;
- seg.y1 = pt1.y;
- seg.x2 = pt2.x;
- seg.y2 = pt2.y;
- seg.r1 = scalew(seg.r1);
- seg.r2 = scaleh(seg.r2);
- } else { // relative
- seg.x = scalew(seg.x);
- seg.y = scaleh(seg.y);
- seg.x1 = scalew(seg.x1);
- seg.y1 = scaleh(seg.y1);
- seg.x2 = scalew(seg.x2);
- seg.y2 = scaleh(seg.y2);
- seg.r1 = scalew(seg.r1);
- seg.r2 = scaleh(seg.r2);
- }
- } // for each segment
+ len = changes.d.length;
+ var firstseg = changes.d[0],
+ currentpt = remap(firstseg.x, firstseg.y);
+ changes.d[0].x = currentpt.x;
+ changes.d[0].y = currentpt.y;
+ for (i = 1; i < len; ++i) {
+ seg = changes.d[i];
+ type = seg.type;
+ // if absolute or first segment, we want to remap x, y, x1, y1, x2, y2
+ // if relative, we want to scalew, scaleh
+ if (type % 2 === 0) { // absolute
+ var thisx = (seg.x !== undefined) ? seg.x : currentpt.x, // for V commands
+ thisy = (seg.y !== undefined) ? seg.y : currentpt.y; // for H commands
+ pt = remap(thisx, thisy);
+ pt1 = remap(seg.x1, seg.y1);
+ pt2 = remap(seg.x2, seg.y2);
+ seg.x = pt.x;
+ seg.y = pt.y;
+ seg.x1 = pt1.x;
+ seg.y1 = pt1.y;
+ seg.x2 = pt2.x;
+ seg.y2 = pt2.y;
+ seg.r1 = scalew(seg.r1);
+ seg.r2 = scaleh(seg.r2);
+ } else { // relative
+ seg.x = scalew(seg.x);
+ seg.y = scaleh(seg.y);
+ seg.x1 = scalew(seg.x1);
+ seg.y1 = scaleh(seg.y1);
+ seg.x2 = scalew(seg.x2);
+ seg.y2 = scaleh(seg.y2);
+ seg.r1 = scalew(seg.r1);
+ seg.r2 = scaleh(seg.r2);
+ }
+ } // for each segment
- var dstr = '';
- len = changes.d.length;
- for (i = 0; i < len; ++i) {
- seg = changes.d[i];
- type = seg.type;
- dstr += pathMap[type];
- switch (type) {
- case 13: // relative horizontal line (h)
- case 12: // absolute horizontal line (H)
- dstr += seg.x + ' ';
- break;
- case 15: // relative vertical line (v)
- case 14: // absolute vertical line (V)
- dstr += seg.y + ' ';
- break;
- case 3: // relative move (m)
- case 5: // relative line (l)
- case 19: // relative smooth quad (t)
- case 2: // absolute move (M)
- case 4: // absolute line (L)
- case 18: // absolute smooth quad (T)
- dstr += seg.x + ',' + seg.y + ' ';
- break;
- case 7: // relative cubic (c)
- case 6: // absolute cubic (C)
- dstr += seg.x1 + ',' + seg.y1 + ' ' + seg.x2 + ',' + seg.y2 + ' ' +
- seg.x + ',' + seg.y + ' ';
- break;
- case 9: // relative quad (q)
- case 8: // absolute quad (Q)
- dstr += seg.x1 + ',' + seg.y1 + ' ' + seg.x + ',' + seg.y + ' ';
- break;
- case 11: // relative elliptical arc (a)
- case 10: // absolute elliptical arc (A)
- dstr += seg.r1 + ',' + seg.r2 + ' ' + seg.angle + ' ' + (+seg.largeArcFlag) +
- ' ' + (+seg.sweepFlag) + ' ' + seg.x + ',' + seg.y + ' ';
- break;
- case 17: // relative smooth cubic (s)
- case 16: // absolute smooth cubic (S)
- dstr += seg.x2 + ',' + seg.y2 + ' ' + seg.x + ',' + seg.y + ' ';
- break;
- }
- }
+ var dstr = '';
+ len = changes.d.length;
+ for (i = 0; i < len; ++i) {
+ seg = changes.d[i];
+ type = seg.type;
+ dstr += pathMap[type];
+ switch (type) {
+ case 13: // relative horizontal line (h)
+ case 12: // absolute horizontal line (H)
+ dstr += seg.x + ' ';
+ break;
+ case 15: // relative vertical line (v)
+ case 14: // absolute vertical line (V)
+ dstr += seg.y + ' ';
+ break;
+ case 3: // relative move (m)
+ case 5: // relative line (l)
+ case 19: // relative smooth quad (t)
+ case 2: // absolute move (M)
+ case 4: // absolute line (L)
+ case 18: // absolute smooth quad (T)
+ dstr += seg.x + ',' + seg.y + ' ';
+ break;
+ case 7: // relative cubic (c)
+ case 6: // absolute cubic (C)
+ dstr += seg.x1 + ',' + seg.y1 + ' ' + seg.x2 + ',' + seg.y2 + ' ' +
+ seg.x + ',' + seg.y + ' ';
+ break;
+ case 9: // relative quad (q)
+ case 8: // absolute quad (Q)
+ dstr += seg.x1 + ',' + seg.y1 + ' ' + seg.x + ',' + seg.y + ' ';
+ break;
+ case 11: // relative elliptical arc (a)
+ case 10: // absolute elliptical arc (A)
+ dstr += seg.r1 + ',' + seg.r2 + ' ' + seg.angle + ' ' + (+seg.largeArcFlag) +
+ ' ' + (+seg.sweepFlag) + ' ' + seg.x + ',' + seg.y + ' ';
+ break;
+ case 17: // relative smooth cubic (s)
+ case 16: // absolute smooth cubic (S)
+ dstr += seg.x2 + ',' + seg.y2 + ' ' + seg.x + ',' + seg.y + ' ';
+ break;
+ }
+ }
- selected.setAttribute('d', dstr);
- break;
- }
+ selected.setAttribute('d', dstr);
+ break;
+ }
};
}());
diff --git a/editor/draw.js b/editor/draw.js
index 9799cd9f..7080b9f0 100644
--- a/editor/draw.js
+++ b/editor/draw.js
@@ -17,7 +17,7 @@
'use strict';
if (!svgedit.draw) {
- svgedit.draw = {};
+ svgedit.draw = {};
}
// alias
var NS = svgedit.NS;
@@ -25,9 +25,9 @@ var NS = svgedit.NS;
var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'.split(',');
var RandomizeModes = {
- LET_DOCUMENT_DECIDE: 0,
- ALWAYS_RANDOMIZE: 1,
- NEVER_RANDOMIZE: 2
+ LET_DOCUMENT_DECIDE: 0,
+ ALWAYS_RANDOMIZE: 1,
+ NEVER_RANDOMIZE: 2
};
var randomizeIds = RandomizeModes.LET_DOCUMENT_DECIDE;
@@ -38,15 +38,15 @@ var randomizeIds = RandomizeModes.LET_DOCUMENT_DECIDE;
* @param {svgedit.draw.Drawing} currentDrawing
*/
svgedit.draw.randomizeIds = function (enableRandomization, currentDrawing) {
- randomizeIds = enableRandomization === false
- ? RandomizeModes.NEVER_RANDOMIZE
- : RandomizeModes.ALWAYS_RANDOMIZE;
+ randomizeIds = enableRandomization === false
+ ? RandomizeModes.NEVER_RANDOMIZE
+ : RandomizeModes.ALWAYS_RANDOMIZE;
- if (randomizeIds === RandomizeModes.ALWAYS_RANDOMIZE && !currentDrawing.getNonce()) {
- currentDrawing.setNonce(Math.floor(Math.random() * 100001));
- } else if (randomizeIds === RandomizeModes.NEVER_RANDOMIZE && currentDrawing.getNonce()) {
- currentDrawing.clearNonce();
- }
+ if (randomizeIds === RandomizeModes.ALWAYS_RANDOMIZE && !currentDrawing.getNonce()) {
+ currentDrawing.setNonce(Math.floor(Math.random() * 100001));
+ } else if (randomizeIds === RandomizeModes.NEVER_RANDOMIZE && currentDrawing.getNonce()) {
+ currentDrawing.clearNonce();
+ }
};
/**
@@ -57,72 +57,72 @@ svgedit.draw.randomizeIds = function (enableRandomization, currentDrawing) {
* @param {String=svg_} [optIdPrefix] - The ID prefix to use.
*/
svgedit.draw.Drawing = function (svgElem, optIdPrefix) {
- if (!svgElem || !svgElem.tagName || !svgElem.namespaceURI ||
- svgElem.tagName !== 'svg' || svgElem.namespaceURI !== NS.SVG) {
- throw new Error('Error: svgedit.draw.Drawing instance initialized without a element');
- }
+ if (!svgElem || !svgElem.tagName || !svgElem.namespaceURI ||
+ svgElem.tagName !== 'svg' || svgElem.namespaceURI !== NS.SVG) {
+ throw new Error('Error: svgedit.draw.Drawing instance initialized without a element');
+ }
- /**
- * The SVG DOM Element that represents this drawing.
- * @type {SVGSVGElement}
- */
- this.svgElem_ = svgElem;
+ /**
+ * The SVG DOM Element that represents this drawing.
+ * @type {SVGSVGElement}
+ */
+ this.svgElem_ = svgElem;
- /**
- * The latest object number used in this drawing.
- * @type {number}
- */
- this.obj_num = 0;
+ /**
+ * The latest object number used in this drawing.
+ * @type {number}
+ */
+ this.obj_num = 0;
- /**
- * The prefix to prepend to each element id in the drawing.
- * @type {String}
- */
- this.idPrefix = optIdPrefix || 'svg_';
+ /**
+ * The prefix to prepend to each element id in the drawing.
+ * @type {String}
+ */
+ this.idPrefix = optIdPrefix || 'svg_';
- /**
- * An array of released element ids to immediately reuse.
- * @type {Array.}
- */
- this.releasedNums = [];
+ /**
+ * An array of released element ids to immediately reuse.
+ * @type {Array.}
+ */
+ this.releasedNums = [];
- /**
- * The z-ordered array of Layer objects. Each layer has a name
- * and group element.
- * The first layer is the one at the bottom of the rendering.
- * @type {Array.}
- */
- this.all_layers = [];
+ /**
+ * The z-ordered array of Layer objects. Each layer has a name
+ * and group element.
+ * The first layer is the one at the bottom of the rendering.
+ * @type {Array.}
+ */
+ this.all_layers = [];
- /**
- * Map of all_layers by name.
- *
- * Note: Layers are ordered, but referenced externally by name; so, we need both container
- * types depending on which function is called (i.e. all_layers and layer_map).
- *
- * @type {Object.}
- */
- this.layer_map = {};
+ /**
+ * Map of all_layers by name.
+ *
+ * Note: Layers are ordered, but referenced externally by name; so, we need both container
+ * types depending on which function is called (i.e. all_layers and layer_map).
+ *
+ * @type {Object.}
+ */
+ this.layer_map = {};
- /**
- * The current layer being used.
- * @type {Layer}
- */
- this.current_layer = null;
+ /**
+ * The current layer being used.
+ * @type {Layer}
+ */
+ this.current_layer = null;
- /**
- * The nonce to use to uniquely identify elements across drawings.
- * @type {!String}
- */
- this.nonce_ = '';
- var n = this.svgElem_.getAttributeNS(NS.SE, 'nonce');
- // If already set in the DOM, use the nonce throughout the document
- // else, if randomizeIds(true) has been called, create and set the nonce.
- if (!!n && randomizeIds !== RandomizeModes.NEVER_RANDOMIZE) {
- this.nonce_ = n;
- } else if (randomizeIds === RandomizeModes.ALWAYS_RANDOMIZE) {
- this.setNonce(Math.floor(Math.random() * 100001));
- }
+ /**
+ * The nonce to use to uniquely identify elements across drawings.
+ * @type {!String}
+ */
+ this.nonce_ = '';
+ var n = this.svgElem_.getAttributeNS(NS.SE, 'nonce');
+ // If already set in the DOM, use the nonce throughout the document
+ // else, if randomizeIds(true) has been called, create and set the nonce.
+ if (!!n && randomizeIds !== RandomizeModes.NEVER_RANDOMIZE) {
+ this.nonce_ = n;
+ } else if (randomizeIds === RandomizeModes.ALWAYS_RANDOMIZE) {
+ this.setNonce(Math.floor(Math.random() * 100001));
+ }
};
/**
@@ -130,44 +130,44 @@ svgedit.draw.Drawing = function (svgElem, optIdPrefix) {
* @returns {Element} SVG element within the root SVGSVGElement
*/
svgedit.draw.Drawing.prototype.getElem_ = function (id) {
- if (this.svgElem_.querySelector) {
- // querySelector lookup
- return this.svgElem_.querySelector('#' + id);
- }
- // jQuery lookup: twice as slow as xpath in FF
- return $(this.svgElem_).find('[id=' + id + ']')[0];
+ if (this.svgElem_.querySelector) {
+ // querySelector lookup
+ return this.svgElem_.querySelector('#' + id);
+ }
+ // jQuery lookup: twice as slow as xpath in FF
+ return $(this.svgElem_).find('[id=' + id + ']')[0];
};
/**
* @returns {SVGSVGElement}
*/
svgedit.draw.Drawing.prototype.getSvgElem = function () {
- return this.svgElem_;
+ return this.svgElem_;
};
/**
* @returns {!string|number} The previously set nonce
*/
svgedit.draw.Drawing.prototype.getNonce = function () {
- return this.nonce_;
+ return this.nonce_;
};
/**
* @param {!string|number} n The nonce to set
*/
svgedit.draw.Drawing.prototype.setNonce = function (n) {
- this.svgElem_.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
- this.svgElem_.setAttributeNS(NS.SE, 'se:nonce', n);
- this.nonce_ = n;
+ this.svgElem_.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
+ this.svgElem_.setAttributeNS(NS.SE, 'se:nonce', n);
+ this.nonce_ = n;
};
/**
* Clears any previously set nonce
*/
svgedit.draw.Drawing.prototype.clearNonce = function () {
- // We deliberately leave any se:nonce attributes alone,
- // we just don't use it to randomize ids.
- this.nonce_ = '';
+ // We deliberately leave any se:nonce attributes alone,
+ // we just don't use it to randomize ids.
+ this.nonce_ = '';
};
/**
@@ -175,9 +175,9 @@ svgedit.draw.Drawing.prototype.clearNonce = function () {
* @return {String} The latest object Id.
*/
svgedit.draw.Drawing.prototype.getId = function () {
- return this.nonce_
- ? this.idPrefix + this.nonce_ + '_' + this.obj_num
- : this.idPrefix + this.obj_num;
+ return this.nonce_
+ ? this.idPrefix + this.nonce_ + '_' + this.obj_num
+ : this.idPrefix + this.obj_num;
};
/**
@@ -185,35 +185,35 @@ svgedit.draw.Drawing.prototype.getId = function () {
* @return {String} The next object Id to use.
*/
svgedit.draw.Drawing.prototype.getNextId = function () {
- var oldObjNum = this.obj_num;
- var restoreOldObjNum = false;
+ var oldObjNum = this.obj_num;
+ var restoreOldObjNum = false;
- // If there are any released numbers in the release stack,
- // use the last one instead of the next obj_num.
- // We need to temporarily use obj_num as that is what getId() depends on.
- if (this.releasedNums.length > 0) {
- this.obj_num = this.releasedNums.pop();
- restoreOldObjNum = true;
- } else {
- // If we are not using a released id, then increment the obj_num.
- this.obj_num++;
- }
+ // If there are any released numbers in the release stack,
+ // use the last one instead of the next obj_num.
+ // We need to temporarily use obj_num as that is what getId() depends on.
+ if (this.releasedNums.length > 0) {
+ this.obj_num = this.releasedNums.pop();
+ restoreOldObjNum = true;
+ } else {
+ // If we are not using a released id, then increment the obj_num.
+ this.obj_num++;
+ }
- // Ensure the ID does not exist.
- var id = this.getId();
- while (this.getElem_(id)) {
- if (restoreOldObjNum) {
- this.obj_num = oldObjNum;
- restoreOldObjNum = false;
- }
- this.obj_num++;
- id = this.getId();
- }
- // Restore the old object number if required.
- if (restoreOldObjNum) {
- this.obj_num = oldObjNum;
- }
- return id;
+ // Ensure the ID does not exist.
+ var id = this.getId();
+ while (this.getElem_(id)) {
+ if (restoreOldObjNum) {
+ this.obj_num = oldObjNum;
+ restoreOldObjNum = false;
+ }
+ this.obj_num++;
+ id = this.getId();
+ }
+ // Restore the old object number if required.
+ if (restoreOldObjNum) {
+ this.obj_num = oldObjNum;
+ }
+ return id;
};
/**
@@ -224,24 +224,24 @@ svgedit.draw.Drawing.prototype.getNextId = function () {
* @returns {boolean} True if the id was valid to be released, false otherwise.
*/
svgedit.draw.Drawing.prototype.releaseId = function (id) {
- // confirm if this is a valid id for this Document, else return false
- var front = this.idPrefix + (this.nonce_ ? this.nonce_ + '_' : '');
- if (typeof id !== 'string' || id.indexOf(front) !== 0) {
- return false;
- }
- // extract the obj_num of this id
- var num = parseInt(id.substr(front.length), 10);
+ // confirm if this is a valid id for this Document, else return false
+ var front = this.idPrefix + (this.nonce_ ? this.nonce_ + '_' : '');
+ if (typeof id !== 'string' || id.indexOf(front) !== 0) {
+ return false;
+ }
+ // extract the obj_num of this id
+ var num = parseInt(id.substr(front.length), 10);
- // if we didn't get a positive number or we already released this number
- // then return false.
- if (typeof num !== 'number' || num <= 0 || this.releasedNums.indexOf(num) !== -1) {
- return false;
- }
+ // if we didn't get a positive number or we already released this number
+ // then return false.
+ if (typeof num !== 'number' || num <= 0 || this.releasedNums.indexOf(num) !== -1) {
+ return false;
+ }
- // push the released number into the released queue
- this.releasedNums.push(num);
+ // push the released number into the released queue
+ this.releasedNums.push(num);
- return true;
+ return true;
};
/**
@@ -249,7 +249,7 @@ svgedit.draw.Drawing.prototype.releaseId = function (id) {
* @returns {integer} The number of layers in the current drawing.
*/
svgedit.draw.Drawing.prototype.getNumLayers = function () {
- return this.all_layers.length;
+ return this.all_layers.length;
};
/**
@@ -257,7 +257,7 @@ svgedit.draw.Drawing.prototype.getNumLayers = function () {
* @param {string} name - The layer name to check
*/
svgedit.draw.Drawing.prototype.hasLayer = function (name) {
- return this.layer_map[name] !== undefined;
+ return this.layer_map[name] !== undefined;
};
/**
@@ -266,14 +266,14 @@ svgedit.draw.Drawing.prototype.hasLayer = function (name) {
* @returns {string} The name of the ith layer (or the empty string if none found)
*/
svgedit.draw.Drawing.prototype.getLayerName = function (i) {
- return i >= 0 && i < this.getNumLayers() ? this.all_layers[i].getName() : '';
+ return i >= 0 && i < this.getNumLayers() ? this.all_layers[i].getName() : '';
};
/**
* @returns {SVGGElement} The SVGGElement representing the current layer.
*/
svgedit.draw.Drawing.prototype.getCurrentLayer = function () {
- return this.current_layer ? this.current_layer.getGroup() : null;
+ return this.current_layer ? this.current_layer.getGroup() : null;
};
/**
@@ -281,8 +281,8 @@ svgedit.draw.Drawing.prototype.getCurrentLayer = function () {
* @returns {SVGGElement} The SVGGElement representing the named layer or null.
*/
svgedit.draw.Drawing.prototype.getLayerByName = function (name) {
- var layer = this.layer_map[name];
- return layer ? layer.getGroup() : null;
+ var layer = this.layer_map[name];
+ return layer ? layer.getGroup() : null;
};
/**
@@ -291,7 +291,7 @@ svgedit.draw.Drawing.prototype.getLayerByName = function (name) {
* @returns {string} The name of the currently active layer (or the empty string if none found).
*/
svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
- return this.current_layer ? this.current_layer.getName() : '';
+ return this.current_layer ? this.current_layer.getName() : '';
};
/**
@@ -301,16 +301,16 @@ svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
* @returns {string|null} The new name if changed; otherwise, null.
*/
svgedit.draw.Drawing.prototype.setCurrentLayerName = function (name, hrService) {
- var finalName = null;
- if (this.current_layer) {
- var oldName = this.current_layer.getName();
- finalName = this.current_layer.setName(name, hrService);
- if (finalName) {
- delete this.layer_map[oldName];
- this.layer_map[finalName] = this.current_layer;
- }
- }
- return finalName;
+ var finalName = null;
+ if (this.current_layer) {
+ var oldName = this.current_layer.getName();
+ finalName = this.current_layer.setName(name, hrService);
+ if (finalName) {
+ delete this.layer_map[oldName];
+ this.layer_map[finalName] = this.current_layer;
+ }
+ }
+ return finalName;
};
/**
@@ -319,89 +319,89 @@ svgedit.draw.Drawing.prototype.setCurrentLayerName = function (name, hrService)
* @returns {Object} If the name was changed, returns {title:SVGGElement, previousName:string}; otherwise null.
*/
svgedit.draw.Drawing.prototype.setCurrentLayerPosition = function (newpos) {
- var layerCount = this.getNumLayers();
- if (!this.current_layer || newpos < 0 || newpos >= layerCount) {
- return null;
- }
+ var layerCount = this.getNumLayers();
+ if (!this.current_layer || newpos < 0 || newpos >= layerCount) {
+ return null;
+ }
- var oldpos;
- for (oldpos = 0; oldpos < layerCount; ++oldpos) {
- if (this.all_layers[oldpos] === this.current_layer) { break; }
- }
- // some unknown error condition (current_layer not in all_layers)
- if (oldpos === layerCount) { return null; }
+ var oldpos;
+ for (oldpos = 0; oldpos < layerCount; ++oldpos) {
+ if (this.all_layers[oldpos] === this.current_layer) { break; }
+ }
+ // some unknown error condition (current_layer not in all_layers)
+ if (oldpos === layerCount) { return null; }
- if (oldpos !== newpos) {
- // if our new position is below us, we need to insert before the node after newpos
- var refGroup = null;
- var currentGroup = this.current_layer.getGroup();
- var oldNextSibling = currentGroup.nextSibling;
- if (newpos > oldpos) {
- if (newpos < layerCount - 1) {
- refGroup = this.all_layers[newpos + 1].getGroup();
- }
- // if our new position is above us, we need to insert before the node at newpos
- } else {
- refGroup = this.all_layers[newpos].getGroup();
- }
- this.svgElem_.insertBefore(currentGroup, refGroup);
+ if (oldpos !== newpos) {
+ // if our new position is below us, we need to insert before the node after newpos
+ var refGroup = null;
+ var currentGroup = this.current_layer.getGroup();
+ var oldNextSibling = currentGroup.nextSibling;
+ if (newpos > oldpos) {
+ if (newpos < layerCount - 1) {
+ refGroup = this.all_layers[newpos + 1].getGroup();
+ }
+ // if our new position is above us, we need to insert before the node at newpos
+ } else {
+ refGroup = this.all_layers[newpos].getGroup();
+ }
+ this.svgElem_.insertBefore(currentGroup, refGroup);
- this.identifyLayers();
- this.setCurrentLayer(this.getLayerName(newpos));
+ this.identifyLayers();
+ this.setCurrentLayer(this.getLayerName(newpos));
- return {
- currentGroup: currentGroup,
- oldNextSibling: oldNextSibling
- };
- }
- return null;
+ return {
+ currentGroup: currentGroup,
+ oldNextSibling: oldNextSibling
+ };
+ }
+ return null;
};
svgedit.draw.Drawing.prototype.mergeLayer = function (hrService) {
- var currentGroup = this.current_layer.getGroup();
- var prevGroup = $(currentGroup).prev()[0];
- if (!prevGroup) { return; }
+ var currentGroup = this.current_layer.getGroup();
+ var prevGroup = $(currentGroup).prev()[0];
+ if (!prevGroup) { return; }
- hrService.startBatchCommand('Merge Layer');
+ hrService.startBatchCommand('Merge Layer');
- var layerNextSibling = currentGroup.nextSibling;
- hrService.removeElement(currentGroup, layerNextSibling, this.svgElem_);
+ var layerNextSibling = currentGroup.nextSibling;
+ hrService.removeElement(currentGroup, layerNextSibling, this.svgElem_);
- while (currentGroup.firstChild) {
- var child = currentGroup.firstChild;
- if (child.localName === 'title') {
- hrService.removeElement(child, child.nextSibling, currentGroup);
- currentGroup.removeChild(child);
- continue;
- }
- var oldNextSibling = child.nextSibling;
- prevGroup.appendChild(child);
- hrService.moveElement(child, oldNextSibling, currentGroup);
- }
+ while (currentGroup.firstChild) {
+ var child = currentGroup.firstChild;
+ if (child.localName === 'title') {
+ hrService.removeElement(child, child.nextSibling, currentGroup);
+ currentGroup.removeChild(child);
+ continue;
+ }
+ var oldNextSibling = child.nextSibling;
+ prevGroup.appendChild(child);
+ hrService.moveElement(child, oldNextSibling, currentGroup);
+ }
- // Remove current layer's group
- this.current_layer.removeGroup();
- // Remove the current layer and set the previous layer as the new current layer
- var index = this.all_layers.indexOf(this.current_layer);
- if (index > 0) {
- var name = this.current_layer.getName();
- this.current_layer = this.all_layers[index - 1];
- this.all_layers.splice(index, 1);
- delete this.layer_map[name];
- }
+ // Remove current layer's group
+ this.current_layer.removeGroup();
+ // Remove the current layer and set the previous layer as the new current layer
+ var index = this.all_layers.indexOf(this.current_layer);
+ if (index > 0) {
+ var name = this.current_layer.getName();
+ this.current_layer = this.all_layers[index - 1];
+ this.all_layers.splice(index, 1);
+ delete this.layer_map[name];
+ }
- hrService.endBatchCommand();
+ hrService.endBatchCommand();
};
svgedit.draw.Drawing.prototype.mergeAllLayers = function (hrService) {
- // Set the current layer to the last layer.
- this.current_layer = this.all_layers[this.all_layers.length - 1];
+ // Set the current layer to the last layer.
+ this.current_layer = this.all_layers[this.all_layers.length - 1];
- hrService.startBatchCommand('Merge all Layers');
- while (this.all_layers.length > 1) {
- this.mergeLayer(hrService);
- }
- hrService.endBatchCommand();
+ hrService.startBatchCommand('Merge all Layers');
+ while (this.all_layers.length > 1) {
+ this.mergeLayer(hrService);
+ }
+ hrService.endBatchCommand();
};
/**
@@ -412,16 +412,16 @@ svgedit.draw.Drawing.prototype.mergeAllLayers = function (hrService) {
* @returns {boolean} true if the current layer was switched, otherwise false
*/
svgedit.draw.Drawing.prototype.setCurrentLayer = function (name) {
- var layer = this.layer_map[name];
- if (layer) {
- if (this.current_layer) {
- this.current_layer.deactivate();
- }
- this.current_layer = layer;
- this.current_layer.activate();
- return true;
- }
- return false;
+ var layer = this.layer_map[name];
+ if (layer) {
+ if (this.current_layer) {
+ this.current_layer.deactivate();
+ }
+ this.current_layer = layer;
+ this.current_layer.activate();
+ return true;
+ }
+ return false;
};
/**
@@ -430,12 +430,12 @@ svgedit.draw.Drawing.prototype.setCurrentLayer = function (name) {
* @returns {SVGGElement} The SVGGElement of the layer removed or null.
*/
svgedit.draw.Drawing.prototype.deleteCurrentLayer = function () {
- if (this.current_layer && this.getNumLayers() > 1) {
- var oldLayerGroup = this.current_layer.removeGroup();
- this.identifyLayers();
- return oldLayerGroup;
- }
- return null;
+ if (this.current_layer && this.getNumLayers() > 1) {
+ var oldLayerGroup = this.current_layer.removeGroup();
+ this.identifyLayers();
+ return oldLayerGroup;
+ }
+ return null;
};
/**
@@ -444,13 +444,13 @@ svgedit.draw.Drawing.prototype.deleteCurrentLayer = function () {
* @returns {string} The layer name or empty string.
*/
function findLayerNameInGroup (group) {
- var name = $('title', group).text();
+ var name = $('title', group).text();
- // Hack for Opera 10.60
- if (!name && svgedit.browser.isOpera() && group.querySelectorAll) {
- name = $(group.querySelectorAll('title')).text();
- }
- return name;
+ // Hack for Opera 10.60
+ if (!name && svgedit.browser.isOpera() && group.querySelectorAll) {
+ name = $(group.querySelectorAll('title')).text();
+ }
+ return name;
}
/**
@@ -459,10 +459,10 @@ function findLayerNameInGroup (group) {
* @returns {string} - The new name.
*/
function getNewLayerName (existingLayerNames) {
- var i = 1;
- // TODO(codedread): What about internationalization of "Layer"?
- while (existingLayerNames.indexOf(('Layer ' + i)) >= 0) { i++; }
- return 'Layer ' + i;
+ var i = 1;
+ // TODO(codedread): What about internationalization of "Layer"?
+ while (existingLayerNames.indexOf(('Layer ' + i)) >= 0) { i++; }
+ return 'Layer ' + i;
}
/**
@@ -470,46 +470,46 @@ function getNewLayerName (existingLayerNames) {
* top-most layer (last child of this drawing).
*/
svgedit.draw.Drawing.prototype.identifyLayers = function () {
- this.all_layers = [];
- this.layer_map = {};
- var numchildren = this.svgElem_.childNodes.length;
- // loop through all children of SVG element
- var orphans = [], layernames = [];
- var layer = null;
- var childgroups = false;
- for (var i = 0; i < numchildren; ++i) {
- var child = this.svgElem_.childNodes.item(i);
- // for each g, find its layer name
- if (child && child.nodeType === 1) {
- if (child.tagName === 'g') {
- childgroups = true;
- var name = findLayerNameInGroup(child);
- if (name) {
- layernames.push(name);
- layer = new svgedit.draw.Layer(name, child);
- this.all_layers.push(layer);
- this.layer_map[name] = layer;
- } else {
- // if group did not have a name, it is an orphan
- orphans.push(child);
- }
- } else if (~visElems.indexOf(child.nodeName)) {
- // Child is "visible" (i.e. not a or element), so it is an orphan
- orphans.push(child);
- }
- }
- }
+ this.all_layers = [];
+ this.layer_map = {};
+ var numchildren = this.svgElem_.childNodes.length;
+ // loop through all children of SVG element
+ var orphans = [], layernames = [];
+ var layer = null;
+ var childgroups = false;
+ for (var i = 0; i < numchildren; ++i) {
+ var child = this.svgElem_.childNodes.item(i);
+ // for each g, find its layer name
+ if (child && child.nodeType === 1) {
+ if (child.tagName === 'g') {
+ childgroups = true;
+ var name = findLayerNameInGroup(child);
+ if (name) {
+ layernames.push(name);
+ layer = new svgedit.draw.Layer(name, child);
+ this.all_layers.push(layer);
+ this.layer_map[name] = layer;
+ } else {
+ // if group did not have a name, it is an orphan
+ orphans.push(child);
+ }
+ } else if (~visElems.indexOf(child.nodeName)) {
+ // Child is "visible" (i.e. not a or element), so it is an orphan
+ orphans.push(child);
+ }
+ }
+ }
- // If orphans or no layers found, create a new layer and add all the orphans to it
- if (orphans.length > 0 || !childgroups) {
- layer = new svgedit.draw.Layer(getNewLayerName(layernames), null, this.svgElem_);
- layer.appendChildren(orphans);
- this.all_layers.push(layer);
- this.layer_map[name] = layer;
- } else {
- layer.activate();
- }
- this.current_layer = layer;
+ // If orphans or no layers found, create a new layer and add all the orphans to it
+ if (orphans.length > 0 || !childgroups) {
+ layer = new svgedit.draw.Layer(getNewLayerName(layernames), null, this.svgElem_);
+ layer.appendChildren(orphans);
+ this.all_layers.push(layer);
+ this.layer_map[name] = layer;
+ } else {
+ layer.activate();
+ }
+ this.current_layer = layer;
};
/**
@@ -521,27 +521,27 @@ svgedit.draw.Drawing.prototype.identifyLayers = function () {
* also the current layer of this drawing.
*/
svgedit.draw.Drawing.prototype.createLayer = function (name, hrService) {
- if (this.current_layer) {
- this.current_layer.deactivate();
- }
- // Check for duplicate name.
- if (name === undefined || name === null || name === '' || this.layer_map[name]) {
- name = getNewLayerName(Object.keys(this.layer_map));
- }
+ if (this.current_layer) {
+ this.current_layer.deactivate();
+ }
+ // Check for duplicate name.
+ if (name === undefined || name === null || name === '' || this.layer_map[name]) {
+ name = getNewLayerName(Object.keys(this.layer_map));
+ }
- // Crate new layer and add to DOM as last layer
- var layer = new svgedit.draw.Layer(name, null, this.svgElem_);
- // Like to assume hrService exists, but this is backwards compatible with old version of createLayer.
- if (hrService) {
- hrService.startBatchCommand('Create Layer');
- hrService.insertElement(layer.getGroup());
- hrService.endBatchCommand();
- }
+ // Crate new layer and add to DOM as last layer
+ var layer = new svgedit.draw.Layer(name, null, this.svgElem_);
+ // Like to assume hrService exists, but this is backwards compatible with old version of createLayer.
+ if (hrService) {
+ hrService.startBatchCommand('Create Layer');
+ hrService.insertElement(layer.getGroup());
+ hrService.endBatchCommand();
+ }
- this.all_layers.push(layer);
- this.layer_map[name] = layer;
- this.current_layer = layer;
- return layer.getGroup();
+ this.all_layers.push(layer);
+ this.layer_map[name] = layer;
+ this.current_layer = layer;
+ return layer.getGroup();
};
/**
@@ -552,43 +552,43 @@ svgedit.draw.Drawing.prototype.createLayer = function (name, hrService) {
* also the current layer of this drawing.
*/
svgedit.draw.Drawing.prototype.cloneLayer = function (name, hrService) {
- if (!this.current_layer) { return null; }
- this.current_layer.deactivate();
- // Check for duplicate name.
- if (name === undefined || name === null || name === '' || this.layer_map[name]) {
- name = getNewLayerName(Object.keys(this.layer_map));
- }
+ if (!this.current_layer) { return null; }
+ this.current_layer.deactivate();
+ // Check for duplicate name.
+ if (name === undefined || name === null || name === '' || this.layer_map[name]) {
+ name = getNewLayerName(Object.keys(this.layer_map));
+ }
- // Create new group and add to DOM just after current_layer
- var currentGroup = this.current_layer.getGroup();
- var layer = new svgedit.draw.Layer(name, currentGroup, this.svgElem_);
- var group = layer.getGroup();
+ // Create new group and add to DOM just after current_layer
+ var currentGroup = this.current_layer.getGroup();
+ var layer = new svgedit.draw.Layer(name, currentGroup, this.svgElem_);
+ var group = layer.getGroup();
- // Clone children
- var children = currentGroup.childNodes;
- var index;
- for (index = 0; index < children.length; index++) {
- var ch = children[index];
- if (ch.localName === 'title') { continue; }
- group.appendChild(this.copyElem(ch));
- }
+ // Clone children
+ var children = currentGroup.childNodes;
+ var index;
+ for (index = 0; index < children.length; index++) {
+ var ch = children[index];
+ if (ch.localName === 'title') { continue; }
+ group.appendChild(this.copyElem(ch));
+ }
- if (hrService) {
- hrService.startBatchCommand('Duplicate Layer');
- hrService.insertElement(group);
- hrService.endBatchCommand();
- }
+ if (hrService) {
+ hrService.startBatchCommand('Duplicate Layer');
+ hrService.insertElement(group);
+ hrService.endBatchCommand();
+ }
- // Update layer containers and current_layer.
- index = this.all_layers.indexOf(this.current_layer);
- if (index >= 0) {
- this.all_layers.splice(index + 1, 0, layer);
- } else {
- this.all_layers.push(layer);
- }
- this.layer_map[name] = layer;
- this.current_layer = layer;
- return group;
+ // Update layer containers and current_layer.
+ index = this.all_layers.indexOf(this.current_layer);
+ if (index >= 0) {
+ this.all_layers.splice(index + 1, 0, layer);
+ } else {
+ this.all_layers.push(layer);
+ }
+ this.layer_map[name] = layer;
+ this.current_layer = layer;
+ return group;
};
/**
@@ -598,8 +598,8 @@ svgedit.draw.Drawing.prototype.cloneLayer = function (name, hrService) {
* @returns {boolean} The visibility state of the layer, or false if the layer name was invalid.
*/
svgedit.draw.Drawing.prototype.getLayerVisibility = function (layername) {
- var layer = this.layer_map[layername];
- return layer ? layer.isVisible() : false;
+ var layer = this.layer_map[layername];
+ return layer ? layer.isVisible() : false;
};
/**
@@ -612,13 +612,13 @@ svgedit.draw.Drawing.prototype.getLayerVisibility = function (layername) {
* layername was valid, otherwise null.
*/
svgedit.draw.Drawing.prototype.setLayerVisibility = function (layername, bVisible) {
- if (typeof bVisible !== 'boolean') {
- return null;
- }
- var layer = this.layer_map[layername];
- if (!layer) { return null; }
- layer.setVisible(bVisible);
- return layer.getGroup();
+ if (typeof bVisible !== 'boolean') {
+ return null;
+ }
+ var layer = this.layer_map[layername];
+ if (!layer) { return null; }
+ layer.setVisible(bVisible);
+ return layer.getGroup();
};
/**
@@ -628,9 +628,9 @@ svgedit.draw.Drawing.prototype.setLayerVisibility = function (layername, bVisibl
* if layername is not a valid layer
*/
svgedit.draw.Drawing.prototype.getLayerOpacity = function (layername) {
- var layer = this.layer_map[layername];
- if (!layer) { return null; }
- return layer.getOpacity();
+ var layer = this.layer_map[layername];
+ if (!layer) { return null; }
+ return layer.getOpacity();
};
/**
@@ -641,13 +641,13 @@ svgedit.draw.Drawing.prototype.getLayerOpacity = function (layername) {
* @param {number} opacity - A float value in the range 0.0-1.0
*/
svgedit.draw.Drawing.prototype.setLayerOpacity = function (layername, opacity) {
- if (typeof opacity !== 'number' || opacity < 0.0 || opacity > 1.0) {
- return;
- }
- var layer = this.layer_map[layername];
- if (layer) {
- layer.setOpacity(opacity);
- }
+ if (typeof opacity !== 'number' || opacity < 0.0 || opacity > 1.0) {
+ return;
+ }
+ var layer = this.layer_map[layername];
+ if (layer) {
+ layer.setOpacity(opacity);
+ }
};
/**
@@ -656,8 +656,8 @@ svgedit.draw.Drawing.prototype.setLayerOpacity = function (layername, opacity) {
* @returns {Element}
*/
svgedit.draw.Drawing.prototype.copyElem = function (el) {
- var self = this;
- var getNextIdClosure = function () { return self.getNextId(); };
- return svgedit.utilities.copyElem(el, getNextIdClosure);
+ var self = this;
+ var getNextIdClosure = function () { return self.getNextId(); };
+ return svgedit.utilities.copyElem(el, getNextIdClosure);
};
}());
diff --git a/editor/embedapi-dom.js b/editor/embedapi-dom.js
index 098912df..33c661ff 100644
--- a/editor/embedapi-dom.js
+++ b/editor/embedapi-dom.js
@@ -5,76 +5,76 @@ var initEmbed; // eslint-disable-line no-unused-vars
// Todo: Get rid of frame.contentWindow dependencies so can be more easily adjusted to work cross-domain
$(function () {
- 'use strict';
+ 'use strict';
- var svgCanvas = null;
- var frame;
+ var svgCanvas = null;
+ var frame;
- initEmbed = function () {
- var doc, mainButton;
- svgCanvas = new EmbeddedSVGEdit(frame);
- // Hide main button, as we will be controlling new, load, save, etc. from the host document
- doc = frame.contentDocument || frame.contentWindow.document;
- mainButton = doc.getElementById('main_button');
- mainButton.style.display = 'none';
- };
+ initEmbed = function () {
+ var doc, mainButton;
+ svgCanvas = new EmbeddedSVGEdit(frame);
+ // Hide main button, as we will be controlling new, load, save, etc. from the host document
+ doc = frame.contentDocument || frame.contentWindow.document;
+ mainButton = doc.getElementById('main_button');
+ mainButton.style.display = 'none';
+ };
- function handleSvgData (data, error) {
- if (error) {
- alert('error ' + error);
- } else {
- alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
- }
- }
+ function handleSvgData (data, error) {
+ if (error) {
+ alert('error ' + error);
+ } else {
+ alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
+ }
+ }
- function loadSvg () {
- var svgexample = 'Layer 1 ';
- svgCanvas.setSvgString(svgexample);
- }
+ function loadSvg () {
+ var svgexample = 'Layer 1 ';
+ svgCanvas.setSvgString(svgexample);
+ }
- function saveSvg () {
- svgCanvas.getSvgString()(handleSvgData);
- }
+ function saveSvg () {
+ svgCanvas.getSvgString()(handleSvgData);
+ }
- function exportPNG () {
- var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
+ function exportPNG () {
+ var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
- var exportWindow = window.open(
- 'data:text/html;charset=utf-8,' + encodeURIComponent('' + str + ' ' + str + ' '),
- 'svg-edit-exportWindow'
- );
- svgCanvas.rasterExport('PNG', null, exportWindow.name);
- }
+ var exportWindow = window.open(
+ 'data:text/html;charset=utf-8,' + encodeURIComponent('' + str + ' ' + str + ' '),
+ 'svg-edit-exportWindow'
+ );
+ svgCanvas.rasterExport('PNG', null, exportWindow.name);
+ }
- function exportPDF () {
- var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
+ function exportPDF () {
+ var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
- /**
- // If you want to handle the PDF blob yourself, do as follows
- svgCanvas.bind('exportedPDF', function (win, data) {
- alert(data.dataurlstring);
- });
- svgCanvas.exportPDF(); // Accepts two args: optionalWindowName supplied back to bound exportPDF handler and optionalOutputType (defaults to dataurlstring)
- return;
- */
+ /**
+ // If you want to handle the PDF blob yourself, do as follows
+ svgCanvas.bind('exportedPDF', function (win, data) {
+ alert(data.dataurlstring);
+ });
+ svgCanvas.exportPDF(); // Accepts two args: optionalWindowName supplied back to bound exportPDF handler and optionalOutputType (defaults to dataurlstring)
+ return;
+ */
- var exportWindow = window.open(
- 'data:text/html;charset=utf-8,' + encodeURIComponent('' + str + ' ' + str + ' '),
- 'svg-edit-exportWindow'
- );
- svgCanvas.exportPDF(exportWindow.name);
- }
+ var exportWindow = window.open(
+ 'data:text/html;charset=utf-8,' + encodeURIComponent('' + str + ' ' + str + ' '),
+ 'svg-edit-exportWindow'
+ );
+ svgCanvas.exportPDF(exportWindow.name);
+ }
- // Add event handlers
- $('#load').click(loadSvg);
- $('#save').click(saveSvg);
- $('#exportPNG').click(exportPNG);
- $('#exportPDF').click(exportPDF);
- $('body').append(
- $(''
- )
- );
- frame = document.getElementById('svgedit');
+ // Add event handlers
+ $('#load').click(loadSvg);
+ $('#save').click(saveSvg);
+ $('#exportPNG').click(exportPNG);
+ $('#exportPDF').click(exportPDF);
+ $('body').append(
+ $(''
+ )
+ );
+ frame = document.getElementById('svgedit');
});
diff --git a/editor/embedapi.html b/editor/embedapi.html
index 04e176a4..95f45572 100644
--- a/editor/embedapi.html
+++ b/editor/embedapi.html
@@ -1,17 +1,17 @@
-
- Embed API
-
-
-
+
+ Embed API
+
+
+
- Load example
- Save data
- Export data to PNG
- Export data to PDF
-
+ Load example
+ Save data
+ Export data to PNG
+ Export data to PDF
+
diff --git a/editor/embedapi.js b/editor/embedapi.js
index a996e9b7..af61b41f 100644
--- a/editor/embedapi.js
+++ b/editor/embedapi.js
@@ -10,11 +10,11 @@ var svgCanvas = new EmbeddedSVGEdit(window.frames.svgedit);
svgCanvas.setSvgString('string')
- Or if a callback is needed:
svgCanvas.setSvgString('string')(function(data, error){
- if (error){
- // There was an error
- } else{
- // Handle data
- }
+ if (error){
+ // There was an error
+ } else{
+ // Handle data
+ }
})
Everything is done with the same API as the real svg-edit,
@@ -42,15 +42,15 @@ blah.clearSelection('woot', 'blah', 1337, [1, 2, 3, 4, 5, 'moo'], -42, {a: 'tree
var cbid = 0;
function getCallbackSetter (d) {
- return function () {
- var t = this, // New callback
- args = [].slice.call(arguments),
- cbid = t.send(d, args, function () {}); // The callback (currently it's nothing, but will be set later)
+ return function () {
+ var t = this, // New callback
+ args = [].slice.call(arguments),
+ cbid = t.send(d, args, function () {}); // The callback (currently it's nothing, but will be set later)
- return function (newcallback) {
- t.callbacks[cbid] = newcallback; // Set callback
- };
- };
+ return function (newcallback) {
+ t.callbacks[cbid] = newcallback; // Set callback
+ };
+ };
}
/*
@@ -59,38 +59,38 @@ function getCallbackSetter (d) {
* of same domain control
*/
function addCallback (t, data) {
- var result = data.result || data.error,
- cbid = data.id;
- if (t.callbacks[cbid]) {
- if (data.result) {
- t.callbacks[cbid](result);
- } else {
- t.callbacks[cbid](result, 'error');
- }
- }
+ var result = data.result || data.error,
+ cbid = data.id;
+ if (t.callbacks[cbid]) {
+ if (data.result) {
+ t.callbacks[cbid](result);
+ } else {
+ t.callbacks[cbid](result, 'error');
+ }
+ }
}
function messageListener (e) {
- // We accept and post strings as opposed to objects for the sake of IE9 support; this
- // will most likely be changed in the future
- if (typeof e.data !== 'string') {
- return;
- }
- var allowedOrigins = this.allowedOrigins,
- data = e.data && JSON.parse(e.data);
- if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
- e.source !== this.frame.contentWindow ||
- (allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1)
- ) {
- return;
- }
- addCallback(this, data);
+ // We accept and post strings as opposed to objects for the sake of IE9 support; this
+ // will most likely be changed in the future
+ if (typeof e.data !== 'string') {
+ return;
+ }
+ var allowedOrigins = this.allowedOrigins,
+ data = e.data && JSON.parse(e.data);
+ if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
+ e.source !== this.frame.contentWindow ||
+ (allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1)
+ ) {
+ return;
+ }
+ addCallback(this, data);
}
function getMessageListener (t) {
- return function (e) {
- messageListener.call(t, e);
- };
+ return function (e) {
+ messageListener.call(t, e);
+ };
}
/**
@@ -100,77 +100,77 @@ function getMessageListener (t) {
* If supplied, it should probably be the same as svgEditor's allowedOrigins
*/
function EmbeddedSVGEdit (frame, allowedOrigins) {
- if (!(this instanceof EmbeddedSVGEdit)) { // Allow invocation without 'new' keyword
- return new EmbeddedSVGEdit(frame);
- }
- this.allowedOrigins = allowedOrigins || [];
- // Initialize communication
- this.frame = frame;
- this.callbacks = {};
- // List of functions extracted with this:
- // Run in firebug on http://svg-edit.googlecode.com/svn/trunk/docs/files/svgcanvas-js.html
+ if (!(this instanceof EmbeddedSVGEdit)) { // Allow invocation without 'new' keyword
+ return new EmbeddedSVGEdit(frame);
+ }
+ this.allowedOrigins = allowedOrigins || [];
+ // Initialize communication
+ this.frame = frame;
+ this.callbacks = {};
+ // List of functions extracted with this:
+ // Run in firebug on http://svg-edit.googlecode.com/svn/trunk/docs/files/svgcanvas-js.html
- // for (var i=0,q=[],f = document.querySelectorAll('div.CFunction h3.CTitle a'); i < f.length; i++) { q.push(f[i].name); }; q
- // var functions = ['clearSelection', 'addToSelection', 'removeFromSelection', 'open', 'save', 'getSvgString', 'setSvgString',
- // 'createLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility',
- // 'moveSelectedToLayer', 'clear'];
+ // for (var i=0,q=[],f = document.querySelectorAll('div.CFunction h3.CTitle a'); i < f.length; i++) { q.push(f[i].name); }; q
+ // var functions = ['clearSelection', 'addToSelection', 'removeFromSelection', 'open', 'save', 'getSvgString', 'setSvgString',
+ // 'createLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility',
+ // 'moveSelectedToLayer', 'clear'];
- // Newer, well, it extracts things that aren't documented as well. All functions accessible through the normal thingy can now be accessed though the API
- // var svgCanvas = frame.contentWindow.svgCanvas;
- // var l = []; for (var i in svgCanvas){ if (typeof svgCanvas[i] == 'function') { l.push(i);} };
- // alert("['" + l.join("', '") + "']");
- // Run in svgedit itself
- var i,
- functions = [
- 'clearSvgContentElement', 'setIdPrefix', 'getCurrentDrawing', 'addSvgElementFromJson', 'getTransformList', 'matrixMultiply', 'hasMatrixTransform', 'transformListToTransform', 'convertToNum', 'findDefs', 'getUrlFromAttr', 'getHref', 'setHref', 'getBBox', 'getRotationAngle', 'getElem', 'getRefElem', 'assignAttributes', 'cleanupElement', 'remapElement', 'recalculateDimensions', 'sanitizeSvg', 'runExtensions', 'addExtension', 'round', 'getIntersectionList', 'getStrokedBBox', 'getVisibleElements', 'getVisibleElementsAndBBoxes', 'groupSvgElem', 'getId', 'getNextId', 'call', 'bind', 'prepareSvg', 'setRotationAngle', 'recalculateAllSelectedDimensions', 'clearSelection', 'addToSelection', 'selectOnly', 'removeFromSelection', 'selectAllInCurrentLayer', 'getMouseTarget', 'removeUnusedDefElems', 'svgCanvasToString', 'svgToString', 'embedImage', 'setGoodImage', 'open', 'save', 'rasterExport', 'exportPDF', 'getSvgString', 'randomizeIds', 'uniquifyElems', 'setUseData', 'convertGradients', 'convertToGroup', 'setSvgString', 'importSvgString', 'identifyLayers', 'createLayer', 'cloneLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility', 'moveSelectedToLayer', 'mergeLayer', 'mergeAllLayers', 'leaveContext', 'setContext', 'clear', 'linkControlPoints', 'getContentElem', 'getRootElem', 'getSelectedElems', 'getResolution', 'getZoom', 'getVersion', 'setUiStrings', 'setConfig', 'getTitle', 'setGroupTitle', 'getDocumentTitle', 'setDocumentTitle', 'getEditorNS', 'setResolution', 'getOffset', 'setBBoxZoom', 'setZoom', 'getMode', 'setMode', 'getColor', 'setColor', 'setGradient', 'setPaint', 'setStrokePaint', 'setFillPaint', 'getStrokeWidth', 'setStrokeWidth', 'setStrokeAttr', 'getStyle', 'getOpacity', 'setOpacity', 'getFillOpacity', 'getStrokeOpacity', 'setPaintOpacity', 'getPaintOpacity', 'getBlur', 'setBlurNoUndo', 'setBlurOffsets', 'setBlur', 'getBold', 'setBold', 'getItalic', 'setItalic', 'getFontFamily', 'setFontFamily', 'setFontColor', 'getFontColor', 'getFontSize', 'setFontSize', 'getText', 'setTextContent', 'setImageURL', 'setLinkURL', 'setRectRadius', 'makeHyperlink', 'removeHyperlink', 'setSegType', 'convertToPath', 'changeSelectedAttribute', 'deleteSelectedElements', 'cutSelectedElements', 'copySelectedElements', 'pasteElements', 'groupSelectedElements', 'pushGroupProperties', 'ungroupSelectedElement', 'moveToTopSelectedElement', 'moveToBottomSelectedElement', 'moveUpDownSelected', 'moveSelectedElements', 'cloneSelectedElements', 'alignSelectedElements', 'updateCanvas', 'setBackground', 'cycleElement', 'getPrivateMethods', 'zoomChanged', 'ready'
- ];
+ // Newer, well, it extracts things that aren't documented as well. All functions accessible through the normal thingy can now be accessed though the API
+ // var svgCanvas = frame.contentWindow.svgCanvas;
+ // var l = []; for (var i in svgCanvas){ if (typeof svgCanvas[i] == 'function') { l.push(i);} };
+ // alert("['" + l.join("', '") + "']");
+ // Run in svgedit itself
+ var i,
+ functions = [
+ 'clearSvgContentElement', 'setIdPrefix', 'getCurrentDrawing', 'addSvgElementFromJson', 'getTransformList', 'matrixMultiply', 'hasMatrixTransform', 'transformListToTransform', 'convertToNum', 'findDefs', 'getUrlFromAttr', 'getHref', 'setHref', 'getBBox', 'getRotationAngle', 'getElem', 'getRefElem', 'assignAttributes', 'cleanupElement', 'remapElement', 'recalculateDimensions', 'sanitizeSvg', 'runExtensions', 'addExtension', 'round', 'getIntersectionList', 'getStrokedBBox', 'getVisibleElements', 'getVisibleElementsAndBBoxes', 'groupSvgElem', 'getId', 'getNextId', 'call', 'bind', 'prepareSvg', 'setRotationAngle', 'recalculateAllSelectedDimensions', 'clearSelection', 'addToSelection', 'selectOnly', 'removeFromSelection', 'selectAllInCurrentLayer', 'getMouseTarget', 'removeUnusedDefElems', 'svgCanvasToString', 'svgToString', 'embedImage', 'setGoodImage', 'open', 'save', 'rasterExport', 'exportPDF', 'getSvgString', 'randomizeIds', 'uniquifyElems', 'setUseData', 'convertGradients', 'convertToGroup', 'setSvgString', 'importSvgString', 'identifyLayers', 'createLayer', 'cloneLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility', 'moveSelectedToLayer', 'mergeLayer', 'mergeAllLayers', 'leaveContext', 'setContext', 'clear', 'linkControlPoints', 'getContentElem', 'getRootElem', 'getSelectedElems', 'getResolution', 'getZoom', 'getVersion', 'setUiStrings', 'setConfig', 'getTitle', 'setGroupTitle', 'getDocumentTitle', 'setDocumentTitle', 'getEditorNS', 'setResolution', 'getOffset', 'setBBoxZoom', 'setZoom', 'getMode', 'setMode', 'getColor', 'setColor', 'setGradient', 'setPaint', 'setStrokePaint', 'setFillPaint', 'getStrokeWidth', 'setStrokeWidth', 'setStrokeAttr', 'getStyle', 'getOpacity', 'setOpacity', 'getFillOpacity', 'getStrokeOpacity', 'setPaintOpacity', 'getPaintOpacity', 'getBlur', 'setBlurNoUndo', 'setBlurOffsets', 'setBlur', 'getBold', 'setBold', 'getItalic', 'setItalic', 'getFontFamily', 'setFontFamily', 'setFontColor', 'getFontColor', 'getFontSize', 'setFontSize', 'getText', 'setTextContent', 'setImageURL', 'setLinkURL', 'setRectRadius', 'makeHyperlink', 'removeHyperlink', 'setSegType', 'convertToPath', 'changeSelectedAttribute', 'deleteSelectedElements', 'cutSelectedElements', 'copySelectedElements', 'pasteElements', 'groupSelectedElements', 'pushGroupProperties', 'ungroupSelectedElement', 'moveToTopSelectedElement', 'moveToBottomSelectedElement', 'moveUpDownSelected', 'moveSelectedElements', 'cloneSelectedElements', 'alignSelectedElements', 'updateCanvas', 'setBackground', 'cycleElement', 'getPrivateMethods', 'zoomChanged', 'ready'
+ ];
- // TODO: rewrite the following, it's pretty scary.
- for (i = 0; i < functions.length; i++) {
- this[functions[i]] = getCallbackSetter(functions[i]);
- }
+ // TODO: rewrite the following, it's pretty scary.
+ for (i = 0; i < functions.length; i++) {
+ this[functions[i]] = getCallbackSetter(functions[i]);
+ }
- // Older IE may need a polyfill for addEventListener, but so it would for SVG
- window.addEventListener('message', getMessageListener(this), false);
+ // Older IE may need a polyfill for addEventListener, but so it would for SVG
+ window.addEventListener('message', getMessageListener(this), false);
}
EmbeddedSVGEdit.prototype.send = function (name, args, callback) {
- var t = this;
- cbid++;
+ var t = this;
+ cbid++;
- this.callbacks[cbid] = callback;
- setTimeout((function (cbid) {
- return function () { // Delay for the callback to be set in case its synchronous
- /*
- * Todo: Handle non-JSON arguments and return values (undefined,
- * nonfinite numbers, functions, and built-in objects like Date,
- * RegExp), etc.? Allow promises instead of callbacks? Review
- * SVG-Edit functions for whether JSON-able parameters can be
- * made compatile with all API functionality
- */
- // We accept and post strings for the sake of IE9 support
- if (window.location.origin === t.frame.contentWindow.location.origin) {
- // Although we do not really need this API if we are working same
- // domain, it could allow us to write in a way that would work
- // cross-domain as well, assuming we stick to the argument limitations
- // of the current JSON-based communication API (e.g., not passing
- // callbacks). We might be able to address these shortcomings; see
- // the todo elsewhere in this file.
- var message = {id: cbid},
- svgCanvas = t.frame.contentWindow.svgCanvas;
- try {
- message.result = svgCanvas[name].apply(svgCanvas, args);
- } catch (err) {
- message.error = err.message;
- }
- addCallback(t, message);
- } else { // Requires the ext-xdomain-messaging.js extension
- t.frame.contentWindow.postMessage(JSON.stringify({namespace: 'svgCanvas', id: cbid, name: name, args: args}), '*');
- }
- };
- }(cbid)), 0);
+ this.callbacks[cbid] = callback;
+ setTimeout((function (cbid) {
+ return function () { // Delay for the callback to be set in case its synchronous
+ /*
+ * Todo: Handle non-JSON arguments and return values (undefined,
+ * nonfinite numbers, functions, and built-in objects like Date,
+ * RegExp), etc.? Allow promises instead of callbacks? Review
+ * SVG-Edit functions for whether JSON-able parameters can be
+ * made compatile with all API functionality
+ */
+ // We accept and post strings for the sake of IE9 support
+ if (window.location.origin === t.frame.contentWindow.location.origin) {
+ // Although we do not really need this API if we are working same
+ // domain, it could allow us to write in a way that would work
+ // cross-domain as well, assuming we stick to the argument limitations
+ // of the current JSON-based communication API (e.g., not passing
+ // callbacks). We might be able to address these shortcomings; see
+ // the todo elsewhere in this file.
+ var message = {id: cbid},
+ svgCanvas = t.frame.contentWindow.svgCanvas;
+ try {
+ message.result = svgCanvas[name].apply(svgCanvas, args);
+ } catch (err) {
+ message.error = err.message;
+ }
+ addCallback(t, message);
+ } else { // Requires the ext-xdomain-messaging.js extension
+ t.frame.contentWindow.postMessage(JSON.stringify({namespace: 'svgCanvas', id: cbid, name: name, args: args}), '*');
+ }
+ };
+ }(cbid)), 0);
- return cbid;
+ return cbid;
};
window.embedded_svg_edit = EmbeddedSVGEdit; // Export old, deprecated API
diff --git a/editor/history.js b/editor/history.js
index d546779b..b2970615 100644
--- a/editor/history.js
+++ b/editor/history.js
@@ -17,15 +17,15 @@
'use strict';
if (!svgedit.history) {
- svgedit.history = {};
+ svgedit.history = {};
}
// Group: Undo/Redo history management
svgedit.history.HistoryEventTypes = {
- BEFORE_APPLY: 'before_apply',
- AFTER_APPLY: 'after_apply',
- BEFORE_UNAPPLY: 'before_unapply',
- AFTER_UNAPPLY: 'after_unapply'
+ BEFORE_APPLY: 'before_apply',
+ AFTER_APPLY: 'after_apply',
+ BEFORE_UNAPPLY: 'before_unapply',
+ AFTER_UNAPPLY: 'after_unapply'
};
// var removedElements = {};
@@ -63,18 +63,18 @@ svgedit.history.HistoryEventTypes = {
* @param {string} [text] - An optional string visible to user related to this change
*/
svgedit.history.MoveElementCommand = function (elem, oldNextSibling, oldParent, text) {
- this.elem = elem;
- this.text = text ? ('Move ' + elem.tagName + ' to ' + text) : ('Move ' + elem.tagName);
- this.oldNextSibling = oldNextSibling;
- this.oldParent = oldParent;
- this.newNextSibling = elem.nextSibling;
- this.newParent = elem.parentNode;
+ this.elem = elem;
+ this.text = text ? ('Move ' + elem.tagName + ' to ' + text) : ('Move ' + elem.tagName);
+ this.oldNextSibling = oldNextSibling;
+ this.oldParent = oldParent;
+ this.newNextSibling = elem.nextSibling;
+ this.newParent = elem.parentNode;
};
svgedit.history.MoveElementCommand.type = function () { return 'svgedit.history.MoveElementCommand'; };
svgedit.history.MoveElementCommand.prototype.type = svgedit.history.MoveElementCommand.type;
svgedit.history.MoveElementCommand.prototype.getText = function () {
- return this.text;
+ return this.text;
};
/**
@@ -82,16 +82,16 @@ svgedit.history.MoveElementCommand.prototype.getText = function () {
* @param {handleHistoryEvent: function}
*/
svgedit.history.MoveElementCommand.prototype.apply = function (handler) {
- // TODO(codedread): Refactor this common event code into a base HistoryCommand class.
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
- }
+ // TODO(codedread): Refactor this common event code into a base HistoryCommand class.
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
+ }
- this.elem = this.newParent.insertBefore(this.elem, this.newNextSibling);
+ this.elem = this.newParent.insertBefore(this.elem, this.newNextSibling);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
+ }
};
/**
@@ -99,21 +99,21 @@ svgedit.history.MoveElementCommand.prototype.apply = function (handler) {
* @param {handleHistoryEvent: function}
*/
svgedit.history.MoveElementCommand.prototype.unapply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
+ }
- this.elem = this.oldParent.insertBefore(this.elem, this.oldNextSibling);
+ this.elem = this.oldParent.insertBefore(this.elem, this.oldNextSibling);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
+ }
};
// Function: svgedit.history.MoveElementCommand.elements
// Returns array with element associated with this command
svgedit.history.MoveElementCommand.prototype.elements = function () {
- return [this.elem];
+ return [this.elem];
};
// Class: svgedit.history.InsertElementCommand
@@ -124,52 +124,52 @@ svgedit.history.MoveElementCommand.prototype.elements = function () {
// elem - The newly added DOM element
// text - An optional string visible to user related to this change
svgedit.history.InsertElementCommand = function (elem, text) {
- this.elem = elem;
- this.text = text || ('Create ' + elem.tagName);
- this.parent = elem.parentNode;
- this.nextSibling = this.elem.nextSibling;
+ this.elem = elem;
+ this.text = text || ('Create ' + elem.tagName);
+ this.parent = elem.parentNode;
+ this.nextSibling = this.elem.nextSibling;
};
svgedit.history.InsertElementCommand.type = function () { return 'svgedit.history.InsertElementCommand'; };
svgedit.history.InsertElementCommand.prototype.type = svgedit.history.InsertElementCommand.type;
// Function: svgedit.history.InsertElementCommand.getText
svgedit.history.InsertElementCommand.prototype.getText = function () {
- return this.text;
+ return this.text;
};
// Function: svgedit.history.InsertElementCommand.apply
// Re-Inserts the new element
svgedit.history.InsertElementCommand.prototype.apply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
+ }
- this.elem = this.parent.insertBefore(this.elem, this.nextSibling);
+ this.elem = this.parent.insertBefore(this.elem, this.nextSibling);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
+ }
};
// Function: svgedit.history.InsertElementCommand.unapply
// Removes the element
svgedit.history.InsertElementCommand.prototype.unapply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
+ }
- this.parent = this.elem.parentNode;
- this.elem = this.elem.parentNode.removeChild(this.elem);
+ this.parent = this.elem.parentNode;
+ this.elem = this.elem.parentNode.removeChild(this.elem);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
+ }
};
// Function: svgedit.history.InsertElementCommand.elements
// Returns array with element associated with this command
svgedit.history.InsertElementCommand.prototype.elements = function () {
- return [this.elem];
+ return [this.elem];
};
// Class: svgedit.history.RemoveElementCommand
@@ -182,62 +182,62 @@ svgedit.history.InsertElementCommand.prototype.elements = function () {
// oldParent - The DOM element's parent
// text - An optional string visible to user related to this change
svgedit.history.RemoveElementCommand = function (elem, oldNextSibling, oldParent, text) {
- this.elem = elem;
- this.text = text || ('Delete ' + elem.tagName);
- this.nextSibling = oldNextSibling;
- this.parent = oldParent;
+ this.elem = elem;
+ this.text = text || ('Delete ' + elem.tagName);
+ this.nextSibling = oldNextSibling;
+ this.parent = oldParent;
- // special hack for webkit: remove this element's entry in the svgTransformLists map
- svgedit.transformlist.removeElementFromListMap(elem);
+ // special hack for webkit: remove this element's entry in the svgTransformLists map
+ svgedit.transformlist.removeElementFromListMap(elem);
};
svgedit.history.RemoveElementCommand.type = function () { return 'svgedit.history.RemoveElementCommand'; };
svgedit.history.RemoveElementCommand.prototype.type = svgedit.history.RemoveElementCommand.type;
// Function: svgedit.history.RemoveElementCommand.getText
svgedit.history.RemoveElementCommand.prototype.getText = function () {
- return this.text;
+ return this.text;
};
// Function: RemoveElementCommand.apply
// Re-removes the new element
svgedit.history.RemoveElementCommand.prototype.apply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
+ }
- svgedit.transformlist.removeElementFromListMap(this.elem);
- this.parent = this.elem.parentNode;
- this.elem = this.parent.removeChild(this.elem);
+ svgedit.transformlist.removeElementFromListMap(this.elem);
+ this.parent = this.elem.parentNode;
+ this.elem = this.parent.removeChild(this.elem);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
+ }
};
// Function: RemoveElementCommand.unapply
// Re-adds the new element
svgedit.history.RemoveElementCommand.prototype.unapply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
+ }
- svgedit.transformlist.removeElementFromListMap(this.elem);
- if (this.nextSibling == null) {
- if (window.console) {
- console.log('Error: reference element was lost');
- }
- }
- this.parent.insertBefore(this.elem, this.nextSibling);
+ svgedit.transformlist.removeElementFromListMap(this.elem);
+ if (this.nextSibling == null) {
+ if (window.console) {
+ console.log('Error: reference element was lost');
+ }
+ }
+ this.parent.insertBefore(this.elem, this.nextSibling);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
+ }
};
// Function: RemoveElementCommand.elements
// Returns array with element associated with this command
svgedit.history.RemoveElementCommand.prototype.elements = function () {
- return [this.elem];
+ return [this.elem];
};
// Class: svgedit.history.ChangeElementCommand
@@ -250,135 +250,135 @@ svgedit.history.RemoveElementCommand.prototype.elements = function () {
// attrs - An object with the attributes to be changed and the values they had *before* the change
// text - An optional string visible to user related to this change
svgedit.history.ChangeElementCommand = function (elem, attrs, text) {
- this.elem = elem;
- this.text = text ? ('Change ' + elem.tagName + ' ' + text) : ('Change ' + elem.tagName);
- this.newValues = {};
- this.oldValues = attrs;
- var attr;
- for (attr in attrs) {
- if (attr === '#text') {
- this.newValues[attr] = elem.textContent;
- } else if (attr === '#href') {
- this.newValues[attr] = svgedit.utilities.getHref(elem);
- } else {
- this.newValues[attr] = elem.getAttribute(attr);
- }
- }
+ this.elem = elem;
+ this.text = text ? ('Change ' + elem.tagName + ' ' + text) : ('Change ' + elem.tagName);
+ this.newValues = {};
+ this.oldValues = attrs;
+ var attr;
+ for (attr in attrs) {
+ if (attr === '#text') {
+ this.newValues[attr] = elem.textContent;
+ } else if (attr === '#href') {
+ this.newValues[attr] = svgedit.utilities.getHref(elem);
+ } else {
+ this.newValues[attr] = elem.getAttribute(attr);
+ }
+ }
};
svgedit.history.ChangeElementCommand.type = function () { return 'svgedit.history.ChangeElementCommand'; };
svgedit.history.ChangeElementCommand.prototype.type = svgedit.history.ChangeElementCommand.type;
// Function: svgedit.history.ChangeElementCommand.getText
svgedit.history.ChangeElementCommand.prototype.getText = function () {
- return this.text;
+ return this.text;
};
// Function: svgedit.history.ChangeElementCommand.apply
// Performs the stored change action
svgedit.history.ChangeElementCommand.prototype.apply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
+ }
- var bChangedTransform = false;
- var attr;
- for (attr in this.newValues) {
- if (this.newValues[attr]) {
- if (attr === '#text') {
- this.elem.textContent = this.newValues[attr];
- } else if (attr === '#href') {
- svgedit.utilities.setHref(this.elem, this.newValues[attr]);
- } else {
- this.elem.setAttribute(attr, this.newValues[attr]);
- }
- } else {
- if (attr === '#text') {
- this.elem.textContent = '';
- } else {
- this.elem.setAttribute(attr, '');
- this.elem.removeAttribute(attr);
- }
- }
+ var bChangedTransform = false;
+ var attr;
+ for (attr in this.newValues) {
+ if (this.newValues[attr]) {
+ if (attr === '#text') {
+ this.elem.textContent = this.newValues[attr];
+ } else if (attr === '#href') {
+ svgedit.utilities.setHref(this.elem, this.newValues[attr]);
+ } else {
+ this.elem.setAttribute(attr, this.newValues[attr]);
+ }
+ } else {
+ if (attr === '#text') {
+ this.elem.textContent = '';
+ } else {
+ this.elem.setAttribute(attr, '');
+ this.elem.removeAttribute(attr);
+ }
+ }
- if (attr === 'transform') { bChangedTransform = true; }
- }
+ if (attr === 'transform') { bChangedTransform = true; }
+ }
- // relocate rotational transform, if necessary
- if (!bChangedTransform) {
- var angle = svgedit.utilities.getRotationAngle(this.elem);
- if (angle) {
- var bbox = this.elem.getBBox();
- var cx = bbox.x + bbox.width / 2,
- cy = bbox.y + bbox.height / 2;
- var rotate = ['rotate(', angle, ' ', cx, ',', cy, ')'].join('');
- if (rotate !== this.elem.getAttribute('transform')) {
- this.elem.setAttribute('transform', rotate);
- }
- }
- }
+ // relocate rotational transform, if necessary
+ if (!bChangedTransform) {
+ var angle = svgedit.utilities.getRotationAngle(this.elem);
+ if (angle) {
+ var bbox = this.elem.getBBox();
+ var cx = bbox.x + bbox.width / 2,
+ cy = bbox.y + bbox.height / 2;
+ var rotate = ['rotate(', angle, ' ', cx, ',', cy, ')'].join('');
+ if (rotate !== this.elem.getAttribute('transform')) {
+ this.elem.setAttribute('transform', rotate);
+ }
+ }
+ }
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
+ }
- return true;
+ return true;
};
// Function: svgedit.history.ChangeElementCommand.unapply
// Reverses the stored change action
svgedit.history.ChangeElementCommand.prototype.unapply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
+ }
- var bChangedTransform = false;
- var attr;
- for (attr in this.oldValues) {
- if (this.oldValues[attr]) {
- if (attr === '#text') {
- this.elem.textContent = this.oldValues[attr];
- } else if (attr === '#href') {
- svgedit.utilities.setHref(this.elem, this.oldValues[attr]);
- } else {
- this.elem.setAttribute(attr, this.oldValues[attr]);
- }
- } else {
- if (attr === '#text') {
- this.elem.textContent = '';
- } else {
- this.elem.removeAttribute(attr);
- }
- }
- if (attr === 'transform') { bChangedTransform = true; }
- }
- // relocate rotational transform, if necessary
- if (!bChangedTransform) {
- var angle = svgedit.utilities.getRotationAngle(this.elem);
- if (angle) {
- var bbox = this.elem.getBBox();
- var cx = bbox.x + bbox.width / 2,
- cy = bbox.y + bbox.height / 2;
- var rotate = ['rotate(', angle, ' ', cx, ',', cy, ')'].join('');
- if (rotate !== this.elem.getAttribute('transform')) {
- this.elem.setAttribute('transform', rotate);
- }
- }
- }
+ var bChangedTransform = false;
+ var attr;
+ for (attr in this.oldValues) {
+ if (this.oldValues[attr]) {
+ if (attr === '#text') {
+ this.elem.textContent = this.oldValues[attr];
+ } else if (attr === '#href') {
+ svgedit.utilities.setHref(this.elem, this.oldValues[attr]);
+ } else {
+ this.elem.setAttribute(attr, this.oldValues[attr]);
+ }
+ } else {
+ if (attr === '#text') {
+ this.elem.textContent = '';
+ } else {
+ this.elem.removeAttribute(attr);
+ }
+ }
+ if (attr === 'transform') { bChangedTransform = true; }
+ }
+ // relocate rotational transform, if necessary
+ if (!bChangedTransform) {
+ var angle = svgedit.utilities.getRotationAngle(this.elem);
+ if (angle) {
+ var bbox = this.elem.getBBox();
+ var cx = bbox.x + bbox.width / 2,
+ cy = bbox.y + bbox.height / 2;
+ var rotate = ['rotate(', angle, ' ', cx, ',', cy, ')'].join('');
+ if (rotate !== this.elem.getAttribute('transform')) {
+ this.elem.setAttribute('transform', rotate);
+ }
+ }
+ }
- // Remove transformlist to prevent confusion that causes bugs like 575.
- svgedit.transformlist.removeElementFromListMap(this.elem);
+ // Remove transformlist to prevent confusion that causes bugs like 575.
+ svgedit.transformlist.removeElementFromListMap(this.elem);
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
+ }
- return true;
+ return true;
};
// Function: ChangeElementCommand.elements
// Returns array with element associated with this command
svgedit.history.ChangeElementCommand.prototype.elements = function () {
- return [this.elem];
+ return [this.elem];
};
// TODO: create a 'typing' command object that tracks changes in text
@@ -392,65 +392,65 @@ svgedit.history.ChangeElementCommand.prototype.elements = function () {
// Parameters:
// text - An optional string visible to user related to this change
svgedit.history.BatchCommand = function (text) {
- this.text = text || 'Batch Command';
- this.stack = [];
+ this.text = text || 'Batch Command';
+ this.stack = [];
};
svgedit.history.BatchCommand.type = function () { return 'svgedit.history.BatchCommand'; };
svgedit.history.BatchCommand.prototype.type = svgedit.history.BatchCommand.type;
// Function: svgedit.history.BatchCommand.getText
svgedit.history.BatchCommand.prototype.getText = function () {
- return this.text;
+ return this.text;
};
// Function: svgedit.history.BatchCommand.apply
// Runs "apply" on all subcommands
svgedit.history.BatchCommand.prototype.apply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_APPLY, this);
+ }
- var i,
- len = this.stack.length;
- for (i = 0; i < len; ++i) {
- this.stack[i].apply(handler);
- }
+ var i,
+ len = this.stack.length;
+ for (i = 0; i < len; ++i) {
+ this.stack[i].apply(handler);
+ }
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_APPLY, this);
+ }
};
// Function: svgedit.history.BatchCommand.unapply
// Runs "unapply" on all subcommands
svgedit.history.BatchCommand.prototype.unapply = function (handler) {
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.BEFORE_UNAPPLY, this);
+ }
- var i;
- for (i = this.stack.length - 1; i >= 0; i--) {
- this.stack[i].unapply(handler);
- }
+ var i;
+ for (i = this.stack.length - 1; i >= 0; i--) {
+ this.stack[i].unapply(handler);
+ }
- if (handler) {
- handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
- }
+ if (handler) {
+ handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
+ }
};
// Function: svgedit.history.BatchCommand.elements
// Iterate through all our subcommands and returns all the elements we are changing
svgedit.history.BatchCommand.prototype.elements = function () {
- var elems = [];
- var cmd = this.stack.length;
- while (cmd--) {
- var thisElems = this.stack[cmd].elements();
- var elem = thisElems.length;
- while (elem--) {
- if (elems.indexOf(thisElems[elem]) === -1) { elems.push(thisElems[elem]); }
- }
- }
- return elems;
+ var elems = [];
+ var cmd = this.stack.length;
+ while (cmd--) {
+ var thisElems = this.stack[cmd].elements();
+ var elem = thisElems.length;
+ while (elem--) {
+ if (elems.indexOf(thisElems[elem]) === -1) { elems.push(thisElems[elem]); }
+ }
+ }
+ return elems;
};
// Function: svgedit.history.BatchCommand.addSubCommand
@@ -459,13 +459,13 @@ svgedit.history.BatchCommand.prototype.elements = function () {
// Parameters:
// cmd - The undo command object to add
svgedit.history.BatchCommand.prototype.addSubCommand = function (cmd) {
- this.stack.push(cmd);
+ this.stack.push(cmd);
};
// Function: svgedit.history.BatchCommand.isEmpty
// Returns a boolean indicating whether or not the batch command is empty
svgedit.history.BatchCommand.prototype.isEmpty = function () {
- return this.stack.length === 0;
+ return this.stack.length === 0;
};
// Class: svgedit.history.UndoManager
@@ -473,67 +473,67 @@ svgedit.history.BatchCommand.prototype.isEmpty = function () {
// historyEventHandler - an object that conforms to the HistoryEventHandler interface
// (see above)
svgedit.history.UndoManager = function (historyEventHandler) {
- this.handler_ = historyEventHandler || null;
- this.undoStackPointer = 0;
- this.undoStack = [];
+ this.handler_ = historyEventHandler || null;
+ this.undoStackPointer = 0;
+ this.undoStack = [];
- // this is the stack that stores the original values, the elements and
- // the attribute name for begin/finish
- this.undoChangeStackPointer = -1;
- this.undoableChangeStack = [];
+ // this is the stack that stores the original values, the elements and
+ // the attribute name for begin/finish
+ this.undoChangeStackPointer = -1;
+ this.undoableChangeStack = [];
};
// Function: svgedit.history.UndoManager.resetUndoStack
// Resets the undo stack, effectively clearing the undo/redo history
svgedit.history.UndoManager.prototype.resetUndoStack = function () {
- this.undoStack = [];
- this.undoStackPointer = 0;
+ this.undoStack = [];
+ this.undoStackPointer = 0;
};
// Function: svgedit.history.UndoManager.getUndoStackSize
// Returns:
// Integer with the current size of the undo history stack
svgedit.history.UndoManager.prototype.getUndoStackSize = function () {
- return this.undoStackPointer;
+ return this.undoStackPointer;
};
// Function: svgedit.history.UndoManager.getRedoStackSize
// Returns:
// Integer with the current size of the redo history stack
svgedit.history.UndoManager.prototype.getRedoStackSize = function () {
- return this.undoStack.length - this.undoStackPointer;
+ return this.undoStack.length - this.undoStackPointer;
};
// Function: svgedit.history.UndoManager.getNextUndoCommandText
// Returns:
// String associated with the next undo command
svgedit.history.UndoManager.prototype.getNextUndoCommandText = function () {
- return this.undoStackPointer > 0 ? this.undoStack[this.undoStackPointer - 1].getText() : '';
+ return this.undoStackPointer > 0 ? this.undoStack[this.undoStackPointer - 1].getText() : '';
};
// Function: svgedit.history.UndoManager.getNextRedoCommandText
// Returns:
// String associated with the next redo command
svgedit.history.UndoManager.prototype.getNextRedoCommandText = function () {
- return this.undoStackPointer < this.undoStack.length ? this.undoStack[this.undoStackPointer].getText() : '';
+ return this.undoStackPointer < this.undoStack.length ? this.undoStack[this.undoStackPointer].getText() : '';
};
// Function: svgedit.history.UndoManager.undo
// Performs an undo step
svgedit.history.UndoManager.prototype.undo = function () {
- if (this.undoStackPointer > 0) {
- var cmd = this.undoStack[--this.undoStackPointer];
- cmd.unapply(this.handler_);
- }
+ if (this.undoStackPointer > 0) {
+ var cmd = this.undoStack[--this.undoStackPointer];
+ cmd.unapply(this.handler_);
+ }
};
// Function: svgedit.history.UndoManager.redo
// Performs a redo step
svgedit.history.UndoManager.prototype.redo = function () {
- if (this.undoStackPointer < this.undoStack.length && this.undoStack.length > 0) {
- var cmd = this.undoStack[this.undoStackPointer++];
- cmd.apply(this.handler_);
- }
+ if (this.undoStackPointer < this.undoStack.length && this.undoStack.length > 0) {
+ var cmd = this.undoStack[this.undoStackPointer++];
+ cmd.apply(this.handler_);
+ }
};
// Function: svgedit.history.UndoManager.addCommandToHistory
@@ -542,18 +542,18 @@ svgedit.history.UndoManager.prototype.redo = function () {
// Parameters:
// cmd - The command object to add
svgedit.history.UndoManager.prototype.addCommandToHistory = function (cmd) {
- // FIXME: we MUST compress consecutive text changes to the same element
- // (right now each keystroke is saved as a separate command that includes the
- // entire text contents of the text element)
- // TODO: consider limiting the history that we store here (need to do some slicing)
+ // FIXME: we MUST compress consecutive text changes to the same element
+ // (right now each keystroke is saved as a separate command that includes the
+ // entire text contents of the text element)
+ // TODO: consider limiting the history that we store here (need to do some slicing)
- // if our stack pointer is not at the end, then we have to remove
- // all commands after the pointer and insert the new command
- if (this.undoStackPointer < this.undoStack.length && this.undoStack.length > 0) {
- this.undoStack = this.undoStack.splice(0, this.undoStackPointer);
- }
- this.undoStack.push(cmd);
- this.undoStackPointer = this.undoStack.length;
+ // if our stack pointer is not at the end, then we have to remove
+ // all commands after the pointer and insert the new command
+ if (this.undoStackPointer < this.undoStack.length && this.undoStack.length > 0) {
+ this.undoStack = this.undoStack.splice(0, this.undoStackPointer);
+ }
+ this.undoStack.push(cmd);
+ this.undoStackPointer = this.undoStack.length;
};
// Function: svgedit.history.UndoManager.beginUndoableChange
@@ -567,20 +567,20 @@ svgedit.history.UndoManager.prototype.addCommandToHistory = function (cmd) {
// attrName - The name of the attribute being changed
// elems - Array of DOM elements being changed
svgedit.history.UndoManager.prototype.beginUndoableChange = function (attrName, elems) {
- var p = ++this.undoChangeStackPointer;
- var i = elems.length;
- var oldValues = new Array(i), elements = new Array(i);
- while (i--) {
- var elem = elems[i];
- if (elem == null) { continue; }
- elements[i] = elem;
- oldValues[i] = elem.getAttribute(attrName);
- }
- this.undoableChangeStack[p] = {
- 'attrName': attrName,
- 'oldValues': oldValues,
- 'elements': elements
- };
+ var p = ++this.undoChangeStackPointer;
+ var i = elems.length;
+ var oldValues = new Array(i), elements = new Array(i);
+ while (i--) {
+ var elem = elems[i];
+ if (elem == null) { continue; }
+ elements[i] = elem;
+ oldValues[i] = elem.getAttribute(attrName);
+ }
+ this.undoableChangeStack[p] = {
+ 'attrName': attrName,
+ 'oldValues': oldValues,
+ 'elements': elements
+ };
};
// Function: svgedit.history.UndoManager.finishUndoableChange
@@ -591,21 +591,21 @@ svgedit.history.UndoManager.prototype.beginUndoableChange = function (attrName,
// Returns:
// Batch command object with resulting changes
svgedit.history.UndoManager.prototype.finishUndoableChange = function () {
- var p = this.undoChangeStackPointer--;
- var changeset = this.undoableChangeStack[p];
- var i = changeset.elements.length;
- var attrName = changeset.attrName;
- var batchCmd = new svgedit.history.BatchCommand('Change ' + attrName);
- while (i--) {
- var elem = changeset.elements[i];
- if (elem == null) { continue; }
- var changes = {};
- changes[attrName] = changeset.oldValues[i];
- if (changes[attrName] !== elem.getAttribute(attrName)) {
- batchCmd.addSubCommand(new svgedit.history.ChangeElementCommand(elem, changes, attrName));
- }
- }
- this.undoableChangeStack[p] = null;
- return batchCmd;
+ var p = this.undoChangeStackPointer--;
+ var changeset = this.undoableChangeStack[p];
+ var i = changeset.elements.length;
+ var attrName = changeset.attrName;
+ var batchCmd = new svgedit.history.BatchCommand('Change ' + attrName);
+ while (i--) {
+ var elem = changeset.elements[i];
+ if (elem == null) { continue; }
+ var changes = {};
+ changes[attrName] = changeset.oldValues[i];
+ if (changes[attrName] !== elem.getAttribute(attrName)) {
+ batchCmd.addSubCommand(new svgedit.history.ChangeElementCommand(elem, changes, attrName));
+ }
+ }
+ this.undoableChangeStack[p] = null;
+ return batchCmd;
};
}());
diff --git a/editor/historyrecording.js b/editor/historyrecording.js
index 9fdd0280..2f7a39b4 100644
--- a/editor/historyrecording.js
+++ b/editor/historyrecording.js
@@ -15,7 +15,7 @@
'use strict';
if (!svgedit.history) {
- svgedit.history = {};
+ svgedit.history = {};
}
var history = svgedit.history;
@@ -58,9 +58,9 @@ var history = svgedit.history;
* See singleton: HistoryRecordingService.NO_HISTORY
*/
var HistoryRecordingService = history.HistoryRecordingService = function (undoManager) {
- this.undoManager_ = undoManager;
- this.currentBatchCommand_ = null;
- this.batchCommandStack_ = [];
+ this.undoManager_ = undoManager;
+ this.currentBatchCommand_ = null;
+ this.batchCommandStack_ = [];
};
/**
@@ -77,10 +77,10 @@ HistoryRecordingService.NO_HISTORY = new HistoryRecordingService();
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.startBatchCommand = function (text) {
- if (!this.undoManager_) { return this; }
- this.currentBatchCommand_ = new history.BatchCommand(text);
- this.batchCommandStack_.push(this.currentBatchCommand_);
- return this;
+ if (!this.undoManager_) { return this; }
+ this.currentBatchCommand_ = new history.BatchCommand(text);
+ this.batchCommandStack_.push(this.currentBatchCommand_);
+ return this;
};
/**
@@ -88,15 +88,15 @@ HistoryRecordingService.prototype.startBatchCommand = function (text) {
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.endBatchCommand = function () {
- if (!this.undoManager_) { return this; }
- if (this.currentBatchCommand_) {
- var batchCommand = this.currentBatchCommand_;
- this.batchCommandStack_.pop();
- var length = this.batchCommandStack_.length;
- this.currentBatchCommand_ = length ? this.batchCommandStack_[length - 1] : null;
- this.addCommand_(batchCommand);
- }
- return this;
+ if (!this.undoManager_) { return this; }
+ if (this.currentBatchCommand_) {
+ var batchCommand = this.currentBatchCommand_;
+ this.batchCommandStack_.pop();
+ var length = this.batchCommandStack_.length;
+ this.currentBatchCommand_ = length ? this.batchCommandStack_[length - 1] : null;
+ this.addCommand_(batchCommand);
+ }
+ return this;
};
/**
@@ -108,9 +108,9 @@ HistoryRecordingService.prototype.endBatchCommand = function () {
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.moveElement = function (elem, oldNextSibling, oldParent, text) {
- if (!this.undoManager_) { return this; }
- this.addCommand_(new history.MoveElementCommand(elem, oldNextSibling, oldParent, text));
- return this;
+ if (!this.undoManager_) { return this; }
+ this.addCommand_(new history.MoveElementCommand(elem, oldNextSibling, oldParent, text));
+ return this;
};
/**
@@ -120,9 +120,9 @@ HistoryRecordingService.prototype.moveElement = function (elem, oldNextSibling,
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.insertElement = function (elem, text) {
- if (!this.undoManager_) { return this; }
- this.addCommand_(new history.InsertElementCommand(elem, text));
- return this;
+ if (!this.undoManager_) { return this; }
+ this.addCommand_(new history.InsertElementCommand(elem, text));
+ return this;
};
/**
@@ -134,9 +134,9 @@ HistoryRecordingService.prototype.insertElement = function (elem, text) {
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.removeElement = function (elem, oldNextSibling, oldParent, text) {
- if (!this.undoManager_) { return this; }
- this.addCommand_(new history.RemoveElementCommand(elem, oldNextSibling, oldParent, text));
- return this;
+ if (!this.undoManager_) { return this; }
+ this.addCommand_(new history.RemoveElementCommand(elem, oldNextSibling, oldParent, text));
+ return this;
};
/**
@@ -147,9 +147,9 @@ HistoryRecordingService.prototype.removeElement = function (elem, oldNextSibling
* @returns {svgedit.history.HistoryRecordingService}
*/
HistoryRecordingService.prototype.changeElement = function (elem, attrs, text) {
- if (!this.undoManager_) { return this; }
- this.addCommand_(new history.ChangeElementCommand(elem, attrs, text));
- return this;
+ if (!this.undoManager_) { return this; }
+ this.addCommand_(new history.ChangeElementCommand(elem, attrs, text));
+ return this;
};
/**
@@ -159,11 +159,11 @@ HistoryRecordingService.prototype.changeElement = function (elem, attrs, text) {
* @private
*/
HistoryRecordingService.prototype.addCommand_ = function (cmd) {
- if (!this.undoManager_) { return this; }
- if (this.currentBatchCommand_) {
- this.currentBatchCommand_.addSubCommand(cmd);
- } else {
- this.undoManager_.addCommandToHistory(cmd);
- }
+ if (!this.undoManager_) { return this; }
+ if (this.currentBatchCommand_) {
+ this.currentBatchCommand_.addSubCommand(cmd);
+ } else {
+ this.undoManager_.addCommandToHistory(cmd);
+ }
};
}());
diff --git a/editor/layer.js b/editor/layer.js
index b9f56239..197eee9f 100644
--- a/editor/layer.js
+++ b/editor/layer.js
@@ -17,7 +17,7 @@
'use strict';
if (!svgedit.draw) {
- svgedit.draw = {};
+ svgedit.draw = {};
}
var NS = svgedit.NS;
@@ -39,29 +39,29 @@ var NS = svgedit.NS;
* a new layer to the document.
*/
var Layer = svgedit.draw.Layer = function (name, group, svgElem) {
- this.name_ = name;
- this.group_ = svgElem ? null : group;
+ this.name_ = name;
+ this.group_ = svgElem ? null : group;
- if (svgElem) {
- // Create a group element with title and add it to the DOM.
- var svgdoc = svgElem.ownerDocument;
- this.group_ = svgdoc.createElementNS(NS.SVG, 'g');
- var layerTitle = svgdoc.createElementNS(NS.SVG, 'title');
- layerTitle.textContent = name;
- this.group_.appendChild(layerTitle);
- if (group) {
- $(group).after(this.group_);
- } else {
- svgElem.appendChild(this.group_);
- }
- }
+ if (svgElem) {
+ // Create a group element with title and add it to the DOM.
+ var svgdoc = svgElem.ownerDocument;
+ this.group_ = svgdoc.createElementNS(NS.SVG, 'g');
+ var layerTitle = svgdoc.createElementNS(NS.SVG, 'title');
+ layerTitle.textContent = name;
+ this.group_.appendChild(layerTitle);
+ if (group) {
+ $(group).after(this.group_);
+ } else {
+ svgElem.appendChild(this.group_);
+ }
+ }
- addLayerClass(this.group_);
- svgedit.utilities.walkTree(this.group_, function (e) {
- e.setAttribute('style', 'pointer-events:inherit');
- });
+ addLayerClass(this.group_);
+ svgedit.utilities.walkTree(this.group_, function (e) {
+ e.setAttribute('style', 'pointer-events:inherit');
+ });
- this.group_.setAttribute('style', svgElem ? 'pointer-events:all' : 'pointer-events:none');
+ this.group_.setAttribute('style', svgElem ? 'pointer-events:all' : 'pointer-events:none');
};
/**
@@ -79,7 +79,7 @@ Layer.CLASS_REGEX = new RegExp('(\\s|^)' + Layer.CLASS_NAME + '(\\s|$)');
* @returns {string} The layer name
*/
Layer.prototype.getName = function () {
- return this.name_;
+ return this.name_;
};
/**
@@ -87,21 +87,21 @@ Layer.prototype.getName = function () {
* @returns {SVGGElement} The layer SVG group
*/
Layer.prototype.getGroup = function () {
- return this.group_;
+ return this.group_;
};
/**
* Active this layer so it takes pointer events.
*/
Layer.prototype.activate = function () {
- this.group_.setAttribute('style', 'pointer-events:all');
+ this.group_.setAttribute('style', 'pointer-events:all');
};
/**
* Deactive this layer so it does NOT take pointer events.
*/
Layer.prototype.deactivate = function () {
- this.group_.setAttribute('style', 'pointer-events:none');
+ this.group_.setAttribute('style', 'pointer-events:none');
};
/**
@@ -109,11 +109,11 @@ Layer.prototype.deactivate = function () {
* @param {boolean} visible - If true, make visible; otherwise, hide it.
*/
Layer.prototype.setVisible = function (visible) {
- var expected = visible === undefined || visible ? 'inline' : 'none';
- var oldDisplay = this.group_.getAttribute('display');
- if (oldDisplay !== expected) {
- this.group_.setAttribute('display', expected);
- }
+ var expected = visible === undefined || visible ? 'inline' : 'none';
+ var oldDisplay = this.group_.getAttribute('display');
+ if (oldDisplay !== expected) {
+ this.group_.setAttribute('display', expected);
+ }
};
/**
@@ -121,7 +121,7 @@ Layer.prototype.setVisible = function (visible) {
* @returns {boolean} True if visible.
*/
Layer.prototype.isVisible = function () {
- return this.group_.getAttribute('display') !== 'none';
+ return this.group_.getAttribute('display') !== 'none';
};
/**
@@ -129,11 +129,11 @@ Layer.prototype.isVisible = function () {
* @returns {number} Opacity value.
*/
Layer.prototype.getOpacity = function () {
- var opacity = this.group_.getAttribute('opacity');
- if (opacity === null || opacity === undefined) {
- return 1;
- }
- return parseFloat(opacity);
+ var opacity = this.group_.getAttribute('opacity');
+ if (opacity === null || opacity === undefined) {
+ return 1;
+ }
+ return parseFloat(opacity);
};
/**
@@ -142,9 +142,9 @@ Layer.prototype.getOpacity = function () {
* @param {number} opacity - A float value in the range 0.0-1.0
*/
Layer.prototype.setOpacity = function (opacity) {
- if (typeof opacity === 'number' && opacity >= 0.0 && opacity <= 1.0) {
- this.group_.setAttribute('opacity', opacity);
- }
+ if (typeof opacity === 'number' && opacity >= 0.0 && opacity <= 1.0) {
+ this.group_.setAttribute('opacity', opacity);
+ }
};
/**
@@ -152,20 +152,20 @@ Layer.prototype.setOpacity = function (opacity) {
* @param {SVGGElement} children - The children to append to this layer.
*/
Layer.prototype.appendChildren = function (children) {
- for (var i = 0; i < children.length; ++i) {
- this.group_.appendChild(children[i]);
- }
+ for (var i = 0; i < children.length; ++i) {
+ this.group_.appendChild(children[i]);
+ }
};
Layer.prototype.getTitleElement = function () {
- var len = this.group_.childNodes.length;
- for (var i = 0; i < len; ++i) {
- var child = this.group_.childNodes.item(i);
- if (child && child.tagName === 'title') {
- return child;
- }
- }
- return null;
+ var len = this.group_.childNodes.length;
+ for (var i = 0; i < len; ++i) {
+ var child = this.group_.childNodes.item(i);
+ if (child && child.tagName === 'title') {
+ return child;
+ }
+ }
+ return null;
};
/**
@@ -175,20 +175,20 @@ Layer.prototype.getTitleElement = function () {
* @returns {string|null} The new name if changed; otherwise, null.
*/
Layer.prototype.setName = function (name, hrService) {
- var previousName = this.name_;
- name = svgedit.utilities.toXml(name);
- // now change the underlying title element contents
- var title = this.getTitleElement();
- if (title) {
- $(title).empty();
- title.textContent = name;
- this.name_ = name;
- if (hrService) {
- hrService.changeElement(title, {'#text': previousName});
- }
- return this.name_;
- }
- return null;
+ var previousName = this.name_;
+ name = svgedit.utilities.toXml(name);
+ // now change the underlying title element contents
+ var title = this.getTitleElement();
+ if (title) {
+ $(title).empty();
+ title.textContent = name;
+ this.name_ = name;
+ if (hrService) {
+ hrService.changeElement(title, {'#text': previousName});
+ }
+ return this.name_;
+ }
+ return null;
};
/**
@@ -197,10 +197,10 @@ Layer.prototype.setName = function (name, hrService) {
* @returns {SVGGElement} The layer SVG group that was just removed.
*/
Layer.prototype.removeGroup = function () {
- var parent = this.group_.parentNode;
- var group = parent.removeChild(this.group_);
- this.group_ = undefined;
- return group;
+ var parent = this.group_.parentNode;
+ var group = parent.removeChild(this.group_);
+ this.group_ = undefined;
+ return group;
};
/**
@@ -210,11 +210,11 @@ Layer.prototype.removeGroup = function () {
* @param {SVGGElement} elem - The SVG element to update
*/
function addLayerClass (elem) {
- var classes = elem.getAttribute('class');
- if (classes === null || classes === undefined || classes.length === 0) {
- elem.setAttribute('class', Layer.CLASS_NAME);
- } else if (!Layer.CLASS_REGEX.test(classes)) {
- elem.setAttribute('class', classes + ' ' + Layer.CLASS_NAME);
- }
+ var classes = elem.getAttribute('class');
+ if (classes === null || classes === undefined || classes.length === 0) {
+ elem.setAttribute('class', Layer.CLASS_NAME);
+ } else if (!Layer.CLASS_REGEX.test(classes)) {
+ elem.setAttribute('class', classes + ' ' + Layer.CLASS_NAME);
+ }
}
}());
diff --git a/editor/math.js b/editor/math.js
index 466f76c0..1f95ec1f 100644
--- a/editor/math.js
+++ b/editor/math.js
@@ -24,7 +24,7 @@
'use strict';
if (!svgedit.math) {
- svgedit.math = {};
+ svgedit.math = {};
}
// Constants
@@ -42,7 +42,7 @@ var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
* @returns {Object} An x, y object representing the transformed point
*/
svgedit.math.transformPoint = function (x, y, m) {
- return {x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f};
+ return {x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f};
};
/**
@@ -52,7 +52,7 @@ svgedit.math.transformPoint = function (x, y, m) {
* @returns {boolean} Indicates whether or not the matrix is 1,0,0,1,0,0
*/
svgedit.math.isIdentity = function (m) {
- return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0);
+ return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0);
};
/**
@@ -62,20 +62,20 @@ svgedit.math.isIdentity = function (m) {
* @returns {SVGMatrix} The matrix object resulting from the calculation
*/
svgedit.math.matrixMultiply = function (matr) {
- var args = arguments, i = args.length, m = args[i - 1];
+ var args = arguments, i = args.length, m = args[i - 1];
- while (i-- > 1) {
- var m1 = args[i - 1];
- m = m1.multiply(m);
- }
- if (Math.abs(m.a) < NEAR_ZERO) { m.a = 0; }
- if (Math.abs(m.b) < NEAR_ZERO) { m.b = 0; }
- if (Math.abs(m.c) < NEAR_ZERO) { m.c = 0; }
- if (Math.abs(m.d) < NEAR_ZERO) { m.d = 0; }
- if (Math.abs(m.e) < NEAR_ZERO) { m.e = 0; }
- if (Math.abs(m.f) < NEAR_ZERO) { m.f = 0; }
+ while (i-- > 1) {
+ var m1 = args[i - 1];
+ m = m1.multiply(m);
+ }
+ if (Math.abs(m.a) < NEAR_ZERO) { m.a = 0; }
+ if (Math.abs(m.b) < NEAR_ZERO) { m.b = 0; }
+ if (Math.abs(m.c) < NEAR_ZERO) { m.c = 0; }
+ if (Math.abs(m.d) < NEAR_ZERO) { m.d = 0; }
+ if (Math.abs(m.e) < NEAR_ZERO) { m.e = 0; }
+ if (Math.abs(m.f) < NEAR_ZERO) { m.f = 0; }
- return m;
+ return m;
};
/**
@@ -84,13 +84,13 @@ svgedit.math.matrixMultiply = function (matr) {
* @returns {boolean} Whether or not a matrix transform was found
*/
svgedit.math.hasMatrixTransform = function (tlist) {
- if (!tlist) { return false; }
- var num = tlist.numberOfItems;
- while (num--) {
- var xform = tlist.getItem(num);
- if (xform.type === 1 && !svgedit.math.isIdentity(xform.matrix)) { return true; }
- }
- return false;
+ if (!tlist) { return false; }
+ var num = tlist.numberOfItems;
+ while (num--) {
+ var xform = tlist.getItem(num);
+ if (xform.type === 1 && !svgedit.math.isIdentity(xform.matrix)) { return true; }
+ }
+ return false;
};
/**
@@ -112,30 +112,30 @@ svgedit.math.hasMatrixTransform = function (tlist) {
* height - Float with the axis-aligned height coordinate
*/
svgedit.math.transformBox = function (l, t, w, h, m) {
- var transformPoint = svgedit.math.transformPoint,
+ var transformPoint = svgedit.math.transformPoint,
- tl = transformPoint(l, t, m),
- tr = transformPoint((l + w), t, m),
- bl = transformPoint(l, (t + h), m),
- br = transformPoint((l + w), (t + h), m),
+ tl = transformPoint(l, t, m),
+ tr = transformPoint((l + w), t, m),
+ bl = transformPoint(l, (t + h), m),
+ br = transformPoint((l + w), (t + h), m),
- minx = Math.min(tl.x, tr.x, bl.x, br.x),
- maxx = Math.max(tl.x, tr.x, bl.x, br.x),
- miny = Math.min(tl.y, tr.y, bl.y, br.y),
- maxy = Math.max(tl.y, tr.y, bl.y, br.y);
+ minx = Math.min(tl.x, tr.x, bl.x, br.x),
+ maxx = Math.max(tl.x, tr.x, bl.x, br.x),
+ miny = Math.min(tl.y, tr.y, bl.y, br.y),
+ maxy = Math.max(tl.y, tr.y, bl.y, br.y);
- return {
- tl: tl,
- tr: tr,
- bl: bl,
- br: br,
- aabox: {
- x: minx,
- y: miny,
- width: (maxx - minx),
- height: (maxy - miny)
- }
- };
+ return {
+ tl: tl,
+ tr: tr,
+ bl: bl,
+ br: br,
+ aabox: {
+ x: minx,
+ y: miny,
+ width: (maxx - minx),
+ height: (maxy - miny)
+ }
+ };
};
/**
@@ -150,25 +150,25 @@ svgedit.math.transformBox = function (l, t, w, h, m) {
* @returns {Object} A single matrix transform object
*/
svgedit.math.transformListToTransform = function (tlist, min, max) {
- if (tlist == null) {
- // Or should tlist = null have been prevented before this?
- return svg.createSVGTransformFromMatrix(svg.createSVGMatrix());
- }
- min = min || 0;
- max = max || (tlist.numberOfItems - 1);
- min = parseInt(min, 10);
- max = parseInt(max, 10);
- if (min > max) { var temp = max; max = min; min = temp; }
- var m = svg.createSVGMatrix();
- var i;
- for (i = min; i <= max; ++i) {
- // if our indices are out of range, just use a harmless identity matrix
- var mtom = (i >= 0 && i < tlist.numberOfItems
- ? tlist.getItem(i).matrix
- : svg.createSVGMatrix());
- m = svgedit.math.matrixMultiply(m, mtom);
- }
- return svg.createSVGTransformFromMatrix(m);
+ if (tlist == null) {
+ // Or should tlist = null have been prevented before this?
+ return svg.createSVGTransformFromMatrix(svg.createSVGMatrix());
+ }
+ min = min || 0;
+ max = max || (tlist.numberOfItems - 1);
+ min = parseInt(min, 10);
+ max = parseInt(max, 10);
+ if (min > max) { var temp = max; max = min; min = temp; }
+ var m = svg.createSVGMatrix();
+ var i;
+ for (i = min; i <= max; ++i) {
+ // if our indices are out of range, just use a harmless identity matrix
+ var mtom = (i >= 0 && i < tlist.numberOfItems
+ ? tlist.getItem(i).matrix
+ : svg.createSVGMatrix());
+ m = svgedit.math.matrixMultiply(m, mtom);
+ }
+ return svg.createSVGTransformFromMatrix(m);
};
/**
@@ -177,8 +177,8 @@ svgedit.math.transformListToTransform = function (tlist, min, max) {
* @returns {SVGMatrix} The matrix object associated with the element's transformlist
*/
svgedit.math.getMatrix = function (elem) {
- var tlist = svgedit.transformlist.getTransformList(elem);
- return svgedit.math.transformListToTransform(tlist).matrix;
+ var tlist = svgedit.transformlist.getTransformList(elem);
+ return svgedit.math.transformListToTransform(tlist).matrix;
};
/**
@@ -191,18 +191,18 @@ svgedit.math.getMatrix = function (elem) {
* @returns {AngleCoord45}
*/
svgedit.math.snapToAngle = function (x1, y1, x2, y2) {
- var snap = Math.PI / 4; // 45 degrees
- var dx = x2 - x1;
- var dy = y2 - y1;
- var angle = Math.atan2(dy, dx);
- var dist = Math.sqrt(dx * dx + dy * dy);
- var snapangle = Math.round(angle / snap) * snap;
+ var snap = Math.PI / 4; // 45 degrees
+ var dx = x2 - x1;
+ var dy = y2 - y1;
+ var angle = Math.atan2(dy, dx);
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ var snapangle = Math.round(angle / snap) * snap;
- return {
- x: x1 + dist * Math.cos(snapangle),
- y: y1 + dist * Math.sin(snapangle),
- a: snapangle
- };
+ return {
+ x: x1 + dist * Math.cos(snapangle),
+ y: y1 + dist * Math.sin(snapangle),
+ a: snapangle
+ };
};
/**
@@ -212,9 +212,9 @@ svgedit.math.snapToAngle = function (x1, y1, x2, y2) {
* @returns {boolean} True if rectangles intersect
*/
svgedit.math.rectsIntersect = function (r1, r2) {
- return r2.x < (r1.x + r1.width) &&
- (r2.x + r2.width) > r1.x &&
- r2.y < (r1.y + r1.height) &&
- (r2.y + r2.height) > r1.y;
+ return r2.x < (r1.x + r1.width) &&
+ (r2.x + r2.width) > r1.x &&
+ r2.y < (r1.y + r1.height) &&
+ (r2.y + r2.height) > r1.y;
};
}());
diff --git a/editor/path.js b/editor/path.js
index 46dca2e9..b8f4207f 100644
--- a/editor/path.js
+++ b/editor/path.js
@@ -19,25 +19,25 @@
'use strict';
if (!svgedit.path) {
- svgedit.path = {};
+ svgedit.path = {};
}
var NS = svgedit.NS;
var uiStrings = {
- 'pathNodeTooltip': 'Drag node to move it. Double-click node to change segment type',
- 'pathCtrlPtTooltip': 'Drag control point to adjust curve properties'
+ 'pathNodeTooltip': 'Drag node to move it. Double-click node to change segment type',
+ 'pathCtrlPtTooltip': 'Drag control point to adjust curve properties'
};
var segData = {
- 2: ['x', 'y'],
- 4: ['x', 'y'],
- 6: ['x', 'y', 'x1', 'y1', 'x2', 'y2'],
- 8: ['x', 'y', 'x1', 'y1'],
- 10: ['x', 'y', 'r1', 'r2', 'angle', 'largeArcFlag', 'sweepFlag'],
- 12: ['x'],
- 14: ['y'],
- 16: ['x', 'y', 'x2', 'y2'],
- 18: ['x', 'y']
+ 2: ['x', 'y'],
+ 4: ['x', 'y'],
+ 6: ['x', 'y', 'x1', 'y1', 'x2', 'y2'],
+ 8: ['x', 'y', 'x1', 'y1'],
+ 10: ['x', 'y', 'r1', 'r2', 'angle', 'largeArcFlag', 'sweepFlag'],
+ 12: ['x'],
+ 14: ['y'],
+ 16: ['x', 'y', 'x2', 'y2'],
+ 18: ['x', 'y']
};
var pathFuncs = [];
@@ -49,7 +49,7 @@ var linkControlPts = true;
var pathData = {};
svgedit.path.setLinkControlPoints = function (lcp) {
- linkControlPts = lcp;
+ linkControlPts = lcp;
};
svgedit.path.path = null;
@@ -57,300 +57,300 @@ svgedit.path.path = null;
var editorContext_ = null;
svgedit.path.init = function (editorContext) {
- editorContext_ = editorContext;
+ editorContext_ = editorContext;
- pathFuncs = [0, 'ClosePath'];
- var pathFuncsStrs = ['Moveto', 'Lineto', 'CurvetoCubic', 'CurvetoQuadratic', 'Arc',
- 'LinetoHorizontal', 'LinetoVertical', 'CurvetoCubicSmooth', 'CurvetoQuadraticSmooth'];
- $.each(pathFuncsStrs, function (i, s) {
- pathFuncs.push(s + 'Abs');
- pathFuncs.push(s + 'Rel');
- });
+ pathFuncs = [0, 'ClosePath'];
+ var pathFuncsStrs = ['Moveto', 'Lineto', 'CurvetoCubic', 'CurvetoQuadratic', 'Arc',
+ 'LinetoHorizontal', 'LinetoVertical', 'CurvetoCubicSmooth', 'CurvetoQuadraticSmooth'];
+ $.each(pathFuncsStrs, function (i, s) {
+ pathFuncs.push(s + 'Abs');
+ pathFuncs.push(s + 'Rel');
+ });
};
svgedit.path.insertItemBefore = function (elem, newseg, index) {
- // Support insertItemBefore on paths for FF2
- var list = elem.pathSegList;
+ // Support insertItemBefore on paths for FF2
+ var list = elem.pathSegList;
- if (svgedit.browser.supportsPathInsertItemBefore()) {
- list.insertItemBefore(newseg, index);
- return;
- }
- var len = list.numberOfItems;
- var arr = [];
- var i;
- for (i = 0; i < len; i++) {
- var curSeg = list.getItem(i);
- arr.push(curSeg);
- }
- list.clear();
- for (i = 0; i < len; i++) {
- if (i === index) { // index + 1
- list.appendItem(newseg);
- }
- list.appendItem(arr[i]);
- }
+ if (svgedit.browser.supportsPathInsertItemBefore()) {
+ list.insertItemBefore(newseg, index);
+ return;
+ }
+ var len = list.numberOfItems;
+ var arr = [];
+ var i;
+ for (i = 0; i < len; i++) {
+ var curSeg = list.getItem(i);
+ arr.push(curSeg);
+ }
+ list.clear();
+ for (i = 0; i < len; i++) {
+ if (i === index) { // index + 1
+ list.appendItem(newseg);
+ }
+ list.appendItem(arr[i]);
+ }
};
// TODO: See if this should just live in replacePathSeg
svgedit.path.ptObjToArr = function (type, segItem) {
- var arr = segData[type], len = arr.length;
- var i, out = [];
- for (i = 0; i < len; i++) {
- out[i] = segItem[arr[i]];
- }
- return out;
+ var arr = segData[type], len = arr.length;
+ var i, out = [];
+ for (i = 0; i < len; i++) {
+ out[i] = segItem[arr[i]];
+ }
+ return out;
};
svgedit.path.getGripPt = function (seg, altPt) {
- var out = {
- x: altPt ? altPt.x : seg.item.x,
- y: altPt ? altPt.y : seg.item.y
- }, path = seg.path;
+ var out = {
+ x: altPt ? altPt.x : seg.item.x,
+ y: altPt ? altPt.y : seg.item.y
+ }, path = seg.path;
- if (path.matrix) {
- var pt = svgedit.math.transformPoint(out.x, out.y, path.matrix);
- out = pt;
- }
+ if (path.matrix) {
+ var pt = svgedit.math.transformPoint(out.x, out.y, path.matrix);
+ out = pt;
+ }
- out.x *= editorContext_.getCurrentZoom();
- out.y *= editorContext_.getCurrentZoom();
+ out.x *= editorContext_.getCurrentZoom();
+ out.y *= editorContext_.getCurrentZoom();
- return out;
+ return out;
};
svgedit.path.getPointFromGrip = function (pt, path) {
- var out = {
- x: pt.x,
- y: pt.y
- };
+ var out = {
+ x: pt.x,
+ y: pt.y
+ };
- if (path.matrix) {
- pt = svgedit.math.transformPoint(out.x, out.y, path.imatrix);
- out.x = pt.x;
- out.y = pt.y;
- }
+ if (path.matrix) {
+ pt = svgedit.math.transformPoint(out.x, out.y, path.imatrix);
+ out.x = pt.x;
+ out.y = pt.y;
+ }
- out.x /= editorContext_.getCurrentZoom();
- out.y /= editorContext_.getCurrentZoom();
+ out.x /= editorContext_.getCurrentZoom();
+ out.y /= editorContext_.getCurrentZoom();
- return out;
+ return out;
};
svgedit.path.addPointGrip = function (index, x, y) {
- // create the container of all the point grips
- var pointGripContainer = svgedit.path.getGripContainer();
+ // create the container of all the point grips
+ var pointGripContainer = svgedit.path.getGripContainer();
- var pointGrip = svgedit.utilities.getElem('pathpointgrip_' + index);
- // create it
- if (!pointGrip) {
- pointGrip = document.createElementNS(NS.SVG, 'circle');
- svgedit.utilities.assignAttributes(pointGrip, {
- 'id': 'pathpointgrip_' + index,
- 'display': 'none',
- 'r': 4,
- 'fill': '#0FF',
- 'stroke': '#00F',
- 'stroke-width': 2,
- 'cursor': 'move',
- 'style': 'pointer-events:all',
- 'xlink:title': uiStrings.pathNodeTooltip
- });
- pointGrip = pointGripContainer.appendChild(pointGrip);
+ var pointGrip = svgedit.utilities.getElem('pathpointgrip_' + index);
+ // create it
+ if (!pointGrip) {
+ pointGrip = document.createElementNS(NS.SVG, 'circle');
+ svgedit.utilities.assignAttributes(pointGrip, {
+ 'id': 'pathpointgrip_' + index,
+ 'display': 'none',
+ 'r': 4,
+ 'fill': '#0FF',
+ 'stroke': '#00F',
+ 'stroke-width': 2,
+ 'cursor': 'move',
+ 'style': 'pointer-events:all',
+ 'xlink:title': uiStrings.pathNodeTooltip
+ });
+ pointGrip = pointGripContainer.appendChild(pointGrip);
- var grip = $('#pathpointgrip_' + index);
- grip.dblclick(function () {
- if (svgedit.path.path) {
- svgedit.path.path.setSegType();
- }
- });
- }
- if (x && y) {
- // set up the point grip element and display it
- svgedit.utilities.assignAttributes(pointGrip, {
- 'cx': x,
- 'cy': y,
- 'display': 'inline'
- });
- }
- return pointGrip;
+ var grip = $('#pathpointgrip_' + index);
+ grip.dblclick(function () {
+ if (svgedit.path.path) {
+ svgedit.path.path.setSegType();
+ }
+ });
+ }
+ if (x && y) {
+ // set up the point grip element and display it
+ svgedit.utilities.assignAttributes(pointGrip, {
+ 'cx': x,
+ 'cy': y,
+ 'display': 'inline'
+ });
+ }
+ return pointGrip;
};
svgedit.path.getGripContainer = function () {
- var c = svgedit.utilities.getElem('pathpointgrip_container');
- if (!c) {
- var parent = svgedit.utilities.getElem('selectorParentGroup');
- c = parent.appendChild(document.createElementNS(NS.SVG, 'g'));
- c.id = 'pathpointgrip_container';
- }
- return c;
+ var c = svgedit.utilities.getElem('pathpointgrip_container');
+ if (!c) {
+ var parent = svgedit.utilities.getElem('selectorParentGroup');
+ c = parent.appendChild(document.createElementNS(NS.SVG, 'g'));
+ c.id = 'pathpointgrip_container';
+ }
+ return c;
};
svgedit.path.addCtrlGrip = function (id) {
- var pointGrip = svgedit.utilities.getElem('ctrlpointgrip_' + id);
- if (pointGrip) { return pointGrip; }
+ var pointGrip = svgedit.utilities.getElem('ctrlpointgrip_' + id);
+ if (pointGrip) { return pointGrip; }
- pointGrip = document.createElementNS(NS.SVG, 'circle');
- svgedit.utilities.assignAttributes(pointGrip, {
- 'id': 'ctrlpointgrip_' + id,
- 'display': 'none',
- 'r': 4,
- 'fill': '#0FF',
- 'stroke': '#55F',
- 'stroke-width': 1,
- 'cursor': 'move',
- 'style': 'pointer-events:all',
- 'xlink:title': uiStrings.pathCtrlPtTooltip
- });
- svgedit.path.getGripContainer().appendChild(pointGrip);
- return pointGrip;
+ pointGrip = document.createElementNS(NS.SVG, 'circle');
+ svgedit.utilities.assignAttributes(pointGrip, {
+ 'id': 'ctrlpointgrip_' + id,
+ 'display': 'none',
+ 'r': 4,
+ 'fill': '#0FF',
+ 'stroke': '#55F',
+ 'stroke-width': 1,
+ 'cursor': 'move',
+ 'style': 'pointer-events:all',
+ 'xlink:title': uiStrings.pathCtrlPtTooltip
+ });
+ svgedit.path.getGripContainer().appendChild(pointGrip);
+ return pointGrip;
};
svgedit.path.getCtrlLine = function (id) {
- var ctrlLine = svgedit.utilities.getElem('ctrlLine_' + id);
- if (ctrlLine) { return ctrlLine; }
+ var ctrlLine = svgedit.utilities.getElem('ctrlLine_' + id);
+ if (ctrlLine) { return ctrlLine; }
- ctrlLine = document.createElementNS(NS.SVG, 'line');
- svgedit.utilities.assignAttributes(ctrlLine, {
- 'id': 'ctrlLine_' + id,
- 'stroke': '#555',
- 'stroke-width': 1,
- 'style': 'pointer-events:none'
- });
- svgedit.path.getGripContainer().appendChild(ctrlLine);
- return ctrlLine;
+ ctrlLine = document.createElementNS(NS.SVG, 'line');
+ svgedit.utilities.assignAttributes(ctrlLine, {
+ 'id': 'ctrlLine_' + id,
+ 'stroke': '#555',
+ 'stroke-width': 1,
+ 'style': 'pointer-events:none'
+ });
+ svgedit.path.getGripContainer().appendChild(ctrlLine);
+ return ctrlLine;
};
svgedit.path.getPointGrip = function (seg, update) {
- var index = seg.index;
- var pointGrip = svgedit.path.addPointGrip(index);
+ var index = seg.index;
+ var pointGrip = svgedit.path.addPointGrip(index);
- if (update) {
- var pt = svgedit.path.getGripPt(seg);
- svgedit.utilities.assignAttributes(pointGrip, {
- 'cx': pt.x,
- 'cy': pt.y,
- 'display': 'inline'
- });
- }
+ if (update) {
+ var pt = svgedit.path.getGripPt(seg);
+ svgedit.utilities.assignAttributes(pointGrip, {
+ 'cx': pt.x,
+ 'cy': pt.y,
+ 'display': 'inline'
+ });
+ }
- return pointGrip;
+ return pointGrip;
};
svgedit.path.getControlPoints = function (seg) {
- var item = seg.item;
- var index = seg.index;
- if (!('x1' in item) || !('x2' in item)) { return null; }
- var cpt = {};
- /* var pointGripContainer = */ svgedit.path.getGripContainer();
+ var item = seg.item;
+ var index = seg.index;
+ if (!('x1' in item) || !('x2' in item)) { return null; }
+ var cpt = {};
+ /* var pointGripContainer = */ svgedit.path.getGripContainer();
- // Note that this is intentionally not seg.prev.item
- var prev = svgedit.path.path.segs[index - 1].item;
+ // Note that this is intentionally not seg.prev.item
+ var prev = svgedit.path.path.segs[index - 1].item;
- var segItems = [prev, item];
+ var segItems = [prev, item];
- var i;
- for (i = 1; i < 3; i++) {
- var id = index + 'c' + i;
+ var i;
+ for (i = 1; i < 3; i++) {
+ var id = index + 'c' + i;
- var ctrlLine = cpt['c' + i + '_line'] = svgedit.path.getCtrlLine(id);
+ var ctrlLine = cpt['c' + i + '_line'] = svgedit.path.getCtrlLine(id);
- var pt = svgedit.path.getGripPt(seg, {x: item['x' + i], y: item['y' + i]});
- var gpt = svgedit.path.getGripPt(seg, {x: segItems[i - 1].x, y: segItems[i - 1].y});
+ var pt = svgedit.path.getGripPt(seg, {x: item['x' + i], y: item['y' + i]});
+ var gpt = svgedit.path.getGripPt(seg, {x: segItems[i - 1].x, y: segItems[i - 1].y});
- svgedit.utilities.assignAttributes(ctrlLine, {
- 'x1': pt.x,
- 'y1': pt.y,
- 'x2': gpt.x,
- 'y2': gpt.y,
- 'display': 'inline'
- });
+ svgedit.utilities.assignAttributes(ctrlLine, {
+ 'x1': pt.x,
+ 'y1': pt.y,
+ 'x2': gpt.x,
+ 'y2': gpt.y,
+ 'display': 'inline'
+ });
- cpt['c' + i + '_line'] = ctrlLine;
+ cpt['c' + i + '_line'] = ctrlLine;
- // create it
- var pointGrip = cpt['c' + i] = svgedit.path.addCtrlGrip(id);
+ // create it
+ var pointGrip = cpt['c' + i] = svgedit.path.addCtrlGrip(id);
- svgedit.utilities.assignAttributes(pointGrip, {
- 'cx': pt.x,
- 'cy': pt.y,
- 'display': 'inline'
- });
- cpt['c' + i] = pointGrip;
- }
- return cpt;
+ svgedit.utilities.assignAttributes(pointGrip, {
+ 'cx': pt.x,
+ 'cy': pt.y,
+ 'display': 'inline'
+ });
+ cpt['c' + i] = pointGrip;
+ }
+ return cpt;
};
// This replaces the segment at the given index. Type is given as number.
svgedit.path.replacePathSeg = function (type, index, pts, elem) {
- var path = elem || svgedit.path.path.elem;
+ var path = elem || svgedit.path.path.elem;
- var func = 'createSVGPathSeg' + pathFuncs[type];
- var seg = path[func].apply(path, pts);
+ var func = 'createSVGPathSeg' + pathFuncs[type];
+ var seg = path[func].apply(path, pts);
- if (svgedit.browser.supportsPathReplaceItem()) {
- path.pathSegList.replaceItem(seg, index);
- } else {
- var segList = path.pathSegList;
- var len = segList.numberOfItems;
- var arr = [];
- var i;
- for (i = 0; i < len; i++) {
- var curSeg = segList.getItem(i);
- arr.push(curSeg);
- }
- segList.clear();
- for (i = 0; i < len; i++) {
- if (i === index) {
- segList.appendItem(seg);
- } else {
- segList.appendItem(arr[i]);
- }
- }
- }
+ if (svgedit.browser.supportsPathReplaceItem()) {
+ path.pathSegList.replaceItem(seg, index);
+ } else {
+ var segList = path.pathSegList;
+ var len = segList.numberOfItems;
+ var arr = [];
+ var i;
+ for (i = 0; i < len; i++) {
+ var curSeg = segList.getItem(i);
+ arr.push(curSeg);
+ }
+ segList.clear();
+ for (i = 0; i < len; i++) {
+ if (i === index) {
+ segList.appendItem(seg);
+ } else {
+ segList.appendItem(arr[i]);
+ }
+ }
+ }
};
svgedit.path.getSegSelector = function (seg, update) {
- var index = seg.index;
- var segLine = svgedit.utilities.getElem('segline_' + index);
- if (!segLine) {
- var pointGripContainer = svgedit.path.getGripContainer();
- // create segline
- segLine = document.createElementNS(NS.SVG, 'path');
- svgedit.utilities.assignAttributes(segLine, {
- 'id': 'segline_' + index,
- 'display': 'none',
- 'fill': 'none',
- 'stroke': '#0FF',
- 'stroke-width': 2,
- 'style': 'pointer-events:none',
- 'd': 'M0,0 0,0'
- });
- pointGripContainer.appendChild(segLine);
- }
+ var index = seg.index;
+ var segLine = svgedit.utilities.getElem('segline_' + index);
+ if (!segLine) {
+ var pointGripContainer = svgedit.path.getGripContainer();
+ // create segline
+ segLine = document.createElementNS(NS.SVG, 'path');
+ svgedit.utilities.assignAttributes(segLine, {
+ 'id': 'segline_' + index,
+ 'display': 'none',
+ 'fill': 'none',
+ 'stroke': '#0FF',
+ 'stroke-width': 2,
+ 'style': 'pointer-events:none',
+ 'd': 'M0,0 0,0'
+ });
+ pointGripContainer.appendChild(segLine);
+ }
- if (update) {
- var prev = seg.prev;
- if (!prev) {
- segLine.setAttribute('display', 'none');
- return segLine;
- }
+ if (update) {
+ var prev = seg.prev;
+ if (!prev) {
+ segLine.setAttribute('display', 'none');
+ return segLine;
+ }
- var pt = svgedit.path.getGripPt(prev);
- // Set start point
- svgedit.path.replacePathSeg(2, 0, [pt.x, pt.y], segLine);
+ var pt = svgedit.path.getGripPt(prev);
+ // Set start point
+ svgedit.path.replacePathSeg(2, 0, [pt.x, pt.y], segLine);
- var pts = svgedit.path.ptObjToArr(seg.type, seg.item, true);
- var i;
- for (i = 0; i < pts.length; i += 2) {
- pt = svgedit.path.getGripPt(seg, {x: pts[i], y: pts[i + 1]});
- pts[i] = pt.x;
- pts[i + 1] = pt.y;
- }
+ var pts = svgedit.path.ptObjToArr(seg.type, seg.item, true);
+ var i;
+ for (i = 0; i < pts.length; i += 2) {
+ pt = svgedit.path.getGripPt(seg, {x: pts[i], y: pts[i + 1]});
+ pts[i] = pt.x;
+ pts[i + 1] = pt.y;
+ }
- svgedit.path.replacePathSeg(seg.type, 1, pts, segLine);
- }
- return segLine;
+ svgedit.path.replacePathSeg(seg.type, 1, pts, segLine);
+ }
+ return segLine;
};
// Function: smoothControlPoints
@@ -364,571 +364,571 @@ svgedit.path.getSegSelector = function (seg, update) {
// Returns:
// Array of two "smoothed" point objects
svgedit.path.smoothControlPoints = function (ct1, ct2, pt) {
- // each point must not be the origin
- var x1 = ct1.x - pt.x,
- y1 = ct1.y - pt.y,
- x2 = ct2.x - pt.x,
- y2 = ct2.y - pt.y;
+ // each point must not be the origin
+ var x1 = ct1.x - pt.x,
+ y1 = ct1.y - pt.y,
+ x2 = ct2.x - pt.x,
+ y2 = ct2.y - pt.y;
- if ((x1 !== 0 || y1 !== 0) && (x2 !== 0 || y2 !== 0)) {
- var anglea = Math.atan2(y1, x1),
- angleb = Math.atan2(y2, x2),
- r1 = Math.sqrt(x1 * x1 + y1 * y1),
- r2 = Math.sqrt(x2 * x2 + y2 * y2),
- nct1 = editorContext_.getSVGRoot().createSVGPoint(),
- nct2 = editorContext_.getSVGRoot().createSVGPoint();
- if (anglea < 0) { anglea += 2 * Math.PI; }
- if (angleb < 0) { angleb += 2 * Math.PI; }
+ if ((x1 !== 0 || y1 !== 0) && (x2 !== 0 || y2 !== 0)) {
+ var anglea = Math.atan2(y1, x1),
+ angleb = Math.atan2(y2, x2),
+ r1 = Math.sqrt(x1 * x1 + y1 * y1),
+ r2 = Math.sqrt(x2 * x2 + y2 * y2),
+ nct1 = editorContext_.getSVGRoot().createSVGPoint(),
+ nct2 = editorContext_.getSVGRoot().createSVGPoint();
+ if (anglea < 0) { anglea += 2 * Math.PI; }
+ if (angleb < 0) { angleb += 2 * Math.PI; }
- var angleBetween = Math.abs(anglea - angleb),
- angleDiff = Math.abs(Math.PI - angleBetween) / 2;
+ var angleBetween = Math.abs(anglea - angleb),
+ angleDiff = Math.abs(Math.PI - angleBetween) / 2;
- var newAnglea, newAngleb;
- if (anglea - angleb > 0) {
- newAnglea = angleBetween < Math.PI ? (anglea + angleDiff) : (anglea - angleDiff);
- newAngleb = angleBetween < Math.PI ? (angleb - angleDiff) : (angleb + angleDiff);
- } else {
- newAnglea = angleBetween < Math.PI ? (anglea - angleDiff) : (anglea + angleDiff);
- newAngleb = angleBetween < Math.PI ? (angleb + angleDiff) : (angleb - angleDiff);
- }
+ var newAnglea, newAngleb;
+ if (anglea - angleb > 0) {
+ newAnglea = angleBetween < Math.PI ? (anglea + angleDiff) : (anglea - angleDiff);
+ newAngleb = angleBetween < Math.PI ? (angleb - angleDiff) : (angleb + angleDiff);
+ } else {
+ newAnglea = angleBetween < Math.PI ? (anglea - angleDiff) : (anglea + angleDiff);
+ newAngleb = angleBetween < Math.PI ? (angleb + angleDiff) : (angleb - angleDiff);
+ }
- // rotate the points
- nct1.x = r1 * Math.cos(newAnglea) + pt.x;
- nct1.y = r1 * Math.sin(newAnglea) + pt.y;
- nct2.x = r2 * Math.cos(newAngleb) + pt.x;
- nct2.y = r2 * Math.sin(newAngleb) + pt.y;
+ // rotate the points
+ nct1.x = r1 * Math.cos(newAnglea) + pt.x;
+ nct1.y = r1 * Math.sin(newAnglea) + pt.y;
+ nct2.x = r2 * Math.cos(newAngleb) + pt.x;
+ nct2.y = r2 * Math.sin(newAngleb) + pt.y;
- return [nct1, nct2];
- }
- return undefined;
+ return [nct1, nct2];
+ }
+ return undefined;
};
svgedit.path.Segment = function (index, item) {
- this.selected = false;
- this.index = index;
- this.item = item;
- this.type = item.pathSegType;
+ this.selected = false;
+ this.index = index;
+ this.item = item;
+ this.type = item.pathSegType;
- this.ctrlpts = [];
- this.ptgrip = null;
- this.segsel = null;
+ this.ctrlpts = [];
+ this.ptgrip = null;
+ this.segsel = null;
};
svgedit.path.Segment.prototype.showCtrlPts = function (y) {
- var i;
- for (i in this.ctrlpts) {
- if (this.ctrlpts.hasOwnProperty(i)) {
- this.ctrlpts[i].setAttribute('display', y ? 'inline' : 'none');
- }
- }
+ var i;
+ for (i in this.ctrlpts) {
+ if (this.ctrlpts.hasOwnProperty(i)) {
+ this.ctrlpts[i].setAttribute('display', y ? 'inline' : 'none');
+ }
+ }
};
svgedit.path.Segment.prototype.selectCtrls = function (y) {
- $('#ctrlpointgrip_' + this.index + 'c1, #ctrlpointgrip_' + this.index + 'c2')
- .attr('fill', y ? '#0FF' : '#EEE');
+ $('#ctrlpointgrip_' + this.index + 'c1, #ctrlpointgrip_' + this.index + 'c2')
+ .attr('fill', y ? '#0FF' : '#EEE');
};
svgedit.path.Segment.prototype.show = function (y) {
- if (this.ptgrip) {
- this.ptgrip.setAttribute('display', y ? 'inline' : 'none');
- this.segsel.setAttribute('display', y ? 'inline' : 'none');
- // Show/hide all control points if available
- this.showCtrlPts(y);
- }
+ if (this.ptgrip) {
+ this.ptgrip.setAttribute('display', y ? 'inline' : 'none');
+ this.segsel.setAttribute('display', y ? 'inline' : 'none');
+ // Show/hide all control points if available
+ this.showCtrlPts(y);
+ }
};
svgedit.path.Segment.prototype.select = function (y) {
- if (this.ptgrip) {
- this.ptgrip.setAttribute('stroke', y ? '#0FF' : '#00F');
- this.segsel.setAttribute('display', y ? 'inline' : 'none');
- if (this.ctrlpts) {
- this.selectCtrls(y);
- }
- this.selected = y;
- }
+ if (this.ptgrip) {
+ this.ptgrip.setAttribute('stroke', y ? '#0FF' : '#00F');
+ this.segsel.setAttribute('display', y ? 'inline' : 'none');
+ if (this.ctrlpts) {
+ this.selectCtrls(y);
+ }
+ this.selected = y;
+ }
};
svgedit.path.Segment.prototype.addGrip = function () {
- this.ptgrip = svgedit.path.getPointGrip(this, true);
- this.ctrlpts = svgedit.path.getControlPoints(this, true);
- this.segsel = svgedit.path.getSegSelector(this, true);
+ this.ptgrip = svgedit.path.getPointGrip(this, true);
+ this.ctrlpts = svgedit.path.getControlPoints(this, true);
+ this.segsel = svgedit.path.getSegSelector(this, true);
};
svgedit.path.Segment.prototype.update = function (full) {
- if (this.ptgrip) {
- var pt = svgedit.path.getGripPt(this);
- svgedit.utilities.assignAttributes(this.ptgrip, {
- 'cx': pt.x,
- 'cy': pt.y
- });
+ if (this.ptgrip) {
+ var pt = svgedit.path.getGripPt(this);
+ svgedit.utilities.assignAttributes(this.ptgrip, {
+ 'cx': pt.x,
+ 'cy': pt.y
+ });
- svgedit.path.getSegSelector(this, true);
+ svgedit.path.getSegSelector(this, true);
- if (this.ctrlpts) {
- if (full) {
- this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
- this.type = this.item.pathSegType;
- }
- svgedit.path.getControlPoints(this);
- }
- // this.segsel.setAttribute('display', y?'inline':'none');
- }
+ if (this.ctrlpts) {
+ if (full) {
+ this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
+ this.type = this.item.pathSegType;
+ }
+ svgedit.path.getControlPoints(this);
+ }
+ // this.segsel.setAttribute('display', y?'inline':'none');
+ }
};
svgedit.path.Segment.prototype.move = function (dx, dy) {
- var curPts, item = this.item;
+ var curPts, item = this.item;
- if (this.ctrlpts) {
- curPts = [item.x += dx, item.y += dy,
- item.x1, item.y1, item.x2 += dx, item.y2 += dy];
- } else {
- curPts = [item.x += dx, item.y += dy];
- }
+ if (this.ctrlpts) {
+ curPts = [item.x += dx, item.y += dy,
+ item.x1, item.y1, item.x2 += dx, item.y2 += dy];
+ } else {
+ curPts = [item.x += dx, item.y += dy];
+ }
- svgedit.path.replacePathSeg(this.type, this.index, curPts);
+ svgedit.path.replacePathSeg(this.type, this.index, curPts);
- if (this.next && this.next.ctrlpts) {
- var next = this.next.item;
- var nextPts = [next.x, next.y,
- next.x1 += dx, next.y1 += dy, next.x2, next.y2];
- svgedit.path.replacePathSeg(this.next.type, this.next.index, nextPts);
- }
+ if (this.next && this.next.ctrlpts) {
+ var next = this.next.item;
+ var nextPts = [next.x, next.y,
+ next.x1 += dx, next.y1 += dy, next.x2, next.y2];
+ svgedit.path.replacePathSeg(this.next.type, this.next.index, nextPts);
+ }
- if (this.mate) {
- // The last point of a closed subpath has a 'mate',
- // which is the 'M' segment of the subpath
- item = this.mate.item;
- var pts = [item.x += dx, item.y += dy];
- svgedit.path.replacePathSeg(this.mate.type, this.mate.index, pts);
- // Has no grip, so does not need 'updating'?
- }
+ if (this.mate) {
+ // The last point of a closed subpath has a 'mate',
+ // which is the 'M' segment of the subpath
+ item = this.mate.item;
+ var pts = [item.x += dx, item.y += dy];
+ svgedit.path.replacePathSeg(this.mate.type, this.mate.index, pts);
+ // Has no grip, so does not need 'updating'?
+ }
- this.update(true);
- if (this.next) { this.next.update(true); }
+ this.update(true);
+ if (this.next) { this.next.update(true); }
};
svgedit.path.Segment.prototype.setLinked = function (num) {
- var seg, anum, pt;
- if (num === 2) {
- anum = 1;
- seg = this.next;
- if (!seg) { return; }
- pt = this.item;
- } else {
- anum = 2;
- seg = this.prev;
- if (!seg) { return; }
- pt = seg.item;
- }
+ var seg, anum, pt;
+ if (num === 2) {
+ anum = 1;
+ seg = this.next;
+ if (!seg) { return; }
+ pt = this.item;
+ } else {
+ anum = 2;
+ seg = this.prev;
+ if (!seg) { return; }
+ pt = seg.item;
+ }
- var item = seg.item;
- item['x' + anum] = pt.x + (pt.x - this.item['x' + num]);
- item['y' + anum] = pt.y + (pt.y - this.item['y' + num]);
+ var item = seg.item;
+ item['x' + anum] = pt.x + (pt.x - this.item['x' + num]);
+ item['y' + anum] = pt.y + (pt.y - this.item['y' + num]);
- var pts = [item.x, item.y,
- item.x1, item.y1,
- item.x2, item.y2];
+ var pts = [item.x, item.y,
+ item.x1, item.y1,
+ item.x2, item.y2];
- svgedit.path.replacePathSeg(seg.type, seg.index, pts);
- seg.update(true);
+ svgedit.path.replacePathSeg(seg.type, seg.index, pts);
+ seg.update(true);
};
svgedit.path.Segment.prototype.moveCtrl = function (num, dx, dy) {
- var item = this.item;
- item['x' + num] += dx;
- item['y' + num] += dy;
+ var item = this.item;
+ item['x' + num] += dx;
+ item['y' + num] += dy;
- var pts = [item.x, item.y,
- item.x1, item.y1, item.x2, item.y2];
+ var pts = [item.x, item.y,
+ item.x1, item.y1, item.x2, item.y2];
- svgedit.path.replacePathSeg(this.type, this.index, pts);
- this.update(true);
+ svgedit.path.replacePathSeg(this.type, this.index, pts);
+ this.update(true);
};
svgedit.path.Segment.prototype.setType = function (newType, pts) {
- svgedit.path.replacePathSeg(newType, this.index, pts);
- this.type = newType;
- this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
- this.showCtrlPts(newType === 6);
- this.ctrlpts = svgedit.path.getControlPoints(this);
- this.update(true);
+ svgedit.path.replacePathSeg(newType, this.index, pts);
+ this.type = newType;
+ this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
+ this.showCtrlPts(newType === 6);
+ this.ctrlpts = svgedit.path.getControlPoints(this);
+ this.update(true);
};
svgedit.path.Path = function (elem) {
- if (!elem || elem.tagName !== 'path') {
- throw new Error('svgedit.path.Path constructed without a element');
- }
+ if (!elem || elem.tagName !== 'path') {
+ throw new Error('svgedit.path.Path constructed without a element');
+ }
- this.elem = elem;
- this.segs = [];
- this.selected_pts = [];
- svgedit.path.path = this;
+ this.elem = elem;
+ this.segs = [];
+ this.selected_pts = [];
+ svgedit.path.path = this;
- this.init();
+ this.init();
};
// Reset path data
svgedit.path.Path.prototype.init = function () {
- // Hide all grips, etc
+ // Hide all grips, etc
- // fixed, needed to work on all found elements, not just first
- $(svgedit.path.getGripContainer()).find('*').each(function () {
- $(this).attr('display', 'none');
- });
+ // fixed, needed to work on all found elements, not just first
+ $(svgedit.path.getGripContainer()).find('*').each(function () {
+ $(this).attr('display', 'none');
+ });
- var segList = this.elem.pathSegList;
- var len = segList.numberOfItems;
- this.segs = [];
- this.selected_pts = [];
- this.first_seg = null;
+ var segList = this.elem.pathSegList;
+ var len = segList.numberOfItems;
+ this.segs = [];
+ this.selected_pts = [];
+ this.first_seg = null;
- // Set up segs array
- var i;
- for (i = 0; i < len; i++) {
- var item = segList.getItem(i);
- var segment = new svgedit.path.Segment(i, item);
- segment.path = this;
- this.segs.push(segment);
- }
+ // Set up segs array
+ var i;
+ for (i = 0; i < len; i++) {
+ var item = segList.getItem(i);
+ var segment = new svgedit.path.Segment(i, item);
+ segment.path = this;
+ this.segs.push(segment);
+ }
- var segs = this.segs;
- var startI = null;
+ var segs = this.segs;
+ var startI = null;
- for (i = 0; i < len; i++) {
- var seg = segs[i];
- var nextSeg = (i + 1) >= len ? null : segs[i + 1];
- var prevSeg = (i - 1) < 0 ? null : segs[i - 1];
- var startSeg;
- if (seg.type === 2) {
- if (prevSeg && prevSeg.type !== 1) {
- // New sub-path, last one is open,
- // so add a grip to last sub-path's first point
- startSeg = segs[startI];
- startSeg.next = segs[startI + 1];
- startSeg.next.prev = startSeg;
- startSeg.addGrip();
- }
- // Remember that this is a starter seg
- startI = i;
- } else if (nextSeg && nextSeg.type === 1) {
- // This is the last real segment of a closed sub-path
- // Next is first seg after "M"
- seg.next = segs[startI + 1];
+ for (i = 0; i < len; i++) {
+ var seg = segs[i];
+ var nextSeg = (i + 1) >= len ? null : segs[i + 1];
+ var prevSeg = (i - 1) < 0 ? null : segs[i - 1];
+ var startSeg;
+ if (seg.type === 2) {
+ if (prevSeg && prevSeg.type !== 1) {
+ // New sub-path, last one is open,
+ // so add a grip to last sub-path's first point
+ startSeg = segs[startI];
+ startSeg.next = segs[startI + 1];
+ startSeg.next.prev = startSeg;
+ startSeg.addGrip();
+ }
+ // Remember that this is a starter seg
+ startI = i;
+ } else if (nextSeg && nextSeg.type === 1) {
+ // This is the last real segment of a closed sub-path
+ // Next is first seg after "M"
+ seg.next = segs[startI + 1];
- // First seg after "M"'s prev is this
- seg.next.prev = seg;
- seg.mate = segs[startI];
- seg.addGrip();
- if (this.first_seg == null) {
- this.first_seg = seg;
- }
- } else if (!nextSeg) {
- if (seg.type !== 1) {
- // Last seg, doesn't close so add a grip
- // to last sub-path's first point
- startSeg = segs[startI];
- startSeg.next = segs[startI + 1];
- startSeg.next.prev = startSeg;
- startSeg.addGrip();
- seg.addGrip();
+ // First seg after "M"'s prev is this
+ seg.next.prev = seg;
+ seg.mate = segs[startI];
+ seg.addGrip();
+ if (this.first_seg == null) {
+ this.first_seg = seg;
+ }
+ } else if (!nextSeg) {
+ if (seg.type !== 1) {
+ // Last seg, doesn't close so add a grip
+ // to last sub-path's first point
+ startSeg = segs[startI];
+ startSeg.next = segs[startI + 1];
+ startSeg.next.prev = startSeg;
+ startSeg.addGrip();
+ seg.addGrip();
- if (!this.first_seg) {
- // Open path, so set first as real first and add grip
- this.first_seg = segs[startI];
- }
- }
- } else if (seg.type !== 1) {
- // Regular segment, so add grip and its "next"
- seg.addGrip();
+ if (!this.first_seg) {
+ // Open path, so set first as real first and add grip
+ this.first_seg = segs[startI];
+ }
+ }
+ } else if (seg.type !== 1) {
+ // Regular segment, so add grip and its "next"
+ seg.addGrip();
- // Don't set its "next" if it's an "M"
- if (nextSeg && nextSeg.type !== 2) {
- seg.next = nextSeg;
- seg.next.prev = seg;
- }
- }
- }
- return this;
+ // Don't set its "next" if it's an "M"
+ if (nextSeg && nextSeg.type !== 2) {
+ seg.next = nextSeg;
+ seg.next.prev = seg;
+ }
+ }
+ }
+ return this;
};
svgedit.path.Path.prototype.eachSeg = function (fn) {
- var i;
- var len = this.segs.length;
- for (i = 0; i < len; i++) {
- var ret = fn.call(this.segs[i], i);
- if (ret === false) { break; }
- }
+ var i;
+ var len = this.segs.length;
+ for (i = 0; i < len; i++) {
+ var ret = fn.call(this.segs[i], i);
+ if (ret === false) { break; }
+ }
};
svgedit.path.Path.prototype.addSeg = function (index) {
- // Adds a new segment
- var seg = this.segs[index];
- if (!seg.prev) { return; }
+ // Adds a new segment
+ var seg = this.segs[index];
+ if (!seg.prev) { return; }
- var prev = seg.prev;
- var newseg, newX, newY;
- switch (seg.item.pathSegType) {
- case 4:
- newX = (seg.item.x + prev.item.x) / 2;
- newY = (seg.item.y + prev.item.y) / 2;
- newseg = this.elem.createSVGPathSegLinetoAbs(newX, newY);
- break;
- case 6: // make it a curved segment to preserve the shape (WRS)
- // http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm#Geometric_interpretation
- var p0x = (prev.item.x + seg.item.x1) / 2;
- var p1x = (seg.item.x1 + seg.item.x2) / 2;
- var p2x = (seg.item.x2 + seg.item.x) / 2;
- var p01x = (p0x + p1x) / 2;
- var p12x = (p1x + p2x) / 2;
- newX = (p01x + p12x) / 2;
- var p0y = (prev.item.y + seg.item.y1) / 2;
- var p1y = (seg.item.y1 + seg.item.y2) / 2;
- var p2y = (seg.item.y2 + seg.item.y) / 2;
- var p01y = (p0y + p1y) / 2;
- var p12y = (p1y + p2y) / 2;
- newY = (p01y + p12y) / 2;
- newseg = this.elem.createSVGPathSegCurvetoCubicAbs(newX, newY, p0x, p0y, p01x, p01y);
- var pts = [seg.item.x, seg.item.y, p12x, p12y, p2x, p2y];
- svgedit.path.replacePathSeg(seg.type, index, pts);
- break;
- }
+ var prev = seg.prev;
+ var newseg, newX, newY;
+ switch (seg.item.pathSegType) {
+ case 4:
+ newX = (seg.item.x + prev.item.x) / 2;
+ newY = (seg.item.y + prev.item.y) / 2;
+ newseg = this.elem.createSVGPathSegLinetoAbs(newX, newY);
+ break;
+ case 6: // make it a curved segment to preserve the shape (WRS)
+ // http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm#Geometric_interpretation
+ var p0x = (prev.item.x + seg.item.x1) / 2;
+ var p1x = (seg.item.x1 + seg.item.x2) / 2;
+ var p2x = (seg.item.x2 + seg.item.x) / 2;
+ var p01x = (p0x + p1x) / 2;
+ var p12x = (p1x + p2x) / 2;
+ newX = (p01x + p12x) / 2;
+ var p0y = (prev.item.y + seg.item.y1) / 2;
+ var p1y = (seg.item.y1 + seg.item.y2) / 2;
+ var p2y = (seg.item.y2 + seg.item.y) / 2;
+ var p01y = (p0y + p1y) / 2;
+ var p12y = (p1y + p2y) / 2;
+ newY = (p01y + p12y) / 2;
+ newseg = this.elem.createSVGPathSegCurvetoCubicAbs(newX, newY, p0x, p0y, p01x, p01y);
+ var pts = [seg.item.x, seg.item.y, p12x, p12y, p2x, p2y];
+ svgedit.path.replacePathSeg(seg.type, index, pts);
+ break;
+ }
- svgedit.path.insertItemBefore(this.elem, newseg, index);
+ svgedit.path.insertItemBefore(this.elem, newseg, index);
};
svgedit.path.Path.prototype.deleteSeg = function (index) {
- var seg = this.segs[index];
- var list = this.elem.pathSegList;
+ var seg = this.segs[index];
+ var list = this.elem.pathSegList;
- seg.show(false);
- var next = seg.next;
- var pt;
- if (seg.mate) {
- // Make the next point be the "M" point
- pt = [next.item.x, next.item.y];
- svgedit.path.replacePathSeg(2, next.index, pt);
+ seg.show(false);
+ var next = seg.next;
+ var pt;
+ if (seg.mate) {
+ // Make the next point be the "M" point
+ pt = [next.item.x, next.item.y];
+ svgedit.path.replacePathSeg(2, next.index, pt);
- // Reposition last node
- svgedit.path.replacePathSeg(4, seg.index, pt);
+ // Reposition last node
+ svgedit.path.replacePathSeg(4, seg.index, pt);
- list.removeItem(seg.mate.index);
- } else if (!seg.prev) {
- // First node of open path, make next point the M
- // var item = seg.item;
- pt = [next.item.x, next.item.y];
- svgedit.path.replacePathSeg(2, seg.next.index, pt);
- list.removeItem(index);
- } else {
- list.removeItem(index);
- }
+ list.removeItem(seg.mate.index);
+ } else if (!seg.prev) {
+ // First node of open path, make next point the M
+ // var item = seg.item;
+ pt = [next.item.x, next.item.y];
+ svgedit.path.replacePathSeg(2, seg.next.index, pt);
+ list.removeItem(index);
+ } else {
+ list.removeItem(index);
+ }
};
svgedit.path.Path.prototype.subpathIsClosed = function (index) {
- var closed = false;
- // Check if subpath is already open
- svgedit.path.path.eachSeg(function (i) {
- if (i <= index) { return true; }
- if (this.type === 2) {
- // Found M first, so open
- return false;
- }
- if (this.type === 1) {
- // Found Z first, so closed
- closed = true;
- return false;
- }
- });
+ var closed = false;
+ // Check if subpath is already open
+ svgedit.path.path.eachSeg(function (i) {
+ if (i <= index) { return true; }
+ if (this.type === 2) {
+ // Found M first, so open
+ return false;
+ }
+ if (this.type === 1) {
+ // Found Z first, so closed
+ closed = true;
+ return false;
+ }
+ });
- return closed;
+ return closed;
};
svgedit.path.Path.prototype.removePtFromSelection = function (index) {
- var pos = this.selected_pts.indexOf(index);
- if (pos === -1) {
- return;
- }
- this.segs[index].select(false);
- this.selected_pts.splice(pos, 1);
+ var pos = this.selected_pts.indexOf(index);
+ if (pos === -1) {
+ return;
+ }
+ this.segs[index].select(false);
+ this.selected_pts.splice(pos, 1);
};
svgedit.path.Path.prototype.clearSelection = function () {
- this.eachSeg(function () {
- // 'this' is the segment here
- this.select(false);
- });
- this.selected_pts = [];
+ this.eachSeg(function () {
+ // 'this' is the segment here
+ this.select(false);
+ });
+ this.selected_pts = [];
};
svgedit.path.Path.prototype.storeD = function () {
- this.last_d = this.elem.getAttribute('d');
+ this.last_d = this.elem.getAttribute('d');
};
svgedit.path.Path.prototype.show = function (y) {
- // Shows this path's segment grips
- this.eachSeg(function () {
- // 'this' is the segment here
- this.show(y);
- });
- if (y) {
- this.selectPt(this.first_seg.index);
- }
- return this;
+ // Shows this path's segment grips
+ this.eachSeg(function () {
+ // 'this' is the segment here
+ this.show(y);
+ });
+ if (y) {
+ this.selectPt(this.first_seg.index);
+ }
+ return this;
};
// Move selected points
svgedit.path.Path.prototype.movePts = function (dx, dy) {
- var i = this.selected_pts.length;
- while (i--) {
- var seg = this.segs[this.selected_pts[i]];
- seg.move(dx, dy);
- }
+ var i = this.selected_pts.length;
+ while (i--) {
+ var seg = this.segs[this.selected_pts[i]];
+ seg.move(dx, dy);
+ }
};
svgedit.path.Path.prototype.moveCtrl = function (dx, dy) {
- var seg = this.segs[this.selected_pts[0]];
- seg.moveCtrl(this.dragctrl, dx, dy);
- if (linkControlPts) {
- seg.setLinked(this.dragctrl);
- }
+ var seg = this.segs[this.selected_pts[0]];
+ seg.moveCtrl(this.dragctrl, dx, dy);
+ if (linkControlPts) {
+ seg.setLinked(this.dragctrl);
+ }
};
svgedit.path.Path.prototype.setSegType = function (newType) {
- this.storeD();
- var i = this.selected_pts.length;
- var text;
- while (i--) {
- var selPt = this.selected_pts[i];
+ this.storeD();
+ var i = this.selected_pts.length;
+ var text;
+ while (i--) {
+ var selPt = this.selected_pts[i];
- // Selected seg
- var cur = this.segs[selPt];
- var prev = cur.prev;
- if (!prev) { continue; }
+ // Selected seg
+ var cur = this.segs[selPt];
+ var prev = cur.prev;
+ if (!prev) { continue; }
- if (!newType) { // double-click, so just toggle
- text = 'Toggle Path Segment Type';
+ if (!newType) { // double-click, so just toggle
+ text = 'Toggle Path Segment Type';
- // Toggle segment to curve/straight line
- var oldType = cur.type;
+ // Toggle segment to curve/straight line
+ var oldType = cur.type;
- newType = (oldType === 6) ? 4 : 6;
- }
+ newType = (oldType === 6) ? 4 : 6;
+ }
- newType = Number(newType);
+ newType = Number(newType);
- var curX = cur.item.x;
- var curY = cur.item.y;
- var prevX = prev.item.x;
- var prevY = prev.item.y;
- var points;
- switch (newType) {
- case 6:
- if (cur.olditem) {
- var old = cur.olditem;
- points = [curX, curY, old.x1, old.y1, old.x2, old.y2];
- } else {
- var diffX = curX - prevX;
- var diffY = curY - prevY;
- // get control points from straight line segment
- /*
- var ct1x = (prevX + (diffY/2));
- var ct1y = (prevY - (diffX/2));
- var ct2x = (curX + (diffY/2));
- var ct2y = (curY - (diffX/2));
- */
- // create control points on the line to preserve the shape (WRS)
- var ct1x = (prevX + (diffX / 3));
- var ct1y = (prevY + (diffY / 3));
- var ct2x = (curX - (diffX / 3));
- var ct2y = (curY - (diffY / 3));
- points = [curX, curY, ct1x, ct1y, ct2x, ct2y];
- }
- break;
- case 4:
- points = [curX, curY];
+ var curX = cur.item.x;
+ var curY = cur.item.y;
+ var prevX = prev.item.x;
+ var prevY = prev.item.y;
+ var points;
+ switch (newType) {
+ case 6:
+ if (cur.olditem) {
+ var old = cur.olditem;
+ points = [curX, curY, old.x1, old.y1, old.x2, old.y2];
+ } else {
+ var diffX = curX - prevX;
+ var diffY = curY - prevY;
+ // get control points from straight line segment
+ /*
+ var ct1x = (prevX + (diffY/2));
+ var ct1y = (prevY - (diffX/2));
+ var ct2x = (curX + (diffY/2));
+ var ct2y = (curY - (diffX/2));
+ */
+ // create control points on the line to preserve the shape (WRS)
+ var ct1x = (prevX + (diffX / 3));
+ var ct1y = (prevY + (diffY / 3));
+ var ct2x = (curX - (diffX / 3));
+ var ct2y = (curY - (diffY / 3));
+ points = [curX, curY, ct1x, ct1y, ct2x, ct2y];
+ }
+ break;
+ case 4:
+ points = [curX, curY];
- // Store original prevve segment nums
- cur.olditem = cur.item;
- break;
- }
+ // Store original prevve segment nums
+ cur.olditem = cur.item;
+ break;
+ }
- cur.setType(newType, points);
- }
- svgedit.path.path.endChanges(text);
+ cur.setType(newType, points);
+ }
+ svgedit.path.path.endChanges(text);
};
svgedit.path.Path.prototype.selectPt = function (pt, ctrlNum) {
- this.clearSelection();
- if (pt == null) {
- this.eachSeg(function (i) {
- // 'this' is the segment here.
- if (this.prev) {
- pt = i;
- }
- });
- }
- this.addPtsToSelection(pt);
- if (ctrlNum) {
- this.dragctrl = ctrlNum;
+ this.clearSelection();
+ if (pt == null) {
+ this.eachSeg(function (i) {
+ // 'this' is the segment here.
+ if (this.prev) {
+ pt = i;
+ }
+ });
+ }
+ this.addPtsToSelection(pt);
+ if (ctrlNum) {
+ this.dragctrl = ctrlNum;
- if (linkControlPts) {
- this.segs[pt].setLinked(ctrlNum);
- }
- }
+ if (linkControlPts) {
+ this.segs[pt].setLinked(ctrlNum);
+ }
+ }
};
// Update position of all points
svgedit.path.Path.prototype.update = function () {
- var elem = this.elem;
- if (svgedit.utilities.getRotationAngle(elem)) {
- this.matrix = svgedit.math.getMatrix(elem);
- this.imatrix = this.matrix.inverse();
- } else {
- this.matrix = null;
- this.imatrix = null;
- }
+ var elem = this.elem;
+ if (svgedit.utilities.getRotationAngle(elem)) {
+ this.matrix = svgedit.math.getMatrix(elem);
+ this.imatrix = this.matrix.inverse();
+ } else {
+ this.matrix = null;
+ this.imatrix = null;
+ }
- this.eachSeg(function (i) {
- this.item = elem.pathSegList.getItem(i);
- this.update();
- });
+ this.eachSeg(function (i) {
+ this.item = elem.pathSegList.getItem(i);
+ this.update();
+ });
- return this;
+ return this;
};
svgedit.path.getPath_ = function (elem) {
- var p = pathData[elem.id];
- if (!p) {
- p = pathData[elem.id] = new svgedit.path.Path(elem);
- }
- return p;
+ var p = pathData[elem.id];
+ if (!p) {
+ p = pathData[elem.id] = new svgedit.path.Path(elem);
+ }
+ return p;
};
svgedit.path.removePath_ = function (id) {
- if (id in pathData) { delete pathData[id]; }
+ if (id in pathData) { delete pathData[id]; }
};
var newcx, newcy, oldcx, oldcy, angle;
var getRotVals = function (x, y) {
- var dx = x - oldcx;
- var dy = y - oldcy;
+ var dx = x - oldcx;
+ var dy = y - oldcy;
- // rotate the point around the old center
- var r = Math.sqrt(dx * dx + dy * dy);
- var theta = Math.atan2(dy, dx) + angle;
- dx = r * Math.cos(theta) + oldcx;
- dy = r * Math.sin(theta) + oldcy;
+ // rotate the point around the old center
+ var r = Math.sqrt(dx * dx + dy * dy);
+ var theta = Math.atan2(dy, dx) + angle;
+ dx = r * Math.cos(theta) + oldcx;
+ dy = r * Math.sin(theta) + oldcy;
- // dx,dy should now hold the actual coordinates of each
- // point after being rotated
+ // dx,dy should now hold the actual coordinates of each
+ // point after being rotated
- // now we want to rotate them around the new center in the reverse direction
- dx -= newcx;
- dy -= newcy;
+ // now we want to rotate them around the new center in the reverse direction
+ dx -= newcx;
+ dy -= newcy;
- r = Math.sqrt(dx * dx + dy * dy);
- theta = Math.atan2(dy, dx) - angle;
+ r = Math.sqrt(dx * dx + dy * dy);
+ theta = Math.atan2(dy, dx) - angle;
- return {'x': r * Math.cos(theta) + newcx,
- 'y': r * Math.sin(theta) + newcy};
+ return {'x': r * Math.cos(theta) + newcx,
+ 'y': r * Math.sin(theta) + newcy};
};
// If the path was rotated, we must now pay the piper:
@@ -939,59 +939,59 @@ var getRotVals = function (x, y) {
// TODO: This is still using ye olde transform methods, can probably
// be optimized or even taken care of by recalculateDimensions
svgedit.path.recalcRotatedPath = function () {
- var currentPath = svgedit.path.path.elem;
- angle = svgedit.utilities.getRotationAngle(currentPath, true);
- if (!angle) { return; }
- // selectedBBoxes[0] = svgedit.path.path.oldbbox;
- var box = svgedit.utilities.getBBox(currentPath),
- oldbox = svgedit.path.path.oldbbox; // selectedBBoxes[0],
- oldcx = oldbox.x + oldbox.width / 2;
- oldcy = oldbox.y + oldbox.height / 2;
- newcx = box.x + box.width / 2;
- newcy = box.y + box.height / 2;
+ var currentPath = svgedit.path.path.elem;
+ angle = svgedit.utilities.getRotationAngle(currentPath, true);
+ if (!angle) { return; }
+ // selectedBBoxes[0] = svgedit.path.path.oldbbox;
+ var box = svgedit.utilities.getBBox(currentPath),
+ oldbox = svgedit.path.path.oldbbox; // selectedBBoxes[0],
+ oldcx = oldbox.x + oldbox.width / 2;
+ oldcy = oldbox.y + oldbox.height / 2;
+ newcx = box.x + box.width / 2;
+ newcy = box.y + box.height / 2;
- // un-rotate the new center to the proper position
- var dx = newcx - oldcx,
- dy = newcy - oldcy,
- r = Math.sqrt(dx * dx + dy * dy),
- theta = Math.atan2(dy, dx) + angle;
+ // un-rotate the new center to the proper position
+ var dx = newcx - oldcx,
+ dy = newcy - oldcy,
+ r = Math.sqrt(dx * dx + dy * dy),
+ theta = Math.atan2(dy, dx) + angle;
- newcx = r * Math.cos(theta) + oldcx;
- newcy = r * Math.sin(theta) + oldcy;
+ newcx = r * Math.cos(theta) + oldcx;
+ newcy = r * Math.sin(theta) + oldcy;
- var list = currentPath.pathSegList,
- i = list.numberOfItems;
- while (i) {
- i -= 1;
- var seg = list.getItem(i),
- type = seg.pathSegType;
- if (type === 1) { continue; }
+ var list = currentPath.pathSegList,
+ i = list.numberOfItems;
+ while (i) {
+ i -= 1;
+ var seg = list.getItem(i),
+ type = seg.pathSegType;
+ if (type === 1) { continue; }
- var rvals = getRotVals(seg.x, seg.y),
- points = [rvals.x, rvals.y];
- if (seg.x1 != null && seg.x2 != null) {
- var cVals1 = getRotVals(seg.x1, seg.y1);
- var cVals2 = getRotVals(seg.x2, seg.y2);
- points.splice(points.length, 0, cVals1.x, cVals1.y, cVals2.x, cVals2.y);
- }
- svgedit.path.replacePathSeg(type, i, points);
- } // loop for each point
+ var rvals = getRotVals(seg.x, seg.y),
+ points = [rvals.x, rvals.y];
+ if (seg.x1 != null && seg.x2 != null) {
+ var cVals1 = getRotVals(seg.x1, seg.y1);
+ var cVals2 = getRotVals(seg.x2, seg.y2);
+ points.splice(points.length, 0, cVals1.x, cVals1.y, cVals2.x, cVals2.y);
+ }
+ svgedit.path.replacePathSeg(type, i, points);
+ } // loop for each point
- box = svgedit.utilities.getBBox(currentPath);
- // selectedBBoxes[0].x = box.x; selectedBBoxes[0].y = box.y;
- // selectedBBoxes[0].width = box.width; selectedBBoxes[0].height = box.height;
+ box = svgedit.utilities.getBBox(currentPath);
+ // selectedBBoxes[0].x = box.x; selectedBBoxes[0].y = box.y;
+ // selectedBBoxes[0].width = box.width; selectedBBoxes[0].height = box.height;
- // now we must set the new transform to be rotated around the new center
- var Rnc = svgroot.createSVGTransform(),
- tlist = svgedit.transformlist.getTransformList(currentPath);
- Rnc.setRotate((angle * 180.0 / Math.PI), newcx, newcy);
- tlist.replaceItem(Rnc, 0);
+ // now we must set the new transform to be rotated around the new center
+ var Rnc = svgroot.createSVGTransform(),
+ tlist = svgedit.transformlist.getTransformList(currentPath);
+ Rnc.setRotate((angle * 180.0 / Math.PI), newcx, newcy);
+ tlist.replaceItem(Rnc, 0);
};
// ====================================
// Public API starts here
svgedit.path.clearData = function () {
- pathData = {};
+ pathData = {};
};
}());
diff --git a/editor/pathseg.js b/editor/pathseg.js
index 648721d2..b267c973 100644
--- a/editor/pathseg.js
+++ b/editor/pathseg.js
@@ -9,361 +9,361 @@
(function () {
'use strict';
if (!('SVGPathSeg' in window)) {
- // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
- window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
- this.pathSegType = type;
- this.pathSegTypeAsLetter = typeAsLetter;
- this._owningPathSegList = owningPathSegList;
- };
+ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
+ window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
+ this.pathSegType = type;
+ this.pathSegTypeAsLetter = typeAsLetter;
+ this._owningPathSegList = owningPathSegList;
+ };
- window.SVGPathSeg.prototype.classname = 'SVGPathSeg';
+ window.SVGPathSeg.prototype.classname = 'SVGPathSeg';
- window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
- window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
- window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
- window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
- window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
- window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
- window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
- window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
- window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
- window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
- window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
- window.SVGPathSeg.PATHSEG_ARC_REL = 11;
- window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
- window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
- window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
- window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
- window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
- window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
- window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
- window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
+ window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
+ window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
+ window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
+ window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
+ window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
+ window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
+ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
+ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
+ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
+ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
+ window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
+ window.SVGPathSeg.PATHSEG_ARC_REL = 11;
+ window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
+ window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
+ window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
+ window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
+ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
+ window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
+ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
+ window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
- // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
- window.SVGPathSeg.prototype._segmentChanged = function () {
- if (this._owningPathSegList) {
- this._owningPathSegList.segmentChanged(this);
- }
- };
+ // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
+ window.SVGPathSeg.prototype._segmentChanged = function () {
+ if (this._owningPathSegList) {
+ this._owningPathSegList.segmentChanged(this);
+ }
+ };
- window.SVGPathSegClosePath = function (owningPathSegList) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList);
- };
- window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegClosePath.prototype.toString = function () { return '[object SVGPathSegClosePath]'; };
- window.SVGPathSegClosePath.prototype._asPathString = function () { return this.pathSegTypeAsLetter; };
- window.SVGPathSegClosePath.prototype.clone = function () { return new window.SVGPathSegClosePath(undefined); };
+ window.SVGPathSegClosePath = function (owningPathSegList) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList);
+ };
+ window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegClosePath.prototype.toString = function () { return '[object SVGPathSegClosePath]'; };
+ window.SVGPathSegClosePath.prototype._asPathString = function () { return this.pathSegTypeAsLetter; };
+ window.SVGPathSegClosePath.prototype.clone = function () { return new window.SVGPathSegClosePath(undefined); };
- window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegMovetoAbs.prototype.toString = function () { return '[object SVGPathSegMovetoAbs]'; };
- window.SVGPathSegMovetoAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegMovetoAbs.prototype.clone = function () { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegMovetoAbs.prototype.toString = function () { return '[object SVGPathSegMovetoAbs]'; };
+ window.SVGPathSegMovetoAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegMovetoAbs.prototype.clone = function () { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegMovetoRel.prototype.toString = function () { return '[object SVGPathSegMovetoRel]'; };
- window.SVGPathSegMovetoRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegMovetoRel.prototype.clone = function () { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegMovetoRel.prototype.toString = function () { return '[object SVGPathSegMovetoRel]'; };
+ window.SVGPathSegMovetoRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegMovetoRel.prototype.clone = function () { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoAbs.prototype.toString = function () { return '[object SVGPathSegLinetoAbs]'; };
- window.SVGPathSegLinetoAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegLinetoAbs.prototype.clone = function () { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoAbs.prototype.toString = function () { return '[object SVGPathSegLinetoAbs]'; };
+ window.SVGPathSegLinetoAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegLinetoAbs.prototype.clone = function () { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoRel.prototype.toString = function () { return '[object SVGPathSegLinetoRel]'; };
- window.SVGPathSegLinetoRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegLinetoRel.prototype.clone = function () { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoRel.prototype.toString = function () { return '[object SVGPathSegLinetoRel]'; };
+ window.SVGPathSegLinetoRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegLinetoRel.prototype.clone = function () { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x1 = x1;
- this._y1 = y1;
- this._x2 = x2;
- this._y2 = y2;
- };
- window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicAbs]'; };
- window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); };
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x1 = x1;
+ this._y1 = y1;
+ this._x2 = x2;
+ this._y2 = y2;
+ };
+ window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicAbs]'; };
+ window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); };
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x1 = x1;
- this._y1 = y1;
- this._x2 = x2;
- this._y2 = y2;
- };
- window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicRel]'; };
- window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); };
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x1 = x1;
+ this._y1 = y1;
+ this._x2 = x2;
+ this._y2 = y2;
+ };
+ window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicRel]'; };
+ window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); };
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x1 = x1;
- this._y1 = y1;
- };
- window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticAbs]'; };
- window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); };
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x1 = x1;
+ this._y1 = y1;
+ };
+ window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticAbs]'; };
+ window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); };
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x1 = x1;
- this._y1 = y1;
- };
- window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticRel]'; };
- window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); };
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x1 = x1;
+ this._y1 = y1;
+ };
+ window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticRel]'; };
+ window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); };
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', { get: function () { return this._x1; }, set: function (x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', { get: function () { return this._y1; }, set: function (y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList);
- this._x = x;
- this._y = y;
- this._r1 = r1;
- this._r2 = r2;
- this._angle = angle;
- this._largeArcFlag = largeArcFlag;
- this._sweepFlag = sweepFlag;
- };
- window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegArcAbs.prototype.toString = function () { return '[object SVGPathSegArcAbs]'; };
- window.SVGPathSegArcAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegArcAbs.prototype.clone = function () { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); };
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { get: function () { return this._r1; }, set: function (r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { get: function () { return this._r2; }, set: function (r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { get: function () { return this._angle; }, set: function (angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { get: function () { return this._largeArcFlag; }, set: function (largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { get: function () { return this._sweepFlag; }, set: function (sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._r1 = r1;
+ this._r2 = r2;
+ this._angle = angle;
+ this._largeArcFlag = largeArcFlag;
+ this._sweepFlag = sweepFlag;
+ };
+ window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegArcAbs.prototype.toString = function () { return '[object SVGPathSegArcAbs]'; };
+ window.SVGPathSegArcAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegArcAbs.prototype.clone = function () { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); };
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { get: function () { return this._r1; }, set: function (r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { get: function () { return this._r2; }, set: function (r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { get: function () { return this._angle; }, set: function (angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { get: function () { return this._largeArcFlag; }, set: function (largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { get: function () { return this._sweepFlag; }, set: function (sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList);
- this._x = x;
- this._y = y;
- this._r1 = r1;
- this._r2 = r2;
- this._angle = angle;
- this._largeArcFlag = largeArcFlag;
- this._sweepFlag = sweepFlag;
- };
- window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegArcRel.prototype.toString = function () { return '[object SVGPathSegArcRel]'; };
- window.SVGPathSegArcRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegArcRel.prototype.clone = function () { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); };
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { get: function () { return this._r1; }, set: function (r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { get: function () { return this._r2; }, set: function (r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { get: function () { return this._angle; }, set: function (angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { get: function () { return this._largeArcFlag; }, set: function (largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { get: function () { return this._sweepFlag; }, set: function (sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._r1 = r1;
+ this._r2 = r2;
+ this._angle = angle;
+ this._largeArcFlag = largeArcFlag;
+ this._sweepFlag = sweepFlag;
+ };
+ window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegArcRel.prototype.toString = function () { return '[object SVGPathSegArcRel]'; };
+ window.SVGPathSegArcRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegArcRel.prototype.clone = function () { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); };
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { get: function () { return this._r1; }, set: function (r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { get: function () { return this._r2; }, set: function (r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { get: function () { return this._angle; }, set: function (angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { get: function () { return this._largeArcFlag; }, set: function (largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { get: function () { return this._sweepFlag; }, set: function (sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList);
- this._x = x;
- };
- window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { return '[object SVGPathSegLinetoHorizontalAbs]'; };
- window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x; };
- window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); };
- Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList);
+ this._x = x;
+ };
+ window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { return '[object SVGPathSegLinetoHorizontalAbs]'; };
+ window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x; };
+ window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); };
+ Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList);
- this._x = x;
- };
- window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { return '[object SVGPathSegLinetoHorizontalRel]'; };
- window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x; };
- window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); };
- Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList);
+ this._x = x;
+ };
+ window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { return '[object SVGPathSegLinetoHorizontalRel]'; };
+ window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x; };
+ window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); };
+ Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList);
- this._y = y;
- };
- window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { return '[object SVGPathSegLinetoVerticalAbs]'; };
- window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._y; };
- window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); };
- Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList);
+ this._y = y;
+ };
+ window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { return '[object SVGPathSegLinetoVerticalAbs]'; };
+ window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._y; };
+ window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); };
+ Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList);
- this._y = y;
- };
- window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { return '[object SVGPathSegLinetoVerticalRel]'; };
- window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._y; };
- window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); };
- Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList);
+ this._y = y;
+ };
+ window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { return '[object SVGPathSegLinetoVerticalRel]'; };
+ window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._y; };
+ window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); };
+ Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x2 = x2;
- this._y2 = y2;
- };
- window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicSmoothAbs]'; };
- window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); };
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x2 = x2;
+ this._y2 = y2;
+ };
+ window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicSmoothAbs]'; };
+ window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); };
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList);
- this._x = x;
- this._y = y;
- this._x2 = x2;
- this._y2 = y2;
- };
- window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicSmoothRel]'; };
- window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); };
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ this._x2 = x2;
+ this._y2 = y2;
+ };
+ window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { return '[object SVGPathSegCurvetoCubicSmoothRel]'; };
+ window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); };
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', { get: function () { return this._x2; }, set: function (x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', { get: function () { return this._y2; }, set: function (y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'; };
- window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'; };
+ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
- window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList);
- this._x = x;
- this._y = y;
- };
- window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
- window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticSmoothRel]'; };
- window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
- window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); };
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
- Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
+ window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
+ window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList);
+ this._x = x;
+ this._y = y;
+ };
+ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
+ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { return '[object SVGPathSegCurvetoQuadraticSmoothRel]'; };
+ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; };
+ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); };
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', { get: function () { return this._x; }, set: function (x) { this._x = x; this._segmentChanged(); }, enumerable: true });
+ Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', { get: function () { return this._y; }, set: function (y) { this._y = y; this._segmentChanged(); }, enumerable: true });
- // Add createSVGPathSeg* functions to window.SVGPathElement.
- // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
- window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { return new window.SVGPathSegClosePath(undefined); };
- window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { return new window.SVGPathSegMovetoAbs(undefined, x, y); };
- window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { return new window.SVGPathSegMovetoRel(undefined, x, y); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { return new window.SVGPathSegLinetoAbs(undefined, x, y); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { return new window.SVGPathSegLinetoRel(undefined, x, y); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); };
- window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); };
- window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { return new window.SVGPathSegLinetoHorizontalRel(undefined, x); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { return new window.SVGPathSegLinetoVerticalAbs(undefined, y); };
- window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { return new window.SVGPathSegLinetoVerticalRel(undefined, y); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); };
- window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); };
+ // Add createSVGPathSeg* functions to window.SVGPathElement.
+ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
+ window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { return new window.SVGPathSegClosePath(undefined); };
+ window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { return new window.SVGPathSegMovetoAbs(undefined, x, y); };
+ window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { return new window.SVGPathSegMovetoRel(undefined, x, y); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { return new window.SVGPathSegLinetoAbs(undefined, x, y); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { return new window.SVGPathSegLinetoRel(undefined, x, y); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); };
+ window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); };
+ window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { return new window.SVGPathSegLinetoHorizontalRel(undefined, x); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { return new window.SVGPathSegLinetoVerticalAbs(undefined, y); };
+ window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { return new window.SVGPathSegLinetoVerticalRel(undefined, y); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); };
+ window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); };
- if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {
- // Add getPathSegAtLength to SVGPathElement.
- // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
- // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
- window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
- if (distance === undefined || !isFinite(distance)) {
- throw new Error('Invalid arguments.');
- }
+ if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {
+ // Add getPathSegAtLength to SVGPathElement.
+ // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
+ // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
+ window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
+ if (distance === undefined || !isFinite(distance)) {
+ throw new Error('Invalid arguments.');
+ }
- var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
- measurementElement.setAttribute('d', this.getAttribute('d'));
- var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
+ var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
+ measurementElement.setAttribute('d', this.getAttribute('d'));
+ var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
- // If the path is empty, return 0.
- if (lastPathSegment <= 0) {
- return 0;
- }
+ // If the path is empty, return 0.
+ if (lastPathSegment <= 0) {
+ return 0;
+ }
- do {
- measurementElement.pathSegList.removeItem(lastPathSegment);
- if (distance > measurementElement.getTotalLength()) {
- break;
- }
- lastPathSegment--;
- } while (lastPathSegment > 0);
- return lastPathSegment;
- };
- }
+ do {
+ measurementElement.pathSegList.removeItem(lastPathSegment);
+ if (distance > measurementElement.getTotalLength()) {
+ break;
+ }
+ lastPathSegment--;
+ } while (lastPathSegment > 0);
+ return lastPathSegment;
+ };
+ }
}
// Checking for SVGPathSegList in window checks for the case of an implementation without the
@@ -372,508 +372,508 @@ if (!('SVGPathSeg' in window)) {
// SVGPathSegList API (e.g., appendItem). In this case we need to re-implement the entire API
// so the polyfill data (i.e., _list) is used throughout.
if (!('SVGPathSegList' in window) || !('appendItem' in window.SVGPathSegList.prototype)) {
- // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
- window.SVGPathSegList = function (pathElement) {
- this._pathElement = pathElement;
- this._list = this._parsePath(this._pathElement.getAttribute('d'));
+ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
+ window.SVGPathSegList = function (pathElement) {
+ this._pathElement = pathElement;
+ this._list = this._parsePath(this._pathElement.getAttribute('d'));
- // Use a MutationObserver to catch changes to the path's "d" attribute.
- this._mutationObserverConfig = { 'attributes': true, 'attributeFilter': ['d'] };
- this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
- this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
- };
+ // Use a MutationObserver to catch changes to the path's "d" attribute.
+ this._mutationObserverConfig = { 'attributes': true, 'attributeFilter': ['d'] };
+ this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
+ this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
+ };
- window.SVGPathSegList.prototype.classname = 'SVGPathSegList';
+ window.SVGPathSegList.prototype.classname = 'SVGPathSegList';
- Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {
- get: function () {
- this._checkPathSynchronizedToList();
- return this._list.length;
- },
- enumerable: true
- });
+ Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {
+ get: function () {
+ this._checkPathSynchronizedToList();
+ return this._list.length;
+ },
+ enumerable: true
+ });
- // Add the pathSegList accessors to window.SVGPathElement.
- // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
- Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {
- get: function () {
- if (!this._pathSegList) {
- this._pathSegList = new window.SVGPathSegList(this);
- }
- return this._pathSegList;
- },
- enumerable: true
- });
- // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
- Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
- Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
- Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
+ // Add the pathSegList accessors to window.SVGPathElement.
+ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
+ Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {
+ get: function () {
+ if (!this._pathSegList) {
+ this._pathSegList = new window.SVGPathSegList(this);
+ }
+ return this._pathSegList;
+ },
+ enumerable: true
+ });
+ // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
+ Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
+ Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
+ Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', { get: function () { return this.pathSegList; }, enumerable: true });
- // Process any pending mutations to the path element and update the list as needed.
- // This should be the first call of all public functions and is needed because
- // MutationObservers are not synchronous so we can have pending asynchronous mutations.
- window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
- this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
- };
+ // Process any pending mutations to the path element and update the list as needed.
+ // This should be the first call of all public functions and is needed because
+ // MutationObservers are not synchronous so we can have pending asynchronous mutations.
+ window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
+ this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
+ };
- window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
- if (!this._pathElement) {
- return;
- }
- var hasPathMutations = false;
- mutationRecords.forEach(function (record) {
- if (record.attributeName === 'd') {
- hasPathMutations = true;
- }
- });
- if (hasPathMutations) {
- this._list = this._parsePath(this._pathElement.getAttribute('d'));
- }
- };
+ window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
+ if (!this._pathElement) {
+ return;
+ }
+ var hasPathMutations = false;
+ mutationRecords.forEach(function (record) {
+ if (record.attributeName === 'd') {
+ hasPathMutations = true;
+ }
+ });
+ if (hasPathMutations) {
+ this._list = this._parsePath(this._pathElement.getAttribute('d'));
+ }
+ };
- // Serialize the list and update the path's 'd' attribute.
- window.SVGPathSegList.prototype._writeListToPath = function () {
- this._pathElementMutationObserver.disconnect();
- this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list));
- this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
- };
+ // Serialize the list and update the path's 'd' attribute.
+ window.SVGPathSegList.prototype._writeListToPath = function () {
+ this._pathElementMutationObserver.disconnect();
+ this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list));
+ this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
+ };
- // When a path segment changes the list needs to be synchronized back to the path element.
- window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
- this._writeListToPath();
- };
+ // When a path segment changes the list needs to be synchronized back to the path element.
+ window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
+ this._writeListToPath();
+ };
- window.SVGPathSegList.prototype.clear = function () {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.clear = function () {
+ this._checkPathSynchronizedToList();
- this._list.forEach(function (pathSeg) {
- pathSeg._owningPathSegList = null;
- });
- this._list = [];
- this._writeListToPath();
- };
+ this._list.forEach(function (pathSeg) {
+ pathSeg._owningPathSegList = null;
+ });
+ this._list = [];
+ this._writeListToPath();
+ };
- window.SVGPathSegList.prototype.initialize = function (newItem) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.initialize = function (newItem) {
+ this._checkPathSynchronizedToList();
- this._list = [newItem];
- newItem._owningPathSegList = this;
- this._writeListToPath();
- return newItem;
- };
+ this._list = [newItem];
+ newItem._owningPathSegList = this;
+ this._writeListToPath();
+ return newItem;
+ };
- window.SVGPathSegList.prototype._checkValidIndex = function (index) {
- if (isNaN(index) || index < 0 || index >= this.numberOfItems) {
- throw new Error('INDEX_SIZE_ERR');
- }
- };
+ window.SVGPathSegList.prototype._checkValidIndex = function (index) {
+ if (isNaN(index) || index < 0 || index >= this.numberOfItems) {
+ throw new Error('INDEX_SIZE_ERR');
+ }
+ };
- window.SVGPathSegList.prototype.getItem = function (index) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.getItem = function (index) {
+ this._checkPathSynchronizedToList();
- this._checkValidIndex(index);
- return this._list[index];
- };
+ this._checkValidIndex(index);
+ return this._list[index];
+ };
- window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
+ this._checkPathSynchronizedToList();
- // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
- if (index > this.numberOfItems) {
- index = this.numberOfItems;
- }
- if (newItem._owningPathSegList) {
- // SVG2 spec says to make a copy.
- newItem = newItem.clone();
- }
- this._list.splice(index, 0, newItem);
- newItem._owningPathSegList = this;
- this._writeListToPath();
- return newItem;
- };
+ // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
+ if (index > this.numberOfItems) {
+ index = this.numberOfItems;
+ }
+ if (newItem._owningPathSegList) {
+ // SVG2 spec says to make a copy.
+ newItem = newItem.clone();
+ }
+ this._list.splice(index, 0, newItem);
+ newItem._owningPathSegList = this;
+ this._writeListToPath();
+ return newItem;
+ };
- window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
+ this._checkPathSynchronizedToList();
- if (newItem._owningPathSegList) {
- // SVG2 spec says to make a copy.
- newItem = newItem.clone();
- }
- this._checkValidIndex(index);
- this._list[index] = newItem;
- newItem._owningPathSegList = this;
- this._writeListToPath();
- return newItem;
- };
+ if (newItem._owningPathSegList) {
+ // SVG2 spec says to make a copy.
+ newItem = newItem.clone();
+ }
+ this._checkValidIndex(index);
+ this._list[index] = newItem;
+ newItem._owningPathSegList = this;
+ this._writeListToPath();
+ return newItem;
+ };
- window.SVGPathSegList.prototype.removeItem = function (index) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.removeItem = function (index) {
+ this._checkPathSynchronizedToList();
- this._checkValidIndex(index);
- var item = this._list[index];
- this._list.splice(index, 1);
- this._writeListToPath();
- return item;
- };
+ this._checkValidIndex(index);
+ var item = this._list[index];
+ this._list.splice(index, 1);
+ this._writeListToPath();
+ return item;
+ };
- window.SVGPathSegList.prototype.appendItem = function (newItem) {
- this._checkPathSynchronizedToList();
+ window.SVGPathSegList.prototype.appendItem = function (newItem) {
+ this._checkPathSynchronizedToList();
- if (newItem._owningPathSegList) {
- // SVG2 spec says to make a copy.
- newItem = newItem.clone();
- }
- this._list.push(newItem);
- newItem._owningPathSegList = this;
- // TODO: Optimize this to just append to the existing attribute.
- this._writeListToPath();
- return newItem;
- };
+ if (newItem._owningPathSegList) {
+ // SVG2 spec says to make a copy.
+ newItem = newItem.clone();
+ }
+ this._list.push(newItem);
+ newItem._owningPathSegList = this;
+ // TODO: Optimize this to just append to the existing attribute.
+ this._writeListToPath();
+ return newItem;
+ };
- window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
- var string = '';
- var first = true;
- pathSegArray.forEach(function (pathSeg) {
- if (first) {
- first = false;
- string += pathSeg._asPathString();
- } else {
- string += ' ' + pathSeg._asPathString();
- }
- });
- return string;
- };
+ window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
+ var string = '';
+ var first = true;
+ pathSegArray.forEach(function (pathSeg) {
+ if (first) {
+ first = false;
+ string += pathSeg._asPathString();
+ } else {
+ string += ' ' + pathSeg._asPathString();
+ }
+ });
+ return string;
+ };
- // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
- window.SVGPathSegList.prototype._parsePath = function (string) {
- if (!string || string.length === 0) {
- return [];
- }
+ // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
+ window.SVGPathSegList.prototype._parsePath = function (string) {
+ if (!string || string.length === 0) {
+ return [];
+ }
- var owningPathSegList = this;
+ var owningPathSegList = this;
- var Builder = function () {
- this.pathSegList = [];
- };
+ var Builder = function () {
+ this.pathSegList = [];
+ };
- Builder.prototype.appendSegment = function (pathSeg) {
- this.pathSegList.push(pathSeg);
- };
+ Builder.prototype.appendSegment = function (pathSeg) {
+ this.pathSegList.push(pathSeg);
+ };
- var Source = function (string) {
- this._string = string;
- this._currentIndex = 0;
- this._endIndex = this._string.length;
- this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
+ var Source = function (string) {
+ this._string = string;
+ this._currentIndex = 0;
+ this._endIndex = this._string.length;
+ this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
- this._skipOptionalSpaces();
- };
+ this._skipOptionalSpaces();
+ };
- Source.prototype._isCurrentSpace = function () {
- var character = this._string[this._currentIndex];
- return character <= ' ' && (character === ' ' || character === '\n' || character === '\t' || character === '\r' || character === '\f');
- };
+ Source.prototype._isCurrentSpace = function () {
+ var character = this._string[this._currentIndex];
+ return character <= ' ' && (character === ' ' || character === '\n' || character === '\t' || character === '\r' || character === '\f');
+ };
- Source.prototype._skipOptionalSpaces = function () {
- while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
- this._currentIndex++;
- }
- return this._currentIndex < this._endIndex;
- };
+ Source.prototype._skipOptionalSpaces = function () {
+ while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
+ this._currentIndex++;
+ }
+ return this._currentIndex < this._endIndex;
+ };
- Source.prototype._skipOptionalSpacesOrDelimiter = function () {
- if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) !== ',') {
- return false;
- }
- if (this._skipOptionalSpaces()) {
- if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === ',') {
- this._currentIndex++;
- this._skipOptionalSpaces();
- }
- }
- return this._currentIndex < this._endIndex;
- };
+ Source.prototype._skipOptionalSpacesOrDelimiter = function () {
+ if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) !== ',') {
+ return false;
+ }
+ if (this._skipOptionalSpaces()) {
+ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === ',') {
+ this._currentIndex++;
+ this._skipOptionalSpaces();
+ }
+ }
+ return this._currentIndex < this._endIndex;
+ };
- Source.prototype.hasMoreData = function () {
- return this._currentIndex < this._endIndex;
- };
+ Source.prototype.hasMoreData = function () {
+ return this._currentIndex < this._endIndex;
+ };
- Source.prototype.peekSegmentType = function () {
- var lookahead = this._string[this._currentIndex];
- return this._pathSegTypeFromChar(lookahead);
- };
+ Source.prototype.peekSegmentType = function () {
+ var lookahead = this._string[this._currentIndex];
+ return this._pathSegTypeFromChar(lookahead);
+ };
- Source.prototype._pathSegTypeFromChar = function (lookahead) {
- switch (lookahead) {
- case 'Z':
- case 'z':
- return window.SVGPathSeg.PATHSEG_CLOSEPATH;
- case 'M':
- return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
- case 'm':
- return window.SVGPathSeg.PATHSEG_MOVETO_REL;
- case 'L':
- return window.SVGPathSeg.PATHSEG_LINETO_ABS;
- case 'l':
- return window.SVGPathSeg.PATHSEG_LINETO_REL;
- case 'C':
- return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
- case 'c':
- return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
- case 'Q':
- return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
- case 'q':
- return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
- case 'A':
- return window.SVGPathSeg.PATHSEG_ARC_ABS;
- case 'a':
- return window.SVGPathSeg.PATHSEG_ARC_REL;
- case 'H':
- return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
- case 'h':
- return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
- case 'V':
- return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
- case 'v':
- return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
- case 'S':
- return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
- case 's':
- return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
- case 'T':
- return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
- case 't':
- return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
- default:
- return window.SVGPathSeg.PATHSEG_UNKNOWN;
- }
- };
+ Source.prototype._pathSegTypeFromChar = function (lookahead) {
+ switch (lookahead) {
+ case 'Z':
+ case 'z':
+ return window.SVGPathSeg.PATHSEG_CLOSEPATH;
+ case 'M':
+ return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
+ case 'm':
+ return window.SVGPathSeg.PATHSEG_MOVETO_REL;
+ case 'L':
+ return window.SVGPathSeg.PATHSEG_LINETO_ABS;
+ case 'l':
+ return window.SVGPathSeg.PATHSEG_LINETO_REL;
+ case 'C':
+ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
+ case 'c':
+ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
+ case 'Q':
+ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
+ case 'q':
+ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
+ case 'A':
+ return window.SVGPathSeg.PATHSEG_ARC_ABS;
+ case 'a':
+ return window.SVGPathSeg.PATHSEG_ARC_REL;
+ case 'H':
+ return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
+ case 'h':
+ return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
+ case 'V':
+ return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
+ case 'v':
+ return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
+ case 'S':
+ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
+ case 's':
+ return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
+ case 'T':
+ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
+ case 't':
+ return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
+ default:
+ return window.SVGPathSeg.PATHSEG_UNKNOWN;
+ }
+ };
- Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
- // Check for remaining coordinates in the current command.
- if ((lookahead === '+' || lookahead === '-' || lookahead === '.' || (lookahead >= '0' && lookahead <= '9')) && previousCommand !== window.SVGPathSeg.PATHSEG_CLOSEPATH) {
- if (previousCommand === window.SVGPathSeg.PATHSEG_MOVETO_ABS) {
- return window.SVGPathSeg.PATHSEG_LINETO_ABS;
- }
- if (previousCommand === window.SVGPathSeg.PATHSEG_MOVETO_REL) {
- return window.SVGPathSeg.PATHSEG_LINETO_REL;
- }
- return previousCommand;
- }
- return window.SVGPathSeg.PATHSEG_UNKNOWN;
- };
+ Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
+ // Check for remaining coordinates in the current command.
+ if ((lookahead === '+' || lookahead === '-' || lookahead === '.' || (lookahead >= '0' && lookahead <= '9')) && previousCommand !== window.SVGPathSeg.PATHSEG_CLOSEPATH) {
+ if (previousCommand === window.SVGPathSeg.PATHSEG_MOVETO_ABS) {
+ return window.SVGPathSeg.PATHSEG_LINETO_ABS;
+ }
+ if (previousCommand === window.SVGPathSeg.PATHSEG_MOVETO_REL) {
+ return window.SVGPathSeg.PATHSEG_LINETO_REL;
+ }
+ return previousCommand;
+ }
+ return window.SVGPathSeg.PATHSEG_UNKNOWN;
+ };
- Source.prototype.initialCommandIsMoveTo = function () {
- // If the path is empty it is still valid, so return true.
- if (!this.hasMoreData()) {
- return true;
- }
- var command = this.peekSegmentType();
- // Path must start with moveTo.
- return command === window.SVGPathSeg.PATHSEG_MOVETO_ABS || command === window.SVGPathSeg.PATHSEG_MOVETO_REL;
- };
+ Source.prototype.initialCommandIsMoveTo = function () {
+ // If the path is empty it is still valid, so return true.
+ if (!this.hasMoreData()) {
+ return true;
+ }
+ var command = this.peekSegmentType();
+ // Path must start with moveTo.
+ return command === window.SVGPathSeg.PATHSEG_MOVETO_ABS || command === window.SVGPathSeg.PATHSEG_MOVETO_REL;
+ };
- // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
- // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
- Source.prototype._parseNumber = function () {
- var exponent = 0;
- var integer = 0;
- var frac = 1;
- var decimal = 0;
- var sign = 1;
- var expsign = 1;
+ // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
+ // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
+ Source.prototype._parseNumber = function () {
+ var exponent = 0;
+ var integer = 0;
+ var frac = 1;
+ var decimal = 0;
+ var sign = 1;
+ var expsign = 1;
- var startIndex = this._currentIndex;
+ var startIndex = this._currentIndex;
- this._skipOptionalSpaces();
+ this._skipOptionalSpaces();
- // Read the sign.
- if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '+') {
- this._currentIndex++;
- } else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '-') {
- this._currentIndex++;
- sign = -1;
- }
+ // Read the sign.
+ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '+') {
+ this._currentIndex++;
+ } else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '-') {
+ this._currentIndex++;
+ sign = -1;
+ }
- if (this._currentIndex === this._endIndex || ((this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') && this._string.charAt(this._currentIndex) !== '.')) {
- // The first character of a number must be one of [0-9+-.].
- return undefined;
- }
+ if (this._currentIndex === this._endIndex || ((this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') && this._string.charAt(this._currentIndex) !== '.')) {
+ // The first character of a number must be one of [0-9+-.].
+ return undefined;
+ }
- // Read the integer part, build right-to-left.
- var startIntPartIndex = this._currentIndex;
- while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
- this._currentIndex++; // Advance to first non-digit.
- }
+ // Read the integer part, build right-to-left.
+ var startIntPartIndex = this._currentIndex;
+ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
+ this._currentIndex++; // Advance to first non-digit.
+ }
- if (this._currentIndex !== startIntPartIndex) {
- var scanIntPartIndex = this._currentIndex - 1;
- var multiplier = 1;
- while (scanIntPartIndex >= startIntPartIndex) {
- integer += multiplier * (this._string.charAt(scanIntPartIndex--) - '0');
- multiplier *= 10;
- }
- }
+ if (this._currentIndex !== startIntPartIndex) {
+ var scanIntPartIndex = this._currentIndex - 1;
+ var multiplier = 1;
+ while (scanIntPartIndex >= startIntPartIndex) {
+ integer += multiplier * (this._string.charAt(scanIntPartIndex--) - '0');
+ multiplier *= 10;
+ }
+ }
- // Read the decimals.
- if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '.') {
- this._currentIndex++;
+ // Read the decimals.
+ if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) === '.') {
+ this._currentIndex++;
- // There must be a least one digit following the .
- if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') {
- return undefined;
- }
- while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
- frac *= 10;
- decimal += (this._string.charAt(this._currentIndex) - '0') / frac;
- this._currentIndex += 1;
- }
- }
+ // There must be a least one digit following the .
+ if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') {
+ return undefined;
+ }
+ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
+ frac *= 10;
+ decimal += (this._string.charAt(this._currentIndex) - '0') / frac;
+ this._currentIndex += 1;
+ }
+ }
- // Read the exponent part.
- if (this._currentIndex !== startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) === 'e' || this._string.charAt(this._currentIndex) === 'E') && (this._string.charAt(this._currentIndex + 1) !== 'x' && this._string.charAt(this._currentIndex + 1) !== 'm')) {
- this._currentIndex++;
+ // Read the exponent part.
+ if (this._currentIndex !== startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) === 'e' || this._string.charAt(this._currentIndex) === 'E') && (this._string.charAt(this._currentIndex + 1) !== 'x' && this._string.charAt(this._currentIndex + 1) !== 'm')) {
+ this._currentIndex++;
- // Read the sign of the exponent.
- if (this._string.charAt(this._currentIndex) === '+') {
- this._currentIndex++;
- } else if (this._string.charAt(this._currentIndex) === '-') {
- this._currentIndex++;
- expsign = -1;
- }
+ // Read the sign of the exponent.
+ if (this._string.charAt(this._currentIndex) === '+') {
+ this._currentIndex++;
+ } else if (this._string.charAt(this._currentIndex) === '-') {
+ this._currentIndex++;
+ expsign = -1;
+ }
- // There must be an exponent.
- if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') {
- return undefined;
- }
+ // There must be an exponent.
+ if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') {
+ return undefined;
+ }
- while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
- exponent *= 10;
- exponent += (this._string.charAt(this._currentIndex) - '0');
- this._currentIndex++;
- }
- }
+ while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') {
+ exponent *= 10;
+ exponent += (this._string.charAt(this._currentIndex) - '0');
+ this._currentIndex++;
+ }
+ }
- var number = integer + decimal;
- number *= sign;
+ var number = integer + decimal;
+ number *= sign;
- if (exponent) {
- number *= Math.pow(10, expsign * exponent);
- }
+ if (exponent) {
+ number *= Math.pow(10, expsign * exponent);
+ }
- if (startIndex === this._currentIndex) {
- return undefined;
- }
+ if (startIndex === this._currentIndex) {
+ return undefined;
+ }
- this._skipOptionalSpacesOrDelimiter();
+ this._skipOptionalSpacesOrDelimiter();
- return number;
- };
+ return number;
+ };
- Source.prototype._parseArcFlag = function () {
- if (this._currentIndex >= this._endIndex) {
- return undefined;
- }
- var flag = false;
- var flagChar = this._string.charAt(this._currentIndex++);
- if (flagChar === '0') {
- flag = false;
- } else if (flagChar === '1') {
- flag = true;
- } else {
- return undefined;
- }
+ Source.prototype._parseArcFlag = function () {
+ if (this._currentIndex >= this._endIndex) {
+ return undefined;
+ }
+ var flag = false;
+ var flagChar = this._string.charAt(this._currentIndex++);
+ if (flagChar === '0') {
+ flag = false;
+ } else if (flagChar === '1') {
+ flag = true;
+ } else {
+ return undefined;
+ }
- this._skipOptionalSpacesOrDelimiter();
- return flag;
- };
+ this._skipOptionalSpacesOrDelimiter();
+ return flag;
+ };
- Source.prototype.parseSegment = function () {
- var lookahead = this._string[this._currentIndex];
- var command = this._pathSegTypeFromChar(lookahead);
- if (command === window.SVGPathSeg.PATHSEG_UNKNOWN) {
- // Possibly an implicit command. Not allowed if this is the first command.
- if (this._previousCommand === window.SVGPathSeg.PATHSEG_UNKNOWN) {
- return null;
- }
- command = this._nextCommandHelper(lookahead, this._previousCommand);
- if (command === window.SVGPathSeg.PATHSEG_UNKNOWN) {
- return null;
- }
- } else {
- this._currentIndex++;
- }
+ Source.prototype.parseSegment = function () {
+ var lookahead = this._string[this._currentIndex];
+ var command = this._pathSegTypeFromChar(lookahead);
+ if (command === window.SVGPathSeg.PATHSEG_UNKNOWN) {
+ // Possibly an implicit command. Not allowed if this is the first command.
+ if (this._previousCommand === window.SVGPathSeg.PATHSEG_UNKNOWN) {
+ return null;
+ }
+ command = this._nextCommandHelper(lookahead, this._previousCommand);
+ if (command === window.SVGPathSeg.PATHSEG_UNKNOWN) {
+ return null;
+ }
+ } else {
+ this._currentIndex++;
+ }
- this._previousCommand = command;
+ this._previousCommand = command;
- switch (command) {
- case window.SVGPathSeg.PATHSEG_MOVETO_REL:
- return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
- return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_REL:
- return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_ABS:
- return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
- return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
- return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
- return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
- case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
- return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
- case window.SVGPathSeg.PATHSEG_CLOSEPATH:
- this._skipOptionalSpaces();
- return new window.SVGPathSegClosePath(owningPathSegList);
- case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
- case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
- case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
- var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
- case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
- var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
- case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
- case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
- case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
- return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
- return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
- case window.SVGPathSeg.PATHSEG_ARC_REL:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
- case window.SVGPathSeg.PATHSEG_ARC_ABS:
- var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
- return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
- default:
- throw new Error('Unknown path seg type.');
- }
- };
+ switch (command) {
+ case window.SVGPathSeg.PATHSEG_MOVETO_REL:
+ return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
+ return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_REL:
+ return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_ABS:
+ return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
+ return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
+ return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
+ return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
+ return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_CLOSEPATH:
+ this._skipOptionalSpaces();
+ return new window.SVGPathSegClosePath(owningPathSegList);
+ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
+ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
+ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
+ var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
+ case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
+ var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
+ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
+ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
+ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
+ return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
+ return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
+ case window.SVGPathSeg.PATHSEG_ARC_REL:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
+ case window.SVGPathSeg.PATHSEG_ARC_ABS:
+ var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
+ return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
+ default:
+ throw new Error('Unknown path seg type.');
+ }
+ };
- var builder = new Builder();
- var source = new Source(string);
+ var builder = new Builder();
+ var source = new Source(string);
- if (!source.initialCommandIsMoveTo()) {
- return [];
- }
- while (source.hasMoreData()) {
- var pathSeg = source.parseSegment();
- if (!pathSeg) {
- return [];
- }
- builder.appendSegment(pathSeg);
- }
+ if (!source.initialCommandIsMoveTo()) {
+ return [];
+ }
+ while (source.hasMoreData()) {
+ var pathSeg = source.parseSegment();
+ if (!pathSeg) {
+ return [];
+ }
+ builder.appendSegment(pathSeg);
+ }
- return builder.pathSegList;
- };
+ return builder.pathSegList;
+ };
}
}());
diff --git a/editor/recalculate.js b/editor/recalculate.js
index 0065bdb7..3e37eacc 100644
--- a/editor/recalculate.js
+++ b/editor/recalculate.js
@@ -24,7 +24,7 @@ var svgedit = svgedit || {}; // eslint-disable-line no-use-before-define
(function () {
if (!svgedit.recalculate) {
- svgedit.recalculate = {};
+ svgedit.recalculate = {};
}
var NS = svgedit.NS;
@@ -32,7 +32,7 @@ var context_;
// Function: svgedit.recalculate.init
svgedit.recalculate.init = function (editorContext) {
- context_ = editorContext;
+ context_ = editorContext;
};
// Function: svgedit.recalculate.updateClipPath
@@ -43,15 +43,15 @@ svgedit.recalculate.init = function (editorContext) {
// tx - The translation's x value
// ty - The translation's y value
svgedit.recalculate.updateClipPath = function (attr, tx, ty) {
- var path = getRefElem(attr).firstChild;
- var cpXform = svgedit.transformlist.getTransformList(path);
- var newxlate = context_.getSVGRoot().createSVGTransform();
- newxlate.setTranslate(tx, ty);
+ var path = getRefElem(attr).firstChild;
+ var cpXform = svgedit.transformlist.getTransformList(path);
+ var newxlate = context_.getSVGRoot().createSVGTransform();
+ newxlate.setTranslate(tx, ty);
- cpXform.appendItem(newxlate);
+ cpXform.appendItem(newxlate);
- // Update clipPath's dimensions
- svgedit.recalculate.recalculateDimensions(path);
+ // Update clipPath's dimensions
+ svgedit.recalculate.recalculateDimensions(path);
};
// Function: svgedit.recalculate.recalculateDimensions
@@ -63,748 +63,748 @@ svgedit.recalculate.updateClipPath = function (attr, tx, ty) {
// Returns:
// Undo command object with the resulting change
svgedit.recalculate.recalculateDimensions = function (selected) {
- if (selected == null) { return null; }
+ if (selected == null) { return null; }
- // Firefox Issue - 1081
- if (selected.nodeName === 'svg' && navigator.userAgent.indexOf('Firefox/20') >= 0) {
- return null;
- }
+ // Firefox Issue - 1081
+ if (selected.nodeName === 'svg' && navigator.userAgent.indexOf('Firefox/20') >= 0) {
+ return null;
+ }
- var svgroot = context_.getSVGRoot();
- var tlist = svgedit.transformlist.getTransformList(selected);
- var k;
- // remove any unnecessary transforms
- if (tlist && tlist.numberOfItems > 0) {
- k = tlist.numberOfItems;
- var noi = k;
- while (k--) {
- var xform = tlist.getItem(k);
- if (xform.type === 0) {
- tlist.removeItem(k);
- // remove identity matrices
- } else if (xform.type === 1) {
- if (svgedit.math.isIdentity(xform.matrix)) {
- if (noi === 1) {
- // Overcome Chrome bug (though only when noi is 1) with
- // `removeItem` preventing `removeAttribute` from
- // subsequently working
- // See https://bugs.chromium.org/p/chromium/issues/detail?id=843901
- selected.removeAttribute('transform');
- return null;
- }
- tlist.removeItem(k);
- }
- // remove zero-degree rotations
- } else if (xform.type === 4) {
- if (xform.angle === 0) {
- tlist.removeItem(k);
- }
- }
- }
- // End here if all it has is a rotation
- if (tlist.numberOfItems === 1 &&
- svgedit.utilities.getRotationAngle(selected)) { return null; }
- }
+ var svgroot = context_.getSVGRoot();
+ var tlist = svgedit.transformlist.getTransformList(selected);
+ var k;
+ // remove any unnecessary transforms
+ if (tlist && tlist.numberOfItems > 0) {
+ k = tlist.numberOfItems;
+ var noi = k;
+ while (k--) {
+ var xform = tlist.getItem(k);
+ if (xform.type === 0) {
+ tlist.removeItem(k);
+ // remove identity matrices
+ } else if (xform.type === 1) {
+ if (svgedit.math.isIdentity(xform.matrix)) {
+ if (noi === 1) {
+ // Overcome Chrome bug (though only when noi is 1) with
+ // `removeItem` preventing `removeAttribute` from
+ // subsequently working
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=843901
+ selected.removeAttribute('transform');
+ return null;
+ }
+ tlist.removeItem(k);
+ }
+ // remove zero-degree rotations
+ } else if (xform.type === 4) {
+ if (xform.angle === 0) {
+ tlist.removeItem(k);
+ }
+ }
+ }
+ // End here if all it has is a rotation
+ if (tlist.numberOfItems === 1 &&
+ svgedit.utilities.getRotationAngle(selected)) { return null; }
+ }
- // if this element had no transforms, we are done
- if (!tlist || tlist.numberOfItems === 0) {
- // Chrome apparently had a bug that requires clearing the attribute first.
- selected.setAttribute('transform', '');
- // However, this still next line currently doesn't work at all in Chrome
- selected.removeAttribute('transform');
- // selected.transform.baseVal.clear(); // Didn't help for Chrome bug
- return null;
- }
+ // if this element had no transforms, we are done
+ if (!tlist || tlist.numberOfItems === 0) {
+ // Chrome apparently had a bug that requires clearing the attribute first.
+ selected.setAttribute('transform', '');
+ // However, this still next line currently doesn't work at all in Chrome
+ selected.removeAttribute('transform');
+ // selected.transform.baseVal.clear(); // Didn't help for Chrome bug
+ return null;
+ }
- // TODO: Make this work for more than 2
- if (tlist) {
- k = tlist.numberOfItems;
- var mxs = [];
- while (k--) {
- var xform = tlist.getItem(k);
- if (xform.type === 1) {
- mxs.push([xform.matrix, k]);
- } else if (mxs.length) {
- mxs = [];
- }
- }
- if (mxs.length === 2) {
- var mNew = svgroot.createSVGTransformFromMatrix(svgedit.math.matrixMultiply(mxs[1][0], mxs[0][0]));
- tlist.removeItem(mxs[0][1]);
- tlist.removeItem(mxs[1][1]);
- tlist.insertItemBefore(mNew, mxs[1][1]);
- }
+ // TODO: Make this work for more than 2
+ if (tlist) {
+ k = tlist.numberOfItems;
+ var mxs = [];
+ while (k--) {
+ var xform = tlist.getItem(k);
+ if (xform.type === 1) {
+ mxs.push([xform.matrix, k]);
+ } else if (mxs.length) {
+ mxs = [];
+ }
+ }
+ if (mxs.length === 2) {
+ var mNew = svgroot.createSVGTransformFromMatrix(svgedit.math.matrixMultiply(mxs[1][0], mxs[0][0]));
+ tlist.removeItem(mxs[0][1]);
+ tlist.removeItem(mxs[1][1]);
+ tlist.insertItemBefore(mNew, mxs[1][1]);
+ }
- // combine matrix + translate
- k = tlist.numberOfItems;
- if (k >= 2 && tlist.getItem(k - 2).type === 1 && tlist.getItem(k - 1).type === 2) {
- var mt = svgroot.createSVGTransform();
+ // combine matrix + translate
+ k = tlist.numberOfItems;
+ if (k >= 2 && tlist.getItem(k - 2).type === 1 && tlist.getItem(k - 1).type === 2) {
+ var mt = svgroot.createSVGTransform();
- var m = svgedit.math.matrixMultiply(
- tlist.getItem(k - 2).matrix,
- tlist.getItem(k - 1).matrix);
- mt.setMatrix(m);
- tlist.removeItem(k - 2);
- tlist.removeItem(k - 2);
- tlist.appendItem(mt);
- }
- }
+ var m = svgedit.math.matrixMultiply(
+ tlist.getItem(k - 2).matrix,
+ tlist.getItem(k - 1).matrix);
+ mt.setMatrix(m);
+ tlist.removeItem(k - 2);
+ tlist.removeItem(k - 2);
+ tlist.appendItem(mt);
+ }
+ }
- // If it still has a single [M] or [R][M], return null too (prevents BatchCommand from being returned).
- switch (selected.tagName) {
- // Ignore these elements, as they can absorb the [M]
- case 'line':
- case 'polyline':
- case 'polygon':
- case 'path':
- break;
- default:
- if ((tlist.numberOfItems === 1 && tlist.getItem(0).type === 1) ||
- (tlist.numberOfItems === 2 && tlist.getItem(0).type === 1 && tlist.getItem(0).type === 4)) {
- return null;
- }
- }
+ // If it still has a single [M] or [R][M], return null too (prevents BatchCommand from being returned).
+ switch (selected.tagName) {
+ // Ignore these elements, as they can absorb the [M]
+ case 'line':
+ case 'polyline':
+ case 'polygon':
+ case 'path':
+ break;
+ default:
+ if ((tlist.numberOfItems === 1 && tlist.getItem(0).type === 1) ||
+ (tlist.numberOfItems === 2 && tlist.getItem(0).type === 1 && tlist.getItem(0).type === 4)) {
+ return null;
+ }
+ }
- // Grouped SVG element
- var gsvg = $(selected).data('gsvg');
+ // Grouped SVG element
+ var gsvg = $(selected).data('gsvg');
- // we know we have some transforms, so set up return variable
- var batchCmd = new svgedit.history.BatchCommand('Transform');
+ // we know we have some transforms, so set up return variable
+ var batchCmd = new svgedit.history.BatchCommand('Transform');
- // store initial values that will be affected by reducing the transform list
- var changes = {}, initial = null, attrs = [];
- switch (selected.tagName) {
- case 'line':
- attrs = ['x1', 'y1', 'x2', 'y2'];
- break;
- case 'circle':
- attrs = ['cx', 'cy', 'r'];
- break;
- case 'ellipse':
- attrs = ['cx', 'cy', 'rx', 'ry'];
- break;
- case 'foreignObject':
- case 'rect':
- case 'image':
- attrs = ['width', 'height', 'x', 'y'];
- break;
- case 'use':
- case 'text':
- case 'tspan':
- attrs = ['x', 'y'];
- break;
- case 'polygon':
- case 'polyline':
- initial = {};
- initial.points = selected.getAttribute('points');
- var list = selected.points;
- var len = list.numberOfItems;
- changes.points = new Array(len);
- var i;
- for (i = 0; i < len; ++i) {
- var pt = list.getItem(i);
- changes.points[i] = {x: pt.x, y: pt.y};
- }
- break;
- case 'path':
- initial = {};
- initial.d = selected.getAttribute('d');
- changes.d = selected.getAttribute('d');
- break;
- } // switch on element type to get initial values
+ // store initial values that will be affected by reducing the transform list
+ var changes = {}, initial = null, attrs = [];
+ switch (selected.tagName) {
+ case 'line':
+ attrs = ['x1', 'y1', 'x2', 'y2'];
+ break;
+ case 'circle':
+ attrs = ['cx', 'cy', 'r'];
+ break;
+ case 'ellipse':
+ attrs = ['cx', 'cy', 'rx', 'ry'];
+ break;
+ case 'foreignObject':
+ case 'rect':
+ case 'image':
+ attrs = ['width', 'height', 'x', 'y'];
+ break;
+ case 'use':
+ case 'text':
+ case 'tspan':
+ attrs = ['x', 'y'];
+ break;
+ case 'polygon':
+ case 'polyline':
+ initial = {};
+ initial.points = selected.getAttribute('points');
+ var list = selected.points;
+ var len = list.numberOfItems;
+ changes.points = new Array(len);
+ var i;
+ for (i = 0; i < len; ++i) {
+ var pt = list.getItem(i);
+ changes.points[i] = {x: pt.x, y: pt.y};
+ }
+ break;
+ case 'path':
+ initial = {};
+ initial.d = selected.getAttribute('d');
+ changes.d = selected.getAttribute('d');
+ break;
+ } // switch on element type to get initial values
- if (attrs.length) {
- changes = $(selected).attr(attrs);
- $.each(changes, function (attr, val) {
- changes[attr] = svgedit.units.convertToNum(attr, val);
- });
- } else if (gsvg) {
- // GSVG exception
- changes = {
- x: $(gsvg).attr('x') || 0,
- y: $(gsvg).attr('y') || 0
- };
- }
+ if (attrs.length) {
+ changes = $(selected).attr(attrs);
+ $.each(changes, function (attr, val) {
+ changes[attr] = svgedit.units.convertToNum(attr, val);
+ });
+ } else if (gsvg) {
+ // GSVG exception
+ changes = {
+ x: $(gsvg).attr('x') || 0,
+ y: $(gsvg).attr('y') || 0
+ };
+ }
- // if we haven't created an initial array in polygon/polyline/path, then
- // make a copy of initial values and include the transform
- if (initial == null) {
- initial = $.extend(true, {}, changes);
- $.each(initial, function (attr, val) {
- initial[attr] = svgedit.units.convertToNum(attr, val);
- });
- }
- // save the start transform value too
- initial.transform = context_.getStartTransform() || '';
+ // if we haven't created an initial array in polygon/polyline/path, then
+ // make a copy of initial values and include the transform
+ if (initial == null) {
+ initial = $.extend(true, {}, changes);
+ $.each(initial, function (attr, val) {
+ initial[attr] = svgedit.units.convertToNum(attr, val);
+ });
+ }
+ // save the start transform value too
+ initial.transform = context_.getStartTransform() || '';
- // if it's a regular group, we have special processing to flatten transforms
- if ((selected.tagName === 'g' && !gsvg) || selected.tagName === 'a') {
- var box = svgedit.utilities.getBBox(selected),
- oldcenter = {x: box.x + box.width / 2, y: box.y + box.height / 2},
- newcenter = svgedit.math.transformPoint(box.x + box.width / 2,
- box.y + box.height / 2,
- svgedit.math.transformListToTransform(tlist).matrix),
- m = svgroot.createSVGMatrix();
+ // if it's a regular group, we have special processing to flatten transforms
+ if ((selected.tagName === 'g' && !gsvg) || selected.tagName === 'a') {
+ var box = svgedit.utilities.getBBox(selected),
+ oldcenter = {x: box.x + box.width / 2, y: box.y + box.height / 2},
+ newcenter = svgedit.math.transformPoint(box.x + box.width / 2,
+ box.y + box.height / 2,
+ svgedit.math.transformListToTransform(tlist).matrix),
+ m = svgroot.createSVGMatrix();
- // temporarily strip off the rotate and save the old center
- var gangle = svgedit.utilities.getRotationAngle(selected);
- if (gangle) {
- var a = gangle * Math.PI / 180;
- if (Math.abs(a) > (1.0e-10)) {
- var s = Math.sin(a) / (1 - Math.cos(a));
- } else {
- // FIXME: This blows up if the angle is exactly 0!
- var s = 2 / a;
- }
- var i;
- for (i = 0; i < tlist.numberOfItems; ++i) {
- var xform = tlist.getItem(i);
- if (xform.type === 4) {
- // extract old center through mystical arts
- var rm = xform.matrix;
- oldcenter.y = (s * rm.e + rm.f) / 2;
- oldcenter.x = (rm.e - s * rm.f) / 2;
- tlist.removeItem(i);
- break;
- }
- }
- }
- var tx = 0, ty = 0,
- operation = 0,
- N = tlist.numberOfItems;
+ // temporarily strip off the rotate and save the old center
+ var gangle = svgedit.utilities.getRotationAngle(selected);
+ if (gangle) {
+ var a = gangle * Math.PI / 180;
+ if (Math.abs(a) > (1.0e-10)) {
+ var s = Math.sin(a) / (1 - Math.cos(a));
+ } else {
+ // FIXME: This blows up if the angle is exactly 0!
+ var s = 2 / a;
+ }
+ var i;
+ for (i = 0; i < tlist.numberOfItems; ++i) {
+ var xform = tlist.getItem(i);
+ if (xform.type === 4) {
+ // extract old center through mystical arts
+ var rm = xform.matrix;
+ oldcenter.y = (s * rm.e + rm.f) / 2;
+ oldcenter.x = (rm.e - s * rm.f) / 2;
+ tlist.removeItem(i);
+ break;
+ }
+ }
+ }
+ var tx = 0, ty = 0,
+ operation = 0,
+ N = tlist.numberOfItems;
- if (N) {
- var firstM = tlist.getItem(0).matrix;
- }
+ if (N) {
+ var firstM = tlist.getItem(0).matrix;
+ }
- // first, if it was a scale then the second-last transform will be it
- if (N >= 3 && tlist.getItem(N - 2).type === 3 &&
- tlist.getItem(N - 3).type === 2 && tlist.getItem(N - 1).type === 2) {
- operation = 3; // scale
+ // first, if it was a scale then the second-last transform will be it
+ if (N >= 3 && tlist.getItem(N - 2).type === 3 &&
+ tlist.getItem(N - 3).type === 2 && tlist.getItem(N - 1).type === 2) {
+ operation = 3; // scale
- // if the children are unrotated, pass the scale down directly
- // otherwise pass the equivalent matrix() down directly
- var tm = tlist.getItem(N - 3).matrix,
- sm = tlist.getItem(N - 2).matrix,
- tmn = tlist.getItem(N - 1).matrix;
+ // if the children are unrotated, pass the scale down directly
+ // otherwise pass the equivalent matrix() down directly
+ var tm = tlist.getItem(N - 3).matrix,
+ sm = tlist.getItem(N - 2).matrix,
+ tmn = tlist.getItem(N - 1).matrix;
- var children = selected.childNodes;
- var c = children.length;
- while (c--) {
- var child = children.item(c);
- tx = 0;
- ty = 0;
- if (child.nodeType === 1) {
- var childTlist = svgedit.transformlist.getTransformList(child);
+ var children = selected.childNodes;
+ var c = children.length;
+ while (c--) {
+ var child = children.item(c);
+ tx = 0;
+ ty = 0;
+ if (child.nodeType === 1) {
+ var childTlist = svgedit.transformlist.getTransformList(child);
- // some children might not have a transform (, , etc)
- if (!childTlist) { continue; }
+ // some children might not have a transform (, , etc)
+ if (!childTlist) { continue; }
- var m = svgedit.math.transformListToTransform(childTlist).matrix;
+ var m = svgedit.math.transformListToTransform(childTlist).matrix;
- // Convert a matrix to a scale if applicable
- // if (svgedit.math.hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) {
- // if (m.b==0 && m.c==0 && m.e==0 && m.f==0) {
- // childTlist.removeItem(0);
- // var translateOrigin = svgroot.createSVGTransform(),
- // scale = svgroot.createSVGTransform(),
- // translateBack = svgroot.createSVGTransform();
- // translateOrigin.setTranslate(0, 0);
- // scale.setScale(m.a, m.d);
- // translateBack.setTranslate(0, 0);
- // childTlist.appendItem(translateBack);
- // childTlist.appendItem(scale);
- // childTlist.appendItem(translateOrigin);
- // }
- // }
+ // Convert a matrix to a scale if applicable
+ // if (svgedit.math.hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) {
+ // if (m.b==0 && m.c==0 && m.e==0 && m.f==0) {
+ // childTlist.removeItem(0);
+ // var translateOrigin = svgroot.createSVGTransform(),
+ // scale = svgroot.createSVGTransform(),
+ // translateBack = svgroot.createSVGTransform();
+ // translateOrigin.setTranslate(0, 0);
+ // scale.setScale(m.a, m.d);
+ // translateBack.setTranslate(0, 0);
+ // childTlist.appendItem(translateBack);
+ // childTlist.appendItem(scale);
+ // childTlist.appendItem(translateOrigin);
+ // }
+ // }
- var angle = svgedit.utilities.getRotationAngle(child);
- var oldStartTransform = context_.getStartTransform();
- var childxforms = [];
- context_.setStartTransform(child.getAttribute('transform'));
- if (angle || svgedit.math.hasMatrixTransform(childTlist)) {
- var e2t = svgroot.createSVGTransform();
- e2t.setMatrix(svgedit.math.matrixMultiply(tm, sm, tmn, m));
- childTlist.clear();
- childTlist.appendItem(e2t);
- childxforms.push(e2t);
- // if not rotated or skewed, push the [T][S][-T] down to the child
- } else {
- // update the transform list with translate,scale,translate
+ var angle = svgedit.utilities.getRotationAngle(child);
+ var oldStartTransform = context_.getStartTransform();
+ var childxforms = [];
+ context_.setStartTransform(child.getAttribute('transform'));
+ if (angle || svgedit.math.hasMatrixTransform(childTlist)) {
+ var e2t = svgroot.createSVGTransform();
+ e2t.setMatrix(svgedit.math.matrixMultiply(tm, sm, tmn, m));
+ childTlist.clear();
+ childTlist.appendItem(e2t);
+ childxforms.push(e2t);
+ // if not rotated or skewed, push the [T][S][-T] down to the child
+ } else {
+ // update the transform list with translate,scale,translate
- // slide the [T][S][-T] from the front to the back
- // [T][S][-T][M] = [M][T2][S2][-T2]
+ // slide the [T][S][-T] from the front to the back
+ // [T][S][-T][M] = [M][T2][S2][-T2]
- // (only bringing [-T] to the right of [M])
- // [T][S][-T][M] = [T][S][M][-T2]
- // [-T2] = [M_inv][-T][M]
- var t2n = svgedit.math.matrixMultiply(m.inverse(), tmn, m);
- // [T2] is always negative translation of [-T2]
- var t2 = svgroot.createSVGMatrix();
- t2.e = -t2n.e;
- t2.f = -t2n.f;
+ // (only bringing [-T] to the right of [M])
+ // [T][S][-T][M] = [T][S][M][-T2]
+ // [-T2] = [M_inv][-T][M]
+ var t2n = svgedit.math.matrixMultiply(m.inverse(), tmn, m);
+ // [T2] is always negative translation of [-T2]
+ var t2 = svgroot.createSVGMatrix();
+ t2.e = -t2n.e;
+ t2.f = -t2n.f;
- // [T][S][-T][M] = [M][T2][S2][-T2]
- // [S2] = [T2_inv][M_inv][T][S][-T][M][-T2_inv]
- var s2 = svgedit.math.matrixMultiply(t2.inverse(), m.inverse(), tm, sm, tmn, m, t2n.inverse());
+ // [T][S][-T][M] = [M][T2][S2][-T2]
+ // [S2] = [T2_inv][M_inv][T][S][-T][M][-T2_inv]
+ var s2 = svgedit.math.matrixMultiply(t2.inverse(), m.inverse(), tm, sm, tmn, m, t2n.inverse());
- var translateOrigin = svgroot.createSVGTransform(),
- scale = svgroot.createSVGTransform(),
- translateBack = svgroot.createSVGTransform();
- translateOrigin.setTranslate(t2n.e, t2n.f);
- scale.setScale(s2.a, s2.d);
- translateBack.setTranslate(t2.e, t2.f);
- childTlist.appendItem(translateBack);
- childTlist.appendItem(scale);
- childTlist.appendItem(translateOrigin);
- childxforms.push(translateBack);
- childxforms.push(scale);
- childxforms.push(translateOrigin);
- // logMatrix(translateBack.matrix);
- // logMatrix(scale.matrix);
- } // not rotated
- batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
- // TODO: If any have this group as a parent and are
- // referencing this child, then we need to impose a reverse
- // scale on it so that when it won't get double-translated
- // var uses = selected.getElementsByTagNameNS(NS.SVG, 'use');
- // var href = '#' + child.id;
- // var u = uses.length;
- // while (u--) {
- // var useElem = uses.item(u);
- // if (href == svgedit.utilities.getHref(useElem)) {
- // var usexlate = svgroot.createSVGTransform();
- // usexlate.setTranslate(-tx,-ty);
- // svgedit.transformlist.getTransformList(useElem).insertItemBefore(usexlate,0);
- // batchCmd.addSubCommand( svgedit.recalculate.recalculateDimensions(useElem) );
- // }
- // }
- context_.setStartTransform(oldStartTransform);
- } // element
- } // for each child
- // Remove these transforms from group
- tlist.removeItem(N - 1);
- tlist.removeItem(N - 2);
- tlist.removeItem(N - 3);
- } else if (N >= 3 && tlist.getItem(N - 1).type === 1) {
- operation = 3; // scale
- m = svgedit.math.transformListToTransform(tlist).matrix;
- var e2t = svgroot.createSVGTransform();
- e2t.setMatrix(m);
- tlist.clear();
- tlist.appendItem(e2t);
- // next, check if the first transform was a translate
- // if we had [ T1 ] [ M ] we want to transform this into [ M ] [ T2 ]
- // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ]
- } else if ((N === 1 || (N > 1 && tlist.getItem(1).type !== 3)) &&
- tlist.getItem(0).type === 2) {
- operation = 2; // translate
- var T_M = svgedit.math.transformListToTransform(tlist).matrix;
- tlist.removeItem(0);
- var mInv = svgedit.math.transformListToTransform(tlist).matrix.inverse();
- var M2 = svgedit.math.matrixMultiply(mInv, T_M);
+ var translateOrigin = svgroot.createSVGTransform(),
+ scale = svgroot.createSVGTransform(),
+ translateBack = svgroot.createSVGTransform();
+ translateOrigin.setTranslate(t2n.e, t2n.f);
+ scale.setScale(s2.a, s2.d);
+ translateBack.setTranslate(t2.e, t2.f);
+ childTlist.appendItem(translateBack);
+ childTlist.appendItem(scale);
+ childTlist.appendItem(translateOrigin);
+ childxforms.push(translateBack);
+ childxforms.push(scale);
+ childxforms.push(translateOrigin);
+ // logMatrix(translateBack.matrix);
+ // logMatrix(scale.matrix);
+ } // not rotated
+ batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
+ // TODO: If any have this group as a parent and are
+ // referencing this child, then we need to impose a reverse
+ // scale on it so that when it won't get double-translated
+ // var uses = selected.getElementsByTagNameNS(NS.SVG, 'use');
+ // var href = '#' + child.id;
+ // var u = uses.length;
+ // while (u--) {
+ // var useElem = uses.item(u);
+ // if (href == svgedit.utilities.getHref(useElem)) {
+ // var usexlate = svgroot.createSVGTransform();
+ // usexlate.setTranslate(-tx,-ty);
+ // svgedit.transformlist.getTransformList(useElem).insertItemBefore(usexlate,0);
+ // batchCmd.addSubCommand( svgedit.recalculate.recalculateDimensions(useElem) );
+ // }
+ // }
+ context_.setStartTransform(oldStartTransform);
+ } // element
+ } // for each child
+ // Remove these transforms from group
+ tlist.removeItem(N - 1);
+ tlist.removeItem(N - 2);
+ tlist.removeItem(N - 3);
+ } else if (N >= 3 && tlist.getItem(N - 1).type === 1) {
+ operation = 3; // scale
+ m = svgedit.math.transformListToTransform(tlist).matrix;
+ var e2t = svgroot.createSVGTransform();
+ e2t.setMatrix(m);
+ tlist.clear();
+ tlist.appendItem(e2t);
+ // next, check if the first transform was a translate
+ // if we had [ T1 ] [ M ] we want to transform this into [ M ] [ T2 ]
+ // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ]
+ } else if ((N === 1 || (N > 1 && tlist.getItem(1).type !== 3)) &&
+ tlist.getItem(0).type === 2) {
+ operation = 2; // translate
+ var T_M = svgedit.math.transformListToTransform(tlist).matrix;
+ tlist.removeItem(0);
+ var mInv = svgedit.math.transformListToTransform(tlist).matrix.inverse();
+ var M2 = svgedit.math.matrixMultiply(mInv, T_M);
- tx = M2.e;
- ty = M2.f;
+ tx = M2.e;
+ ty = M2.f;
- if (tx !== 0 || ty !== 0) {
- // we pass the translates down to the individual children
- var children = selected.childNodes;
- var c = children.length;
+ if (tx !== 0 || ty !== 0) {
+ // we pass the translates down to the individual children
+ var children = selected.childNodes;
+ var c = children.length;
- var clipPathsDone = [];
+ var clipPathsDone = [];
- while (c--) {
- var child = children.item(c);
- if (child.nodeType === 1) {
- // Check if child has clip-path
- if (child.getAttribute('clip-path')) {
- // tx, ty
- var attr = child.getAttribute('clip-path');
- if (clipPathsDone.indexOf(attr) === -1) {
- svgedit.recalculate.updateClipPath(attr, tx, ty);
- clipPathsDone.push(attr);
- }
- }
+ while (c--) {
+ var child = children.item(c);
+ if (child.nodeType === 1) {
+ // Check if child has clip-path
+ if (child.getAttribute('clip-path')) {
+ // tx, ty
+ var attr = child.getAttribute('clip-path');
+ if (clipPathsDone.indexOf(attr) === -1) {
+ svgedit.recalculate.updateClipPath(attr, tx, ty);
+ clipPathsDone.push(attr);
+ }
+ }
- var oldStartTransform = context_.getStartTransform();
- context_.setStartTransform(child.getAttribute('transform'));
+ var oldStartTransform = context_.getStartTransform();
+ context_.setStartTransform(child.getAttribute('transform'));
- var childTlist = svgedit.transformlist.getTransformList(child);
- // some children might not have a transform (, , etc)
- if (childTlist) {
- var newxlate = svgroot.createSVGTransform();
- newxlate.setTranslate(tx, ty);
- if (childTlist.numberOfItems) {
- childTlist.insertItemBefore(newxlate, 0);
- } else {
- childTlist.appendItem(newxlate);
- }
- batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
- // If any have this group as a parent and are
- // referencing this child, then impose a reverse translate on it
- // so that when it won't get double-translated
- var uses = selected.getElementsByTagNameNS(NS.SVG, 'use');
- var href = '#' + child.id;
- var u = uses.length;
- while (u--) {
- var useElem = uses.item(u);
- if (href === svgedit.utilities.getHref(useElem)) {
- var usexlate = svgroot.createSVGTransform();
- usexlate.setTranslate(-tx, -ty);
- svgedit.transformlist.getTransformList(useElem).insertItemBefore(usexlate, 0);
- batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(useElem));
- }
- }
- context_.setStartTransform(oldStartTransform);
- }
- }
- }
+ var childTlist = svgedit.transformlist.getTransformList(child);
+ // some children might not have a transform (, , etc)
+ if (childTlist) {
+ var newxlate = svgroot.createSVGTransform();
+ newxlate.setTranslate(tx, ty);
+ if (childTlist.numberOfItems) {
+ childTlist.insertItemBefore(newxlate, 0);
+ } else {
+ childTlist.appendItem(newxlate);
+ }
+ batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
+ // If any have this group as a parent and are
+ // referencing this child, then impose a reverse translate on it
+ // so that when it won't get double-translated
+ var uses = selected.getElementsByTagNameNS(NS.SVG, 'use');
+ var href = '#' + child.id;
+ var u = uses.length;
+ while (u--) {
+ var useElem = uses.item(u);
+ if (href === svgedit.utilities.getHref(useElem)) {
+ var usexlate = svgroot.createSVGTransform();
+ usexlate.setTranslate(-tx, -ty);
+ svgedit.transformlist.getTransformList(useElem).insertItemBefore(usexlate, 0);
+ batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(useElem));
+ }
+ }
+ context_.setStartTransform(oldStartTransform);
+ }
+ }
+ }
- clipPathsDone = [];
- context_.setStartTransform(oldStartTransform);
- }
- // else, a matrix imposition from a parent group
- // keep pushing it down to the children
- } else if (N === 1 && tlist.getItem(0).type === 1 && !gangle) {
- operation = 1;
- var m = tlist.getItem(0).matrix,
- children = selected.childNodes,
- c = children.length;
- while (c--) {
- var child = children.item(c);
- if (child.nodeType === 1) {
- var oldStartTransform = context_.getStartTransform();
- context_.setStartTransform(child.getAttribute('transform'));
- var childTlist = svgedit.transformlist.getTransformList(child);
+ clipPathsDone = [];
+ context_.setStartTransform(oldStartTransform);
+ }
+ // else, a matrix imposition from a parent group
+ // keep pushing it down to the children
+ } else if (N === 1 && tlist.getItem(0).type === 1 && !gangle) {
+ operation = 1;
+ var m = tlist.getItem(0).matrix,
+ children = selected.childNodes,
+ c = children.length;
+ while (c--) {
+ var child = children.item(c);
+ if (child.nodeType === 1) {
+ var oldStartTransform = context_.getStartTransform();
+ context_.setStartTransform(child.getAttribute('transform'));
+ var childTlist = svgedit.transformlist.getTransformList(child);
- if (!childTlist) { continue; }
+ if (!childTlist) { continue; }
- var em = svgedit.math.matrixMultiply(m, svgedit.math.transformListToTransform(childTlist).matrix);
- var e2m = svgroot.createSVGTransform();
- e2m.setMatrix(em);
- childTlist.clear();
- childTlist.appendItem(e2m, 0);
+ var em = svgedit.math.matrixMultiply(m, svgedit.math.transformListToTransform(childTlist).matrix);
+ var e2m = svgroot.createSVGTransform();
+ e2m.setMatrix(em);
+ childTlist.clear();
+ childTlist.appendItem(e2m, 0);
- batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
- context_.setStartTransform(oldStartTransform);
+ batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
+ context_.setStartTransform(oldStartTransform);
- // Convert stroke
- // TODO: Find out if this should actually happen somewhere else
- var sw = child.getAttribute('stroke-width');
- if (child.getAttribute('stroke') !== 'none' && !isNaN(sw)) {
- var avg = (Math.abs(em.a) + Math.abs(em.d)) / 2;
- child.setAttribute('stroke-width', sw * avg);
- }
- }
- }
- tlist.clear();
- // else it was just a rotate
- } else {
- if (gangle) {
- var newRot = svgroot.createSVGTransform();
- newRot.setRotate(gangle, newcenter.x, newcenter.y);
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(newRot, 0);
- } else {
- tlist.appendItem(newRot);
- }
- }
- if (tlist.numberOfItems === 0) {
- selected.removeAttribute('transform');
- }
- return null;
- }
+ // Convert stroke
+ // TODO: Find out if this should actually happen somewhere else
+ var sw = child.getAttribute('stroke-width');
+ if (child.getAttribute('stroke') !== 'none' && !isNaN(sw)) {
+ var avg = (Math.abs(em.a) + Math.abs(em.d)) / 2;
+ child.setAttribute('stroke-width', sw * avg);
+ }
+ }
+ }
+ tlist.clear();
+ // else it was just a rotate
+ } else {
+ if (gangle) {
+ var newRot = svgroot.createSVGTransform();
+ newRot.setRotate(gangle, newcenter.x, newcenter.y);
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(newRot, 0);
+ } else {
+ tlist.appendItem(newRot);
+ }
+ }
+ if (tlist.numberOfItems === 0) {
+ selected.removeAttribute('transform');
+ }
+ return null;
+ }
- // if it was a translate, put back the rotate at the new center
- if (operation === 2) {
- if (gangle) {
- newcenter = {
- x: oldcenter.x + firstM.e,
- y: oldcenter.y + firstM.f
- };
+ // if it was a translate, put back the rotate at the new center
+ if (operation === 2) {
+ if (gangle) {
+ newcenter = {
+ x: oldcenter.x + firstM.e,
+ y: oldcenter.y + firstM.f
+ };
- var newRot = svgroot.createSVGTransform();
- newRot.setRotate(gangle, newcenter.x, newcenter.y);
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(newRot, 0);
- } else {
- tlist.appendItem(newRot);
- }
- }
- // if it was a resize
- } else if (operation === 3) {
- var m = svgedit.math.transformListToTransform(tlist).matrix;
- var roldt = svgroot.createSVGTransform();
- roldt.setRotate(gangle, oldcenter.x, oldcenter.y);
- var rold = roldt.matrix;
- var rnew = svgroot.createSVGTransform();
- rnew.setRotate(gangle, newcenter.x, newcenter.y);
- var rnewInv = rnew.matrix.inverse(),
- mInv = m.inverse(),
- extrat = svgedit.math.matrixMultiply(mInv, rnewInv, rold, m);
+ var newRot = svgroot.createSVGTransform();
+ newRot.setRotate(gangle, newcenter.x, newcenter.y);
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(newRot, 0);
+ } else {
+ tlist.appendItem(newRot);
+ }
+ }
+ // if it was a resize
+ } else if (operation === 3) {
+ var m = svgedit.math.transformListToTransform(tlist).matrix;
+ var roldt = svgroot.createSVGTransform();
+ roldt.setRotate(gangle, oldcenter.x, oldcenter.y);
+ var rold = roldt.matrix;
+ var rnew = svgroot.createSVGTransform();
+ rnew.setRotate(gangle, newcenter.x, newcenter.y);
+ var rnewInv = rnew.matrix.inverse(),
+ mInv = m.inverse(),
+ extrat = svgedit.math.matrixMultiply(mInv, rnewInv, rold, m);
- tx = extrat.e;
- ty = extrat.f;
+ tx = extrat.e;
+ ty = extrat.f;
- if (tx !== 0 || ty !== 0) {
- // now push this transform down to the children
- // we pass the translates down to the individual children
- var children = selected.childNodes;
- var c = children.length;
- while (c--) {
- var child = children.item(c);
- if (child.nodeType === 1) {
- var oldStartTransform = context_.getStartTransform();
- context_.setStartTransform(child.getAttribute('transform'));
- var childTlist = svgedit.transformlist.getTransformList(child);
- var newxlate = svgroot.createSVGTransform();
- newxlate.setTranslate(tx, ty);
- if (childTlist.numberOfItems) {
- childTlist.insertItemBefore(newxlate, 0);
- } else {
- childTlist.appendItem(newxlate);
- }
+ if (tx !== 0 || ty !== 0) {
+ // now push this transform down to the children
+ // we pass the translates down to the individual children
+ var children = selected.childNodes;
+ var c = children.length;
+ while (c--) {
+ var child = children.item(c);
+ if (child.nodeType === 1) {
+ var oldStartTransform = context_.getStartTransform();
+ context_.setStartTransform(child.getAttribute('transform'));
+ var childTlist = svgedit.transformlist.getTransformList(child);
+ var newxlate = svgroot.createSVGTransform();
+ newxlate.setTranslate(tx, ty);
+ if (childTlist.numberOfItems) {
+ childTlist.insertItemBefore(newxlate, 0);
+ } else {
+ childTlist.appendItem(newxlate);
+ }
- batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
- context_.setStartTransform(oldStartTransform);
- }
- }
- }
+ batchCmd.addSubCommand(svgedit.recalculate.recalculateDimensions(child));
+ context_.setStartTransform(oldStartTransform);
+ }
+ }
+ }
- if (gangle) {
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(rnew, 0);
- } else {
- tlist.appendItem(rnew);
- }
- }
- }
- // else, it's a non-group
- } else {
- // FIXME: box might be null for some elements ( etc), need to handle this
- var box = svgedit.utilities.getBBox(selected);
+ if (gangle) {
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(rnew, 0);
+ } else {
+ tlist.appendItem(rnew);
+ }
+ }
+ }
+ // else, it's a non-group
+ } else {
+ // FIXME: box might be null for some elements ( etc), need to handle this
+ var box = svgedit.utilities.getBBox(selected);
- // Paths (and possbly other shapes) will have no BBox while still in ,
- // but we still may need to recalculate them (see issue 595).
- // TODO: Figure out how to get BBox from these elements in case they
- // have a rotation transform
+ // Paths (and possbly other shapes) will have no BBox while still in ,
+ // but we still may need to recalculate them (see issue 595).
+ // TODO: Figure out how to get BBox from these elements in case they
+ // have a rotation transform
- if (!box && selected.tagName !== 'path') return null;
+ if (!box && selected.tagName !== 'path') return null;
- var m = svgroot.createSVGMatrix(),
- // temporarily strip off the rotate and save the old center
- angle = svgedit.utilities.getRotationAngle(selected);
- if (angle) {
- var oldcenter = {x: box.x + box.width / 2, y: box.y + box.height / 2},
- newcenter = svgedit.math.transformPoint(box.x + box.width / 2, box.y + box.height / 2,
- svgedit.math.transformListToTransform(tlist).matrix);
+ var m = svgroot.createSVGMatrix(),
+ // temporarily strip off the rotate and save the old center
+ angle = svgedit.utilities.getRotationAngle(selected);
+ if (angle) {
+ var oldcenter = {x: box.x + box.width / 2, y: box.y + box.height / 2},
+ newcenter = svgedit.math.transformPoint(box.x + box.width / 2, box.y + box.height / 2,
+ svgedit.math.transformListToTransform(tlist).matrix);
- var a = angle * Math.PI / 180;
- if (Math.abs(a) > (1.0e-10)) {
- var s = Math.sin(a) / (1 - Math.cos(a));
- } else {
- // FIXME: This blows up if the angle is exactly 0!
- var s = 2 / a;
- }
- for (var i = 0; i < tlist.numberOfItems; ++i) {
- var xform = tlist.getItem(i);
- if (xform.type === 4) {
- // extract old center through mystical arts
- var rm = xform.matrix;
- oldcenter.y = (s * rm.e + rm.f) / 2;
- oldcenter.x = (rm.e - s * rm.f) / 2;
- tlist.removeItem(i);
- break;
- }
- }
- }
+ var a = angle * Math.PI / 180;
+ if (Math.abs(a) > (1.0e-10)) {
+ var s = Math.sin(a) / (1 - Math.cos(a));
+ } else {
+ // FIXME: This blows up if the angle is exactly 0!
+ var s = 2 / a;
+ }
+ for (var i = 0; i < tlist.numberOfItems; ++i) {
+ var xform = tlist.getItem(i);
+ if (xform.type === 4) {
+ // extract old center through mystical arts
+ var rm = xform.matrix;
+ oldcenter.y = (s * rm.e + rm.f) / 2;
+ oldcenter.x = (rm.e - s * rm.f) / 2;
+ tlist.removeItem(i);
+ break;
+ }
+ }
+ }
- // 2 = translate, 3 = scale, 4 = rotate, 1 = matrix imposition
- var operation = 0;
- var N = tlist.numberOfItems;
+ // 2 = translate, 3 = scale, 4 = rotate, 1 = matrix imposition
+ var operation = 0;
+ var N = tlist.numberOfItems;
- // Check if it has a gradient with userSpaceOnUse, in which case
- // adjust it by recalculating the matrix transform.
- // TODO: Make this work in Webkit using svgedit.transformlist.SVGTransformList
- if (!svgedit.browser.isWebkit()) {
- var fill = selected.getAttribute('fill');
- if (fill && fill.indexOf('url(') === 0) {
- var paint = getRefElem(fill);
- var type = 'pattern';
- if (paint.tagName !== type) type = 'gradient';
- var attrVal = paint.getAttribute(type + 'Units');
- if (attrVal === 'userSpaceOnUse') {
- // Update the userSpaceOnUse element
- m = svgedit.math.transformListToTransform(tlist).matrix;
- var gtlist = svgedit.transformlist.getTransformList(paint);
- var gmatrix = svgedit.math.transformListToTransform(gtlist).matrix;
- m = svgedit.math.matrixMultiply(m, gmatrix);
- var mStr = 'matrix(' + [m.a, m.b, m.c, m.d, m.e, m.f].join(',') + ')';
- paint.setAttribute(type + 'Transform', mStr);
- }
- }
- }
+ // Check if it has a gradient with userSpaceOnUse, in which case
+ // adjust it by recalculating the matrix transform.
+ // TODO: Make this work in Webkit using svgedit.transformlist.SVGTransformList
+ if (!svgedit.browser.isWebkit()) {
+ var fill = selected.getAttribute('fill');
+ if (fill && fill.indexOf('url(') === 0) {
+ var paint = getRefElem(fill);
+ var type = 'pattern';
+ if (paint.tagName !== type) type = 'gradient';
+ var attrVal = paint.getAttribute(type + 'Units');
+ if (attrVal === 'userSpaceOnUse') {
+ // Update the userSpaceOnUse element
+ m = svgedit.math.transformListToTransform(tlist).matrix;
+ var gtlist = svgedit.transformlist.getTransformList(paint);
+ var gmatrix = svgedit.math.transformListToTransform(gtlist).matrix;
+ m = svgedit.math.matrixMultiply(m, gmatrix);
+ var mStr = 'matrix(' + [m.a, m.b, m.c, m.d, m.e, m.f].join(',') + ')';
+ paint.setAttribute(type + 'Transform', mStr);
+ }
+ }
+ }
- // first, if it was a scale of a non-skewed element, then the second-last
- // transform will be the [S]
- // if we had [M][T][S][T] we want to extract the matrix equivalent of
- // [T][S][T] and push it down to the element
- if (N >= 3 && tlist.getItem(N - 2).type === 3 &&
- tlist.getItem(N - 3).type === 2 && tlist.getItem(N - 1).type === 2) {
- // Removed this so a with a given [T][S][T] would convert to a matrix.
- // Is that bad?
- // && selected.nodeName != 'use'
- operation = 3; // scale
- m = svgedit.math.transformListToTransform(tlist, N - 3, N - 1).matrix;
- tlist.removeItem(N - 1);
- tlist.removeItem(N - 2);
- tlist.removeItem(N - 3);
- // if we had [T][S][-T][M], then this was a skewed element being resized
- // Thus, we simply combine it all into one matrix
- } else if (N === 4 && tlist.getItem(N - 1).type === 1) {
- operation = 3; // scale
- m = svgedit.math.transformListToTransform(tlist).matrix;
- var e2t = svgroot.createSVGTransform();
- e2t.setMatrix(m);
- tlist.clear();
- tlist.appendItem(e2t);
- // reset the matrix so that the element is not re-mapped
- m = svgroot.createSVGMatrix();
- // if we had [R][T][S][-T][M], then this was a rotated matrix-element
- // if we had [T1][M] we want to transform this into [M][T2]
- // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ] and we can push [T2]
- // down to the element
- } else if ((N === 1 || (N > 1 && tlist.getItem(1).type !== 3)) &&
- tlist.getItem(0).type === 2) {
- operation = 2; // translate
- var oldxlate = tlist.getItem(0).matrix,
- meq = svgedit.math.transformListToTransform(tlist, 1).matrix,
- meqInv = meq.inverse();
- m = svgedit.math.matrixMultiply(meqInv, oldxlate, meq);
- tlist.removeItem(0);
- // else if this child now has a matrix imposition (from a parent group)
- // we might be able to simplify
- } else if (N === 1 && tlist.getItem(0).type === 1 && !angle) {
- // Remap all point-based elements
- m = svgedit.math.transformListToTransform(tlist).matrix;
- switch (selected.tagName) {
- case 'line':
- changes = $(selected).attr(['x1', 'y1', 'x2', 'y2']);
- // Fallthrough
- case 'polyline':
- case 'polygon':
- changes.points = selected.getAttribute('points');
- if (changes.points) {
- var list = selected.points;
- var len = list.numberOfItems;
- changes.points = new Array(len);
- for (var i = 0; i < len; ++i) {
- var pt = list.getItem(i);
- changes.points[i] = {x: pt.x, y: pt.y};
- }
- }
- // Fallthrough
- case 'path':
- changes.d = selected.getAttribute('d');
- operation = 1;
- tlist.clear();
- break;
- default:
- break;
- }
- // if it was a rotation, put the rotate back and return without a command
- // (this function has zero work to do for a rotate())
- } else {
- operation = 4; // rotation
- if (angle) {
- var newRot = svgroot.createSVGTransform();
- newRot.setRotate(angle, newcenter.x, newcenter.y);
+ // first, if it was a scale of a non-skewed element, then the second-last
+ // transform will be the [S]
+ // if we had [M][T][S][T] we want to extract the matrix equivalent of
+ // [T][S][T] and push it down to the element
+ if (N >= 3 && tlist.getItem(N - 2).type === 3 &&
+ tlist.getItem(N - 3).type === 2 && tlist.getItem(N - 1).type === 2) {
+ // Removed this so a with a given [T][S][T] would convert to a matrix.
+ // Is that bad?
+ // && selected.nodeName != 'use'
+ operation = 3; // scale
+ m = svgedit.math.transformListToTransform(tlist, N - 3, N - 1).matrix;
+ tlist.removeItem(N - 1);
+ tlist.removeItem(N - 2);
+ tlist.removeItem(N - 3);
+ // if we had [T][S][-T][M], then this was a skewed element being resized
+ // Thus, we simply combine it all into one matrix
+ } else if (N === 4 && tlist.getItem(N - 1).type === 1) {
+ operation = 3; // scale
+ m = svgedit.math.transformListToTransform(tlist).matrix;
+ var e2t = svgroot.createSVGTransform();
+ e2t.setMatrix(m);
+ tlist.clear();
+ tlist.appendItem(e2t);
+ // reset the matrix so that the element is not re-mapped
+ m = svgroot.createSVGMatrix();
+ // if we had [R][T][S][-T][M], then this was a rotated matrix-element
+ // if we had [T1][M] we want to transform this into [M][T2]
+ // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ] and we can push [T2]
+ // down to the element
+ } else if ((N === 1 || (N > 1 && tlist.getItem(1).type !== 3)) &&
+ tlist.getItem(0).type === 2) {
+ operation = 2; // translate
+ var oldxlate = tlist.getItem(0).matrix,
+ meq = svgedit.math.transformListToTransform(tlist, 1).matrix,
+ meqInv = meq.inverse();
+ m = svgedit.math.matrixMultiply(meqInv, oldxlate, meq);
+ tlist.removeItem(0);
+ // else if this child now has a matrix imposition (from a parent group)
+ // we might be able to simplify
+ } else if (N === 1 && tlist.getItem(0).type === 1 && !angle) {
+ // Remap all point-based elements
+ m = svgedit.math.transformListToTransform(tlist).matrix;
+ switch (selected.tagName) {
+ case 'line':
+ changes = $(selected).attr(['x1', 'y1', 'x2', 'y2']);
+ // Fallthrough
+ case 'polyline':
+ case 'polygon':
+ changes.points = selected.getAttribute('points');
+ if (changes.points) {
+ var list = selected.points;
+ var len = list.numberOfItems;
+ changes.points = new Array(len);
+ for (var i = 0; i < len; ++i) {
+ var pt = list.getItem(i);
+ changes.points[i] = {x: pt.x, y: pt.y};
+ }
+ }
+ // Fallthrough
+ case 'path':
+ changes.d = selected.getAttribute('d');
+ operation = 1;
+ tlist.clear();
+ break;
+ default:
+ break;
+ }
+ // if it was a rotation, put the rotate back and return without a command
+ // (this function has zero work to do for a rotate())
+ } else {
+ operation = 4; // rotation
+ if (angle) {
+ var newRot = svgroot.createSVGTransform();
+ newRot.setRotate(angle, newcenter.x, newcenter.y);
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(newRot, 0);
- } else {
- tlist.appendItem(newRot);
- }
- }
- if (tlist.numberOfItems === 0) {
- selected.removeAttribute('transform');
- }
- return null;
- }
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(newRot, 0);
+ } else {
+ tlist.appendItem(newRot);
+ }
+ }
+ if (tlist.numberOfItems === 0) {
+ selected.removeAttribute('transform');
+ }
+ return null;
+ }
- // if it was a translate or resize, we need to remap the element and absorb the xform
- if (operation === 1 || operation === 2 || operation === 3) {
- svgedit.coords.remapElement(selected, changes, m);
- } // if we are remapping
+ // if it was a translate or resize, we need to remap the element and absorb the xform
+ if (operation === 1 || operation === 2 || operation === 3) {
+ svgedit.coords.remapElement(selected, changes, m);
+ } // if we are remapping
- // if it was a translate, put back the rotate at the new center
- if (operation === 2) {
- if (angle) {
- if (!svgedit.math.hasMatrixTransform(tlist)) {
- newcenter = {
- x: oldcenter.x + m.e,
- y: oldcenter.y + m.f
- };
- }
- var newRot = svgroot.createSVGTransform();
- newRot.setRotate(angle, newcenter.x, newcenter.y);
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(newRot, 0);
- } else {
- tlist.appendItem(newRot);
- }
- }
- // We have special processing for tspans: Tspans are not transformable
- // but they can have x,y coordinates (sigh). Thus, if this was a translate,
- // on a text element, also translate any tspan children.
- if (selected.tagName === 'text') {
- var children = selected.childNodes;
- var c = children.length;
- while (c--) {
- var child = children.item(c);
- if (child.tagName === 'tspan') {
- var tspanChanges = {
- x: $(child).attr('x') || 0,
- y: $(child).attr('y') || 0
- };
- svgedit.coords.remapElement(child, tspanChanges, m);
- }
- }
- }
- // [Rold][M][T][S][-T] became [Rold][M]
- // we want it to be [Rnew][M][Tr] where Tr is the
- // translation required to re-center it
- // Therefore, [Tr] = [M_inv][Rnew_inv][Rold][M]
- } else if (operation === 3 && angle) {
- var m = svgedit.math.transformListToTransform(tlist).matrix;
- var roldt = svgroot.createSVGTransform();
- roldt.setRotate(angle, oldcenter.x, oldcenter.y);
- var rold = roldt.matrix;
- var rnew = svgroot.createSVGTransform();
- rnew.setRotate(angle, newcenter.x, newcenter.y);
- var rnewInv = rnew.matrix.inverse();
- var mInv = m.inverse();
- var extrat = svgedit.math.matrixMultiply(mInv, rnewInv, rold, m);
+ // if it was a translate, put back the rotate at the new center
+ if (operation === 2) {
+ if (angle) {
+ if (!svgedit.math.hasMatrixTransform(tlist)) {
+ newcenter = {
+ x: oldcenter.x + m.e,
+ y: oldcenter.y + m.f
+ };
+ }
+ var newRot = svgroot.createSVGTransform();
+ newRot.setRotate(angle, newcenter.x, newcenter.y);
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(newRot, 0);
+ } else {
+ tlist.appendItem(newRot);
+ }
+ }
+ // We have special processing for tspans: Tspans are not transformable
+ // but they can have x,y coordinates (sigh). Thus, if this was a translate,
+ // on a text element, also translate any tspan children.
+ if (selected.tagName === 'text') {
+ var children = selected.childNodes;
+ var c = children.length;
+ while (c--) {
+ var child = children.item(c);
+ if (child.tagName === 'tspan') {
+ var tspanChanges = {
+ x: $(child).attr('x') || 0,
+ y: $(child).attr('y') || 0
+ };
+ svgedit.coords.remapElement(child, tspanChanges, m);
+ }
+ }
+ }
+ // [Rold][M][T][S][-T] became [Rold][M]
+ // we want it to be [Rnew][M][Tr] where Tr is the
+ // translation required to re-center it
+ // Therefore, [Tr] = [M_inv][Rnew_inv][Rold][M]
+ } else if (operation === 3 && angle) {
+ var m = svgedit.math.transformListToTransform(tlist).matrix;
+ var roldt = svgroot.createSVGTransform();
+ roldt.setRotate(angle, oldcenter.x, oldcenter.y);
+ var rold = roldt.matrix;
+ var rnew = svgroot.createSVGTransform();
+ rnew.setRotate(angle, newcenter.x, newcenter.y);
+ var rnewInv = rnew.matrix.inverse();
+ var mInv = m.inverse();
+ var extrat = svgedit.math.matrixMultiply(mInv, rnewInv, rold, m);
- svgedit.coords.remapElement(selected, changes, extrat);
- if (angle) {
- if (tlist.numberOfItems) {
- tlist.insertItemBefore(rnew, 0);
- } else {
- tlist.appendItem(rnew);
- }
- }
- }
- } // a non-group
+ svgedit.coords.remapElement(selected, changes, extrat);
+ if (angle) {
+ if (tlist.numberOfItems) {
+ tlist.insertItemBefore(rnew, 0);
+ } else {
+ tlist.appendItem(rnew);
+ }
+ }
+ }
+ } // a non-group
- // if the transform list has been emptied, remove it
- if (tlist.numberOfItems === 0) {
- selected.removeAttribute('transform');
- }
+ // if the transform list has been emptied, remove it
+ if (tlist.numberOfItems === 0) {
+ selected.removeAttribute('transform');
+ }
- batchCmd.addSubCommand(new svgedit.history.ChangeElementCommand(selected, initial));
+ batchCmd.addSubCommand(new svgedit.history.ChangeElementCommand(selected, initial));
- return batchCmd;
+ return batchCmd;
};
})();
diff --git a/editor/sanitize.js b/editor/sanitize.js
index 8c237bc3..ac1c864c 100644
--- a/editor/sanitize.js
+++ b/editor/sanitize.js
@@ -19,95 +19,95 @@
'use strict';
if (!svgedit.sanitize) {
- svgedit.sanitize = {};
+ svgedit.sanitize = {};
}
var NS = svgedit.NS,
- REVERSE_NS = svgedit.getReverseNS();
+ REVERSE_NS = svgedit.getReverseNS();
// this defines which elements and attributes that we support
var svgWhiteList_ = {
- // SVG Elements
- 'a': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'xlink:href', 'xlink:title'],
- 'circle': ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
- 'clipPath': ['class', 'clipPathUnits', 'id'],
- 'defs': [],
- 'style': ['type'],
- 'desc': [],
- 'ellipse': ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
- 'feGaussianBlur': ['class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation'],
- 'filter': ['class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y'],
- 'foreignObject': ['class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y'],
- 'g': ['class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor'],
- 'image': ['class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y'],
- 'line': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2'],
- 'linearGradient': ['class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2'],
- 'marker': ['id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox'],
- 'mask': ['class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y'],
- 'metadata': ['class', 'id'],
- 'path': ['class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
- 'pattern': ['class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y'],
- 'polygon': ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
- 'polyline': ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
- 'radialGradient': ['class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href'],
- 'rect': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y'],
- 'stop': ['class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage'],
- 'svg': ['class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y'],
- 'switch': ['class', 'id', 'requiredFeatures', 'systemLanguage'],
- 'symbol': ['class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox'],
- 'text': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y'],
- 'textPath': ['class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href'],
- 'title': [],
- 'tspan': ['class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y'],
- 'use': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y'],
+ // SVG Elements
+ 'a': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'xlink:href', 'xlink:title'],
+ 'circle': ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
+ 'clipPath': ['class', 'clipPathUnits', 'id'],
+ 'defs': [],
+ 'style': ['type'],
+ 'desc': [],
+ 'ellipse': ['class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
+ 'feGaussianBlur': ['class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation'],
+ 'filter': ['class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y'],
+ 'foreignObject': ['class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y'],
+ 'g': ['class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor'],
+ 'image': ['class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y'],
+ 'line': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2'],
+ 'linearGradient': ['class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2'],
+ 'marker': ['id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox'],
+ 'mask': ['class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y'],
+ 'metadata': ['class', 'id'],
+ 'path': ['class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
+ 'pattern': ['class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y'],
+ 'polygon': ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
+ 'polyline': ['class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform'],
+ 'radialGradient': ['class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href'],
+ 'rect': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y'],
+ 'stop': ['class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage'],
+ 'svg': ['class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y'],
+ 'switch': ['class', 'id', 'requiredFeatures', 'systemLanguage'],
+ 'symbol': ['class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox'],
+ 'text': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y'],
+ 'textPath': ['class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href'],
+ 'title': [],
+ 'tspan': ['class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y'],
+ 'use': ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y'],
- // MathML Elements
- 'annotation': ['encoding'],
- 'annotation-xml': ['encoding'],
- 'maction': ['actiontype', 'other', 'selection'],
- 'math': ['class', 'id', 'display', 'xmlns'],
- 'menclose': ['notation'],
- 'merror': [],
- 'mfrac': ['linethickness'],
- 'mi': ['mathvariant'],
- 'mmultiscripts': [],
- 'mn': [],
- 'mo': ['fence', 'lspace', 'maxsize', 'minsize', 'rspace', 'stretchy'],
- 'mover': [],
- 'mpadded': ['lspace', 'width', 'height', 'depth', 'voffset'],
- 'mphantom': [],
- 'mprescripts': [],
- 'mroot': [],
- 'mrow': ['xlink:href', 'xlink:type', 'xmlns:xlink'],
- 'mspace': ['depth', 'height', 'width'],
- 'msqrt': [],
- 'mstyle': ['displaystyle', 'mathbackground', 'mathcolor', 'mathvariant', 'scriptlevel'],
- 'msub': [],
- 'msubsup': [],
- 'msup': [],
- 'mtable': ['align', 'columnalign', 'columnlines', 'columnspacing', 'displaystyle', 'equalcolumns', 'equalrows', 'frame', 'rowalign', 'rowlines', 'rowspacing', 'width'],
- 'mtd': ['columnalign', 'columnspan', 'rowalign', 'rowspan'],
- 'mtext': [],
- 'mtr': ['columnalign', 'rowalign'],
- 'munder': [],
- 'munderover': [],
- 'none': [],
- 'semantics': []
+ // MathML Elements
+ 'annotation': ['encoding'],
+ 'annotation-xml': ['encoding'],
+ 'maction': ['actiontype', 'other', 'selection'],
+ 'math': ['class', 'id', 'display', 'xmlns'],
+ 'menclose': ['notation'],
+ 'merror': [],
+ 'mfrac': ['linethickness'],
+ 'mi': ['mathvariant'],
+ 'mmultiscripts': [],
+ 'mn': [],
+ 'mo': ['fence', 'lspace', 'maxsize', 'minsize', 'rspace', 'stretchy'],
+ 'mover': [],
+ 'mpadded': ['lspace', 'width', 'height', 'depth', 'voffset'],
+ 'mphantom': [],
+ 'mprescripts': [],
+ 'mroot': [],
+ 'mrow': ['xlink:href', 'xlink:type', 'xmlns:xlink'],
+ 'mspace': ['depth', 'height', 'width'],
+ 'msqrt': [],
+ 'mstyle': ['displaystyle', 'mathbackground', 'mathcolor', 'mathvariant', 'scriptlevel'],
+ 'msub': [],
+ 'msubsup': [],
+ 'msup': [],
+ 'mtable': ['align', 'columnalign', 'columnlines', 'columnspacing', 'displaystyle', 'equalcolumns', 'equalrows', 'frame', 'rowalign', 'rowlines', 'rowspacing', 'width'],
+ 'mtd': ['columnalign', 'columnspan', 'rowalign', 'rowspan'],
+ 'mtext': [],
+ 'mtr': ['columnalign', 'rowalign'],
+ 'munder': [],
+ 'munderover': [],
+ 'none': [],
+ 'semantics': []
};
// Produce a Namespace-aware version of svgWhitelist
var svgWhiteListNS_ = {};
$.each(svgWhiteList_, function (elt, atts) {
- var attNS = {};
- $.each(atts, function (i, att) {
- if (att.indexOf(':') >= 0) {
- var v = att.split(':');
- attNS[v[1]] = NS[(v[0]).toUpperCase()];
- } else {
- attNS[att] = att === 'xmlns' ? NS.XMLNS : null;
- }
- });
- svgWhiteListNS_[elt] = attNS;
+ var attNS = {};
+ $.each(atts, function (i, att) {
+ if (att.indexOf(':') >= 0) {
+ var v = att.split(':');
+ attNS[v[1]] = NS[(v[0]).toUpperCase()];
+ } else {
+ attNS[att] = att === 'xmlns' ? NS.XMLNS : null;
+ }
+ });
+ svgWhiteListNS_[elt] = attNS;
});
// Function: svgedit.sanitize.sanitizeSvg
@@ -117,140 +117,140 @@ $.each(svgWhiteList_, function (elt, atts) {
// Parameters:
// node - The DOM element to be checked (we'll also check its children)
svgedit.sanitize.sanitizeSvg = function (node) {
- // Cleanup text nodes
- if (node.nodeType === 3) { // 3 == TEXT_NODE
- // Trim whitespace
- node.nodeValue = node.nodeValue.replace(/^\s+|\s+$/g, '');
- // Remove if empty
- if (node.nodeValue.length === 0) {
- node.parentNode.removeChild(node);
- }
- }
+ // Cleanup text nodes
+ if (node.nodeType === 3) { // 3 == TEXT_NODE
+ // Trim whitespace
+ node.nodeValue = node.nodeValue.replace(/^\s+|\s+$/g, '');
+ // Remove if empty
+ if (node.nodeValue.length === 0) {
+ node.parentNode.removeChild(node);
+ }
+ }
- // We only care about element nodes.
- // Automatically return for all non-element nodes, such as comments, etc.
- if (node.nodeType !== 1) { // 1 == ELEMENT_NODE
- return;
- }
+ // We only care about element nodes.
+ // Automatically return for all non-element nodes, such as comments, etc.
+ if (node.nodeType !== 1) { // 1 == ELEMENT_NODE
+ return;
+ }
- var doc = node.ownerDocument;
- var parent = node.parentNode;
- // can parent ever be null here? I think the root node's parent is the document...
- if (!doc || !parent) {
- return;
- }
+ var doc = node.ownerDocument;
+ var parent = node.parentNode;
+ // can parent ever be null here? I think the root node's parent is the document...
+ if (!doc || !parent) {
+ return;
+ }
- var allowedAttrs = svgWhiteList_[node.nodeName];
- var allowedAttrsNS = svgWhiteListNS_[node.nodeName];
- var i;
- // if this element is supported, sanitize it
- if (typeof allowedAttrs !== 'undefined') {
- var seAttrs = [];
- i = node.attributes.length;
- while (i--) {
- // if the attribute is not in our whitelist, then remove it
- // could use jQuery's inArray(), but I don't know if that's any better
- var attr = node.attributes.item(i);
- var attrName = attr.nodeName;
- var attrLocalName = attr.localName;
- var attrNsURI = attr.namespaceURI;
- // Check that an attribute with the correct localName in the correct namespace is on
- // our whitelist or is a namespace declaration for one of our allowed namespaces
- if (!(allowedAttrsNS.hasOwnProperty(attrLocalName) && attrNsURI === allowedAttrsNS[attrLocalName] && attrNsURI !== NS.XMLNS) &&
- !(attrNsURI === NS.XMLNS && REVERSE_NS[attr.value])) {
- // TODO(codedread): Programmatically add the se: attributes to the NS-aware whitelist.
- // Bypassing the whitelist to allow se: prefixes.
- // Is there a more appropriate way to do this?
- if (attrName.indexOf('se:') === 0 || attrName.indexOf('data-') === 0) {
- seAttrs.push([attrName, attr.value]);
- }
- node.removeAttributeNS(attrNsURI, attrLocalName);
- }
+ var allowedAttrs = svgWhiteList_[node.nodeName];
+ var allowedAttrsNS = svgWhiteListNS_[node.nodeName];
+ var i;
+ // if this element is supported, sanitize it
+ if (typeof allowedAttrs !== 'undefined') {
+ var seAttrs = [];
+ i = node.attributes.length;
+ while (i--) {
+ // if the attribute is not in our whitelist, then remove it
+ // could use jQuery's inArray(), but I don't know if that's any better
+ var attr = node.attributes.item(i);
+ var attrName = attr.nodeName;
+ var attrLocalName = attr.localName;
+ var attrNsURI = attr.namespaceURI;
+ // Check that an attribute with the correct localName in the correct namespace is on
+ // our whitelist or is a namespace declaration for one of our allowed namespaces
+ if (!(allowedAttrsNS.hasOwnProperty(attrLocalName) && attrNsURI === allowedAttrsNS[attrLocalName] && attrNsURI !== NS.XMLNS) &&
+ !(attrNsURI === NS.XMLNS && REVERSE_NS[attr.value])) {
+ // TODO(codedread): Programmatically add the se: attributes to the NS-aware whitelist.
+ // Bypassing the whitelist to allow se: prefixes.
+ // Is there a more appropriate way to do this?
+ if (attrName.indexOf('se:') === 0 || attrName.indexOf('data-') === 0) {
+ seAttrs.push([attrName, attr.value]);
+ }
+ node.removeAttributeNS(attrNsURI, attrLocalName);
+ }
- // Add spaces before negative signs where necessary
- if (svgedit.browser.isGecko()) {
- switch (attrName) {
- case 'transform':
- case 'gradientTransform':
- case 'patternTransform':
- var val = attr.value.replace(/(\d)-/g, '$1 -');
- node.setAttribute(attrName, val);
- break;
- }
- }
+ // Add spaces before negative signs where necessary
+ if (svgedit.browser.isGecko()) {
+ switch (attrName) {
+ case 'transform':
+ case 'gradientTransform':
+ case 'patternTransform':
+ var val = attr.value.replace(/(\d)-/g, '$1 -');
+ node.setAttribute(attrName, val);
+ break;
+ }
+ }
- // For the style attribute, rewrite it in terms of XML presentational attributes
- if (attrName === 'style') {
- var props = attr.value.split(';'),
- p = props.length;
- while (p--) {
- var nv = props[p].split(':');
- var styleAttrName = $.trim(nv[0]);
- var styleAttrVal = $.trim(nv[1]);
- // Now check that this attribute is supported
- if (allowedAttrs.indexOf(styleAttrName) >= 0) {
- node.setAttribute(styleAttrName, styleAttrVal);
- }
- }
- node.removeAttribute('style');
- }
- }
+ // For the style attribute, rewrite it in terms of XML presentational attributes
+ if (attrName === 'style') {
+ var props = attr.value.split(';'),
+ p = props.length;
+ while (p--) {
+ var nv = props[p].split(':');
+ var styleAttrName = $.trim(nv[0]);
+ var styleAttrVal = $.trim(nv[1]);
+ // Now check that this attribute is supported
+ if (allowedAttrs.indexOf(styleAttrName) >= 0) {
+ node.setAttribute(styleAttrName, styleAttrVal);
+ }
+ }
+ node.removeAttribute('style');
+ }
+ }
- $.each(seAttrs, function (i, attr) {
- node.setAttributeNS(NS.SE, attr[0], attr[1]);
- });
+ $.each(seAttrs, function (i, attr) {
+ node.setAttributeNS(NS.SE, attr[0], attr[1]);
+ });
- // for some elements that have a xlink:href, ensure the URI refers to a local element
- // (but not for links)
- var href = svgedit.utilities.getHref(node);
- if (href &&
- ['filter', 'linearGradient', 'pattern',
- 'radialGradient', 'textPath', 'use'].indexOf(node.nodeName) >= 0) {
- // TODO: we simply check if the first character is a #, is this bullet-proof?
- if (href[0] !== '#') {
- // remove the attribute (but keep the element)
- svgedit.utilities.setHref(node, '');
- node.removeAttributeNS(NS.XLINK, 'href');
- }
- }
+ // for some elements that have a xlink:href, ensure the URI refers to a local element
+ // (but not for links)
+ var href = svgedit.utilities.getHref(node);
+ if (href &&
+ ['filter', 'linearGradient', 'pattern',
+ 'radialGradient', 'textPath', 'use'].indexOf(node.nodeName) >= 0) {
+ // TODO: we simply check if the first character is a #, is this bullet-proof?
+ if (href[0] !== '#') {
+ // remove the attribute (but keep the element)
+ svgedit.utilities.setHref(node, '');
+ node.removeAttributeNS(NS.XLINK, 'href');
+ }
+ }
- // Safari crashes on a without a xlink:href, so we just remove the node here
- if (node.nodeName === 'use' && !svgedit.utilities.getHref(node)) {
- parent.removeChild(node);
- return;
- }
- // if the element has attributes pointing to a non-local reference,
- // need to remove the attribute
- $.each(['clip-path', 'fill', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'stroke'], function (i, attr) {
- var val = node.getAttribute(attr);
- if (val) {
- val = svgedit.utilities.getUrlFromAttr(val);
- // simply check for first character being a '#'
- if (val && val[0] !== '#') {
- node.setAttribute(attr, '');
- node.removeAttribute(attr);
- }
- }
- });
+ // Safari crashes on a without a xlink:href, so we just remove the node here
+ if (node.nodeName === 'use' && !svgedit.utilities.getHref(node)) {
+ parent.removeChild(node);
+ return;
+ }
+ // if the element has attributes pointing to a non-local reference,
+ // need to remove the attribute
+ $.each(['clip-path', 'fill', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'stroke'], function (i, attr) {
+ var val = node.getAttribute(attr);
+ if (val) {
+ val = svgedit.utilities.getUrlFromAttr(val);
+ // simply check for first character being a '#'
+ if (val && val[0] !== '#') {
+ node.setAttribute(attr, '');
+ node.removeAttribute(attr);
+ }
+ }
+ });
- // recurse to children
- i = node.childNodes.length;
- while (i--) { svgedit.sanitize.sanitizeSvg(node.childNodes.item(i)); }
- // else (element not supported), remove it
- } else {
- // remove all children from this node and insert them before this node
- // FIXME: in the case of animation elements this will hardly ever be correct
- var children = [];
- while (node.hasChildNodes()) {
- children.push(parent.insertBefore(node.firstChild, node));
- }
+ // recurse to children
+ i = node.childNodes.length;
+ while (i--) { svgedit.sanitize.sanitizeSvg(node.childNodes.item(i)); }
+ // else (element not supported), remove it
+ } else {
+ // remove all children from this node and insert them before this node
+ // FIXME: in the case of animation elements this will hardly ever be correct
+ var children = [];
+ while (node.hasChildNodes()) {
+ children.push(parent.insertBefore(node.firstChild, node));
+ }
- // remove this node from the document altogether
- parent.removeChild(node);
+ // remove this node from the document altogether
+ parent.removeChild(node);
- // call sanitizeSvg on each of those children
- i = children.length;
- while (i--) { svgedit.sanitize.sanitizeSvg(children[i]); }
- }
+ // call sanitizeSvg on each of those children
+ i = children.length;
+ while (i--) { svgedit.sanitize.sanitizeSvg(children[i]); }
+ }
};
}());
diff --git a/editor/select.js b/editor/select.js
index 661bd863..43ed97e7 100644
--- a/editor/select.js
+++ b/editor/select.js
@@ -20,7 +20,7 @@
'use strict';
if (!svgedit.select) {
- svgedit.select = {};
+ svgedit.select = {};
}
var svgFactory_;
@@ -36,50 +36,50 @@ var gripRadius = svgedit.browser.isTouch() ? 10 : 4;
// elem - DOM element associated with this selector
// bbox - Optional bbox to use for initialization (prevents duplicate getBBox call).
svgedit.select.Selector = function (id, elem, bbox) {
- // this is the selector's unique number
- this.id = id;
+ // this is the selector's unique number
+ this.id = id;
- // this holds a reference to the element for which this selector is being used
- this.selectedElement = elem;
+ // this holds a reference to the element for which this selector is being used
+ this.selectedElement = elem;
- // this is a flag used internally to track whether the selector is being used or not
- this.locked = true;
+ // this is a flag used internally to track whether the selector is being used or not
+ this.locked = true;
- // this holds a reference to the element that holds all visual elements of the selector
- this.selectorGroup = svgFactory_.createSVGElement({
- 'element': 'g',
- 'attr': {'id': ('selectorGroup' + this.id)}
- });
+ // this holds a reference to the element that holds all visual elements of the selector
+ this.selectorGroup = svgFactory_.createSVGElement({
+ 'element': 'g',
+ 'attr': {'id': ('selectorGroup' + this.id)}
+ });
- // this holds a reference to the path rect
- this.selectorRect = this.selectorGroup.appendChild(
- svgFactory_.createSVGElement({
- 'element': 'path',
- 'attr': {
- 'id': ('selectedBox' + this.id),
- 'fill': 'none',
- 'stroke': '#22C',
- 'stroke-width': '1',
- 'stroke-dasharray': '5,5',
- // need to specify this so that the rect is not selectable
- 'style': 'pointer-events:none'
- }
- })
- );
+ // this holds a reference to the path rect
+ this.selectorRect = this.selectorGroup.appendChild(
+ svgFactory_.createSVGElement({
+ 'element': 'path',
+ 'attr': {
+ 'id': ('selectedBox' + this.id),
+ 'fill': 'none',
+ 'stroke': '#22C',
+ 'stroke-width': '1',
+ 'stroke-dasharray': '5,5',
+ // need to specify this so that the rect is not selectable
+ 'style': 'pointer-events:none'
+ }
+ })
+ );
- // this holds a reference to the grip coordinates for this selector
- this.gripCoords = {
- 'nw': null,
- 'n': null,
- 'ne': null,
- 'e': null,
- 'se': null,
- 's': null,
- 'sw': null,
- 'w': null
- };
+ // this holds a reference to the grip coordinates for this selector
+ this.gripCoords = {
+ 'nw': null,
+ 'n': null,
+ 'ne': null,
+ 'e': null,
+ 'se': null,
+ 's': null,
+ 'sw': null,
+ 'w': null
+ };
- this.reset(this.selectedElement, bbox);
+ this.reset(this.selectedElement, bbox);
};
// Function: svgedit.select.Selector.reset
@@ -89,10 +89,10 @@ svgedit.select.Selector = function (id, elem, bbox) {
// e - DOM element associated with this selector
// bbox - Optional bbox to use for reset (prevents duplicate getBBox call).
svgedit.select.Selector.prototype.reset = function (e, bbox) {
- this.locked = true;
- this.selectedElement = e;
- this.resize(bbox);
- this.selectorGroup.setAttribute('display', 'inline');
+ this.locked = true;
+ this.selectedElement = e;
+ this.resize(bbox);
+ this.selectorGroup.setAttribute('display', 'inline');
};
// Function: svgedit.select.Selector.updateGripCursors
@@ -101,22 +101,22 @@ svgedit.select.Selector.prototype.reset = function (e, bbox) {
// Parameters:
// angle - Float indicating current rotation angle in degrees
svgedit.select.Selector.prototype.updateGripCursors = function (angle) {
- var dir,
- dirArr = [],
- steps = Math.round(angle / 45);
- if (steps < 0) { steps += 8; }
- for (dir in selectorManager_.selectorGrips) {
- dirArr.push(dir);
- }
- while (steps > 0) {
- dirArr.push(dirArr.shift());
- steps--;
- }
- var i = 0;
- for (dir in selectorManager_.selectorGrips) {
- selectorManager_.selectorGrips[dir].setAttribute('style', ('cursor:' + dirArr[i] + '-resize'));
- i++;
- }
+ var dir,
+ dirArr = [],
+ steps = Math.round(angle / 45);
+ if (steps < 0) { steps += 8; }
+ for (dir in selectorManager_.selectorGrips) {
+ dirArr.push(dir);
+ }
+ while (steps > 0) {
+ dirArr.push(dirArr.shift());
+ steps--;
+ }
+ var i = 0;
+ for (dir in selectorManager_.selectorGrips) {
+ selectorManager_.selectorGrips[dir].setAttribute('style', ('cursor:' + dirArr[i] + '-resize'));
+ i++;
+ }
};
// Function: svgedit.select.Selector.showGrips
@@ -125,292 +125,292 @@ svgedit.select.Selector.prototype.updateGripCursors = function (angle) {
// Parameters:
// show - boolean indicating whether grips should be shown or not
svgedit.select.Selector.prototype.showGrips = function (show) {
- var bShow = show ? 'inline' : 'none';
- selectorManager_.selectorGripsGroup.setAttribute('display', bShow);
- var elem = this.selectedElement;
- this.hasGrips = show;
- if (elem && show) {
- this.selectorGroup.appendChild(selectorManager_.selectorGripsGroup);
- this.updateGripCursors(svgedit.utilities.getRotationAngle(elem));
- }
+ var bShow = show ? 'inline' : 'none';
+ selectorManager_.selectorGripsGroup.setAttribute('display', bShow);
+ var elem = this.selectedElement;
+ this.hasGrips = show;
+ if (elem && show) {
+ this.selectorGroup.appendChild(selectorManager_.selectorGripsGroup);
+ this.updateGripCursors(svgedit.utilities.getRotationAngle(elem));
+ }
};
// Function: svgedit.select.Selector.resize
// Updates the selector to match the element's size
// bbox - Optional bbox to use for resize (prevents duplicate getBBox call).
svgedit.select.Selector.prototype.resize = function (bbox) {
- var selectedBox = this.selectorRect,
- mgr = selectorManager_,
- selectedGrips = mgr.selectorGrips,
- selected = this.selectedElement,
- sw = selected.getAttribute('stroke-width'),
- currentZoom = svgFactory_.currentZoom();
- var offset = 1 / currentZoom;
- if (selected.getAttribute('stroke') !== 'none' && !isNaN(sw)) {
- offset += (sw / 2);
- }
+ var selectedBox = this.selectorRect,
+ mgr = selectorManager_,
+ selectedGrips = mgr.selectorGrips,
+ selected = this.selectedElement,
+ sw = selected.getAttribute('stroke-width'),
+ currentZoom = svgFactory_.currentZoom();
+ var offset = 1 / currentZoom;
+ if (selected.getAttribute('stroke') !== 'none' && !isNaN(sw)) {
+ offset += (sw / 2);
+ }
- var tagName = selected.tagName;
- if (tagName === 'text') {
- offset += 2 / currentZoom;
- }
+ var tagName = selected.tagName;
+ if (tagName === 'text') {
+ offset += 2 / currentZoom;
+ }
- // loop and transform our bounding box until we reach our first rotation
- var tlist = svgedit.transformlist.getTransformList(selected);
- var m = svgedit.math.transformListToTransform(tlist).matrix;
+ // loop and transform our bounding box until we reach our first rotation
+ var tlist = svgedit.transformlist.getTransformList(selected);
+ var m = svgedit.math.transformListToTransform(tlist).matrix;
- // This should probably be handled somewhere else, but for now
- // it keeps the selection box correctly positioned when zoomed
- m.e *= currentZoom;
- m.f *= currentZoom;
+ // This should probably be handled somewhere else, but for now
+ // it keeps the selection box correctly positioned when zoomed
+ m.e *= currentZoom;
+ m.f *= currentZoom;
- if (!bbox) {
- bbox = svgedit.utilities.getBBox(selected);
- }
- // TODO: svgedit.utilities.getBBox (previous line) already knows to call getStrokedBBox when tagName === 'g'. Remove this?
- // TODO: svgedit.utilities.getBBox doesn't exclude 'gsvg' and calls getStrokedBBox for any 'g'. Should getBBox be updated?
- if (tagName === 'g' && !$.data(selected, 'gsvg')) {
- // The bbox for a group does not include stroke vals, so we
- // get the bbox based on its children.
- var strokedBbox = svgFactory_.getStrokedBBox(selected.childNodes);
- if (strokedBbox) {
- bbox = strokedBbox;
- }
- }
+ if (!bbox) {
+ bbox = svgedit.utilities.getBBox(selected);
+ }
+ // TODO: svgedit.utilities.getBBox (previous line) already knows to call getStrokedBBox when tagName === 'g'. Remove this?
+ // TODO: svgedit.utilities.getBBox doesn't exclude 'gsvg' and calls getStrokedBBox for any 'g'. Should getBBox be updated?
+ if (tagName === 'g' && !$.data(selected, 'gsvg')) {
+ // The bbox for a group does not include stroke vals, so we
+ // get the bbox based on its children.
+ var strokedBbox = svgFactory_.getStrokedBBox(selected.childNodes);
+ if (strokedBbox) {
+ bbox = strokedBbox;
+ }
+ }
- // apply the transforms
- var l = bbox.x, t = bbox.y, w = bbox.width, h = bbox.height;
- bbox = {x: l, y: t, width: w, height: h};
+ // apply the transforms
+ var l = bbox.x, t = bbox.y, w = bbox.width, h = bbox.height;
+ bbox = {x: l, y: t, width: w, height: h};
- // we need to handle temporary transforms too
- // if skewed, get its transformed box, then find its axis-aligned bbox
+ // we need to handle temporary transforms too
+ // if skewed, get its transformed box, then find its axis-aligned bbox
- // *
- offset *= currentZoom;
+ // *
+ offset *= currentZoom;
- var nbox = svgedit.math.transformBox(l * currentZoom, t * currentZoom, w * currentZoom, h * currentZoom, m),
- aabox = nbox.aabox,
- nbax = aabox.x - offset,
- nbay = aabox.y - offset,
- nbaw = aabox.width + (offset * 2),
- nbah = aabox.height + (offset * 2);
+ var nbox = svgedit.math.transformBox(l * currentZoom, t * currentZoom, w * currentZoom, h * currentZoom, m),
+ aabox = nbox.aabox,
+ nbax = aabox.x - offset,
+ nbay = aabox.y - offset,
+ nbaw = aabox.width + (offset * 2),
+ nbah = aabox.height + (offset * 2);
- // now if the shape is rotated, un-rotate it
- var cx = nbax + nbaw / 2,
- cy = nbay + nbah / 2;
+ // now if the shape is rotated, un-rotate it
+ var cx = nbax + nbaw / 2,
+ cy = nbay + nbah / 2;
- var angle = svgedit.utilities.getRotationAngle(selected);
- if (angle) {
- var rot = svgFactory_.svgRoot().createSVGTransform();
- rot.setRotate(-angle, cx, cy);
- var rotm = rot.matrix;
- nbox.tl = svgedit.math.transformPoint(nbox.tl.x, nbox.tl.y, rotm);
- nbox.tr = svgedit.math.transformPoint(nbox.tr.x, nbox.tr.y, rotm);
- nbox.bl = svgedit.math.transformPoint(nbox.bl.x, nbox.bl.y, rotm);
- nbox.br = svgedit.math.transformPoint(nbox.br.x, nbox.br.y, rotm);
+ var angle = svgedit.utilities.getRotationAngle(selected);
+ if (angle) {
+ var rot = svgFactory_.svgRoot().createSVGTransform();
+ rot.setRotate(-angle, cx, cy);
+ var rotm = rot.matrix;
+ nbox.tl = svgedit.math.transformPoint(nbox.tl.x, nbox.tl.y, rotm);
+ nbox.tr = svgedit.math.transformPoint(nbox.tr.x, nbox.tr.y, rotm);
+ nbox.bl = svgedit.math.transformPoint(nbox.bl.x, nbox.bl.y, rotm);
+ nbox.br = svgedit.math.transformPoint(nbox.br.x, nbox.br.y, rotm);
- // calculate the axis-aligned bbox
- var tl = nbox.tl;
- var minx = tl.x,
- miny = tl.y,
- maxx = tl.x,
- maxy = tl.y;
+ // calculate the axis-aligned bbox
+ var tl = nbox.tl;
+ var minx = tl.x,
+ miny = tl.y,
+ maxx = tl.x,
+ maxy = tl.y;
- var min = Math.min, max = Math.max;
+ var min = Math.min, max = Math.max;
- minx = min(minx, min(nbox.tr.x, min(nbox.bl.x, nbox.br.x))) - offset;
- miny = min(miny, min(nbox.tr.y, min(nbox.bl.y, nbox.br.y))) - offset;
- maxx = max(maxx, max(nbox.tr.x, max(nbox.bl.x, nbox.br.x))) + offset;
- maxy = max(maxy, max(nbox.tr.y, max(nbox.bl.y, nbox.br.y))) + offset;
+ minx = min(minx, min(nbox.tr.x, min(nbox.bl.x, nbox.br.x))) - offset;
+ miny = min(miny, min(nbox.tr.y, min(nbox.bl.y, nbox.br.y))) - offset;
+ maxx = max(maxx, max(nbox.tr.x, max(nbox.bl.x, nbox.br.x))) + offset;
+ maxy = max(maxy, max(nbox.tr.y, max(nbox.bl.y, nbox.br.y))) + offset;
- nbax = minx;
- nbay = miny;
- nbaw = (maxx - minx);
- nbah = (maxy - miny);
- }
+ nbax = minx;
+ nbay = miny;
+ nbaw = (maxx - minx);
+ nbah = (maxy - miny);
+ }
- var dstr = 'M' + nbax + ',' + nbay +
- ' L' + (nbax + nbaw) + ',' + nbay +
- ' ' + (nbax + nbaw) + ',' + (nbay + nbah) +
- ' ' + nbax + ',' + (nbay + nbah) + 'z';
- selectedBox.setAttribute('d', dstr);
+ var dstr = 'M' + nbax + ',' + nbay +
+ ' L' + (nbax + nbaw) + ',' + nbay +
+ ' ' + (nbax + nbaw) + ',' + (nbay + nbah) +
+ ' ' + nbax + ',' + (nbay + nbah) + 'z';
+ selectedBox.setAttribute('d', dstr);
- var xform = angle ? 'rotate(' + [angle, cx, cy].join(',') + ')' : '';
- this.selectorGroup.setAttribute('transform', xform);
+ var xform = angle ? 'rotate(' + [angle, cx, cy].join(',') + ')' : '';
+ this.selectorGroup.setAttribute('transform', xform);
- // TODO(codedread): Is this if needed?
- // if (selected === selectedElements[0]) {
- this.gripCoords = {
- 'nw': [nbax, nbay],
- 'ne': [nbax + nbaw, nbay],
- 'sw': [nbax, nbay + nbah],
- 'se': [nbax + nbaw, nbay + nbah],
- 'n': [nbax + (nbaw) / 2, nbay],
- 'w': [nbax, nbay + (nbah) / 2],
- 'e': [nbax + nbaw, nbay + (nbah) / 2],
- 's': [nbax + (nbaw) / 2, nbay + nbah]
- };
- var dir;
- for (dir in this.gripCoords) {
- var coords = this.gripCoords[dir];
- selectedGrips[dir].setAttribute('cx', coords[0]);
- selectedGrips[dir].setAttribute('cy', coords[1]);
- }
+ // TODO(codedread): Is this if needed?
+ // if (selected === selectedElements[0]) {
+ this.gripCoords = {
+ 'nw': [nbax, nbay],
+ 'ne': [nbax + nbaw, nbay],
+ 'sw': [nbax, nbay + nbah],
+ 'se': [nbax + nbaw, nbay + nbah],
+ 'n': [nbax + (nbaw) / 2, nbay],
+ 'w': [nbax, nbay + (nbah) / 2],
+ 'e': [nbax + nbaw, nbay + (nbah) / 2],
+ 's': [nbax + (nbaw) / 2, nbay + nbah]
+ };
+ var dir;
+ for (dir in this.gripCoords) {
+ var coords = this.gripCoords[dir];
+ selectedGrips[dir].setAttribute('cx', coords[0]);
+ selectedGrips[dir].setAttribute('cy', coords[1]);
+ }
- // we want to go 20 pixels in the negative transformed y direction, ignoring scale
- mgr.rotateGripConnector.setAttribute('x1', nbax + (nbaw) / 2);
- mgr.rotateGripConnector.setAttribute('y1', nbay);
- mgr.rotateGripConnector.setAttribute('x2', nbax + (nbaw) / 2);
- mgr.rotateGripConnector.setAttribute('y2', nbay - (gripRadius * 5));
+ // we want to go 20 pixels in the negative transformed y direction, ignoring scale
+ mgr.rotateGripConnector.setAttribute('x1', nbax + (nbaw) / 2);
+ mgr.rotateGripConnector.setAttribute('y1', nbay);
+ mgr.rotateGripConnector.setAttribute('x2', nbax + (nbaw) / 2);
+ mgr.rotateGripConnector.setAttribute('y2', nbay - (gripRadius * 5));
- mgr.rotateGrip.setAttribute('cx', nbax + (nbaw) / 2);
- mgr.rotateGrip.setAttribute('cy', nbay - (gripRadius * 5));
- // }
+ mgr.rotateGrip.setAttribute('cx', nbax + (nbaw) / 2);
+ mgr.rotateGrip.setAttribute('cy', nbay - (gripRadius * 5));
+ // }
};
// Class: svgedit.select.SelectorManager
svgedit.select.SelectorManager = function () {
- // this will hold the element that contains all selector rects/grips
- this.selectorParentGroup = null;
+ // this will hold the element that contains all selector rects/grips
+ this.selectorParentGroup = null;
- // this is a special rect that is used for multi-select
- this.rubberBandBox = null;
+ // this is a special rect that is used for multi-select
+ this.rubberBandBox = null;
- // this will hold objects of type svgedit.select.Selector (see above)
- this.selectors = [];
+ // this will hold objects of type svgedit.select.Selector (see above)
+ this.selectors = [];
- // this holds a map of SVG elements to their Selector object
- this.selectorMap = {};
+ // this holds a map of SVG elements to their Selector object
+ this.selectorMap = {};
- // this holds a reference to the grip elements
- this.selectorGrips = {
- 'nw': null,
- 'n': null,
- 'ne': null,
- 'e': null,
- 'se': null,
- 's': null,
- 'sw': null,
- 'w': null
- };
+ // this holds a reference to the grip elements
+ this.selectorGrips = {
+ 'nw': null,
+ 'n': null,
+ 'ne': null,
+ 'e': null,
+ 'se': null,
+ 's': null,
+ 'sw': null,
+ 'w': null
+ };
- this.selectorGripsGroup = null;
- this.rotateGripConnector = null;
- this.rotateGrip = null;
+ this.selectorGripsGroup = null;
+ this.rotateGripConnector = null;
+ this.rotateGrip = null;
- this.initGroup();
+ this.initGroup();
};
// Function: svgedit.select.SelectorManager.initGroup
// Resets the parent selector group element
svgedit.select.SelectorManager.prototype.initGroup = function () {
- // remove old selector parent group if it existed
- if (this.selectorParentGroup && this.selectorParentGroup.parentNode) {
- this.selectorParentGroup.parentNode.removeChild(this.selectorParentGroup);
- }
+ // remove old selector parent group if it existed
+ if (this.selectorParentGroup && this.selectorParentGroup.parentNode) {
+ this.selectorParentGroup.parentNode.removeChild(this.selectorParentGroup);
+ }
- // create parent selector group and add it to svgroot
- this.selectorParentGroup = svgFactory_.createSVGElement({
- 'element': 'g',
- 'attr': {'id': 'selectorParentGroup'}
- });
- this.selectorGripsGroup = svgFactory_.createSVGElement({
- 'element': 'g',
- 'attr': {'display': 'none'}
- });
- this.selectorParentGroup.appendChild(this.selectorGripsGroup);
- svgFactory_.svgRoot().appendChild(this.selectorParentGroup);
+ // create parent selector group and add it to svgroot
+ this.selectorParentGroup = svgFactory_.createSVGElement({
+ 'element': 'g',
+ 'attr': {'id': 'selectorParentGroup'}
+ });
+ this.selectorGripsGroup = svgFactory_.createSVGElement({
+ 'element': 'g',
+ 'attr': {'display': 'none'}
+ });
+ this.selectorParentGroup.appendChild(this.selectorGripsGroup);
+ svgFactory_.svgRoot().appendChild(this.selectorParentGroup);
- this.selectorMap = {};
- this.selectors = [];
- this.rubberBandBox = null;
+ this.selectorMap = {};
+ this.selectors = [];
+ this.rubberBandBox = null;
- // add the corner grips
- var dir;
- for (dir in this.selectorGrips) {
- var grip = svgFactory_.createSVGElement({
- 'element': 'circle',
- 'attr': {
- 'id': ('selectorGrip_resize_' + dir),
- 'fill': '#22C',
- 'r': gripRadius,
- 'style': ('cursor:' + dir + '-resize'),
- // This expands the mouse-able area of the grips making them
- // easier to grab with the mouse.
- // This works in Opera and WebKit, but does not work in Firefox
- // see https://bugzilla.mozilla.org/show_bug.cgi?id=500174
- 'stroke-width': 2,
- 'pointer-events': 'all'
- }
- });
+ // add the corner grips
+ var dir;
+ for (dir in this.selectorGrips) {
+ var grip = svgFactory_.createSVGElement({
+ 'element': 'circle',
+ 'attr': {
+ 'id': ('selectorGrip_resize_' + dir),
+ 'fill': '#22C',
+ 'r': gripRadius,
+ 'style': ('cursor:' + dir + '-resize'),
+ // This expands the mouse-able area of the grips making them
+ // easier to grab with the mouse.
+ // This works in Opera and WebKit, but does not work in Firefox
+ // see https://bugzilla.mozilla.org/show_bug.cgi?id=500174
+ 'stroke-width': 2,
+ 'pointer-events': 'all'
+ }
+ });
- $.data(grip, 'dir', dir);
- $.data(grip, 'type', 'resize');
- this.selectorGrips[dir] = this.selectorGripsGroup.appendChild(grip);
- }
+ $.data(grip, 'dir', dir);
+ $.data(grip, 'type', 'resize');
+ this.selectorGrips[dir] = this.selectorGripsGroup.appendChild(grip);
+ }
- // add rotator elems
- this.rotateGripConnector = this.selectorGripsGroup.appendChild(
- svgFactory_.createSVGElement({
- 'element': 'line',
- 'attr': {
- 'id': ('selectorGrip_rotateconnector'),
- 'stroke': '#22C',
- 'stroke-width': '1'
- }
- })
- );
+ // add rotator elems
+ this.rotateGripConnector = this.selectorGripsGroup.appendChild(
+ svgFactory_.createSVGElement({
+ 'element': 'line',
+ 'attr': {
+ 'id': ('selectorGrip_rotateconnector'),
+ 'stroke': '#22C',
+ 'stroke-width': '1'
+ }
+ })
+ );
- this.rotateGrip = this.selectorGripsGroup.appendChild(
- svgFactory_.createSVGElement({
- 'element': 'circle',
- 'attr': {
- 'id': 'selectorGrip_rotate',
- 'fill': 'lime',
- 'r': gripRadius,
- 'stroke': '#22C',
- 'stroke-width': 2,
- 'style': 'cursor:url(' + config_.imgPath + 'rotate.png) 12 12, auto;'
- }
- })
- );
- $.data(this.rotateGrip, 'type', 'rotate');
+ this.rotateGrip = this.selectorGripsGroup.appendChild(
+ svgFactory_.createSVGElement({
+ 'element': 'circle',
+ 'attr': {
+ 'id': 'selectorGrip_rotate',
+ 'fill': 'lime',
+ 'r': gripRadius,
+ 'stroke': '#22C',
+ 'stroke-width': 2,
+ 'style': 'cursor:url(' + config_.imgPath + 'rotate.png) 12 12, auto;'
+ }
+ })
+ );
+ $.data(this.rotateGrip, 'type', 'rotate');
- if ($('#canvasBackground').length) { return; }
+ if ($('#canvasBackground').length) { return; }
- var dims = config_.dimensions;
- var canvasbg = svgFactory_.createSVGElement({
- 'element': 'svg',
- 'attr': {
- 'id': 'canvasBackground',
- 'width': dims[0],
- 'height': dims[1],
- 'x': 0,
- 'y': 0,
- 'overflow': (svgedit.browser.isWebkit() ? 'none' : 'visible'), // Chrome 7 has a problem with this when zooming out
- 'style': 'pointer-events:none'
- }
- });
+ var dims = config_.dimensions;
+ var canvasbg = svgFactory_.createSVGElement({
+ 'element': 'svg',
+ 'attr': {
+ 'id': 'canvasBackground',
+ 'width': dims[0],
+ 'height': dims[1],
+ 'x': 0,
+ 'y': 0,
+ 'overflow': (svgedit.browser.isWebkit() ? 'none' : 'visible'), // Chrome 7 has a problem with this when zooming out
+ 'style': 'pointer-events:none'
+ }
+ });
- var rect = svgFactory_.createSVGElement({
- 'element': 'rect',
- 'attr': {
- 'width': '100%',
- 'height': '100%',
- 'x': 0,
- 'y': 0,
- 'stroke-width': 1,
- 'stroke': '#000',
- 'fill': '#FFF',
- 'style': 'pointer-events:none'
- }
- });
+ var rect = svgFactory_.createSVGElement({
+ 'element': 'rect',
+ 'attr': {
+ 'width': '100%',
+ 'height': '100%',
+ 'x': 0,
+ 'y': 0,
+ 'stroke-width': 1,
+ 'stroke': '#000',
+ 'fill': '#FFF',
+ 'style': 'pointer-events:none'
+ }
+ });
- // Both Firefox and WebKit are too slow with this filter region (especially at higher
- // zoom levels) and Opera has at least one bug
- // if (!svgedit.browser.isOpera()) rect.setAttribute('filter', 'url(#canvashadow)');
- canvasbg.appendChild(rect);
- svgFactory_.svgRoot().insertBefore(canvasbg, svgFactory_.svgContent());
+ // Both Firefox and WebKit are too slow with this filter region (especially at higher
+ // zoom levels) and Opera has at least one bug
+ // if (!svgedit.browser.isOpera()) rect.setAttribute('filter', 'url(#canvashadow)');
+ canvasbg.appendChild(rect);
+ svgFactory_.svgRoot().insertBefore(canvasbg, svgFactory_.svgContent());
};
// Function: svgedit.select.SelectorManager.requestSelector
@@ -420,27 +420,27 @@ svgedit.select.SelectorManager.prototype.initGroup = function () {
// elem - DOM element to get the selector for
// bbox - Optional bbox to use for reset (prevents duplicate getBBox call).
svgedit.select.SelectorManager.prototype.requestSelector = function (elem, bbox) {
- if (elem == null) { return null; }
- var i,
- N = this.selectors.length;
- // If we've already acquired one for this element, return it.
- if (typeof this.selectorMap[elem.id] === 'object') {
- this.selectorMap[elem.id].locked = true;
- return this.selectorMap[elem.id];
- }
- for (i = 0; i < N; ++i) {
- if (this.selectors[i] && !this.selectors[i].locked) {
- this.selectors[i].locked = true;
- this.selectors[i].reset(elem, bbox);
- this.selectorMap[elem.id] = this.selectors[i];
- return this.selectors[i];
- }
- }
- // if we reached here, no available selectors were found, we create one
- this.selectors[N] = new svgedit.select.Selector(N, elem, bbox);
- this.selectorParentGroup.appendChild(this.selectors[N].selectorGroup);
- this.selectorMap[elem.id] = this.selectors[N];
- return this.selectors[N];
+ if (elem == null) { return null; }
+ var i,
+ N = this.selectors.length;
+ // If we've already acquired one for this element, return it.
+ if (typeof this.selectorMap[elem.id] === 'object') {
+ this.selectorMap[elem.id].locked = true;
+ return this.selectorMap[elem.id];
+ }
+ for (i = 0; i < N; ++i) {
+ if (this.selectors[i] && !this.selectors[i].locked) {
+ this.selectors[i].locked = true;
+ this.selectors[i].reset(elem, bbox);
+ this.selectorMap[elem.id] = this.selectors[i];
+ return this.selectors[i];
+ }
+ }
+ // if we reached here, no available selectors were found, we create one
+ this.selectors[N] = new svgedit.select.Selector(N, elem, bbox);
+ this.selectorParentGroup.appendChild(this.selectors[N].selectorGroup);
+ this.selectorMap[elem.id] = this.selectors[N];
+ return this.selectors[N];
};
// Function: svgedit.select.SelectorManager.releaseSelector
@@ -449,51 +449,51 @@ svgedit.select.SelectorManager.prototype.requestSelector = function (elem, bbox)
// Parameters:
// elem - DOM element to remove the selector for
svgedit.select.SelectorManager.prototype.releaseSelector = function (elem) {
- if (elem == null) { return; }
- var i,
- N = this.selectors.length,
- sel = this.selectorMap[elem.id];
- if (!sel.locked) {
- // TODO(codedread): Ensure this exists in this module.
- console.log('WARNING! selector was released but was already unlocked');
- }
- for (i = 0; i < N; ++i) {
- if (this.selectors[i] && this.selectors[i] === sel) {
- delete this.selectorMap[elem.id];
- sel.locked = false;
- sel.selectedElement = null;
- sel.showGrips(false);
+ if (elem == null) { return; }
+ var i,
+ N = this.selectors.length,
+ sel = this.selectorMap[elem.id];
+ if (!sel.locked) {
+ // TODO(codedread): Ensure this exists in this module.
+ console.log('WARNING! selector was released but was already unlocked');
+ }
+ for (i = 0; i < N; ++i) {
+ if (this.selectors[i] && this.selectors[i] === sel) {
+ delete this.selectorMap[elem.id];
+ sel.locked = false;
+ sel.selectedElement = null;
+ sel.showGrips(false);
- // remove from DOM and store reference in JS but only if it exists in the DOM
- try {
- sel.selectorGroup.setAttribute('display', 'none');
- } catch (e) {}
+ // remove from DOM and store reference in JS but only if it exists in the DOM
+ try {
+ sel.selectorGroup.setAttribute('display', 'none');
+ } catch (e) {}
- break;
- }
- }
+ break;
+ }
+ }
};
// Function: svgedit.select.SelectorManager.getRubberBandBox
// Returns the rubberBandBox DOM element. This is the rectangle drawn by the user for selecting/zooming
svgedit.select.SelectorManager.prototype.getRubberBandBox = function () {
- if (!this.rubberBandBox) {
- this.rubberBandBox = this.selectorParentGroup.appendChild(
- svgFactory_.createSVGElement({
- 'element': 'rect',
- 'attr': {
- 'id': 'selectorRubberBand',
- 'fill': '#22C',
- 'fill-opacity': 0.15,
- 'stroke': '#22C',
- 'stroke-width': 0.5,
- 'display': 'none',
- 'style': 'pointer-events:none'
- }
- })
- );
- }
- return this.rubberBandBox;
+ if (!this.rubberBandBox) {
+ this.rubberBandBox = this.selectorParentGroup.appendChild(
+ svgFactory_.createSVGElement({
+ 'element': 'rect',
+ 'attr': {
+ 'id': 'selectorRubberBand',
+ 'fill': '#22C',
+ 'fill-opacity': 0.15,
+ 'stroke': '#22C',
+ 'stroke-width': 0.5,
+ 'display': 'none',
+ 'style': 'pointer-events:none'
+ }
+ })
+ );
+ }
+ return this.rubberBandBox;
};
/**
@@ -519,9 +519,9 @@ svgedit.select.SelectorManager.prototype.getRubberBandBox = function () {
* svgFactory - an object implementing the SVGFactory interface (see above).
*/
svgedit.select.init = function (config, svgFactory) {
- config_ = config;
- svgFactory_ = svgFactory;
- selectorManager_ = new svgedit.select.SelectorManager();
+ config_ = config;
+ svgFactory_ = svgFactory;
+ selectorManager_ = new svgedit.select.SelectorManager();
};
/**
@@ -531,6 +531,6 @@ svgedit.select.init = function (config, svgFactory) {
* The SelectorManager instance.
*/
svgedit.select.getSelectorManager = function () {
- return selectorManager_;
+ return selectorManager_;
};
}());
diff --git a/editor/svg-editor.css b/editor/svg-editor.css
index 2b744a8f..47622325 100644
--- a/editor/svg-editor.css
+++ b/editor/svg-editor.css
@@ -1,450 +1,450 @@
body {
- background: #D0D0D0;
+ background: #D0D0D0;
}
html, body, div{
- -webkit-user-select: text;
- -khtml-user-select: text;
- -moz-user-select: text;
- -o-user-select: text;
- user-select: text;
- /* this will work for QtWebKit in future */
- -webkit-user-drag: text;
+ -webkit-user-select: text;
+ -khtml-user-select: text;
+ -moz-user-select: text;
+ -o-user-select: text;
+ user-select: text;
+ /* this will work for QtWebKit in future */
+ -webkit-user-drag: text;
}
#svg_editor * {
- transform-origin: 0 0;
- -moz-transform-origin: 0 0;
- -o-transform-origin: 0 0;
- -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -moz-transform-origin: 0 0;
+ -o-transform-origin: 0 0;
+ -webkit-transform-origin: 0 0;
}
#svg_editor {
- font-size: 8pt;
- font-family: Verdana, Helvetica, Arial;
- color: #000000;
+ font-size: 8pt;
+ font-family: Verdana, Helvetica, Arial;
+ color: #000000;
}
a {
- color: #19c;
+ color: #19c;
}
hr {
- border: none;
- border-bottom: 1px solid #808080;
+ border: none;
+ border-bottom: 1px solid #808080;
}
select {
- margin-top: 4px;
+ margin-top: 4px;
}
#svgroot {
- -moz-user-select: none;
- -webkit-user-select: none;
- position: absolute;
- top: 0;
- left: 0;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ position: absolute;
+ top: 0;
+ left: 0;
}
#svgcanvas {
- line-height: normal;
- display: inline-block;
- background-color: #A0A0A0;
- text-align: center;
- vertical-align: middle;
- width: 640px;
- height: 480px;
- -apple-dashboard-region:dashboard-region(control rectangle 0px 0px 0px 0px); /* for widget regions that shouldn't react to dragging */
- position: relative;
- /*
- A subtle gradient effect in the canvas.
- Just experimenting - not sure if this is worth it.
- */
- background: -moz-radial-gradient(45deg,#bbb,#222);
- background: -webkit-gradient(radial, center center, 3, center center, 1000, from(#bbb), to(#222));
+ line-height: normal;
+ display: inline-block;
+ background-color: #A0A0A0;
+ text-align: center;
+ vertical-align: middle;
+ width: 640px;
+ height: 480px;
+ -apple-dashboard-region:dashboard-region(control rectangle 0px 0px 0px 0px); /* for widget regions that shouldn't react to dragging */
+ position: relative;
+ /*
+ A subtle gradient effect in the canvas.
+ Just experimenting - not sure if this is worth it.
+ */
+ background: -moz-radial-gradient(45deg,#bbb,#222);
+ background: -webkit-gradient(radial, center center, 3, center center, 1000, from(#bbb), to(#222));
}
/* Rulers
——————————————————————————————————————*/
#rulers > div {
- position: absolute;
- background: #DDD;
- z-index: 1;
- overflow: hidden;
+ position: absolute;
+ background: #DDD;
+ z-index: 1;
+ overflow: hidden;
}
#ruler_corner {
- top: 41px;
- left: 41px;
- width: 15px;
- height: 15px;
+ top: 41px;
+ left: 41px;
+ width: 15px;
+ height: 15px;
}
#ruler_x {
- height: 15px;
- top: 41px;
- left: 56px;
- right: 30px;
- border-bottom: 1px solid;
- border-left: 1px solid #777;
+ height: 15px;
+ top: 41px;
+ left: 56px;
+ right: 30px;
+ border-bottom: 1px solid;
+ border-left: 1px solid #777;
}
#ruler_y {
- width: 15px;
- top: 55px;
- left: 41px;
- bottom: 56px;
- border-right: 1px solid;
- border-top: 1px solid #777;
+ width: 15px;
+ top: 55px;
+ left: 41px;
+ bottom: 56px;
+ border-right: 1px solid;
+ border-top: 1px solid #777;
}
#ruler_x canvas:first-child {
- margin-left: -16px;
+ margin-left: -16px;
}
#ruler_x canvas {
- float: left;
+ float: left;
}
#ruler_y canvas {
- margin-top: -16px;
+ margin-top: -16px;
}
#ruler_x > div,
#ruler_y > div {
- overflow: hidden;
+ overflow: hidden;
}
#palette_holder {
- overflow: hidden;
- margin-top: 5px;
- padding: 5px;
- position: absolute;
- right: 15px;
- height: 16px;
- background: #f0f0f0;
- border-radius: 3px;
- z-index: 2;
+ overflow: hidden;
+ margin-top: 5px;
+ padding: 5px;
+ position: absolute;
+ right: 15px;
+ height: 16px;
+ background: #f0f0f0;
+ border-radius: 3px;
+ z-index: 2;
}
#stroke_bg,
#fill_bg {
- height: 16px;
- width: 16px;
- margin: 1px;
+ height: 16px;
+ width: 16px;
+ margin: 1px;
}
#zoomLabel {
- cursor: pointer;
- margin-right: 5px;
- padding-top: 4px
+ cursor: pointer;
+ margin-right: 5px;
+ padding-top: 4px
}
#linkLabel > svg {
- height: 20px;
- padding-top: 4px;
+ height: 20px;
+ padding-top: 4px;
}
#palette {
- float: left;
- width: 632px;
- height: 16px;
+ float: left;
+ width: 632px;
+ height: 16px;
}
#workarea {
- display: inline-table-cell;
- position:absolute;
- top: 40px;
- left: 40px;
- bottom: 40px;
- right: 14px;
- background-color: #A0A0A0;
- border: 1px solid #808080;
- overflow: auto;
- text-align: center;
+ display: inline-table-cell;
+ position:absolute;
+ top: 40px;
+ left: 40px;
+ bottom: 40px;
+ right: 14px;
+ background-color: #A0A0A0;
+ border: 1px solid #808080;
+ overflow: auto;
+ text-align: center;
}
#sidepanels {
- display: inline-block;
- position:absolute;
- top: 40px;
- bottom: 40px;
- right: 0;
- width: 2px;
- padding: 10px;
- border-color: #808080;
- border-style: solid;
- border-width: 1px;
- border-left: none;
- overflow-x:hidden;
- overflow-y:visible;
+ display: inline-block;
+ position:absolute;
+ top: 40px;
+ bottom: 40px;
+ right: 0;
+ width: 2px;
+ padding: 10px;
+ border-color: #808080;
+ border-style: solid;
+ border-width: 1px;
+ border-left: none;
+ overflow-x:hidden;
+ overflow-y:visible;
}
#layerpanel {
- display: inline-block;
- position:relative;
- top: 0px;
- bottom: 0;
- left: 12px;
- width: 0;
- overflow: hidden;
- margin: 0;
- -moz-user-select: none;
- -webkit-user-select: none;
+ display: inline-block;
+ position:relative;
+ top: 0px;
+ bottom: 0;
+ left: 12px;
+ width: 0;
+ overflow: hidden;
+ margin: 0;
+ -moz-user-select: none;
+ -webkit-user-select: none;
}
/*
- border-style: solid;
- border-color: #666;
- border-width: 0px 0px 0px 1px;
+ border-style: solid;
+ border-color: #666;
+ border-width: 0px 0px 0px 1px;
*/
#sidepanel_handle {
- display: inline-block;
- position: absolute;
- background-color: #D0D0D0;
- font-weight: bold;
- left: 0;
- top: 40%;
- width: 1em;
- padding: 5px 1px 5px 5px;
- margin-left: 3px;
- cursor: pointer;
- border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-user-select: none;
- -webkit-user-select: none;
+ display: inline-block;
+ position: absolute;
+ background-color: #D0D0D0;
+ font-weight: bold;
+ left: 0;
+ top: 40%;
+ width: 1em;
+ padding: 5px 1px 5px 5px;
+ margin-left: 3px;
+ cursor: pointer;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-user-select: none;
+ -webkit-user-select: none;
}
#sidepanel_handle:hover {
- font-weight: bold;
+ font-weight: bold;
}
#sidepanel_handle * {
- cursor: pointer;
- -moz-user-select: none;
- -webkit-user-select: none;
+ cursor: pointer;
+ -moz-user-select: none;
+ -webkit-user-select: none;
}
#layerbuttons {
- margin: 0;
- padding: 0;
- padding-left: 2px;
- padding-right: 2px;
- width: 125px;
- height: 20px;
- border-right: 1px solid #FFFFFF;
- border-bottom: 1px solid #FFFFFF;
- border-left: 1px solid #808080;
- border-top: 1px solid #808080;
- overflow: hidden;
+ margin: 0;
+ padding: 0;
+ padding-left: 2px;
+ padding-right: 2px;
+ width: 125px;
+ height: 20px;
+ border-right: 1px solid #FFFFFF;
+ border-bottom: 1px solid #FFFFFF;
+ border-left: 1px solid #808080;
+ border-top: 1px solid #808080;
+ overflow: hidden;
}
.layer_button {
- width: 14px;
- height: 14px;
- padding: 1px;
- border-left: 1px solid #FFFFFF;
- border-top: 1px solid #FFFFFF;
- border-right: 1px solid #808080;
- border-bottom: 1px solid #808080;
- cursor: pointer;
- float: left;
- margin-right: 3px;
+ width: 14px;
+ height: 14px;
+ padding: 1px;
+ border-left: 1px solid #FFFFFF;
+ border-top: 1px solid #FFFFFF;
+ border-right: 1px solid #808080;
+ border-bottom: 1px solid #808080;
+ cursor: pointer;
+ float: left;
+ margin-right: 3px;
}
.layer_button:last-child {
- margin-right: 0;
+ margin-right: 0;
}
.layer_buttonpressed {
- width: 14px;
- height: 14px;
- padding: 1px;
- border-right: 1px solid #FFFFFF;
- border-bottom: 1px solid #FFFFFF;
- border-left: 1px solid #808080;
- border-top: 1px solid #808080;
- cursor: pointer;
+ width: 14px;
+ height: 14px;
+ padding: 1px;
+ border-right: 1px solid #FFFFFF;
+ border-bottom: 1px solid #FFFFFF;
+ border-left: 1px solid #808080;
+ border-top: 1px solid #808080;
+ cursor: pointer;
}
#layerlist {
- margin: 1px;
- padding: 0;
- width: 127px;
- border-collapse: collapse;
- border: 1px solid #808080;
- background-color: #FFFFFF;
+ margin: 1px;
+ padding: 0;
+ width: 127px;
+ border-collapse: collapse;
+ border: 1px solid #808080;
+ background-color: #FFFFFF;
}
#layerlist tr.layer {
- background-color: #FFFFFF;
- margin: 0;
- padding: 0;
+ background-color: #FFFFFF;
+ margin: 0;
+ padding: 0;
}
#layerlist tr.layersel {
- border: 1px solid #808080;
- background-color: #CCCCCC;
+ border: 1px solid #808080;
+ background-color: #CCCCCC;
}
#layerlist td.layervis {
- width: 22px;
- cursor: pointer;
+ width: 22px;
+ cursor: pointer;
}
#layerlist td.layerinvis {
- background-image: none;
- cursor: pointer;
+ background-image: none;
+ cursor: pointer;
}
#layerlist td.layervis * {
- display: block;
+ display: block;
}
#layerlist td.layerinvis * {
- display: none;
+ display: none;
}
#layerlist td.layername {
- cursor: pointer;
+ cursor: pointer;
}
#layerlist td.layername:hover {
- color: blue;
- font-style: italic;
+ color: blue;
+ font-style: italic;
}
#layerlist tr.layersel td.layername {
- font-weight: bold;
+ font-weight: bold;
}
#selLayerLabel {
- white-space: nowrap;
+ white-space: nowrap;
}
#selLayerNames {
- display: block;
+ display: block;
}
div.palette_item {
- height: 15px;
- width: 15px;
- float: left;
+ height: 15px;
+ width: 15px;
+ float: left;
}
div.palette_item:first-child {
- background: white;
+ background: white;
}
/* Main button
—————————————————————————————*/
#main_button {
- position: absolute;
- top: 4px;
- left: 5px;
- z-index: 5;
+ position: absolute;
+ top: 4px;
+ left: 5px;
+ z-index: 5;
}
#main_icon {
- position: relative;
- top: -2px;
- left: -2px;
- width: 95px;
- line-height: 26px;
+ position: relative;
+ top: -2px;
+ left: -2px;
+ width: 95px;
+ line-height: 26px;
}
#main_icon:hover {
- background: #eee !important;
+ background: #eee !important;
}
#main_icon.buttondown {
- background: #eee !important;
- -moz-box-shadow: none !important;
- -webkit-box-shadow: none !important;
- box-shadow: none !important;
- border-radius: 3px 3px 0 0;
+ background: #eee !important;
+ -moz-box-shadow: none !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ border-radius: 3px 3px 0 0;
}
#logo {
- margin-top: -2px;
+ margin-top: -2px;
}
#logo img {
- border: 0;
- width: 28px;
- height: 28px;
+ border: 0;
+ width: 28px;
+ height: 28px;
}
#main_icon > div {
- float: left;
+ float: left;
}
#main_button .dropdown {
- position: absolute;
- right: 7px;
- top: 4px;
+ position: absolute;
+ right: 7px;
+ top: 4px;
}
#main_icon span {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- display: block;
- z-index: 2;
- font-weight: bold;
- padding-left: 34px;
- line-height: 32px;
- font-family: sans-serif;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ display: block;
+ z-index: 2;
+ font-weight: bold;
+ padding-left: 34px;
+ line-height: 32px;
+ font-family: sans-serif;
}
#main_menu {
- z-index: 12;
- background: #eee;
- position: relative;
- width: 230px;
- padding: 5px;
- -moz-box-shadow: #555 1px 1px 4px;
- -webkit-box-shadow: #555 1px 1px 4px;
- box-shadow: #555 1px 1px 4px;
- font-size: 1.1em;
- display: none;
- overflow: hidden;
- clear: both;
- top: -9px;
+ z-index: 12;
+ background: #eee;
+ position: relative;
+ width: 230px;
+ padding: 5px;
+ -moz-box-shadow: #555 1px 1px 4px;
+ -webkit-box-shadow: #555 1px 1px 4px;
+ box-shadow: #555 1px 1px 4px;
+ font-size: 1.1em;
+ display: none;
+ overflow: hidden;
+ clear: both;
+ top: -9px;
}
#main_menu ul,
#main_menu li {
- list-style: none;
- margin: 0;
- padding: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0;
}
#main_menu li {
/* height: 35px;*/
- line-height: 22px;
- padding-top: 7px;
- padding-left: 7px;
- margin: -5px;
- overflow: auto;
- cursor: default;
+ line-height: 22px;
+ padding-top: 7px;
+ padding-left: 7px;
+ margin: -5px;
+ overflow: auto;
+ cursor: default;
}
#main_menu li:hover {
- background: #FFC;
+ background: #FFC;
}
#main_menu li > div {
- float: left;
- padding-right: 5px;
+ float: left;
+ padding-right: 5px;
}
#main_menu p {
- margin-top: 5px;
+ margin-top: 5px;
}
/*—————————————————————————————*/
@@ -456,232 +456,232 @@ div.palette_item:first-child {
.tool_button_current,
.push_button_pressed
{
- background-color: #ffc !important;
+ background-color: #ffc !important;
}
.tool_button_current,
.push_button_pressed,
.buttondown {
- background-color: #f4e284 !important;
- -webkit-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
- -moz-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
- box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
+ background-color: #f4e284 !important;
+ -webkit-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
+ -moz-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
+ box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
}
#tools_top {
- position: absolute;
- left: 108px;
- right: 2px;
- top: 2px;
- height: 40px;
- border-bottom: none;
- overflow: auto;
+ position: absolute;
+ left: 108px;
+ right: 2px;
+ top: 2px;
+ height: 40px;
+ border-bottom: none;
+ overflow: auto;
}
#tools_top .tool_sep {
- margin-top: 5px;
+ margin-top: 5px;
}
#tools_left {
- position: absolute;
- border-right: none;
- width: 32px;
- top: 40px;
- left: 1px;
- margin-top: -2px;
- padding-left: 2px;
- background: #D0D0D0; /* Needed so flyout icons don't appear on the left */
- z-index: 4;
+ position: absolute;
+ border-right: none;
+ width: 32px;
+ top: 40px;
+ left: 1px;
+ margin-top: -2px;
+ padding-left: 2px;
+ background: #D0D0D0; /* Needed so flyout icons don't appear on the left */
+ z-index: 4;
}
#workarea.wireframe #svgcontent * {
- fill: none;
- stroke: #000;
- stroke-width: 1px;
- stroke-opacity: 1.0;
- stroke-dasharray: 0;
- opacity: 1;
- pointer-events: stroke;
- vector-effect: non-scaling-stroke;
- filter: none;
+ fill: none;
+ stroke: #000;
+ stroke-width: 1px;
+ stroke-opacity: 1.0;
+ stroke-dasharray: 0;
+ opacity: 1;
+ pointer-events: stroke;
+ vector-effect: non-scaling-stroke;
+ filter: none;
}
#workarea.wireframe #svgcontent text {
- fill: #000;
- stroke: none;
+ fill: #000;
+ stroke: none;
}
#workarea.wireframe #canvasBackground > rect {
- fill: #FFF !important;
+ fill: #FFF !important;
}
#tools_top div[id$="_panel"]:not(#editor_panel):not(#history_panel) {
- display: none;
+ display: none;
}
#editor_panel, #history_panel {
- height: 34px;
- float: left;
+ height: 34px;
+ float: left;
}
#multiselected_panel .selected_tool {
- vertical-align: 12px;
+ vertical-align: 12px;
}
/*TODO: Adjust position of rulers are not visible*/
#cur_context_panel {
- position: absolute;
- top: 57px;
- left: 56px;
- line-height: 22px;
- overflow: auto;
- padding-left: 5px;
- font-size: 12px;
- background: rgba(0, 0, 0, 0.8);
- color: #ccc;
- padding: 0 10px;
- border-radius: 0 0 3px 0;
+ position: absolute;
+ top: 57px;
+ left: 56px;
+ line-height: 22px;
+ overflow: auto;
+ padding-left: 5px;
+ font-size: 12px;
+ background: rgba(0, 0, 0, 0.8);
+ color: #ccc;
+ padding: 0 10px;
+ border-radius: 0 0 3px 0;
}
#cur_context_panel a {
- float: none;
- text-decoration: none;
+ float: none;
+ text-decoration: none;
}
#cur_context_panel a:hover {
- text-decoration: underline;
+ text-decoration: underline;
}
#tools_top > div, #tools_top {
- line-height: 26px;
+ line-height: 26px;
}
div.toolset,
div.toolset > * {
- float: left;
+ float: left;
}
div.toolset {
- height: 34px;
+ height: 34px;
}
div.toolset label span {
/* outline: 1px solid red;*/
- padding-top: 3px;
- display: inline-block;
+ padding-top: 3px;
+ display: inline-block;
}
#tools_top > div > * {
- float: left;
- margin-right: 2px;
+ float: left;
+ margin-right: 2px;
}
#tools_top label {
- margin-top: 0;
- margin-left: 5px;
+ margin-top: 0;
+ margin-left: 5px;
}
#tools_top input {
- margin-top: 5px;
- height: 15px;
+ margin-top: 5px;
+ height: 15px;
}
input[type=text] {
- padding: 2px;
+ padding: 2px;
}
#tools_left .tool_button,
#tools_left .tool_button_current {
- position: relative;
- z-index: 11;
+ position: relative;
+ z-index: 11;
}
.flyout_arrow_horiz {
- position: absolute;
- bottom: -1px;
- right: 0;
- z-index: 10;
+ position: absolute;
+ bottom: -1px;
+ right: 0;
+ z-index: 10;
}
span.zoom_tool {
- line-height: 26px;
- padding: 3px;
+ line-height: 26px;
+ padding: 3px;
}
#zoom_panel {
- margin-top: 5px;
+ margin-top: 5px;
}
.dropdown {
- position: relative;
+ position: relative;
}
.dropdown button {
- width: 15px;
- height: 21px;
- margin: 6px 0 0 1px;
- padding: 0;
- border-left: 1px solid #FFFFFF;
- border-top: 1px solid #FFFFFF;
- border-right: 1px solid #808080;
- border-bottom: 1px solid #808080;
- background-color: #E8E8E8;
+ width: 15px;
+ height: 21px;
+ margin: 6px 0 0 1px;
+ padding: 0;
+ border-left: 1px solid #FFFFFF;
+ border-top: 1px solid #FFFFFF;
+ border-right: 1px solid #808080;
+ border-bottom: 1px solid #808080;
+ background-color: #E8E8E8;
}
.dropdown button.down {
- border-left: 1px solid #808080;
- border-top: 1px solid #808080;
- border-right: 1px solid #FFFFFF;
- border-bottom: 1px solid #FFFFFF;
- background-color: #B0B0B0;
+ border-left: 1px solid #808080;
+ border-top: 1px solid #808080;
+ border-right: 1px solid #FFFFFF;
+ border-bottom: 1px solid #FFFFFF;
+ background-color: #B0B0B0;
}
.dropdown ul {
- list-style: none;
- position: absolute;
- margin: 0;
- padding: 0;
- left: -85px;
- top: 26px;
- z-index: 4;
- display: none;
+ list-style: none;
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ left: -85px;
+ top: 26px;
+ z-index: 4;
+ display: none;
}
.dropup ul {
- top: auto;
- bottom: 24px;
+ top: auto;
+ bottom: 24px;
}
.dropdown li {
- display: block;
- width: 120px;
- padding: 4px;
- background: #E8E8E8;
- border: 1px solid #B0B0B0;
- margin: 0 0 -1px 0;
- line-height: 16px;
+ display: block;
+ width: 120px;
+ padding: 4px;
+ background: #E8E8E8;
+ border: 1px solid #B0B0B0;
+ margin: 0 0 -1px 0;
+ line-height: 16px;
}
.dropdown li:hover {
- background-color: #FFC;
+ background-color: #FFC;
}
.dropdown li.special {
- padding: 10px 4px;
+ padding: 10px 4px;
}
.dropdown li.special:hover {
- background: #FFC;
+ background: #FFC;
}
#font_family_dropdown-list li {
- font-size: 1.4em;
+ font-size: 1.4em;
}
#font_family {
- margin-left: 5px;
- margin-right: 0;
+ margin-left: 5px;
+ margin-right: 0;
}
.tool_button,
@@ -689,179 +689,179 @@ span.zoom_tool {
.tool_button_current,
.push_button_pressed
{
- height: 24px;
- width: 24px;
- margin: 2px 2px 4px 2px;
- padding: 3px;
- -webkit-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
- moz-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
- box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
- background-color: #E8E8E8;
- cursor: pointer;
- border-radius: 3px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
+ height: 24px;
+ width: 24px;
+ margin: 2px 2px 4px 2px;
+ padding: 3px;
+ -webkit-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
+ moz-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
+ box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
+ background-color: #E8E8E8;
+ cursor: pointer;
+ border-radius: 3px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
}
#main_menu li#tool_open, #main_menu li#tool_import {
- position: relative;
- overflow: hidden;
+ position: relative;
+ overflow: hidden;
}
#tool_image {
- overflow: hidden;
+ overflow: hidden;
}
#tool_open input,
#tool_import input,
#tool_image input {
- position: absolute;
- opacity: 0;
- font-size: 10em;
- top: -5px;
- right: -5px;
- margin: 0;
- cursor: pointer; /* Sadly doesn't appear to have an effect */
+ position: absolute;
+ opacity: 0;
+ font-size: 10em;
+ top: -5px;
+ right: -5px;
+ margin: 0;
+ cursor: pointer; /* Sadly doesn't appear to have an effect */
}
.disabled {
- opacity: 0.5;
- cursor: default;
+ opacity: 0.5;
+ cursor: default;
}
.tool_sep {
- width: 1px;
- background: #888;
- border-left: 1px outset #EEE;
- margin: 2px 3px;
- padding: 0;
- height: 24px;
+ width: 1px;
+ background: #888;
+ border-left: 1px outset #EEE;
+ margin: 2px 3px;
+ padding: 0;
+ height: 24px;
}
.icon_label {
- float: left;
- padding-top: 3px;
- padding-right: 3px;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- height: 0;
+ float: left;
+ padding-top: 3px;
+ padding-right: 3px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ height: 0;
}
.width_label {
- padding-right: 5px;
+ padding-right: 5px;
}
#tool_bold, #tool_italic {
- font: bold 2.1em/1.1em serif;
- text-align: center;
- padding-left: 2px;
- position: relative;
+ font: bold 2.1em/1.1em serif;
+ text-align: center;
+ padding-left: 2px;
+ position: relative;
}
#text {
- position: absolute;
- left: -9999px;
+ position: absolute;
+ left: -9999px;
}
#tool_bold span, #tool_italic span {
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0; left: 0;
- background: #000;
- opacity: 0;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0; left: 0;
+ background: #000;
+ opacity: 0;
}
#tool_italic {
- font-weight: normal;
- font-style: italic;
+ font-weight: normal;
+ font-style: italic;
}
#url_notice {
- padding-top: 4px;
- display: none;
+ padding-top: 4px;
+ display: none;
}
#color_picker {
- position: absolute;
- display: none;
- background: #E8E8E8;
- height: 350px;
- z-index: 5;
+ position: absolute;
+ display: none;
+ background: #E8E8E8;
+ height: 350px;
+ z-index: 5;
}
.tools_flyout {
- position: absolute;
- display: none;
- cursor: pointer;
- width: 400px;
- z-index: 1;
+ position: absolute;
+ display: none;
+ cursor: pointer;
+ width: 400px;
+ z-index: 1;
}
.tools_flyout_v {
- position: absolute;
- display: none;
- cursor: pointer;
- width: 30px;
+ position: absolute;
+ display: none;
+ cursor: pointer;
+ width: 30px;
}
.tools_flyout .tool_button {
- float: left;
- background-color: #E8E8E8;
- border-left: 1px solid #FFFFFF;
- border-top: 1px solid #FFFFFF;
- border-right: 1px solid #808080;
- border-bottom: 1px solid #808080;
- height: 28px;
- width: 28px;
+ float: left;
+ background-color: #E8E8E8;
+ border-left: 1px solid #FFFFFF;
+ border-top: 1px solid #FFFFFF;
+ border-right: 1px solid #808080;
+ border-bottom: 1px solid #808080;
+ height: 28px;
+ width: 28px;
}
#tools_bottom {
- position: absolute;
- left: 40px;
- right: 0;
- bottom: 0;
- height: 40px;
- overflow: visible;
+ position: absolute;
+ left: 40px;
+ right: 0;
+ bottom: 0;
+ height: 40px;
+ overflow: visible;
}
#tools_bottom_1 {
- width: 115px;
- float: left;
+ width: 115px;
+ float: left;
}
#tools_bottom input[type=text] {
- width: 2.2em;
+ width: 2.2em;
}
/* Color tools: fill, stroke, opacity
–––––––––––––––––––––––––––––––––––––*/
#tools_bottom_2 {
- float: left;
- width: 300px;
- position: relative;
- margin-top: 5px;
- -webkit-transition: width 150ms ease;
+ float: left;
+ width: 300px;
+ position: relative;
+ margin-top: 5px;
+ -webkit-transition: width 150ms ease;
}
.expanded #tools_bottom_2 {
- width: 450px;
+ width: 450px;
}
#tools_bottom #tools_bottom_2 .dropdown button {
- margin-top: 2px;
+ margin-top: 2px;
}
.dropdown li.tool_button {
- width: 24px;
+ width: 24px;
}
#tools_bottom_2 .icon_label {
- display: block;
- margin: 3px 5px;
- padding: 0;
+ display: block;
+ margin: 3px 5px;
+ padding: 0;
}
#tool_opacity { right: 0;}
@@ -869,477 +869,477 @@ span.zoom_tool {
#tool_stroke { left: 60px;}
#fill_color, #stroke_color {
- height: 16px;
- width: 16px;
- border: 1px solid #808080;
- cursor: pointer;
- overflow: hidden;
+ height: 16px;
+ width: 16px;
+ border: 1px solid #808080;
+ cursor: pointer;
+ overflow: hidden;
}
#stroke_expand {
- width: 0;
- overflow: hidden;
+ width: 0;
+ overflow: hidden;
}
#toggle_stroke_tools {
- position: absolute;
- right: 0;
- top: 0;
- bottom: 0;
- width: 25px;
- text-align: center;
- border-radius: 0 3px 3px 0;
- margin: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ width: 25px;
+ text-align: center;
+ border-radius: 0 3px 3px 0;
+ margin: 0;
}
#toggle_stroke_tools:before {
- content: '>>';
- letter-spacing: -3px;
- font-weight: bold;
- color: #666;
+ content: '>>';
+ letter-spacing: -3px;
+ font-weight: bold;
+ color: #666;
}
.expanded #tool_stroke.color_tool {
- width: 280px;
+ width: 280px;
}
.expanded #toggle_stroke_tools:before {
- content: '<<';
+ content: '<<';
}
#toggle_stroke_tools:hover {
- background: white;
+ background: white;
}
.color_tool {
- position: absolute;
- overflow: hidden;
- background: #f0f0f0;
- height: 26px;
- line-height: 26px;
- border-radius: 3px;
- min-width: 52px;
+ position: absolute;
+ overflow: hidden;
+ background: #f0f0f0;
+ height: 26px;
+ line-height: 26px;
+ border-radius: 3px;
+ min-width: 52px;
}
#tool_stroke.color_tool {
- width: 130px;
- z-index: 2;
- -webkit-transition: width 150ms ease;
- -moz-transition: width 150ms ease;
- -o-transition: width 150ms ease;
- -ms-transition: width 150ms ease;
- transition: width 150ms ease;
+ width: 130px;
+ z-index: 2;
+ -webkit-transition: width 150ms ease;
+ -moz-transition: width 150ms ease;
+ -o-transition: width 150ms ease;
+ -ms-transition: width 150ms ease;
+ transition: width 150ms ease;
}
.color_block {
- position: absolute;
- top: 0;
- left: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
}
.color_block svg {
- display: block;
+ display: block;
}
.color_tool > * {
- float: left;
- margin-right: 5px;
+ float: left;
+ margin-right: 5px;
}
.color_tool .dropdown > * {
- float: left;
+ float: left;
}
.color_tool .stroke_label {
- margin-left: 25px;
- float: left;
+ margin-left: 25px;
+ float: left;
}
.color_tool > .color_block {
- top: 3px;
- left: 29px;
+ top: 3px;
+ left: 29px;
}
.color_tool input {
- margin: 0;
+ margin: 0;
}
#tool_opacity {
- overflow: visible;
+ overflow: visible;
}
@media screen and (max-width:1250px) {
- .expanded #palette_holder {
- left: 560px;
- overflow-x: scroll;
- padding: 0 5px;
- margin-top: 2px;
- height: 30px;
- }
- #tools_top {
- height: 71px;
- }
- #workarea, #sidepanels {
- top: 70px;
- }
- #rulers #ruler_corner,
- #rulers #ruler_x, #tools_left {
- top: 71px;
- }
+ .expanded #palette_holder {
+ left: 560px;
+ overflow-x: scroll;
+ padding: 0 5px;
+ margin-top: 2px;
+ height: 30px;
+ }
+ #tools_top {
+ height: 71px;
+ }
+ #workarea, #sidepanels {
+ top: 70px;
+ }
+ #rulers #ruler_corner,
+ #rulers #ruler_x, #tools_left {
+ top: 71px;
+ }
- #rulers #ruler_y {
- top: 86px;
- }
+ #rulers #ruler_y {
+ top: 86px;
+ }
- #cur_context_panel {
- top: 87px;
- }
+ #cur_context_panel {
+ top: 87px;
+ }
- #selected_panel {
- clear: right;
- }
+ #selected_panel {
+ clear: right;
+ }
}
@media screen and (max-width:1100px) {
- #tools_bottom:not(.expanded) #palette_holder {
- left: 410px;
- overflow-x: scroll;
- padding: 0 5px;
- margin-top: 2px;
- height: 30px;
- }
+ #tools_bottom:not(.expanded) #palette_holder {
+ left: 410px;
+ overflow-x: scroll;
+ padding: 0 5px;
+ margin-top: 2px;
+ height: 30px;
+ }
}
/*–––––––––––––––––––––––––––––––––––––*/
#option_lists ul {
- display: none;
- position: absolute;
- height: auto;
- z-index: 3;
- margin: -10px;
- list-style: none;
- padding-left: 0;
+ display: none;
+ position: absolute;
+ height: auto;
+ z-index: 3;
+ margin: -10px;
+ list-style: none;
+ padding-left: 0;
}
#option_lists .optcols2 {
- width: 70px;
- margin-left: -15px;
+ width: 70px;
+ margin-left: -15px;
}
#option_lists .optcols3 {
- width: 90px;
- margin-left: -31px;
+ width: 90px;
+ margin-left: -31px;
}
#option_lists .optcols4 {
- width: 130px;
- margin-left: -44px;
+ width: 130px;
+ margin-left: -44px;
}
#option_lists ul[class^=optcols] li {
- float: left;
+ float: left;
}
ul li.current {
- background-color: #F4E284;
+ background-color: #F4E284;
}
#option_lists ul li {
- margin: 0;
- border-radius: 0;
- -moz-border-radius: 0;
- -webkit-border-radius: 0;
+ margin: 0;
+ border-radius: 0;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
}
#tools_bottom .dropdown button {
- margin-top: 2px;
+ margin-top: 2px;
}
#opacity_dropdown li {
- width: 140px;
+ width: 140px;
}
#copyright {
- text-align: right;
- padding-right: .3em;
+ text-align: right;
+ padding-right: .3em;
}
#svg_source_editor {
- display: none;
+ display: none;
}
.overlay {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- background-color: black;
- opacity: 0.6;
- z-index: 5;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ background-color: black;
+ opacity: 0.6;
+ z-index: 5;
}
#svg_source_editor #svg_source_container {
- position: absolute;
- top: 30px;
- left: 30px;
- right: 30px;
- bottom: 30px;
- background-color: #B0B0B0;
- opacity: 1.0;
- text-align: center;
- border: 1px outset #777;
- z-index: 6;
+ position: absolute;
+ top: 30px;
+ left: 30px;
+ right: 30px;
+ bottom: 30px;
+ background-color: #B0B0B0;
+ opacity: 1.0;
+ text-align: center;
+ border: 1px outset #777;
+ z-index: 6;
}
#save_output_btns {
- display: none;
- text-align: left;
+ display: none;
+ text-align: left;
}
#save_output_btns p {
- margin: .5em 1.5em;
- display: inline-block;
+ margin: .5em 1.5em;
+ display: inline-block;
}
#bg_blocks {
- overflow: auto;
- margin-left: 30px;
+ overflow: auto;
+ margin-left: 30px;
}
#bg_blocks .color_block {
- position: static;
+ position: static;
}
#svg_docprops #svg_docprops_container,
#svg_prefs #svg_prefs_container {
- position: absolute;
- top: 50px;
- padding: 10px;
- background-color: #B0B0B0;
- border: 1px outset #777;
- opacity: 1.0;
+ position: absolute;
+ top: 50px;
+ padding: 10px;
+ background-color: #B0B0B0;
+ border: 1px outset #777;
+ opacity: 1.0;
/* width: 450px;*/
- font-family: Verdana, Helvetica, sans-serif;
- font-size: .8em;
- z-index: 20001;
+ font-family: Verdana, Helvetica, sans-serif;
+ font-size: .8em;
+ z-index: 20001;
}
#svg_docprops .error {
- border: 1px solid red;
- padding: 3px;
+ border: 1px solid red;
+ padding: 3px;
}
#svg_docprops #resolution {
- max-width: 14em;
+ max-width: 14em;
}
#tool_docprops_back,
#tool_prefs_back {
- margin-left: 1em;
- overflow: auto;
+ margin-left: 1em;
+ overflow: auto;
}
#svg_docprops_container #svg_docprops_docprops,
#svg_prefs #svg_docprops_prefs {
- float: left;
- width: 221px;
- margin: 5px .7em;
- overflow: hidden;
+ float: left;
+ width: 221px;
+ margin: 5px .7em;
+ overflow: hidden;
}
#svg_prefs_container fieldset + fieldset {
- float: right;
+ float: right;
}
#svg_docprops legend,
#svg_prefs legend {
- max-width: 195px;
+ max-width: 195px;
}
#svg_docprops_docprops > legend,
#svg_prefs_container > fieldset > legend {
- font-weight: bold;
- font-size: 1.1em;
+ font-weight: bold;
+ font-size: 1.1em;
}
#svg_docprops_container fieldset,
#svg_prefs fieldset {
- padding: 5px;
- margin: 5px;
- border: 1px solid #DDD;
+ padding: 5px;
+ margin: 5px;
+ border: 1px solid #DDD;
}
#svg_docprops_container label,
#svg_prefs_container label {
- display: block;
- margin: .5em;
+ display: block;
+ margin: .5em;
}
#svginfo_bg_note {
- font-size: .9em;
- font-style: italic;
- color: #444;
+ font-size: .9em;
+ font-style: italic;
+ color: #444;
}
#canvas_title, #canvas_bg_url {
- display: block;
- width: 96%;
+ display: block;
+ width: 96%;
}
#svg_source_editor form {
- position: absolute;
- top: 40px;
- bottom: 30px;
- width: 100%;
+ position: absolute;
+ top: 40px;
+ bottom: 30px;
+ width: 100%;
}
#svg_source_editor #svg_source_textarea {
- position: relative;
- width: 95%;
- height: 95%;
- padding: 5px;
- font-size: 12px;
+ position: relative;
+ width: 95%;
+ height: 95%;
+ padding: 5px;
+ font-size: 12px;
}
#svg_source_editor #tool_source_back {
- text-align: left;
- padding-left: 20px;
+ text-align: left;
+ padding-left: 20px;
}
#svg_prefs_container div.color_block {
- float: left;
- margin: 2px;
- padding: 20px;
+ float: left;
+ margin: 2px;
+ padding: 20px;
}
#change_background div.cur_background {
- border: 2px solid blue;
- padding: 18px;
+ border: 2px solid blue;
+ padding: 18px;
}
#background_img {
- position: absolute;
- top: 0;
- left: 0;
- text-align: left;
+ position: absolute;
+ top: 0;
+ left: 0;
+ text-align: left;
}
#svg_docprops button,
#svg_prefs button {
- margin-top: 0;
- margin-bottom: 5px;
+ margin-top: 0;
+ margin-bottom: 5px;
}
#svg_docprops,
#svg_prefs {
- display: none;
+ display: none;
}
#image_save_opts label {
- font-size: .9em;
+ font-size: .9em;
}
#image_save_opts input {
- margin-left: 0;
+ margin-left: 0;
}
#tool_prefs_option {
- float: right;
+ float: right;
}
.toolbar_button button {
- border:1px solid #dedede;
- line-height:130%;
- float: left;
- background: #E8E8E8 none;
- padding:5px 10px 5px 7px; /* Firefox */
- line-height:17px; /* Safari */
- margin: 5px 20px 0 0;
- border: 1px #808080 solid;
- border-top-color: #FFF;
- border-left-color: #FFF;
- border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
+ border:1px solid #dedede;
+ line-height:130%;
+ float: left;
+ background: #E8E8E8 none;
+ padding:5px 10px 5px 7px; /* Firefox */
+ line-height:17px; /* Safari */
+ margin: 5px 20px 0 0;
+ border: 1px #808080 solid;
+ border-top-color: #FFF;
+ border-left-color: #FFF;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
.toolbar_button button:hover {
- border: 1px #e0a874 solid;
- border-top-color: #fcd9ba;
- border-left-color: #fcd9ba;
- background-color: #FFC;
+ border: 1px #e0a874 solid;
+ border-top-color: #fcd9ba;
+ border-left-color: #fcd9ba;
+ background-color: #FFC;
}
.toolbar_button button:active {
- background-color: #F4E284;
- border-left: 1px solid #663300;
- border-top: 1px solid #663300;
+ background-color: #F4E284;
+ border-left: 1px solid #663300;
+ border-top: 1px solid #663300;
}
.toolbar_button button .svg_icon {
- margin: 0 3px -3px 0 !important;
- padding: 0;
- border: none;
- width: 16px;
- height: 16px;
+ margin: 0 3px -3px 0 !important;
+ padding: 0;
+ border: none;
+ width: 16px;
+ height: 16px;
}
#dialog_box {
- display: none;
+ display: none;
}
#dialog_content {
- height: 95px;
- margin: 10px 10px 5px 10px;
- background: #DDD;
- overflow: auto;
- text-align: left;
- border: 1px solid #B0B0B0;
+ height: 95px;
+ margin: 10px 10px 5px 10px;
+ background: #DDD;
+ overflow: auto;
+ text-align: left;
+ border: 1px solid #B0B0B0;
}
#dialog_content.prompt {
- height: 75px;
+ height: 75px;
}
#dialog_content p {
- margin: 10px;
- line-height: 1.3em;
+ margin: 10px;
+ line-height: 1.3em;
}
#dialog_container {
- position: absolute;
- font-family: Verdana;
- text-align: center;
- left: 50%;
- top: 50%;
- width: 300px;
- margin-left: -150px;
- height: 150px;
- margin-top: -80px;
- position: fixed;
- z-index: 50001;
- background: #CCC;
- border: 1px outset #777;
- font-family:Verdana,Helvetica,sans-serif;
- font-size:0.8em;
+ position: absolute;
+ font-family: Verdana;
+ text-align: center;
+ left: 50%;
+ top: 50%;
+ width: 300px;
+ margin-left: -150px;
+ height: 150px;
+ margin-top: -80px;
+ position: fixed;
+ z-index: 50001;
+ background: #CCC;
+ border: 1px outset #777;
+ font-family:Verdana,Helvetica,sans-serif;
+ font-size:0.8em;
}
#dialog_container, #dialog_content {
- border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
#dialog_buttons input[type=text] {
- width: 90%;
- display: block;
- margin: 0 0 5px 11px;
+ width: 90%;
+ display: block;
+ margin: 0 0 5px 11px;
}
#dialog_buttons input[type=button] {
- margin: 0 1em;
+ margin: 0 1em;
}
/* Slider
@@ -1361,93 +1361,93 @@ ul li.current {
.ui-slider-vertical .ui-slider-range-max { top: 0; }
.ui-slider {
- border: 1px solid #B0B0B0;
+ border: 1px solid #B0B0B0;
}
.ui-slider-handle {
- background: #B0B0B0;
- border: 1px solid #000;
+ background: #B0B0B0;
+ border: 1px solid #000;
}
/* Necessary to keep the flyouts sized properly */
.tools_flyout .tool_button,
.tools_flyout .tool_flyout {
- padding: 2px;
- width: 24px;
- height: 24px;
- margin: 0;
- border-radius: 0px;
- -moz-border-radius: 0px;
- -webkit-border-radius: 0px;
+ padding: 2px;
+ width: 24px;
+ height: 24px;
+ margin: 0;
+ border-radius: 0px;
+ -moz-border-radius: 0px;
+ -webkit-border-radius: 0px;
}
/* Generic context menu styles */
.contextMenu {
- position: absolute;
- z-index: 99999;
- border: solid 1px rgba(0,0,0,.33);
- background: rgba(255,255,255,.95);
- padding: 5px 0;
- margin: 0px;
- display: none;
- font: 12px/15px Lucida Sans, Helvetica, Verdana, sans-serif;
- border-radius: 5px;
- -moz-border-radius: 5px;
- -moz-box-shadow: 2px 5px 10px rgba(0,0,0,.3);
- -webkit-box-shadow: 2px 5px 10px rgba(0,0,0,.3);
- box-shadow: 2px 5px 10px rgba(0,0,0,.3);
+ position: absolute;
+ z-index: 99999;
+ border: solid 1px rgba(0,0,0,.33);
+ background: rgba(255,255,255,.95);
+ padding: 5px 0;
+ margin: 0px;
+ display: none;
+ font: 12px/15px Lucida Sans, Helvetica, Verdana, sans-serif;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -moz-box-shadow: 2px 5px 10px rgba(0,0,0,.3);
+ -webkit-box-shadow: 2px 5px 10px rgba(0,0,0,.3);
+ box-shadow: 2px 5px 10px rgba(0,0,0,.3);
}
.contextMenu LI {
- list-style: none;
- padding: 0px;
- margin: 0px;
+ list-style: none;
+ padding: 0px;
+ margin: 0px;
}
.contextMenu .shortcut {
- width: 115px;
- text-align:right;
- float:right;
+ width: 115px;
+ text-align:right;
+ float:right;
}
.contextMenu A {
- -moz-user-select: none;
- -webkit-user-select: none;
- color: #222;
- text-decoration: none;
- display: block;
- line-height: 20px;
- height: 20px;
- background-position: 6px center;
- background-repeat: no-repeat;
- outline: none;
- padding: 0px 15px 1px 20px;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ color: #222;
+ text-decoration: none;
+ display: block;
+ line-height: 20px;
+ height: 20px;
+ background-position: 6px center;
+ background-repeat: no-repeat;
+ outline: none;
+ padding: 0px 15px 1px 20px;
}
.contextMenu LI.hover A {
- background-color: #2e5dea;
- color: white;
- cursor: default;
+ background-color: #2e5dea;
+ color: white;
+ cursor: default;
}
.contextMenu LI.disabled A {
- color: #999;
+ color: #999;
}
.contextMenu LI.hover.disabled A {
- background-color: transparent;
+ background-color: transparent;
}
.contextMenu LI.separator {
- border-top: solid 1px #E3E3E3;
- padding-top: 5px;
- margin-top: 5px;
+ border-top: solid 1px #E3E3E3;
+ padding-top: 5px;
+ margin-top: 5px;
}
/*
- Adding Icons
- You can add icons to the context menu by adding
- classes to the respective LI element(s)
+ Adding Icons
+ You can add icons to the context menu by adding
+ classes to the respective LI element(s)
*/
/*
diff --git a/editor/svg-editor.html b/editor/svg-editor.html
index 8c93d9e6..0439b938 100644
--- a/editor/svg-editor.html
+++ b/editor/svg-editor.html
@@ -71,17 +71,17 @@
@@ -92,514 +92,514 @@
-
-
Layers
-
-
-
-
-
-
-
-
+
+
Layers
+
+
+
+
+
+
+
+
-
-
Move elements to:
-
- Layer 1
-
-
-
L a y e r s
+
+
Move elements to:
+
+ Layer 1
+
+
+
L a y e r s
-
+
-
+
-
-
-
-
- New Image (N)
-
+
+
+
+
+ New Image (N)
+
-
-
- Open SVG
-
+
+
+ Open SVG
+
-
-
- Import Image
-
+
+
+ Import Image
+
-
-
- Save Image (S)
-
+
+
+ Save Image (S)
+
-
-
- Export
-
+
+
+ Export
+
-
-
- Document Properties (D)
-
-
+
+
+ Document Properties (D)
+
+
-
-
- SVG-edit Home Page
-
-
+
+
+ SVG-edit Home Page
+
+
-
- Editor Options
-
+
+ Editor Options
+
-
+
-
-
-
- Apply Changes
- Cancel
-
-
-
Copy the contents of this box into a text editor, then save the file with a .svg extension.
-
Done
-
-
-
+
+
+
+ Apply Changes
+ Cancel
+
+
+
Copy the contents of this box into a text editor, then save the file with a .svg extension.
+
Done
+
+
+
+
+