').parent().attr({
- id: modeId + '_' + id,
- title: id
- });
- // Store for later use
- curLib.buttons.push(iconBtn[0]);
- }
- }
+ var iconBtn = icon.wrap('
').parent().attr({
+ id: modeId + '_' + id,
+ title: id
+ });
+ // Store for later use
+ curLib.buttons.push(iconBtn[0]);
+ }
+ }
- function loadLibrary (catId) {
- var lib = library[catId];
+ function loadLibrary (catId) {
+ var lib = library[catId];
- if (!lib) {
- $('#shape_buttons').html('Loading...');
- $.getJSON(svgEditor.curConfig.extPath + 'shapelib/' + catId + '.json', function (result) {
- curLib = library[catId] = {
- data: result.data,
- size: result.size,
- fill: result.fill
- };
- makeButtons(catId, result);
- loadIcons();
- });
- return;
- }
- curLib = lib;
- if (!lib.buttons.length) { makeButtons(catId, lib); }
- loadIcons();
- }
+ if (!lib) {
+ $('#shape_buttons').html('Loading...');
+ $.getJSON(svgEditor.curConfig.extPath + 'shapelib/' + catId + '.json', function (result) {
+ curLib = library[catId] = {
+ data: result.data,
+ size: result.size,
+ fill: result.fill
+ };
+ makeButtons(catId, result);
+ loadIcons();
+ });
+ return;
+ }
+ curLib = lib;
+ if (!lib.buttons.length) { makeButtons(catId, lib); }
+ loadIcons();
+ }
- return {
- svgicons: svgEditor.curConfig.extPath + 'ext-shapes.xml',
- buttons: [{
- id: 'tool_shapelib',
- type: 'mode_flyout', // _flyout
- position: 6,
- title: 'Shape library',
- events: {
- click: function () {
- canv.setMode(modeId);
- }
- }
- }],
- callback: function () {
- $('').appendTo('head');
- }
- fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
- $('#star_panel').toggle(on);
- }
+ function showPanel (on) {
+ var fcRules = $('#fc_rules');
+ if (!fcRules.length) {
+ fcRules = $('').appendTo('head');
+ }
+ fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
+ $('#star_panel').toggle(on);
+ }
- /*
- function toggleSourceButtons(on){
- $('#star_save, #star_cancel').toggle(on);
- }
- */
+ /*
+ function toggleSourceButtons(on){
+ $('#star_save, #star_cancel').toggle(on);
+ }
+ */
- function setAttr (attr, val) {
- svgCanvas.changeSelectedAttribute(attr, val);
- S.call('changed', selElems);
- }
+ function setAttr (attr, val) {
+ svgCanvas.changeSelectedAttribute(attr, val);
+ S.call('changed', selElems);
+ }
- /*
- function cot(n){
- return 1 / Math.tan(n);
- }
+ /*
+ function cot(n){
+ return 1 / Math.tan(n);
+ }
- function sec(n){
- return 1 / Math.cos(n);
- }
- */
+ function sec(n){
+ return 1 / Math.cos(n);
+ }
+ */
- return {
- name: 'star',
- svgicons: svgEditor.curConfig.extPath + 'star-icons.svg',
- buttons: [{
- id: 'tool_star',
- type: 'mode',
- title: 'Star Tool',
- position: 12,
- events: {
- click: function () {
- showPanel(true);
- svgCanvas.setMode('star');
- }
- }
- }],
+ return {
+ name: 'star',
+ svgicons: svgEditor.curConfig.extPath + 'star-icons.svg',
+ buttons: [{
+ id: 'tool_star',
+ type: 'mode',
+ title: 'Star Tool',
+ position: 12,
+ events: {
+ click: function () {
+ showPanel(true);
+ svgCanvas.setMode('star');
+ }
+ }
+ }],
- context_tools: [{
- type: 'input',
- panel: 'star_panel',
- title: 'Number of Sides',
- id: 'starNumPoints',
- label: 'points',
- size: 3,
- defval: 5,
- events: {
- change: function () {
- setAttr('point', this.value);
- }
- }
- }, {
- type: 'input',
- panel: 'star_panel',
- title: 'Pointiness',
- id: 'starRadiusMulitplier',
- label: 'Pointiness',
- size: 3,
- defval: 2.5
- }, {
- type: 'input',
- panel: 'star_panel',
- title: 'Twists the star',
- id: 'radialShift',
- label: 'Radial Shift',
- size: 3,
- defval: 0,
- events: {
- change: function () {
- setAttr('radialshift', this.value);
- }
- }
- }],
- callback: function () {
- $('#star_panel').hide();
- // var endChanges = function(){};
- },
- mouseDown: function (opts) {
- var rgb = svgCanvas.getColor('fill');
- // var ccRgbEl = rgb.substring(1, rgb.length);
- var sRgb = svgCanvas.getColor('stroke');
- // var ccSRgbEl = sRgb.substring(1, rgb.length);
- var sWidth = svgCanvas.getStrokeWidth();
+ context_tools: [{
+ type: 'input',
+ panel: 'star_panel',
+ title: 'Number of Sides',
+ id: 'starNumPoints',
+ label: 'points',
+ size: 3,
+ defval: 5,
+ events: {
+ change: function () {
+ setAttr('point', this.value);
+ }
+ }
+ }, {
+ type: 'input',
+ panel: 'star_panel',
+ title: 'Pointiness',
+ id: 'starRadiusMulitplier',
+ label: 'Pointiness',
+ size: 3,
+ defval: 2.5
+ }, {
+ type: 'input',
+ panel: 'star_panel',
+ title: 'Twists the star',
+ id: 'radialShift',
+ label: 'Radial Shift',
+ size: 3,
+ defval: 0,
+ events: {
+ change: function () {
+ setAttr('radialshift', this.value);
+ }
+ }
+ }],
+ callback: function () {
+ $('#star_panel').hide();
+ // var endChanges = function(){};
+ },
+ mouseDown: function (opts) {
+ var rgb = svgCanvas.getColor('fill');
+ // var ccRgbEl = rgb.substring(1, rgb.length);
+ var sRgb = svgCanvas.getColor('stroke');
+ // var ccSRgbEl = sRgb.substring(1, rgb.length);
+ var sWidth = svgCanvas.getStrokeWidth();
- if (svgCanvas.getMode() === 'star') {
- started = true;
+ if (svgCanvas.getMode() === 'star') {
+ started = true;
- newFO = S.addSvgElementFromJson({
- 'element': 'polygon',
- 'attr': {
- 'cx': opts.start_x,
- 'cy': opts.start_y,
- 'id': S.getNextId(),
- 'shape': 'star',
- 'point': document.getElementById('starNumPoints').value,
- 'r': 0,
- 'radialshift': document.getElementById('radialShift').value,
- 'r2': 0,
- 'orient': 'point',
- 'fill': rgb,
- 'strokecolor': sRgb,
- 'strokeWidth': sWidth
- }
- });
- return {
- started: true
- };
- }
- },
- mouseMove: function (opts) {
- if (!started) {
- return;
- }
- if (svgCanvas.getMode() === 'star') {
- var x = opts.mouse_x;
- var y = opts.mouse_y;
- var c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
+ newFO = S.addSvgElementFromJson({
+ 'element': 'polygon',
+ 'attr': {
+ 'cx': opts.start_x,
+ 'cy': opts.start_y,
+ 'id': S.getNextId(),
+ 'shape': 'star',
+ 'point': document.getElementById('starNumPoints').value,
+ 'r': 0,
+ 'radialshift': document.getElementById('radialShift').value,
+ 'r2': 0,
+ 'orient': 'point',
+ 'fill': rgb,
+ 'strokecolor': sRgb,
+ 'strokeWidth': sWidth
+ }
+ });
+ return {
+ started: true
+ };
+ }
+ },
+ mouseMove: function (opts) {
+ if (!started) {
+ return;
+ }
+ if (svgCanvas.getMode() === 'star') {
+ var x = opts.mouse_x;
+ var y = opts.mouse_y;
+ var c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
- var cx = c.cx, cy = c.cy, fill = c.fill, strokecolor = c.strokecolor, strokewidth = c.strokeWidth, radialShift = c.radialshift, point = c.point, orient = c.orient, circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5, inradius = circumradius / document.getElementById('starRadiusMulitplier').value;
- newFO.setAttributeNS(null, 'r', circumradius);
- newFO.setAttributeNS(null, 'r2', inradius);
+ var cx = c.cx, cy = c.cy, fill = c.fill, strokecolor = c.strokecolor, strokewidth = c.strokeWidth, radialShift = c.radialshift, point = c.point, orient = c.orient, circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5, inradius = circumradius / document.getElementById('starRadiusMulitplier').value;
+ newFO.setAttributeNS(null, 'r', circumradius);
+ newFO.setAttributeNS(null, 'r2', inradius);
- var polyPoints = '';
- var s;
- for (s = 0; point >= s; s++) {
- var angle = 2.0 * Math.PI * (s / point);
- if (orient === 'point') {
- angle -= (Math.PI / 2);
- } else if (orient === 'edge') {
- angle = (angle + (Math.PI / point)) - (Math.PI / 2);
- }
+ var polyPoints = '';
+ var s;
+ for (s = 0; point >= s; s++) {
+ var angle = 2.0 * Math.PI * (s / point);
+ if (orient === 'point') {
+ angle -= (Math.PI / 2);
+ } else if (orient === 'edge') {
+ angle = (angle + (Math.PI / point)) - (Math.PI / 2);
+ }
- x = (circumradius * Math.cos(angle)) + cx;
- y = (circumradius * Math.sin(angle)) + cy;
+ x = (circumradius * Math.cos(angle)) + cx;
+ y = (circumradius * Math.sin(angle)) + cy;
- polyPoints += x + ',' + y + ' ';
+ polyPoints += x + ',' + y + ' ';
- if (inradius != null) {
- angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);
- if (orient === 'point') {
- angle -= (Math.PI / 2);
- } else if (orient === 'edge') {
- angle = (angle + (Math.PI / point)) - (Math.PI / 2);
- }
- angle += radialShift;
+ if (inradius != null) {
+ angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);
+ if (orient === 'point') {
+ angle -= (Math.PI / 2);
+ } else if (orient === 'edge') {
+ angle = (angle + (Math.PI / point)) - (Math.PI / 2);
+ }
+ angle += radialShift;
- x = (inradius * Math.cos(angle)) + cx;
- y = (inradius * Math.sin(angle)) + cy;
+ x = (inradius * Math.cos(angle)) + cx;
+ y = (inradius * Math.sin(angle)) + cy;
- polyPoints += x + ',' + y + ' ';
- }
- }
- newFO.setAttributeNS(null, 'points', polyPoints);
- newFO.setAttributeNS(null, 'fill', fill);
- newFO.setAttributeNS(null, 'stroke', strokecolor);
- newFO.setAttributeNS(null, 'stroke-width', strokewidth);
- /* var shape = */ newFO.getAttributeNS(null, 'shape');
+ polyPoints += x + ',' + y + ' ';
+ }
+ }
+ newFO.setAttributeNS(null, 'points', polyPoints);
+ newFO.setAttributeNS(null, 'fill', fill);
+ newFO.setAttributeNS(null, 'stroke', strokecolor);
+ newFO.setAttributeNS(null, 'stroke-width', strokewidth);
+ /* var shape = */ newFO.getAttributeNS(null, 'shape');
- return {
- started: true
- };
- }
- },
- mouseUp: function () {
- if (svgCanvas.getMode() === 'star') {
- var attrs = $(newFO).attr(['r']);
- // svgCanvas.addToSelection([newFO], true);
- return {
- keep: (attrs.r !== '0'),
- element: newFO
- };
- }
- },
- selectedChanged: function (opts) {
- // Use this to update the current selected elements
- selElems = opts.elems;
+ return {
+ started: true
+ };
+ }
+ },
+ mouseUp: function () {
+ if (svgCanvas.getMode() === 'star') {
+ var attrs = $(newFO).attr(['r']);
+ // svgCanvas.addToSelection([newFO], true);
+ return {
+ keep: (attrs.r !== '0'),
+ element: newFO
+ };
+ }
+ },
+ selectedChanged: function (opts) {
+ // Use this to update the current selected elements
+ selElems = opts.elems;
- var i = selElems.length;
+ var i = selElems.length;
- while (i--) {
- var elem = selElems[i];
- if (elem && elem.getAttributeNS(null, 'shape') === 'star') {
- if (opts.selectedElement && !opts.multiselected) {
- // $('#starRadiusMulitplier').val(elem.getAttribute('r2'));
- $('#starNumPoints').val(elem.getAttribute('point'));
- $('#radialShift').val(elem.getAttribute('radialshift'));
- showPanel(true);
- } else {
- showPanel(false);
- }
- } else {
- showPanel(false);
- }
- }
- },
- elementChanged: function (opts) {
- // var elem = opts.elems[0];
- }
- };
+ while (i--) {
+ var elem = selElems[i];
+ if (elem && elem.getAttributeNS(null, 'shape') === 'star') {
+ if (opts.selectedElement && !opts.multiselected) {
+ // $('#starRadiusMulitplier').val(elem.getAttribute('r2'));
+ $('#starNumPoints').val(elem.getAttribute('point'));
+ $('#radialShift').val(elem.getAttribute('radialshift'));
+ showPanel(true);
+ } else {
+ showPanel(false);
+ }
+ } else {
+ showPanel(false);
+ }
+ }
+ },
+ elementChanged: function (opts) {
+ // var elem = opts.elems[0];
+ }
+ };
});
diff --git a/editor/extensions/ext-storage.js b/editor/extensions/ext-storage.js
index edb8e814..8293fc47 100644
--- a/editor/extensions/ext-storage.js
+++ b/editor/extensions/ext-storage.js
@@ -21,265 +21,265 @@
/*
TODOS
1. Revisit on whether to use $.pref over directly setting curConfig in all
- extensions for a more public API (not only for extPath and imagePath,
- but other currently used config in the extensions)
+ extensions for a more public API (not only for extPath and imagePath,
+ but other currently used config in the extensions)
2. We might provide control of storage settings through the UI besides the
initial (or URL-forced) dialog.
*/
svgEditor.addExtension('storage', function () {
- // We could empty any already-set data for users when they decline storage,
- // but it would be a risk for users who wanted to store but accidentally
- // said "no"; instead, we'll let those who already set it, delete it themselves;
- // to change, set the "emptyStorageOnDecline" config setting to true
- // in config.js.
- var emptyStorageOnDecline = svgEditor.curConfig.emptyStorageOnDecline,
- // When the code in svg-editor.js prevents local storage on load per
- // user request, we also prevent storing on unload here so as to
- // avoid third-party sites making XSRF requests or providing links
- // which would cause the user's local storage not to load and then
- // upon page unload (such as the user closing the window), the storage
- // would thereby be set with an empty value, erasing any of the
- // user's prior work. To change this behavior so that no use of storage
- // or adding of new storage takes place regardless of settings, set
- // the "noStorageOnLoad" config setting to true in config.js.
- noStorageOnLoad = svgEditor.curConfig.noStorageOnLoad,
- forceStorage = svgEditor.curConfig.forceStorage,
- storage = svgEditor.storage;
+ // We could empty any already-set data for users when they decline storage,
+ // but it would be a risk for users who wanted to store but accidentally
+ // said "no"; instead, we'll let those who already set it, delete it themselves;
+ // to change, set the "emptyStorageOnDecline" config setting to true
+ // in config.js.
+ var emptyStorageOnDecline = svgEditor.curConfig.emptyStorageOnDecline,
+ // When the code in svg-editor.js prevents local storage on load per
+ // user request, we also prevent storing on unload here so as to
+ // avoid third-party sites making XSRF requests or providing links
+ // which would cause the user's local storage not to load and then
+ // upon page unload (such as the user closing the window), the storage
+ // would thereby be set with an empty value, erasing any of the
+ // user's prior work. To change this behavior so that no use of storage
+ // or adding of new storage takes place regardless of settings, set
+ // the "noStorageOnLoad" config setting to true in config.js.
+ noStorageOnLoad = svgEditor.curConfig.noStorageOnLoad,
+ forceStorage = svgEditor.curConfig.forceStorage,
+ storage = svgEditor.storage;
- function replaceStoragePrompt (val) {
- val = val ? 'storagePrompt=' + val : '';
- var loc = top.location; // Allow this to work with the embedded editor as well
- if (loc.href.indexOf('storagePrompt=') > -1) {
- loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
- return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));
- });
- } else {
- loc.href += (loc.href.indexOf('?') > -1 ? '&' : '?') + val;
- }
- }
- function setSVGContentStorage (val) {
- if (storage) {
- var name = 'svgedit-' + svgEditor.curConfig.canvasName;
- if (!val) {
- storage.removeItem(name);
- } else {
- storage.setItem(name, val);
- }
- }
- }
+ function replaceStoragePrompt (val) {
+ val = val ? 'storagePrompt=' + val : '';
+ var loc = top.location; // Allow this to work with the embedded editor as well
+ if (loc.href.indexOf('storagePrompt=') > -1) {
+ loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
+ return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));
+ });
+ } else {
+ loc.href += (loc.href.indexOf('?') > -1 ? '&' : '?') + val;
+ }
+ }
+ function setSVGContentStorage (val) {
+ if (storage) {
+ var name = 'svgedit-' + svgEditor.curConfig.canvasName;
+ if (!val) {
+ storage.removeItem(name);
+ } else {
+ storage.setItem(name, val);
+ }
+ }
+ }
- function expireCookie (cookie) {
- document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
- }
+ function expireCookie (cookie) {
+ document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
+ }
- function removeStoragePrefCookie () {
- expireCookie('store');
- }
+ function removeStoragePrefCookie () {
+ expireCookie('store');
+ }
- function emptyStorage () {
- setSVGContentStorage('');
- var name;
- for (name in svgEditor.curPrefs) {
- if (svgEditor.curPrefs.hasOwnProperty(name)) {
- name = 'svg-edit-' + name;
- if (storage) {
- storage.removeItem(name);
- }
- expireCookie(name);
- }
- }
- }
+ function emptyStorage () {
+ setSVGContentStorage('');
+ var name;
+ for (name in svgEditor.curPrefs) {
+ if (svgEditor.curPrefs.hasOwnProperty(name)) {
+ name = 'svg-edit-' + name;
+ if (storage) {
+ storage.removeItem(name);
+ }
+ expireCookie(name);
+ }
+ }
+ }
- // emptyStorage();
+ // emptyStorage();
- /**
- * Listen for unloading: If and only if opted in by the user, set the content
- * document and preferences into storage:
- * 1. Prevent save warnings (since we're automatically saving unsaved
- * content into storage)
- * 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)
- * 3. Use localStorage (where available) or cookies to set preferences.
- */
- function setupBeforeUnloadListener () {
- window.addEventListener('beforeunload', function (e) {
- // Don't save anything unless the user opted in to storage
- if (!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)) {
- return;
- }
- var key;
- if (document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)) {
- setSVGContentStorage(svgCanvas.getSvgString());
- }
+ /**
+ * Listen for unloading: If and only if opted in by the user, set the content
+ * document and preferences into storage:
+ * 1. Prevent save warnings (since we're automatically saving unsaved
+ * content into storage)
+ * 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)
+ * 3. Use localStorage (where available) or cookies to set preferences.
+ */
+ function setupBeforeUnloadListener () {
+ window.addEventListener('beforeunload', function (e) {
+ // Don't save anything unless the user opted in to storage
+ if (!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)) {
+ return;
+ }
+ var key;
+ if (document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)) {
+ setSVGContentStorage(svgCanvas.getSvgString());
+ }
- svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on
- // svgEditor.showSaveWarning = false;
+ svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on
+ // svgEditor.showSaveWarning = false;
- var curPrefs = svgEditor.curPrefs;
+ var curPrefs = svgEditor.curPrefs;
- for (key in curPrefs) {
- if (curPrefs.hasOwnProperty(key)) { // It's our own config, so we don't need to iterate up the prototype chain
- var val = curPrefs[key],
- store = (val !== undefined);
- key = 'svg-edit-' + key;
- if (!store) {
- continue;
- }
- if (storage) {
- storage.setItem(key, val);
- } else if (window.widget) {
- widget.setPreferenceForKey(val, key);
- } else {
- val = encodeURIComponent(val);
- document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
- }
- }
- }
- }, false);
- }
+ for (key in curPrefs) {
+ if (curPrefs.hasOwnProperty(key)) { // It's our own config, so we don't need to iterate up the prototype chain
+ var val = curPrefs[key],
+ store = (val !== undefined);
+ key = 'svg-edit-' + key;
+ if (!store) {
+ continue;
+ }
+ if (storage) {
+ storage.setItem(key, val);
+ } else if (window.widget) {
+ widget.setPreferenceForKey(val, key);
+ } else {
+ val = encodeURIComponent(val);
+ document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
+ }
+ }
+ }
+ }, false);
+ }
- /*
- // We could add locales here instead (and also thereby avoid the need
- // to keep our content within "langReady"), but this would be less
- // convenient for translators.
- $.extend(uiStrings, {confirmSetStorage: {
- message: "By default and where supported, SVG-Edit can store your editor "+
- "preferences and SVG content locally on your machine so you do not "+
- "need to add these back each time you load SVG-Edit. If, for privacy "+
- "reasons, you do not wish to store this information on your machine, "+
- "you can change away from the default option below.",
- storagePrefsAndContent: "Store preferences and SVG content locally",
- storagePrefsOnly: "Only store preferences locally",
- storagePrefs: "Store preferences locally",
- storageNoPrefsOrContent: "Do not store my preferences or SVG content locally",
- storageNoPrefs: "Do not store my preferences locally",
- rememberLabel: "Remember this choice?",
- rememberTooltip: "If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again."
- }});
- */
- var loaded = false;
- return {
- name: 'storage',
- langReady: function (data) {
- var // lang = data.lang,
- uiStrings = data.uiStrings, // No need to store as dialog should only run once
- storagePrompt = $.deparam.querystring(true).storagePrompt;
+ /*
+ // We could add locales here instead (and also thereby avoid the need
+ // to keep our content within "langReady"), but this would be less
+ // convenient for translators.
+ $.extend(uiStrings, {confirmSetStorage: {
+ message: "By default and where supported, SVG-Edit can store your editor "+
+ "preferences and SVG content locally on your machine so you do not "+
+ "need to add these back each time you load SVG-Edit. If, for privacy "+
+ "reasons, you do not wish to store this information on your machine, "+
+ "you can change away from the default option below.",
+ storagePrefsAndContent: "Store preferences and SVG content locally",
+ storagePrefsOnly: "Only store preferences locally",
+ storagePrefs: "Store preferences locally",
+ storageNoPrefsOrContent: "Do not store my preferences or SVG content locally",
+ storageNoPrefs: "Do not store my preferences locally",
+ rememberLabel: "Remember this choice?",
+ rememberTooltip: "If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again."
+ }});
+ */
+ var loaded = false;
+ return {
+ name: 'storage',
+ langReady: function (data) {
+ var // lang = data.lang,
+ uiStrings = data.uiStrings, // No need to store as dialog should only run once
+ storagePrompt = $.deparam.querystring(true).storagePrompt;
- // No need to run this one-time dialog again just because the user
- // changes the language
- if (loaded) {
- return;
- }
- loaded = true;
+ // No need to run this one-time dialog again just because the user
+ // changes the language
+ if (loaded) {
+ return;
+ }
+ loaded = true;
- // Note that the following can load even if "noStorageOnLoad" is
- // set to false; to avoid any chance of storage, avoid this
- // extension! (and to avoid using any prior storage, set the
- // config option "noStorageOnLoad" to true).
- if (!forceStorage && (
- // If the URL has been explicitly set to always prompt the
- // user (e.g., so one can be pointed to a URL where one
- // can alter one's settings, say to prevent future storage)...
- storagePrompt === true ||
- (
- // ...or...if the URL at least doesn't explicitly prevent a
- // storage prompt (as we use for users who
- // don't want to set cookies at all but who don't want
- // continual prompts about it)...
- storagePrompt !== false &&
- // ...and this user hasn't previously indicated a desire for storage
- !document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)
- )
- // ...then show the storage prompt.
- )) {
- var options = [];
- if (storage) {
- options.unshift(
- {value: 'prefsAndContent', text: uiStrings.confirmSetStorage.storagePrefsAndContent},
- {value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefsOnly},
- {value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefsOrContent}
- );
- } else {
- options.unshift(
- {value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefs},
- {value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefs}
- );
- }
+ // Note that the following can load even if "noStorageOnLoad" is
+ // set to false; to avoid any chance of storage, avoid this
+ // extension! (and to avoid using any prior storage, set the
+ // config option "noStorageOnLoad" to true).
+ if (!forceStorage && (
+ // If the URL has been explicitly set to always prompt the
+ // user (e.g., so one can be pointed to a URL where one
+ // can alter one's settings, say to prevent future storage)...
+ storagePrompt === true ||
+ (
+ // ...or...if the URL at least doesn't explicitly prevent a
+ // storage prompt (as we use for users who
+ // don't want to set cookies at all but who don't want
+ // continual prompts about it)...
+ storagePrompt !== false &&
+ // ...and this user hasn't previously indicated a desire for storage
+ !document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)
+ )
+ // ...then show the storage prompt.
+ )) {
+ var options = [];
+ if (storage) {
+ options.unshift(
+ {value: 'prefsAndContent', text: uiStrings.confirmSetStorage.storagePrefsAndContent},
+ {value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefsOnly},
+ {value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefsOrContent}
+ );
+ } else {
+ options.unshift(
+ {value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefs},
+ {value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefs}
+ );
+ }
- // Hack to temporarily provide a wide and high enough dialog
- var oldContainerWidth = $('#dialog_container')[0].style.width,
- oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft,
- oldContentHeight = $('#dialog_content')[0].style.height,
- oldContainerHeight = $('#dialog_container')[0].style.height;
- $('#dialog_content')[0].style.height = '120px';
- $('#dialog_container')[0].style.height = '170px';
- $('#dialog_container')[0].style.width = '800px';
- $('#dialog_container')[0].style.marginLeft = '-400px';
+ // Hack to temporarily provide a wide and high enough dialog
+ var oldContainerWidth = $('#dialog_container')[0].style.width,
+ oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft,
+ oldContentHeight = $('#dialog_content')[0].style.height,
+ oldContainerHeight = $('#dialog_container')[0].style.height;
+ $('#dialog_content')[0].style.height = '120px';
+ $('#dialog_container')[0].style.height = '170px';
+ $('#dialog_container')[0].style.width = '800px';
+ $('#dialog_container')[0].style.marginLeft = '-400px';
- // Open select-with-checkbox dialog
- $.select(
- uiStrings.confirmSetStorage.message,
- options,
- function (pref, checked) {
- if (pref && pref !== 'noPrefsOrContent') {
- // Regardless of whether the user opted
- // to remember the choice (and move to a URL which won't
- // ask them again), we have to assume the user
- // doesn't even want to remember their not wanting
- // storage, so we don't set the cookie or continue on with
- // setting storage on beforeunload
- document.cookie = 'store=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'
- // If the URL was configured to always insist on a prompt, if
- // the user does indicate a wish to store their info, we
- // don't want ask them again upon page refresh so move
- // them instead to a URL which does not always prompt
- if (storagePrompt === true && checked) {
- replaceStoragePrompt();
- return;
- }
- } else { // The user does not wish storage (or cancelled, which we treat equivalently)
- removeStoragePrefCookie();
- if (pref && // If the user explicitly expresses wish for no storage
- emptyStorageOnDecline
- ) {
- emptyStorage();
- }
- if (pref && checked) {
- // Open a URL which won't set storage and won't prompt user about storage
- replaceStoragePrompt('false');
- return;
- }
- }
+ // Open select-with-checkbox dialog
+ $.select(
+ uiStrings.confirmSetStorage.message,
+ options,
+ function (pref, checked) {
+ if (pref && pref !== 'noPrefsOrContent') {
+ // Regardless of whether the user opted
+ // to remember the choice (and move to a URL which won't
+ // ask them again), we have to assume the user
+ // doesn't even want to remember their not wanting
+ // storage, so we don't set the cookie or continue on with
+ // setting storage on beforeunload
+ document.cookie = 'store=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'
+ // If the URL was configured to always insist on a prompt, if
+ // the user does indicate a wish to store their info, we
+ // don't want ask them again upon page refresh so move
+ // them instead to a URL which does not always prompt
+ if (storagePrompt === true && checked) {
+ replaceStoragePrompt();
+ return;
+ }
+ } else { // The user does not wish storage (or cancelled, which we treat equivalently)
+ removeStoragePrefCookie();
+ if (pref && // If the user explicitly expresses wish for no storage
+ emptyStorageOnDecline
+ ) {
+ emptyStorage();
+ }
+ if (pref && checked) {
+ // Open a URL which won't set storage and won't prompt user about storage
+ replaceStoragePrompt('false');
+ return;
+ }
+ }
- // Reset width/height of dialog (e.g., for use by Export)
- $('#dialog_container')[0].style.width = oldContainerWidth;
- $('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
- $('#dialog_content')[0].style.height = oldContentHeight;
- $('#dialog_container')[0].style.height = oldContainerHeight;
+ // Reset width/height of dialog (e.g., for use by Export)
+ $('#dialog_container')[0].style.width = oldContainerWidth;
+ $('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
+ $('#dialog_content')[0].style.height = oldContentHeight;
+ $('#dialog_container')[0].style.height = oldContainerHeight;
- // It should be enough to (conditionally) add to storage on
- // beforeunload, but if we wished to update immediately,
- // we might wish to try setting:
- // svgEditor.setConfig({noStorageOnLoad: true});
- // and then call:
- // svgEditor.loadContentAndPrefs();
+ // It should be enough to (conditionally) add to storage on
+ // beforeunload, but if we wished to update immediately,
+ // we might wish to try setting:
+ // svgEditor.setConfig({noStorageOnLoad: true});
+ // and then call:
+ // svgEditor.loadContentAndPrefs();
- // We don't check for noStorageOnLoad here because
- // the prompt gives the user the option to store data
- setupBeforeUnloadListener();
+ // We don't check for noStorageOnLoad here because
+ // the prompt gives the user the option to store data
+ setupBeforeUnloadListener();
- svgEditor.storagePromptClosed = true;
- },
- null,
- null,
- {
- label: uiStrings.confirmSetStorage.rememberLabel,
- checked: false,
- tooltip: uiStrings.confirmSetStorage.rememberTooltip
- }
- );
- } else if (!noStorageOnLoad || forceStorage) {
- setupBeforeUnloadListener();
- }
- }
- };
+ svgEditor.storagePromptClosed = true;
+ },
+ null,
+ null,
+ {
+ label: uiStrings.confirmSetStorage.rememberLabel,
+ checked: false,
+ tooltip: uiStrings.confirmSetStorage.rememberTooltip
+ }
+ );
+ } else if (!noStorageOnLoad || forceStorage) {
+ setupBeforeUnloadListener();
+ }
+ }
+ };
});
diff --git a/editor/extensions/ext-webappfind.js b/editor/extensions/ext-webappfind.js
index 456001b4..5f8104d9 100644
--- a/editor/extensions/ext-webappfind.js
+++ b/editor/extensions/ext-webappfind.js
@@ -10,58 +10,58 @@ Todos:
'use strict';
var pathID,
- saveMessage = 'webapp-save',
- readMessage = 'webapp-read',
- excludedMessages = [readMessage, saveMessage];
+ saveMessage = 'webapp-save',
+ readMessage = 'webapp-read',
+ excludedMessages = [readMessage, saveMessage];
window.addEventListener('message', function (e) {
- if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
- (!Array.isArray(e.data) || excludedMessages.indexOf(e.data[0]) > -1) // Validate format and avoid our post below
- ) {
- return;
- }
- var svgString,
- messageType = e.data[0];
- switch (messageType) {
- case 'webapp-view':
- // Populate the contents
- pathID = e.data[1];
+ if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
+ (!Array.isArray(e.data) || excludedMessages.indexOf(e.data[0]) > -1) // Validate format and avoid our post below
+ ) {
+ return;
+ }
+ var svgString,
+ messageType = e.data[0];
+ switch (messageType) {
+ case 'webapp-view':
+ // Populate the contents
+ pathID = e.data[1];
- svgString = e.data[2];
- svgEditor.loadFromString(svgString);
+ svgString = e.data[2];
+ svgEditor.loadFromString(svgString);
- /* if ($('#tool_save_file')) {
- $('#tool_save_file').disabled = false;
- } */
- break;
- case 'webapp-save-end':
- alert('save complete for pathID ' + e.data[1] + '!');
- break;
- default:
- throw new Error('Unexpected mode');
- }
+ /* if ($('#tool_save_file')) {
+ $('#tool_save_file').disabled = false;
+ } */
+ break;
+ case 'webapp-save-end':
+ alert('save complete for pathID ' + e.data[1] + '!');
+ break;
+ default:
+ throw new Error('Unexpected mode');
+ }
}, false);
window.postMessage([readMessage], window.location.origin !== 'null' ? window.location.origin : '*'); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
svgEditor.addExtension('WebAppFind', function () {
- return {
- name: 'WebAppFind',
- svgicons: svgEditor.curConfig.extPath + 'webappfind-icon.svg',
- buttons: [{
- id: 'webappfind_save', //
- type: 'app_menu',
- title: 'Save Image back to Disk',
- position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
- events: {
- click: function () {
- if (!pathID) { // Not ready yet as haven't received first payload
- return;
- }
- window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
- }
- }
- }]
- };
+ return {
+ name: 'WebAppFind',
+ svgicons: svgEditor.curConfig.extPath + 'webappfind-icon.svg',
+ buttons: [{
+ id: 'webappfind_save', //
+ type: 'app_menu',
+ title: 'Save Image back to Disk',
+ position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
+ events: {
+ click: function () {
+ if (!pathID) { // Not ready yet as haven't received first payload
+ return;
+ }
+ window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
+ }
+ }
+ }]
+ };
});
}());
diff --git a/editor/extensions/ext-xdomain-messaging.js b/editor/extensions/ext-xdomain-messaging.js
index cc7839bf..e34c974c 100644
--- a/editor/extensions/ext-xdomain-messaging.js
+++ b/editor/extensions/ext-xdomain-messaging.js
@@ -6,38 +6,38 @@
* in embedapi.js with a demo at embedapi.html
*/
svgEditor.addExtension('xdomain-messaging', function () {
- 'use strict';
- try {
- window.addEventListener('message', function (e) {
- // We accept and post strings for the sake of IE9 support
- if (typeof e.data !== 'string' || e.data.charAt() === '|') {
- return;
- }
- var cbid, name, args, message, allowedOrigins, data = JSON.parse(e.data);
- if (!data || typeof data !== 'object' || data.namespace !== 'svgCanvas') {
- return;
- }
- // The default is not to allow any origins, including even the same domain or if run on a file:// URL
- // See config-sample.js for an example of how to configure
- allowedOrigins = svgEditor.curConfig.allowedOrigins;
- if (allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1) {
- return;
- }
- cbid = data.id;
- name = data.name;
- args = data.args;
- message = {
- namespace: 'svg-edit',
- id: cbid
- };
- try {
- message.result = svgCanvas[name].apply(svgCanvas, args);
- } catch (err) {
- message.error = err.message;
- }
- e.source.postMessage(JSON.stringify(message), '*');
- }, false);
- } catch (err) {
- console.log('Error with xdomain message listener: ' + err);
- }
+ 'use strict';
+ try {
+ window.addEventListener('message', function (e) {
+ // We accept and post strings for the sake of IE9 support
+ if (typeof e.data !== 'string' || e.data.charAt() === '|') {
+ return;
+ }
+ var cbid, name, args, message, allowedOrigins, data = JSON.parse(e.data);
+ if (!data || typeof data !== 'object' || data.namespace !== 'svgCanvas') {
+ return;
+ }
+ // The default is not to allow any origins, including even the same domain or if run on a file:// URL
+ // See config-sample.js for an example of how to configure
+ allowedOrigins = svgEditor.curConfig.allowedOrigins;
+ if (allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1) {
+ return;
+ }
+ cbid = data.id;
+ name = data.name;
+ args = data.args;
+ message = {
+ namespace: 'svg-edit',
+ id: cbid
+ };
+ try {
+ message.result = svgCanvas[name].apply(svgCanvas, args);
+ } catch (err) {
+ message.error = err.message;
+ }
+ e.source.postMessage(JSON.stringify(message), '*');
+ }, false);
+ } catch (err) {
+ console.log('Error with xdomain message listener: ' + err);
+ }
});
diff --git a/editor/extensions/imagelib/index.js b/editor/extensions/imagelib/index.js
index 24d90668..d65724f7 100644
--- a/editor/extensions/imagelib/index.js
+++ b/editor/extensions/imagelib/index.js
@@ -1,51 +1,51 @@
/* eslint-disable no-var */
/* globals $ */
$('a').click(function () {
- 'use strict';
- var metaStr;
- var href = this.href;
- var target = window.parent;
- // Convert Non-SVG images to data URL first
- // (this could also have been done server-side by the library)
- if (this.href.indexOf('.svg') === -1) {
- metaStr = JSON.stringify({
- name: $(this).text(),
- id: href
- });
- target.postMessage(metaStr, '*');
+ 'use strict';
+ var metaStr;
+ var href = this.href;
+ var target = window.parent;
+ // Convert Non-SVG images to data URL first
+ // (this could also have been done server-side by the library)
+ if (this.href.indexOf('.svg') === -1) {
+ metaStr = JSON.stringify({
+ name: $(this).text(),
+ id: href
+ });
+ target.postMessage(metaStr, '*');
- var img = new Image();
- img.onload = function () {
- var canvas = document.createElement('canvas');
- canvas.width = this.width;
- canvas.height = this.height;
- // load the raster image into the canvas
- canvas.getContext('2d').drawImage(this, 0, 0);
- // retrieve the data: URL
- var dataurl;
- try {
- dataurl = canvas.toDataURL();
- } catch (err) {
- // This fails in Firefox with file:// URLs :(
- alert('Data URL conversion failed: ' + err);
- dataurl = '';
- }
- target.postMessage('|' + href + '|' + dataurl, '*');
- };
- img.src = href;
- } else {
- // Send metadata (also indicates file is about to be sent)
- metaStr = JSON.stringify({
- name: $(this).text(),
- id: href
- });
- target.postMessage(metaStr, '*');
- // Do ajax request for image's href value
- $.get(href, function (data) {
- data = '|' + href + '|' + data;
- // This is where the magic happens!
- target.postMessage(data, '*');
- }, 'html'); // 'html' is necessary to keep returned data as a string
- }
- return false;
+ var img = new Image();
+ img.onload = function () {
+ var canvas = document.createElement('canvas');
+ canvas.width = this.width;
+ canvas.height = this.height;
+ // load the raster image into the canvas
+ canvas.getContext('2d').drawImage(this, 0, 0);
+ // retrieve the data: URL
+ var dataurl;
+ try {
+ dataurl = canvas.toDataURL();
+ } catch (err) {
+ // This fails in Firefox with file:// URLs :(
+ alert('Data URL conversion failed: ' + err);
+ dataurl = '';
+ }
+ target.postMessage('|' + href + '|' + dataurl, '*');
+ };
+ img.src = href;
+ } else {
+ // Send metadata (also indicates file is about to be sent)
+ metaStr = JSON.stringify({
+ name: $(this).text(),
+ id: href
+ });
+ target.postMessage(metaStr, '*');
+ // Do ajax request for image's href value
+ $.get(href, function (data) {
+ data = '|' + href + '|' + data;
+ // This is where the magic happens!
+ target.postMessage(data, '*');
+ }, 'html'); // 'html' is necessary to keep returned data as a string
+ }
+ return false;
});