update master to V7

This commit is contained in:
JFH
2021-05-09 19:29:45 +02:00
parent 41fc05672d
commit 593c415664
1000 changed files with 47537 additions and 54304 deletions

View File

@@ -6,26 +6,27 @@
*
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller
*/
import jQueryPluginSVG from '../common/jQuery.attr.js'; // Needed for SVG attribute
import {NS} from '../common/namespaces.js';
import jQueryPluginSVG from './jQuery.attr.js'; // Needed for SVG attribute
import { NS } from '../common/namespaces.js';
import * as hstry from './history.js';
import * as pathModule from './path.js';
import {
isNullish, getStrokedBBoxDefaultVisible, setHref, getElem, getHref, getVisibleElements,
findDefs, getRotationAngle, getRefElem, getBBox as utilsGetBBox, walkTreePost, assignAttributes
} from '../common/utilities.js';
} from './utilities.js';
import {
transformPoint, matrixMultiply, transformListToTransform
} from '../common/math.js';
} from './math.js';
import {
getTransformList
} from '../common/svgtransformlist.js';
} from './svgtransformlist.js';
import {
recalculateDimensions
} from './recalculate.js';
import {
isGecko
} from '../common/browser.js'; // , supportsEditableText
import { getParents } from '../editor/components/jgraduate/Util.js';
const {
MoveElementCommand, BatchCommand, InsertElementCommand, RemoveElementCommand, ChangeElementCommand
@@ -53,10 +54,10 @@ export const init = function (elementContext) {
export const moveToTopSelectedElem = function () {
const [selected] = elementContext_.getSelectedElements();
if (!isNullish(selected)) {
let t = selected;
const t = selected;
const oldParent = t.parentNode;
const oldNextSibling = t.nextSibling;
t = t.parentNode.appendChild(t);
t.parentNode.append(t);
// If the element actually moved position, add the command and fire the changed
// event handler.
if (oldNextSibling !== t.nextSibling) {
@@ -79,7 +80,7 @@ export const moveToBottomSelectedElem = function () {
let t = selected;
const oldParent = t.parentNode;
const oldNextSibling = t.nextSibling;
let {firstChild} = t.parentNode;
let { firstChild } = t.parentNode;
if (firstChild.tagName === 'title') {
firstChild = firstChild.nextSibling;
}
@@ -115,17 +116,17 @@ export const moveUpDownSelected = function (dir) {
// curBBoxes = [];
let closest, foundCur;
// jQuery sorts this list
const list = $(elementContext_.getIntersectionList(getStrokedBBoxDefaultVisible([selected]))).toArray();
const list = elementContext_.getIntersectionList(getStrokedBBoxDefaultVisible([selected]));
if (dir === 'Down') { list.reverse(); }
$.each(list, function () {
Array.prototype.forEach.call(list, function (el) {
if (!foundCur) {
if (this === selected) {
if (el === selected) {
foundCur = true;
}
return true;
}
closest = this;
closest = el;
return false;
});
if (!closest) { return; }
@@ -133,7 +134,11 @@ export const moveUpDownSelected = function (dir) {
const t = selected;
const oldParent = t.parentNode;
const oldNextSibling = t.nextSibling;
$(closest)[dir === 'Down' ? 'before' : 'after'](t);
if (dir === 'Down') {
closest.insertAdjacentElement('beforebegin', t);
} else {
closest.insertAdjacentElement('afterend', t);
}
// If the element actually moved position, add the command and fire the changed
// event handler.
if (oldNextSibling !== t.nextSibling) {
@@ -231,14 +236,24 @@ export const cloneSelectedElements = function (x, y) {
const batchCmd = new BatchCommand('Clone Elements');
// find all the elements selected (stop at first null)
const len = selectedElements.length;
function index(el) {
if (!el) return -1;
var i = 0;
do {
i++;
} while (el == el.previousElementSibling);
return i;
}
/**
* Sorts an array numerically and ascending.
* @param {Element} a
* @param {Element} b
* @returns {Integer}
*/
function sortfunction (a, b) {
return ($(b).index() - $(a).index());
function sortfunction(a, b) {
return (index(b) - index(a));
}
selectedElements.sort(sortfunction);
for (i = 0; i < len; ++i) {
@@ -287,40 +302,40 @@ export const alignSelectedElements = function (type, relativeTo) {
// now bbox is axis-aligned and handles rotation
switch (relativeTo) {
case 'smallest':
if (((type === 'l' || type === 'c' || type === 'r') &&
(curwidth === Number.MIN_VALUE || curwidth > bboxes[i].width)) ||
((type === 't' || type === 'm' || type === 'b') &&
(curheight === Number.MIN_VALUE || curheight > bboxes[i].height))
) {
minx = bboxes[i].x;
miny = bboxes[i].y;
maxx = bboxes[i].x + bboxes[i].width;
maxy = bboxes[i].y + bboxes[i].height;
curwidth = bboxes[i].width;
curheight = bboxes[i].height;
}
break;
case 'largest':
if (((type === 'l' || type === 'c' || type === 'r') &&
(curwidth === Number.MIN_VALUE || curwidth < bboxes[i].width)) ||
((type === 't' || type === 'm' || type === 'b') &&
(curheight === Number.MIN_VALUE || curheight < bboxes[i].height))
) {
minx = bboxes[i].x;
miny = bboxes[i].y;
maxx = bboxes[i].x + bboxes[i].width;
maxy = bboxes[i].y + bboxes[i].height;
curwidth = bboxes[i].width;
curheight = bboxes[i].height;
}
break;
default: // 'selected'
if (bboxes[i].x < minx) { minx = bboxes[i].x; }
if (bboxes[i].y < miny) { miny = bboxes[i].y; }
if (bboxes[i].x + bboxes[i].width > maxx) { maxx = bboxes[i].x + bboxes[i].width; }
if (bboxes[i].y + bboxes[i].height > maxy) { maxy = bboxes[i].y + bboxes[i].height; }
break;
case 'smallest':
if (((type === 'l' || type === 'c' || type === 'r' || type === 'left' || type === 'center' || type === 'right') &&
(curwidth === Number.MIN_VALUE || curwidth > bboxes[i].width)) ||
((type === 't' || type === 'm' || type === 'b' || type === 'top' || type === 'middle' || type === 'bottom') &&
(curheight === Number.MIN_VALUE || curheight > bboxes[i].height))
) {
minx = bboxes[i].x;
miny = bboxes[i].y;
maxx = bboxes[i].x + bboxes[i].width;
maxy = bboxes[i].y + bboxes[i].height;
curwidth = bboxes[i].width;
curheight = bboxes[i].height;
}
break;
case 'largest':
if (((type === 'l' || type === 'c' || type === 'r' || type === 'left' || type === 'center' || type === 'right') &&
(curwidth === Number.MIN_VALUE || curwidth < bboxes[i].width)) ||
((type === 't' || type === 'm' || type === 'b' || type === 'top' || type === 'middle' || type === 'bottom') &&
(curheight === Number.MIN_VALUE || curheight < bboxes[i].height))
) {
minx = bboxes[i].x;
miny = bboxes[i].y;
maxx = bboxes[i].x + bboxes[i].width;
maxy = bboxes[i].y + bboxes[i].height;
curwidth = bboxes[i].width;
curheight = bboxes[i].height;
}
break;
default: // 'selected'
if (bboxes[i].x < minx) { minx = bboxes[i].x; }
if (bboxes[i].y < miny) { miny = bboxes[i].y; }
if (bboxes[i].x + bboxes[i].width > maxx) { maxx = bboxes[i].x + bboxes[i].width; }
if (bboxes[i].y + bboxes[i].height > maxy) { maxy = bboxes[i].y + bboxes[i].height; }
break;
}
} // loop for each element to find the bbox and adjust min/max
@@ -340,24 +355,30 @@ export const alignSelectedElements = function (type, relativeTo) {
dx[i] = 0;
dy[i] = 0;
switch (type) {
case 'l': // left (horizontal)
dx[i] = minx - bbox.x;
break;
case 'c': // center (horizontal)
dx[i] = (minx + maxx) / 2 - (bbox.x + bbox.width / 2);
break;
case 'r': // right (horizontal)
dx[i] = maxx - (bbox.x + bbox.width);
break;
case 't': // top (vertical)
dy[i] = miny - bbox.y;
break;
case 'm': // middle (vertical)
dy[i] = (miny + maxy) / 2 - (bbox.y + bbox.height / 2);
break;
case 'b': // bottom (vertical)
dy[i] = maxy - (bbox.y + bbox.height);
break;
case 'l': // left (horizontal)
case 'left': // left (horizontal)
dx[i] = minx - bbox.x;
break;
case 'c': // center (horizontal)
case 'center': // center (horizontal)
dx[i] = (minx + maxx) / 2 - (bbox.x + bbox.width / 2);
break;
case 'r': // right (horizontal)
case 'right': // right (horizontal)
dx[i] = maxx - (bbox.x + bbox.width);
break;
case 't': // top (vertical)
case 'top': // top (vertical)
dy[i] = miny - bbox.y;
break;
case 'm': // middle (vertical)
case 'middle': // middle (vertical)
dy[i] = (miny + maxy) / 2 - (bbox.y + bbox.height / 2);
break;
case 'b': // bottom (vertical)
case 'bottom': // bottom (vertical)
dy[i] = maxy - (bbox.y + bbox.height);
break;
}
}
moveSelectedElements(dx, dy);
@@ -395,7 +416,7 @@ export const deleteSelectedElements = function () {
parent = parent.parentNode;
}
const {nextSibling} = t;
const { nextSibling } = t;
t.remove();
const elem = t;
selectedCopy.push(selected); // for the copy
@@ -416,16 +437,14 @@ export const deleteSelectedElements = function () {
export const copySelectedElements = function () {
const selectedElements = elementContext_.getSelectedElements();
const data =
JSON.stringify(selectedElements.map((x) => elementContext_.getJsonFromSvgElement(x)));
JSON.stringify(selectedElements.map((x) => elementContext_.getJsonFromSvgElement(x)));
// Use sessionStorage for the clipboard data.
sessionStorage.setItem(elementContext_.getClipboardID(), data);
elementContext_.flashStorage();
const menu = $('#cmenu_canvas');
// Context menu might not exist (it is provided by editor.js).
if (menu.enableContextMenuItems) {
menu.enableContextMenuItems('#paste,#paste_in_place');
}
const canvMenu = document.getElementById('se-cmenu_canvas');
canvMenu.setAttribute('enablemenuitems', '#paste,#paste_in_place');
};
/**
@@ -441,16 +460,17 @@ export const groupSelectedElements = function (type, urlArg) {
let cmdStr = '';
let url;
// eslint-disable-next-line sonarjs/no-small-switch
switch (type) {
case 'a': {
cmdStr = 'Make hyperlink';
url = urlArg || '';
break;
} default: {
type = 'g';
cmdStr = 'Group Elements';
break;
}
case 'a': {
cmdStr = 'Make hyperlink';
url = urlArg || '';
break;
} default: {
type = 'g';
cmdStr = 'Group Elements';
break;
}
}
const batchCmd = new BatchCommand(cmdStr);
@@ -515,7 +535,10 @@ export const pushGroupProperty = function (g, undoable) {
const gangle = getRotationAngle(g);
const gattrs = $(g).attr(['filter', 'opacity']);
const gattrs = {
filter: g.getAttribute('filter'),
opacity: g.getAttribute('opacity'),
};
let gfilter, gblur, changes;
const drawing = elementContext_.getDrawing();
@@ -688,17 +711,20 @@ export const convertToGroup = function (elem) {
if (!elem) {
elem = selectedElements[0];
}
const $elem = $(elem);
const $elem = elem;
const batchCmd = new BatchCommand();
let ts;
if ($elem.data('gsvg')) {
const dataStorage = elementContext_.getDataStorage();
if (dataStorage.has($elem, 'gsvg')) {
// Use the gsvg as the new group
const svg = elem.firstChild;
const pt = $(svg).attr(['x', 'y']);
const pt = {
x: svg.getAttribute('x'),
y: svg.getAttribute('y'),
};
$(elem.firstChild.firstChild).unwrap();
$(elem).removeData('gsvg');
dataStorage.remove(elem, 'gsvg');
const tlist = getTransformList(elem);
const xform = elementContext_.getSVGRoot().createSVGTransform();
@@ -706,8 +732,8 @@ export const convertToGroup = function (elem) {
tlist.appendItem(xform);
recalculateDimensions(elem);
elementContext_.call('selected', [elem]);
} else if ($elem.data('symbol')) {
elem = $elem.data('symbol');
} else if (dataStorage.has($elem, 'symbol')) {
elem = dataStorage.get($elem, 'symbol')
ts = $elem.attr('transform');
const pos = $elem.attr(['x', 'y']);
@@ -731,7 +757,7 @@ export const convertToGroup = function (elem) {
// See if other elements reference this symbol
const svgcontent = elementContext_.getSVGContent();
const hasMore = $(svgcontent).find('use:data(symbol)').length;
const hasMore = svgcontent.querySelectorAll('use:data(symbol)').length;
const g = elementContext_.getDOMDocument().createElementNS(NS.SVG, 'g');
const childs = elem.childNodes;
@@ -743,8 +769,11 @@ export const convertToGroup = function (elem) {
// Duplicate the gradients for Gecko, since they weren't included in the <symbol>
if (isGecko()) {
const dupeGrads = $(findDefs()).children('linearGradient,radialGradient,pattern').clone();
$(g).append(dupeGrads);
const svgElement = findDefs();
const gradients = svgElement.querySelectorAll('linearGradient,radialGradient,pattern');
for (let i = 0, im = gradients.length; im > i; i++) {
g.appendChild(gradients[i].cloneNode(true));
}
}
if (ts) {
@@ -757,7 +786,11 @@ export const convertToGroup = function (elem) {
// Put the dupe gradients back into <defs> (after uniquifying them)
if (isGecko()) {
$(findDefs()).append($(g).find('linearGradient,radialGradient,pattern'));
const svgElement = findDefs();
const elements = g.querySelectorAll('linearGradient,radialGradient,pattern');
for (let i = 0, im = elements.length; im > i; i++) {
svgElement.appendChild(elements[i]);
}
}
// now give the g itself a new id
@@ -768,7 +801,7 @@ export const convertToGroup = function (elem) {
if (parent) {
if (!hasMore) {
// remove symbol/svg element
const {nextSibling} = elem;
const { nextSibling } = elem;
elem.remove();
batchCmd.addSubCommand(new RemoveElementCommand(elem, nextSibling, parent));
}
@@ -789,14 +822,14 @@ export const convertToGroup = function (elem) {
try {
recalculateDimensions(n);
} catch (e) {
console.log(e); // eslint-disable-line no-console
console.log(e);
}
});
// Give ID for any visible element missing one
const visElems = elementContext_.getVisElems();
$(g).find(visElems).each(function () {
if (!this.id) { this.id = elementContext_.getNextId(); }
const visElems = g.querySelectorAll(elementContext_.getVisElems());
Array.prototype.forEach.call(visElems, function (el) {
if (!el.id) { el.id = elementContext_.getNextId(); }
});
elementContext_.selectOnly([g]);
@@ -808,7 +841,7 @@ export const convertToGroup = function (elem) {
elementContext_.addCommandToHistory(batchCmd);
} else {
console.log('Unexpected element to ungroup:', elem); // eslint-disable-line no-console
console.log('Unexpected element to ungroup:', elem);
}
};
@@ -820,11 +853,12 @@ export const convertToGroup = function (elem) {
*/
export const ungroupSelectedElement = function () {
const selectedElements = elementContext_.getSelectedElements();
const dataStorage = elementContext_.getDataStorage();
let g = selectedElements[0];
if (!g) {
return;
}
if ($(g).data('gsvg') || $(g).data('symbol')) {
if (dataStorage.has(g, 'gsvg') || dataStorage.has(g, 'symbol')) {
// Is svg, so actually convert to group
convertToGroup(g);
return;
@@ -832,11 +866,12 @@ export const ungroupSelectedElement = function () {
if (g.tagName === 'use') {
// Somehow doesn't have data set, so retrieve
const symbol = getElem(getHref(g).substr(1));
$(g).data('symbol', symbol).data('ref', symbol);
dataStorage.put(g, 'symbol', symbol);
dataStorage.put(g, 'ref', symbol);
convertToGroup(g);
return;
}
const parentsA = $(g).parents('a');
const parentsA = getParents(g.parentNode, 'a');
if (parentsA.length) {
g = parentsA[0];
}
@@ -859,7 +894,7 @@ export const ungroupSelectedElement = function () {
// Remove child title elements
if (elem.tagName === 'title') {
const {nextSibling} = elem;
const { nextSibling } = elem;
batchCmd.addSubCommand(new RemoveElementCommand(elem, nextSibling, oldParent));
elem.remove();
continue;
@@ -900,7 +935,7 @@ export const updateCanvas = function (w, h) {
elementContext_.getSVGRoot().setAttribute('width', w);
elementContext_.getSVGRoot().setAttribute('height', h);
const currentZoom = elementContext_.getCurrentZoom();
const bg = $('#canvasBackground')[0];
const bg = document.getElementById('canvasBackground');
const oldX = elementContext_.getSVGContent().getAttribute('x');
const oldY = elementContext_.getSVGContent().getAttribute('y');
const x = ((w - this.contentW * currentZoom) / 2);
@@ -947,9 +982,9 @@ export const updateCanvas = function (w, h) {
/**
* @type {module:svgcanvas.SvgCanvas#event:ext_canvasUpdated}
*/
{new_x: x, new_y: y, old_x: oldX, old_y: oldY, d_x: x - oldX, d_y: y - oldY}
{ new_x: x, new_y: y, old_x: oldX, old_y: oldY, d_x: x - oldX, d_y: y - oldY }
);
return {x, y, old_x: oldX, old_y: oldY, d_x: x - oldX, d_y: y - oldY};
return { x, y, old_x: oldX, old_y: oldY, d_x: x - oldX, d_y: y - oldY };
};
/**
* Select the next/previous element within the current layer.