UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

1,100 lines (1,024 loc) 54.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: editor/panels/TopPanel.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: editor/panels/TopPanel.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/* eslint-disable max-len */ /* globals seAlert */ import SvgCanvas from "../../svgcanvas/svgcanvas.js"; import { isValidUnit, getTypeMap, convertUnit } from "../../common/units.js"; const { $qa, $id } = SvgCanvas; /* * register actions for left panel */ /** * */ class TopPanel { /** * @param {PlainObject} editor svgedit handler */ constructor(editor) { this.editor = editor; } /** * @type {module} */ displayTool(className) { // default display is 'none' so removing the property will make the panel visible $qa(`.${className}`).map( (el) => el.style.removeProperty('display')); } /** * @type {module} */ hideTool(className) { $qa(`.${className}`).map( (el) => el.style.display = 'none'); } /** * @type {module} */ get selectedElement() { return this.editor.selectedElement; } /** * @type {module} */ get multiselected() { return this.editor.multiselected; } /** * @type {module} */ get path() { return this.editor.svgCanvas.pathActions; } /** * * @param {Element} opt * @param {boolean} changeElem * @returns {void} */ setStrokeOpt(opt, changeElem) { const { id } = opt; const bits = id.split('_'); const [ pre, val ] = bits; if (changeElem) { this.svgCanvas.setStrokeAttr('stroke-' + pre, val); } opt.classList.add('current'); const elements = Array.prototype.filter.call(opt.parentNode.children, function (child) { return child !== opt; }); Array.from(elements).forEach(function (element) { element.classList.remove('current'); }); } /** * Updates the toolbar (colors, opacity, etc) based on the selected element. * This function also updates the opacity and id elements that are in the * context panel. * @returns {void} */ update() { let i; let len; if (this.selectedElement) { switch (this.selectedElement.tagName) { case "use": case "image": case "foreignObject": break; case "g": case "a": { // Look for common styles const childs = this.selectedElement.getElementsByTagName("*"); let gWidth = null; for (i = 0, len = childs.length; i &lt; len; i++) { const swidth = childs[i].getAttribute("stroke-width"); if (i === 0) { gWidth = swidth; } else if (gWidth !== swidth) { gWidth = null; } } $id("stroke_width").value = (gWidth === null ? "" : gWidth); this.editor.bottomPanel.updateColorpickers(true); break; } default: { this.editor.bottomPanel.updateColorpickers(true); $id("stroke_width").value = this.selectedElement.getAttribute("stroke-width") || 1; $id("stroke_style").value = this.selectedElement.getAttribute("stroke-dasharray") || "none"; $id("stroke_style").setAttribute("value", $id("stroke_style").value); let attr = this.selectedElement.getAttribute("stroke-linejoin") || "miter"; if ($id("linejoin_" + attr)) { this.setStrokeOpt($id("linejoin_" + attr)); $id("stroke_linejoin").setAttribute("value", attr); } attr = this.selectedElement.getAttribute("stroke-linecap") || "butt"; if ($id("linecap_" + attr)) { this.setStrokeOpt($id("linecap_" + attr)); $id("stroke_linecap").setAttribute("value", attr); } } } } // All elements including image and group have opacity if (this.selectedElement) { const opacPerc = (this.selectedElement.getAttribute("opacity") || 1.0) * 100; $id("opacity").value = opacPerc; $id("elem_id").value = this.selectedElement.id; $id("elem_class").value = this.selectedElement.getAttribute("class") ?? ""; } this.editor.bottomPanel.updateToolButtonState(); } /** * @param {PlainObject} [opts={}] * @param {boolean} [opts.cancelDeletes=false] * @returns {void} Resolves to `undefined` */ promptImgURL({ cancelDeletes = false } = {}) { let curhref = this.editor.svgCanvas.getHref(this.editor.selectedElement); curhref = curhref.startsWith("data:") ? "" : curhref; // eslint-disable-next-line no-alert const url = prompt( this.editor.i18next.t('notification.enterNewImgURL'), curhref ); if (url) { this.setImageURL(url); } else if (cancelDeletes) { this.editor.svgCanvas.deleteSelectedElements(); } } /** * Updates the context panel tools based on the selected element. * @returns {void} */ updateContextPanel() { let elem = this.editor.selectedElement; // If element has just been deleted, consider it null if (!elem?.parentNode) { elem = null; } const currentLayerName = this.editor.svgCanvas .getCurrentDrawing() .getCurrentLayerName(); const currentMode = this.editor.svgCanvas.getMode(); const unit = this.editor.configObj.curConfig.baseUnit !== "px" ? this.editor.configObj.curConfig.baseUnit : null; const isNode = currentMode === "pathedit"; // elem ? (elem.id &amp;&amp; elem.id.startsWith('pathpointgrip')) : false; const menuItems = document.getElementById("se-cmenu_canvas"); this.hideTool("selected_panel"); this.hideTool("multiselected_panel"); this.hideTool("g_panel"); this.hideTool("rect_panel"); this.hideTool("circle_panel"); this.hideTool("ellipse_panel"); this.hideTool("line_panel"); this.hideTool("text_panel"); this.hideTool("image_panel"); this.hideTool("container_panel"); this.hideTool("use_panel"); this.hideTool("a_panel"); this.hideTool("xy_panel"); if (elem) { const elname = elem.nodeName; const angle = this.editor.svgCanvas.getRotationAngle(elem); $id("angle").value = angle; const blurval = this.editor.svgCanvas.getBlur(elem) * 10; $id("blur").value = blurval; if ( this.editor.svgCanvas.addedNew &amp;&amp; elname === "image" &amp;&amp; this.editor.svgCanvas.getMode() === "image" &amp;&amp; !this.editor.svgCanvas.getHref(elem).startsWith("data:") ) { /* await */ this.promptImgURL({ cancelDeletes: true }); } if (!isNode &amp;&amp; currentMode !== "pathedit") { this.displayTool("selected_panel"); // Elements in this array already have coord fields if ([ "line", "circle", "ellipse" ].includes(elname)) { this.hideTool("xy_panel"); } else { let x; let y; // Get BBox vals for g, polyline and path if ([ "g", "polyline", "path" ].includes(elname)) { const bb = this.editor.svgCanvas.getStrokedBBox([ elem ]); if (bb) { ({ x, y } = bb); } } else { x = elem.getAttribute("x"); y = elem.getAttribute("y"); } if (unit) { x = convertUnit(x); y = convertUnit(y); } $id("selected_x").value = (x || 0); $id("selected_y").value = (y || 0); this.displayTool("xy_panel"); } // Elements in this array cannot be converted to a path if ([ "image", "text", "path", "g", "use" ].includes(elname)) { this.hideTool("tool_topath"); } else { this.displayTool("tool_topath"); } if (elname === "path") { this.displayTool("tool_reorient"); } else { this.hideTool("tool_reorient"); } $id("tool_reorient").disabled = (angle === 0); } else { const point = this.path.getNodePoint(); $id("tool_add_subpath").pressed = false; // eslint-disable-next-line max-len (!this.path.canDeleteNodes) ? $id("tool_node_delete").classList.add("disabled") : $id("tool_node_delete").classList.remove("disabled"); // Show open/close button based on selected point // setIcon('#tool_openclose_path', path.closed_subpath ? 'open_path' : 'close_path'); if (point) { const segType = $id("seg_type"); if (unit) { point.x = convertUnit(point.x); point.y = convertUnit(point.y); } $id("path_node_x").value = (point.x); $id("path_node_y").value = (point.y); if (point.type) { segType.value = (point.type); segType.removeAttribute("disabled"); } else { segType.value = 4; segType.setAttribute("disabled", "disabled"); } } return; } // update contextual tools here const panels = { g: [], a: [], rect: [ "rx", "width", "height" ], image: [ "width", "height" ], circle: [ "cx", "cy", "r" ], ellipse: [ "cx", "cy", "rx", "ry" ], line: [ "x1", "y1", "x2", "y2" ], text: [], use: [] }; const { tagName } = elem; let linkHref = null; if (tagName === "a") { linkHref = this.editor.svgCanvas.getHref(elem); this.displayTool("g_panel"); } // siblings if (elem.parentNode) { const selements = Array.prototype.filter.call(elem.parentNode.children, function (child) { return child !== elem; }); if (elem.parentNode.tagName === "a" &amp;&amp; !selements.length) { this.displayTool("a_panel"); linkHref = this.editor.svgCanvas.getHref(elem.parentNode); } } // Hide/show the make_link buttons if (linkHref) { this.displayTool('tool_make_link'); this.displayTool('tool_make_link_multi'); $id("link_url").value = linkHref; } else { this.hideTool('tool_make_link'); this.hideTool('tool_make_link_multi'); } if (panels[tagName]) { const curPanel = panels[tagName]; this.displayTool(tagName + "_panel"); curPanel.forEach((item) => { let attrVal = elem.getAttribute(item); if (this.editor.configObj.curConfig.baseUnit !== "px" &amp;&amp; elem[item]) { const bv = elem[item].baseVal.value; attrVal = convertUnit(bv); } $id(`${tagName}_${item}`).value = attrVal || 0; }); if (tagName === "text") { this.displayTool("text_panel"); $id("tool_italic").pressed = this.editor.svgCanvas.getItalic(); $id("tool_bold").pressed = this.editor.svgCanvas.getBold(); $id("tool_font_family").setAttribute("value", elem.getAttribute("font-family")); $id("font_size").value = elem.getAttribute("font-size"); $id("text").value = elem.textContent; const textAnchorStart = $id("tool_text_anchor_start"); const textAnchorMiddle = $id("tool_text_anchor_middle"); const textAnchorEnd = $id("tool_text_anchor_end"); switch (elem.getAttribute("text-anchor")) { case "start": textAnchorStart.pressed = true; textAnchorMiddle.pressed = false; textAnchorEnd.pressed = false; break; case "middle": textAnchorStart.pressed = false; textAnchorMiddle.pressed = true; textAnchorEnd.pressed = false; break; case "end": textAnchorStart.pressed = false; textAnchorMiddle.pressed = false; textAnchorEnd.pressed = true; break; } if (this.editor.svgCanvas.addedNew) { // Timeout needed for IE9 setTimeout(() => { $id("text").focus(); $id("text").select(); }, 100); } // text } else if ( tagName === "image" &amp;&amp; this.editor.svgCanvas.getMode() === "image" ) { this.editor.svgCanvas.setImageURL( this.editor.svgCanvas.getHref(elem) ); // image } else if (tagName === "g" || tagName === "use") { this.displayTool("container_panel"); const title = this.editor.svgCanvas.getTitle(); const label = $id("g_title"); label.value = title; $id("g_title").disabled = (tagName === "use"); } } menuItems.setAttribute( (tagName === "g" ? "en" : "dis") + "ablemenuitems", "#ungroup" ); menuItems.setAttribute( (tagName === "g" || !this.multiselected ? "dis" : "en") + "ablemenuitems", "#group" ); // if (!isNullish(elem)) } else if (this.multiselected) { this.displayTool("multiselected_panel"); menuItems.setAttribute("enablemenuitems", "#group"); menuItems.setAttribute("disablemenuitems", "#ungroup"); } else { menuItems.setAttribute( "disablemenuitems", "#delete,#cut,#copy,#group,#ungroup,#move_front,#move_up,#move_down,#move_back" ); } // update history buttons $id("tool_undo").disabled = this.editor.svgCanvas.undoMgr.getUndoStackSize() === 0; $id("tool_redo").disabled = this.editor.svgCanvas.undoMgr.getRedoStackSize() === 0; this.editor.svgCanvas.addedNew = false; if ((elem &amp;&amp; !isNode) || this.multiselected) { // update the selected elements' layer $id("selLayerNames").removeAttribute("disabled"); $id("selLayerNames").value = currentLayerName; $id("selLayerNames").setAttribute("value", currentLayerName); // Enable regular menu options const canCMenu = document.getElementById("se-cmenu_canvas"); canCMenu.setAttribute( "enablemenuitems", "#delete,#cut,#copy,#move_front,#move_up,#move_down,#move_back" ); } else { $id("selLayerNames").setAttribute("disabled", "disabled"); } } /** * @param {Event} [e] Not used. * @param {boolean} forSaving * @returns {void} */ showSourceEditor(e, forSaving) { const $editorDialog = document.getElementById("se-svg-editor-dialog"); if ($editorDialog.getAttribute("dialog") === "open") return; const origSource = this.editor.svgCanvas.getSvgString(); $editorDialog.setAttribute("dialog", "open"); $editorDialog.setAttribute("value", origSource); $editorDialog.setAttribute("copysec", Boolean(forSaving)); $editorDialog.setAttribute("applysec", !forSaving); } /** * * @returns {void} */ clickWireframe() { $id("tool_wireframe").pressed = !$id("tool_wireframe").pressed; this.editor.workarea.classList.toggle("wireframe"); const wfRules = $id("wireframe_rules"); if (!wfRules) { const fcRules = document.createElement('style'); fcRules.setAttribute('id', 'wireframe_rules'); document.getElementsByTagName("head")[0].appendChild(fcRules); } else { while (wfRules.firstChild) wfRules.removeChild(wfRules.firstChild); } this.editor.updateWireFrame(); } /** * * @returns {void} */ clickUndo() { const { undoMgr, textActions } = this.editor.svgCanvas; if (undoMgr.getUndoStackSize() > 0) { undoMgr.undo(); this.editor.layersPanel.populateLayers(); if (this.editor.svgCanvas.getMode() === 'textedit') { textActions.clear(); } } } /** * * @returns {void} */ clickRedo() { const { undoMgr } = this.editor.svgCanvas; if (undoMgr.getRedoStackSize() > 0) { undoMgr.redo(); this.editor.layersPanel.populateLayers(); } } /** * @type {module} */ changeRectRadius(e) { this.editor.svgCanvas.setRectRadius(e.target.value); } /** * @type {module} */ changeFontSize(e) { this.editor.svgCanvas.setFontSize(e.target.value); } /** * @type {module} */ changeRotationAngle(e) { this.editor.svgCanvas.setRotationAngle(e.target.value); // eslint-disable-next-line max-len (Number.parseInt(e.target.value) === 0) ? $id("tool_reorient").classList.add("disabled") : $id("tool_reorient").classList.remove("disabled"); } /** * @param {PlainObject} e * @returns {void} */ changeBlur(e) { this.editor.svgCanvas.setBlur(e.target.value / 10, true); } /** * * @returns {void} */ clickGroup() { // group if (this.editor.multiselected) { this.editor.svgCanvas.groupSelectedElements(); // ungroup } else if (this.editor.selectedElement) { this.editor.svgCanvas.ungroupSelectedElement(); } } /** * * @returns {void} */ clickClone() { this.editor.svgCanvas.cloneSelectedElements(20, 20); } /** * @param {PlainObject} evt * @returns {void} */ clickAlignEle(evt) { this.editor.svgCanvas.alignSelectedElements(evt.detail.value, "page"); } /** * @param {string} pos indicate the alignment relative to top, bottom, middle etc.. * @returns {void} */ clickAlign(pos) { let value = $id("tool_align_relative").value; if (value === "") { value = "selected"; } this.editor.svgCanvas.alignSelectedElements(pos, value); } /** * * @type {module} */ attrChanger(e) { const attr = e.target.getAttribute("data-attr"); let val = e.target.value; const valid = isValidUnit(attr, val, this.selectedElement); if (!valid) { e.target.value = this.selectedElement.getAttribute(attr); // eslint-disable-next-line no-alert alert(this.editor.i18next.t('notification.invalidAttrValGiven')); return false; } if (attr !== "id" &amp;&amp; attr !== "class") { if (isNaN(val)) { val = this.editor.svgCanvas.convertToNum(attr, val); } else if (this.editor.configObj.curConfig.baseUnit !== "px") { // Convert unitless value to one with given unit const unitData = getTypeMap(); if ( this.editor.selectedElement[attr] || this.editor.svgCanvas.getMode() === "pathedit" || attr === "x" || attr === "y" ) { val *= unitData[this.editor.configObj.curConfig.baseUnit]; } } } // if the user is changing the id, then de-select the element first // change the ID, then re-select it with the new ID if (attr === "id") { const elem = this.editor.selectedElement; this.editor.svgCanvas.clearSelection(); elem.id = val; this.editor.svgCanvas.addToSelection([ elem ], true); } else { this.editor.svgCanvas.changeSelectedAttribute(attr, val); } return true; } /** * * @returns {void} */ convertToPath() { if (this.editor.selectedElement) { this.editor.svgCanvas.convertToPath(); } } /** * * @returns {void} */ reorientPath() { if (this.editor.selectedElement) { this.path.reorient(); } } /** * * @returns {void} Resolves to `undefined` */ makeHyperlink() { if (this.editor.selectedElement || this.multiselected) { // eslint-disable-next-line no-alert const url = prompt( this.editor.i18next.t('notification.enterNewLinkURL'), "http://" ); if (url) { this.editor.svgCanvas.makeHyperlink(url); } } } /** * * @returns {void} */ linkControlPoints() { $id("tool_node_link").pressed = ($id("tool_node_link").pressed) ? false : true; const linked = ($id("tool_node_link").pressed) ? true : false; this.path.linkControlPoints(linked); } /** * * @returns {void} */ clonePathNode() { if (this.path.getNodePoint()) { this.path.clonePathNode(); } } /** * * @returns {void} */ deletePathNode() { if (this.path.getNodePoint()) { this.path.deletePathNode(); } } /** * * @returns {void} */ addSubPath() { const button = $id("tool_add_subpath"); const sp = !button.classList.contains("pressed"); button.pressed = sp; // button.toggleClass('push_button_pressed tool_button'); this.path.addSubPath(sp); } /** * * @returns {void} */ opencloseSubPath() { this.path.opencloseSubPath(); } /** * Delete is a contextual tool that only appears in the ribbon if * an element has been selected. * @returns {void} */ deleteSelected() { if (this.editor.selectedElement || this.editor.multiselected) { this.editor.svgCanvas.deleteSelectedElements(); } } /** * * @returns {void} */ moveToTopSelected() { if (this.editor.selectedElement) { this.editor.svgCanvas.moveToTopSelectedElement(); } } /** * * @returns {void} */ moveToBottomSelected() { if (this.editor.selectedElement) { this.editor.svgCanvas.moveToBottomSelectedElement(); } } /** * * @returns {false} */ clickBold() { this.editor.svgCanvas.setBold(!this.editor.svgCanvas.getBold()); this.updateContextPanel(); return false; } /** * * @returns {false} */ clickItalic() { this.editor.svgCanvas.setItalic(!this.editor.svgCanvas.getItalic()); this.updateContextPanel(); return false; } /** * * @param {string} value "start","end" or "middle" * @returns {false} */ clickTextAnchor(value) { this.editor.svgCanvas.setTextAnchor(value); this.updateContextPanel(); return false; } /** * Set a selected image's URL. * @function module:SVGthis.setImageURL * @param {string} url * @returns {void} */ setImageURL(url) { const { editor } = this; if (!url) { url = editor.defaultImageURL; } editor.svgCanvas.setImageURL(url); $id("image_url").value = url; if (url.startsWith('data:')) { // data URI found this.hideTool("image_url"); } else { // regular URL const promised = editor.svgCanvas.embedImage(url); // eslint-disable-next-line promise/catch-or-return promised // eslint-disable-next-line promise/always-return .then(() => { // switch into "select" mode if we've clicked on an element editor.svgCanvas.setMode('select'); editor.svgCanvas.selectOnly(editor.svgCanvas.getSelectedElems(), true); }, (error) => { console.error("error =", error); seAlert(editor.i18next.t('tools.no_embed')); editor.svgCanvas.deleteSelectedElements(); }); this.displayTool("image_url"); } } /** * @param {boolean} editmode * @param {module:svgcanvas.SvgCanvas#event:selected} elems * @returns {void} */ togglePathEditMode(editMode, elems) { if (editMode) { this.displayTool('path_node_panel'); } else { this.hideTool('path_node_panel'); } if (editMode) { // Change select icon $id('tool_path').pressed = false; $id('tool_select').pressed = true; $id('tool_select').setAttribute('src', `select_node.svg`); this.editor.multiselected = false; if (elems.length) { this.editor.selectedElement = elems[0]; } } else { setTimeout(() => { $id('tool_select').setAttribute('src', `select.svg`); }, 1000); } } /** * @type {module} */ init() { // add Top panel const template = document.createElement("template"); const { i18next } = this.editor; // eslint-disable-next-line no-unsanitized/property template.innerHTML = ` &lt;div id="tools_top"> &lt;div id="editor_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_source" title="tools.tool_source" shortcut="U" src="source.svg">&lt;/se-button> &lt;se-button id="tool_wireframe" title="tools.wireframe_mode" shortcut="F" src="wireframe.svg">&lt;/se-button> &lt;/div> &lt;!-- editor_panel --> &lt;div id="history_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_undo" title="tools.undo" shortcut="Z" src="undo.svg" disabled>&lt;/se-button> &lt;se-button id="tool_redo" title="tools.redo" shortcut="Y" src="redo.svg" disabled>&lt;/se-button> &lt;/div> &lt;!-- history_panel --> &lt;!-- Buttons when a single element is selected --> &lt;div class="selected_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_clone" title="tools.clone" shortcut="D" src="clone.svg">&lt;/se-button> &lt;se-button id="tool_delete" title="tools.del" shortcut="Delete/Backspace" src="delete.svg">&lt;/se-button> &lt;/div> &lt;div class="selected_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_move_top" title="tools.move_top" shortcut="Ctrl+Shift+]" src="move_top.svg">&lt;/se-button> &lt;se-button id="tool_move_bottom" title="tools.move_bottom" shortcut="Ctrl+Shift+[" src="move_bottom.svg">&lt;/se-button> &lt;/div> &lt;div class="selected_panel"> &lt;se-button id="tool_topath" title="tools.to_path" src="to_path.svg">&lt;/se-button> &lt;se-button id="tool_reorient" title="tools.reorient_path" src="reorient.svg">&lt;/se-button> &lt;se-button id="tool_make_link" title="tools.make_link" src="globe_link.svg">&lt;/se-button> &lt;/div> &lt;div class="selected_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-input id="elem_id" data-attr="id" size="10" label="properties.id_label" title="properties.id">&lt;/se-input> &lt;/div> &lt;div class="selected_panel"> &lt;se-input id="elem_class" data-attr="class" size="10" label="properties.class_label" title="properties.class">&lt;/se-input> &lt;se-spin-input size="3" id="angle" min=-180 max=180 step=5 src="angle.svg" title="properties.angle">&lt;/se-spin-input> &lt;se-spin-input size="2" id="blur" min=0 max=100 step=5 src="blur.svg" title="properties.blur">&lt;/se-spin-input> &lt;se-list id="tool_position" title="tools.align_to_page" label="" width="22px" height="22px"> &lt;se-list-item id="tool_posleft" value="l" title="tools.align_left" src="align_left.svg" img-height="22px">&lt;/se-list-item> &lt;se-list-item id="tool_poscenter" value="c" title="tools.align_center" src="align_center.svg" img-height="22px">&lt;/se-list-item> &lt;se-list-item id="tool_posright" value="r" title="tools.align_right" src="align_right.svg" img-height="22px">&lt;/se-list-item> &lt;se-list-item id="tool_postop" value="t" title="tools.align_top" src="align_top.svg" img-height="22px">&lt;/se-list-item> &lt;se-list-item id="tool_posmiddle" value="m" title="tools.align_middle" src="align_middle.svg" img-height="22px">&lt;/se-list-item> &lt;se-list-item id="tool_posbottom" value="b" src="align_bottom.svg" title="tools.align_bottom" img-height="22px">&lt;/se-list-item> &lt;/se-list> &lt;/div> &lt;div class="xy_panel"> &lt;se-spin-input id="selected_x" data-attr="x" size="4" type="text" label="properties.x_label" title="properties.pos_x"> &lt;/se-spin-input> &lt;se-spin-input id="selected_y" data-attr="y" size="4" type="text" label="properties.y_label" title="properties.pos_y"> &lt;/se-spin-input> &lt;/div> &lt;!-- Buttons when multiple elements are selected --> &lt;div class="multiselected_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_clone_multi" title="tools.clone" shortcut="C" src="clone.svg">&lt;/se-button> &lt;se-button id="tool_delete_multi" title="tools.del" shortcut="Delete/Backspace" src="delete.svg">&lt;/se-button> &lt;/div> &lt;div class="multiselected_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_group_elements" title="tools.group_elements" shortcut="G" src="group_elements.svg"> &lt;/se-button> &lt;se-button id="tool_make_link_multi" title="tools.make_link" src="globe_link.svg">&lt;/se-button> &lt;se-button id="tool_align_left" title="tools.align_left" src="align_left.svg">&lt;/se-button> &lt;se-button id="tool_align_center" title="tools.align_center" src="align_center.svg">&lt;/se-button> &lt;se-button id="tool_align_right" title="tools.align_right" src="align_right.svg">&lt;/se-button> &lt;se-button id="tool_align_top" title="tools.align_top" src="align_top.svg">&lt;/se-button> &lt;se-button id="tool_align_middle" title="tools.align_middle" src="align_middle.svg">&lt;/se-button> &lt;se-button id="tool_align_bottom" title="tools.align_bottom" src="align_bottom.svg">&lt;/se-button> &lt;se-select id="tool_align_relative" label="tools.relativeTo" options="tools.selected_objects,tools.largest_object,tools.smallest_object,tools.page" values="selected::largest::smallest::page">&lt;/se-list-item> &lt;/se-select> &lt;/div> &lt;!-- multiselected_panel --> &lt;div class="rect_panel"> &lt;se-spin-input id="rect_width" data-attr="width" size="4" label="properties.w_label" title="properties.rect_width">&lt;/se-spin-input> &lt;se-spin-input id="rect_height" data-attr="height" size="4" label="properties.h_label" title="properties.rect_height">&lt;/se-spin-input> &lt;se-spin-input id="rect_rx" min=0 max=1000 step=1 size="3" title="properties.corner_radius" data-attr="Corner Radius" src="c_radius.svg">&lt;/se-spin-input> &lt;/div> &lt;!-- rect_panel --> &lt;div class="image_panel"> &lt;se-spin-input id="image_width" data-attr="width" size="4" type="text" label="properties.w_label" title="properties.image_width">&lt;/se-spin-input> &lt;se-spin-input id="image_height" data-attr="height" size="4" type="text" label="properties.h_label" title="properties.image_height">&lt;/se-spin-input> &lt;/div> &lt;div class="image_panel"> &lt;se-input id="image_url" data-attr="image_url" size="15" label="properties.image_url">&lt;/se-input> &lt;/div> &lt;div class="circle_panel"> &lt;se-spin-input id="circle_cx" data-attr="cx" size="4" label="properties.cx_label">&lt;/se-spin-input> &lt;se-spin-input id="circle_cy" data-attr="cy" size="4" label="properties.cy_label">&lt;/se-spin-input> &lt;/div> &lt;div class="circle_panel"> &lt;se-spin-input id="circle_r" data-attr="r" size="4" label="properties.r_label">&lt;/se-spin-input> &lt;/div> &lt;div class="ellipse_panel"> &lt;se-spin-input id="ellipse_cx" data-attr="cx" size="4" title="properties.ellipse_cx" label="properties.cx_label">&lt;/se-spin-input> &lt;se-spin-input id="ellipse_cy" data-attr="cy" size="4" title="properties.ellipse_cy" label="properties.cy_label">&lt;/se-spin-input> &lt;/div> &lt;div class="ellipse_panel"> &lt;se-spin-input id="ellipse_rx" data-attr="rx" size="4" title="properties.ellipse_rx" label="properties.rx_label">&lt;/se-spin-input> &lt;se-spin-input id="ellipse_ry" data-attr="ry" size="4" title="properties.ellipse_ry" label="properties.ry_label">&lt;/se-spin-input> &lt;/div> &lt;div class="line_panel"> &lt;se-spin-input id="line_x1" data-attr="x1" size="4" title="properties.line_x1" label="properties.x1_label">&lt;/se-spin-input> &lt;se-spin-input id="line_y1" data-attr="y1" size="4" title="properties.line_y1" label="properties.y1_label">&lt;/se-spin-input> &lt;se-spin-input id="line_x2" data-attr="x2" size="4" title="properties.line_x2" label="properties.x2_label">&lt;/se-spin-input> &lt;se-spin-input id="line_y2" data-attr="y2" size="4" title="properties.line_y2" label="properties.y2_label">&lt;/se-spin-input> &lt;/div> &lt;div class="text_panel"> &lt;se-button id="tool_bold" title="properties.bold" src="bold.svg" shortcut="B">&lt;/se-button> &lt;se-button id="tool_italic" title="properties.italic" src="italic.svg" shortcut="I">&lt;/se-button> &lt;se-select id="tool_font_family" label="properties.font_family_label" options="properties.serif,properties.sans_serif,properties.cursive,properties.fantasy,properties.monospace,properties.courier,properties.helvetica,properties.times" values="Serif::Sans-serif::Cursive::Fantasy::Monospace::Courier::Helvetica::Times">&lt;/select> &lt;se-spin-input size="2" id="font_size" min=1 max=1000 step=1 title="properties.font_size" src="fontsize.svg">&lt;/se-spin-input> &lt;/div> &lt;div class="text_panel"> &lt;se-button id="tool_text_anchor_start" title="properties.text_anchor_start" src="anchor_start.svg">&lt;/se-button> &lt;se-button id="tool_text_anchor_middle" title="properties.text_anchor_middle" src="anchor_middle.svg">&lt;/se-button> &lt;se-button id="tool_text_anchor_end" title="properties.text_anchor_end" src="anchor_end.svg">&lt;/se-button> &lt;/div> &lt;!-- Not visible, but still used --> &lt;input id="text" type="text" size="35" /> &lt;div class="container_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-input id="g_title" data-attr="title" size="8" label="properties.label">&lt;/se-input> &lt;/div> &lt;!-- container_panel --> &lt;div class="use_panel"> &lt;se-button id="tool_unlink_use" title="tools.tool_unlink_use" src="unlink_use.svg">&lt;/se-button> &lt;/div> &lt;!-- use_panel --> &lt;div class="g_panel"> &lt;se-button id="tool_ungroup" title="tools.ungroup" src="ungroup.svg">&lt;/se-button> &lt;/div> &lt;!-- g_panel --> &lt;!-- For anchor elements --> &lt;div class="a_panel"> &lt;label id="tool_link_url"> &lt;span id="linkLabel" class="icon_label">&lt;/span> &lt;input id="link_url" type="text" size="35" /> &lt;/label> &lt;/div> &lt;!-- a_panel --> &lt;div class="path_node_panel"> &lt;div class="tool_sep">&lt;/div> &lt;se-button id="tool_node_link" title="tools.node_link" src="tool_node_link.svg" pressed>&lt;/se-button> &lt;div class="tool_sep">&lt;/div> &lt;se-spin-input id="path_node_x" data-attr="x" size="4" title="properties.node_x" label="properties.x_label">&lt;/se-spin-input> &lt;se-spin-input id="path_node_y" data-attr="y" size="4" title="properties.node_y" label="properties.y_label">&lt;/se-spin-input> &lt;se-select id="seg_type" title="properties.seg_type" label="" options="properties.straight_segments,properties.curve_segments" values="4::6">&lt;/se-select> &lt;se-button id="tool_node_clone" title="tools.node_clone" src="tool_node_clone.svg">&lt;/se-button> &lt;se-button id="tool_node_delete" title="tools.node_delete" src="tool_node_delete.svg">&lt;/se-button> &lt;se-button id="tool_openclose_path" title="tools.openclose_path" src="tool_openclose_path.svg">&lt;/se-button> &lt;se-button id="tool_add_subpath" title="tools.add_subpath" src="tool_add_subpath.svg">&lt;/se-button> &lt;/div> &lt;!-- path_node_panel --> &lt;div id="cur_context_panel">&lt;/div> &lt;/div> `; this.editor.$svgEditor.append(template.content.cloneNode(true)); // svg editor source dialoag added to DOM const newSeEditorDialog = document.createElement( "se-svg-source-editor-dialog" ); newSeEditorDialog.setAttribute("id", "se-svg-editor-dialog"); this.editor.$container.append(newSeEditorDialog); newSeEditorDialog.init(i18next); $id("tool_link_url").setAttribute("title", i18next.t('tools.set_link_url')); // register action to top panel buttons $id("tool_source").addEventListener("click", this.showSourceEditor.bind(this)); $id("tool_wireframe").addEventListener("click", this.clickWireframe.bind(this)); $id("tool_undo").addEventListener("click", this.clickUndo.bind(this)); $id("tool_redo").addEventListener("click", this.clickRedo.bind(this)); $id("tool_clone").addEventListener("click", this.clickClone.bind(this)); $id("tool_clone_multi").addEventListener("click", this.clickClone.bind(this)); $id("tool_delete").addEventListener("click", this.deleteSelected.bind(this)); $id("tool_delete_multi").addEventListener("click", this.deleteSelected.bind(this)); $id("tool_move_top").addEventListener("click", this.moveToTopSelected.bind(this)); $id("tool_move_bottom").addEventListener("click", this.moveToBottomSelected.bind(this)); $id("tool_topath").addEventListener("click", this.convertToPath.bind(this)); $id("tool_make_link").addEventListener("click", this.makeHyperlink.bind(this)); $id("tool_make_link_multi").addEventListener("click", this.makeHyperlink.bind(this)); $id("tool_reorient").addEventListener("click", this.reorientPath.bind(this)); $id("tool_group_elements").addEventListener("click", this.clickGroup.bind(this)); $id("tool_position").addEventListener("change", (evt) => this.clickAlignEle.bind(this)(evt)); $id("tool_align_left").addEventListener("click", () => this.clickAlign.bind(this)("left")); $id("tool_align_right").addEventListener("click", () => this.clickAlign.bind(this)("right")); $id("tool_align_center").addEventListener("click", () => this.clickAlign.bind(this)("center")); $id("tool_align_top").addEventListener("click", () => this.clickAlign.bind(this)("top")); $id("tool_align_bottom").addEventListener("click", () => this.clickAlign.bind(this)("bottom")); $id("tool_align_middle").addEventListener("click", () => this.clickAlign.bind(this)("middle")); $id("tool_node_clone").addEventListener("click", this.clonePathNode.bind(this)); $id("tool_node_delete").addEventListener("click", this.deletePathNode.bind(this)); $id("tool_openclose_path").addEventListener("click", this.opencloseSubPath.bind(this)); $id("tool_add_subpath").addEventListener("click", this.addSubPath.bind(this)); $id("tool_node_link").addEventListener("click", this.linkControlPoints.bind(this)); $id("angle").addEventListener("change", this.changeRotationAngle.bind(this)); $id("blur").addEventListener("change", this.changeBlur.bind(this)); $id("rect_rx").addEventListener("change", this.changeRectRadius.bind(this)); $id("font_size").addEventListener("change", this.changeFontSize.bind(this)); $id("tool_ungroup").addEventListener("click", this.clickGroup.bind(this)); $id("tool_bold").addEventListener("click", this.clickBold.bind(this)); $id("tool_italic").addEventListener("click", this.clickItalic.bind(this)); $id("tool_text_anchor_start").addEventListener("click", () => this.clickTextAnchor.bind(this)("start")); $id("tool_text_anchor_middle").addEventListener("click", () => this.clickTextAnchor.bind(this)("middle")); $id("tool_text_anchor_end").addEventListener("click", () => this.clickTextAnchor.bind(this)("end")); $id("tool_unlink_use").addEventListener("click", this.clickGroup.bind(this)); $id('image_url').addEventListener('change', (evt) => { this.setImageURL(evt.currentTarget.value);}); // all top panel attributes [ "elem_id", "elem_class", "circle_cx", "circle_cy", "circle_r", "ellipse_cx", "ellipse_cy", "ellipse_rx", "ellipse_ry", "selected_x", "selected_y", "rect_width", "rect_height", "line_x1", "line_x2", "line_y1", "line_y2", "image_width", "image_height", "path_node_x", "path_node_y" ].forEach((attrId) => $id(attrId).addEventListener("change", this.attrChanger.bind(this)) ); } } export default TopPanel; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-blur.html">blur</a></li><li><a href="module-browser.html">browser</a></li><li><a href="module-clear.html">clear</a></li><li><a href="module-contextmenu.html">contextmenu</a></li><li><a href="module-coords.html">coords</a></li><li><a href="module-draw.html">draw</a></li><li><a href="module-elem-get-set%2520get%2520and%2520set%2520methods..html">elem-get-set get and set methods.</a></li><li><a href="module-event.html">event</a></li><li><a href="module-history.html">history</a></li><li><a href="module-jGraduate.html">jGraduate</a></li><li><a href="module-jPicker.html">jPicker</a></li><li><a href="module-jQueryAttr.html">jQueryAttr</a></li><li><a href="module-layer.html">layer</a></li><li><a href="module-locale.html">locale</a></li><li><a href="module-math.html">math</a></li><li><a href="module-namespaces.html">namespaces</a></li><li><a href="module-path.html">path</a></li><li><a href="module-recalculate.html">recalculate</a></li><li><a href="module-sanitize.html">sanitize</a></li><li><a href="module-select.html">select</a></li><li><a href="module-selected-elem.html">selected-elem</a></li><li><a href="module-selection.html">selection</a></li><li><a href="module-svg.html">svg</a></li><li><a href="module-svgcanvas.html">svgcanvas</a></li><li><a href="module-SVGEditor.html">SVGEditor</a></li><li><a href="module-text-actions%2520Tools%2520for%2520Text%2520edit%2520functions.html">text-actions Tools for Text edit functions</a></li><li><a href="module-undo.html">undo</a></li><li><a href="module-units.html">units</a></li><li><a href="module-utilities.html">utilities</a></li></ul><h3>Externals</h3><ul><li><a href="external-JamilihArray.html">JamilihArray</a></li><li><a href="external-jQuery.html">jQuery</a></li><li><a href="external-Math.html">Math</a></li><li><a href="external-MouseEvent.html">MouseEvent</a></li><li><a href="external-Window.html">Window</a></li></ul><h3>Namespaces</h3><ul><li><a href="external-jQuery.fn.html">fn</a></li><li><a href="external-jQuery.fn.$.fn.jPicker.defaults.html">defaults</a></li><li><a href="external-jQuery.fn.exports.jPickerMethod.html">exports.jPickerMethod</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.html">jGraduateDefaults</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.images.html">images</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.window.html">window</a></li><li><a href="external-jQuery.jGraduate.html">jGraduate</a></li><li><a href="external-jQuery.jPicker.html">jPicker</a></li><li><a href="external-jQuery.jPicker.ColorMethods.html">ColorMethods</a></li><li><a href="module-path.html#.pathActions">pathActions</a></li><li><a href="module-svgcanvas.SvgCanvas_pathActions.html">pathActions</a></li><li><a href="module-svgcanvas.SvgCanvas_textActions.html">textActions</a></li></ul><h3>Classes</h3><ul><li><a href="BottomPanel.html">BottomPanel</a></li><li><a href="configObj.html">configObj</a></li><li><a href="Dropdown.html">Dropdown</a></li><li><a href="EditorStartup.html">EditorStartup</a></li><li><a href="ElixMenuButton.html">ElixMenuButton</a></li><li><a href="ElixNumberSpinBox.html">ElixNumberSpinBox</a></li><li><a href="ExplorerButton.html">ExplorerButton</a></li><li><a href="external-jQuery.jGraduate.Paint.html">Paint</a></li><li><a href="external-jQuery.jPicker.Color.html">Color</a></li><li><a href="FlyingButton.html">FlyingButton</a></li><li><a href="LayersPanel.html">LayersPanel</a></li><li><a href="LeftPanel.html">LeftPanel</a></li><li><a href="MainMenu.html">MainMenu</a></li><li><a href="module.exports.html">exports</a></li><li><a href="module.exports_module.exports.html">exports</a></li><li><a href="module-draw.Drawing.html">Drawing</a></li><li><a href="module-draw.Layer.html">Layer</a></li><li><a href="module-history.BatchCommand.html">BatchCommand</a></li><li><a href="module-history.ChangeElementCommand.html">ChangeElementCommand</a></li><li><a href="module-history.Command.html">Command</a></li><li><a href="module-history.HistoryRecordingService.html">HistoryRecordingService</a></li><li><a href="module-history.InsertElementCommand.html">InsertElementCommand</a></li><li><a href="module-history.MoveElementCommand.html">MoveElementCommand</a></li><li><a href="module-history.RemoveElementCommand.html">RemoveElementCommand</a></li><li><a href="module-history.UndoManager.html">UndoManager</a></li><li><a href="module-jPicker.module.exports.html">module.exports</a></li><li><a href="module-layer.Layer.html">Layer</a></li><li><a href="module-path.Path.html">Path</a></li><li><a href="module-path.Segment.html">Segment</a></li><li><a href="module-select.Selector.html">Selector</a></li><li><a href="module-select.SelectorManager.html">SelectorManager</a></li><li><a href="module-svgcanvas.SvgCanvas.html">SvgCanvas</a></li><li><a href="module-SVGEditor-Editor.html">Editor</a></li><li><a href="NumberSpinBox.html">NumberSpinBox</a></li><li><a href="PaintBox.html">PaintBox</a></li><li><a href="PlainNumberSpinBox.html">PlainNumberSpinBox</a></li><li><a href="Rulers.html">Rulers</a></li><li><a href="SeCMenuDialog.html">SeCMenuDialog</a></li><li><a href="SeCMenuLayerDialog.html">SeCMenuLayerDialog</a></li><li><a href="SeColorPicker.html">SeColorPicker</a></li><li><a href="SeEditPrefsDialog.html">SeEditPrefsDialog</a></li><li><a href="SeExportDialog.html">SeExportDialog</a></li><li><a href="SeImgPropDialog.html">SeImgPropDialog</a></li><li><a href="SEInput.html">SEInput</a></li><li><a href="SeList.html">SeList</a></li><li><a href="SeMenu.html">SeMenu</a></li><li><a href="SeMenuItem.html">SeMenuItem</a></li><li><a href="SEPalette.html">SEPalette</a></li><li><a href="SePlainAlertDialog.html">SePlainAlertDialog</a></li><li><a href="SePlainBorderButton.html">SePlainBorderButton</a></li><li><a href="SePromptDialog.html">SePromptDialog</a></li><li><a href="SESpinInput.html">SESpinInput</a></li><li><a href="SeStorageDialog.html">SeStorageDialog</a></li><li><a href="SeSvgSourceEditorDialog.html">SeSvgSourceEditorDialog</a></li><li><a href="SeText.html">SeText</a></li><li><a href="ToolButton.html">ToolButton</a></li><li><a href="TopPanel.html">TopPanel</a></li></ul><h3>Interfaces</h3><ul><li><a href="module-coords.EditorContext.html">EditorContext</a></li><li><a href="module-draw.DrawCanvasInit.html">DrawCanvasInit</a></li><li><a href="module-history.HistoryCommand.html">HistoryCommand</a></li><li><a href="module-history.HistoryEventHandler.html">HistoryEventHandler</a></li><li><a href="module-locale.LocaleEditorInit.html">LocaleEditorInit</a></li><li><a href="module-path.EditorContext.html">EditorContext</a></li><li><a href="module-recalculate.EditorContext.html">EditorContext</a></li><li><a href="module-select.SVGFactory.html">SVGFactory</a></li><li><a href="module-svgcanvas.PrivateMethods.html">PrivateMethods</a></li><li><a href="module-SVGEditor.Config.html">Config</a></li><li><a href="module-SVGEditor.Prefs.html">Prefs</a></li><li><a href="module-SVGthis.CustomHandler.html">CustomHandler</a></li><li><a href="module-units.ElementContainer.html">ElementContainer</a></li><li><a href="module-utilities.EditorContext.html">EditorContext</a></li></ul><h3>Events</h3><ul><li><a href="module-history-Command.html#event:event:history">history</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:changed">changed</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:cleared">cleared</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:contextset">contextset</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:exported">exported</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:exportedPDF">exportedPDF</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_addLangData">ext_addLangData</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_callback">ext_callback</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_canvasUpdated">ext_canvasUpdated</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_elementChanged">ext_elementChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_elementTransition">ext_elementTransition</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_IDsUpdated">ext_IDsUpdated</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_langChanged">ext_langChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_langReady">ext_langReady</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseDown">ext_mouseDown</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseMove">ext_mouseMove</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseUp">ext_mouseUp</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_onNewDocument">ext_onNewDocument</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_selectedChanged">ext_selectedChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_toolButtonStateUpdate">ext_toolButtonStateUpdate</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_w