- Breaking change: Rename config file to svgedit-config-iife.js (or for the module version, svgedit-config-es.js);

also expect one directory higher; incorporates #207 (@iuyiuy)
- Breaking change: Separate `extIconsPath` from `extPath` (not copying over icons)
- Breaking change: Don't reference `custom.css` in HTML; can instead be referenced in JavaScript through
    the config file (provided in `svgedit-config-sample-iife.js`/`svgedit-config-sample-es.js` as `svgedit-custom.css` for
    better namespacing); incorporates #207 (@iuyiuy)
- Breaking change: Remove minified jgraduate/spinbtn files (minified within Rollup routine)
- Fix: Zoom when scrolled; incorporates #169 (@AndrolGenhald), adapting for conventions; also allow avoidance when shift key pressed
- Fix: Update Atom feed reference in HTML
- Fixes related to recent commits: Some path and method name fixes needed, function order, missing methods, variable scope declaration, no need for DOMContentLoaded listeners in modules, switch back to non-default export, avoid trimming nullish, deal with mock tests, fix `math.matrixMultiply`, use jquery-svg where needed for array/SVG attributes; add babel-polyfill and defer script to imagelib; other misc. fixes
- Enhancement: Move config-sample.js out of `editor` directory
- Enhancement: For `callback`-style extensions, also provide config object; add following
   to that object: buildCanvgCallback, canvg, decode64, encode64, executeAfterLoads, getTypeMap, isChrome, ieIE, NS, text2xml
- Enhancement: Complete ES6 modules work (extensions, locales, tests), along with Babel;
    make Node build routine for converting modular source to non-modular,
    use `loadStylesheets` for modular stylehsheet defining (but parallel loading);
- Enhancement: Add `stylesheets` config for modular but parallel stylesheet loading with `@default` option for simple inclusion/exclusion of defaults (if not going with default).
- Refactoring: Clean up `svg-editor.html`: consistent indents; avoid extra lbs, avoid long lines
- Refactoring: Avoid embedded API adding inline JavaScript listener
- Refactoring: Move layers and context code to `draw.js`
- Refactoring: Move `pathActions` from `svgcanvas.js` (though preserve aliases to these methods on `canvas`) and `convertPath` from `svgutils.js` to `path.js`
- Refactoring: Move `getStrokedBBox` from `svgcanvas.js` (while keeping an alias) to `svgutils.js` (as `getStrokedBBoxDefaultVisible` to avoid conflict with existing)
- Docs: Remove "dependencies" comments in code except where summarizing role of jQuery or a non-obvious dependency
- Refactoring/Linting: Enfore `no-extra-semi` and `quote-props` rules
- Refactoring: Further avoidance of quotes on properties (as possible)
- Refactoring: Use `class` in place of functions where intended as classes
- Refactoring: Consistency and granularity in extensions imports
- Testing: Update QUnit to 2.6.1 (node_modules) and Sinon to 5.0.8 (and add sinon-test at 2.1.3) and enforce eslint-plugin-qunit linting rules; update custom extensions
- Testing: Add node-static for automating (and accessing out-of-directory contents)
- Testing: Avoid HTML attributes for styling
- Testing: Add npm `test` script
- Testing: Comment out unused jQuery SVG test
- Testing: Add test1 and svgutils_performance_test to all tests page
- Testing: Due apparently to Path having not been a formal class, the test was calling it without `new`; refactored now with sufficient mock data to take into account it is a class
- npm: Update devDeps
- npm: Add html modules and config build to test script
This commit is contained in:
Brett Zamir
2018-05-22 18:03:16 +08:00
parent ae2394f086
commit 8c9e40d349
260 changed files with 100462 additions and 13388 deletions

View File

@@ -124,6 +124,7 @@ rect.setAttribute('x', 0.1);
const crect = rect.cloneNode(false);
const retValue = (!crect.getAttribute('x').includes(','));
if (!retValue) {
// Todo: i18nize or remove
$.alert('NOTE: This version of Opera is known to contain bugs in SVG-edit.\n' +
'Please upgrade to the <a href="http://opera.com">latest version</a> in which the problems have been fixed.');
}
@@ -136,7 +137,7 @@ rect.setAttribute('style', 'vector-effect:non-scaling-stroke');
return rect.style.vectorEffect === 'non-scaling-stroke';
}());
const supportsNativeSVGTransformLists_ = (function () {
let supportsNativeSVGTransformLists_ = (function () {
const rect = document.createElementNS(NS.SVG, 'rect');
const rxform = rect.transform.baseVal;
const t1 = svg.createSVGTransform();
@@ -176,3 +177,8 @@ export const supportsEditableText = () => supportsEditableText_;
export const supportsGoodDecimals = () => supportsGoodDecimals_;
export const supportsNonScalingStroke = () => supportsNonScalingStroke_;
export const supportsNativeTransformLists = () => supportsNativeSVGTransformLists_;
// Using for unit testing
export const disableSupportsNativeTransformLists = () => {
supportsNativeSVGTransformLists_ = false;
};

View File

@@ -65,7 +65,7 @@ export default function canvg (target, s, opts) {
// load from url
svg.load(ctx, s);
}
};
}
function build (opts) {
const svg = {opts};
@@ -76,7 +76,7 @@ function build (opts) {
svg.log = function (msg) {};
if (svg.opts.log === true && typeof console !== 'undefined') {
svg.log = function (msg) { console.log(msg); };
};
}
// globals
svg.init = function (ctx) {
@@ -150,17 +150,17 @@ function build (opts) {
// text extensions
// get the text baseline
const textBaselineMapping = {
'baseline': 'alphabetic',
baseline: 'alphabetic',
'before-edge': 'top',
'text-before-edge': 'top',
'middle': 'middle',
'central': 'middle',
middle: 'middle',
central: 'middle',
'after-edge': 'bottom',
'text-after-edge': 'bottom',
'ideographic': 'ideographic',
'alphabetic': 'alphabetic',
'hanging': 'hanging',
'mathematical': 'alphabetic'
ideographic: 'ideographic',
alphabetic: 'alphabetic',
hanging: 'hanging',
mathematical: 'alphabetic'
};
svg.Property = class Property {

View File

@@ -1,145 +0,0 @@
// DO NOT EDIT THIS FILE!
// THIS FILE IS JUST A SAMPLE; TO APPLY, YOU MUST
// CREATE A NEW FILE config.js AND ADD CONTENTS
// SUCH AS SHOWN BELOW INTO THAT FILE.
/*
The config.js file is intended for the setting of configuration or
preferences which must run early on; if this is not needed, it is
recommended that you create an extension instead (for greater
reusability and modularity).
*/
// CONFIG AND EXTENSION SETTING
/*
See defaultConfig and defaultExtensions in svg-editor.js for a list
of possible configuration settings.
See svg-editor.js for documentation on using setConfig().
*/
import svgEditor from './svg-editor.js';
// 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,
});
svgEditor.setConfig({
/*
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
});
// 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
});
// PREF CHANGES
/**
setConfig() can also be used to set preferences in addition to
configuration (see defaultPrefs in svg-editor.js for a list of
possible settings), but at least if you are using ext-storage.js
to store preferences, it will probably be better to let your
users control these.
As with configuration, one may use allowInitialUserOverride, but
in the case of preferences, any previously stored preferences
will also thereby be enabled to override this setting (and at a
higher priority than any URL preference setting overrides).
Failing to use allowInitialUserOverride will ensure preferences
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
});
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}
);

View File

@@ -16,7 +16,7 @@ let contextMenuExtensions = {};
const menuItemIsValid = function (menuItem) {
return menuItem && menuItem.id && menuItem.label && menuItem.action && typeof menuItem.action === 'function';
};
export const addContextMenuItem = function (menuItem) {
export const add = 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');
@@ -31,10 +31,10 @@ export const addContextMenuItem = function (menuItem) {
contextMenuExtensions[menuItem.id] = menuItem;
// TODO: Need to consider how to handle custom enable/disable behavior
};
export const hasCustomMenuItemHandler = function (handlerKey) {
export const hasCustomHandler = function (handlerKey) {
return Boolean(contextMenuExtensions[handlerKey]);
};
export const getCustomMenuItemHandler = function (handlerKey) {
export const getCustomHandler = function (handlerKey) {
return contextMenuExtensions[handlerKey].action;
};
const injectExtendedContextMenuItemIntoDom = function (menuItem) {

View File

@@ -14,7 +14,7 @@
// This plugin is dual-licensed under the GNU General Public License
// and the MIT License and is copyright A Beautiful Site, LLC.
//
import {isMac} from './browser.js';
import {isMac} from '../browser.js';
export default function ($) {
const win = $(window);
@@ -125,7 +125,7 @@ export default function ($) {
// Disable text selection
if ($.browser.mozilla) {
$('#' + o.menu).each(function () { $(this).css({'MozUserSelect': 'none'}); });
$('#' + o.menu).each(function () { $(this).css({MozUserSelect: 'none'}); });
} else if ($.browser.msie) {
$('#' + o.menu).each(function () { $(this).bind('selectstart.disableTextSelect', function () { return false; }); });
} else {

View File

@@ -6,9 +6,6 @@
*
*/
// Dependencies:
// 1) jquery.min.js
import './pathseg.js';
import {
snapToGrid, assignAttributes, getBBox, getRefElem, findDefs

View File

@@ -7,10 +7,18 @@
* Copyright(c) 2011 Jeff Schiller
*/
import Layer from './layer.js';
import HistoryRecordingService from './historyrecording.js';
import {NS} from './svgedit.js';
import {isOpera} from './browser.js';
import {copyElem as utilCopyElem} from './svgutils.js';
import Layer from './layer.js';
import {
toXml, getElem,
copyElem as utilCopyElem
} from './svgutils.js';
import {
BatchCommand, RemoveElementCommand, MoveElementCommand, ChangeElementCommand
} from './history.js';
const $ = jQuery;
@@ -22,6 +30,17 @@ const RandomizeModes = {
NEVER_RANDOMIZE: 2
};
let randIds = RandomizeModes.LET_DOCUMENT_DECIDE;
// Array with current disabled elements (for in-group editing)
let disabledElems = [];
/**
* Get a HistoryRecordingService.
* @param {svgedit.history.HistoryRecordingService=} hrService - if exists, return it instead of creating a new service.
* @returns {svgedit.history.HistoryRecordingService}
*/
function historyRecordingService (hrService) {
return hrService || new HistoryRecordingService(canvas_.undoMgr);
}
/**
* Find the layer name in a group element.
@@ -652,3 +671,247 @@ export const randomizeIds = function (enableRandomization, currentDrawing) {
currentDrawing.clearNonce();
}
};
// Layer API Functions
// Group: Layers
let canvas_;
export const init = function (canvas) {
canvas_ = canvas;
};
// Updates layer system
export const identifyLayers = function () {
leaveContext();
canvas_.getCurrentDrawing().identifyLayers();
};
/**
* Creates a new top-level layer in the drawing with the given name, sets the current layer
* to it, and then clears the selection. This function then calls the 'changed' handler.
* This is an undoable action.
* @param name - The given name
* @param hrService
*/
export const createLayer = function (name, hrService) {
const newLayer = canvas_.getCurrentDrawing().createLayer(
name,
historyRecordingService(hrService)
);
canvas_.clearSelection();
canvas_.call('changed', [newLayer]);
};
/**
* Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents
* to it, and then clears the selection. This function then calls the 'changed' handler.
* This is an undoable action.
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
*/
export const cloneLayer = function (name, hrService) {
// Clone the current layer and make the cloned layer the new current layer
const newLayer = canvas_.getCurrentDrawing().cloneLayer(name, historyRecordingService(hrService));
canvas_.clearSelection();
leaveContext();
canvas_.call('changed', [newLayer]);
};
/**
* Deletes the current layer from the drawing and then clears the selection. This function
* then calls the 'changed' handler. This is an undoable action.
*/
export const deleteCurrentLayer = function () {
let currentLayer = canvas_.getCurrentDrawing().getCurrentLayer();
const {nextSibling} = currentLayer;
const parent = currentLayer.parentNode;
currentLayer = canvas_.getCurrentDrawing().deleteCurrentLayer();
if (currentLayer) {
const batchCmd = new BatchCommand('Delete Layer');
// store in our Undo History
batchCmd.addSubCommand(new RemoveElementCommand(currentLayer, nextSibling, parent));
canvas_.addCommandToHistory(batchCmd);
canvas_.clearSelection();
canvas_.call('changed', [parent]);
return true;
}
return false;
};
/**
* Sets the current layer. If the name is not a valid layer name, then this function returns
* false. Otherwise it returns true. This is not an undo-able action.
* @param name - The name of the layer you want to switch to.
*
* @returns true if the current layer was switched, otherwise false
*/
export const setCurrentLayer = function (name) {
const result = canvas_.getCurrentDrawing().setCurrentLayer(toXml(name));
if (result) {
canvas_.clearSelection();
}
return result;
};
/**
* Renames the current layer. If the layer name is not valid (i.e. unique), then this function
* does nothing and returns false, otherwise it returns true. This is an undo-able action.
*
* @param newname - the new name you want to give the current layer. This name must be unique
* among all layer names.
* @returns {Boolean} Whether the rename succeeded
*/
export const renameCurrentLayer = function (newname) {
const drawing = canvas_.getCurrentDrawing();
const layer = drawing.getCurrentLayer();
if (layer) {
const result = drawing.setCurrentLayerName(newname, historyRecordingService());
if (result) {
canvas_.call('changed', [layer]);
return true;
}
}
return false;
};
/**
* Changes the position of the current layer to the new value. If the new index is not valid,
* this function does nothing and returns false, otherwise it returns true. This is an
* undo-able action.
* @param newpos - The zero-based index of the new position of the layer. This should be between
* 0 and (number of layers - 1)
*
* @returns {Boolean} true if the current layer position was changed, false otherwise.
*/
export const setCurrentLayerPosition = function (newpos) {
const drawing = canvas_.getCurrentDrawing();
const result = drawing.setCurrentLayerPosition(newpos);
if (result) {
canvas_.addCommandToHistory(new MoveElementCommand(result.currentGroup, result.oldNextSibling, canvas_.getSVGContent()));
return true;
}
return false;
};
/**
* Sets the visibility of the layer. If the layer name is not valid, this function return
* false, otherwise it returns true. This is an undo-able action.
* @param layername - The name of the layer to change the visibility
* @param {Boolean} bVisible - Whether the layer should be visible
* @returns {Boolean} true if the layer's visibility was set, false otherwise
*/
export const setLayerVisibility = function (layername, bVisible) {
const drawing = canvas_.getCurrentDrawing();
const prevVisibility = drawing.getLayerVisibility(layername);
const layer = drawing.setLayerVisibility(layername, bVisible);
if (layer) {
const oldDisplay = prevVisibility ? 'inline' : 'none';
canvas_.addCommandToHistory(new ChangeElementCommand(layer, {display: oldDisplay}, 'Layer Visibility'));
} else {
return false;
}
if (layer === drawing.getCurrentLayer()) {
canvas_.clearSelection();
canvas_.pathActions.clear();
}
// call('changed', [selected]);
return true;
};
/**
* Moves the selected elements to layername. If the name is not a valid layer name, then false
* is returned. Otherwise it returns true. This is an undo-able action.
*
* @param layername - The name of the layer you want to which you want to move the selected elements
* @returns {Boolean} Whether the selected elements were moved to the layer.
*/
export const moveSelectedToLayer = function (layername) {
// find the layer
const drawing = canvas_.getCurrentDrawing();
const layer = drawing.getLayerByName(layername);
if (!layer) { return false; }
const batchCmd = new BatchCommand('Move Elements to Layer');
// loop for each selected element and move it
const selElems = canvas_.getSelectedElements();
let i = selElems.length;
while (i--) {
const elem = selElems[i];
if (!elem) { continue; }
const oldNextSibling = elem.nextSibling;
// TODO: this is pretty brittle!
const oldLayer = elem.parentNode;
layer.appendChild(elem);
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldLayer));
}
canvas_.addCommandToHistory(batchCmd);
return true;
};
export const mergeLayer = function (hrService) {
canvas_.getCurrentDrawing().mergeLayer(historyRecordingService(hrService));
canvas_.clearSelection();
leaveContext();
canvas_.changeSvgcontent();
};
export const mergeAllLayers = function (hrService) {
canvas_.getCurrentDrawing().mergeAllLayers(historyRecordingService(hrService));
canvas_.clearSelection();
leaveContext();
canvas_.changeSvgcontent();
};
// Return from a group context to the regular kind, make any previously
// disabled elements enabled again
export const leaveContext = function () {
const len = disabledElems.length;
if (len) {
for (let i = 0; i < len; i++) {
const elem = disabledElems[i];
const orig = canvas_.elData(elem, 'orig_opac');
if (orig !== 1) {
elem.setAttribute('opacity', orig);
} else {
elem.removeAttribute('opacity');
}
elem.setAttribute('style', 'pointer-events: inherit');
}
disabledElems = [];
canvas_.clearSelection(true);
canvas_.call('contextset', null);
}
canvas_.setCurrentGroup(null);
};
// Set the current context (for in-group editing)
export const setContext = function (elem) {
leaveContext();
if (typeof elem === 'string') {
elem = getElem(elem);
}
// Edit inside this group
canvas_.setCurrentGroup(elem);
// Disable other elements
$(elem).parentsUntil('#svgcontent').andSelf().siblings().each(function () {
const opac = this.getAttribute('opacity') || 1;
// Store the original's opacity
canvas_.elData(this, 'orig_opac', opac);
this.setAttribute('opacity', opac * 0.33);
this.setAttribute('style', 'pointer-events: none');
disabledElems.push(this);
});
canvas_.clearSelection();
canvas_.call('contextset', canvas_.getCurrentGroup());
};
export {Layer};

View File

@@ -1,80 +1,73 @@
/* globals jQuery */
import EmbeddedSVGEdit from './embedapi.js';
import svgEditor from './svg-editor.js';
const $ = jQuery;
// Todo: Add iframe load listener
var initEmbed;
let svgCanvas = null;
// Todo: Get rid of frame.contentWindow dependencies so can be more
// easily adjusted to work cross-domain
$(function () {
let svgCanvas = null;
initEmbed = function () {
svgCanvas = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new, load, save, etc. from the host document
const doc = frame.contentDocument || frame.contentWindow.document;
const 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 () {
const svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/></g></svg>';
svgCanvas.setSvgString(svgexample);
}
function loadSvg () {
const svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/></g></svg>';
svgCanvas.setSvgString(svgexample);
}
function saveSvg () {
svgCanvas.getSvgString()(handleSvgData);
}
function saveSvg () {
svgCanvas.getSvgString()(handleSvgData);
}
function exportPNG () {
const str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
function exportPNG () {
const str = svgEditor.uiStrings.notification.loadingImage;
const exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
svgCanvas.rasterExport('PNG', null, exportWindow.name);
}
function exportPDF () {
const 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;
*/
const exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
svgCanvas.exportPDF(exportWindow.name);
}
// Add event handlers
$('#load').click(loadSvg);
$('#save').click(saveSvg);
$('#exportPNG').click(exportPNG);
$('#exportPDF').click(exportPDF);
$('body').append(
$('<iframe src="svg-editor.html?extensions=ext-xdomain-messaging.js' +
window.location.href.replace(/\?(.*)$/, '&$1') + // Append arguments to this file onto the iframe
'" width="900px" height="600px" id="svgedit" onload="initEmbed();"></iframe>'
)
const exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
const frame = document.getElementById('svgedit');
svgCanvas.rasterExport('PNG', null, exportWindow.name);
}
function exportPDF () {
const str = 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;
*/
const exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
svgCanvas.exportPDF(exportWindow.name);
}
// Add event handlers
$('#load').click(loadSvg);
$('#save').click(saveSvg);
$('#exportPNG').click(exportPNG);
$('#exportPDF').click(exportPDF);
const iframe = $('<iframe src="svg-editor.html?extensions=ext-xdomain-messaging.js' +
window.location.href.replace(/\?(.*)$/, '&$1') + // Append arguments to this file onto the iframe
'" width="900px" height="600px" id="svgedit" onload="initEmbed();"></iframe>'
);
iframe[0].addEventListener('load', function () {
svgCanvas = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new, load, save, etc. from the host document
const doc = frame.contentDocument || frame.contentWindow.document;
const mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
});
$('body').append(iframe);
const frame = document.getElementById('svgedit');

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-arrows.js
*
@@ -7,18 +7,19 @@
* Copyright(c) 2010 Alexis Deveria
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('Arrows', function (S) {
const svgCanvas = svgEditor.canvas;
const $ = jQuery;
const // {svgcontent} = S,
addElem = S.addSvgElementFromJson,
{nonce} = S,
langList = {
'en': [
{'id': 'arrow_none', 'textContent': 'No arrow'}
en: [
{id: 'arrow_none', textContent: 'No arrow'}
],
'fr': [
{'id': 'arrow_none', 'textContent': 'Sans flèche'}
fr: [
{id: 'arrow_none', textContent: 'Sans flèche'}
]
},
prefix = 'se_arrow_';

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor */
/* globals jQuery */
/*
* ext-closepath.js
*
@@ -7,7 +7,8 @@
* Copyright(c) 2010 Jeff Schiller
*
*/
// import './pathseg.js';
import '../pathseg.js';
import svgEditor from '../svg-editor.js';
// This extension adds a simple button to the contextual panel for paths
// The button toggles whether the path is open or closed
@@ -46,7 +47,7 @@ svgEditor.addExtension('ClosePath', function () {
return {
name: 'ClosePath',
svgicons: svgEditor.curConfig.extPath + 'closepath_icons.svg',
svgicons: svgEditor.curConfig.extIconsPath + 'closepath_icons.svg',
buttons: [{
id: 'tool_openpath',
type: 'context',

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-connector.js
*
@@ -8,8 +8,10 @@
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('Connector', function (S) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
const {svgroot, getNextId, getElem, curConfig} = S,
addElem = S.addSvgElementFromJson,
selManager = S.selectorManager,
@@ -29,11 +31,11 @@ svgEditor.addExtension('Connector', function (S) {
selElems = [];
const langList = {
'en': [
{'id': 'mode_connect', 'title': 'Connect two objects'}
en: [
{id: 'mode_connect', title: 'Connect two objects'}
],
'fr': [
{'id': 'mode_connect', 'title': 'Connecter deux objets'}
fr: [
{id: 'mode_connect', title: 'Connecter deux objets'}
]
};
@@ -360,15 +362,15 @@ svgEditor.addExtension('Connector', function (S) {
started = true;
curLine = addElem({
'element': 'polyline',
'attr': {
'id': getNextId(),
'points': (x + ',' + y + ' ' + x + ',' + y + ' ' + startX + ',' + startY),
'stroke': '#' + curConfig.initStroke.color,
element: 'polyline',
attr: {
id: getNextId(),
points: (x + ',' + y + ' ' + x + ',' + y + ' ' + startX + ',' + startY),
stroke: '#' + curConfig.initStroke.color,
'stroke-width': (!startElem.stroke_width || startElem.stroke_width === 0) ? curConfig.initStroke.width : startElem.stroke_width,
'fill': 'none',
'opacity': curConfig.initStroke.opacity,
'style': 'pointer-events:none'
fill: 'none',
opacity: curConfig.initStroke.opacity,
style: 'pointer-events:none'
}
});
elData(curLine, 'start_bb', bb);
@@ -555,14 +557,14 @@ svgEditor.addExtension('Connector', function (S) {
const midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
const pline = addElem({
'element': 'polyline',
'attr': {
'points': (x1 + ',' + y1 + midPt + x2 + ',' + y2),
'stroke': elem.getAttribute('stroke'),
element: 'polyline',
attr: {
points: (x1 + ',' + y1 + midPt + x2 + ',' + y2),
stroke: elem.getAttribute('stroke'),
'stroke-width': elem.getAttribute('stroke-width'),
'marker-mid': mid,
'fill': 'none',
'opacity': elem.getAttribute('opacity') || 1
fill: 'none',
opacity: elem.getAttribute('opacity') || 1
}
});
$(elem).after(pline).remove();

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit */
/* globals jQuery */
/*
* ext-eyedropper.js
*
@@ -8,18 +8,13 @@
*
*/
// Dependencies:
// 1) jQuery
// 2) history.js
// 3) svg_editor.js
// 4) svgcanvas.js
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('eyedropper', function (S) {
const $ = jQuery;
const // {svgcontent} = S,
const {ChangeElementCommand} = S, // , svgcontent,
// svgdoc = S.svgroot.parentNode.ownerDocument,
svgCanvas = svgEditor.canvas,
{ChangeElementCommand} = svgedit.history,
addToHistory = function (cmd) { svgCanvas.undoMgr.addCommandToHistory(cmd); },
currentStyle = {
fillPaint: 'red', fillOpacity: 1.0,
@@ -61,7 +56,7 @@ svgEditor.addExtension('eyedropper', function (S) {
return {
name: 'eyedropper',
svgicons: svgEditor.curConfig.extPath + 'eyedropper-icon.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'eyedropper-icon.xml',
buttons: [{
id: 'tool_eyedropper',
type: 'mode',

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit, svgCanvas */
/* globals jQuery */
/*
* ext-foreignobject.js
*
@@ -9,11 +9,13 @@
*
*/
import {NS} from './svgedit.js';
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('foreignObject', function (S) {
const {text2xml, NS} = S;
const $ = jQuery;
const Utils = svgedit.utilities,
const svgCanvas = svgEditor.canvas;
const
// {svgcontent} = S,
// addElem = S.addSvgElementFromJson,
svgdoc = S.svgroot.parentNode.ownerDocument;
@@ -56,7 +58,7 @@ svgEditor.addExtension('foreignObject', function (S) {
const elt = selElems[0];
try {
// convert string into XML document
const newDoc = Utils.text2xml('<svg xmlns="' + NS.SVG + '" xmlns:xlink="' + NS.XLINK + '">' + xmlString + '</svg>');
const newDoc = text2xml('<svg xmlns="' + NS.SVG + '" xmlns:xlink="' + NS.XLINK + '">' + xmlString + '</svg>');
// run it through our sanitizer to remove anything we do not support
S.sanitizeSvg(newDoc.documentElement);
elt.parentNode.replaceChild(svgdoc.importNode(newDoc.documentElement.firstChild, true), elt);
@@ -91,7 +93,7 @@ svgEditor.addExtension('foreignObject', function (S) {
return {
name: 'foreignObject',
svgicons: svgEditor.curConfig.extPath + 'foreignobject-icons.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'foreignobject-icons.xml',
buttons: [{
id: 'tool_foreign',
type: 'mode',
@@ -194,15 +196,15 @@ svgEditor.addExtension('foreignObject', function (S) {
if (svgCanvas.getMode() === 'foreign') {
started = true;
newFO = S.addSvgElementFromJson({
'element': 'foreignObject',
'attr': {
'x': opts.start_x,
'y': opts.start_y,
'id': S.getNextId(),
element: 'foreignObject',
attr: {
x: opts.start_x,
y: opts.start_y,
id: S.getNextId(),
'font-size': 16, // cur_text.font_size,
'width': '48',
'height': '20',
'style': 'pointer-events:inherit'
width: '48',
height: '20',
style: 'pointer-events:inherit'
}
});
const m = svgdoc.createElementNS(NS.MATH, 'math');

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-grid.js
*
@@ -9,20 +9,16 @@
*
*/
// Dependencies:
// 1) units.js
// 2) everything else
import svgEditor from '../svg-editor.js';
import {NS} from './svgedit.js';
import {getTypeMap} from './units.js';
svgEditor.addExtension('view_grid', function () {
svgEditor.addExtension('view_grid', function ({NS, getTypeMap}) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
const svgdoc = document.getElementById('svgcanvas').ownerDocument,
{assignAttributes} = svgCanvas,
hcanvas = document.createElement('canvas'),
canvBG = $('#canvasBackground'),
units = getTypeMap(),
units = getTypeMap(), // Assumes prior `init()` call on `units.js` module
intervals = [0.01, 0.1, 1, 10, 100, 1000];
let showGrid = svgEditor.curConfig.showGrid || false;
@@ -136,7 +132,7 @@ svgEditor.addExtension('view_grid', function () {
}
return {
name: 'view_grid',
svgicons: svgEditor.curConfig.extPath + 'grid-icon.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'grid-icon.xml',
zoomChanged (zoom) {
if (showGrid) { updateGrid(zoom); }

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-helloworld.js
*
@@ -13,14 +13,15 @@
the left panel. Clicking on the button, and then the canvas will show the
user the point on the canvas that was clicked on.
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('Hello World', function () {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
return {
name: 'Hello World',
// For more notes on how to make an icon file, see the source of
// the helloworld-icon.xml
svgicons: svgEditor.curConfig.extPath + 'helloworld-icon.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'helloworld-icon.xml',
// Multiple buttons can be added in this array
buttons: [{

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit, svgCanvas */
/* globals jQuery */
/*
* ext-imagelib.js
*
@@ -7,10 +7,11 @@
* Copyright(c) 2010 Alexis Deveria
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('imagelib', function () {
svgEditor.addExtension('imagelib', function ({decode64}) {
const $ = jQuery;
const {uiStrings} = svgEditor;
const {uiStrings, canvas: svgCanvas} = svgEditor;
$.extend(uiStrings, {
imagelib: {
@@ -22,10 +23,15 @@ svgEditor.addExtension('imagelib', function () {
}
});
const modularVersion = !('svgEditor' in window) ||
!window.svgEditor ||
window.svgEditor.modules !== false;
const imgLibs = [
{
name: 'Demo library (local)',
url: svgEditor.curConfig.extPath + 'imagelib/index.html',
url: svgEditor.curConfig.extPath +
'imagelib/index' + (modularVersion ? '-es' : '') + '.html',
description: 'Demonstration library for SVG-edit on this server'
},
{
@@ -46,14 +52,14 @@ svgEditor.addExtension('imagelib', function () {
function importImage (url) {
const newImage = svgCanvas.addSvgElementFromJson({
'element': 'image',
'attr': {
'x': 0,
'y': 0,
'width': 0,
'height': 0,
'id': svgCanvas.getNextId(),
'style': 'pointer-events:inherit'
element: 'image',
attr: {
x: 0,
y: 0,
width: 0,
height: 0,
id: svgCanvas.getNextId(),
style: 'pointer-events:inherit'
}
});
svgCanvas.clearSelection();
@@ -142,7 +148,7 @@ svgEditor.addExtension('imagelib', function () {
if (response.startsWith('data:image/svg+xml')) {
const pre = 'data:image/svg+xml;base64,';
const src = response.substring(pre.length);
response = svgedit.utilities.decode64(src);
response = decode64(src);
svgStr = true;
break;
} else if (response.startsWith('data:image/')) {
@@ -354,16 +360,16 @@ svgEditor.addExtension('imagelib', function () {
cancel.prepend($.getSvgIcon('cancel', true));
back.prepend($.getSvgIcon('tool_imagelib', true));
$.each(imgLibs, function (i, opts) {
$.each(imgLibs, function (i, {name, url, description}) {
$('<li>')
.appendTo(libOpts)
.text(opts.name)
.text(name)
.on('click touchend', function () {
frame.attr('src', opts.url).show();
header.text(opts.name);
frame.attr('src', url).show();
header.text(name);
libOpts.hide();
back.show();
}).append('<span>' + opts.description + '</span>');
}).append(`<span>${description}</span>`);
});
} else {
$('#imgbrowse_holder').show();
@@ -371,7 +377,7 @@ svgEditor.addExtension('imagelib', function () {
}
return {
svgicons: svgEditor.curConfig.extPath + 'ext-imagelib.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'ext-imagelib.xml',
buttons: [{
id: 'tool_imagelib',
type: 'app_menu', // _flyout

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-markers.js
*
@@ -30,9 +30,10 @@
* add support for dimension extension lines
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('Markers', function (S) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
const // {svgcontent} = S,
addElem = S.addSvgElementFromJson;
const mtypes = ['start', 'mid', 'end'];
@@ -51,7 +52,7 @@ svgEditor.addExtension('Markers', function (S) {
rightarrow:
{element: 'path', attr: {d: 'M100,50 L0,90 L30,50 L0,10 Z'}},
textmarker:
{element: 'text', attr: {x: 0, y: 0, 'stroke-width': 0, 'stroke': 'none', 'font-size': 75, 'font-family': 'serif', 'text-anchor': 'left',
{element: 'text', attr: {x: 0, y: 0, 'stroke-width': 0, stroke: 'none', 'font-size': 75, 'font-family': 'serif', 'text-anchor': 'left',
'xml:space': 'preserve'}},
forwardslash:
{element: 'path', attr: {d: 'M30,100 L70,0'}},
@@ -72,7 +73,7 @@ svgEditor.addExtension('Markers', function (S) {
};
const langList = {
'en': [
en: [
{id: 'start_marker_list', title: 'Select start marker type'},
{id: 'mid_marker_list', title: 'Select mid marker type'},
{id: 'end_marker_list', title: 'Select end marker type'},
@@ -229,14 +230,14 @@ svgEditor.addExtension('Markers', function (S) {
markerHeight = bb.height / 10;
const box = addElem({
'element': 'rect',
'attr': {
'x': bb.x,
'y': bb.y,
'width': bb.width,
'height': bb.height,
'fill': txtBoxBg,
'stroke': txtBoxBorder,
element: 'rect',
attr: {
x: bb.x,
y: bb.y,
width: bb.width,
height: bb.height,
fill: txtBoxBg,
stroke: txtBoxBorder,
'stroke-width': txtBoxStrokeWidth
}
});
@@ -270,13 +271,13 @@ svgEditor.addExtension('Markers', function (S) {
const midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
const pline = addElem({
'element': 'polyline',
'attr': {
'points': (x1 + ',' + y1 + midPt + x2 + ',' + y2),
'stroke': elem.getAttribute('stroke'),
element: 'polyline',
attr: {
points: (x1 + ',' + y1 + midPt + x2 + ',' + y2),
stroke: elem.getAttribute('stroke'),
'stroke-width': elem.getAttribute('stroke-width'),
'fill': 'none',
'opacity': elem.getAttribute('opacity') || 1
fill: 'none',
opacity: elem.getAttribute('opacity') || 1
}
});
$.each(mtypes, function (i, pos) { // get any existing marker definitions
@@ -298,7 +299,7 @@ svgEditor.addExtension('Markers', function (S) {
}
function setMarker () {
const poslist = {'start_marker': 'start', 'mid_marker': 'mid', 'end_marker': 'end'};
const poslist = {start_marker: 'start', mid_marker: 'mid', end_marker: 'end'};
const pos = poslist[this.id];
const markerName = 'marker-' + pos;
let el = selElems[0];
@@ -435,21 +436,21 @@ svgEditor.addExtension('Markers', function (S) {
id: idPrefix + 'markers_off',
title: 'Turn off all markers',
type: 'context',
events: { 'click': setMarkerSet },
events: { click: setMarkerSet },
panel: 'marker_panel'
});
buttons.push({
id: idPrefix + 'markers_dimension',
title: 'Dimension',
type: 'context',
events: { 'click': setMarkerSet },
events: { click: setMarkerSet },
panel: 'marker_panel'
});
buttons.push({
id: idPrefix + 'markers_label',
title: 'Label',
type: 'context',
events: { 'click': setMarkerSet },
events: { click: setMarkerSet },
panel: 'marker_panel'
});
*/
@@ -463,7 +464,7 @@ svgEditor.addExtension('Markers', function (S) {
svgicon: id,
title,
type: 'context',
events: {'click': setArrowFromButton},
events: {click: setArrowFromButton},
panel: 'marker_panel',
list: listname,
isDefault: def
@@ -477,7 +478,7 @@ svgEditor.addExtension('Markers', function (S) {
let currentLang;
const ret = {
name: 'Markers',
svgicons: svgEditor.curConfig.extPath + 'markers-icons.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'markers-icons.xml',
callback () {
$('#marker_panel').addClass('toolset').hide();
},

View File

@@ -1,4 +1,4 @@
/* globals jQuery, MathJax, svgEditor, svgCanvas */
/* globals jQuery, MathJax */
/*
* ext-mathjax.js
*
@@ -7,9 +7,10 @@
* Copyright(c) 2013 Jo Segaert
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('mathjax', function () {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
// Configuration of the MathJax extention.
@@ -112,7 +113,7 @@ svgEditor.addExtension('mathjax', function () {
return {
name: 'MathJax',
svgicons: svgEditor.curConfig.extPath + 'mathjax-icons.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'mathjax-icons.xml',
buttons: [{
id: 'tool_mathjax',
type: 'mode',
@@ -164,8 +165,20 @@ svgEditor.addExtension('mathjax', function () {
$('body').addClass('tex2jax_ignore');
// Now get (and run) the MathJax Library.
// Todo: insert script with `s.type = 'module';` once modules widely supported
// and if this ends up providing an ES6 module export
// Todo: insert script with modules once widely supported
// and if MathJax (and its `TeX-AMS-MML_SVG.js` dependency) ends up
// providing an ES6 module export: https://github.com/mathjax/MathJax/issues/1998
/*
const s = document.createElement('script');
const modularVersion = !('svgEditor' in window) ||
!window.svgEditor ||
window.svgEditor.modules !== false;
if (modularVersion) {
s.type = 'module'; // Make this the default when widely supported
}
s.src = curConfig.extPath + mathjaxSrcSecure;
// See `executeAfterLoads` in `svgutils.js`
*/
$.getScript(mathjaxSrcSecure)
.done(function (script, textStatus) {
// When MathJax is loaded get the div where the math will be rendered.

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit */
/* globals jQuery */
/*
* ext-overview_window.js
*
@@ -7,13 +7,14 @@
* Copyright(c) 2013 James Sacksteder
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('overview_window', function () {
svgEditor.addExtension('overview_window', function ({isChrome, isIE}) {
const $ = jQuery;
const overviewWindowGlobals = {};
// Disabled in Chrome 48-, see https://github.com/SVG-Edit/svgedit/issues/26 and
// https://code.google.com/p/chromium/issues/detail?id=565120.
if (svgedit.browser.isChrome()) {
if (isChrome()) {
const verIndex = navigator.userAgent.indexOf('Chrome/') + 7;
const chromeVersion = parseInt(navigator.userAgent.substring(verIndex), 10);
if (chromeVersion < 49) {
@@ -72,7 +73,7 @@ svgEditor.addExtension('overview_window', function () {
let viewX = 640;
let viewY = 480;
if (svgedit.browser.isIE()) {
if (isIE()) {
// This has only been tested with Firefox 10 and IE 9 (without chrome frame).
// I am not sure if if is Firefox or IE that is being non compliant here.
// Either way the one that is noncompliant may become more compliant later.

View File

@@ -1,4 +1,4 @@
/* globals svgEditor, svgCanvas */
import svgEditor from '../svg-editor.js';
/*
* ext-panning.js
*
@@ -13,9 +13,10 @@
*/
svgEditor.addExtension('ext-panning', function () {
const svgCanvas = svgEditor.canvas;
return {
name: 'Extension Panning',
svgicons: svgEditor.curConfig.extPath + 'ext-panning.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'ext-panning.xml',
buttons: [{
id: 'ext-panning',
type: 'mode',

View File

@@ -1,10 +1,11 @@
/* globals jQuery, svgCanvas, svgEditor */
/* globals jQuery */
// TODO: Might add support for "exportImage" custom
// handler as in "ext-server_opensave.js" (and in savefile.php)
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('php_savefile', {
callback () {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
function getFileNameFromTitle () {
const title = svgCanvas.getDocumentTitle();
return title.trim();

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-polygon.js
*
@@ -7,8 +7,10 @@
* All rights reserved
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('polygon', function (S) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
const // {svgcontent} = S,
// addElem = S.addSvgElementFromJson,
editingitex = false;
@@ -88,7 +90,7 @@ svgEditor.addExtension('polygon', function (S) {
semantics.appendChild(annotation);
math.appendChild(semantics);
// make an AJAX request to the server, to get the MathML
$.post(ajaxEndpoint, {tex, 'display': 'inline'}, function(data){
$.post(ajaxEndpoint, {tex, display: 'inline'}, function(data){
const children = data.documentElement.childNodes;
while (children.length > 0) {
mrow.appendChild(svgdoc.adoptNode(children[0], true));
@@ -109,7 +111,7 @@ svgEditor.addExtension('polygon', function (S) {
*/
return {
name: 'polygon',
svgicons: svgEditor.curConfig.extPath + 'polygon-icons.svg',
svgicons: svgEditor.curConfig.extIconsPath + 'polygon-icons.svg',
buttons: [{
id: 'tool_polygon',
type: 'mode',
@@ -183,18 +185,18 @@ svgEditor.addExtension('polygon', function (S) {
started = true;
newFO = S.addSvgElementFromJson({
'element': 'polygon',
'attr': {
'cx': opts.start_x,
'cy': opts.start_y,
'id': S.getNextId(),
'shape': 'regularPoly',
'sides': document.getElementById('polySides').value,
'orient': 'x',
'edge': 0,
'fill': rgb,
'strokecolor': sRgb,
'strokeWidth': sWidth
element: 'polygon',
attr: {
cx: opts.start_x,
cy: opts.start_y,
id: S.getNextId(),
shape: 'regularPoly',
sides: document.getElementById('polySides').value,
orient: 'x',
edge: 0,
fill: rgb,
strokecolor: sRgb,
strokeWidth: sWidth
}
});

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit, svgCanvas, canvg */
/* globals jQuery */
/*
* ext-server_moinsave.js
*
@@ -10,11 +10,12 @@
* (I agree to dual license my work to additional GPLv2 or later)
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('server_opensave', {
callback () {
callback ({canvg, encode64, buildCanvgCallback}) {
const $ = jQuery;
const Utils = svgedit.utilities;
const svgCanvas = svgEditor.canvas;
const saveSvgAction = '/+modify';
// Create upload target (hidden iframe)
@@ -25,18 +26,18 @@ svgEditor.addExtension('server_opensave', {
const svg = '<?xml version="1.0"?>\n' + data;
const qstr = $.param.querystring();
const name = qstr.substr(9).split('/+get/')[1];
const svgData = Utils.encode64(svg);
const svgData = encode64(svg);
if (!$('#export_canvas').length) {
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
}
const c = $('#export_canvas')[0];
c.width = svgCanvas.contentW;
c.height = svgCanvas.contentH;
Utils.buildCanvgCallback(function () {
buildCanvgCallback(function () {
canvg(c, svg, {renderCallback () {
const datauri = c.toDataURL('image/png');
// const {uiStrings} = svgEditor;
const pngData = Utils.encode64(datauri); // Brett: This encoding seems unnecessary
const pngData = encode64(datauri); // Brett: This encoding seems unnecessary
/* const form = */ $('<form>').attr({
method: 'post',
action: saveSvgAction + '/' + name,

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgedit, svgCanvas, canvg */
/* globals jQuery */
/*
* ext-server_opensave.js
*
@@ -7,10 +7,12 @@
* Copyright(c) 2010 Alexis Deveria
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('server_opensave', {
callback () {
callback ({canvg, decode64, encode64, buildCanvgCallback}) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
function getFileNameFromTitle () {
const title = svgCanvas.getDocumentTitle();
// We convert (to underscore) only those disallowed Win7 file name characters
@@ -23,16 +25,19 @@ svgEditor.addExtension('server_opensave', {
const support = $('<a>')[0].download === '';
let a;
if (support) {
a = $('<a>hidden</a>').attr({download: (filename || 'image') + suffix, href: uri}).css('display', 'none').appendTo('body');
a = $('<a>hidden</a>').attr({
download: (filename || 'image') + suffix,
href: uri
}).css('display', 'none').appendTo('body');
a[0].click();
return true;
}
}
const
saveSvgAction = svgEditor.curConfig.extPath + 'filesave.php',
saveImgAction = svgEditor.curConfig.extPath + 'filesave.php',
saveImgAction = svgEditor.curConfig.extPath + 'filesave.php';
// Create upload target (hidden iframe)
Utils = svgedit.utilities;
let cancelled = false;
$('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
@@ -41,7 +46,7 @@ svgEditor.addExtension('server_opensave', {
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
filename = getFileNameFromTitle();
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + Utils.encode64(svg))) {
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + encode64(svg))) {
return;
}
@@ -81,7 +86,7 @@ svgEditor.addExtension('server_opensave', {
c.width = svgCanvas.contentW;
c.height = svgCanvas.contentH;
Utils.buildCanvgCallback(function () {
buildCanvgCallback(function () {
canvg(c, data.svg, {renderCallback () {
const datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType);
// {uiStrings} = svgEditor;
@@ -137,7 +142,7 @@ svgEditor.addExtension('server_opensave', {
$('#dialog_box').hide();
if (type !== 'import_img') {
xmlstr = Utils.decode64(str64);
xmlstr = decode64(str64);
}
switch (type) {

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor */
/* globals jQuery */
/*
* ext-shapes.js
*
@@ -8,7 +8,7 @@
* Copyright(c) 2010 Alexis Deveria
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('shapes', function () {
const $ = jQuery;
const canv = svgEditor.canvas;
@@ -36,34 +36,34 @@ svgEditor.addExtension('shapes', function () {
const library = {
basic: {
data: {
'heart': 'm150,73c61,-175 300,0 0,225c-300,-225 -61,-400 0,-225z',
'frame': 'm0,0l300,0l0,300l-300,0zm35,-265l0,230l230,0l0,-230z',
'donut': 'm1,150l0,0c0,-82.29042 66.70958,-149 149,-149l0,0c39.51724,0 77.41599,15.69816 105.35889,43.64108c27.94293,27.94293 43.64111,65.84165 43.64111,105.35892l0,0c0,82.29041 -66.70958,149 -149,149l0,0c-82.29041,0 -149,-66.70959 -149,-149zm74.5,0l0,0c0,41.1452 33.35481,74.5 74.5,74.5c41.14522,0 74.5,-33.3548 74.5,-74.5c0,-41.1452 -33.3548,-74.5 -74.5,-74.5l0,0c-41.14519,0 -74.5,33.35481 -74.5,74.5z',
'triangle': 'm1,280.375l149,-260.75l149,260.75z',
'right_triangle': 'm1,299l0,-298l298,298z',
'diamond': 'm1,150l149,-149l149,149l-149,149l-149,-149z',
'pentagon': 'm1.00035,116.97758l148.99963,-108.4053l148.99998,108.4053l-56.91267,175.4042l-184.1741,0l-56.91284,-175.4042z',
'hexagon': 'm1,149.99944l63.85715,-127.71428l170.28572,0l63.85713,127.71428l-63.85713,127.71428l-170.28572,0l-63.85715,-127.71428z',
'septagon1': 'm0.99917,191.06511l29.51249,-127.7108l119.48833,-56.83673l119.48836,56.83673l29.51303,127.7108l-82.69087,102.41679l-132.62103,0l-82.69031,-102.41679z',
'heptagon': 'm1,88.28171l87.28172,-87.28171l123.43653,0l87.28172,87.28171l0,123.43654l-87.28172,87.28172l-123.43653,0l-87.28172,-87.28172l0,-123.43654z',
'decagon': 'm1,150.00093l28.45646,-88.40318l74.49956,-54.63682l92.08794,0l74.50002,54.63682l28.45599,88.40318l-28.45599,88.40318l-74.50002,54.63681l-92.08794,0l-74.49956,-54.63681l-28.45646,-88.40318z',
'dodecagon': 'm1,110.07421l39.92579,-69.14842l69.14842,-39.92579l79.85159,0l69.14842,39.92579l39.92578,69.14842l0,79.85159l-39.92578,69.14842l-69.14842,39.92578l-79.85159,0l-69.14842,-39.92578l-39.92579,-69.14842l0,-79.85159z',
'star_points_5': 'm1,116.58409l113.82668,0l35.17332,-108.13487l35.17334,108.13487l113.82666,0l-92.08755,66.83026l35.17514,108.13487l-92.08759,-66.83208l-92.08757,66.83208l35.17515,-108.13487l-92.08758,-66.83026z',
'trapezoid': 'm1,299l55.875,-298l186.25001,0l55.87498,298z',
'arrow_up': 'm1.49805,149.64304l148.50121,-148.00241l148.50121,148.00241l-74.25061,0l0,148.71457l-148.5012,0l0,-148.71457z',
'vertical_scrool': 'm37.375,261.625l0,-242.9375l0,0c0,-10.32083 8.36669,-18.6875 18.6875,-18.6875l224.25,0c10.32083,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36667,18.6875 -18.6875,18.6875l-18.6875,0l0,242.9375c0,10.32083 -8.36668,18.6875 -18.6875,18.6875l-224.25,0l0,0c-10.32083,0 -18.6875,-8.36667 -18.6875,-18.6875c0,-10.32083 8.36667,-18.6875 18.6875,-18.6875zm37.375,-261.625l0,0c10.32081,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36669,18.6875 -18.6875,18.6875c-5.1604,0 -9.34375,-4.18335 -9.34375,-9.34375c0,-5.16041 4.18335,-9.34375 9.34375,-9.34375l18.6875,0m186.875,18.6875l-205.5625,0m-37.375,224.25l0,0c5.1604,0 9.34375,4.18335 9.34375,9.34375c0,5.1604 -4.18335,9.34375 -9.34375,9.34375l18.6875,0m-18.6875,18.6875l0,0c10.32081,0 18.6875,-8.36667 18.6875,-18.6875l0,-18.6875',
'smiley': 'm68.49886,214.78838q81.06408,55.67332 161.93891,0m-144.36983,-109.9558c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57948,6.97517 15.57948,15.57949c0,8.60431 -6.97517,15.57947 -15.57948,15.57947c-8.60431,0 -15.57948,-6.97516 -15.57948,-15.57947m95.83109,0c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57947,6.97517 15.57947,15.57949c0,8.60431 -6.97516,15.57947 -15.57947,15.57947c-8.60429,0 -15.57948,-6.97516 -15.57948,-15.57947m-181.89903,44.73038l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296zm0,0l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296z',
'left_braket': 'm174.24565,298.5c-13.39009,0 -24.24489,-1.80908 -24.24489,-4.04065l0,-140.4187c0,-2.23158 -10.85481,-4.04065 -24.2449,-4.04065l0,0c13.39009,0 24.2449,-1.80907 24.2449,-4.04065l0,-140.4187l0,0c0,-2.23159 10.8548,-4.04066 24.24489,-4.04066',
'uml_actor': 'm40.5,100l219,0m-108.99991,94.00006l107,105m-107.00009,-106.00006l-100,106m99.5,-231l0,125m33.24219,-158.75781c0,18.35916 -14.88303,33.24219 -33.24219,33.24219c-18.35916,0 -33.2422,-14.88303 -33.2422,-33.24219c0.00002,-18.35915 14.88304,-33.24219 33.2422,-33.24219c18.35916,0 33.24219,14.88304 33.24219,33.24219z',
'dialog_balloon_1': 'm0.99786,35.96579l0,0c0,-19.31077 15.28761,-34.96524 34.14583,-34.96524l15.52084,0l0,0l74.50001,0l139.68748,0c9.05606,0 17.74118,3.68382 24.14478,10.24108c6.40356,6.55726 10.00107,15.45081 10.00107,24.72416l0,87.41311l0,0l0,52.44785l0,0c0,19.31078 -15.2876,34.96524 -34.14584,34.96524l-139.68748,0l-97.32507,88.90848l22.82506,-88.90848l-15.52084,0c-18.85822,0 -34.14583,-15.65446 -34.14583,-34.96524l0,0l0,-52.44785l0,0z',
'cloud': 'm182.05086,34.31005c-0.64743,0.02048 -1.27309,0.07504 -1.92319,0.13979c-10.40161,1.03605 -19.58215,7.63722 -24.24597,17.4734l-2.47269,7.44367c0.53346,-2.57959 1.35258,-5.08134 2.47269,-7.44367c-8.31731,-8.61741 -19.99149,-12.59487 -31.52664,-10.72866c-11.53516,1.8662 -21.55294,9.3505 -27.02773,20.19925c-15.45544,-9.51897 -34.72095,-8.94245 -49.62526,1.50272c-14.90431,10.44516 -22.84828,28.93916 -20.43393,47.59753l1.57977,7.58346c-0.71388,-2.48442 -1.24701,-5.01186 -1.57977,-7.58346l-0.2404,0.69894c-12.95573,1.4119 -23.58103,11.46413 -26.34088,24.91708c-2.75985,13.45294 2.9789,27.25658 14.21789,34.21291l17.54914,4.26352c-6.1277,0.50439 -12.24542,-0.9808 -17.54914,-4.26352c-8.66903,9.71078 -10.6639,24.08736 -4.94535,35.96027c5.71854,11.87289 17.93128,18.70935 30.53069,17.15887l7.65843,-2.02692c-2.46413,1.0314 -5.02329,1.70264 -7.65843,2.02692c7.15259,13.16728 19.01251,22.77237 32.93468,26.5945c13.92217,3.82214 28.70987,1.56322 41.03957,-6.25546c10.05858,15.86252 27.91113,24.19412 45.81322,21.38742c17.90208,-2.8067 32.66954,-16.26563 37.91438,-34.52742l1.82016,-10.20447c-0.27254,3.46677 -0.86394,6.87508 -1.82016,10.20447c12.31329,8.07489 27.80199,8.52994 40.52443,1.18819c12.72244,-7.34175 20.6609,-21.34155 20.77736,-36.58929l-4.56108,-22.7823l-17.96776,-15.41455c13.89359,8.70317 22.6528,21.96329 22.52884,38.19685c16.5202,0.17313 30.55292,-13.98268 36.84976,-30.22897c6.29684,-16.24631 3.91486,-34.76801 -6.2504,-48.68089c4.21637,-10.35873 3.96622,-22.14172 -0.68683,-32.29084c-4.65308,-10.14912 -13.23602,-17.69244 -23.55914,-20.65356c-2.31018,-13.45141 -11.83276,-24.27162 -24.41768,-27.81765c-12.58492,-3.54603 -25.98557,0.82654 -34.41142,11.25287l-5.11707,8.63186c1.30753,-3.12148 3.01521,-6.03101 5.11707,-8.63186c-5.93959,-8.19432 -15.2556,-12.8181 -24.96718,-12.51096z',
'cylinder': 'm299.0007,83.77844c0,18.28676 -66.70958,33.11111 -149.00002,33.11111m149.00002,-33.11111l0,0c0,18.28676 -66.70958,33.11111 -149.00002,33.11111c-82.29041,0 -148.99997,-14.82432 -148.99997,-33.11111m0,0l0,0c0,-18.28674 66.70956,-33.1111 148.99997,-33.1111c82.29044,0 149.00002,14.82436 149.00002,33.1111l0,132.44449c0,18.28674 -66.70958,33.11105 -149.00002,33.11105c-82.29041,0 -148.99997,-14.82431 -148.99997,-33.11105z',
'arrow_u_turn': 'm1.00059,299.00055l0,-167.62497l0,0c0,-72.00411 58.37087,-130.37499 130.375,-130.37499l0,0l0,0c34.57759,0 67.73898,13.7359 92.18906,38.18595c24.45006,24.45005 38.18593,57.61144 38.18593,92.18904l0,18.625l37.24997,0l-74.49995,74.50002l-74.50002,-74.50002l37.25,0l0,-18.625c0,-30.8589 -25.0161,-55.87498 -55.87498,-55.87498l0,0l0,0c-30.85892,0 -55.875,25.01608 -55.875,55.87498l0,167.62497z',
'arrow_left_up': 'm0.99865,224.5l74.50004,-74.5l0,37.25l111.74991,0l0,-111.75l-37.25,0l74.5,-74.5l74.5,74.5l-37.25,0l0,186.25l-186.24989,0l0,37.25l-74.50005,-74.5z',
'maximize': 'm1.00037,150.34581l55.30305,-55.30267l0,27.65093l22.17356,0l0,-44.21833l44.21825,0l0,-22.17357l-27.65095,0l55.30267,-55.30292l55.3035,55.30292l-27.65175,0l0,22.17357l44.21835,0l0,44.21833l22.17357,0l0,-27.65093l55.30345,55.30267l-55.30345,55.3035l0,-27.65175l-22.17357,0l0,44.21834l-44.21835,0l0,22.17355l27.65175,0l-55.3035,55.30348l-55.30267,-55.30348l27.65095,0l0,-22.17355l-44.21825,0l0,-44.21834l-22.17356,0l0,27.65175l-55.30305,-55.3035z',
'cross': 'm0.99844,99.71339l98.71494,0l0,-98.71495l101.26279,0l0,98.71495l98.71495,0l0,101.2628l-98.71495,0l0,98.71494l-101.26279,0l0,-98.71494l-98.71494,0z',
'plaque': 'm-0.00197,49.94376l0,0c27.5829,0 49.94327,-22.36036 49.94327,-49.94327l199.76709,0l0,0c0,27.5829 22.36037,49.94327 49.94325,49.94327l0,199.7671l0,0c-27.58289,0 -49.94325,22.36034 -49.94325,49.94325l-199.76709,0c0,-27.58292 -22.36037,-49.94325 -49.94327,-49.94325z',
'page': 'm249.3298,298.99744l9.9335,-39.73413l39.73413,-9.93355l-49.66763,49.66768l-248.33237,0l0,-298.00001l298.00001,0l0,248.33234'
heart: 'm150,73c61,-175 300,0 0,225c-300,-225 -61,-400 0,-225z',
frame: 'm0,0l300,0l0,300l-300,0zm35,-265l0,230l230,0l0,-230z',
donut: 'm1,150l0,0c0,-82.29042 66.70958,-149 149,-149l0,0c39.51724,0 77.41599,15.69816 105.35889,43.64108c27.94293,27.94293 43.64111,65.84165 43.64111,105.35892l0,0c0,82.29041 -66.70958,149 -149,149l0,0c-82.29041,0 -149,-66.70959 -149,-149zm74.5,0l0,0c0,41.1452 33.35481,74.5 74.5,74.5c41.14522,0 74.5,-33.3548 74.5,-74.5c0,-41.1452 -33.3548,-74.5 -74.5,-74.5l0,0c-41.14519,0 -74.5,33.35481 -74.5,74.5z',
triangle: 'm1,280.375l149,-260.75l149,260.75z',
right_triangle: 'm1,299l0,-298l298,298z',
diamond: 'm1,150l149,-149l149,149l-149,149l-149,-149z',
pentagon: 'm1.00035,116.97758l148.99963,-108.4053l148.99998,108.4053l-56.91267,175.4042l-184.1741,0l-56.91284,-175.4042z',
hexagon: 'm1,149.99944l63.85715,-127.71428l170.28572,0l63.85713,127.71428l-63.85713,127.71428l-170.28572,0l-63.85715,-127.71428z',
septagon1: 'm0.99917,191.06511l29.51249,-127.7108l119.48833,-56.83673l119.48836,56.83673l29.51303,127.7108l-82.69087,102.41679l-132.62103,0l-82.69031,-102.41679z',
heptagon: 'm1,88.28171l87.28172,-87.28171l123.43653,0l87.28172,87.28171l0,123.43654l-87.28172,87.28172l-123.43653,0l-87.28172,-87.28172l0,-123.43654z',
decagon: 'm1,150.00093l28.45646,-88.40318l74.49956,-54.63682l92.08794,0l74.50002,54.63682l28.45599,88.40318l-28.45599,88.40318l-74.50002,54.63681l-92.08794,0l-74.49956,-54.63681l-28.45646,-88.40318z',
dodecagon: 'm1,110.07421l39.92579,-69.14842l69.14842,-39.92579l79.85159,0l69.14842,39.92579l39.92578,69.14842l0,79.85159l-39.92578,69.14842l-69.14842,39.92578l-79.85159,0l-69.14842,-39.92578l-39.92579,-69.14842l0,-79.85159z',
star_points_5: 'm1,116.58409l113.82668,0l35.17332,-108.13487l35.17334,108.13487l113.82666,0l-92.08755,66.83026l35.17514,108.13487l-92.08759,-66.83208l-92.08757,66.83208l35.17515,-108.13487l-92.08758,-66.83026z',
trapezoid: 'm1,299l55.875,-298l186.25001,0l55.87498,298z',
arrow_up: 'm1.49805,149.64304l148.50121,-148.00241l148.50121,148.00241l-74.25061,0l0,148.71457l-148.5012,0l0,-148.71457z',
vertical_scrool: 'm37.375,261.625l0,-242.9375l0,0c0,-10.32083 8.36669,-18.6875 18.6875,-18.6875l224.25,0c10.32083,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36667,18.6875 -18.6875,18.6875l-18.6875,0l0,242.9375c0,10.32083 -8.36668,18.6875 -18.6875,18.6875l-224.25,0l0,0c-10.32083,0 -18.6875,-8.36667 -18.6875,-18.6875c0,-10.32083 8.36667,-18.6875 18.6875,-18.6875zm37.375,-261.625l0,0c10.32081,0 18.6875,8.36667 18.6875,18.6875c0,10.32081 -8.36669,18.6875 -18.6875,18.6875c-5.1604,0 -9.34375,-4.18335 -9.34375,-9.34375c0,-5.16041 4.18335,-9.34375 9.34375,-9.34375l18.6875,0m186.875,18.6875l-205.5625,0m-37.375,224.25l0,0c5.1604,0 9.34375,4.18335 9.34375,9.34375c0,5.1604 -4.18335,9.34375 -9.34375,9.34375l18.6875,0m-18.6875,18.6875l0,0c10.32081,0 18.6875,-8.36667 18.6875,-18.6875l0,-18.6875',
smiley: 'm68.49886,214.78838q81.06408,55.67332 161.93891,0m-144.36983,-109.9558c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57948,6.97517 15.57948,15.57949c0,8.60431 -6.97517,15.57947 -15.57948,15.57947c-8.60431,0 -15.57948,-6.97516 -15.57948,-15.57947m95.83109,0c0,-8.60432 6.97517,-15.57949 15.57948,-15.57949c8.60431,0 15.57947,6.97517 15.57947,15.57949c0,8.60431 -6.97516,15.57947 -15.57947,15.57947c-8.60429,0 -15.57948,-6.97516 -15.57948,-15.57947m-181.89903,44.73038l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296zm0,0l0,0c0,-82.60133 66.96162,-149.56296 149.56296,-149.56296c82.60135,0 149.56296,66.96162 149.56296,149.56296c0,82.60135 -66.96161,149.56296 -149.56296,149.56296c-82.60133,0 -149.56296,-66.96161 -149.56296,-149.56296z',
left_braket: 'm174.24565,298.5c-13.39009,0 -24.24489,-1.80908 -24.24489,-4.04065l0,-140.4187c0,-2.23158 -10.85481,-4.04065 -24.2449,-4.04065l0,0c13.39009,0 24.2449,-1.80907 24.2449,-4.04065l0,-140.4187l0,0c0,-2.23159 10.8548,-4.04066 24.24489,-4.04066',
uml_actor: 'm40.5,100l219,0m-108.99991,94.00006l107,105m-107.00009,-106.00006l-100,106m99.5,-231l0,125m33.24219,-158.75781c0,18.35916 -14.88303,33.24219 -33.24219,33.24219c-18.35916,0 -33.2422,-14.88303 -33.2422,-33.24219c0.00002,-18.35915 14.88304,-33.24219 33.2422,-33.24219c18.35916,0 33.24219,14.88304 33.24219,33.24219z',
dialog_balloon_1: 'm0.99786,35.96579l0,0c0,-19.31077 15.28761,-34.96524 34.14583,-34.96524l15.52084,0l0,0l74.50001,0l139.68748,0c9.05606,0 17.74118,3.68382 24.14478,10.24108c6.40356,6.55726 10.00107,15.45081 10.00107,24.72416l0,87.41311l0,0l0,52.44785l0,0c0,19.31078 -15.2876,34.96524 -34.14584,34.96524l-139.68748,0l-97.32507,88.90848l22.82506,-88.90848l-15.52084,0c-18.85822,0 -34.14583,-15.65446 -34.14583,-34.96524l0,0l0,-52.44785l0,0z',
cloud: 'm182.05086,34.31005c-0.64743,0.02048 -1.27309,0.07504 -1.92319,0.13979c-10.40161,1.03605 -19.58215,7.63722 -24.24597,17.4734l-2.47269,7.44367c0.53346,-2.57959 1.35258,-5.08134 2.47269,-7.44367c-8.31731,-8.61741 -19.99149,-12.59487 -31.52664,-10.72866c-11.53516,1.8662 -21.55294,9.3505 -27.02773,20.19925c-15.45544,-9.51897 -34.72095,-8.94245 -49.62526,1.50272c-14.90431,10.44516 -22.84828,28.93916 -20.43393,47.59753l1.57977,7.58346c-0.71388,-2.48442 -1.24701,-5.01186 -1.57977,-7.58346l-0.2404,0.69894c-12.95573,1.4119 -23.58103,11.46413 -26.34088,24.91708c-2.75985,13.45294 2.9789,27.25658 14.21789,34.21291l17.54914,4.26352c-6.1277,0.50439 -12.24542,-0.9808 -17.54914,-4.26352c-8.66903,9.71078 -10.6639,24.08736 -4.94535,35.96027c5.71854,11.87289 17.93128,18.70935 30.53069,17.15887l7.65843,-2.02692c-2.46413,1.0314 -5.02329,1.70264 -7.65843,2.02692c7.15259,13.16728 19.01251,22.77237 32.93468,26.5945c13.92217,3.82214 28.70987,1.56322 41.03957,-6.25546c10.05858,15.86252 27.91113,24.19412 45.81322,21.38742c17.90208,-2.8067 32.66954,-16.26563 37.91438,-34.52742l1.82016,-10.20447c-0.27254,3.46677 -0.86394,6.87508 -1.82016,10.20447c12.31329,8.07489 27.80199,8.52994 40.52443,1.18819c12.72244,-7.34175 20.6609,-21.34155 20.77736,-36.58929l-4.56108,-22.7823l-17.96776,-15.41455c13.89359,8.70317 22.6528,21.96329 22.52884,38.19685c16.5202,0.17313 30.55292,-13.98268 36.84976,-30.22897c6.29684,-16.24631 3.91486,-34.76801 -6.2504,-48.68089c4.21637,-10.35873 3.96622,-22.14172 -0.68683,-32.29084c-4.65308,-10.14912 -13.23602,-17.69244 -23.55914,-20.65356c-2.31018,-13.45141 -11.83276,-24.27162 -24.41768,-27.81765c-12.58492,-3.54603 -25.98557,0.82654 -34.41142,11.25287l-5.11707,8.63186c1.30753,-3.12148 3.01521,-6.03101 5.11707,-8.63186c-5.93959,-8.19432 -15.2556,-12.8181 -24.96718,-12.51096z',
cylinder: 'm299.0007,83.77844c0,18.28676 -66.70958,33.11111 -149.00002,33.11111m149.00002,-33.11111l0,0c0,18.28676 -66.70958,33.11111 -149.00002,33.11111c-82.29041,0 -148.99997,-14.82432 -148.99997,-33.11111m0,0l0,0c0,-18.28674 66.70956,-33.1111 148.99997,-33.1111c82.29044,0 149.00002,14.82436 149.00002,33.1111l0,132.44449c0,18.28674 -66.70958,33.11105 -149.00002,33.11105c-82.29041,0 -148.99997,-14.82431 -148.99997,-33.11105z',
arrow_u_turn: 'm1.00059,299.00055l0,-167.62497l0,0c0,-72.00411 58.37087,-130.37499 130.375,-130.37499l0,0l0,0c34.57759,0 67.73898,13.7359 92.18906,38.18595c24.45006,24.45005 38.18593,57.61144 38.18593,92.18904l0,18.625l37.24997,0l-74.49995,74.50002l-74.50002,-74.50002l37.25,0l0,-18.625c0,-30.8589 -25.0161,-55.87498 -55.87498,-55.87498l0,0l0,0c-30.85892,0 -55.875,25.01608 -55.875,55.87498l0,167.62497z',
arrow_left_up: 'm0.99865,224.5l74.50004,-74.5l0,37.25l111.74991,0l0,-111.75l-37.25,0l74.5,-74.5l74.5,74.5l-37.25,0l0,186.25l-186.24989,0l0,37.25l-74.50005,-74.5z',
maximize: 'm1.00037,150.34581l55.30305,-55.30267l0,27.65093l22.17356,0l0,-44.21833l44.21825,0l0,-22.17357l-27.65095,0l55.30267,-55.30292l55.3035,55.30292l-27.65175,0l0,22.17357l44.21835,0l0,44.21833l22.17357,0l0,-27.65093l55.30345,55.30267l-55.30345,55.3035l0,-27.65175l-22.17357,0l0,44.21834l-44.21835,0l0,22.17355l27.65175,0l-55.3035,55.30348l-55.30267,-55.30348l27.65095,0l0,-22.17355l-44.21825,0l0,-44.21834l-22.17356,0l0,27.65175l-55.30305,-55.3035z',
cross: 'm0.99844,99.71339l98.71494,0l0,-98.71495l101.26279,0l0,98.71495l98.71495,0l0,101.2628l-98.71495,0l0,98.71494l-101.26279,0l0,-98.71494l-98.71494,0z',
plaque: 'm-0.00197,49.94376l0,0c27.5829,0 49.94327,-22.36036 49.94327,-49.94327l199.76709,0l0,0c0,27.5829 22.36037,49.94327 49.94325,49.94327l0,199.7671l0,0c-27.58289,0 -49.94325,22.36034 -49.94325,49.94325l-199.76709,0c0,-27.58292 -22.36037,-49.94325 -49.94327,-49.94325z',
page: 'm249.3298,298.99744l9.9335,-39.73413l39.73413,-9.93355l-49.66763,49.66768l-248.33237,0l0,-298.00001l298.00001,0l0,248.33234'
},
buttons: []
@@ -135,7 +135,7 @@ svgEditor.addExtension('shapes', function () {
}
return {
svgicons: svgEditor.curConfig.extPath + 'ext-shapes.xml',
svgicons: svgEditor.curConfig.extIconsPath + 'ext-shapes.xml',
buttons: [{
id: 'tool_shapelib',
type: 'mode_flyout', // _flyout
@@ -249,13 +249,13 @@ svgEditor.addExtension('shapes', function () {
startClientPos.y = opts.event.clientY;
curShape = canv.addSvgElementFromJson({
'element': 'path',
'curStyles': true,
'attr': {
'd': currentD,
'id': canv.getNextId(),
'opacity': curStyle.opacity / 2,
'style': 'pointer-events:none'
element: 'path',
curStyles: true,
attr: {
d: currentD,
id: canv.getNextId(),
opacity: curStyle.opacity / 2,
style: 'pointer-events:none'
}
});
@@ -294,10 +294,10 @@ svgEditor.addExtension('shapes', function () {
// const dx = (x - startX), dy = (y - startY);
const newbox = {
'x': Math.min(startX, x),
'y': Math.min(startY, y),
'width': Math.abs(x - startX),
'height': Math.abs(y - startY)
x: Math.min(startX, x),
y: Math.min(startY, y),
width: Math.abs(x - startX),
height: Math.abs(y - startY)
};
/*

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-star.js
*
@@ -7,9 +7,11 @@
* All rights reserved
*
*/
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('star', function (S) {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
let // {svgcontent} = S,
selElems,
// editingitex = false,
@@ -53,7 +55,7 @@ svgEditor.addExtension('star', function (S) {
return {
name: 'star',
svgicons: svgEditor.curConfig.extPath + 'star-icons.svg',
svgicons: svgEditor.curConfig.extIconsPath + 'star-icons.svg',
buttons: [{
id: 'tool_star',
type: 'mode',
@@ -117,20 +119,20 @@ svgEditor.addExtension('star', function (S) {
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
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 {

View File

@@ -1,4 +1,4 @@
/* globals jQuery, svgEditor, svgCanvas */
/* globals jQuery */
/*
* ext-storage.js
*
@@ -29,15 +29,19 @@ TODOS
2. We might provide control of storage settings through the UI besides the
initial (or URL-forced) dialog.
*/
// Todo: We might use dynamic `import()` later instead, based on detected locale
import confirmSetStorage from './ext-locale/storage.js';
import svgEditor from '../svg-editor.js';
svgEditor.addExtension('storage', function () {
const $ = jQuery;
const svgCanvas = svgEditor.canvas;
// 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.
// in svgedit-config-iife.js/svgedit-config-es.js.
const {
emptyStorageOnDecline,
// When the code in svg-editor.js prevents local storage on load per
@@ -48,7 +52,7 @@ svgEditor.addExtension('storage', function () {
// 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.
// the "noStorageOnLoad" config setting to true in svgedit-config-iife.js.
noStorageOnLoad,
forceStorage
} = svgEditor.curConfig;

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
/*
Depends on Firefox add-on and executables from https://github.com/brettz9/webappfind
@@ -45,7 +45,7 @@ window.postMessage([readMessage], window.location.origin !== 'null' ? window.loc
svgEditor.addExtension('WebAppFind', function () {
return {
name: 'WebAppFind',
svgicons: svgEditor.curConfig.extPath + 'webappfind-icon.svg',
svgicons: svgEditor.curConfig.extIconsPath + 'webappfind-icon.svg',
buttons: [{
id: 'webappfind_save', //
type: 'app_menu',

View File

@@ -1,10 +1,11 @@
/* globals svgEditor, svgCanvas */
import svgEditor from '../svg-editor.js';
/**
* Should not be needed for same domain control (just call via child frame),
* but an API common for cross-domain and same domain use can be found
* in embedapi.js with a demo at embedapi.html
*/
svgEditor.addExtension('xdomain-messaging', function () {
const svgCanvas = svgEditor.canvas;
try {
window.addEventListener('message', function (e) {
// We accept and post strings for the sake of IE9 support

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>-</title>
<link rel="icon" type="image/png" href="../../images/logo.png"/>
<script src="jquery.min.js"></script>
<script src="../../external/babel-polyfill/polyfill.min.js"></script>
<script type="module" src="index.js"></script>
</head>
<body>
<h1>Select an image:</h1>
<a href="smiley.svg">smiley.svg</a>
<br/>
<a href="../../images/logo.png">logo.png</a>
</body>
</html>

View File

@@ -1,18 +1,20 @@
<!DOCTYPE html>
<!-- AUTO-GENERATED FROM imagelib/index-es.html; DO NOT EDIT; use build-html.js to build -->
<html>
<head>
<meta charset="utf-8" />
<title>-</title>
<link rel="icon" type="image/png" href="../../images/logo.png"/>
<script src="jquery.min.js"></script>
<script src="../../external/babel-polyfill/polyfill.min.js"></script>
<script defer="defer" src="../../../dist/extensions/imagelib/index.js"></script>
</head>
<body>
<h1>Select an image:</h1>
<a href="smiley.svg">smiley.svg</a>
<br>
<br/>
<a href="../../images/logo.png">logo.png</a>
<script src="index.js"></script>
</body>
</html>

7574
editor/external/babel-polyfill/polyfill.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,66 @@
// MIT License
// From: https://github.com/uupaa/dynamic-import-polyfill/blob/master/importModule.js
function toAbsoluteURL(url) {
const a = document.createElement("a");
a.setAttribute("href", url); // <a href="hoge.html">
return a.cloneNode(false).href; // -> "http://example.com/hoge.html"
}
// My own addition
export function importScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
const destructor = () => {
script.onerror = null;
script.onload = null;
script.remove();
script.src = "";
};
script.defer = "defer";
script.onerror = () => {
reject(new Error(`Failed to import: ${url}`));
destructor();
};
script.onload = () => {
resolve(window[vector]);
destructor();
};
script.src = url;
document.head.appendChild(script);
});
}
export function importModule(url) {
return new Promise((resolve, reject) => {
const vector = "$importModule$" + Math.random().toString(32).slice(2);
const script = document.createElement("script");
const destructor = () => {
delete window[vector];
script.onerror = null;
script.onload = null;
script.remove();
URL.revokeObjectURL(script.src);
script.src = "";
};
script.defer = "defer";
script.type = "module";
script.onerror = () => {
reject(new Error(`Failed to import: ${url}`));
destructor();
};
script.onload = () => {
resolve(window[vector]);
destructor();
};
const absURL = toAbsoluteURL(url);
const loader = `import * as m from "${absURL}"; window.${vector} = m;`; // export Module
const blob = new Blob([loader], { type: "text/javascript" });
script.src = URL.createObjectURL(blob);
document.head.appendChild(script);
});
}
export default importModule;

View File

@@ -0,0 +1,80 @@
function loadStylesheets(stylesheets, {
before: beforeDefault, after: afterDefault, favicon: faviconDefault,
canvas: canvasDefault, image: imageDefault = true
} = {}) {
stylesheets = Array.isArray(stylesheets) ? stylesheets : [stylesheets];
function setupLink(stylesheetURL) {
let options = {};
if (Array.isArray(stylesheetURL)) {
[stylesheetURL, options = {}] = stylesheetURL;
}
let { favicon = faviconDefault } = options;
const {
before = beforeDefault,
after = afterDefault,
canvas = canvasDefault,
image = imageDefault
} = options;
function addLink() {
if (before) {
before.before(link);
} else if (after) {
after.after(link);
} else {
document.head.appendChild(link);
}
}
const link = document.createElement('link');
return new Promise((resolve, reject) => {
if (stylesheetURL.endsWith('.css')) {
favicon = false;
} else if (stylesheetURL.endsWith('.ico')) {
favicon = true;
}
if (favicon) {
link.rel = 'shortcut icon';
link.type = 'image/x-icon';
if (image === false) {
link.href = stylesheetURL;
addLink();
resolve(link);
return;
}
const cnv = document.createElement('canvas');
cnv.width = 16;
cnv.height = 16;
const context = cnv.getContext('2d');
const img = document.createElement('img');
img.addEventListener('error', error => {
reject(error);
});
img.addEventListener('load', () => {
context.drawImage(img, 0, 0);
link.href = canvas ? cnv.toDataURL('image/x-icon') : stylesheetURL;
addLink();
resolve(link);
});
img.src = stylesheetURL;
return;
}
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = stylesheetURL;
addLink();
link.addEventListener('error', error => {
reject(error);
});
link.addEventListener('load', () => {
resolve(link);
});
});
}
return Promise.all(stylesheets.map(setupLink));
}
export default loadStylesheets;

View File

@@ -6,7 +6,7 @@
* Copyright(c) 2010 Jeff Schiller
*/
import {getHref, setHref, getRotationAngle} from 'svgutils.js';
import {getHref, setHref, getRotationAngle} from './svgutils.js';
import {removeElementFromListMap} from './svgtransformlist.js';
// Group: Undo/Redo history management
@@ -123,7 +123,7 @@ export class InsertElementCommand {
type () {
return 'svgedit.history.InsertElementCommand';
};
}
getText () {
return this.text;
@@ -257,7 +257,7 @@ export class ChangeElementCommand {
}
type () {
return 'svgedit.history.ChangeElementCommand';
};
}
getText () {
return this.text;

View File

@@ -20,6 +20,13 @@ Math.precision = function (value, precision) {
};
export default function ($) {
if (!$.loadingStylesheets) {
$.loadingStylesheets = [];
}
const stylesheet = 'jgraduate/css/jPicker.css';
if (!$.loadingStylesheets.includes(stylesheet)) {
$.loadingStylesheets.push(stylesheet);
}
/**
* Encapsulate slider functionality for the ColorMap and ColorBar -
* could be useful to use a jQuery UI draggable for this with certain extensions
@@ -503,250 +510,252 @@ export default function ($) {
List: [], // array holding references to each active instance of the control
// color object - we will be able to assign by any color space type or retrieve any color space info
// we want this public so we can optionally assign new color objects to initial values using inputs other than a string hex value (also supported)
Color (init) {
const $this = this;
function fireChangeEvents (context) {
for (let i = 0; i < changeEvents.length; i++) changeEvents[i].call($this, $this, context);
}
function val (name, value, context) {
// Kind of ugly
const set = Boolean(value);
if (set && value.ahex === '') value.ahex = '00000000';
if (!set) {
if (name === undefined || name == null || name === '') name = 'all';
if (r == null) return null;
Color: class {
constructor (init) {
const $this = this;
function fireChangeEvents (context) {
for (let i = 0; i < changeEvents.length; i++) changeEvents[i].call($this, $this, context);
}
function val (name, value, context) {
// Kind of ugly
const set = Boolean(value);
if (set && value.ahex === '') value.ahex = '00000000';
if (!set) {
if (name === undefined || name == null || name === '') name = 'all';
if (r == null) return null;
switch (name.toLowerCase()) {
case 'ahex': return ColorMethods.rgbaToHex({ r, g, b, a });
case 'hex': return val('ahex').substring(0, 6);
case 'all': return { r, g, b, a, h, s, v, hex: val.call($this, 'hex'), ahex: val.call($this, 'ahex') };
default:
let ret = {};
for (let i = 0; i < name.length; i++) {
switch (name.charAt(i)) {
case 'r':
if (name.length === 1) ret = r;
else ret.r = r;
break;
case 'g':
if (name.length === 1) ret = g;
else ret.g = g;
break;
case 'b':
if (name.length === 1) ret = b;
else ret.b = b;
break;
case 'a':
if (name.length === 1) ret = a;
else ret.a = a;
break;
case 'h':
if (name.length === 1) ret = h;
else ret.h = h;
break;
case 's':
if (name.length === 1) ret = s;
else ret.s = s;
break;
case 'v':
if (name.length === 1) ret = v;
else ret.v = v;
break;
}
}
return !name.length ? val.call($this, 'all') : ret;
}
}
if (context != null && context === $this) return;
if (name == null) name = '';
let changed = false;
if (value == null) {
if (r != null) {
r = null;
changed = true;
}
if (g != null) {
g = null;
changed = true;
}
if (b != null) {
b = null;
changed = true;
}
if (a != null) {
a = null;
changed = true;
}
if (h != null) {
h = null;
changed = true;
}
if (s != null) {
s = null;
changed = true;
}
if (v != null) {
v = null;
changed = true;
}
changed && fireChangeEvents.call($this, context || $this);
return;
}
switch (name.toLowerCase()) {
case 'ahex': return ColorMethods.rgbaToHex({ r, g, b, a });
case 'hex': return val('ahex').substring(0, 6);
case 'all': return { r, g, b, a, h, s, v, hex: val.call($this, 'hex'), ahex: val.call($this, 'ahex') };
case 'ahex':
case 'hex':
const ret = ColorMethods.hexToRgba((value && (value.ahex || value.hex)) || value || 'none');
val.call($this, 'rgba', { r: ret.r, g: ret.g, b: ret.b, a: name === 'ahex' ? ret.a : a != null ? a : 255 }, context);
break;
default:
let ret = {};
if (value && (value.ahex != null || value.hex != null)) {
val.call($this, 'ahex', value.ahex || value.hex || '00000000', context);
return;
}
const newV = {};
let rgb = false, hsv = false;
if (value.r !== undefined && !name.includes('r')) name += 'r';
if (value.g !== undefined && !name.includes('g')) name += 'g';
if (value.b !== undefined && !name.includes('b')) name += 'b';
if (value.a !== undefined && !name.includes('a')) name += 'a';
if (value.h !== undefined && !name.includes('h')) name += 'h';
if (value.s !== undefined && !name.includes('s')) name += 's';
if (value.v !== undefined && !name.includes('v')) name += 'v';
for (let i = 0; i < name.length; i++) {
switch (name.charAt(i)) {
case 'r':
if (name.length === 1) ret = r;
else ret.r = r;
if (hsv) continue;
rgb = true;
newV.r = (value && value.r && value.r | 0) || (value && value | 0) || 0;
if (newV.r < 0) newV.r = 0;
else if (newV.r > 255) newV.r = 255;
if (r !== newV.r) {
({r} = newV);
changed = true;
}
break;
case 'g':
if (name.length === 1) ret = g;
else ret.g = g;
if (hsv) continue;
rgb = true;
newV.g = (value && value.g && value.g | 0) || (value && value | 0) || 0;
if (newV.g < 0) newV.g = 0;
else if (newV.g > 255) newV.g = 255;
if (g !== newV.g) {
({g} = newV);
changed = true;
}
break;
case 'b':
if (name.length === 1) ret = b;
else ret.b = b;
if (hsv) continue;
rgb = true;
newV.b = (value && value.b && value.b | 0) || (value && value | 0) || 0;
if (newV.b < 0) newV.b = 0;
else if (newV.b > 255) newV.b = 255;
if (b !== newV.b) {
({b} = newV);
changed = true;
}
break;
case 'a':
if (name.length === 1) ret = a;
else ret.a = a;
newV.a = value && value.a != null ? value.a | 0 : value != null ? value | 0 : 255;
if (newV.a < 0) newV.a = 0;
else if (newV.a > 255) newV.a = 255;
if (a !== newV.a) {
({a} = newV);
changed = true;
}
break;
case 'h':
if (name.length === 1) ret = h;
else ret.h = h;
if (rgb) continue;
hsv = true;
newV.h = (value && value.h && value.h | 0) || (value && value | 0) || 0;
if (newV.h < 0) newV.h = 0;
else if (newV.h > 360) newV.h = 360;
if (h !== newV.h) {
({h} = newV);
changed = true;
}
break;
case 's':
if (name.length === 1) ret = s;
else ret.s = s;
if (rgb) continue;
hsv = true;
newV.s = value && value.s != null ? value.s | 0 : value != null ? value | 0 : 100;
if (newV.s < 0) newV.s = 0;
else if (newV.s > 100) newV.s = 100;
if (s !== newV.s) {
({s} = newV);
changed = true;
}
break;
case 'v':
if (name.length === 1) ret = v;
else ret.v = v;
if (rgb) continue;
hsv = true;
newV.v = value && value.v != null ? value.v | 0 : value != null ? value | 0 : 100;
if (newV.v < 0) newV.v = 0;
else if (newV.v > 100) newV.v = 100;
if (v !== newV.v) {
({v} = newV);
changed = true;
}
break;
}
}
return !name.length ? val.call($this, 'all') : ret;
}
}
if (context != null && context === $this) return;
if (name == null) name = '';
let changed = false;
if (value == null) {
if (r != null) {
r = null;
changed = true;
}
if (g != null) {
g = null;
changed = true;
}
if (b != null) {
b = null;
changed = true;
}
if (a != null) {
a = null;
changed = true;
}
if (h != null) {
h = null;
changed = true;
}
if (s != null) {
s = null;
changed = true;
}
if (v != null) {
v = null;
changed = true;
}
changed && fireChangeEvents.call($this, context || $this);
return;
}
switch (name.toLowerCase()) {
case 'ahex':
case 'hex':
const ret = ColorMethods.hexToRgba((value && (value.ahex || value.hex)) || value || 'none');
val.call($this, 'rgba', { r: ret.r, g: ret.g, b: ret.b, a: name === 'ahex' ? ret.a : a != null ? a : 255 }, context);
break;
default:
if (value && (value.ahex != null || value.hex != null)) {
val.call($this, 'ahex', value.ahex || value.hex || '00000000', context);
return;
}
const newV = {};
let rgb = false, hsv = false;
if (value.r !== undefined && !name.includes('r')) name += 'r';
if (value.g !== undefined && !name.includes('g')) name += 'g';
if (value.b !== undefined && !name.includes('b')) name += 'b';
if (value.a !== undefined && !name.includes('a')) name += 'a';
if (value.h !== undefined && !name.includes('h')) name += 'h';
if (value.s !== undefined && !name.includes('s')) name += 's';
if (value.v !== undefined && !name.includes('v')) name += 'v';
for (let i = 0; i < name.length; i++) {
switch (name.charAt(i)) {
case 'r':
if (hsv) continue;
rgb = true;
newV.r = (value && value.r && value.r | 0) || (value && value | 0) || 0;
if (newV.r < 0) newV.r = 0;
else if (newV.r > 255) newV.r = 255;
if (r !== newV.r) {
({r} = newV);
changed = true;
if (changed) {
if (rgb) {
r = r || 0;
g = g || 0;
b = b || 0;
const ret = ColorMethods.rgbToHsv({ r, g, b });
({h, s, v} = ret);
} else if (hsv) {
h = h || 0;
s = s != null ? s : 100;
v = v != null ? v : 100;
const ret = ColorMethods.hsvToRgb({ h, s, v });
({r, g, b} = ret);
}
break;
case 'g':
if (hsv) continue;
rgb = true;
newV.g = (value && value.g && value.g | 0) || (value && value | 0) || 0;
if (newV.g < 0) newV.g = 0;
else if (newV.g > 255) newV.g = 255;
if (g !== newV.g) {
({g} = newV);
changed = true;
}
break;
case 'b':
if (hsv) continue;
rgb = true;
newV.b = (value && value.b && value.b | 0) || (value && value | 0) || 0;
if (newV.b < 0) newV.b = 0;
else if (newV.b > 255) newV.b = 255;
if (b !== newV.b) {
({b} = newV);
changed = true;
}
break;
case 'a':
newV.a = value && value.a != null ? value.a | 0 : value != null ? value | 0 : 255;
if (newV.a < 0) newV.a = 0;
else if (newV.a > 255) newV.a = 255;
if (a !== newV.a) {
({a} = newV);
changed = true;
}
break;
case 'h':
if (rgb) continue;
hsv = true;
newV.h = (value && value.h && value.h | 0) || (value && value | 0) || 0;
if (newV.h < 0) newV.h = 0;
else if (newV.h > 360) newV.h = 360;
if (h !== newV.h) {
({h} = newV);
changed = true;
}
break;
case 's':
if (rgb) continue;
hsv = true;
newV.s = value && value.s != null ? value.s | 0 : value != null ? value | 0 : 100;
if (newV.s < 0) newV.s = 0;
else if (newV.s > 100) newV.s = 100;
if (s !== newV.s) {
({s} = newV);
changed = true;
}
break;
case 'v':
if (rgb) continue;
hsv = true;
newV.v = value && value.v != null ? value.v | 0 : value != null ? value | 0 : 100;
if (newV.v < 0) newV.v = 0;
else if (newV.v > 100) newV.v = 100;
if (v !== newV.v) {
({v} = newV);
changed = true;
}
break;
a = a != null ? a : 255;
fireChangeEvents.call($this, context || $this);
}
break;
}
if (changed) {
if (rgb) {
r = r || 0;
g = g || 0;
b = b || 0;
const ret = ColorMethods.rgbToHsv({ r, g, b });
({h, s, v} = ret);
} else if (hsv) {
h = h || 0;
s = s != null ? s : 100;
v = v != null ? v : 100;
const ret = ColorMethods.hsvToRgb({ h, s, v });
({r, g, b} = ret);
}
a = a != null ? a : 255;
fireChangeEvents.call($this, context || $this);
}
function bind (callback) {
if (typeof callback === 'function') changeEvents.push(callback);
}
function unbind (callback) {
if (typeof callback !== 'function') return;
let i;
while ((i = changeEvents.includes(callback))) {
changeEvents.splice(i, 1);
}
break;
}
}
function bind (callback) {
if (typeof callback === 'function') changeEvents.push(callback);
}
function unbind (callback) {
if (typeof callback !== 'function') return;
let i;
while ((i = changeEvents.includes(callback))) {
changeEvents.splice(i, 1);
function destroy () {
changeEvents = null;
}
}
function destroy () {
changeEvents = null;
}
let r, g, b, a, h, s, v, changeEvents = [];
let r, g, b, a, h, s, v, changeEvents = [];
$.extend(true, $this, {
// public properties and methods
val,
bind,
unbind,
destroy
});
if (init) {
if (init.ahex != null) {
val('ahex', init);
} else if (init.hex != null) {
val(
(init.a != null ? 'a' : '') + 'hex',
init.a != null
? {ahex: init.hex + ColorMethods.intToHex(init.a)}
: init
);
} else if (init.r != null && init.g != null && init.b != null) {
val('rgb' + (init.a != null ? 'a' : ''), init);
} else if (init.h != null && init.s != null && init.v != null) {
val('hsv' + (init.a != null ? 'a' : ''), init);
$.extend(true, $this, {
// public properties and methods
val,
bind,
unbind,
destroy
});
if (init) {
if (init.ahex != null) {
val('ahex', init);
} else if (init.hex != null) {
val(
(init.a != null ? 'a' : '') + 'hex',
init.a != null
? {ahex: init.hex + ColorMethods.intToHex(init.a)}
: init
);
} else if (init.r != null && init.g != null && init.b != null) {
val('rgb' + (init.a != null ? 'a' : ''), init);
} else if (init.h != null && init.s != null && init.v != null) {
val('hsv' + (init.a != null ? 'a' : ''), init);
}
}
}
},

File diff suppressed because one or more lines are too long

View File

@@ -61,6 +61,13 @@ if (!window.console) {
}
export default function ($) {
if (!$.loadingStylesheets) {
$.loadingStylesheets = [];
}
const stylesheet = 'jgraduate/css/jgraduate.css';
if (!$.loadingStylesheets.includes(stylesheet)) {
$.loadingStylesheets.push(stylesheet);
}
$.jGraduate = {
Paint: function (opt) {
const options = opt || {};
@@ -363,6 +370,7 @@ export default function ($) {
}, svg);
}
let stopGroup; // eslint-disable-line prefer-const
if (isSolid) {
grad = curGradient = $('#' + id + '_lg_jgraduate_grad')[0];
color = $this.paint[curType];
@@ -424,7 +432,7 @@ export default function ($) {
// stop visuals created here
const beginCoord = $('<div/>').attr({
'class': 'grad_coord jGraduate_lg_field',
class: 'grad_coord jGraduate_lg_field',
title: 'Begin Stop'
}).text(1).css({
top: y1 * MAX,
@@ -437,7 +445,7 @@ export default function ($) {
}).attr('title', 'End stop').data('coord', 'end').appendTo(container);
const centerCoord = $('<div/>').attr({
'class': 'grad_coord jGraduate_rg_field',
class: 'grad_coord jGraduate_rg_field',
title: 'Center stop'
}).text('C').css({
top: cy * MAX,
@@ -464,6 +472,7 @@ export default function ($) {
// }, 500);
// });
let showFocus;
$.each(['x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'fx', 'fy'], function (i, attr) {
const isRadial = isNaN(attr[1]);
@@ -548,7 +557,7 @@ export default function ($) {
let thisAlpha = (parseFloat(stopOpacity) * 255).toString(16);
while (thisAlpha.length < 2) { thisAlpha = '0' + thisAlpha; }
color = stopColor.substr(1) + thisAlpha;
$('#' + id + '_jGraduate_stopPicker').css({'left': 100, 'bottom': 15}).jPicker({
$('#' + id + '_jGraduate_stopPicker').css({left: 100, bottom: 15}).jPicker({
window: { title: 'Pick the start color and opacity for the gradient' },
images: { clientPath: $settings.images.clientPath },
color: { active: color, alphaSupport: true }
@@ -714,7 +723,7 @@ export default function ($) {
stopMakerSVG.appendChild(delStop);
});
const stopGroup = mkElem('g', {}, stopMakerSVG);
stopGroup = mkElem('g', {}, stopMakerSVG);
mkElem('line', {
x1: 10,
@@ -811,7 +820,7 @@ export default function ($) {
let offset;
// No match, so show focus point
let showFocus = false;
showFocus = false;
previewRect.setAttribute('fill-opacity', gradalpha / 100);

File diff suppressed because one or more lines are too long

11
editor/jquery-svg.js vendored
View File

@@ -5,18 +5,15 @@
*
*/
// Dependencies:
// 1) jquery
// This fixes $(...).attr() to work as expected with SVG elements.
// Does not currently use *AttributeNS() since we rarely need that.
// See https://api.jquery.com/attr/ for basic documentation of .attr()
// Additional functionality:
// - When getting attributes, a string that's a number is return as type number.
// - If an array is supplied as first parameter, multiple values are returned
// as an object with values for each given attributes
// - When getting attributes, a string that's a number is returned as type number.
// - If an array is supplied as the first parameter, multiple values are returned
// as an object with values for each given attribute
export default function ($) {
const proxied = $.fn.attr,
@@ -48,7 +45,7 @@ export default function ($) {
return obj;
}
if (typeof key === 'object') {
// Setting attributes form object
// Setting attributes from object
for (const v in key) {
elem.setAttribute(v, key[v]);
}

View File

@@ -1,3 +1,4 @@
/* globals jsPDF */
/*
* svgToPdf.js
*

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'af',
dir: 'ltr',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'fa',
dir: 'ltr',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

View File

@@ -1,4 +1,4 @@
/* globals svgEditor */
import svgEditor from '../svg-editor.js';
svgEditor.readLang({
lang: 'lang',
dir: 'dir',

Some files were not shown because too many files have changed in this diff Show More