From 08b310a9f2e414899a753efeed04ffecd446c9f8 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 21 Feb 2019 16:26:26 +0800 Subject: [PATCH] - Linting (ESLint): Coding standards (prefer const, etc.) - Refactoring: Use array destructuring for clearer var naming; prefer `includes` over `indexOf` - Docs (CHANGES): Update - Build: Update dist files for non-ES use --- CHANGES.md | 1 + dist/extensions/ext-locale/placemark/en.js | 74 +++ dist/extensions/ext-placemark.js | 710 +++++++++++++++++++++ editor/extensions/ext-placemark.js | 409 ++++++------ 4 files changed, 1000 insertions(+), 194 deletions(-) create mode 100644 dist/extensions/ext-locale/placemark/en.js create mode 100644 dist/extensions/ext-placemark.js diff --git a/CHANGES.md b/CHANGES.md index cbce4ce6..263174d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - Optimization fix: Properly run code conditionally on browser check; fixes #312 (@ianli-sc) +- Enhancement: Add CAD Placemark extension (@NeiroNx) ## 4.2.0 diff --git a/dist/extensions/ext-locale/placemark/en.js b/dist/extensions/ext-locale/placemark/en.js new file mode 100644 index 00000000..23af187f --- /dev/null +++ b/dist/extensions/ext-locale/placemark/en.js @@ -0,0 +1,74 @@ +var svgEditorExtensionLocale_placemark_en = (function () { + 'use strict'; + + var en = { + name: 'placemark', + langList: [{ + id: 'nomarker', + title: 'No Marker' + }, { + id: 'leftarrow', + title: 'Left Arrow' + }, { + id: 'rightarrow', + title: 'Right Arrow' + }, { + id: 'forwardslash', + title: 'Forward Slash' + }, { + id: 'reverseslash', + title: 'Reverse Slash' + }, { + id: 'verticalslash', + title: 'Vertical Slash' + }, { + id: 'box', + title: 'Box' + }, { + id: 'star', + title: 'Star' + }, { + id: 'xmark', + title: 'X' + }, { + id: 'triangle', + title: 'Triangle' + }, { + id: 'mcircle', + title: 'Circle' + }, { + id: 'leftarrow_o', + title: 'Open Left Arrow' + }, { + id: 'rightarrow_o', + title: 'Open Right Arrow' + }, { + id: 'box_o', + title: 'Open Box' + }, { + id: 'star_o', + title: 'Open Star' + }, { + id: 'triangle_o', + title: 'Open Triangle' + }, { + id: 'mcircle_o', + title: 'Open Circle' + }], + buttons: [{ + title: 'Placemark Tool' + }], + contextTools: [{ + title: 'Select Place marker type' + }, { + title: 'Text on separated with ; ', + label: 'Text' + }, { + title: 'Font for text', + label: '' + }] + }; + + return en; + +}()); diff --git a/dist/extensions/ext-placemark.js b/dist/extensions/ext-placemark.js new file mode 100644 index 00000000..9f3013d0 --- /dev/null +++ b/dist/extensions/ext-placemark.js @@ -0,0 +1,710 @@ +var svgEditorExtension_placemark = (function () { + 'use strict'; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } + } + + function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + + _next(undefined); + }); + }; + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + + /** + * ext-placemark.js + * + * + * @copyright 2010 CloudCanvas, Inc. All rights reserved + * + */ + var extPlacemark = { + name: 'placemark', + init: function () { + var _init = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(S) { + var svgEditor, svgCanvas, addElem, $, importLocale, selElems, started, newPM, strings, markerTypes, showPanel, getLinked, updateText, updateFont, addMarker, setMarker, colorChanged, updateReferences, setArrowFromButton, getTitle, addMarkerButtons, buttons, contextTools; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + addMarkerButtons = function _ref11(buttons) { + Object.keys(markerTypes).forEach(function (id) { + var title = getTitle(String(id)); + buttons.push({ + id: 'placemark_marker_' + id, + svgicon: id, + icon: svgEditor.curConfig.extIconsPath + 'markers-' + id + '.png', + title: title, + type: 'context', + events: { + click: setArrowFromButton + }, + panel: 'placemark_panel', + list: 'placemark_marker', + isDefault: id === 'leftarrow' + }); + }); + return buttons; + }; + + getTitle = function _ref10(id) { + var langList = strings.langList; + var item = langList.find(function (itm) { + return itm.id === id; + }); + return item ? item.title : id; + }; + + setArrowFromButton = function _ref9(ev) { + var parts = this.id.split('_'); + var val = parts[2]; + + if (parts[3]) { + val += '_' + parts[3]; + } + + $('#placemark_marker').attr('value', val); + }; + + updateReferences = function _ref8(el) { + var id = 'placemark_marker_' + el.id; + var markerName = 'marker-start'; + var marker = getLinked(el, markerName); + + if (!marker || !marker.attributes.class) { + return; + } // not created by this extension + + + var url = el.getAttribute(markerName); + + if (url) { + var len = el.id.length; + var linkid = url.substr(-len - 1, len); + + if (el.id !== linkid) { + var val = $('#placemark_marker').attr('value') || 'leftarrow'; + addMarker(id, val); + svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')'); + svgCanvas.call('changed', selElems); + } + } + }; + + colorChanged = function _ref7(el) { + var color = el.getAttribute('stroke'); + var marker = getLinked(el, 'marker-start'); // console.log(marker); + + if (!marker) { + return; + } + + if (!marker.attributes.class) { + return; + } // not created by this extension + + + var ch = marker.lastElementChild; + + if (!ch) { + return; + } + + var curfill = ch.getAttribute('fill'); + var curstroke = ch.getAttribute('stroke'); + + if (curfill && curfill !== 'none') { + ch.setAttribute('fill', color); + } + + if (curstroke && curstroke !== 'none') { + ch.setAttribute('stroke', color); + } + }; + + setMarker = function _ref6(el, val) { + var markerName = 'marker-start'; + var marker = getLinked(el, markerName); + + if (marker) { + $(marker).remove(); + } + + el.removeAttribute(markerName); + + if (val === 'nomarker') { + svgCanvas.call('changed', [el]); + return; + } // Set marker on element + + + var id = 'placemark_marker_' + el.id; + addMarker(id, val); + el.setAttribute(markerName, 'url(#' + id + ')'); + svgCanvas.call('changed', [el]); + }; + + addMarker = function _ref5(id, val) { + var marker = svgCanvas.getElem(id); + + if (marker) { + return undefined; + } // console.log(id); + + + if (val === '' || val === 'nomarker') { + return undefined; + } + + var color = svgCanvas.getColor('stroke'); // NOTE: Safari didn't like a negative value in viewBox + // so we use a standardized 0 0 100 100 + // with 50 50 being mapped to the marker position + + var scale = 2; // parseFloat($('#marker_size').val()); + + var strokeWidth = 10; + var refX = 50; + var refY = 50; + var viewBox = '0 0 100 100'; + var markerWidth = 5 * scale; + var markerHeight = 5 * scale; + var seType = val; + + if (!markerTypes[seType]) { + return undefined; + } // an unknown type! + // positional markers(arrows) at end of line + + + if (seType.includes('left')) refX = 0; + if (seType.includes('right')) refX = 100; // create a generic marker + + marker = addElem({ + element: 'marker', + attr: { + id: id, + markerUnits: 'strokeWidth', + orient: 'auto', + style: 'pointer-events:none', + class: seType + } + }); + var mel = addElem(markerTypes[seType]); + var fillcolor = seType.substr(-2) === '_o' ? 'none' : color; + mel.setAttribute('fill', fillcolor); + mel.setAttribute('stroke', color); + mel.setAttribute('stroke-width', strokeWidth); + marker.append(mel); + marker.setAttribute('viewBox', viewBox); + marker.setAttribute('markerWidth', markerWidth); + marker.setAttribute('markerHeight', markerHeight); + marker.setAttribute('refX', refX); + marker.setAttribute('refY', refY); + svgCanvas.findDefs().append(marker); + return marker; + }; + + updateFont = function _ref4(font) { + font = font.split(' '); + var fontSize = parseInt(font.pop()); + font = font.join(' '); + selElems.forEach(function (elem) { + if (elem && elem.getAttribute('class').includes('placemark')) { + $(elem).children().each(function (_, i) { + var _i$id$split3 = i.id.split('_'), + _i$id$split4 = _slicedToArray(_i$id$split3, 3), + type = _i$id$split4[2]; + + if (type === 'txt') { + $(i).attr({ + 'font-family': font, + 'font-size': fontSize + }); + } + }); + } + }); + }; + + updateText = function _ref3(txt) { + var items = txt.split(';'); + selElems.forEach(function (elem) { + if (elem && elem.getAttribute('class').includes('placemark')) { + $(elem).children().each(function (_, i) { + var _i$id$split = i.id.split('_'), + _i$id$split2 = _slicedToArray(_i$id$split, 4), + type = _i$id$split2[2], + n = _i$id$split2[3]; + + if (type === 'txt') { + $(i).text(items[n]); + } + }); + } + }); + }; + + getLinked = function _ref2(elem, attr) { + if (!elem) { + return null; + } + + var str = elem.getAttribute(attr); + + if (!str) { + return null; + } + + var m = str.match(/\(#(.*)\)/); + + if (!m || m.length !== 2) { + return null; + } + + return svgCanvas.getElem(m[1]); + }; + + showPanel = function _ref(on) { + $('#placemark_panel').toggle(on); + }; + + svgEditor = this; + svgCanvas = svgEditor.canvas; + addElem = svgCanvas.addSVGElementFromJson; + $ = S.$, importLocale = S.importLocale; // {svgcontent}, + + _context.next = 17; + return importLocale(); + + case 17: + strings = _context.sent; + markerTypes = { + nomarker: {}, + forwardslash: { + element: 'path', + attr: { + d: 'M30,100 L70,0' + } + }, + reverseslash: { + element: 'path', + attr: { + d: 'M30,0 L70,100' + } + }, + verticalslash: { + element: 'path', + attr: { + d: 'M50,0 L50,100' + } + }, + xmark: { + element: 'path', + attr: { + d: 'M20,80 L80,20 M80,80 L20,20' + } + }, + leftarrow: { + element: 'path', + attr: { + d: 'M0,50 L100,90 L70,50 L100,10 Z' + } + }, + rightarrow: { + element: 'path', + attr: { + d: 'M100,50 L0,90 L30,50 L0,10 Z' + } + }, + box: { + element: 'path', + attr: { + d: 'M20,20 L20,80 L80,80 L80,20 Z' + } + }, + star: { + element: 'path', + attr: { + d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z' + } + }, + mcircle: { + element: 'circle', + attr: { + r: 30, + cx: 50, + cy: 50 + } + }, + triangle: { + element: 'path', + attr: { + d: 'M10,80 L50,20 L80,80 Z' + } + } + }; // duplicate shapes to support unfilled (open) marker types with an _o suffix + + ['leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle'].forEach(function (v) { + markerTypes[v + '_o'] = markerTypes[v]; + }); + /** + * + * @param {boolean} on + * @returns {undefined} + */ + + buttons = [{ + id: 'tool_placemark', + icon: svgEditor.curConfig.extIconsPath + 'placemark.png', + type: 'mode', + position: 12, + events: { + click: function click() { + showPanel(true); + svgCanvas.setMode('placemark'); + } + } + }]; + contextTools = [{ + type: 'button-select', + panel: 'placemark_panel', + id: 'placemark_marker', + colnum: 3, + events: { + change: setArrowFromButton + } + }, { + type: 'input', + panel: 'placemark_panel', + id: 'placemarkText', + size: 20, + defval: '', + events: { + change: function change() { + updateText(this.value); + } + } + }, { + type: 'input', + panel: 'placemark_panel', + id: 'placemarkFont', + size: 7, + defval: 'Arial 10', + events: { + change: function change() { + updateFont(this.value); + } + } + }]; + return _context.abrupt("return", { + name: strings.name, + svgicons: svgEditor.curConfig.extIconsPath + 'placemark-icons.xml', + buttons: addMarkerButtons(strings.buttons.map(function (button, i) { + return Object.assign(buttons[i], button); + })), + context_tools: strings.contextTools.map(function (contextTool, i) { + return Object.assign(contextTools[i], contextTool); + }), + callback: function callback() { + $('#placemark_panel').hide(); // const endChanges = function(){}; + }, + mouseDown: function mouseDown(opts) { + // const rgb = svgCanvas.getColor('fill'); + var sRgb = svgCanvas.getColor('stroke'); + var sWidth = svgCanvas.getStrokeWidth(); + + if (svgCanvas.getMode() === 'placemark') { + started = true; + var id = svgCanvas.getNextId(); + var items = $('#placemarkText').val().split(';'); + var font = $('#placemarkFont').val().split(' '); + var fontSize = parseInt(font.pop()); + font = font.join(' '); + var x0 = opts.start_x + 10, + y0 = opts.start_y + 10; + var maxlen = 0; + var children = [{ + element: 'line', + attr: { + id: id + '_pline_0', + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: opts.start_x, + y1: opts.start_y, + x2: x0, + y2: y0 + } + }]; + items.forEach(function (i, n) { + maxlen = Math.max(maxlen, i.length); + children.push({ + element: 'line', + attr: { + id: id + '_tline_' + n, + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: x0, + y1: y0 + (fontSize + 6) * n, + x2: x0 + i.length * fontSize * 0.5 + fontSize, + y2: y0 + (fontSize + 6) * n + } + }); + children.push({ + element: 'text', + attr: { + id: id + '_txt_' + n, + fill: sRgb, + stroke: 'none', + 'stroke-width': 0, + x: x0 + 3, + y: y0 - 3 + (fontSize + 6) * n, + 'font-family': font, + 'font-size': fontSize, + 'text-anchor': 'start' + }, + children: [i] + }); + }); + + if (items.length > 0) { + children.push({ + element: 'line', + attr: { + id: id + '_vline_0', + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: x0, + y1: y0, + x2: x0, + y2: y0 + (fontSize + 6) * (items.length - 1) + } + }); + } + + newPM = svgCanvas.addSVGElementFromJson({ + element: 'g', + attr: { + id: id, + class: 'placemark', + fontSize: fontSize, + maxlen: maxlen, + lines: items.length, + x: opts.start_x, + y: opts.start_y, + px: opts.start_x, + py: opts.start_y + }, + children: children + }); + setMarker(newPM.firstElementChild, $('#placemark_marker').attr('value') || 'leftarrow'); + return { + started: true + }; + } + + return undefined; + }, + mouseMove: function mouseMove(opts) { + if (!started) { + return undefined; + } + + if (svgCanvas.getMode() === 'placemark') { + var x = opts.mouse_x / svgCanvas.getZoom(); + var y = opts.mouse_y / svgCanvas.getZoom(); + + var _$$attr = $(newPM).attr(['fontSize', 'maxlen', 'lines', 'px', 'py']), + fontSize = _$$attr.fontSize, + maxlen = _$$attr.maxlen, + lines = _$$attr.lines, + px = _$$attr.px, + py = _$$attr.py; + + $(newPM).attr({ + x: x, + y: y + }); + $(newPM).children().each(function (_, i) { + var _i$id$split5 = i.id.split('_'), + _i$id$split6 = _slicedToArray(_i$id$split5, 4), + type = _i$id$split6[2], + n = _i$id$split6[3]; + + var y0 = y + (fontSize + 6) * n, + x0 = x + maxlen * fontSize * 0.5 + fontSize; + var nx = x + (x0 - x) / 2 < px ? x0 : x; + var ny = y + (fontSize + 6) * (lines - 1) / 2 < py ? y + (fontSize + 6) * (lines - 1) : y; + + if (type === 'pline') { + i.setAttribute('x2', nx); + i.setAttribute('y2', ny); + } + + if (type === 'tline') { + i.setAttribute('x1', x); + i.setAttribute('y1', y0); + i.setAttribute('x2', x0); + i.setAttribute('y2', y0); + } + + if (type === 'vline') { + i.setAttribute('x1', nx); + i.setAttribute('y1', y); + i.setAttribute('x2', nx); + i.setAttribute('y2', y + (fontSize + 6) * (lines - 1)); + } + + if (type === 'txt') { + i.setAttribute('x', x + fontSize / 2); + i.setAttribute('y', y0 - 3); + } + }); + return { + started: true + }; + } + + return undefined; + }, + mouseUp: function mouseUp() { + if (svgCanvas.getMode() === 'placemark') { + var _$$attr2 = $(newPM).attr(['x', 'y', 'px', 'py']), + x = _$$attr2.x, + y = _$$attr2.y, + px = _$$attr2.px, + py = _$$attr2.py; + + return { + keep: x != px && y != py, + // eslint-disable-line eqeqeq + element: newPM + }; + } + + return undefined; + }, + selectedChanged: function selectedChanged(opts) { + // Use this to update the current selected elements + selElems = opts.elems; + selElems.forEach(function (elem) { + if (elem && elem.getAttribute('class').includes('placemark')) { + var txt = []; + $(elem).children().each(function (n, i) { + var _i$id$split7 = i.id.split('_'), + _i$id$split8 = _slicedToArray(_i$id$split7, 3), + type = _i$id$split8[2]; + + if (type === 'txt') { + $('#placemarkFont').val(i.getAttribute('font-family') + ' ' + i.getAttribute('font-size')); + txt.push($(i).text()); + } + }); + $('#placemarkText').val(txt.join(';')); + showPanel(true); + } else { + showPanel(false); + } + }); + }, + elementChanged: function elementChanged(opts) { + opts.elems.forEach(function (elem) { + if (elem.id.includes('pline_0')) { + // need update marker of pline_0 + colorChanged(elem); + updateReferences(elem); + } + }); + } + }); + + case 23: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function init(_x) { + return _init.apply(this, arguments); + } + + return init; + }() + }; + + return extPlacemark; + +}()); diff --git a/editor/extensions/ext-placemark.js b/editor/extensions/ext-placemark.js index 8bb10a98..e904f898 100644 --- a/editor/extensions/ext-placemark.js +++ b/editor/extensions/ext-placemark.js @@ -44,7 +44,7 @@ export default { mcircle: {element: 'circle', attr: {r: 30, cx: 50, cy: 50}}, triangle: - {element: 'path', attr: {d: 'M10,80 L50,20 L80,80 Z'}}, + {element: 'path', attr: {d: 'M10,80 L50,20 L80,80 Z'}} }; // duplicate shapes to support unfilled (open) marker types with an _o suffix @@ -52,7 +52,6 @@ export default { markerTypes[v + '_o'] = markerTypes[v]; }); - /** * * @param {boolean} on @@ -79,35 +78,39 @@ export default { } /** - * Called when text is changed + * Called when text is changed. * @param {string} txt * @returns {undefined} */ - function updateText(txt){ - const items = txt.split(";"); - selElems.forEach((elem)=>{ - if (elem && elem.getAttribute('class').indexOf('placemark')!=-1) { - $(elem).children().each((n,i)=>{ - const type = i.id.split("_"); - if(type[2]=="txt")$(i).text(items[type[3]]); + function updateText (txt) { + const items = txt.split(';'); + selElems.forEach((elem) => { + if (elem && elem.getAttribute('class').includes('placemark')) { + $(elem).children().each((_, i) => { + const [, , type, n] = i.id.split('_'); + if (type === 'txt') { + $(i).text(items[n]); + } }); } }); } /** - * Called when font is changed + * Called when font is changed. * @param {string} font * @returns {undefined} */ - function updateFont(font){ - font = font.split(" "); + function updateFont (font) { + font = font.split(' '); const fontSize = parseInt(font.pop()); - font = font.join(" ") - selElems.forEach((elem)=>{ - if (elem && elem.getAttribute('class').indexOf('placemark')!=-1) { - $(elem).children().each((n,i)=>{ - const type = i.id.split("_"); - if(type[2]=="txt")$(i).attr({"font-family":font,"font-size":fontSize}); + font = font.join(' '); + selElems.forEach((elem) => { + if (elem && elem.getAttribute('class').includes('placemark')) { + $(elem).children().each((_, i) => { + const [, , type] = i.id.split('_'); + if (type === 'txt') { + $(i).attr({'font-family': font, 'font-size': fontSize}); + } }); } }); @@ -120,25 +123,25 @@ export default { function addMarker (id, val) { let marker = svgCanvas.getElem(id); if (marker) { return undefined; } - //console.log(id); + // console.log(id); if (val === '' || val === 'nomarker') { return undefined; } const color = svgCanvas.getColor('stroke'); // NOTE: Safari didn't like a negative value in viewBox // so we use a standardized 0 0 100 100 // with 50 50 being mapped to the marker position - const scale = 2;//parseFloat($('#marker_size').val()); + const scale = 2;// parseFloat($('#marker_size').val()); const strokeWidth = 10; let refX = 50; - let refY = 50; - let viewBox = '0 0 100 100'; - let markerWidth = 5*scale; - let markerHeight = 5*scale; - let seType = val; + const refY = 50; + const viewBox = '0 0 100 100'; + const markerWidth = 5 * scale; + const markerHeight = 5 * scale; + const seType = val; if (!markerTypes[seType]) { return undefined; } // an unknown type! - //positional markers(arrows) at end of line - if (seType.includes('left'))refX=0; - if (seType.includes('right'))refX=100; + // positional markers(arrows) at end of line + if (seType.includes('left')) refX = 0; + if (seType.includes('right')) refX = 100; // create a generic marker marker = addElem({ @@ -154,8 +157,8 @@ export default { const mel = addElem(markerTypes[seType]); const fillcolor = (seType.substr(-2) === '_o') - ? 'none' - : color; + ? 'none' + : color; mel.setAttribute('fill', fillcolor); mel.setAttribute('stroke', color); @@ -172,7 +175,8 @@ export default { return marker; } /** - * + * @param {Element} el + * @param {string} val * @returns {undefined} */ function setMarker (el, val) { @@ -200,7 +204,7 @@ export default { function colorChanged (el) { const color = el.getAttribute('stroke'); const marker = getLinked(el, 'marker-start'); - console.log(marker); + // console.log(marker); if (!marker) { return; } if (!marker.attributes.class) { return; } // not created by this extension const ch = marker.lastElementChild; @@ -218,31 +222,31 @@ export default { * @returns {undefined} */ function updateReferences (el) { - const id = "placemark_marker_" + el.id; - const markerName = 'marker-start'; - const marker = getLinked(el, markerName); - if (!marker || !marker.attributes.class) { return; } // not created by this extension - const url = el.getAttribute(markerName); - if (url) { - const len = el.id.length; - const linkid = url.substr(-len - 1, len); - if (el.id !== linkid) { - const val = $('#placemark_marker').attr('value') || 'leftarrow'; - addMarker(id, val); - svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')'); - svgCanvas.call('changed', selElems); - } + const id = 'placemark_marker_' + el.id; + const markerName = 'marker-start'; + const marker = getLinked(el, markerName); + if (!marker || !marker.attributes.class) { return; } // not created by this extension + const url = el.getAttribute(markerName); + if (url) { + const len = el.id.length; + const linkid = url.substr(-len - 1, len); + if (el.id !== linkid) { + const val = $('#placemark_marker').attr('value') || 'leftarrow'; + addMarker(id, val); + svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')'); + svgCanvas.call('changed', selElems); } + } } /** * @param {Event} ev * @returns {Promise} Resolves to `undefined` */ - async function setArrowFromButton (ev) { + function setArrowFromButton (ev) { const parts = this.id.split('_'); let val = parts[2]; if (parts[3]) { val += '_' + parts[3]; } - $("#placemark_marker").attr("value",val); + $('#placemark_marker').attr('value', val); } /** @@ -259,6 +263,7 @@ export default { /** * Build the toolbar button array from the marker definitions. + * @param {module:SVGEditor.Button[]} buttons * @returns {module:SVGEditor.Button[]} */ function addMarkerButtons (buttons) { @@ -273,7 +278,7 @@ export default { events: {click: setArrowFromButton}, panel: 'placemark_panel', list: 'placemark_marker', - isDefault: id=='leftarrow' + isDefault: id === 'leftarrow' }); }); return buttons; @@ -292,136 +297,146 @@ export default { } }]; const contextTools = [ - { + { type: 'button-select', panel: 'placemark_panel', id: 'placemark_marker', colnum: 3, events: {change: setArrowFromButton} - }, - { - type: 'input', - panel: 'placemark_panel', - id: 'placemarkText', - size: 20, - defval: '', - events: { - change () { - updateText(this.value); + }, + { + type: 'input', + panel: 'placemark_panel', + id: 'placemarkText', + size: 20, + defval: '', + events: { + change () { + updateText(this.value); + } + } + }, { + type: 'input', + panel: 'placemark_panel', + id: 'placemarkFont', + size: 7, + defval: 'Arial 10', + events: { + change () { + updateFont(this.value); + } } } - }, { - type: 'input', - panel: 'placemark_panel', - id: 'placemarkFont', - size: 7, - defval: 'Arial 10', - events: { - change () { - updateFont(this.value); - } - } - } ]; return { name: strings.name, svgicons: svgEditor.curConfig.extIconsPath + 'placemark-icons.xml', - buttons: addMarkerButtons(strings.buttons.map((button, i)=> Object.assign(buttons[i], button))), - context_tools: strings.contextTools.map((contextTool, i) => Object.assign(contextTools[i], contextTool)), + buttons: addMarkerButtons(strings.buttons.map((button, i) => { + return Object.assign(buttons[i], button); + })), + context_tools: strings.contextTools.map((contextTool, i) => { + return Object.assign(contextTools[i], contextTool); + }), callback () { $('#placemark_panel').hide(); // const endChanges = function(){}; }, mouseDown (opts) { - //const rgb = svgCanvas.getColor('fill'); + // const rgb = svgCanvas.getColor('fill'); const sRgb = svgCanvas.getColor('stroke'); const sWidth = svgCanvas.getStrokeWidth(); if (svgCanvas.getMode() === 'placemark') { started = true; const id = svgCanvas.getNextId(); - const items = $('#placemarkText').val().split(";"); - let font = $('#placemarkFont').val().split(" "); + const items = $('#placemarkText').val().split(';'); + let font = $('#placemarkFont').val().split(' '); const fontSize = parseInt(font.pop()); - font = font.join(" ") - let x0 = opts.start_x+10, y0 = opts.start_y+10,maxlen=0; - let children = [{ - element:'line', - attr:{ - id: id+'_pline_0', - fill:"none", - stroke: sRgb, - "stroke-width": sWidth, - "stroke-linecap":"round", - x1: opts.start_x, - y1: opts.start_y, - x2: x0, - y2: y0, - } - }]; - items.forEach((i,n)=>{ - maxlen=Math.max(maxlen,i.length) - children.push({ - element:'line', - attr:{ - id: id+'_tline_'+n, - fill:"none", - stroke: sRgb, - "stroke-width": sWidth, - "stroke-linecap":"round", - x1: x0, - y1: y0+(fontSize+6)*n, - x2: x0+i.length*fontSize*0.5+fontSize, - y2: y0+(fontSize+6)*n, - } - }); - children.push({ - element:'text', - attr:{ - id: id+'_txt_'+n, - fill: sRgb, - stroke: "none", - "stroke-width": 0, - x: x0+3, - y: y0-3+(fontSize+6)*n, - "font-family":font, - "font-size":fontSize, - "text-anchor":"start", - }, - children:[i] - }) + font = font.join(' '); + const x0 = opts.start_x + 10, y0 = opts.start_y + 10; + let maxlen = 0; + const children = [{ + element: 'line', + attr: { + id: id + '_pline_0', + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: opts.start_x, + y1: opts.start_y, + x2: x0, + y2: y0 + } + }]; + items.forEach((i, n) => { + maxlen = Math.max(maxlen, i.length); + children.push({ + element: 'line', + attr: { + id: id + '_tline_' + n, + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: x0, + y1: y0 + (fontSize + 6) * n, + x2: x0 + i.length * fontSize * 0.5 + fontSize, + y2: y0 + (fontSize + 6) * n + } + }); + children.push({ + element: 'text', + attr: { + id: id + '_txt_' + n, + fill: sRgb, + stroke: 'none', + 'stroke-width': 0, + x: x0 + 3, + y: y0 - 3 + (fontSize + 6) * n, + 'font-family': font, + 'font-size': fontSize, + 'text-anchor': 'start' + }, + children: [i] + }); }); - if(items.length>0)children.push({ - element:'line', - attr:{ - id: id+'_vline_0', - fill:"none", - stroke: sRgb, - "stroke-width": sWidth, - "stroke-linecap":"round", - x1: x0, - y1: y0, - x2: x0, - y2: y0+(fontSize+6)*(items.length-1), - } - }); + if (items.length > 0) { + children.push({ + element: 'line', + attr: { + id: id + '_vline_0', + fill: 'none', + stroke: sRgb, + 'stroke-width': sWidth, + 'stroke-linecap': 'round', + x1: x0, + y1: y0, + x2: x0, + y2: y0 + (fontSize + 6) * (items.length - 1) + } + }); + } newPM = svgCanvas.addSVGElementFromJson({ element: 'g', attr: { - id: id, - "class": "placemark", - fontSize:fontSize, - maxlen:maxlen, - lines:items.length, - x:opts.start_x, - y:opts.start_y, - px:opts.start_x, - py:opts.start_y, + id, + class: 'placemark', + fontSize, + maxlen, + lines: items.length, + x: opts.start_x, + y: opts.start_y, + px: opts.start_x, + py: opts.start_y }, - children: children, + children }); - setMarker(newPM.firstChild,$('#placemark_marker').attr('value') || 'leftarrow'); + setMarker( + newPM.firstElementChild, + $('#placemark_marker').attr('value') || 'leftarrow' + ); return { started: true }; @@ -433,36 +448,40 @@ export default { return undefined; } if (svgCanvas.getMode() === 'placemark') { - let x = opts.mouse_x/svgCanvas.getZoom(); - let y = opts.mouse_y/svgCanvas.getZoom(); - const {fontSize,maxlen,lines,px,py} = $(newPM).attr(['fontSize','maxlen','lines','px','py']); - $(newPM).attr({"x":x,"y":y}); - $(newPM).children().each((n,i)=>{ - const type = i.id.split("_"); - const y0 = y+(fontSize+6)*type[3],x0 = x+maxlen*fontSize*0.5+fontSize; - const nx = (x+(x0-x)/2 < px)?x0:x; - const ny = (y+((fontSize+6)*(lines-1))/2 < py)?y+(fontSize+6)*(lines-1):y; - if(type[2]=="pline"){ - i.setAttribute("x2",nx); - i.setAttribute("y2",ny); - - } - if(type[2]=="tline"){ - i.setAttribute("x1",x); - i.setAttribute("y1",y0); - i.setAttribute("x2",x0); - i.setAttribute("y2",y0); - } - if(type[2]=="vline"){ - i.setAttribute("x1",nx); - i.setAttribute("y1",y); - i.setAttribute("x2",nx); - i.setAttribute("y2",y+(fontSize+6)*(lines-1)); - } - if(type[2]=="txt"){ - i.setAttribute("x",x+fontSize/2); - i.setAttribute("y",y0-3); - } + const x = opts.mouse_x / svgCanvas.getZoom(); + const y = opts.mouse_y / svgCanvas.getZoom(); + const {fontSize, maxlen, lines, px, py} = $(newPM).attr( + ['fontSize', 'maxlen', 'lines', 'px', 'py'] + ); + $(newPM).attr({x, y}); + $(newPM).children().each((_, i) => { + const [, , type, n] = i.id.split('_'); + const y0 = y + (fontSize + 6) * n, + x0 = x + maxlen * fontSize * 0.5 + fontSize; + const nx = (x + (x0 - x) / 2 < px) ? x0 : x; + const ny = (y + ((fontSize + 6) * (lines - 1)) / 2 < py) + ? y + (fontSize + 6) * (lines - 1) + : y; + if (type === 'pline') { + i.setAttribute('x2', nx); + i.setAttribute('y2', ny); + } + if (type === 'tline') { + i.setAttribute('x1', x); + i.setAttribute('y1', y0); + i.setAttribute('x2', x0); + i.setAttribute('y2', y0); + } + if (type === 'vline') { + i.setAttribute('x1', nx); + i.setAttribute('y1', y); + i.setAttribute('x2', nx); + i.setAttribute('y2', y + (fontSize + 6) * (lines - 1)); + } + if (type === 'txt') { + i.setAttribute('x', x + fontSize / 2); + i.setAttribute('y', y0 - 3); + } }); return { started: true @@ -472,9 +491,9 @@ export default { }, mouseUp () { if (svgCanvas.getMode() === 'placemark') { - const {x,y,px,py} = $(newPM).attr(['x','y','px','py']) + const {x, y, px, py} = $(newPM).attr(['x', 'y', 'px', 'py']); return { - keep: (x!=px&&y!=py), + keep: (x != px && y != py), // eslint-disable-line eqeqeq element: newPM }; } @@ -483,17 +502,19 @@ export default { selectedChanged (opts) { // Use this to update the current selected elements selElems = opts.elems; - selElems.forEach((elem)=>{ - if (elem && elem.getAttribute('class').indexOf('placemark')!=-1) { - let txt = []; - $(elem).children().each((n,i)=>{ - const type = i.id.split("_"); - if(type[2]=="txt"){ - $('#placemarkFont').val(i.getAttribute("font-family")+' '+i.getAttribute("font-size")); - txt.push($(i).text()); + selElems.forEach((elem) => { + if (elem && elem.getAttribute('class').includes('placemark')) { + const txt = []; + $(elem).children().each((n, i) => { + const [, , type] = i.id.split('_'); + if (type === 'txt') { + $('#placemarkFont').val( + i.getAttribute('font-family') + ' ' + i.getAttribute('font-size') + ); + txt.push($(i).text()); } }); - $('#placemarkText').val(txt.join(";")); + $('#placemarkText').val(txt.join(';')); showPanel(true); } else { showPanel(false); @@ -501,12 +522,12 @@ export default { }); }, elementChanged (opts) { - opts.elems.forEach((elem)=>{ - if (elem.id.indexOf("pline_0")!=-1) {//need update marker of pline_0 + opts.elems.forEach((elem) => { + if (elem.id.includes('pline_0')) { // need update marker of pline_0 colorChanged(elem); updateReferences(elem); } - }); + }); } }; }