- Breaking change: Extension now formatted as export (and this is set to editor, including for callback)
- Breaking change: Locale now formatted as export - Breaking change: Moved out remaining modular i18n (imagelib) to own folder - Breaking change: Drop `executeAfterLoads` (and getJSPDF/getCanvg) - Breaking change: `RGBColor` must accept `new` - Breaking change: canvg - `stackBlurCanvasRGBA` must be set now by function (`setStackBlurCanvasRGBA`) rather than global; `canvg` now a named export - Breaking change: Avoid passing `canvg`/`buildCanvgCallback` to extensions (have them import) - Fix: i18nize imaglib more deeply - Fix: Positioning of Document Properties dialog (Fixes #246) - Fix (regression): PDF Export (Fixes #249) - Fix (regression): Add polyfill for `ChildNode`/`ParentNode` (and use further) - Fix (regression): Apply Babel universally to dependencies - Fix (regression): Ordering of `uaPrefix` function in `svgEditor.js` - Fix (regression): Embedded API - Fix (embedded editor): Fix backspace key in Firefox so it doesn't navigate out of frame - Fix: Alert if no exportWindow for PDF (e.g., if blocked) - Refactoring( RGBColor) `RGBColor` as class, without rebuilding constants, optimize string replacement, move methods to prototype, use templates and object literals, use `Object.keys` - Refactoring (canvg) Use classes more internally, use shorthand objects; array extras, return to lazy-loading - Refactoring: Use Promises in place of `$.getScript`; always return Promises in case deciding to await resolving - Refactoring: Avoid importing `RGBColor` into `svgutils.js` (jsPDF imports it itself) - Refactoring: Arrow functions, destructuring, shorter property references - Refactoring: Fix `lang` and `dir` for locales (though not in use currently anyways) - Refactoring: Provide path config for canvg, jspdf
This commit is contained in:
535
dist/extensions/ext-arrows.js
vendored
535
dist/extensions/ext-arrows.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_arrows = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -10,290 +10,295 @@
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('Arrows', function (S) {
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var $ = jQuery;
|
||||
// {svgcontent} = S,
|
||||
var addElem = S.addSvgElementFromJson,
|
||||
nonce = S.nonce,
|
||||
langList = {
|
||||
en: [{ id: 'arrow_none', textContent: 'No arrow' }],
|
||||
fr: [{ id: 'arrow_none', textContent: 'Sans flèche' }]
|
||||
},
|
||||
prefix = 'se_arrow_';
|
||||
var extArrows = {
|
||||
name: 'Arrows',
|
||||
init: function init(S) {
|
||||
var svgEditor = this;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var $ = jQuery;
|
||||
// {svgcontent} = S,
|
||||
var addElem = S.addSvgElementFromJson,
|
||||
nonce = S.nonce,
|
||||
langList = {
|
||||
en: [{ id: 'arrow_none', textContent: 'No arrow' }],
|
||||
fr: [{ id: 'arrow_none', textContent: 'Sans flèche' }]
|
||||
},
|
||||
prefix = 'se_arrow_';
|
||||
|
||||
|
||||
var selElems = void 0,
|
||||
arrowprefix = void 0,
|
||||
randomizeIds = S.randomize_ids;
|
||||
var selElems = void 0,
|
||||
arrowprefix = void 0,
|
||||
randomizeIds = S.randomize_ids;
|
||||
|
||||
function setArrowNonce(window, n) {
|
||||
randomizeIds = true;
|
||||
arrowprefix = prefix + n + '_';
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
|
||||
function unsetArrowNonce(window) {
|
||||
randomizeIds = false;
|
||||
arrowprefix = prefix;
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
|
||||
svgCanvas.bind('setnonce', setArrowNonce);
|
||||
svgCanvas.bind('unsetnonce', unsetArrowNonce);
|
||||
|
||||
if (randomizeIds) {
|
||||
arrowprefix = prefix + nonce + '_';
|
||||
} else {
|
||||
arrowprefix = prefix;
|
||||
}
|
||||
|
||||
var pathdata = {
|
||||
fw: { d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw' },
|
||||
bk: { d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk' }
|
||||
};
|
||||
|
||||
function getLinked(elem, attr) {
|
||||
var str = elem.getAttribute(attr);
|
||||
if (!str) {
|
||||
return null;
|
||||
function setArrowNonce(window, n) {
|
||||
randomizeIds = true;
|
||||
arrowprefix = prefix + n + '_';
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
var m = str.match(/\(#(.*)\)/);
|
||||
if (!m || m.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
return S.getElem(m[1]);
|
||||
}
|
||||
|
||||
function showPanel(on) {
|
||||
$('#arrow_panel').toggle(on);
|
||||
if (on) {
|
||||
function unsetArrowNonce(window) {
|
||||
randomizeIds = false;
|
||||
arrowprefix = prefix;
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
|
||||
svgCanvas.bind('setnonce', setArrowNonce);
|
||||
svgCanvas.bind('unsetnonce', unsetArrowNonce);
|
||||
|
||||
if (randomizeIds) {
|
||||
arrowprefix = prefix + nonce + '_';
|
||||
} else {
|
||||
arrowprefix = prefix;
|
||||
}
|
||||
|
||||
var pathdata = {
|
||||
fw: { d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw' },
|
||||
bk: { d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk' }
|
||||
};
|
||||
|
||||
function getLinked(elem, attr) {
|
||||
var str = elem.getAttribute(attr);
|
||||
if (!str) {
|
||||
return null;
|
||||
}
|
||||
var m = str.match(/\(#(.*)\)/);
|
||||
if (!m || m.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
return S.getElem(m[1]);
|
||||
}
|
||||
|
||||
function showPanel(on) {
|
||||
$('#arrow_panel').toggle(on);
|
||||
if (on) {
|
||||
var el = selElems[0];
|
||||
var end = el.getAttribute('marker-end');
|
||||
var start = el.getAttribute('marker-start');
|
||||
var mid = el.getAttribute('marker-mid');
|
||||
var val = void 0;
|
||||
if (end && start) {
|
||||
val = 'both';
|
||||
} else if (end) {
|
||||
val = 'end';
|
||||
} else if (start) {
|
||||
val = 'start';
|
||||
} else if (mid) {
|
||||
val = 'mid';
|
||||
if (mid.includes('bk')) {
|
||||
val = 'mid_bk';
|
||||
}
|
||||
}
|
||||
|
||||
if (!start && !mid && !end) {
|
||||
val = 'none';
|
||||
}
|
||||
|
||||
$('#arrow_list').val(val);
|
||||
}
|
||||
}
|
||||
|
||||
function resetMarker() {
|
||||
var el = selElems[0];
|
||||
var end = el.getAttribute('marker-end');
|
||||
var start = el.getAttribute('marker-start');
|
||||
var mid = el.getAttribute('marker-mid');
|
||||
var val = void 0;
|
||||
if (end && start) {
|
||||
val = 'both';
|
||||
} else if (end) {
|
||||
val = 'end';
|
||||
} else if (start) {
|
||||
val = 'start';
|
||||
} else if (mid) {
|
||||
val = 'mid';
|
||||
if (mid.includes('bk')) {
|
||||
val = 'mid_bk';
|
||||
}
|
||||
el.removeAttribute('marker-start');
|
||||
el.removeAttribute('marker-mid');
|
||||
el.removeAttribute('marker-end');
|
||||
}
|
||||
|
||||
function addMarker(dir, type, id) {
|
||||
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
||||
id = id || arrowprefix + dir;
|
||||
|
||||
var data = pathdata[dir];
|
||||
|
||||
if (type === 'mid') {
|
||||
data.refx = 5;
|
||||
}
|
||||
|
||||
if (!start && !mid && !end) {
|
||||
val = 'none';
|
||||
}
|
||||
|
||||
$('#arrow_list').val(val);
|
||||
}
|
||||
}
|
||||
|
||||
function resetMarker() {
|
||||
var el = selElems[0];
|
||||
el.removeAttribute('marker-start');
|
||||
el.removeAttribute('marker-mid');
|
||||
el.removeAttribute('marker-end');
|
||||
}
|
||||
|
||||
function addMarker(dir, type, id) {
|
||||
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
||||
id = id || arrowprefix + dir;
|
||||
|
||||
var data = pathdata[dir];
|
||||
|
||||
if (type === 'mid') {
|
||||
data.refx = 5;
|
||||
}
|
||||
|
||||
var marker = S.getElem(id);
|
||||
if (!marker) {
|
||||
marker = addElem({
|
||||
element: 'marker',
|
||||
attr: {
|
||||
viewBox: '0 0 10 10',
|
||||
id: id,
|
||||
refY: 5,
|
||||
markerUnits: 'strokeWidth',
|
||||
markerWidth: 5,
|
||||
markerHeight: 5,
|
||||
orient: 'auto',
|
||||
style: 'pointer-events:none' // Currently needed for Opera
|
||||
}
|
||||
});
|
||||
var arrow = addElem({
|
||||
element: 'path',
|
||||
attr: {
|
||||
d: data.d,
|
||||
fill: '#000000'
|
||||
}
|
||||
});
|
||||
marker.appendChild(arrow);
|
||||
S.findDefs().appendChild(marker);
|
||||
}
|
||||
|
||||
marker.setAttribute('refX', data.refx);
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
function setArrow() {
|
||||
resetMarker();
|
||||
|
||||
var type = this.value;
|
||||
if (type === 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set marker on element
|
||||
var dir = 'fw';
|
||||
if (type === 'mid_bk') {
|
||||
type = 'mid';
|
||||
dir = 'bk';
|
||||
} else if (type === 'both') {
|
||||
addMarker('bk', type);
|
||||
svgCanvas.changeSelectedAttribute('marker-start', 'url(#' + pathdata.bk.id + ')');
|
||||
type = 'end';
|
||||
dir = 'fw';
|
||||
} else if (type === 'start') {
|
||||
dir = 'bk';
|
||||
}
|
||||
|
||||
addMarker(dir, type);
|
||||
svgCanvas.changeSelectedAttribute('marker-' + type, 'url(#' + pathdata[dir].id + ')');
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
function colorChanged(elem) {
|
||||
var color = elem.getAttribute('stroke');
|
||||
var mtypes = ['start', 'mid', 'end'];
|
||||
var defs = S.findDefs();
|
||||
|
||||
$.each(mtypes, function (i, type) {
|
||||
var marker = getLinked(elem, 'marker-' + type);
|
||||
var marker = S.getElem(id);
|
||||
if (!marker) {
|
||||
return;
|
||||
}
|
||||
|
||||
var curColor = $(marker).children().attr('fill');
|
||||
var curD = $(marker).children().attr('d');
|
||||
if (curColor === color) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allMarkers = $(defs).find('marker');
|
||||
var newMarker = null;
|
||||
// Different color, check if already made
|
||||
allMarkers.each(function () {
|
||||
var attrs = $(this).children().attr(['fill', 'd']);
|
||||
if (attrs.fill === color && attrs.d === curD) {
|
||||
// Found another marker with this color and this path
|
||||
newMarker = this;
|
||||
}
|
||||
});
|
||||
|
||||
if (!newMarker) {
|
||||
// Create a new marker with this color
|
||||
var lastId = marker.id;
|
||||
var dir = lastId.includes('_fw') ? 'fw' : 'bk';
|
||||
|
||||
newMarker = addMarker(dir, type, arrowprefix + dir + allMarkers.length);
|
||||
|
||||
$(newMarker).children().attr('fill', color);
|
||||
}
|
||||
|
||||
$(elem).attr('marker-' + type, 'url(#' + newMarker.id + ')');
|
||||
|
||||
// Check if last marker can be removed
|
||||
var remove = true;
|
||||
$(S.svgcontent).find('line, polyline, path, polygon').each(function () {
|
||||
var elem = this;
|
||||
$.each(mtypes, function (j, mtype) {
|
||||
if ($(elem).attr('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
remove = false;
|
||||
return remove;
|
||||
marker = addElem({
|
||||
element: 'marker',
|
||||
attr: {
|
||||
viewBox: '0 0 10 10',
|
||||
id: id,
|
||||
refY: 5,
|
||||
markerUnits: 'strokeWidth',
|
||||
markerWidth: 5,
|
||||
markerHeight: 5,
|
||||
orient: 'auto',
|
||||
style: 'pointer-events:none' // Currently needed for Opera
|
||||
}
|
||||
});
|
||||
if (!remove) {
|
||||
return false;
|
||||
var arrow = addElem({
|
||||
element: 'path',
|
||||
attr: {
|
||||
d: data.d,
|
||||
fill: '#000000'
|
||||
}
|
||||
});
|
||||
marker.append(arrow);
|
||||
S.findDefs().append(marker);
|
||||
}
|
||||
|
||||
marker.setAttribute('refX', data.refx);
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
function setArrow() {
|
||||
resetMarker();
|
||||
|
||||
var type = this.value;
|
||||
if (type === 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set marker on element
|
||||
var dir = 'fw';
|
||||
if (type === 'mid_bk') {
|
||||
type = 'mid';
|
||||
dir = 'bk';
|
||||
} else if (type === 'both') {
|
||||
addMarker('bk', type);
|
||||
svgCanvas.changeSelectedAttribute('marker-start', 'url(#' + pathdata.bk.id + ')');
|
||||
type = 'end';
|
||||
dir = 'fw';
|
||||
} else if (type === 'start') {
|
||||
dir = 'bk';
|
||||
}
|
||||
|
||||
addMarker(dir, type);
|
||||
svgCanvas.changeSelectedAttribute('marker-' + type, 'url(#' + pathdata[dir].id + ')');
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
function colorChanged(elem) {
|
||||
var color = elem.getAttribute('stroke');
|
||||
var mtypes = ['start', 'mid', 'end'];
|
||||
var defs = S.findDefs();
|
||||
|
||||
$.each(mtypes, function (i, type) {
|
||||
var marker = getLinked(elem, 'marker-' + type);
|
||||
if (!marker) {
|
||||
return;
|
||||
}
|
||||
|
||||
var curColor = $(marker).children().attr('fill');
|
||||
var curD = $(marker).children().attr('d');
|
||||
if (curColor === color) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allMarkers = $(defs).find('marker');
|
||||
var newMarker = null;
|
||||
// Different color, check if already made
|
||||
allMarkers.each(function () {
|
||||
var attrs = $(this).children().attr(['fill', 'd']);
|
||||
if (attrs.fill === color && attrs.d === curD) {
|
||||
// Found another marker with this color and this path
|
||||
newMarker = this;
|
||||
}
|
||||
});
|
||||
|
||||
if (!newMarker) {
|
||||
// Create a new marker with this color
|
||||
var lastId = marker.id;
|
||||
var dir = lastId.includes('_fw') ? 'fw' : 'bk';
|
||||
|
||||
newMarker = addMarker(dir, type, arrowprefix + dir + allMarkers.length);
|
||||
|
||||
$(newMarker).children().attr('fill', color);
|
||||
}
|
||||
|
||||
$(elem).attr('marker-' + type, 'url(#' + newMarker.id + ')');
|
||||
|
||||
// Check if last marker can be removed
|
||||
var remove = true;
|
||||
$(S.svgcontent).find('line, polyline, path, polygon').each(function () {
|
||||
var elem = this;
|
||||
$.each(mtypes, function (j, mtype) {
|
||||
if ($(elem).attr('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
remove = false;
|
||||
return remove;
|
||||
}
|
||||
});
|
||||
if (!remove) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Not found, so can safely remove
|
||||
if (remove) {
|
||||
$(marker).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Not found, so can safely remove
|
||||
if (remove) {
|
||||
$(marker).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Arrows',
|
||||
context_tools: [{
|
||||
type: 'select',
|
||||
panel: 'arrow_panel',
|
||||
title: 'Select arrow type',
|
||||
id: 'arrow_list',
|
||||
options: {
|
||||
none: 'No arrow',
|
||||
end: '---->',
|
||||
start: '<----',
|
||||
both: '<--->',
|
||||
mid: '-->--',
|
||||
mid_bk: '--<--'
|
||||
return {
|
||||
name: 'Arrows',
|
||||
context_tools: [{
|
||||
type: 'select',
|
||||
panel: 'arrow_panel',
|
||||
title: 'Select arrow type',
|
||||
id: 'arrow_list',
|
||||
options: {
|
||||
none: 'No arrow',
|
||||
end: '---->',
|
||||
start: '<----',
|
||||
both: '<--->',
|
||||
mid: '-->--',
|
||||
mid_bk: '--<--'
|
||||
},
|
||||
defval: 'none',
|
||||
events: {
|
||||
change: setArrow
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#arrow_panel').hide();
|
||||
// Set ID so it can be translated in locale file
|
||||
$('#arrow_list option')[0].id = 'connector_no_arrow';
|
||||
},
|
||||
defval: 'none',
|
||||
events: {
|
||||
change: setArrow
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#arrow_panel').hide();
|
||||
// Set ID so it can be translated in locale file
|
||||
$('#arrow_list option')[0].id = 'connector_no_arrow';
|
||||
},
|
||||
addLangData: function addLangData(lang) {
|
||||
return {
|
||||
data: langList[lang]
|
||||
};
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
addLangData: function addLangData(lang) {
|
||||
return {
|
||||
data: langList[lang]
|
||||
};
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && markerElems.includes(elem.tagName)) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
var markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && markerElems.includes(elem.tagName)) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
var elem = opts.elems[0];
|
||||
if (elem && (elem.getAttribute('marker-start') || elem.getAttribute('marker-mid') || elem.getAttribute('marker-end'))) {
|
||||
// const start = elem.getAttribute('marker-start');
|
||||
// const mid = elem.getAttribute('marker-mid');
|
||||
// const end = elem.getAttribute('marker-end');
|
||||
// Has marker, so see if it should match color
|
||||
colorChanged(elem);
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
var elem = opts.elems[0];
|
||||
if (elem && (elem.getAttribute('marker-start') || elem.getAttribute('marker-mid') || elem.getAttribute('marker-end'))) {
|
||||
// const start = elem.getAttribute('marker-start');
|
||||
// const mid = elem.getAttribute('marker-mid');
|
||||
// const end = elem.getAttribute('marker-end');
|
||||
// Has marker, so see if it should match color
|
||||
colorChanged(elem);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extArrows;
|
||||
|
||||
}());
|
||||
|
||||
144
dist/extensions/ext-closepath.js
vendored
144
dist/extensions/ext-closepath.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_closepath = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -13,85 +13,91 @@
|
||||
|
||||
// This extension adds a simple button to the contextual panel for paths
|
||||
// The button toggles whether the path is open or closed
|
||||
svgEditor.addExtension('ClosePath', function () {
|
||||
var $ = jQuery;
|
||||
var selElems = void 0;
|
||||
var updateButton = function updateButton(path) {
|
||||
var seglist = path.pathSegList,
|
||||
closed = seglist.getItem(seglist.numberOfItems - 1).pathSegType === 1,
|
||||
showbutton = closed ? '#tool_openpath' : '#tool_closepath',
|
||||
hidebutton = closed ? '#tool_closepath' : '#tool_openpath';
|
||||
$(hidebutton).hide();
|
||||
$(showbutton).show();
|
||||
};
|
||||
var showPanel = function showPanel(on) {
|
||||
$('#closepath_panel').toggle(on);
|
||||
if (on) {
|
||||
var extClosepath = {
|
||||
name: 'ClosePath',
|
||||
init: function init() {
|
||||
var $ = jQuery;
|
||||
var svgEditor = this;
|
||||
var selElems = void 0;
|
||||
var updateButton = function updateButton(path) {
|
||||
var seglist = path.pathSegList,
|
||||
closed = seglist.getItem(seglist.numberOfItems - 1).pathSegType === 1,
|
||||
showbutton = closed ? '#tool_openpath' : '#tool_closepath',
|
||||
hidebutton = closed ? '#tool_closepath' : '#tool_openpath';
|
||||
$(hidebutton).hide();
|
||||
$(showbutton).show();
|
||||
};
|
||||
var showPanel = function showPanel(on) {
|
||||
$('#closepath_panel').toggle(on);
|
||||
if (on) {
|
||||
var path = selElems[0];
|
||||
if (path) {
|
||||
updateButton(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
var toggleClosed = function toggleClosed() {
|
||||
var path = selElems[0];
|
||||
if (path) {
|
||||
var seglist = path.pathSegList,
|
||||
last = seglist.numberOfItems - 1;
|
||||
// is closed
|
||||
if (seglist.getItem(last).pathSegType === 1) {
|
||||
seglist.removeItem(last);
|
||||
} else {
|
||||
seglist.appendItem(path.createSVGPathSegClosePath());
|
||||
}
|
||||
updateButton(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
var toggleClosed = function toggleClosed() {
|
||||
var path = selElems[0];
|
||||
if (path) {
|
||||
var seglist = path.pathSegList,
|
||||
last = seglist.numberOfItems - 1;
|
||||
// is closed
|
||||
if (seglist.getItem(last).pathSegType === 1) {
|
||||
seglist.removeItem(last);
|
||||
} else {
|
||||
seglist.appendItem(path.createSVGPathSegClosePath());
|
||||
}
|
||||
updateButton(path);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'ClosePath',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'closepath_icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_openpath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Open path',
|
||||
events: {
|
||||
click: function click() {
|
||||
toggleClosed();
|
||||
return {
|
||||
name: 'ClosePath',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'closepath_icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_openpath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Open path',
|
||||
events: {
|
||||
click: function click() {
|
||||
toggleClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
id: 'tool_closepath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Close path',
|
||||
events: {
|
||||
click: function click() {
|
||||
toggleClosed();
|
||||
}, {
|
||||
id: 'tool_closepath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Close path',
|
||||
events: {
|
||||
click: function click() {
|
||||
toggleClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#closepath_panel').hide();
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
selElems = opts.elems;
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.tagName === 'path') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#closepath_panel').hide();
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
selElems = opts.elems;
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.tagName === 'path') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extClosepath;
|
||||
|
||||
}());
|
||||
|
||||
1107
dist/extensions/ext-connector.js
vendored
1107
dist/extensions/ext-connector.js
vendored
File diff suppressed because it is too large
Load Diff
220
dist/extensions/ext-eyedropper.js
vendored
220
dist/extensions/ext-eyedropper.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_eyedropper = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -11,117 +11,123 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('eyedropper', function (S) {
|
||||
var $ = jQuery;
|
||||
var ChangeElementCommand = S.ChangeElementCommand,
|
||||
svgCanvas = svgEditor.canvas,
|
||||
addToHistory = function addToHistory(cmd) {
|
||||
svgCanvas.undoMgr.addCommandToHistory(cmd);
|
||||
},
|
||||
currentStyle = {
|
||||
fillPaint: 'red', fillOpacity: 1.0,
|
||||
strokePaint: 'black', strokeOpacity: 1.0,
|
||||
strokeWidth: 5, strokeDashArray: null,
|
||||
opacity: 1.0,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'miter'
|
||||
};
|
||||
var extEyedropper = {
|
||||
name: 'eyedropper',
|
||||
init: function init(S) {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var ChangeElementCommand = S.ChangeElementCommand,
|
||||
svgCanvas = svgEditor.canvas,
|
||||
addToHistory = function addToHistory(cmd) {
|
||||
svgCanvas.undoMgr.addCommandToHistory(cmd);
|
||||
},
|
||||
currentStyle = {
|
||||
fillPaint: 'red', fillOpacity: 1.0,
|
||||
strokePaint: 'black', strokeOpacity: 1.0,
|
||||
strokeWidth: 5, strokeDashArray: null,
|
||||
opacity: 1.0,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'miter'
|
||||
};
|
||||
|
||||
function getStyle(opts) {
|
||||
// if we are in eyedropper mode, we don't want to disable the eye-dropper tool
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode === 'eyedropper') {
|
||||
return;
|
||||
}
|
||||
|
||||
var tool = $('#tool_eyedropper');
|
||||
// enable-eye-dropper if one element is selected
|
||||
var elem = null;
|
||||
if (!opts.multiselected && opts.elems[0] && !['svg', 'g', 'use'].includes(opts.elems[0].nodeName)) {
|
||||
elem = opts.elems[0];
|
||||
tool.removeClass('disabled');
|
||||
// grab the current style
|
||||
currentStyle.fillPaint = elem.getAttribute('fill') || 'black';
|
||||
currentStyle.fillOpacity = elem.getAttribute('fill-opacity') || 1.0;
|
||||
currentStyle.strokePaint = elem.getAttribute('stroke');
|
||||
currentStyle.strokeOpacity = elem.getAttribute('stroke-opacity') || 1.0;
|
||||
currentStyle.strokeWidth = elem.getAttribute('stroke-width');
|
||||
currentStyle.strokeDashArray = elem.getAttribute('stroke-dasharray');
|
||||
currentStyle.strokeLinecap = elem.getAttribute('stroke-linecap');
|
||||
currentStyle.strokeLinejoin = elem.getAttribute('stroke-linejoin');
|
||||
currentStyle.opacity = elem.getAttribute('opacity') || 1.0;
|
||||
// disable eye-dropper tool
|
||||
} else {
|
||||
tool.addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'eyedropper',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'eyedropper-icon.xml',
|
||||
buttons: [{
|
||||
id: 'tool_eyedropper',
|
||||
type: 'mode',
|
||||
title: 'Eye Dropper Tool',
|
||||
key: 'I',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('eyedropper');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
// if we have selected an element, grab its paint and enable the eye dropper button
|
||||
selectedChanged: getStyle,
|
||||
elementChanged: getStyle,
|
||||
|
||||
mouseDown: function mouseDown(opts) {
|
||||
function getStyle(opts) {
|
||||
// if we are in eyedropper mode, we don't want to disable the eye-dropper tool
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode === 'eyedropper') {
|
||||
var e = opts.event;
|
||||
var target = e.target;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!['svg', 'g', 'use'].includes(target.nodeName)) {
|
||||
var changes = {};
|
||||
|
||||
var change = function change(elem, attrname, newvalue) {
|
||||
changes[attrname] = elem.getAttribute(attrname);
|
||||
elem.setAttribute(attrname, newvalue);
|
||||
};
|
||||
|
||||
if (currentStyle.fillPaint) {
|
||||
change(target, 'fill', currentStyle.fillPaint);
|
||||
}
|
||||
if (currentStyle.fillOpacity) {
|
||||
change(target, 'fill-opacity', currentStyle.fillOpacity);
|
||||
}
|
||||
if (currentStyle.strokePaint) {
|
||||
change(target, 'stroke', currentStyle.strokePaint);
|
||||
}
|
||||
if (currentStyle.strokeOpacity) {
|
||||
change(target, 'stroke-opacity', currentStyle.strokeOpacity);
|
||||
}
|
||||
if (currentStyle.strokeWidth) {
|
||||
change(target, 'stroke-width', currentStyle.strokeWidth);
|
||||
}
|
||||
if (currentStyle.strokeDashArray) {
|
||||
change(target, 'stroke-dasharray', currentStyle.strokeDashArray);
|
||||
}
|
||||
if (currentStyle.opacity) {
|
||||
change(target, 'opacity', currentStyle.opacity);
|
||||
}
|
||||
if (currentStyle.strokeLinecap) {
|
||||
change(target, 'stroke-linecap', currentStyle.strokeLinecap);
|
||||
}
|
||||
if (currentStyle.strokeLinejoin) {
|
||||
change(target, 'stroke-linejoin', currentStyle.strokeLinejoin);
|
||||
}
|
||||
|
||||
addToHistory(new ChangeElementCommand(target, changes));
|
||||
}
|
||||
var tool = $('#tool_eyedropper');
|
||||
// enable-eye-dropper if one element is selected
|
||||
var elem = null;
|
||||
if (!opts.multiselected && opts.elems[0] && !['svg', 'g', 'use'].includes(opts.elems[0].nodeName)) {
|
||||
elem = opts.elems[0];
|
||||
tool.removeClass('disabled');
|
||||
// grab the current style
|
||||
currentStyle.fillPaint = elem.getAttribute('fill') || 'black';
|
||||
currentStyle.fillOpacity = elem.getAttribute('fill-opacity') || 1.0;
|
||||
currentStyle.strokePaint = elem.getAttribute('stroke');
|
||||
currentStyle.strokeOpacity = elem.getAttribute('stroke-opacity') || 1.0;
|
||||
currentStyle.strokeWidth = elem.getAttribute('stroke-width');
|
||||
currentStyle.strokeDashArray = elem.getAttribute('stroke-dasharray');
|
||||
currentStyle.strokeLinecap = elem.getAttribute('stroke-linecap');
|
||||
currentStyle.strokeLinejoin = elem.getAttribute('stroke-linejoin');
|
||||
currentStyle.opacity = elem.getAttribute('opacity') || 1.0;
|
||||
// disable eye-dropper tool
|
||||
} else {
|
||||
tool.addClass('disabled');
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
name: 'eyedropper',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'eyedropper-icon.xml',
|
||||
buttons: [{
|
||||
id: 'tool_eyedropper',
|
||||
type: 'mode',
|
||||
title: 'Eye Dropper Tool',
|
||||
key: 'I',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('eyedropper');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
// if we have selected an element, grab its paint and enable the eye dropper button
|
||||
selectedChanged: getStyle,
|
||||
elementChanged: getStyle,
|
||||
|
||||
mouseDown: function mouseDown(opts) {
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode === 'eyedropper') {
|
||||
var e = opts.event;
|
||||
var target = e.target;
|
||||
|
||||
if (!['svg', 'g', 'use'].includes(target.nodeName)) {
|
||||
var changes = {};
|
||||
|
||||
var change = function change(elem, attrname, newvalue) {
|
||||
changes[attrname] = elem.getAttribute(attrname);
|
||||
elem.setAttribute(attrname, newvalue);
|
||||
};
|
||||
|
||||
if (currentStyle.fillPaint) {
|
||||
change(target, 'fill', currentStyle.fillPaint);
|
||||
}
|
||||
if (currentStyle.fillOpacity) {
|
||||
change(target, 'fill-opacity', currentStyle.fillOpacity);
|
||||
}
|
||||
if (currentStyle.strokePaint) {
|
||||
change(target, 'stroke', currentStyle.strokePaint);
|
||||
}
|
||||
if (currentStyle.strokeOpacity) {
|
||||
change(target, 'stroke-opacity', currentStyle.strokeOpacity);
|
||||
}
|
||||
if (currentStyle.strokeWidth) {
|
||||
change(target, 'stroke-width', currentStyle.strokeWidth);
|
||||
}
|
||||
if (currentStyle.strokeDashArray) {
|
||||
change(target, 'stroke-dasharray', currentStyle.strokeDashArray);
|
||||
}
|
||||
if (currentStyle.opacity) {
|
||||
change(target, 'opacity', currentStyle.opacity);
|
||||
}
|
||||
if (currentStyle.strokeLinecap) {
|
||||
change(target, 'stroke-linecap', currentStyle.strokeLinecap);
|
||||
}
|
||||
if (currentStyle.strokeLinejoin) {
|
||||
change(target, 'stroke-linejoin', currentStyle.strokeLinejoin);
|
||||
}
|
||||
|
||||
addToHistory(new ChangeElementCommand(target, changes));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extEyedropper;
|
||||
|
||||
}());
|
||||
|
||||
470
dist/extensions/ext-foreignobject.js
vendored
470
dist/extensions/ext-foreignobject.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_foreignobject = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -12,258 +12,262 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('foreignObject', function (S) {
|
||||
var text2xml = S.text2xml,
|
||||
NS = S.NS;
|
||||
var extForeignobject = {
|
||||
name: 'foreignObject',
|
||||
init: function init(S) {
|
||||
var svgEditor = this;
|
||||
var text2xml = S.text2xml,
|
||||
NS = S.NS;
|
||||
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var
|
||||
// {svgcontent} = S,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
svgdoc = S.svgroot.parentNode.ownerDocument;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var
|
||||
// {svgcontent} = S,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
svgdoc = S.svgroot.parentNode.ownerDocument;
|
||||
|
||||
var properlySourceSizeTextArea = function properlySourceSizeTextArea() {
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
var height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
};
|
||||
var properlySourceSizeTextArea = function properlySourceSizeTextArea() {
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
var height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
};
|
||||
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#foreignObject_panel').toggle(on);
|
||||
}
|
||||
|
||||
function toggleSourceButtons(on) {
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#foreign_save, #foreign_cancel').toggle(on);
|
||||
}
|
||||
|
||||
var selElems = void 0,
|
||||
started = void 0,
|
||||
newFO = void 0,
|
||||
editingforeign = false;
|
||||
|
||||
/**
|
||||
* This function sets the content of element elt to the input XML.
|
||||
* @param {String} xmlString - The XML text.
|
||||
* @param elt - the parent element to append to
|
||||
* @returns {Boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
function setForeignString(xmlString) {
|
||||
var elt = selElems[0];
|
||||
try {
|
||||
// convert string into XML document
|
||||
var 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);
|
||||
S.call('changed', [elt]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#foreignObject_panel').toggle(on);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function showForeignEditor() {
|
||||
var elt = selElems[0];
|
||||
if (!elt || editingforeign) {
|
||||
return;
|
||||
function toggleSourceButtons(on) {
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#foreign_save, #foreign_cancel').toggle(on);
|
||||
}
|
||||
editingforeign = true;
|
||||
toggleSourceButtons(true);
|
||||
elt.removeAttribute('fill');
|
||||
|
||||
var str = S.svgToString(elt, 0);
|
||||
$('#svg_source_textarea').val(str);
|
||||
$('#svg_source_editor').fadeIn();
|
||||
properlySourceSizeTextArea();
|
||||
$('#svg_source_textarea').focus();
|
||||
}
|
||||
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'foreignObject',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'foreignobject-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_foreign',
|
||||
type: 'mode',
|
||||
title: 'Foreign Object Tool',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('foreign');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
id: 'edit_foreign',
|
||||
type: 'context',
|
||||
panel: 'foreignObject_panel',
|
||||
title: 'Edit ForeignObject Content',
|
||||
events: {
|
||||
click: function click() {
|
||||
showForeignEditor();
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's width",
|
||||
id: 'foreign_width',
|
||||
label: 'w',
|
||||
size: 3,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('width', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's height",
|
||||
id: 'foreign_height',
|
||||
label: 'h',
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('height', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's font size",
|
||||
id: 'foreign_font_size',
|
||||
label: 'font-size',
|
||||
size: 2,
|
||||
defval: 16,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('font-size', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#foreignObject_panel').hide();
|
||||
|
||||
var endChanges = function endChanges() {
|
||||
$('#svg_source_editor').hide();
|
||||
var selElems = void 0,
|
||||
started = void 0,
|
||||
newFO = void 0,
|
||||
editingforeign = false;
|
||||
$('#svg_source_textarea').blur();
|
||||
toggleSourceButtons(false);
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */$('#tool_source_save').clone().hide().attr('id', 'foreign_save').unbind().appendTo('#tool_source_back').click(function () {
|
||||
if (!editingforeign) {
|
||||
return;
|
||||
/**
|
||||
* This function sets the content of element elt to the input XML.
|
||||
* @param {String} xmlString - The XML text.
|
||||
* @param elt - the parent element to append to
|
||||
* @returns {Boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
function setForeignString(xmlString) {
|
||||
var elt = selElems[0];
|
||||
try {
|
||||
// convert string into XML document
|
||||
var 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.replaceWith(svgdoc.importNode(newDoc.documentElement.firstChild, true));
|
||||
S.call('changed', [elt]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function showForeignEditor() {
|
||||
var elt = selElems[0];
|
||||
if (!elt || editingforeign) {
|
||||
return;
|
||||
}
|
||||
editingforeign = true;
|
||||
toggleSourceButtons(true);
|
||||
elt.removeAttribute('fill');
|
||||
|
||||
var str = S.svgToString(elt, 0);
|
||||
$('#svg_source_textarea').val(str);
|
||||
$('#svg_source_editor').fadeIn();
|
||||
properlySourceSizeTextArea();
|
||||
$('#svg_source_textarea').focus();
|
||||
}
|
||||
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'foreignObject',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'foreignobject-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_foreign',
|
||||
type: 'mode',
|
||||
title: 'Foreign Object Tool',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('foreign');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
id: 'edit_foreign',
|
||||
type: 'context',
|
||||
panel: 'foreignObject_panel',
|
||||
title: 'Edit ForeignObject Content',
|
||||
events: {
|
||||
click: function click() {
|
||||
showForeignEditor();
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
if (!setForeignString($('#svg_source_textarea').val())) {
|
||||
$.confirm('Errors found. Revert to original?', function (ok) {
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's width",
|
||||
id: 'foreign_width',
|
||||
label: 'w',
|
||||
size: 3,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('width', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's height",
|
||||
id: 'foreign_height',
|
||||
label: 'h',
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('height', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's font size",
|
||||
id: 'foreign_font_size',
|
||||
label: 'font-size',
|
||||
size: 2,
|
||||
defval: 16,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('font-size', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#foreignObject_panel').hide();
|
||||
|
||||
var endChanges = function endChanges() {
|
||||
$('#svg_source_editor').hide();
|
||||
editingforeign = false;
|
||||
$('#svg_source_textarea').blur();
|
||||
toggleSourceButtons(false);
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */$('#tool_source_save').clone().hide().attr('id', 'foreign_save').unbind().appendTo('#tool_source_back').click(function () {
|
||||
if (!editingforeign) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!setForeignString($('#svg_source_textarea').val())) {
|
||||
$.confirm('Errors found. Revert to original?', function (ok) {
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
endChanges();
|
||||
});
|
||||
} else {
|
||||
endChanges();
|
||||
});
|
||||
} else {
|
||||
}
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* const cancel = */$('#tool_source_cancel').clone().hide().attr('id', 'foreign_cancel').unbind().appendTo('#tool_source_back').click(function () {
|
||||
endChanges();
|
||||
}
|
||||
// setSelectMode();
|
||||
});
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
// const e = opts.event;
|
||||
|
||||
/* const cancel = */$('#tool_source_cancel').clone().hide().attr('id', 'foreign_cancel').unbind().appendTo('#tool_source_back').click(function () {
|
||||
endChanges();
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
// const e = opts.event;
|
||||
if (svgCanvas.getMode() === 'foreign') {
|
||||
started = true;
|
||||
newFO = S.addSvgElementFromJson({
|
||||
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'
|
||||
}
|
||||
});
|
||||
var m = svgdoc.createElementNS(NS.MATH, 'math');
|
||||
m.setAttributeNS(NS.XMLNS, 'xmlns', NS.MATH);
|
||||
m.setAttribute('display', 'inline');
|
||||
var mi = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi.setAttribute('mathvariant', 'normal');
|
||||
mi.textContent = '\u03A6';
|
||||
var mo = svgdoc.createElementNS(NS.MATH, 'mo');
|
||||
mo.textContent = '\u222A';
|
||||
var mi2 = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi2.textContent = '\u2133';
|
||||
m.append(mi, mo, mi2);
|
||||
newFO.append(m);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
// const e = opts.event;
|
||||
if (svgCanvas.getMode() === 'foreign' && started) {
|
||||
var attrs = $(newFO).attr(['width', 'height']);
|
||||
var keep = attrs.width !== '0' || attrs.height !== '0';
|
||||
svgCanvas.addToSelection([newFO], true);
|
||||
|
||||
if (svgCanvas.getMode() === 'foreign') {
|
||||
started = true;
|
||||
newFO = S.addSvgElementFromJson({
|
||||
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'
|
||||
}
|
||||
});
|
||||
var m = svgdoc.createElementNS(NS.MATH, 'math');
|
||||
m.setAttributeNS(NS.XMLNS, 'xmlns', NS.MATH);
|
||||
m.setAttribute('display', 'inline');
|
||||
var mi = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi.setAttribute('mathvariant', 'normal');
|
||||
mi.textContent = '\u03A6';
|
||||
var mo = svgdoc.createElementNS(NS.MATH, 'mo');
|
||||
mo.textContent = '\u222A';
|
||||
var mi2 = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi2.textContent = '\u2133';
|
||||
m.appendChild(mi);
|
||||
m.appendChild(mo);
|
||||
m.appendChild(mi2);
|
||||
newFO.appendChild(m);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
// const e = opts.event;
|
||||
if (svgCanvas.getMode() === 'foreign' && started) {
|
||||
var attrs = $(newFO).attr(['width', 'height']);
|
||||
var keep = attrs.width !== '0' || attrs.height !== '0';
|
||||
svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.tagName === 'foreignObject') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#foreign_font_size').val(elem.getAttribute('font-size'));
|
||||
$('#foreign_width').val(elem.getAttribute('width'));
|
||||
$('#foreign_height').val(elem.getAttribute('height'));
|
||||
showPanel(true);
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.tagName === 'foreignObject') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#foreign_font_size').val(elem.getAttribute('font-size'));
|
||||
$('#foreign_width').val(elem.getAttribute('width'));
|
||||
$('#foreign_height').val(elem.getAttribute('height'));
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extForeignobject;
|
||||
|
||||
}());
|
||||
|
||||
292
dist/extensions/ext-grid.js
vendored
292
dist/extensions/ext-grid.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_grid = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -12,157 +12,163 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('view_grid', function (_ref) {
|
||||
var NS = _ref.NS,
|
||||
getTypeMap = _ref.getTypeMap;
|
||||
var extGrid = {
|
||||
name: 'view_grid',
|
||||
init: function init(_ref) {
|
||||
var NS = _ref.NS,
|
||||
getTypeMap = _ref.getTypeMap;
|
||||
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var svgdoc = document.getElementById('svgcanvas').ownerDocument,
|
||||
assignAttributes = svgCanvas.assignAttributes,
|
||||
hcanvas = document.createElement('canvas'),
|
||||
canvBG = $('#canvasBackground'),
|
||||
units = getTypeMap(),
|
||||
intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var svgdoc = document.getElementById('svgcanvas').ownerDocument,
|
||||
assignAttributes = svgCanvas.assignAttributes,
|
||||
hcanvas = document.createElement('canvas'),
|
||||
canvBG = $('#canvasBackground'),
|
||||
units = getTypeMap(),
|
||||
intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
||||
|
||||
var showGrid = svgEditor.curConfig.showGrid || false;
|
||||
var showGrid = svgEditor.curConfig.showGrid || false;
|
||||
|
||||
$(hcanvas).hide().appendTo('body');
|
||||
$(hcanvas).hide().appendTo('body');
|
||||
|
||||
var canvasGrid = svgdoc.createElementNS(NS.SVG, 'svg');
|
||||
assignAttributes(canvasGrid, {
|
||||
id: 'canvasGrid',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
x: 0,
|
||||
y: 0,
|
||||
overflow: 'visible',
|
||||
display: 'none'
|
||||
});
|
||||
canvBG.append(canvasGrid);
|
||||
var canvasGrid = svgdoc.createElementNS(NS.SVG, 'svg');
|
||||
assignAttributes(canvasGrid, {
|
||||
id: 'canvasGrid',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
x: 0,
|
||||
y: 0,
|
||||
overflow: 'visible',
|
||||
display: 'none'
|
||||
});
|
||||
canvBG.append(canvasGrid);
|
||||
|
||||
// grid-pattern
|
||||
var gridPattern = svgdoc.createElementNS(NS.SVG, 'pattern');
|
||||
assignAttributes(gridPattern, {
|
||||
id: 'gridpattern',
|
||||
patternUnits: 'userSpaceOnUse',
|
||||
x: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
y: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
// grid-pattern
|
||||
var gridPattern = svgdoc.createElementNS(NS.SVG, 'pattern');
|
||||
assignAttributes(gridPattern, {
|
||||
id: 'gridpattern',
|
||||
patternUnits: 'userSpaceOnUse',
|
||||
x: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
y: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
|
||||
var gridimg = svgdoc.createElementNS(NS.SVG, 'image');
|
||||
assignAttributes(gridimg, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
gridPattern.appendChild(gridimg);
|
||||
$('#svgroot defs').append(gridPattern);
|
||||
var gridimg = svgdoc.createElementNS(NS.SVG, 'image');
|
||||
assignAttributes(gridimg, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
gridPattern.append(gridimg);
|
||||
$('#svgroot defs').append(gridPattern);
|
||||
|
||||
// grid-box
|
||||
var gridBox = svgdoc.createElementNS(NS.SVG, 'rect');
|
||||
assignAttributes(gridBox, {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
x: 0,
|
||||
y: 0,
|
||||
'stroke-width': 0,
|
||||
stroke: 'none',
|
||||
fill: 'url(#gridpattern)',
|
||||
style: 'pointer-events: none; display:visible;'
|
||||
});
|
||||
$('#canvasGrid').append(gridBox);
|
||||
// grid-box
|
||||
var gridBox = svgdoc.createElementNS(NS.SVG, 'rect');
|
||||
assignAttributes(gridBox, {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
x: 0,
|
||||
y: 0,
|
||||
'stroke-width': 0,
|
||||
stroke: 'none',
|
||||
fill: 'url(#gridpattern)',
|
||||
style: 'pointer-events: none; display:visible;'
|
||||
});
|
||||
$('#canvasGrid').append(gridBox);
|
||||
|
||||
function updateGrid(zoom) {
|
||||
// TODO: Try this with <line> elements, then compare performance difference
|
||||
var unit = units[svgEditor.curConfig.baseUnit]; // 1 = 1px
|
||||
var uMulti = unit * zoom;
|
||||
// Calculate the main number interval
|
||||
var rawM = 100 / uMulti;
|
||||
var multi = 1;
|
||||
for (var i = 0; i < intervals.length; i++) {
|
||||
var num = intervals[i];
|
||||
multi = num;
|
||||
if (rawM <= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
var bigInt = multi * uMulti;
|
||||
|
||||
// Set the canvas size to the width of the container
|
||||
hcanvas.width = bigInt;
|
||||
hcanvas.height = bigInt;
|
||||
var ctx = hcanvas.getContext('2d');
|
||||
var curD = 0.5;
|
||||
var part = bigInt / 10;
|
||||
|
||||
ctx.globalAlpha = 0.2;
|
||||
ctx.strokeStyle = svgEditor.curConfig.gridColor;
|
||||
for (var _i = 1; _i < 10; _i++) {
|
||||
var subD = Math.round(part * _i) + 0.5;
|
||||
// const lineNum = (i % 2)?12:10;
|
||||
var lineNum = 0;
|
||||
ctx.moveTo(subD, bigInt);
|
||||
ctx.lineTo(subD, lineNum);
|
||||
ctx.moveTo(bigInt, subD);
|
||||
ctx.lineTo(lineNum, subD);
|
||||
}
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.moveTo(curD, bigInt);
|
||||
ctx.lineTo(curD, 0);
|
||||
|
||||
ctx.moveTo(bigInt, curD);
|
||||
ctx.lineTo(0, curD);
|
||||
ctx.stroke();
|
||||
|
||||
var datauri = hcanvas.toDataURL('image/png');
|
||||
gridimg.setAttribute('width', bigInt);
|
||||
gridimg.setAttribute('height', bigInt);
|
||||
gridimg.parentNode.setAttribute('width', bigInt);
|
||||
gridimg.parentNode.setAttribute('height', bigInt);
|
||||
svgCanvas.setHref(gridimg, datauri);
|
||||
}
|
||||
|
||||
function gridUpdate() {
|
||||
if (showGrid) {
|
||||
updateGrid(svgCanvas.getZoom());
|
||||
}
|
||||
$('#canvasGrid').toggle(showGrid);
|
||||
$('#view_grid').toggleClass('push_button_pressed tool_button');
|
||||
}
|
||||
return {
|
||||
name: 'view_grid',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'grid-icon.xml',
|
||||
|
||||
zoomChanged: function zoomChanged(zoom) {
|
||||
if (showGrid) {
|
||||
updateGrid(zoom);
|
||||
}
|
||||
},
|
||||
callback: function callback() {
|
||||
if (showGrid) {
|
||||
gridUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
buttons: [{
|
||||
id: 'view_grid',
|
||||
type: 'context',
|
||||
panel: 'editor_panel',
|
||||
title: 'Show/Hide Grid',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
function updateGrid(zoom) {
|
||||
// TODO: Try this with <line> elements, then compare performance difference
|
||||
var unit = units[svgEditor.curConfig.baseUnit]; // 1 = 1px
|
||||
var uMulti = unit * zoom;
|
||||
// Calculate the main number interval
|
||||
var rawM = 100 / uMulti;
|
||||
var multi = 1;
|
||||
for (var i = 0; i < intervals.length; i++) {
|
||||
var num = intervals[i];
|
||||
multi = num;
|
||||
if (rawM <= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
});
|
||||
var bigInt = multi * uMulti;
|
||||
|
||||
// Set the canvas size to the width of the container
|
||||
hcanvas.width = bigInt;
|
||||
hcanvas.height = bigInt;
|
||||
var ctx = hcanvas.getContext('2d');
|
||||
var curD = 0.5;
|
||||
var part = bigInt / 10;
|
||||
|
||||
ctx.globalAlpha = 0.2;
|
||||
ctx.strokeStyle = svgEditor.curConfig.gridColor;
|
||||
for (var _i = 1; _i < 10; _i++) {
|
||||
var subD = Math.round(part * _i) + 0.5;
|
||||
// const lineNum = (i % 2)?12:10;
|
||||
var lineNum = 0;
|
||||
ctx.moveTo(subD, bigInt);
|
||||
ctx.lineTo(subD, lineNum);
|
||||
ctx.moveTo(bigInt, subD);
|
||||
ctx.lineTo(lineNum, subD);
|
||||
}
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.moveTo(curD, bigInt);
|
||||
ctx.lineTo(curD, 0);
|
||||
|
||||
ctx.moveTo(bigInt, curD);
|
||||
ctx.lineTo(0, curD);
|
||||
ctx.stroke();
|
||||
|
||||
var datauri = hcanvas.toDataURL('image/png');
|
||||
gridimg.setAttribute('width', bigInt);
|
||||
gridimg.setAttribute('height', bigInt);
|
||||
gridimg.parentNode.setAttribute('width', bigInt);
|
||||
gridimg.parentNode.setAttribute('height', bigInt);
|
||||
svgCanvas.setHref(gridimg, datauri);
|
||||
}
|
||||
|
||||
function gridUpdate() {
|
||||
if (showGrid) {
|
||||
updateGrid(svgCanvas.getZoom());
|
||||
}
|
||||
$('#canvasGrid').toggle(showGrid);
|
||||
$('#view_grid').toggleClass('push_button_pressed tool_button');
|
||||
}
|
||||
return {
|
||||
name: 'view_grid',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'grid-icon.xml',
|
||||
|
||||
zoomChanged: function zoomChanged(zoom) {
|
||||
if (showGrid) {
|
||||
updateGrid(zoom);
|
||||
}
|
||||
},
|
||||
callback: function callback() {
|
||||
if (showGrid) {
|
||||
gridUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
buttons: [{
|
||||
id: 'view_grid',
|
||||
type: 'context',
|
||||
panel: 'editor_panel',
|
||||
title: 'Show/Hide Grid',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extGrid;
|
||||
|
||||
}());
|
||||
|
||||
118
dist/extensions/ext-helloworld.js
vendored
118
dist/extensions/ext-helloworld.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_helloworld = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -17,67 +17,73 @@
|
||||
user the point on the canvas that was clicked on.
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('Hello World', function () {
|
||||
var $ = jQuery;
|
||||
var 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.extIconsPath + 'helloworld-icon.xml',
|
||||
var extHelloworld = {
|
||||
name: 'Hello World',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var 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.extIconsPath + 'helloworld-icon.xml',
|
||||
|
||||
// Multiple buttons can be added in this array
|
||||
buttons: [{
|
||||
// Must match the icon ID in helloworld-icon.xml
|
||||
id: 'hello_world',
|
||||
// Multiple buttons can be added in this array
|
||||
buttons: [{
|
||||
// Must match the icon ID in helloworld-icon.xml
|
||||
id: 'hello_world',
|
||||
|
||||
// This indicates that the button will be added to the "mode"
|
||||
// button panel on the left side
|
||||
type: 'mode',
|
||||
// This indicates that the button will be added to the "mode"
|
||||
// button panel on the left side
|
||||
type: 'mode',
|
||||
|
||||
// Tooltip text
|
||||
title: "Say 'Hello World'",
|
||||
// Tooltip text
|
||||
title: "Say 'Hello World'",
|
||||
|
||||
// Events
|
||||
events: {
|
||||
click: function click() {
|
||||
// The action taken when the button is clicked on.
|
||||
// For "mode" buttons, any other button will
|
||||
// automatically be de-pressed.
|
||||
svgCanvas.setMode('hello_world');
|
||||
// Events
|
||||
events: {
|
||||
click: function click() {
|
||||
// The action taken when the button is clicked on.
|
||||
// For "mode" buttons, any other button will
|
||||
// automatically be de-pressed.
|
||||
svgCanvas.setMode('hello_world');
|
||||
}
|
||||
}
|
||||
}],
|
||||
// This is triggered when the main mouse button is pressed down
|
||||
// on the editor canvas (not the tool panels)
|
||||
mouseDown: function mouseDown() {
|
||||
// Check the mode on mousedown
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
// The returned object must include "started" with
|
||||
// a value of true in order for mouseUp to be triggered
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// This is triggered from anywhere, but "started" must have been set
|
||||
// to true (see above). Note that "opts" is an object with event info
|
||||
mouseUp: function mouseUp(opts) {
|
||||
// Check the mode on mouseup
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var text = 'Hello World!\n\nYou clicked here: ' + x + ', ' + y;
|
||||
|
||||
// Show the text using the custom alert function
|
||||
$.alert(text);
|
||||
}
|
||||
}
|
||||
}],
|
||||
// This is triggered when the main mouse button is pressed down
|
||||
// on the editor canvas (not the tool panels)
|
||||
mouseDown: function mouseDown() {
|
||||
// Check the mode on mousedown
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
// The returned object must include "started" with
|
||||
// a value of true in order for mouseUp to be triggered
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// This is triggered from anywhere, but "started" must have been set
|
||||
// to true (see above). Note that "opts" is an object with event info
|
||||
mouseUp: function mouseUp(opts) {
|
||||
// Check the mode on mouseup
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var text = 'Hello World!\n\nYou clicked here: ' + x + ', ' + y;
|
||||
|
||||
// Show the text using the custom alert function
|
||||
$.alert(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
return extHelloworld;
|
||||
|
||||
}());
|
||||
|
||||
984
dist/extensions/ext-imagelib.js
vendored
984
dist/extensions/ext-imagelib.js
vendored
File diff suppressed because it is too large
Load Diff
33
dist/extensions/ext-locale/imagelib/en.js
vendored
Normal file
33
dist/extensions/ext-locale/imagelib/en.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
var svgEditorExtensionLocale_imagelib_en = (function () {
|
||||
'use strict';
|
||||
|
||||
var en = {
|
||||
select_lib: 'Select an image library',
|
||||
show_list: 'Show library list',
|
||||
import_single: 'Import single',
|
||||
import_multi: 'Import multiple',
|
||||
open: 'Open as new document',
|
||||
imgLibs: [{
|
||||
name: 'Demo library (local)',
|
||||
url: function url(_ref) {
|
||||
var path = _ref.path,
|
||||
modularVersion = _ref.modularVersion;
|
||||
|
||||
return path + 'imagelib/index' + (modularVersion ? '-es' : '') + '.html';
|
||||
},
|
||||
|
||||
description: 'Demonstration library for SVG-edit on this server'
|
||||
}, {
|
||||
name: 'IAN Symbol Libraries',
|
||||
url: 'https://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php',
|
||||
description: 'Free library of illustrations'
|
||||
}, {
|
||||
name: 'Openclipart',
|
||||
url: 'https://openclipart.org/svgedit',
|
||||
description: 'Share and Use Images. Over 50,000 Public Domain SVG Images and Growing.'
|
||||
}]
|
||||
};
|
||||
|
||||
return en;
|
||||
|
||||
}());
|
||||
33
dist/extensions/ext-locale/imagelib/fr.js
vendored
Normal file
33
dist/extensions/ext-locale/imagelib/fr.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
var svgEditorExtensionLocale_imagelib_fr = (function () {
|
||||
'use strict';
|
||||
|
||||
var fr = {
|
||||
select_lib: "Choisir une bibliothèque d'images",
|
||||
show_list: 'show_list',
|
||||
import_single: 'import_single',
|
||||
import_multi: 'import_multi',
|
||||
open: 'open',
|
||||
imgLibs: [{
|
||||
name: 'Demo library (local)',
|
||||
url: function url(_ref) {
|
||||
var path = _ref.path,
|
||||
modularVersion = _ref.modularVersion;
|
||||
|
||||
return path + 'imagelib/index' + (modularVersion ? '-es' : '') + '.html';
|
||||
},
|
||||
|
||||
description: 'Demonstration library for SVG-edit on this server'
|
||||
}, {
|
||||
name: 'IAN Symbol Libraries',
|
||||
url: 'https://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php',
|
||||
description: 'Free library of illustrations'
|
||||
}, {
|
||||
name: 'Openclipart',
|
||||
url: 'https://openclipart.org/svgedit',
|
||||
description: 'Share and Use Images. Over 50,000 Public Domain SVG Images and Growing.'
|
||||
}]
|
||||
};
|
||||
|
||||
return fr;
|
||||
|
||||
}());
|
||||
17
dist/extensions/ext-locale/storage/de.js
vendored
Normal file
17
dist/extensions/ext-locale/storage/de.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
var svgEditorExtensionLocale_storage_de = (function () {
|
||||
'use strict';
|
||||
|
||||
var de = {
|
||||
message: 'Standardmäßig kann SVG-Edit Ihre Editor-Einstellungen ' + 'und die SVG-Inhalte lokal auf Ihrem Gerät abspeichern. So brauchen Sie ' + 'nicht jedes Mal die SVG neu laden. Falls Sie aus Datenschutzgründen ' + 'dies nicht wollen, ' + 'können Sie die Standardeinstellung im Folgenden ändern.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: 'If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again.'
|
||||
};
|
||||
|
||||
return de;
|
||||
|
||||
}());
|
||||
17
dist/extensions/ext-locale/storage/en.js
vendored
Normal file
17
dist/extensions/ext-locale/storage/en.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
var svgEditorExtensionLocale_storage_en = (function () {
|
||||
'use strict';
|
||||
|
||||
var en = {
|
||||
message: 'By default and where supported, SVG-Edit can store your editor ' + 'preferences and SVG content locally on your machine so you do not ' + 'need to add these back each time you load SVG-Edit. If, for privacy ' + 'reasons, you do not wish to store this information on your machine, ' + 'you can change away from the default option below.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: 'If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again.'
|
||||
};
|
||||
|
||||
return en;
|
||||
|
||||
}());
|
||||
17
dist/extensions/ext-locale/storage/fr.js
vendored
Normal file
17
dist/extensions/ext-locale/storage/fr.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
var svgEditorExtensionLocale_storage_fr = (function () {
|
||||
'use strict';
|
||||
|
||||
var fr = {
|
||||
message: "Par défaut et si supporté, SVG-Edit peut stocker les préférences de l'éditeur " + "et le contenu SVG localement sur votre machine de sorte que vous n'ayez pas besoin de les " + 'rajouter chaque fois que vous chargez SVG-Edit. Si, pour des raisons de confidentialité, ' + 'vous ne souhaitez pas stocker ces données sur votre machine, vous pouvez changer ce ' + 'comportement ci-dessous.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: "Si vous choisissez de désactiver le stockage en mémorisant le choix, l'URL va changer afin que la question ne vous soit plus reposée."
|
||||
};
|
||||
|
||||
return fr;
|
||||
|
||||
}());
|
||||
1103
dist/extensions/ext-markers.js
vendored
1103
dist/extensions/ext-markers.js
vendored
File diff suppressed because it is too large
Load Diff
579
dist/extensions/ext-mathjax.js
vendored
579
dist/extensions/ext-mathjax.js
vendored
@@ -1,208 +1,405 @@
|
||||
(function () {
|
||||
var svgEditorExtension_mathjax = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery, MathJax */
|
||||
/*
|
||||
* ext-mathjax.js
|
||||
*
|
||||
* Licensed under the Apache License
|
||||
*
|
||||
* Copyright(c) 2013 Jo Segaert
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('mathjax', function () {
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
|
||||
// Configuration of the MathJax extention.
|
||||
|
||||
// This will be added to the head tag before MathJax is loaded.
|
||||
/* mathjaxConfiguration = `<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
extensions: ['tex2jax.js'],
|
||||
jax: ['input/TeX', 'output/SVG'],
|
||||
showProcessingMessages: true,
|
||||
showMathMenu: false,
|
||||
showMathMenuMSIE: false,
|
||||
errorSettings: {
|
||||
message: ['[Math Processing Error]'],
|
||||
style: {color: '#CC0000', 'font-style': 'italic'}
|
||||
},
|
||||
elements: [],
|
||||
tex2jax: {
|
||||
ignoreClass: 'tex2jax_ignore2', processClass: 'tex2jax_process2',
|
||||
},
|
||||
TeX: {
|
||||
extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
|
||||
},
|
||||
SVG: {
|
||||
}
|
||||
});
|
||||
</script>`, */
|
||||
// mathjaxSrc = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
|
||||
// Had been on https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG.js
|
||||
// Obtained Text-AMS-MML_SVG.js from https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/config/TeX-AMS-MML_SVG.js
|
||||
var mathjaxSrcSecure = 'mathjax/MathJax.js?config=TeX-AMS-MML_SVG.js',
|
||||
_svgEditor = svgEditor,
|
||||
uiStrings = _svgEditor.uiStrings;
|
||||
|
||||
var math = void 0,
|
||||
locationX = void 0,
|
||||
locationY = void 0,
|
||||
mathjaxLoaded = false;
|
||||
|
||||
// TODO: Implement language support. Move these uiStrings to the locale files and the code to the langReady callback.
|
||||
$.extend(uiStrings, {
|
||||
mathjax: {
|
||||
embed_svg: 'Save as mathematics',
|
||||
embed_mathml: 'Save as figure',
|
||||
svg_save_warning: 'The math will be transformed into a figure is manipulatable like everything else. You will not be able to manipulate the TeX-code anymore. ',
|
||||
mathml_save_warning: 'Advised. The math will be saved as a figure.',
|
||||
title: 'Mathematics code editor'
|
||||
}
|
||||
});
|
||||
|
||||
function saveMath() {
|
||||
var code = $('#mathjax_code_textarea').val();
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
* every symbol (glymph) you need only once. These are saved in a <svg> on
|
||||
* the top of your html document, just under the body tag. Each glymph has
|
||||
* its unique id and is saved as a <path> in the <defs> tag of the <svg>
|
||||
*
|
||||
* Then when the symbols are needed in the rest of your html document they
|
||||
* are refferd to by a <use> tag.
|
||||
* Because of bug 1076 we can't just grab the defs tag on the top and add it
|
||||
* to your formula's <svg> and copy the lot. So we have to replace each
|
||||
* <use> tag by it's <path>.
|
||||
*/
|
||||
MathJax.Hub.queue.Push(function () {
|
||||
var mathjaxMath = $('.MathJax_SVG');
|
||||
var svg = $(mathjaxMath.html());
|
||||
svg.find('use').each(function () {
|
||||
// TODO: find a less pragmatic and more elegant solution to this.
|
||||
var id = $(this).attr('href') ? $(this).attr('href').slice(1) // Works in Chrome.
|
||||
: $(this).attr('xlink:href').slice(1); // Works in Firefox.
|
||||
var glymph = $('#' + id).clone().removeAttr('id');
|
||||
var x = $(this).attr('x');
|
||||
var y = $(this).attr('y');
|
||||
var transform = $(this).attr('transform');
|
||||
if (transform && (x || y)) {
|
||||
glymph.attr('transform', transform + ' translate(' + x + ',' + y + ')');
|
||||
} else if (transform) {
|
||||
glymph.attr('transform', transform);
|
||||
} else if (x || y) {
|
||||
glymph.attr('transform', 'translate(' + x + ',' + y + ')');
|
||||
var asyncToGenerator = function (fn) {
|
||||
return function () {
|
||||
var gen = fn.apply(this, arguments);
|
||||
return new Promise(function (resolve, reject) {
|
||||
function step(key, arg) {
|
||||
try {
|
||||
var info = gen[key](arg);
|
||||
var value = info.value;
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
$(this).replaceWith(glymph);
|
||||
});
|
||||
// Remove the style tag because it interferes with SVG-Edit.
|
||||
svg.removeAttr('style');
|
||||
svg.attr('xmlns', 'http://www.w3.org/2000/svg');
|
||||
svgCanvas.importSvgString($('<div>').append(svg.clone()).html(), true);
|
||||
svgCanvas.ungroupSelectedElement();
|
||||
// TODO: To undo the adding of the Formula you now have to undo twice.
|
||||
// This should only be once!
|
||||
svgCanvas.moveSelectedElements(locationX, locationY, true);
|
||||
|
||||
if (info.done) {
|
||||
resolve(value);
|
||||
} else {
|
||||
return Promise.resolve(value).then(function (value) {
|
||||
step("next", value);
|
||||
}, function (err) {
|
||||
step("throw", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return step("next");
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'MathJax',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'mathjax-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
title: 'Add Mathematics',
|
||||
events: {
|
||||
click: function click() {
|
||||
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
|
||||
// From this point on it is very probable that it will be needed, so load it.
|
||||
if (mathjaxLoaded === false) {
|
||||
$('<div id="mathjax">' + '<!-- Here is where MathJax creates the math -->' + '<div id="mathjax_creator" class="tex2jax_process" style="display:none">' + '$${}$$' + '</div>' + '<div id="mathjax_overlay"></div>' + '<div id="mathjax_container">' + '<div id="tool_mathjax_back" class="toolbar_button">' + '<button id="tool_mathjax_save">OK</button>' + '<button id="tool_mathjax_cancel">Cancel</button>' + '</div>' + '<fieldset>' + '<legend id="mathjax_legend">Mathematics Editor</legend>' + '<label>' + '<span id="mathjax_explication">Please type your mathematics in ' + '<a href="https://en.wikipedia.org/wiki/Help:Displaying_a_formula" target="_blank">TeX</a> code.</span></label>' + '<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' + '</fieldset>' + '</div>' + '</div>').insertAfter('#svg_prefs').hide();
|
||||
return target;
|
||||
};
|
||||
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({ cancel: 'button,fieldset', containment: 'window' });
|
||||
// MIT License
|
||||
// From: https://github.com/uupaa/dynamic-import-polyfill/blob/master/importModule.js
|
||||
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true)).on('click touched', function () {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
function toAbsoluteURL(url) {
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', url); // <a href="hoge.html">
|
||||
return a.cloneNode(false).href; // -> "http://example.com/hoge.html"
|
||||
}
|
||||
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true)).on('click touched', function () {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
function addScriptAtts(script, atts) {
|
||||
['id', 'class', 'type'].forEach(function (prop) {
|
||||
if (prop in atts) {
|
||||
script[prop] = atts[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
// Additions by Brett
|
||||
var importSetGlobalDefault = function () {
|
||||
var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(url, config) {
|
||||
return regeneratorRuntime.wrap(function _callee$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
return _context.abrupt('return', importSetGlobal(url, _extends({}, config, { returnDefault: true })));
|
||||
|
||||
// Now get (and run) the MathJax Library.
|
||||
// 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(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure).done(function (script, textStatus) {
|
||||
// When MathJax is loaded get the div where the math will be rendered.
|
||||
MathJax.Hub.queue.Push(function () {
|
||||
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
})
|
||||
// If it fails.
|
||||
.fail(function () {
|
||||
console.log('Failed loadeing MathJax.');
|
||||
$.alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
});
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode('mathjax');
|
||||
case 1:
|
||||
case 'end':
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}],
|
||||
}, _callee, this);
|
||||
}));
|
||||
|
||||
mouseDown: function mouseDown() {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
// Get the coordinates from your mouse.
|
||||
var zoom = svgCanvas.getZoom();
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
locationX = opts.mouse_x / zoom;
|
||||
locationY = opts.mouse_y / zoom;
|
||||
|
||||
$('#mathjax').show();
|
||||
return { started: false }; // Otherwise the last selected object dissapears.
|
||||
}
|
||||
},
|
||||
callback: function callback() {
|
||||
$('<style>').text('#mathjax fieldset{' + 'padding: 5px;' + 'margin: 5px;' + 'border: 1px solid #DDD;' + '}' + '#mathjax label{' + 'display: block;' + 'margin: .5em;' + '}' + '#mathjax legend {' + 'max-width:195px;' + '}' + '#mathjax_overlay {' + 'position: absolute;' + 'top: 0;' + 'left: 0;' + 'right: 0;' + 'bottom: 0;' + 'background-color: black;' + 'opacity: 0.6;' + 'z-index: 20000;' + '}' + '#mathjax_container {' + 'position: absolute;' + 'top: 50px;' + 'padding: 10px;' + 'background-color: #B0B0B0;' + 'border: 1px outset #777;' + 'opacity: 1.0;' + 'font-family: Verdana, Helvetica, sans-serif;' + 'font-size: .8em;' + 'z-index: 20001;' + '}' + '#tool_mathjax_back {' + 'margin-left: 1em;' + 'overflow: auto;' + '}' + '#mathjax_legend{' + 'font-weight: bold;' + 'font-size:1.1em;' + '}' + '#mathjax_code_textarea {\\n' + 'margin: 5px .7em;' + 'overflow: hidden;' + 'width: 416px;' + 'display: block;' + 'height: 100px;' + '}').appendTo('head');
|
||||
|
||||
// Add the MathJax configuration.
|
||||
// $(mathjaxConfiguration).appendTo('head');
|
||||
}
|
||||
return function importSetGlobalDefault(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
});
|
||||
}();
|
||||
var importSetGlobal = function () {
|
||||
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(url, _ref2) {
|
||||
var global = _ref2.global,
|
||||
returnDefault = _ref2.returnDefault;
|
||||
var modularVersion;
|
||||
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
||||
while (1) {
|
||||
switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
// Todo: Replace calls to this function with `import()` when supported
|
||||
modularVersion = !('svgEditor' in window) || !window.svgEditor || window.svgEditor.modules !== false;
|
||||
|
||||
if (!modularVersion) {
|
||||
_context2.next = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context2.abrupt('return', importModule(url, undefined, { returnDefault: returnDefault }));
|
||||
|
||||
case 3:
|
||||
_context2.next = 5;
|
||||
return importScript(url);
|
||||
|
||||
case 5:
|
||||
return _context2.abrupt('return', window[global]);
|
||||
|
||||
case 6:
|
||||
case 'end':
|
||||
return _context2.stop();
|
||||
}
|
||||
}
|
||||
}, _callee2, this);
|
||||
}));
|
||||
|
||||
return function importSetGlobal(_x3, _x4) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
// Addition by Brett
|
||||
function importScript(url) {
|
||||
var atts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
if (Array.isArray(url)) {
|
||||
return Promise.all(url.map(function (u) {
|
||||
return importScript(u, atts);
|
||||
}));
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var script = document.createElement('script');
|
||||
var destructor = function destructor() {
|
||||
script.onerror = null;
|
||||
script.onload = null;
|
||||
script.remove();
|
||||
script.src = '';
|
||||
};
|
||||
script.defer = 'defer';
|
||||
addScriptAtts(script, atts);
|
||||
script.onerror = function () {
|
||||
reject(new Error('Failed to import: ' + url));
|
||||
destructor();
|
||||
};
|
||||
script.onload = function () {
|
||||
resolve();
|
||||
destructor();
|
||||
};
|
||||
script.src = url;
|
||||
|
||||
document.head.append(script);
|
||||
});
|
||||
}
|
||||
|
||||
function importModule(url) {
|
||||
var atts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var _ref4 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
|
||||
_ref4$returnDefault = _ref4.returnDefault,
|
||||
returnDefault = _ref4$returnDefault === undefined ? false : _ref4$returnDefault;
|
||||
|
||||
if (Array.isArray(url)) {
|
||||
return Promise.all(url.map(function (u) {
|
||||
return importModule(u, atts);
|
||||
}));
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var vector = '$importModule$' + Math.random().toString(32).slice(2);
|
||||
var script = document.createElement('script');
|
||||
var destructor = function destructor() {
|
||||
delete window[vector];
|
||||
script.onerror = null;
|
||||
script.onload = null;
|
||||
script.remove();
|
||||
URL.revokeObjectURL(script.src);
|
||||
script.src = '';
|
||||
};
|
||||
addScriptAtts(script, atts);
|
||||
script.defer = 'defer';
|
||||
script.type = 'module';
|
||||
script.onerror = function () {
|
||||
reject(new Error('Failed to import: ' + url));
|
||||
destructor();
|
||||
};
|
||||
script.onload = function () {
|
||||
resolve(window[vector]);
|
||||
destructor();
|
||||
};
|
||||
var absURL = toAbsoluteURL(url);
|
||||
var loader = 'import * as m from \'' + absURL.replace(/'/g, "\\'") + '\'; window.' + vector + ' = ' + (returnDefault ? 'm.default || ' : '') + 'm;'; // export Module
|
||||
var blob = new Blob([loader], { type: 'text/javascript' });
|
||||
script.src = URL.createObjectURL(blob);
|
||||
|
||||
document.head.append(script);
|
||||
});
|
||||
}
|
||||
|
||||
/* globals jQuery, MathJax */
|
||||
|
||||
var extMathjax = {
|
||||
name: 'mathjax',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
|
||||
// Configuration of the MathJax extention.
|
||||
|
||||
// This will be added to the head tag before MathJax is loaded.
|
||||
/* mathjaxConfiguration = `<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
extensions: ['tex2jax.js'],
|
||||
jax: ['input/TeX', 'output/SVG'],
|
||||
showProcessingMessages: true,
|
||||
showMathMenu: false,
|
||||
showMathMenuMSIE: false,
|
||||
errorSettings: {
|
||||
message: ['[Math Processing Error]'],
|
||||
style: {color: '#CC0000', 'font-style': 'italic'}
|
||||
},
|
||||
elements: [],
|
||||
tex2jax: {
|
||||
ignoreClass: 'tex2jax_ignore2', processClass: 'tex2jax_process2',
|
||||
},
|
||||
TeX: {
|
||||
extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
|
||||
},
|
||||
SVG: {
|
||||
}
|
||||
});
|
||||
</script>`, */
|
||||
// mathjaxSrc = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
|
||||
// Had been on https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG.js
|
||||
// Obtained Text-AMS-MML_SVG.js from https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/config/TeX-AMS-MML_SVG.js
|
||||
var mathjaxSrcSecure = 'mathjax/MathJax.js?config=TeX-AMS-MML_SVG.js',
|
||||
uiStrings = svgEditor.uiStrings;
|
||||
|
||||
var math = void 0,
|
||||
locationX = void 0,
|
||||
locationY = void 0,
|
||||
mathjaxLoaded = false;
|
||||
|
||||
// TODO: Implement language support. Move these uiStrings to the locale files and the code to the langReady callback.
|
||||
$.extend(uiStrings, {
|
||||
mathjax: {
|
||||
embed_svg: 'Save as mathematics',
|
||||
embed_mathml: 'Save as figure',
|
||||
svg_save_warning: 'The math will be transformed into a figure is manipulatable like everything else. You will not be able to manipulate the TeX-code anymore. ',
|
||||
mathml_save_warning: 'Advised. The math will be saved as a figure.',
|
||||
title: 'Mathematics code editor'
|
||||
}
|
||||
});
|
||||
|
||||
function saveMath() {
|
||||
var code = $('#mathjax_code_textarea').val();
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
* every symbol (glymph) you need only once. These are saved in a <svg> on
|
||||
* the top of your html document, just under the body tag. Each glymph has
|
||||
* its unique id and is saved as a <path> in the <defs> tag of the <svg>
|
||||
*
|
||||
* Then when the symbols are needed in the rest of your html document they
|
||||
* are refferd to by a <use> tag.
|
||||
* Because of bug 1076 we can't just grab the defs tag on the top and add it
|
||||
* to your formula's <svg> and copy the lot. So we have to replace each
|
||||
* <use> tag by it's <path>.
|
||||
*/
|
||||
MathJax.Hub.queue.Push(function () {
|
||||
var mathjaxMath = $('.MathJax_SVG');
|
||||
var svg = $(mathjaxMath.html());
|
||||
svg.find('use').each(function () {
|
||||
// TODO: find a less pragmatic and more elegant solution to this.
|
||||
var id = $(this).attr('href') ? $(this).attr('href').slice(1) // Works in Chrome.
|
||||
: $(this).attr('xlink:href').slice(1); // Works in Firefox.
|
||||
var glymph = $('#' + id).clone().removeAttr('id');
|
||||
var x = $(this).attr('x');
|
||||
var y = $(this).attr('y');
|
||||
var transform = $(this).attr('transform');
|
||||
if (transform && (x || y)) {
|
||||
glymph.attr('transform', transform + ' translate(' + x + ',' + y + ')');
|
||||
} else if (transform) {
|
||||
glymph.attr('transform', transform);
|
||||
} else if (x || y) {
|
||||
glymph.attr('transform', 'translate(' + x + ',' + y + ')');
|
||||
}
|
||||
$(this).replaceWith(glymph);
|
||||
});
|
||||
// Remove the style tag because it interferes with SVG-Edit.
|
||||
svg.removeAttr('style');
|
||||
svg.attr('xmlns', 'http://www.w3.org/2000/svg');
|
||||
svgCanvas.importSvgString($('<div>').append(svg.clone()).html(), true);
|
||||
svgCanvas.ungroupSelectedElement();
|
||||
// TODO: To undo the adding of the Formula you now have to undo twice.
|
||||
// This should only be once!
|
||||
svgCanvas.moveSelectedElements(locationX, locationY, true);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'MathJax',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'mathjax-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
title: 'Add Mathematics',
|
||||
events: {
|
||||
click: function click() {
|
||||
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
|
||||
// From this point on it is very probable that it will be needed, so load it.
|
||||
if (mathjaxLoaded === false) {
|
||||
$('<div id="mathjax">' + '<!-- Here is where MathJax creates the math -->' + '<div id="mathjax_creator" class="tex2jax_process" style="display:none">' + '$${}$$' + '</div>' + '<div id="mathjax_overlay"></div>' + '<div id="mathjax_container">' + '<div id="tool_mathjax_back" class="toolbar_button">' + '<button id="tool_mathjax_save">OK</button>' + '<button id="tool_mathjax_cancel">Cancel</button>' + '</div>' + '<fieldset>' + '<legend id="mathjax_legend">Mathematics Editor</legend>' + '<label>' + '<span id="mathjax_explication">Please type your mathematics in ' + '<a href="https://en.wikipedia.org/wiki/Help:Displaying_a_formula" target="_blank">TeX</a> code.</span></label>' + '<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' + '</fieldset>' + '</div>' + '</div>').insertAfter('#svg_prefs').hide();
|
||||
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({
|
||||
cancel: 'button,fieldset',
|
||||
containment: 'window'
|
||||
});
|
||||
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true)).on('click touched', function () {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true)).on('click touched', function () {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
|
||||
// Now get (and run) the MathJax Library.
|
||||
// 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 modularVersion = !('svgEditor' in window) ||
|
||||
!window.svgEditor ||
|
||||
window.svgEditor.modules !== false;
|
||||
// Add as second argument to `importScript`
|
||||
{
|
||||
type: modularVersion
|
||||
? 'module' // Make this the default when widely supported
|
||||
: 'text/javascript'
|
||||
}
|
||||
// If only using modules, just use this:
|
||||
const {default: MathJax} = await importModule( // or `import()` when widely supported
|
||||
svgEditor.curConfig.extIconsPath + mathjaxSrcSecure
|
||||
);
|
||||
*/
|
||||
importScript(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure).then(function () {
|
||||
// When MathJax is loaded get the div where the math will be rendered.
|
||||
MathJax.Hub.queue.Push(function () {
|
||||
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
}).catch(function () {
|
||||
console.log('Failed loadeing MathJax.');
|
||||
$.alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
});
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode('mathjax');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
mouseDown: function mouseDown() {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
// Get the coordinates from your mouse.
|
||||
var zoom = svgCanvas.getZoom();
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
locationX = opts.mouse_x / zoom;
|
||||
locationY = opts.mouse_y / zoom;
|
||||
|
||||
$('#mathjax').show();
|
||||
return { started: false }; // Otherwise the last selected object dissapears.
|
||||
}
|
||||
},
|
||||
callback: function callback() {
|
||||
$('<style>').text('#mathjax fieldset{' + 'padding: 5px;' + 'margin: 5px;' + 'border: 1px solid #DDD;' + '}' + '#mathjax label{' + 'display: block;' + 'margin: .5em;' + '}' + '#mathjax legend {' + 'max-width:195px;' + '}' + '#mathjax_overlay {' + 'position: absolute;' + 'top: 0;' + 'left: 0;' + 'right: 0;' + 'bottom: 0;' + 'background-color: black;' + 'opacity: 0.6;' + 'z-index: 20000;' + '}' + '#mathjax_container {' + 'position: absolute;' + 'top: 50px;' + 'padding: 10px;' + 'background-color: #B0B0B0;' + 'border: 1px outset #777;' + 'opacity: 1.0;' + 'font-family: Verdana, Helvetica, sans-serif;' + 'font-size: .8em;' + 'z-index: 20001;' + '}' + '#tool_mathjax_back {' + 'margin-left: 1em;' + 'overflow: auto;' + '}' + '#mathjax_legend{' + 'font-weight: bold;' + 'font-size:1.1em;' + '}' + '#mathjax_code_textarea {\\n' + 'margin: 5px .7em;' + 'overflow: hidden;' + 'width: 416px;' + 'display: block;' + 'height: 100px;' + '}').appendTo('head');
|
||||
|
||||
// Add the MathJax configuration.
|
||||
// $(mathjaxConfiguration).appendTo('head');
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extMathjax;
|
||||
|
||||
}());
|
||||
|
||||
262
dist/extensions/ext-overview_window.js
vendored
262
dist/extensions/ext-overview_window.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_overview_window = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -10,143 +10,147 @@
|
||||
* Copyright(c) 2013 James Sacksteder
|
||||
*
|
||||
*/
|
||||
var extOverview_window = {
|
||||
name: 'overview_window',
|
||||
init: function init(_ref) {
|
||||
var isChrome = _ref.isChrome,
|
||||
isIE = _ref.isIE;
|
||||
|
||||
svgEditor.addExtension('overview_window', function (_ref) {
|
||||
var isChrome = _ref.isChrome,
|
||||
isIE = _ref.isIE;
|
||||
|
||||
var $ = jQuery;
|
||||
var 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 (isChrome()) {
|
||||
var verIndex = navigator.userAgent.indexOf('Chrome/') + 7;
|
||||
var chromeVersion = parseInt(navigator.userAgent.substring(verIndex), 10);
|
||||
if (chromeVersion < 49) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Define and insert the base html element.
|
||||
var propsWindowHtml = '<div id="overview_window_content_pane" style="width:100%; word-wrap:break-word; display:inline-block; margin-top:20px;">' + '<div id="overview_window_content" style="position:relative; left:12px; top:0px;">' + '<div style="background-color:#A0A0A0; display:inline-block; overflow:visible;">' + '<svg id="overviewMiniView" width="150" height="100" x="0" y="0" viewBox="0 0 4800 3600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + '<use x="0" y="0" xlink:href="#svgroot"> </use>' + '</svg>' + '<div id="overview_window_view_box" style="min-width:50px; min-height:50px; position:absolute; top:30px; left:30px; z-index:5; background-color:rgba(255,0,102,0.3);">' + '</div>' + '</div>' + '</div>' + '</div>';
|
||||
$('#sidepanels').append(propsWindowHtml);
|
||||
|
||||
// Define dynamic animation of the view box.
|
||||
var updateViewBox = function updateViewBox() {
|
||||
var portHeight = parseFloat($('#workarea').css('height'));
|
||||
var portWidth = parseFloat($('#workarea').css('width'));
|
||||
var portX = $('#workarea').scrollLeft();
|
||||
var portY = $('#workarea').scrollTop();
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
|
||||
var viewBoxX = portX / windowWidth * overviewWidth;
|
||||
var viewBoxY = portY / windowHeight * overviewHeight;
|
||||
var viewBoxWidth = portWidth / windowWidth * overviewWidth;
|
||||
var viewBoxHeight = portHeight / windowHeight * overviewHeight;
|
||||
|
||||
$('#overview_window_view_box').css('min-width', viewBoxWidth + 'px');
|
||||
$('#overview_window_view_box').css('min-height', viewBoxHeight + 'px');
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
};
|
||||
$('#workarea').scroll(function () {
|
||||
if (!overviewWindowGlobals.viewBoxDragging) {
|
||||
updateViewBox();
|
||||
}
|
||||
});
|
||||
$('#workarea').resize(updateViewBox);
|
||||
updateViewBox();
|
||||
|
||||
// Compensate for changes in zoom and canvas size.
|
||||
var updateViewDimensions = function updateViewDimensions() {
|
||||
var viewWidth = $('#svgroot').attr('width');
|
||||
var viewHeight = $('#svgroot').attr('height');
|
||||
|
||||
var viewX = 640;
|
||||
var viewY = 480;
|
||||
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.
|
||||
// TAG:HACK
|
||||
// TAG:VERSION_DEPENDENT
|
||||
// TAG:BROWSER_SNIFFING
|
||||
viewX = 0;
|
||||
viewY = 0;
|
||||
var $ = jQuery;
|
||||
var 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 (isChrome()) {
|
||||
var verIndex = navigator.userAgent.indexOf('Chrome/') + 7;
|
||||
var chromeVersion = parseInt(navigator.userAgent.substring(verIndex), 10);
|
||||
if (chromeVersion < 49) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var svgWidthOld = $('#overviewMiniView').attr('width');
|
||||
var svgHeightNew = viewHeight / viewWidth * svgWidthOld;
|
||||
$('#overviewMiniView').attr('viewBox', viewX + ' ' + viewY + ' ' + viewWidth + ' ' + viewHeight);
|
||||
$('#overviewMiniView').attr('height', svgHeightNew);
|
||||
// Define and insert the base html element.
|
||||
var propsWindowHtml = '<div id="overview_window_content_pane" style="width:100%; word-wrap:break-word; display:inline-block; margin-top:20px;">' + '<div id="overview_window_content" style="position:relative; left:12px; top:0px;">' + '<div style="background-color:#A0A0A0; display:inline-block; overflow:visible;">' + '<svg id="overviewMiniView" width="150" height="100" x="0" y="0" viewBox="0 0 4800 3600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + '<use x="0" y="0" xlink:href="#svgroot"> </use>' + '</svg>' + '<div id="overview_window_view_box" style="min-width:50px; min-height:50px; position:absolute; top:30px; left:30px; z-index:5; background-color:rgba(255,0,102,0.3);">' + '</div>' + '</div>' + '</div>' + '</div>';
|
||||
$('#sidepanels').append(propsWindowHtml);
|
||||
|
||||
// Define dynamic animation of the view box.
|
||||
var updateViewBox = function updateViewBox() {
|
||||
var portHeight = parseFloat($('#workarea').css('height'));
|
||||
var portWidth = parseFloat($('#workarea').css('width'));
|
||||
var portX = $('#workarea').scrollLeft();
|
||||
var portY = $('#workarea').scrollTop();
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
|
||||
var viewBoxX = portX / windowWidth * overviewWidth;
|
||||
var viewBoxY = portY / windowHeight * overviewHeight;
|
||||
var viewBoxWidth = portWidth / windowWidth * overviewWidth;
|
||||
var viewBoxHeight = portHeight / windowHeight * overviewHeight;
|
||||
|
||||
$('#overview_window_view_box').css('min-width', viewBoxWidth + 'px');
|
||||
$('#overview_window_view_box').css('min-height', viewBoxHeight + 'px');
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
};
|
||||
$('#workarea').scroll(function () {
|
||||
if (!overviewWindowGlobals.viewBoxDragging) {
|
||||
updateViewBox();
|
||||
}
|
||||
});
|
||||
$('#workarea').resize(updateViewBox);
|
||||
updateViewBox();
|
||||
};
|
||||
updateViewDimensions();
|
||||
|
||||
// Set up the overview window as a controller for the view port.
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
var updateViewPortFromViewBox = function updateViewPortFromViewBox() {
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxX = parseFloat($('#overview_window_view_box').css('left'));
|
||||
var viewBoxY = parseFloat($('#overview_window_view_box').css('top'));
|
||||
// Compensate for changes in zoom and canvas size.
|
||||
var updateViewDimensions = function updateViewDimensions() {
|
||||
var viewWidth = $('#svgroot').attr('width');
|
||||
var viewHeight = $('#svgroot').attr('height');
|
||||
|
||||
var portX = viewBoxX / overviewWidth * windowWidth;
|
||||
var portY = viewBoxY / overviewHeight * windowHeight;
|
||||
var viewX = 640;
|
||||
var viewY = 480;
|
||||
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.
|
||||
// TAG:HACK
|
||||
// TAG:VERSION_DEPENDENT
|
||||
// TAG:BROWSER_SNIFFING
|
||||
viewX = 0;
|
||||
viewY = 0;
|
||||
}
|
||||
|
||||
$('#workarea').scrollLeft(portX);
|
||||
$('#workarea').scrollTop(portY);
|
||||
};
|
||||
$('#overview_window_view_box').draggable({
|
||||
containment: 'parent',
|
||||
drag: updateViewPortFromViewBox,
|
||||
start: function start() {
|
||||
overviewWindowGlobals.viewBoxDragging = true;
|
||||
},
|
||||
stop: function stop() {
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
}
|
||||
});
|
||||
$('#overviewMiniView').click(function (evt) {
|
||||
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
||||
var mouseX = evt.offsetX || evt.originalEvent.layerX;
|
||||
var mouseY = evt.offsetY || evt.originalEvent.layerY;
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxWidth = parseFloat($('#overview_window_view_box').css('min-width'));
|
||||
var viewBoxHeight = parseFloat($('#overview_window_view_box').css('min-height'));
|
||||
var svgWidthOld = $('#overviewMiniView').attr('width');
|
||||
var svgHeightNew = viewHeight / viewWidth * svgWidthOld;
|
||||
$('#overviewMiniView').attr('viewBox', viewX + ' ' + viewY + ' ' + viewWidth + ' ' + viewHeight);
|
||||
$('#overviewMiniView').attr('height', svgHeightNew);
|
||||
updateViewBox();
|
||||
};
|
||||
updateViewDimensions();
|
||||
|
||||
var viewBoxX = mouseX - 0.5 * viewBoxWidth;
|
||||
var viewBoxY = mouseY - 0.5 * viewBoxHeight;
|
||||
// deal with constraints
|
||||
if (viewBoxX < 0) {
|
||||
viewBoxX = 0;
|
||||
}
|
||||
if (viewBoxY < 0) {
|
||||
viewBoxY = 0;
|
||||
}
|
||||
if (viewBoxX + viewBoxWidth > overviewWidth) {
|
||||
viewBoxX = overviewWidth - viewBoxWidth;
|
||||
}
|
||||
if (viewBoxY + viewBoxHeight > overviewHeight) {
|
||||
viewBoxY = overviewHeight - viewBoxHeight;
|
||||
}
|
||||
// Set up the overview window as a controller for the view port.
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
var updateViewPortFromViewBox = function updateViewPortFromViewBox() {
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxX = parseFloat($('#overview_window_view_box').css('left'));
|
||||
var viewBoxY = parseFloat($('#overview_window_view_box').css('top'));
|
||||
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
updateViewPortFromViewBox();
|
||||
});
|
||||
var portX = viewBoxX / overviewWidth * windowWidth;
|
||||
var portY = viewBoxY / overviewHeight * windowHeight;
|
||||
|
||||
return {
|
||||
name: 'overview window',
|
||||
canvasUpdated: updateViewDimensions,
|
||||
workareaResized: updateViewBox
|
||||
};
|
||||
});
|
||||
$('#workarea').scrollLeft(portX);
|
||||
$('#workarea').scrollTop(portY);
|
||||
};
|
||||
$('#overview_window_view_box').draggable({
|
||||
containment: 'parent',
|
||||
drag: updateViewPortFromViewBox,
|
||||
start: function start() {
|
||||
overviewWindowGlobals.viewBoxDragging = true;
|
||||
},
|
||||
stop: function stop() {
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
}
|
||||
});
|
||||
$('#overviewMiniView').click(function (evt) {
|
||||
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
||||
var mouseX = evt.offsetX || evt.originalEvent.layerX;
|
||||
var mouseY = evt.offsetY || evt.originalEvent.layerY;
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxWidth = parseFloat($('#overview_window_view_box').css('min-width'));
|
||||
var viewBoxHeight = parseFloat($('#overview_window_view_box').css('min-height'));
|
||||
|
||||
var viewBoxX = mouseX - 0.5 * viewBoxWidth;
|
||||
var viewBoxY = mouseY - 0.5 * viewBoxHeight;
|
||||
// deal with constraints
|
||||
if (viewBoxX < 0) {
|
||||
viewBoxX = 0;
|
||||
}
|
||||
if (viewBoxY < 0) {
|
||||
viewBoxY = 0;
|
||||
}
|
||||
if (viewBoxX + viewBoxWidth > overviewWidth) {
|
||||
viewBoxX = overviewWidth - viewBoxWidth;
|
||||
}
|
||||
if (viewBoxY + viewBoxHeight > overviewHeight) {
|
||||
viewBoxY = overviewHeight - viewBoxHeight;
|
||||
}
|
||||
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
updateViewPortFromViewBox();
|
||||
});
|
||||
|
||||
return {
|
||||
name: 'overview window',
|
||||
canvasUpdated: updateViewDimensions,
|
||||
workareaResized: updateViewBox
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extOverview_window;
|
||||
|
||||
}());
|
||||
|
||||
70
dist/extensions/ext-panning.js
vendored
70
dist/extensions/ext-panning.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_panning = (function () {
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
@@ -11,40 +11,46 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a very basic SVG-Edit extension to let tablet/mobile devices panning without problem
|
||||
This is a very basic SVG-Edit extension to let tablet/mobile devices pan without problem
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('ext-panning', function () {
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
return {
|
||||
name: 'Extension Panning',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-panning.xml',
|
||||
buttons: [{
|
||||
id: 'ext-panning',
|
||||
type: 'mode',
|
||||
title: 'Panning',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('ext-panning');
|
||||
var extPanning = {
|
||||
name: 'ext-panning',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
return {
|
||||
name: 'Extension Panning',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-panning.xml',
|
||||
buttons: [{
|
||||
id: 'ext-panning',
|
||||
type: 'mode',
|
||||
title: 'Panning',
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('ext-panning');
|
||||
}
|
||||
}
|
||||
}],
|
||||
mouseDown: function mouseDown() {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(true);
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp() {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(false);
|
||||
return {
|
||||
keep: false,
|
||||
element: null
|
||||
};
|
||||
}
|
||||
}
|
||||
}],
|
||||
mouseDown: function mouseDown() {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(true);
|
||||
return { started: true };
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp() {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(false);
|
||||
return {
|
||||
keep: false,
|
||||
element: null
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extPanning;
|
||||
|
||||
}());
|
||||
|
||||
10
dist/extensions/ext-php_savefile.js
vendored
10
dist/extensions/ext-php_savefile.js
vendored
@@ -1,12 +1,14 @@
|
||||
(function () {
|
||||
var svgEditorExtension_php_savefile = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
// TODO: Might add support for "exportImage" custom
|
||||
// handler as in "ext-server_opensave.js" (and in savefile.php)
|
||||
|
||||
svgEditor.addExtension('php_savefile', {
|
||||
var extPhp_savefile = {
|
||||
name: 'php_savefile',
|
||||
callback: function callback() {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
function getFileNameFromTitle() {
|
||||
@@ -23,6 +25,8 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return extPhp_savefile;
|
||||
|
||||
}());
|
||||
|
||||
492
dist/extensions/ext-polygon.js
vendored
492
dist/extensions/ext-polygon.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_polygon = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -10,266 +10,270 @@
|
||||
* All rights reserved
|
||||
*
|
||||
*/
|
||||
var extPolygon = {
|
||||
name: 'polygon',
|
||||
init: function init(S) {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var selElems = void 0,
|
||||
|
||||
svgEditor.addExtension('polygon', function (S) {
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var selElems = void 0,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID, modeChangeG,
|
||||
// edg = 0,
|
||||
// undoCommand = 'Not image';
|
||||
started = void 0,
|
||||
newFO = void 0;
|
||||
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID, modeChangeG,
|
||||
// edg = 0,
|
||||
// undoCommand = 'Not image';
|
||||
started = void 0,
|
||||
newFO = void 0;
|
||||
// const ccZoom;
|
||||
// const wEl, hEl;
|
||||
// const wOffset, hOffset;
|
||||
// const ccRBG;
|
||||
// const ccOpacity;
|
||||
// const brushW, brushH;
|
||||
|
||||
// const ccZoom;
|
||||
// const wEl, hEl;
|
||||
// const wOffset, hOffset;
|
||||
// const ccRBG;
|
||||
// const ccOpacity;
|
||||
// const brushW, brushH;
|
||||
// const ccDebug = document.getElementById('debugpanel');
|
||||
|
||||
// const ccDebug = document.getElementById('debugpanel');
|
||||
|
||||
/* const properlySourceSizeTextArea = function(){
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
const height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
}; */
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
/* const properlySourceSizeTextArea = function(){
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
const height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
}; */
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#polygon_panel').toggle(on);
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#polygon_panel').toggle(on);
|
||||
}
|
||||
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#polygon_save, #polygon_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#polygon_save, #polygon_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
function cot(n) {
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
function cot(n) {
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
|
||||
function sec(n) {
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
function sec(n) {
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtained from http://code.google.com/p/passenger-top/source/browse/instiki/public/svg-edit/editor/extensions/ext-itex.js?r=3
|
||||
* This function sets the content of of the currently-selected foreignObject element,
|
||||
* based on the itex contained in string.
|
||||
* @param {string} tex The itex text.
|
||||
* @returns This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
/*
|
||||
function setItexString(tex) {
|
||||
const mathns = 'http://www.w3.org/1998/Math/MathML',
|
||||
xmlnsns = 'http://www.w3.org/2000/xmlns/',
|
||||
ajaxEndpoint = '../../itex';
|
||||
const elt = selElems[0];
|
||||
try {
|
||||
const math = svgdoc.createElementNS(mathns, 'math');
|
||||
math.setAttributeNS(xmlnsns, 'xmlns', mathns);
|
||||
math.setAttribute('display', 'inline');
|
||||
const semantics = document.createElementNS(mathns, 'semantics');
|
||||
const annotation = document.createElementNS(mathns, 'annotation');
|
||||
annotation.setAttribute('encoding', 'application/x-tex');
|
||||
annotation.textContent = tex;
|
||||
const mrow = document.createElementNS(mathns, 'mrow');
|
||||
semantics.appendChild(mrow);
|
||||
semantics.appendChild(annotation);
|
||||
math.appendChild(semantics);
|
||||
// make an AJAX request to the server, to get the MathML
|
||||
$.post(ajaxEndpoint, {tex, display: 'inline'}, function(data){
|
||||
const children = data.documentElement.childNodes;
|
||||
while (children.length > 0) {
|
||||
mrow.appendChild(svgdoc.adoptNode(children[0], true));
|
||||
}
|
||||
S.sanitizeSvg(math);
|
||||
/**
|
||||
* Obtained from http://code.google.com/p/passenger-top/source/browse/instiki/public/svg-edit/editor/extensions/ext-itex.js?r=3
|
||||
* This function sets the content of of the currently-selected foreignObject element,
|
||||
* based on the itex contained in string.
|
||||
* @param {string} tex The itex text.
|
||||
* @returns This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
/*
|
||||
function setItexString(tex) {
|
||||
const mathns = 'http://www.w3.org/1998/Math/MathML',
|
||||
xmlnsns = 'http://www.w3.org/2000/xmlns/',
|
||||
ajaxEndpoint = '../../itex';
|
||||
const elt = selElems[0];
|
||||
try {
|
||||
const math = svgdoc.createElementNS(mathns, 'math');
|
||||
math.setAttributeNS(xmlnsns, 'xmlns', mathns);
|
||||
math.setAttribute('display', 'inline');
|
||||
const semantics = document.createElementNS(mathns, 'semantics');
|
||||
const annotation = document.createElementNS(mathns, 'annotation');
|
||||
annotation.setAttribute('encoding', 'application/x-tex');
|
||||
annotation.textContent = tex;
|
||||
const mrow = document.createElementNS(mathns, 'mrow');
|
||||
semantics.append(mrow, annotation);
|
||||
math.append(semantics);
|
||||
// make an AJAX request to the server, to get the MathML
|
||||
$.post(ajaxEndpoint, {tex, display: 'inline'}, function(data){
|
||||
const children = data.documentElement.childNodes;
|
||||
while (children.length > 0) {
|
||||
mrow.append(svgdoc.adoptNode(children[0], true));
|
||||
}
|
||||
S.sanitizeSvg(math);
|
||||
S.call('changed', [elt]);
|
||||
});
|
||||
elt.firstChild.replaceWith(math);
|
||||
S.call('changed', [elt]);
|
||||
});
|
||||
elt.replaceChild(math, elt.firstChild);
|
||||
S.call('changed', [elt]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
svgCanvas.clearSelection();
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return {
|
||||
name: 'polygon',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'polygon-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_polygon',
|
||||
type: 'mode',
|
||||
title: 'Polygon Tool',
|
||||
position: 11,
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'polySides',
|
||||
label: 'sides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
callback: function callback() {
|
||||
$('#polygon_panel').hide();
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */$('#tool_source_save').clone().hide().attr('id', 'polygon_save').unbind().appendTo('#tool_source_back').click(function () {
|
||||
{
|
||||
return;
|
||||
}
|
||||
// }
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* const cancel = */$('#tool_source_cancel').clone().hide().attr('id', 'polygon_cancel').unbind().appendTo('#tool_source_back').click(function () {
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
// const e = opts.event;
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
// const e = opts.event;
|
||||
var c = $(newFO).attr(['cx', 'cy', 'sides', 'orient', 'fill', 'strokecolor', 'strokeWidth']);
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var cx = c.cx,
|
||||
cy = c.cy,
|
||||
fill = c.fill,
|
||||
strokecolor = c.strokecolor,
|
||||
strokeWidth = c.strokeWidth,
|
||||
sides = c.sides,
|
||||
edg = Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||
|
||||
newFO.setAttributeNS(null, 'edge', edg);
|
||||
|
||||
var inradius = edg / 2 * cot(Math.PI / sides);
|
||||
var circumradius = inradius * sec(Math.PI / sides);
|
||||
var points = '';
|
||||
for (var s = 0; sides >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * s / sides;
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
|
||||
points += x + ',' + y + ' ';
|
||||
}
|
||||
|
||||
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttributeNS(null, 'points', points);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokeWidth);
|
||||
// newFO.setAttributeNS(null, 'transform', 'rotate(-90)');
|
||||
// const shape = newFO.getAttributeNS(null, 'shape');
|
||||
// newFO.appendChild(poly);
|
||||
// DrawPoly(cx, cy, sides, edg, orient);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
var attrs = $(newFO).attr('edge');
|
||||
var keep = attrs.edge !== '0';
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#polySides').val(elem.getAttribute('sides'));
|
||||
|
||||
*/
|
||||
return {
|
||||
name: 'polygon',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'polygon-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_polygon',
|
||||
type: 'mode',
|
||||
title: 'Polygon Tool',
|
||||
position: 11,
|
||||
events: {
|
||||
click: function click() {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'polySides',
|
||||
label: 'sides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
callback: function callback() {
|
||||
$('#polygon_panel').hide();
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */$('#tool_source_save').clone().hide().attr('id', 'polygon_save').unbind().appendTo('#tool_source_back').click(function () {
|
||||
{
|
||||
return;
|
||||
}
|
||||
// }
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* const cancel = */$('#tool_source_cancel').clone().hide().attr('id', 'polygon_cancel').unbind().appendTo('#tool_source_back').click(function () {
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
// const e = opts.event;
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
// const e = opts.event;
|
||||
var c = $(newFO).attr(['cx', 'cy', 'sides', 'orient', 'fill', 'strokecolor', 'strokeWidth']);
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var cx = c.cx,
|
||||
cy = c.cy,
|
||||
fill = c.fill,
|
||||
strokecolor = c.strokecolor,
|
||||
strokeWidth = c.strokeWidth,
|
||||
sides = c.sides,
|
||||
edg = Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||
|
||||
newFO.setAttributeNS(null, 'edge', edg);
|
||||
|
||||
var inradius = edg / 2 * cot(Math.PI / sides);
|
||||
var circumradius = inradius * sec(Math.PI / sides);
|
||||
var points = '';
|
||||
for (var s = 0; sides >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * s / sides;
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
|
||||
points += x + ',' + y + ' ';
|
||||
}
|
||||
|
||||
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttributeNS(null, 'points', points);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokeWidth);
|
||||
// newFO.setAttributeNS(null, 'transform', 'rotate(-90)');
|
||||
// const shape = newFO.getAttributeNS(null, 'shape');
|
||||
// newFO.append(poly);
|
||||
// DrawPoly(cx, cy, sides, edg, orient);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
var attrs = $(newFO).attr('edge');
|
||||
var keep = attrs.edge !== '0';
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#polySides').val(elem.getAttribute('sides'));
|
||||
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extPolygon;
|
||||
|
||||
}());
|
||||
|
||||
4089
dist/extensions/ext-server_moinsave.js
vendored
4089
dist/extensions/ext-server_moinsave.js
vendored
File diff suppressed because it is too large
Load Diff
4117
dist/extensions/ext-server_opensave.js
vendored
4117
dist/extensions/ext-server_opensave.js
vendored
File diff suppressed because it is too large
Load Diff
637
dist/extensions/ext-shapes.js
vendored
637
dist/extensions/ext-shapes.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_shapes = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -11,339 +11,344 @@
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
var extShapes = {
|
||||
name: 'shapes',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var canv = svgEditor.canvas;
|
||||
var svgroot = canv.getRootElem();
|
||||
var lastBBox = {};
|
||||
|
||||
svgEditor.addExtension('shapes', function () {
|
||||
var $ = jQuery;
|
||||
var canv = svgEditor.canvas;
|
||||
var svgroot = canv.getRootElem();
|
||||
var lastBBox = {};
|
||||
// This populates the category list
|
||||
var categories = {
|
||||
basic: 'Basic',
|
||||
object: 'Objects',
|
||||
symbol: 'Symbols',
|
||||
arrow: 'Arrows',
|
||||
flowchart: 'Flowchart',
|
||||
animal: 'Animals',
|
||||
game: 'Cards & Chess',
|
||||
dialog_balloon: 'Dialog balloons',
|
||||
electronics: 'Electronics',
|
||||
math: 'Mathematical',
|
||||
music: 'Music',
|
||||
misc: 'Miscellaneous',
|
||||
raphael_1: 'raphaeljs.com set 1',
|
||||
raphael_2: 'raphaeljs.com set 2'
|
||||
};
|
||||
|
||||
// This populates the category list
|
||||
var categories = {
|
||||
basic: 'Basic',
|
||||
object: 'Objects',
|
||||
symbol: 'Symbols',
|
||||
arrow: 'Arrows',
|
||||
flowchart: 'Flowchart',
|
||||
animal: 'Animals',
|
||||
game: 'Cards & Chess',
|
||||
dialog_balloon: 'Dialog balloons',
|
||||
electronics: 'Electronics',
|
||||
math: 'Mathematical',
|
||||
music: 'Music',
|
||||
misc: 'Miscellaneous',
|
||||
raphael_1: 'raphaeljs.com set 1',
|
||||
raphael_2: 'raphaeljs.com set 2'
|
||||
};
|
||||
var 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'
|
||||
|
||||
var 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'
|
||||
|
||||
},
|
||||
buttons: []
|
||||
}
|
||||
};
|
||||
|
||||
var modeId = 'shapelib';
|
||||
var startClientPos = {};
|
||||
|
||||
var currentD = void 0,
|
||||
curShapeId = void 0,
|
||||
curShape = void 0,
|
||||
startX = void 0,
|
||||
startY = void 0;
|
||||
var curLib = library.basic;
|
||||
|
||||
function loadIcons() {
|
||||
$('#shape_buttons').empty().append(curLib.buttons);
|
||||
}
|
||||
|
||||
function makeButtons(cat, shapes) {
|
||||
var size = curLib.size || 300;
|
||||
var fill = curLib.fill || false;
|
||||
var off = size * 0.05;
|
||||
var vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
var stroke = fill ? 0 : size / 30;
|
||||
var shapeIcon = new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="' + (fill ? '#333' : 'none') + '" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>', 'text/xml');
|
||||
|
||||
var width = 24;
|
||||
var height = 24;
|
||||
shapeIcon.documentElement.setAttribute('width', width);
|
||||
shapeIcon.documentElement.setAttribute('height', height);
|
||||
var svgElem = $(document.importNode(shapeIcon.documentElement, true));
|
||||
|
||||
var data = shapes.data;
|
||||
|
||||
|
||||
curLib.buttons = [];
|
||||
for (var id in data) {
|
||||
var pathD = data[id];
|
||||
var icon = svgElem.clone();
|
||||
icon.find('path').attr('d', pathD);
|
||||
|
||||
var iconBtn = icon.wrap('<div class="tool_button">').parent().attr({
|
||||
id: modeId + '_' + id,
|
||||
title: id
|
||||
});
|
||||
// Store for later use
|
||||
curLib.buttons.push(iconBtn[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function loadLibrary(catId) {
|
||||
var lib = library[catId];
|
||||
|
||||
if (!lib) {
|
||||
$('#shape_buttons').html('Loading...');
|
||||
$.getJSON(svgEditor.curConfig.extIconsPath + 'shapelib/' + catId + '.json', function (result) {
|
||||
curLib = library[catId] = {
|
||||
data: result.data,
|
||||
size: result.size,
|
||||
fill: result.fill
|
||||
};
|
||||
makeButtons(catId, result);
|
||||
loadIcons();
|
||||
});
|
||||
return;
|
||||
}
|
||||
curLib = lib;
|
||||
if (!lib.buttons.length) {
|
||||
makeButtons(catId, lib);
|
||||
}
|
||||
loadIcons();
|
||||
}
|
||||
|
||||
return {
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-shapes.xml',
|
||||
buttons: [{
|
||||
id: 'tool_shapelib',
|
||||
type: 'mode_flyout', // _flyout
|
||||
position: 6,
|
||||
title: 'Shape library',
|
||||
events: {
|
||||
click: function click() {
|
||||
canv.setMode(modeId);
|
||||
}
|
||||
},
|
||||
buttons: []
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('<style>').text('#shape_buttons {' + 'overflow: auto;' + 'width: 180px;' + 'max-height: 300px;' + 'display: table-cell;' + 'vertical-align: middle;' + '}' + '#shape_cats {' + 'min-width: 110px;' + 'display: table-cell;' + 'vertical-align: middle;' + 'height: 300px;' + '}' + '#shape_cats > div {' + 'line-height: 1em;' + 'padding: .5em;' + 'border:1px solid #B0B0B0;' + 'background: #E8E8E8;' + 'margin-bottom: -1px;' + '}' + '#shape_cats div:hover {' + 'background: #FFFFCC;' + '}' + '#shape_cats div.current {' + 'font-weight: bold;' + '}').appendTo('head');
|
||||
};
|
||||
|
||||
var btnDiv = $('<div id="shape_buttons">');
|
||||
$('#tools_shapelib > *').wrapAll(btnDiv);
|
||||
var modeId = 'shapelib';
|
||||
var startClientPos = {};
|
||||
|
||||
var shower = $('#tools_shapelib_show');
|
||||
var currentD = void 0,
|
||||
curShapeId = void 0,
|
||||
curShape = void 0,
|
||||
startX = void 0,
|
||||
startY = void 0;
|
||||
var curLib = library.basic;
|
||||
|
||||
loadLibrary('basic');
|
||||
function loadIcons() {
|
||||
$('#shape_buttons').empty().append(curLib.buttons);
|
||||
}
|
||||
|
||||
// Do mouseup on parent element rather than each button
|
||||
$('#shape_buttons').mouseup(function (evt) {
|
||||
var btn = $(evt.target).closest('div.tool_button');
|
||||
function makeButtons(cat, shapes) {
|
||||
var size = curLib.size || 300;
|
||||
var fill = curLib.fill || false;
|
||||
var off = size * 0.05;
|
||||
var vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
var stroke = fill ? 0 : size / 30;
|
||||
var shapeIcon = new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="' + (fill ? '#333' : 'none') + '" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>', 'text/xml');
|
||||
|
||||
if (!btn.length) {
|
||||
var width = 24;
|
||||
var height = 24;
|
||||
shapeIcon.documentElement.setAttribute('width', width);
|
||||
shapeIcon.documentElement.setAttribute('height', height);
|
||||
var svgElem = $(document.importNode(shapeIcon.documentElement, true));
|
||||
|
||||
var data = shapes.data;
|
||||
|
||||
|
||||
curLib.buttons = [];
|
||||
for (var id in data) {
|
||||
var pathD = data[id];
|
||||
var icon = svgElem.clone();
|
||||
icon.find('path').attr('d', pathD);
|
||||
|
||||
var iconBtn = icon.wrap('<div class="tool_button">').parent().attr({
|
||||
id: modeId + '_' + id,
|
||||
title: id
|
||||
});
|
||||
// Store for later use
|
||||
curLib.buttons.push(iconBtn[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function loadLibrary(catId) {
|
||||
var lib = library[catId];
|
||||
|
||||
if (!lib) {
|
||||
$('#shape_buttons').html('Loading...');
|
||||
$.getJSON(svgEditor.curConfig.extIconsPath + 'shapelib/' + catId + '.json', function (result) {
|
||||
curLib = library[catId] = {
|
||||
data: result.data,
|
||||
size: result.size,
|
||||
fill: result.fill
|
||||
};
|
||||
makeButtons(catId, result);
|
||||
loadIcons();
|
||||
});
|
||||
return;
|
||||
}
|
||||
curLib = lib;
|
||||
if (!lib.buttons.length) {
|
||||
makeButtons(catId, lib);
|
||||
}
|
||||
loadIcons();
|
||||
}
|
||||
|
||||
return {
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-shapes.xml',
|
||||
buttons: [{
|
||||
id: 'tool_shapelib',
|
||||
type: 'mode_flyout', // _flyout
|
||||
position: 6,
|
||||
title: 'Shape library',
|
||||
events: {
|
||||
click: function click() {
|
||||
canv.setMode(modeId);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('<style>').text('#shape_buttons {' + 'overflow: auto;' + 'width: 180px;' + 'max-height: 300px;' + 'display: table-cell;' + 'vertical-align: middle;' + '}' + '#shape_cats {' + 'min-width: 110px;' + 'display: table-cell;' + 'vertical-align: middle;' + 'height: 300px;' + '}' + '#shape_cats > div {' + 'line-height: 1em;' + 'padding: .5em;' + 'border:1px solid #B0B0B0;' + 'background: #E8E8E8;' + 'margin-bottom: -1px;' + '}' + '#shape_cats div:hover {' + 'background: #FFFFCC;' + '}' + '#shape_cats div.current {' + 'font-weight: bold;' + '}').appendTo('head');
|
||||
|
||||
var btnDiv = $('<div id="shape_buttons">');
|
||||
$('#tools_shapelib > *').wrapAll(btnDiv);
|
||||
|
||||
var shower = $('#tools_shapelib_show');
|
||||
|
||||
loadLibrary('basic');
|
||||
|
||||
// Do mouseup on parent element rather than each button
|
||||
$('#shape_buttons').mouseup(function (evt) {
|
||||
var btn = $(evt.target).closest('div.tool_button');
|
||||
|
||||
if (!btn.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var copy = btn.children().clone();
|
||||
shower.children(':not(.flyout_arrow_horiz)').remove();
|
||||
shower.append(copy).attr('data-curopt', '#' + btn[0].id) // This sets the current mode
|
||||
.mouseup();
|
||||
canv.setMode(modeId);
|
||||
|
||||
curShapeId = btn[0].id.substr((modeId + '_').length);
|
||||
currentD = curLib.data[curShapeId];
|
||||
|
||||
$('.tools_flyout').fadeOut();
|
||||
});
|
||||
|
||||
var shapeCats = $('<div id="shape_cats">');
|
||||
|
||||
var catStr = '';
|
||||
$.each(categories, function (id, label) {
|
||||
catStr += '<div data-cat=' + id + '>' + label + '</div>';
|
||||
});
|
||||
|
||||
shapeCats.html(catStr).children().bind('mouseup', function () {
|
||||
var catlink = $(this);
|
||||
catlink.siblings().removeClass('current');
|
||||
catlink.addClass('current');
|
||||
|
||||
loadLibrary(catlink.attr('data-cat'));
|
||||
// Get stuff
|
||||
return false;
|
||||
});
|
||||
|
||||
shapeCats.children().eq(0).addClass('current');
|
||||
|
||||
$('#tools_shapelib').append(shapeCats);
|
||||
|
||||
shower.mouseup(function () {
|
||||
canv.setMode(currentD ? modeId : 'select');
|
||||
});
|
||||
$('#tool_shapelib').remove();
|
||||
|
||||
var h = $('#tools_shapelib').height();
|
||||
$('#tools_shapelib').css({
|
||||
'margin-top': -(h / 2 - 15),
|
||||
'margin-left': 3
|
||||
});
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var copy = btn.children().clone();
|
||||
shower.children(':not(.flyout_arrow_horiz)').remove();
|
||||
shower.append(copy).attr('data-curopt', '#' + btn[0].id) // This sets the current mode
|
||||
.mouseup();
|
||||
canv.setMode(modeId);
|
||||
startX = opts.start_x;
|
||||
var x = startX;
|
||||
startY = opts.start_y;
|
||||
var y = startY;
|
||||
var curStyle = canv.getStyle();
|
||||
|
||||
curShapeId = btn[0].id.substr((modeId + '_').length);
|
||||
currentD = curLib.data[curShapeId];
|
||||
startClientPos.x = opts.event.clientX;
|
||||
startClientPos.y = opts.event.clientY;
|
||||
|
||||
$('.tools_flyout').fadeOut();
|
||||
});
|
||||
curShape = canv.addSvgElementFromJson({
|
||||
element: 'path',
|
||||
curStyles: true,
|
||||
attr: {
|
||||
d: currentD,
|
||||
id: canv.getNextId(),
|
||||
opacity: curStyle.opacity / 2,
|
||||
style: 'pointer-events:none'
|
||||
}
|
||||
});
|
||||
|
||||
var shapeCats = $('<div id="shape_cats">');
|
||||
|
||||
var catStr = '';
|
||||
$.each(categories, function (id, label) {
|
||||
catStr += '<div data-cat=' + id + '>' + label + '</div>';
|
||||
});
|
||||
|
||||
shapeCats.html(catStr).children().bind('mouseup', function () {
|
||||
var catlink = $(this);
|
||||
catlink.siblings().removeClass('current');
|
||||
catlink.addClass('current');
|
||||
|
||||
loadLibrary(catlink.attr('data-cat'));
|
||||
// Get stuff
|
||||
return false;
|
||||
});
|
||||
|
||||
shapeCats.children().eq(0).addClass('current');
|
||||
|
||||
$('#tools_shapelib').append(shapeCats);
|
||||
|
||||
shower.mouseup(function () {
|
||||
canv.setMode(currentD ? modeId : 'select');
|
||||
});
|
||||
$('#tool_shapelib').remove();
|
||||
|
||||
var h = $('#tools_shapelib').height();
|
||||
$('#tools_shapelib').css({
|
||||
'margin-top': -(h / 2 - 15),
|
||||
'margin-left': 3
|
||||
});
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
startX = opts.start_x;
|
||||
var x = startX;
|
||||
startY = opts.start_y;
|
||||
var y = startY;
|
||||
var curStyle = canv.getStyle();
|
||||
|
||||
startClientPos.x = opts.event.clientX;
|
||||
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'
|
||||
// Make sure shape uses absolute values
|
||||
if (/[a-z]/.test(currentD)) {
|
||||
currentD = curLib.data[curShapeId] = canv.pathActions.convertPath(curShape);
|
||||
curShape.setAttribute('d', currentD);
|
||||
canv.pathActions.fixEnd(curShape);
|
||||
}
|
||||
});
|
||||
curShape.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(0.005) translate(' + -x + ',' + -y + ')');
|
||||
|
||||
// Make sure shape uses absolute values
|
||||
if (/[a-z]/.test(currentD)) {
|
||||
currentD = curLib.data[curShapeId] = canv.pathActions.convertPath(curShape);
|
||||
curShape.setAttribute('d', currentD);
|
||||
canv.pathActions.fixEnd(curShape);
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
/* const tlist = */canv.getTransformList(curShape);
|
||||
|
||||
lastBBox = curShape.getBBox();
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var zoom = canv.getZoom();
|
||||
var evt = opts.event;
|
||||
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var tlist = canv.getTransformList(curShape),
|
||||
box = curShape.getBBox(),
|
||||
left = box.x,
|
||||
top = box.y;
|
||||
// {width, height} = box,
|
||||
// const dx = (x - startX), dy = (y - startY);
|
||||
|
||||
var newbox = {
|
||||
x: Math.min(startX, x),
|
||||
y: Math.min(startY, y),
|
||||
width: Math.abs(x - startX),
|
||||
height: Math.abs(y - startY)
|
||||
};
|
||||
|
||||
/*
|
||||
// This is currently serving no purpose, so commenting out
|
||||
let sy = height ? (height + dy) / height : 1,
|
||||
sx = width ? (width + dx) / width : 1;
|
||||
*/
|
||||
|
||||
var sx = newbox.width / lastBBox.width || 1;
|
||||
var sy = newbox.height / lastBBox.height || 1;
|
||||
|
||||
// Not perfect, but mostly works...
|
||||
var tx = 0;
|
||||
if (x < startX) {
|
||||
tx = lastBBox.width;
|
||||
}
|
||||
var ty = 0;
|
||||
if (y < startY) {
|
||||
ty = lastBBox.height;
|
||||
}
|
||||
|
||||
// update the transform list with translate,scale,translate
|
||||
var translateOrigin = svgroot.createSVGTransform(),
|
||||
scale = svgroot.createSVGTransform(),
|
||||
translateBack = svgroot.createSVGTransform();
|
||||
|
||||
translateOrigin.setTranslate(-(left + tx), -(top + ty));
|
||||
if (!evt.shiftKey) {
|
||||
var max = Math.min(Math.abs(sx), Math.abs(sy));
|
||||
|
||||
sx = max * (sx < 0 ? -1 : 1);
|
||||
sy = max * (sy < 0 ? -1 : 1);
|
||||
}
|
||||
scale.setScale(sx, sy);
|
||||
|
||||
translateBack.setTranslate(left + tx, top + ty);
|
||||
tlist.appendItem(translateBack);
|
||||
tlist.appendItem(scale);
|
||||
tlist.appendItem(translateOrigin);
|
||||
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
lastBBox = curShape.getBBox();
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var keepObject = opts.event.clientX !== startClientPos.x && opts.event.clientY !== startClientPos.y;
|
||||
|
||||
return {
|
||||
keep: keepObject,
|
||||
element: curShape,
|
||||
started: false
|
||||
};
|
||||
}
|
||||
curShape.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(0.005) translate(' + -x + ',' + -y + ')');
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
/* const tlist = */canv.getTransformList(curShape);
|
||||
|
||||
lastBBox = curShape.getBBox();
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var zoom = canv.getZoom();
|
||||
var evt = opts.event;
|
||||
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var tlist = canv.getTransformList(curShape),
|
||||
box = curShape.getBBox(),
|
||||
left = box.x,
|
||||
top = box.y;
|
||||
// {width, height} = box,
|
||||
// const dx = (x - startX), dy = (y - startY);
|
||||
|
||||
var newbox = {
|
||||
x: Math.min(startX, x),
|
||||
y: Math.min(startY, y),
|
||||
width: Math.abs(x - startX),
|
||||
height: Math.abs(y - startY)
|
||||
};
|
||||
|
||||
/*
|
||||
// This is currently serving no purpose, so commenting out
|
||||
let sy = height ? (height + dy) / height : 1,
|
||||
sx = width ? (width + dx) / width : 1;
|
||||
*/
|
||||
|
||||
var sx = newbox.width / lastBBox.width || 1;
|
||||
var sy = newbox.height / lastBBox.height || 1;
|
||||
|
||||
// Not perfect, but mostly works...
|
||||
var tx = 0;
|
||||
if (x < startX) {
|
||||
tx = lastBBox.width;
|
||||
}
|
||||
var ty = 0;
|
||||
if (y < startY) {
|
||||
ty = lastBBox.height;
|
||||
}
|
||||
|
||||
// update the transform list with translate,scale,translate
|
||||
var translateOrigin = svgroot.createSVGTransform(),
|
||||
scale = svgroot.createSVGTransform(),
|
||||
translateBack = svgroot.createSVGTransform();
|
||||
|
||||
translateOrigin.setTranslate(-(left + tx), -(top + ty));
|
||||
if (!evt.shiftKey) {
|
||||
var max = Math.min(Math.abs(sx), Math.abs(sy));
|
||||
|
||||
sx = max * (sx < 0 ? -1 : 1);
|
||||
sy = max * (sy < 0 ? -1 : 1);
|
||||
}
|
||||
scale.setScale(sx, sy);
|
||||
|
||||
translateBack.setTranslate(left + tx, top + ty);
|
||||
tlist.appendItem(translateBack);
|
||||
tlist.appendItem(scale);
|
||||
tlist.appendItem(translateOrigin);
|
||||
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
lastBBox = curShape.getBBox();
|
||||
},
|
||||
mouseUp: function mouseUp(opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== modeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var keepObject = opts.event.clientX !== startClientPos.x && opts.event.clientY !== startClientPos.y;
|
||||
|
||||
return {
|
||||
keep: keepObject,
|
||||
element: curShape,
|
||||
started: false
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
return extShapes;
|
||||
|
||||
}());
|
||||
|
||||
411
dist/extensions/ext-star.js
vendored
411
dist/extensions/ext-star.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_star = (function () {
|
||||
'use strict';
|
||||
|
||||
/* globals jQuery */
|
||||
@@ -10,237 +10,242 @@
|
||||
* All rights reserved
|
||||
*
|
||||
*/
|
||||
var extStar = {
|
||||
name: 'star',
|
||||
init: function init(S) {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
|
||||
svgEditor.addExtension('star', function (S) {
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var // {svgcontent} = S,
|
||||
selElems = void 0,
|
||||
|
||||
var // {svgcontent} = S,
|
||||
selElems = void 0,
|
||||
// editingitex = false,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
started = void 0,
|
||||
newFO = void 0;
|
||||
// edg = 0,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID,
|
||||
// undoCommand = 'Not image',
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;
|
||||
|
||||
// editingitex = false,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
started = void 0,
|
||||
newFO = void 0;
|
||||
// edg = 0,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID,
|
||||
// undoCommand = 'Not image',
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;
|
||||
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
function showPanel(on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#star_panel').toggle(on);
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#star_panel').toggle(on);
|
||||
}
|
||||
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#star_save, #star_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#star_save, #star_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
function setAttr(attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
/*
|
||||
function cot(n){
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
function sec(n){
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
function cot(n){
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
function sec(n){
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
*/
|
||||
|
||||
return {
|
||||
name: 'star',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'star-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_star',
|
||||
type: 'mode',
|
||||
title: 'Star Tool',
|
||||
position: 12,
|
||||
events: {
|
||||
click: function click() {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'starNumPoints',
|
||||
label: 'points',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Pointiness',
|
||||
id: 'starRadiusMulitplier',
|
||||
label: 'Pointiness',
|
||||
size: 3,
|
||||
defval: 2.5
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Twists the star',
|
||||
id: 'radialShift',
|
||||
label: 'Radial Shift',
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#star_panel').hide();
|
||||
// const endChanges = function(){};
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// const ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: S.getNextId(),
|
||||
shape: 'star',
|
||||
point: document.getElementById('starNumPoints').value,
|
||||
r: 0,
|
||||
radialshift: document.getElementById('radialShift').value,
|
||||
r2: 0,
|
||||
orient: 'point',
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
return {
|
||||
name: 'star',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'star-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_star',
|
||||
type: 'mode',
|
||||
title: 'Star Tool',
|
||||
position: 12,
|
||||
events: {
|
||||
click: function click() {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
});
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
|
||||
}
|
||||
}],
|
||||
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var cx = c.cx,
|
||||
cy = c.cy,
|
||||
fill = c.fill,
|
||||
strokecolor = c.strokecolor,
|
||||
strokeWidth = c.strokeWidth,
|
||||
radialshift = c.radialshift,
|
||||
point = c.point,
|
||||
orient = c.orient,
|
||||
circumradius = Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5,
|
||||
inradius = circumradius / document.getElementById('starRadiusMulitplier').value;
|
||||
|
||||
newFO.setAttributeNS(null, 'r', circumradius);
|
||||
newFO.setAttributeNS(null, 'r2', inradius);
|
||||
|
||||
var polyPoints = '';
|
||||
for (var s = 0; point >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * (s / point);
|
||||
if (orient === 'point') {
|
||||
angle -= Math.PI / 2;
|
||||
} else if (orient === 'edge') {
|
||||
angle = angle + Math.PI / point - Math.PI / 2;
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'starNumPoints',
|
||||
label: 'points',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Pointiness',
|
||||
id: 'starRadiusMulitplier',
|
||||
label: 'Pointiness',
|
||||
size: 3,
|
||||
defval: 2.5
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Twists the star',
|
||||
id: 'radialShift',
|
||||
label: 'Radial Shift',
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change: function change() {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function callback() {
|
||||
$('#star_panel').hide();
|
||||
// const endChanges = function(){};
|
||||
},
|
||||
mouseDown: function mouseDown(opts) {
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// const ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
started = true;
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
newFO = S.addSvgElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: S.getNextId(),
|
||||
shape: 'star',
|
||||
point: document.getElementById('starNumPoints').value,
|
||||
r: 0,
|
||||
radialshift: document.getElementById('radialShift').value,
|
||||
r2: 0,
|
||||
orient: 'point',
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
}
|
||||
});
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function mouseMove(opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
|
||||
|
||||
if (inradius != null) {
|
||||
angle = 2.0 * Math.PI * (s / point) + Math.PI / point;
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var cx = c.cx,
|
||||
cy = c.cy,
|
||||
fill = c.fill,
|
||||
strokecolor = c.strokecolor,
|
||||
strokeWidth = c.strokeWidth,
|
||||
radialshift = c.radialshift,
|
||||
point = c.point,
|
||||
orient = c.orient,
|
||||
circumradius = Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5,
|
||||
inradius = circumradius / document.getElementById('starRadiusMulitplier').value;
|
||||
|
||||
newFO.setAttributeNS(null, 'r', circumradius);
|
||||
newFO.setAttributeNS(null, 'r2', inradius);
|
||||
|
||||
var polyPoints = '';
|
||||
for (var s = 0; point >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * (s / point);
|
||||
if (orient === 'point') {
|
||||
angle -= Math.PI / 2;
|
||||
} else if (orient === 'edge') {
|
||||
angle = angle + Math.PI / point - Math.PI / 2;
|
||||
}
|
||||
angle += radialshift;
|
||||
|
||||
x = inradius * Math.cos(angle) + cx;
|
||||
y = inradius * Math.sin(angle) + cy;
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
|
||||
if (inradius != null) {
|
||||
angle = 2.0 * Math.PI * (s / point) + Math.PI / point;
|
||||
if (orient === 'point') {
|
||||
angle -= Math.PI / 2;
|
||||
} else if (orient === 'edge') {
|
||||
angle = angle + Math.PI / point - Math.PI / 2;
|
||||
}
|
||||
angle += radialshift;
|
||||
|
||||
x = inradius * Math.cos(angle) + cx;
|
||||
y = inradius * Math.sin(angle) + cy;
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
}
|
||||
}
|
||||
newFO.setAttributeNS(null, 'points', polyPoints);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokeWidth);
|
||||
/* const shape = */newFO.getAttributeNS(null, 'shape');
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
newFO.setAttributeNS(null, 'points', polyPoints);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokeWidth);
|
||||
/* const shape = */newFO.getAttributeNS(null, 'shape');
|
||||
},
|
||||
mouseUp: function mouseUp() {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var attrs = $(newFO).attr(['r']);
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: attrs.r !== '0',
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function mouseUp() {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var attrs = $(newFO).attr(['r']);
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: attrs.r !== '0',
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'star') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
// $('#starRadiusMulitplier').val(elem.getAttribute('r2'));
|
||||
$('#starNumPoints').val(elem.getAttribute('point'));
|
||||
$('#radialShift').val(elem.getAttribute('radialshift'));
|
||||
showPanel(true);
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'star') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
// $('#starRadiusMulitplier').val(elem.getAttribute('r2'));
|
||||
$('#starNumPoints').val(elem.getAttribute('point'));
|
||||
$('#radialShift').val(elem.getAttribute('radialshift'));
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
},
|
||||
elementChanged: function elementChanged(opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extStar;
|
||||
|
||||
}());
|
||||
|
||||
745
dist/extensions/ext-storage.js
vendored
745
dist/extensions/ext-storage.js
vendored
@@ -1,274 +1,499 @@
|
||||
(function () {
|
||||
var svgEditorExtension_storage = (function () {
|
||||
'use strict';
|
||||
|
||||
var confirmSetStorage = {
|
||||
en: {
|
||||
message: 'By default and where supported, SVG-Edit can store your editor ' + 'preferences and SVG content locally on your machine so you do not ' + 'need to add these back each time you load SVG-Edit. If, for privacy ' + 'reasons, you do not wish to store this information on your machine, ' + 'you can change away from the default option below.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: 'If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again.'
|
||||
},
|
||||
de: {
|
||||
message: 'Standardmäßig kann SVG-Edit Ihre Editor-Einstellungen ' + 'und die SVG-Inhalte lokal auf Ihrem Gerät abspeichern. So brauchen Sie ' + 'nicht jedes Mal die SVG neu laden. Falls Sie aus Datenschutzgründen ' + 'dies nicht wollen, ' + 'können Sie die Standardeinstellung im Folgenden ändern.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: 'If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again.'
|
||||
},
|
||||
fr: {
|
||||
message: "Par défaut et si supporté, SVG-Edit peut stocker les préférences de l'éditeur " + "et le contenu SVG localement sur votre machine de sorte que vous n'ayez pas besoin de les " + 'rajouter chaque fois que vous chargez SVG-Edit. Si, pour des raisons de confidentialité, ' + 'vous ne souhaitez pas stocker ces données sur votre machine, vous pouvez changer ce ' + 'comportement ci-dessous.',
|
||||
storagePrefsAndContent: 'Store preferences and SVG content locally',
|
||||
storagePrefsOnly: 'Only store preferences locally',
|
||||
storagePrefs: 'Store preferences locally',
|
||||
storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally',
|
||||
storageNoPrefs: 'Do not store my preferences locally',
|
||||
rememberLabel: 'Remember this choice?',
|
||||
rememberTooltip: "Si vous choisissez de désactiver le stockage en mémorisant le choix, l'URL va changer afin que la question ne vous soit plus reposée."
|
||||
}
|
||||
var asyncToGenerator = function (fn) {
|
||||
return function () {
|
||||
var gen = fn.apply(this, arguments);
|
||||
return new Promise(function (resolve, reject) {
|
||||
function step(key, arg) {
|
||||
try {
|
||||
var info = gen[key](arg);
|
||||
var value = info.value;
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.done) {
|
||||
resolve(value);
|
||||
} else {
|
||||
return Promise.resolve(value).then(function (value) {
|
||||
step("next", value);
|
||||
}, function (err) {
|
||||
step("throw", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return step("next");
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
// MIT License
|
||||
// From: https://github.com/uupaa/dynamic-import-polyfill/blob/master/importModule.js
|
||||
|
||||
function toAbsoluteURL(url) {
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', url); // <a href="hoge.html">
|
||||
return a.cloneNode(false).href; // -> "http://example.com/hoge.html"
|
||||
}
|
||||
|
||||
function addScriptAtts(script, atts) {
|
||||
['id', 'class', 'type'].forEach(function (prop) {
|
||||
if (prop in atts) {
|
||||
script[prop] = atts[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Additions by Brett
|
||||
var importSetGlobalDefault = function () {
|
||||
var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(url, config) {
|
||||
return regeneratorRuntime.wrap(function _callee$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
return _context.abrupt('return', importSetGlobal(url, _extends({}, config, { returnDefault: true })));
|
||||
|
||||
case 1:
|
||||
case 'end':
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}, _callee, this);
|
||||
}));
|
||||
|
||||
return function importSetGlobalDefault(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
var importSetGlobal = function () {
|
||||
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(url, _ref2) {
|
||||
var global = _ref2.global,
|
||||
returnDefault = _ref2.returnDefault;
|
||||
var modularVersion;
|
||||
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
||||
while (1) {
|
||||
switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
// Todo: Replace calls to this function with `import()` when supported
|
||||
modularVersion = !('svgEditor' in window) || !window.svgEditor || window.svgEditor.modules !== false;
|
||||
|
||||
if (!modularVersion) {
|
||||
_context2.next = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context2.abrupt('return', importModule(url, undefined, { returnDefault: returnDefault }));
|
||||
|
||||
case 3:
|
||||
_context2.next = 5;
|
||||
return importScript(url);
|
||||
|
||||
case 5:
|
||||
return _context2.abrupt('return', window[global]);
|
||||
|
||||
case 6:
|
||||
case 'end':
|
||||
return _context2.stop();
|
||||
}
|
||||
}
|
||||
}, _callee2, this);
|
||||
}));
|
||||
|
||||
return function importSetGlobal(_x3, _x4) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
// Addition by Brett
|
||||
function importScript(url) {
|
||||
var atts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
if (Array.isArray(url)) {
|
||||
return Promise.all(url.map(function (u) {
|
||||
return importScript(u, atts);
|
||||
}));
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var script = document.createElement('script');
|
||||
var destructor = function destructor() {
|
||||
script.onerror = null;
|
||||
script.onload = null;
|
||||
script.remove();
|
||||
script.src = '';
|
||||
};
|
||||
script.defer = 'defer';
|
||||
addScriptAtts(script, atts);
|
||||
script.onerror = function () {
|
||||
reject(new Error('Failed to import: ' + url));
|
||||
destructor();
|
||||
};
|
||||
script.onload = function () {
|
||||
resolve();
|
||||
destructor();
|
||||
};
|
||||
script.src = url;
|
||||
|
||||
document.head.append(script);
|
||||
});
|
||||
}
|
||||
|
||||
function importModule(url) {
|
||||
var atts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var _ref4 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
|
||||
_ref4$returnDefault = _ref4.returnDefault,
|
||||
returnDefault = _ref4$returnDefault === undefined ? false : _ref4$returnDefault;
|
||||
|
||||
if (Array.isArray(url)) {
|
||||
return Promise.all(url.map(function (u) {
|
||||
return importModule(u, atts);
|
||||
}));
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var vector = '$importModule$' + Math.random().toString(32).slice(2);
|
||||
var script = document.createElement('script');
|
||||
var destructor = function destructor() {
|
||||
delete window[vector];
|
||||
script.onerror = null;
|
||||
script.onload = null;
|
||||
script.remove();
|
||||
URL.revokeObjectURL(script.src);
|
||||
script.src = '';
|
||||
};
|
||||
addScriptAtts(script, atts);
|
||||
script.defer = 'defer';
|
||||
script.type = 'module';
|
||||
script.onerror = function () {
|
||||
reject(new Error('Failed to import: ' + url));
|
||||
destructor();
|
||||
};
|
||||
script.onload = function () {
|
||||
resolve(window[vector]);
|
||||
destructor();
|
||||
};
|
||||
var absURL = toAbsoluteURL(url);
|
||||
var loader = 'import * as m from \'' + absURL.replace(/'/g, "\\'") + '\'; window.' + vector + ' = ' + (returnDefault ? 'm.default || ' : '') + 'm;'; // export Module
|
||||
var blob = new Blob([loader], { type: 'text/javascript' });
|
||||
script.src = URL.createObjectURL(blob);
|
||||
|
||||
document.head.append(script);
|
||||
});
|
||||
}
|
||||
|
||||
/* globals jQuery */
|
||||
|
||||
svgEditor.addExtension('storage', function () {
|
||||
var $ = jQuery;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
var extStorage = {
|
||||
name: 'storage',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var $ = jQuery;
|
||||
var 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 svgedit-config-iife.js/svgedit-config-es.js.
|
||||
var _svgEditor$curConfig = svgEditor.curConfig,
|
||||
emptyStorageOnDecline = _svgEditor$curConfig.emptyStorageOnDecline,
|
||||
noStorageOnLoad = _svgEditor$curConfig.noStorageOnLoad,
|
||||
forceStorage = _svgEditor$curConfig.forceStorage;
|
||||
var _svgEditor = svgEditor,
|
||||
storage = _svgEditor.storage;
|
||||
// We could empty any already-set data for users when they decline storage,
|
||||
// but it would be a risk for users who wanted to store but accidentally
|
||||
// said "no"; instead, we'll let those who already set it, delete it themselves;
|
||||
// to change, set the "emptyStorageOnDecline" config setting to true
|
||||
// in svgedit-config-iife.js/svgedit-config-es.js.
|
||||
var _svgEditor$curConfig = svgEditor.curConfig,
|
||||
emptyStorageOnDecline = _svgEditor$curConfig.emptyStorageOnDecline,
|
||||
noStorageOnLoad = _svgEditor$curConfig.noStorageOnLoad,
|
||||
forceStorage = _svgEditor$curConfig.forceStorage;
|
||||
var storage = svgEditor.storage;
|
||||
|
||||
|
||||
function replaceStoragePrompt(val) {
|
||||
val = val ? 'storagePrompt=' + val : '';
|
||||
var loc = top.location; // Allow this to work with the embedded editor as well
|
||||
if (loc.href.includes('storagePrompt=')) {
|
||||
loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
|
||||
return (val ? n1 : '') + val + (!val && amp ? n1 : amp || '');
|
||||
});
|
||||
} else {
|
||||
loc.href += (loc.href.includes('?') ? '&' : '?') + val;
|
||||
}
|
||||
}
|
||||
function setSVGContentStorage(val) {
|
||||
if (storage) {
|
||||
var name = 'svgedit-' + svgEditor.curConfig.canvasName;
|
||||
if (!val) {
|
||||
storage.removeItem(name);
|
||||
} else {
|
||||
storage.setItem(name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function expireCookie(cookie) {
|
||||
document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
}
|
||||
|
||||
function removeStoragePrefCookie() {
|
||||
expireCookie('store');
|
||||
}
|
||||
|
||||
function emptyStorage() {
|
||||
setSVGContentStorage('');
|
||||
for (var name in svgEditor.curPrefs) {
|
||||
if (svgEditor.curPrefs.hasOwnProperty(name)) {
|
||||
name = 'svg-edit-' + name;
|
||||
if (storage) {
|
||||
storage.removeItem(name);
|
||||
}
|
||||
expireCookie(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emptyStorage();
|
||||
|
||||
/**
|
||||
* Listen for unloading: If and only if opted in by the user, set the content
|
||||
* document and preferences into storage:
|
||||
* 1. Prevent save warnings (since we're automatically saving unsaved
|
||||
* content into storage)
|
||||
* 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)
|
||||
* 3. Use localStorage (where available) or cookies to set preferences.
|
||||
*/
|
||||
function setupBeforeUnloadListener() {
|
||||
window.addEventListener('beforeunload', function (e) {
|
||||
// Don't save anything unless the user opted in to storage
|
||||
if (!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)) {
|
||||
return;
|
||||
}
|
||||
if (document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)) {
|
||||
setSVGContentStorage(svgCanvas.getSvgString());
|
||||
}
|
||||
|
||||
svgEditor.setConfig({ no_save_warning: true }); // No need for explicit saving at all once storage is on
|
||||
// svgEditor.showSaveWarning = false;
|
||||
|
||||
var _svgEditor2 = svgEditor,
|
||||
curPrefs = _svgEditor2.curPrefs;
|
||||
|
||||
|
||||
for (var key in curPrefs) {
|
||||
if (curPrefs.hasOwnProperty(key)) {
|
||||
// It's our own config, so we don't need to iterate up the prototype chain
|
||||
var val = curPrefs[key];
|
||||
var store = val !== undefined;
|
||||
key = 'svg-edit-' + key;
|
||||
if (!store) {
|
||||
continue;
|
||||
}
|
||||
if (storage) {
|
||||
storage.setItem(key, val);
|
||||
} else if (window.widget) {
|
||||
window.widget.setPreferenceForKey(val, key);
|
||||
} else {
|
||||
val = encodeURIComponent(val);
|
||||
document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
||||
}
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
var loaded = false;
|
||||
return {
|
||||
name: 'storage',
|
||||
langReady: function langReady(data) {
|
||||
// const {uiStrings: {confirmSetStorage}} = data, // No need to store as dialog should only run once
|
||||
var lang = data.lang;
|
||||
|
||||
var _$$deparam$querystrin = $.deparam.querystring(true),
|
||||
storagePrompt = _$$deparam$querystrin.storagePrompt;
|
||||
|
||||
var _confirmSetStorage$la = confirmSetStorage[lang],
|
||||
message = _confirmSetStorage$la.message,
|
||||
storagePrefsAndContent = _confirmSetStorage$la.storagePrefsAndContent,
|
||||
storagePrefsOnly = _confirmSetStorage$la.storagePrefsOnly,
|
||||
storagePrefs = _confirmSetStorage$la.storagePrefs,
|
||||
storageNoPrefsOrContent = _confirmSetStorage$la.storageNoPrefsOrContent,
|
||||
storageNoPrefs = _confirmSetStorage$la.storageNoPrefs,
|
||||
rememberLabel = _confirmSetStorage$la.rememberLabel,
|
||||
rememberTooltip = _confirmSetStorage$la.rememberTooltip;
|
||||
|
||||
// No need to run this one-time dialog again just because the user
|
||||
// changes the language
|
||||
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
|
||||
// Note that the following can load even if "noStorageOnLoad" is
|
||||
// set to false; to avoid any chance of storage, avoid this
|
||||
// extension! (and to avoid using any prior storage, set the
|
||||
// config option "noStorageOnLoad" to true).
|
||||
if (!forceStorage && (
|
||||
// If the URL has been explicitly set to always prompt the
|
||||
// user (e.g., so one can be pointed to a URL where one
|
||||
// can alter one's settings, say to prevent future storage)...
|
||||
storagePrompt === true ||
|
||||
// ...or...if the URL at least doesn't explicitly prevent a
|
||||
// storage prompt (as we use for users who
|
||||
// don't want to set cookies at all but who don't want
|
||||
// continual prompts about it)...
|
||||
storagePrompt !== false &&
|
||||
// ...and this user hasn't previously indicated a desire for storage
|
||||
!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)
|
||||
// ...then show the storage prompt.
|
||||
)) {
|
||||
var options = [];
|
||||
if (storage) {
|
||||
options.unshift({ value: 'prefsAndContent', text: storagePrefsAndContent }, { value: 'prefsOnly', text: storagePrefsOnly }, { value: 'noPrefsOrContent', text: storageNoPrefsOrContent });
|
||||
} else {
|
||||
options.unshift({ value: 'prefsOnly', text: storagePrefs }, { value: 'noPrefsOrContent', text: storageNoPrefs });
|
||||
}
|
||||
|
||||
// Hack to temporarily provide a wide and high enough dialog
|
||||
var oldContainerWidth = $('#dialog_container')[0].style.width,
|
||||
oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft,
|
||||
oldContentHeight = $('#dialog_content')[0].style.height,
|
||||
oldContainerHeight = $('#dialog_container')[0].style.height;
|
||||
$('#dialog_content')[0].style.height = '120px';
|
||||
$('#dialog_container')[0].style.height = '170px';
|
||||
$('#dialog_container')[0].style.width = '800px';
|
||||
$('#dialog_container')[0].style.marginLeft = '-400px';
|
||||
|
||||
// Open select-with-checkbox dialog
|
||||
// From svg-editor.js
|
||||
$.select(message, options, function (pref, checked) {
|
||||
if (pref && pref !== 'noPrefsOrContent') {
|
||||
// Regardless of whether the user opted
|
||||
// to remember the choice (and move to a URL which won't
|
||||
// ask them again), we have to assume the user
|
||||
// doesn't even want to remember their not wanting
|
||||
// storage, so we don't set the cookie or continue on with
|
||||
// setting storage on beforeunload
|
||||
document.cookie = 'store=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'
|
||||
// If the URL was configured to always insist on a prompt, if
|
||||
// the user does indicate a wish to store their info, we
|
||||
// don't want ask them again upon page refresh so move
|
||||
// them instead to a URL which does not always prompt
|
||||
if (storagePrompt === true && checked) {
|
||||
replaceStoragePrompt();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// The user does not wish storage (or cancelled, which we treat equivalently)
|
||||
removeStoragePrefCookie();
|
||||
if (pref && // If the user explicitly expresses wish for no storage
|
||||
emptyStorageOnDecline) {
|
||||
emptyStorage();
|
||||
}
|
||||
if (pref && checked) {
|
||||
// Open a URL which won't set storage and won't prompt user about storage
|
||||
replaceStoragePrompt('false');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset width/height of dialog (e.g., for use by Export)
|
||||
$('#dialog_container')[0].style.width = oldContainerWidth;
|
||||
$('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
|
||||
$('#dialog_content')[0].style.height = oldContentHeight;
|
||||
$('#dialog_container')[0].style.height = oldContainerHeight;
|
||||
|
||||
// It should be enough to (conditionally) add to storage on
|
||||
// beforeunload, but if we wished to update immediately,
|
||||
// we might wish to try setting:
|
||||
// svgEditor.setConfig({noStorageOnLoad: true});
|
||||
// and then call:
|
||||
// svgEditor.loadContentAndPrefs();
|
||||
|
||||
// We don't check for noStorageOnLoad here because
|
||||
// the prompt gives the user the option to store data
|
||||
setupBeforeUnloadListener();
|
||||
|
||||
svgEditor.storagePromptClosed = true;
|
||||
}, null, null, {
|
||||
label: rememberLabel,
|
||||
checked: false,
|
||||
tooltip: rememberTooltip
|
||||
function replaceStoragePrompt(val) {
|
||||
val = val ? 'storagePrompt=' + val : '';
|
||||
var loc = top.location; // Allow this to work with the embedded editor as well
|
||||
if (loc.href.includes('storagePrompt=')) {
|
||||
loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
|
||||
return (val ? n1 : '') + val + (!val && amp ? n1 : amp || '');
|
||||
});
|
||||
} else if (!noStorageOnLoad || forceStorage) {
|
||||
setupBeforeUnloadListener();
|
||||
} else {
|
||||
loc.href += (loc.href.includes('?') ? '&' : '?') + val;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
function setSVGContentStorage(val) {
|
||||
if (storage) {
|
||||
var name = 'svgedit-' + svgEditor.curConfig.canvasName;
|
||||
if (!val) {
|
||||
storage.removeItem(name);
|
||||
} else {
|
||||
storage.setItem(name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function expireCookie(cookie) {
|
||||
document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
}
|
||||
|
||||
function removeStoragePrefCookie() {
|
||||
expireCookie('store');
|
||||
}
|
||||
|
||||
function emptyStorage() {
|
||||
setSVGContentStorage('');
|
||||
for (var name in svgEditor.curPrefs) {
|
||||
if (svgEditor.curPrefs.hasOwnProperty(name)) {
|
||||
name = 'svg-edit-' + name;
|
||||
if (storage) {
|
||||
storage.removeItem(name);
|
||||
}
|
||||
expireCookie(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emptyStorage();
|
||||
|
||||
/**
|
||||
* Listen for unloading: If and only if opted in by the user, set the content
|
||||
* document and preferences into storage:
|
||||
* 1. Prevent save warnings (since we're automatically saving unsaved
|
||||
* content into storage)
|
||||
* 2. Use localStorage to set SVG contents (potentially too large to allow in cookies)
|
||||
* 3. Use localStorage (where available) or cookies to set preferences.
|
||||
*/
|
||||
function setupBeforeUnloadListener() {
|
||||
window.addEventListener('beforeunload', function (e) {
|
||||
// Don't save anything unless the user opted in to storage
|
||||
if (!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)) {
|
||||
return;
|
||||
}
|
||||
if (document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)) {
|
||||
setSVGContentStorage(svgCanvas.getSvgString());
|
||||
}
|
||||
|
||||
svgEditor.setConfig({ no_save_warning: true }); // No need for explicit saving at all once storage is on
|
||||
// svgEditor.showSaveWarning = false;
|
||||
|
||||
var curPrefs = svgEditor.curPrefs;
|
||||
|
||||
|
||||
for (var key in curPrefs) {
|
||||
if (curPrefs.hasOwnProperty(key)) {
|
||||
// It's our own config, so we don't need to iterate up the prototype chain
|
||||
var val = curPrefs[key];
|
||||
var store = val !== undefined;
|
||||
key = 'svg-edit-' + key;
|
||||
if (!store) {
|
||||
continue;
|
||||
}
|
||||
if (storage) {
|
||||
storage.setItem(key, val);
|
||||
} else if (window.widget) {
|
||||
window.widget.setPreferenceForKey(val, key);
|
||||
} else {
|
||||
val = encodeURIComponent(val);
|
||||
document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
||||
}
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
var loaded = false;
|
||||
return {
|
||||
name: 'storage',
|
||||
langReady: function () {
|
||||
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref) {
|
||||
var tryImport = function () {
|
||||
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(lang) {
|
||||
var url;
|
||||
return regeneratorRuntime.wrap(function _callee$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
url = svgEditor.curConfig.extPath + 'ext-locale/storage/' + lang + '.js';
|
||||
_context.next = 3;
|
||||
return importSetGlobalDefault(url, {
|
||||
global: 'svgEditorExtensionLocale_storage_' + lang
|
||||
});
|
||||
|
||||
case 3:
|
||||
confirmSetStorage = _context.sent;
|
||||
|
||||
case 4:
|
||||
case 'end':
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}, _callee, this);
|
||||
}));
|
||||
|
||||
return function tryImport(_x2) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
|
||||
var lang = _ref.lang;
|
||||
|
||||
var _$$deparam$querystrin, storagePrompt, confirmSetStorage, _confirmSetStorage, message, storagePrefsAndContent, storagePrefsOnly, storagePrefs, storageNoPrefsOrContent, storageNoPrefs, rememberLabel, rememberTooltip, options, oldContainerWidth, oldContainerMarginLeft, oldContentHeight, oldContainerHeight;
|
||||
|
||||
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
||||
while (1) {
|
||||
switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
_$$deparam$querystrin = $.deparam.querystring(true), storagePrompt = _$$deparam$querystrin.storagePrompt;
|
||||
confirmSetStorage = void 0;
|
||||
_context2.prev = 2;
|
||||
_context2.next = 5;
|
||||
return tryImport(lang);
|
||||
|
||||
case 5:
|
||||
_context2.next = 11;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_context2.prev = 7;
|
||||
_context2.t0 = _context2['catch'](2);
|
||||
_context2.next = 11;
|
||||
return tryImport('en');
|
||||
|
||||
case 11:
|
||||
_confirmSetStorage = confirmSetStorage, message = _confirmSetStorage.message, storagePrefsAndContent = _confirmSetStorage.storagePrefsAndContent, storagePrefsOnly = _confirmSetStorage.storagePrefsOnly, storagePrefs = _confirmSetStorage.storagePrefs, storageNoPrefsOrContent = _confirmSetStorage.storageNoPrefsOrContent, storageNoPrefs = _confirmSetStorage.storageNoPrefs, rememberLabel = _confirmSetStorage.rememberLabel, rememberTooltip = _confirmSetStorage.rememberTooltip;
|
||||
|
||||
// No need to run this one-time dialog again just because the user
|
||||
// changes the language
|
||||
|
||||
if (!loaded) {
|
||||
_context2.next = 14;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context2.abrupt('return');
|
||||
|
||||
case 14:
|
||||
loaded = true;
|
||||
|
||||
// Note that the following can load even if "noStorageOnLoad" is
|
||||
// set to false; to avoid any chance of storage, avoid this
|
||||
// extension! (and to avoid using any prior storage, set the
|
||||
// config option "noStorageOnLoad" to true).
|
||||
if (!forceStorage && (
|
||||
// If the URL has been explicitly set to always prompt the
|
||||
// user (e.g., so one can be pointed to a URL where one
|
||||
// can alter one's settings, say to prevent future storage)...
|
||||
storagePrompt === true ||
|
||||
// ...or...if the URL at least doesn't explicitly prevent a
|
||||
// storage prompt (as we use for users who
|
||||
// don't want to set cookies at all but who don't want
|
||||
// continual prompts about it)...
|
||||
storagePrompt !== false &&
|
||||
// ...and this user hasn't previously indicated a desire for storage
|
||||
!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)
|
||||
// ...then show the storage prompt.
|
||||
)) {
|
||||
options = [];
|
||||
|
||||
if (storage) {
|
||||
options.unshift({ value: 'prefsAndContent', text: storagePrefsAndContent }, { value: 'prefsOnly', text: storagePrefsOnly }, { value: 'noPrefsOrContent', text: storageNoPrefsOrContent });
|
||||
} else {
|
||||
options.unshift({ value: 'prefsOnly', text: storagePrefs }, { value: 'noPrefsOrContent', text: storageNoPrefs });
|
||||
}
|
||||
|
||||
// Hack to temporarily provide a wide and high enough dialog
|
||||
oldContainerWidth = $('#dialog_container')[0].style.width, oldContainerMarginLeft = $('#dialog_container')[0].style.marginLeft, oldContentHeight = $('#dialog_content')[0].style.height, oldContainerHeight = $('#dialog_container')[0].style.height;
|
||||
|
||||
$('#dialog_content')[0].style.height = '120px';
|
||||
$('#dialog_container')[0].style.height = '170px';
|
||||
$('#dialog_container')[0].style.width = '800px';
|
||||
$('#dialog_container')[0].style.marginLeft = '-400px';
|
||||
|
||||
// Open select-with-checkbox dialog
|
||||
// From svg-editor.js
|
||||
$.select(message, options, function (pref, checked) {
|
||||
if (pref && pref !== 'noPrefsOrContent') {
|
||||
// Regardless of whether the user opted
|
||||
// to remember the choice (and move to a URL which won't
|
||||
// ask them again), we have to assume the user
|
||||
// doesn't even want to remember their not wanting
|
||||
// storage, so we don't set the cookie or continue on with
|
||||
// setting storage on beforeunload
|
||||
document.cookie = 'store=' + encodeURIComponent(pref) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT'; // 'prefsAndContent' | 'prefsOnly'
|
||||
// If the URL was configured to always insist on a prompt, if
|
||||
// the user does indicate a wish to store their info, we
|
||||
// don't want ask them again upon page refresh so move
|
||||
// them instead to a URL which does not always prompt
|
||||
if (storagePrompt === true && checked) {
|
||||
replaceStoragePrompt();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// The user does not wish storage (or cancelled, which we treat equivalently)
|
||||
removeStoragePrefCookie();
|
||||
if (pref && // If the user explicitly expresses wish for no storage
|
||||
emptyStorageOnDecline) {
|
||||
emptyStorage();
|
||||
}
|
||||
if (pref && checked) {
|
||||
// Open a URL which won't set storage and won't prompt user about storage
|
||||
replaceStoragePrompt('false');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset width/height of dialog (e.g., for use by Export)
|
||||
$('#dialog_container')[0].style.width = oldContainerWidth;
|
||||
$('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
|
||||
$('#dialog_content')[0].style.height = oldContentHeight;
|
||||
$('#dialog_container')[0].style.height = oldContainerHeight;
|
||||
|
||||
// It should be enough to (conditionally) add to storage on
|
||||
// beforeunload, but if we wished to update immediately,
|
||||
// we might wish to try setting:
|
||||
// svgEditor.setConfig({noStorageOnLoad: true});
|
||||
// and then call:
|
||||
// svgEditor.loadContentAndPrefs();
|
||||
|
||||
// We don't check for noStorageOnLoad here because
|
||||
// the prompt gives the user the option to store data
|
||||
setupBeforeUnloadListener();
|
||||
|
||||
svgEditor.storagePromptClosed = true;
|
||||
}, null, null, {
|
||||
label: rememberLabel,
|
||||
checked: false,
|
||||
tooltip: rememberTooltip
|
||||
});
|
||||
} else if (!noStorageOnLoad || forceStorage) {
|
||||
setupBeforeUnloadListener();
|
||||
}
|
||||
|
||||
case 16:
|
||||
case 'end':
|
||||
return _context2.stop();
|
||||
}
|
||||
}
|
||||
}, _callee2, this, [[2, 7]]);
|
||||
}));
|
||||
|
||||
function langReady(_x) {
|
||||
return _ref2.apply(this, arguments);
|
||||
}
|
||||
|
||||
return langReady;
|
||||
}()
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return extStorage;
|
||||
|
||||
}());
|
||||
|
||||
78
dist/extensions/ext-webappfind.js
vendored
78
dist/extensions/ext-webappfind.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_webappfind = (function () {
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
@@ -7,44 +7,46 @@
|
||||
Todos:
|
||||
1. See WebAppFind Readme for SVG-related todos
|
||||
*/
|
||||
(function () {
|
||||
var saveMessage = 'webapp-save',
|
||||
readMessage = 'webapp-read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
var pathID = void 0;
|
||||
|
||||
// Todo: Update to new API once released
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
|
||||
!Array.isArray(e.data) || excludedMessages.includes(e.data[0]) // Validate format and avoid our post below
|
||||
) {
|
||||
return;
|
||||
var extWebappfind = {
|
||||
name: 'WebAppFind',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
// Todo: Update to new API once released
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
|
||||
!Array.isArray(e.data) || excludedMessages.includes(e.data[0]) // Validate format and avoid our post below
|
||||
) {
|
||||
return;
|
||||
}
|
||||
var messageType = e.data[0];
|
||||
var svgString = void 0;
|
||||
switch (messageType) {
|
||||
case 'webapp-view':
|
||||
// Populate the contents
|
||||
pathID = e.data[1];
|
||||
|
||||
svgString = e.data[2];
|
||||
svgEditor.loadFromString(svgString);
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'webapp-save-end':
|
||||
alert('save complete for pathID ' + e.data[1] + '!');
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected mode');
|
||||
}
|
||||
var messageType = e.data[0];
|
||||
var svgString = void 0;
|
||||
switch (messageType) {
|
||||
case 'webapp-view':
|
||||
// Populate the contents
|
||||
pathID = e.data[1];
|
||||
}, false);
|
||||
var saveMessage = 'webapp-save',
|
||||
readMessage = 'webapp-read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
var pathID = void 0;
|
||||
|
||||
svgString = e.data[2];
|
||||
svgEditor.loadFromString(svgString);
|
||||
window.postMessage([readMessage], window.location.origin !== 'null' ? window.location.origin : '*'); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'webapp-save-end':
|
||||
alert('save complete for pathID ' + e.data[1] + '!');
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected mode');
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.postMessage([readMessage], window.location.origin !== 'null' ? window.location.origin : '*'); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
|
||||
|
||||
svgEditor.addExtension('WebAppFind', function () {
|
||||
return {
|
||||
name: 'WebAppFind',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'webappfind-icon.svg',
|
||||
@@ -64,7 +66,9 @@
|
||||
}
|
||||
}]
|
||||
};
|
||||
});
|
||||
})();
|
||||
}
|
||||
};
|
||||
|
||||
return extWebappfind;
|
||||
|
||||
}());
|
||||
|
||||
78
dist/extensions/ext-xdomain-messaging.js
vendored
78
dist/extensions/ext-xdomain-messaging.js
vendored
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
var svgEditorExtension_xdomain_messaging = (function () {
|
||||
'use strict';
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
|
||||
@@ -12,43 +12,49 @@
|
||||
* 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 () {
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
try {
|
||||
window.addEventListener('message', function (e) {
|
||||
// We accept and post strings for the sake of IE9 support
|
||||
if (typeof e.data !== 'string' || e.data.charAt() === '|') {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(e.data);
|
||||
if (!data || (typeof data === 'undefined' ? 'undefined' : _typeof(data)) !== 'object' || data.namespace !== 'svgCanvas') {
|
||||
return;
|
||||
}
|
||||
// The default is not to allow any origins, including even the same domain or if run on a file:// URL
|
||||
// See config-sample.js for an example of how to configure
|
||||
var allowedOrigins = svgEditor.curConfig.allowedOrigins;
|
||||
var extXdomainMessaging = {
|
||||
name: 'xdomain-messaging',
|
||||
init: function init() {
|
||||
var svgEditor = this;
|
||||
var svgCanvas = svgEditor.canvas;
|
||||
try {
|
||||
window.addEventListener('message', function (e) {
|
||||
// We accept and post strings for the sake of IE9 support
|
||||
if (typeof e.data !== 'string' || e.data.charAt() === '|') {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(e.data);
|
||||
if (!data || (typeof data === 'undefined' ? 'undefined' : _typeof(data)) !== 'object' || data.namespace !== 'svgCanvas') {
|
||||
return;
|
||||
}
|
||||
// The default is not to allow any origins, including even the same domain or if run on a file:// URL
|
||||
// See config-sample.js for an example of how to configure
|
||||
var allowedOrigins = svgEditor.curConfig.allowedOrigins;
|
||||
|
||||
if (!allowedOrigins.includes('*') && !allowedOrigins.includes(e.origin)) {
|
||||
return;
|
||||
}
|
||||
var cbid = data.id;
|
||||
var name = data.name,
|
||||
args = data.args;
|
||||
if (!allowedOrigins.includes('*') && !allowedOrigins.includes(e.origin)) {
|
||||
return;
|
||||
}
|
||||
var cbid = data.id;
|
||||
var name = data.name,
|
||||
args = data.args;
|
||||
|
||||
var message = {
|
||||
namespace: 'svg-edit',
|
||||
id: cbid
|
||||
};
|
||||
try {
|
||||
message.result = svgCanvas[name].apply(svgCanvas, args);
|
||||
} catch (err) {
|
||||
message.error = err.message;
|
||||
}
|
||||
e.source.postMessage(JSON.stringify(message), '*');
|
||||
}, false);
|
||||
} catch (err) {
|
||||
console.log('Error with xdomain message listener: ' + err);
|
||||
var message = {
|
||||
namespace: 'svg-edit',
|
||||
id: cbid
|
||||
};
|
||||
try {
|
||||
message.result = svgCanvas[name].apply(svgCanvas, args);
|
||||
} catch (err) {
|
||||
message.error = err.message;
|
||||
}
|
||||
e.source.postMessage(JSON.stringify(message), '*');
|
||||
}, false);
|
||||
} catch (err) {
|
||||
console.log('Error with xdomain message listener: ' + err);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return extXdomainMessaging;
|
||||
|
||||
}());
|
||||
|
||||
Reference in New Issue
Block a user