@@ -89,7 +89,7 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
$('#arrow_panel').toggle(on);
|
||||
$id('arrow_panel').style.display = (on) ? 'block' : 'none';
|
||||
if (on) {
|
||||
const el = selElems[0];
|
||||
const end = el.getAttribute('marker-end');
|
||||
@@ -219,21 +219,22 @@ export default {
|
||||
const marker = getLinked(elem, 'marker-' + type);
|
||||
if (!marker) { return; }
|
||||
|
||||
const curColor = $(marker).children().attr('fill');
|
||||
const curD = $(marker).children().attr('d');
|
||||
const curColor = marker.children.getAttribute('fill');
|
||||
const curD = marker.children.getAttribute('d');
|
||||
if (curColor === color) { return; }
|
||||
|
||||
const allMarkers = $(defs).find('marker');
|
||||
const allMarkers = defs.querySelectorAll('marker');
|
||||
let newMarker = null;
|
||||
// Different color, check if already made
|
||||
allMarkers.each(function () {
|
||||
const attrs = $(this).children().attr(['fill', 'd']);
|
||||
if (attrs.fill === color && attrs.d === curD) {
|
||||
Array.from(allMarkers).forEach(function(marker) {
|
||||
const attrsFill = marker.children.getAttribute('fill');
|
||||
const attrsD = marker.children.getAttribute('d');
|
||||
if (attrsFill === color && attrsD === curD) {
|
||||
// Found another marker with this color and this path
|
||||
newMarker = this;
|
||||
newMarker = marker;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!newMarker) {
|
||||
// Create a new marker with this color
|
||||
const lastId = marker.id;
|
||||
@@ -241,17 +242,17 @@ export default {
|
||||
|
||||
newMarker = addMarker(dir, type, arrowprefix + dir + allMarkers.length);
|
||||
|
||||
$(newMarker).children().attr('fill', color);
|
||||
newMarker.children.setAttribute('fill', color);
|
||||
}
|
||||
|
||||
$(elem).attr('marker-' + type, 'url(#' + newMarker.id + ')');
|
||||
elem.setAttribute('marker-' + type, 'url(#' + newMarker.id + ')');
|
||||
|
||||
// Check if last marker can be removed
|
||||
let remove = true;
|
||||
$(S.svgcontent).find('line, polyline, path, polygon').each(function () {
|
||||
const element = this;
|
||||
$.each(mtypes, function (j, mtype) {
|
||||
if ($(element).attr('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
const sElements = S.svgcontent.querySelectorAll('line, polyline, path, polygon');
|
||||
Array.prototype.forEach.call(sElements, function(element, i){
|
||||
mtypes.forEach(function(mtype, j){
|
||||
if (element.getAttribute('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
remove = false;
|
||||
return remove;
|
||||
}
|
||||
@@ -263,7 +264,7 @@ export default {
|
||||
|
||||
// Not found, so can safely remove
|
||||
if (remove) {
|
||||
$(marker).remove();
|
||||
marker.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -289,7 +290,7 @@ export default {
|
||||
$id("arrow_panel").style.display = 'none';
|
||||
|
||||
// Set ID so it can be translated in locale file
|
||||
$('#arrow_list option')[0].id = 'connector_no_arrow';
|
||||
$id('arrow_list option').setAttribute('id', 'connector_no_arrow');
|
||||
},
|
||||
async addLangData ({lang, importLocale}) {
|
||||
const {langList} = await importLocale();
|
||||
|
||||
@@ -38,7 +38,7 @@ export default {
|
||||
$id("showbutton").style.display = 'block';
|
||||
};
|
||||
const showPanel = function (on) {
|
||||
$('#closepath_panel').toggle(on);
|
||||
$id('closepath_panel').style.display = (on) ? 'block' : 'none';
|
||||
if (on) {
|
||||
const path = selElems[0];
|
||||
if (path) { updateButton(path); }
|
||||
|
||||
@@ -27,8 +27,7 @@ export default {
|
||||
const {getElem} = svgCanvas;
|
||||
const {$, svgroot} = S,
|
||||
addElem = svgCanvas.addSVGElementFromJson,
|
||||
selManager = S.selectorManager,
|
||||
elData = $.data;
|
||||
selManager = S.selectorManager;
|
||||
|
||||
let startX,
|
||||
startY,
|
||||
@@ -88,7 +87,6 @@ export default {
|
||||
*/
|
||||
function getOffset (side, line) {
|
||||
const giveOffset = line.getAttribute('marker-' + side);
|
||||
// const giveOffset = $(line).data(side+'_off');
|
||||
|
||||
// TODO: Make this number (5) be based on marker width/height
|
||||
const size = line.getAttribute('stroke-width') * 5;
|
||||
@@ -100,12 +98,14 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
let connRules = $('#connector_rules');
|
||||
if (!connRules.length) {
|
||||
connRules = $('<style id="connector_rules"></style>').appendTo('head');
|
||||
let connRules = $id('connector_rules');
|
||||
if (!connRules) {
|
||||
connRules = document.createElement('style');
|
||||
connRules.setAttribute('id', 'connector_rules');
|
||||
document.getElementsByTagName("head")[0].appendChild(connRules);
|
||||
}
|
||||
connRules.text(!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
||||
$('#connector_panel').toggle(on);
|
||||
connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
||||
$id('connector_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,24 +161,24 @@ export default {
|
||||
// const sw = line.getAttribute('stroke-width') * 5;
|
||||
|
||||
// Update bbox for this element
|
||||
const bb = elData(line, pre + '_bb');
|
||||
const bb = dataStorage.get(line, pre + '_bb');
|
||||
bb.x = conn.start_x + diffX;
|
||||
bb.y = conn.start_y + diffY;
|
||||
elData(line, pre + '_bb', bb);
|
||||
dataStorage.put(line, pre + '_bb', bb);
|
||||
|
||||
const altPre = conn.is_start ? 'end' : 'start';
|
||||
|
||||
// Get center pt of connected element
|
||||
const bb2 = elData(line, altPre + '_bb');
|
||||
const bb2 = dataStorage.get(line, altPre + '_bb');
|
||||
const srcX = bb2.x + bb2.width / 2;
|
||||
const srcY = bb2.y + bb2.height / 2;
|
||||
|
||||
// Set point of element being moved
|
||||
const pt = getBBintersect(srcX, srcY, bb, getOffset(pre, line)); // $(line).data(pre+'_off')?sw:0
|
||||
const pt = getBBintersect(srcX, srcY, bb, getOffset(pre, line));
|
||||
setPoint(line, conn.is_start ? 0 : 'end', pt.x, pt.y, true);
|
||||
|
||||
// Set point of connected element
|
||||
const pt2 = getBBintersect(pt.x, pt.y, elData(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
}
|
||||
}
|
||||
@@ -189,54 +189,50 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function findConnectors (elems = selElems) {
|
||||
const connectors = $(svgcontent).find('.se_connector');
|
||||
// const connectors = svgcontent.querySelectorAll('.se_connector');
|
||||
const connectors = svgcontent.querySelectorAll('.se_connector');
|
||||
connections = [];
|
||||
|
||||
// Loop through connectors to see if one is connected to the element
|
||||
connectors.each(function () {
|
||||
Array.prototype.forEach.call(connectors, function(ethis, i){
|
||||
let addThis;
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function add () {
|
||||
if (elems.includes(this)) {
|
||||
// Pretend this element is selected
|
||||
addThis = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the ends
|
||||
const parts = [];
|
||||
['start', 'end'].forEach(function (pos, i) {
|
||||
const key = 'c_' + pos;
|
||||
let part = elData(this, key);
|
||||
let part = dataStorage.get(ethis, key);
|
||||
if (part === null || part === undefined) { // Does this ever return nullish values?
|
||||
part = document.getElementById(
|
||||
this.attributes['se:connector'].value.split(' ')[i]
|
||||
ethis.attributes['se:connector'].value.split(' ')[i]
|
||||
);
|
||||
elData(this, 'c_' + pos, part.id);
|
||||
elData(this, pos + '_bb', svgCanvas.getStrokedBBox([part]));
|
||||
dataStorage.put(ethis, 'c_' + pos, part.id);
|
||||
dataStorage.put(ethis, pos + '_bb', svgCanvas.getStrokedBBox([part]));
|
||||
} else part = document.getElementById(part);
|
||||
parts.push(part);
|
||||
}, this);
|
||||
}, ethis);
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const cElem = parts[i];
|
||||
|
||||
addThis = false;
|
||||
// The connected element might be part of a selected group
|
||||
$(cElem).parents().each(add);
|
||||
parents = svgCanvas.getParents(cElem.parentNode);
|
||||
Array.prototype.forEach.call(parents, function(el, i){
|
||||
if (elems.includes(el)) {
|
||||
// Pretend this element is selected
|
||||
addThis = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!cElem || !cElem.parentNode) {
|
||||
$(this).remove();
|
||||
ethis.remove();
|
||||
continue;
|
||||
}
|
||||
if (elems.includes(cElem) || addThis) {
|
||||
const bb = svgCanvas.getStrokedBBox([cElem]);
|
||||
connections.push({
|
||||
elem: cElem,
|
||||
connector: this,
|
||||
connector: ethis,
|
||||
is_start: (i === 0),
|
||||
start_x: bb.x,
|
||||
start_y: bb.y
|
||||
@@ -270,13 +266,13 @@ export default {
|
||||
const bb = svgCanvas.getStrokedBBox([elem]);
|
||||
bb.x = conn.start_x;
|
||||
bb.y = conn.start_y;
|
||||
elData(line, pre + '_bb', bb);
|
||||
/* const addOffset = */ elData(line, pre + '_off');
|
||||
dataStorage.put(line, pre + '_bb', bb);
|
||||
/* const addOffset = */ dataStorage.get(line, pre + '_off');
|
||||
|
||||
const altPre = conn.is_start ? 'end' : 'start';
|
||||
|
||||
// Get center pt of connected element
|
||||
const bb2 = elData(line, altPre + '_bb');
|
||||
const bb2 = dataStorage.get(line, altPre + '_bb');
|
||||
const srcX = bb2.x + bb2.width / 2;
|
||||
const srcY = bb2.y + bb2.height / 2;
|
||||
|
||||
@@ -285,7 +281,7 @@ export default {
|
||||
setPoint(line, conn.is_start ? 0 : 'end', pt.x, pt.y, true);
|
||||
|
||||
// Set point of connected element
|
||||
const pt2 = getBBintersect(pt.x, pt.y, elData(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
|
||||
// Update points attribute manually for webkit
|
||||
@@ -308,7 +304,8 @@ export default {
|
||||
const gse = svgCanvas.groupSelectedElements;
|
||||
|
||||
svgCanvas.groupSelectedElements = function (...args) {
|
||||
svgCanvas.removeFromSelection($('.se_connector').toArray());
|
||||
|
||||
svgCanvas.removeFromSelection(document.querySelectorAll('.se_connector'));
|
||||
return gse.apply(this, args);
|
||||
};
|
||||
|
||||
@@ -329,17 +326,18 @@ export default {
|
||||
*/
|
||||
function init () {
|
||||
// Make sure all connectors have data set
|
||||
$(svgcontent).find('*').each(function () {
|
||||
const conn = this.getAttributeNS(seNs, 'connector');
|
||||
const elements = svgcontent.querySelectorAll('*');
|
||||
elements.forEach(function (curthis) {
|
||||
const conn = curthis.getAttributeNS(seNs, 'connector');
|
||||
if (conn) {
|
||||
this.setAttribute('class', 'se_connector');
|
||||
curthis.setAttribute('class', 'se_connector');
|
||||
const connData = conn.split(' ');
|
||||
const sbb = svgCanvas.getStrokedBBox([getElem(connData[0])]);
|
||||
const ebb = svgCanvas.getStrokedBBox([getElem(connData[1])]);
|
||||
$(this).data('c_start', connData[0])
|
||||
.data('c_end', connData[1])
|
||||
.data('start_bb', sbb)
|
||||
.data('end_bb', ebb);
|
||||
dataStorage.put(curthis, 'c_start', connData[0]);
|
||||
dataStorage.put(curthis, 'c_end', connData[1]);
|
||||
dataStorage.put(curthis, 'start_bb', sbb);
|
||||
dataStorage.put(curthis, 'end_bb', ebb);
|
||||
svgCanvas.getEditorNS(true);
|
||||
}
|
||||
});
|
||||
@@ -379,13 +377,13 @@ export default {
|
||||
|
||||
const mouseTarget = e.target;
|
||||
|
||||
const parents = $(mouseTarget).parents();
|
||||
const parents = svgCanvas.getParents(mouseTarget.parentNode);
|
||||
|
||||
if ($.inArray(svgcontent, parents) !== -1) {
|
||||
// Connectable element
|
||||
|
||||
// If child of foreignObject, use parent
|
||||
const fo = $(mouseTarget).closest('foreignObject');
|
||||
const fo = svgCanvas.getClosest(mouseTarget.parentNode, 'foreignObject');
|
||||
startElem = fo.length ? fo[0] : mouseTarget;
|
||||
|
||||
// Get center of source element
|
||||
@@ -408,7 +406,7 @@ export default {
|
||||
style: 'pointer-events:none'
|
||||
}
|
||||
});
|
||||
elData(curLine, 'start_bb', bb);
|
||||
dataStorage.put(curLine, 'start_bb', bb);
|
||||
}
|
||||
return {
|
||||
started: true
|
||||
@@ -433,7 +431,7 @@ export default {
|
||||
if (mode === 'connector' && started) {
|
||||
// const sw = curLine.getAttribute('stroke-width') * 3;
|
||||
// Set start point (adjusts based on bb)
|
||||
const pt = getBBintersect(x, y, elData(curLine, 'start_bb'), getOffset('start', curLine));
|
||||
const pt = getBBintersect(x, y, dataStorage.get(curLine, 'start_bb'), getOffset('start', curLine));
|
||||
startX = pt.x;
|
||||
startY = pt.y;
|
||||
|
||||
@@ -446,7 +444,7 @@ export default {
|
||||
while (slen--) {
|
||||
const elem = selElems[slen];
|
||||
// Look for selected connector elements
|
||||
if (elem && elData(elem, 'c_start')) {
|
||||
if (elem && dataStorage.get(elem, 'c_start')) {
|
||||
// Remove the "translate" transform given to move
|
||||
svgCanvas.removeFromSelection([elem]);
|
||||
svgCanvas.getTransformList(elem).clear();
|
||||
@@ -467,10 +465,10 @@ export default {
|
||||
if (svgCanvas.getMode() !== 'connector') {
|
||||
return undefined;
|
||||
}
|
||||
const fo = $(mouseTarget).closest('foreignObject');
|
||||
const fo = svgCanvas.getClosest(mouseTarget.parentNode, 'foreignObject');
|
||||
if (fo.length) { mouseTarget = fo[0]; }
|
||||
|
||||
const parents = $(mouseTarget).parents();
|
||||
const parents = svgCanvas.getParents(mouseTarget.parentNode);
|
||||
|
||||
if (mouseTarget === startElem) {
|
||||
// Start line through click
|
||||
@@ -481,9 +479,9 @@ export default {
|
||||
started
|
||||
};
|
||||
}
|
||||
if ($.inArray(svgcontent, parents) === -1) {
|
||||
if (parents.indexOf(svgcontent) === -1) {
|
||||
// Not a valid target element, so remove line
|
||||
$(curLine).remove();
|
||||
curLine.remove();
|
||||
started = false;
|
||||
return {
|
||||
keep: false,
|
||||
@@ -498,13 +496,13 @@ export default {
|
||||
const connStr = startId + ' ' + endId;
|
||||
const altStr = endId + ' ' + startId;
|
||||
// Don't create connector if one already exists
|
||||
const dupe = $(svgcontent).find('.se_connector').filter(function () {
|
||||
const conn = this.getAttributeNS(seNs, 'connector');
|
||||
const dupe = Array.prototype.filter.call(svgcontent.querySelectorAll('.se_connector'), function (aThis, i) {
|
||||
const conn = aThis.getAttributeNS(seNs, 'connector');
|
||||
if (conn === connStr || conn === altStr) { return true; }
|
||||
return false;
|
||||
});
|
||||
if (dupe.length) {
|
||||
$(curLine).remove();
|
||||
curLine.remove();
|
||||
return {
|
||||
keep: false,
|
||||
element: null,
|
||||
@@ -516,10 +514,9 @@ export default {
|
||||
|
||||
const pt = getBBintersect(startX, startY, bb, getOffset('start', curLine));
|
||||
setPoint(curLine, 'end', pt.x, pt.y, true);
|
||||
$(curLine)
|
||||
.data('c_start', startId)
|
||||
.data('c_end', endId)
|
||||
.data('end_bb', bb);
|
||||
dataStorage.put(curLine, 'c_start', startId);
|
||||
dataStorage.put(curLine, 'c_end', endId);
|
||||
dataStorage.put(curLine, 'end_bb', bb);
|
||||
seNs = svgCanvas.getEditorNS(true);
|
||||
curLine.setAttributeNS(seNs, 'se:connector', connStr);
|
||||
curLine.setAttribute('class', 'se_connector');
|
||||
@@ -536,7 +533,7 @@ export default {
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// TODO: Find better way to skip operations if no connectors are in use
|
||||
if (!$(svgcontent).find('.se_connector').length) { return; }
|
||||
if (!svgcontent.querySelectorAll('.se_connector').length) { return; }
|
||||
|
||||
if (svgCanvas.getMode() === 'connector') {
|
||||
svgCanvas.setMode('select');
|
||||
@@ -548,7 +545,7 @@ export default {
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
if (elem && elData(elem, 'c_start')) {
|
||||
if (elem && dataStorage.get(elem, 'c_start')) {
|
||||
selManager.requestSelector(elem).showGrips(false);
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
// TODO: Set up context tools and hide most regular line tools
|
||||
@@ -581,9 +578,8 @@ export default {
|
||||
const mid = elem.getAttribute('marker-mid');
|
||||
const end = elem.getAttribute('marker-end');
|
||||
curLine = elem;
|
||||
$(elem)
|
||||
.data('start_off', Boolean(start))
|
||||
.data('end_off', Boolean(end));
|
||||
dataStorage.put(elem, 'start_off', Boolean(start));
|
||||
dataStorage.put(elem, 'end_off', Boolean(end));
|
||||
|
||||
if (elem.tagName === 'line' && mid) {
|
||||
// Convert to polyline to accept mid-arrow
|
||||
@@ -606,7 +602,8 @@ export default {
|
||||
opacity: elem.getAttribute('opacity') || 1
|
||||
}
|
||||
});
|
||||
$(elem).after(pline).remove();
|
||||
elem.insertAdjacentElement('afterend', pline);
|
||||
elem.remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([pline]);
|
||||
@@ -615,7 +612,7 @@ export default {
|
||||
}
|
||||
// Update line if it's a connector
|
||||
if (elem.getAttribute('class') === 'se_connector') {
|
||||
const start = getElem(elData(elem, 'c_start'));
|
||||
const start = getElem(dataStorage.get(elem, 'c_start'));
|
||||
updateConnectors([start]);
|
||||
} else {
|
||||
updateConnectors();
|
||||
|
||||
@@ -44,12 +44,14 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
let fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
let fcRules = $id('fc_rules');
|
||||
if (!fcRules) {
|
||||
fcRules = document.createElement('style');
|
||||
fcRules.setAttribute('id', 'fc_rules');
|
||||
document.getElementsByTagName("head")[0].appendChild(fcRules);
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#foreignObject_panel').toggle(on);
|
||||
fcRules.textContent = !on ? '' : ' #tool_topath { display: none !important; }';
|
||||
$id('foreignObject_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,8 +59,10 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function toggleSourceButtons (on) {
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#foreign_save, #foreign_cancel').toggle(on);
|
||||
$id('tool_source_save').style.display = (!on) ? 'block' : 'none';
|
||||
$id('tool_source_cancel').style.display = (!on) ? 'block' : 'none';
|
||||
$id('foreign_save').style.display = (on) ? 'block' : 'none';
|
||||
$id('foreign_cancel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
let selElems,
|
||||
@@ -75,7 +79,8 @@ export default {
|
||||
const elt = selElems[0]; // The parent `Element` to append to
|
||||
try {
|
||||
// convert string into XML document
|
||||
const newDoc = text2xml('<svg xmlns="' + NS.SVG + '" xmlns:xlink="' + NS.XLINK + '">' + xmlString + '</svg>');
|
||||
const oi = (xmlString.indexOf('xmlns:oi') !== -1) ? ' xmlns:oi="' + NS.OI + '"' : '';
|
||||
const newDoc = text2xml('<svg xmlns="' + NS.SVG + '" xmlns:xlink="' + NS.XLINK + '" '+ oi +'>' + xmlString + '</svg>');
|
||||
// run it through our sanitizer to remove anything we do not support
|
||||
svgCanvas.sanitizeSvg(newDoc.documentElement);
|
||||
elt.replaceWith(svgdoc.importNode(newDoc.documentElement.firstChild, true));
|
||||
@@ -102,10 +107,10 @@ export default {
|
||||
elt.removeAttribute('fill');
|
||||
|
||||
const str = svgCanvas.svgToString(elt, 0);
|
||||
$('#svg_source_textarea').val(str);
|
||||
$('#svg_source_editor').fadeIn();
|
||||
$id('svg_source_textarea').value = str;
|
||||
$id('#svg_source_editor').style.display = 'block';
|
||||
properlySourceSizeTextArea();
|
||||
$('#svg_source_textarea').focus();
|
||||
$id('svg_source_textarea').focus();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,33 +193,45 @@ export default {
|
||||
const endChanges = function () {
|
||||
$id("svg_source_editor").style.display = 'none';
|
||||
editingforeign = false;
|
||||
$('#svg_source_textarea').blur();
|
||||
$id('svg_source_textarea').blur();
|
||||
toggleSourceButtons(false);
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */ $('#tool_source_save').clone()
|
||||
.hide().attr('id', 'foreign_save').unbind()
|
||||
.appendTo('#tool_source_back').click(function () {
|
||||
if (!editingforeign) { return; }
|
||||
const toolSourceSave = $id('tool_source_save').cloneNode(true);
|
||||
toolSourceSave.style.display = 'none';
|
||||
toolSourceSave.id = 'foreign_save';
|
||||
// unbind()
|
||||
// const oldElement = $id('tool_source_save');
|
||||
// oldElement.parentNode.replaceChild(toolSourceSave, oldElement);
|
||||
$id('tool_source_back').append(toolSourceSave);
|
||||
toolSourceSave.addEventListener('click', (e) => function () {
|
||||
if (!editingforeign) { return; }
|
||||
|
||||
if (!setForeignString($('#svg_source_textarea').val())) {
|
||||
const ok = seConfirm('Errors found. Revert to original?');
|
||||
if (!ok) { return; }
|
||||
endChanges();
|
||||
} else {
|
||||
endChanges();
|
||||
}
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* const cancel = */ $('#tool_source_cancel').clone()
|
||||
.hide().attr('id', 'foreign_cancel').unbind()
|
||||
.appendTo('#tool_source_back').click(function () {
|
||||
if (!setForeignString($id('svg_source_textarea').value)) {
|
||||
const ok = seConfirm('Errors found. Revert to original?');
|
||||
if (!ok) { return; }
|
||||
endChanges();
|
||||
});
|
||||
} else {
|
||||
endChanges();
|
||||
}
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
var oldToolSourceCancel = $id('tool_source_cancel');
|
||||
const toolSourceCancel = oldToolSourceCancel.cloneNode(true);
|
||||
toolSourceCancel.style.display = 'none';
|
||||
toolSourceCancel.id = 'foreign_cancel';
|
||||
$id('tool_source_back').append(toolSourceCancel);
|
||||
toolSourceCancel.addEventListener('click', (e) => function () {
|
||||
endChanges();
|
||||
});
|
||||
// unbind()
|
||||
// var oldToolSourceCancel = $id('tool_source_cancel');
|
||||
// oldToolSourceCancel.parentNode.replaceChild(toolSourceCancel, oldToolSourceCancel);
|
||||
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown (opts) {
|
||||
@@ -256,7 +273,10 @@ export default {
|
||||
if (svgCanvas.getMode() !== 'foreign' || !started) {
|
||||
return undefined;
|
||||
}
|
||||
const attrs = $(newFO).attr(['width', 'height']);
|
||||
const attrs = {
|
||||
width: newFO.getAttribute('width'),
|
||||
height: newFO.getAttribute('height'),
|
||||
}
|
||||
const keep = (attrs.width !== '0' || attrs.height !== '0');
|
||||
svgCanvas.addToSelection([newFO], true);
|
||||
|
||||
@@ -274,9 +294,9 @@ export default {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.tagName === 'foreignObject') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#foreign_font_size').val(elem.getAttribute('font-size'));
|
||||
$('#foreign_width').val(elem.getAttribute('width'));
|
||||
$('#foreign_height').val(elem.getAttribute('height'));
|
||||
$id('foreign_font_size').value = elem.getAttribute('font-size');
|
||||
$id('foreign_width').value = elem.getAttribute('width');
|
||||
$id('foreign_height').value = elem.getAttribute('height');
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
|
||||
@@ -25,15 +25,17 @@ export default {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
const svgdoc = document.getElementById('svgcanvas').ownerDocument,
|
||||
{assignAttributes} = svgCanvas,
|
||||
hcanvas = document.createElement('canvas'),
|
||||
canvBG = $('#canvasBackground'),
|
||||
units = getTypeMap(), // Assumes prior `init()` call on `units.js` module
|
||||
intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
||||
const {$id} = svgCanvas;
|
||||
const svgdoc = document.getElementById('svgcanvas').ownerDocument;
|
||||
const {assignAttributes} = svgCanvas;
|
||||
const hcanvas = document.createElement('canvas');
|
||||
const canvBG = $id('canvasBackground');
|
||||
const units = getTypeMap(); // Assumes prior `init()` call on `units.js` module
|
||||
const intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
||||
let showGrid = svgEditor.configObj.curConfig.showGrid || false;
|
||||
|
||||
$(hcanvas).hide().appendTo('body');
|
||||
hcanvas.style.display = 'none';
|
||||
document.body.appendChild(hcanvas);
|
||||
|
||||
const canvasGrid = svgdoc.createElementNS(NS.SVG, 'svg');
|
||||
assignAttributes(canvasGrid, {
|
||||
@@ -45,7 +47,7 @@ export default {
|
||||
overflow: 'visible',
|
||||
display: 'none'
|
||||
});
|
||||
canvBG.append(canvasGrid);
|
||||
canvBG.appendChild(canvasGrid);
|
||||
const gridDefs = svgdoc.createElementNS(NS.SVG, 'defs');
|
||||
// grid-pattern
|
||||
const gridPattern = svgdoc.createElementNS(NS.SVG, 'pattern');
|
||||
@@ -67,7 +69,7 @@ export default {
|
||||
});
|
||||
gridPattern.append(gridimg);
|
||||
gridDefs.append(gridPattern);
|
||||
$('#canvasGrid').append(gridDefs);
|
||||
$id('canvasGrid').appendChild(gridDefs);
|
||||
|
||||
// grid-box
|
||||
const gridBox = svgdoc.createElementNS(NS.SVG, 'rect');
|
||||
@@ -81,14 +83,14 @@ export default {
|
||||
fill: 'url(#gridpattern)',
|
||||
style: 'pointer-events: none; display:visible;'
|
||||
});
|
||||
$('#canvasGrid').append(gridBox);
|
||||
$id('canvasGrid').appendChild(gridBox);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Float} zoom
|
||||
* @returns {void}
|
||||
*/
|
||||
function updateGrid (zoom) {
|
||||
const updateGrid = (zoom) => {
|
||||
// TODO: Try this with <line> elements, then compare performance difference
|
||||
const unit = units[svgEditor.configObj.curConfig.baseUnit]; // 1 = 1px
|
||||
const uMulti = unit * zoom;
|
||||
@@ -141,11 +143,11 @@ export default {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function gridUpdate () {
|
||||
const gridUpdate = () => {
|
||||
if (showGrid) {
|
||||
updateGrid(svgCanvas.getZoom());
|
||||
}
|
||||
$('#canvasGrid').toggle(showGrid);
|
||||
$id('canvasGrid').style.display = (showGrid) ? 'block' : 'none';
|
||||
document.getElementById('view_grid').pressed = showGrid;
|
||||
}
|
||||
return {
|
||||
@@ -154,15 +156,19 @@ export default {
|
||||
if (showGrid) { updateGrid(zoom); }
|
||||
},
|
||||
callback () {
|
||||
if (showGrid) {
|
||||
gridUpdate();
|
||||
}
|
||||
},
|
||||
events: {
|
||||
id: 'view_grid',
|
||||
click () {
|
||||
// Add the button and its handler(s)
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-button id="view_grid" title="Show grid" src="./images/grid.svg"></se-button>
|
||||
`
|
||||
$id('editor_panel').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('view_grid').addEventListener("click", () => {
|
||||
svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
});
|
||||
|
||||
if (showGrid) {
|
||||
gridUpdate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-unsanitized/property */
|
||||
/* globals seConfirm */
|
||||
/**
|
||||
* @file ext-imagelib.js
|
||||
@@ -188,8 +189,10 @@ export default {
|
||||
await seConfirm(message);
|
||||
transferStopped = true;
|
||||
} else {
|
||||
entry = $('<div>').text(message).data('id', curMeta.id);
|
||||
preview.append(entry);
|
||||
entry = document.createElement('div');
|
||||
entry.textContent = message;
|
||||
entry.dataset.id = curMeta.id;
|
||||
preview.appendChild(entry);
|
||||
curMeta.entry = entry;
|
||||
}
|
||||
|
||||
@@ -256,51 +259,54 @@ export default {
|
||||
// Try to find a title
|
||||
// `dropXMLInternalSubset` is to help prevent the billion laughs attack
|
||||
const xml = new DOMParser().parseFromString(dropXMLInternalSubset(response), 'text/xml').documentElement; // lgtm [js/xml-bomb]
|
||||
title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
|
||||
title = xml.querySelector('title').textContent || '(SVG #' + response.length + ')';
|
||||
}
|
||||
if (curMeta) {
|
||||
$(preview).children().each(function () {
|
||||
if ($(this).data('id') === id) {
|
||||
Array.from(preview.children).forEach(function(element) {
|
||||
if (element.dataset.id === id) {
|
||||
if (curMeta.preview_url) {
|
||||
$(this).html(
|
||||
$('<span>').append(
|
||||
$('<img>').attr('src', curMeta.preview_url),
|
||||
title
|
||||
)
|
||||
);
|
||||
const img = document.createElement("img");
|
||||
img.src = curMeta.preview_url;
|
||||
const span = document.createElement("span");
|
||||
span.appendChild(img);
|
||||
element.append(span);
|
||||
} else {
|
||||
$(this).text(title);
|
||||
element.textContent = title;
|
||||
}
|
||||
submit.removeAttr('disabled');
|
||||
submit.removeAttribute('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
preview.append(
|
||||
$('<div>').text(title)
|
||||
);
|
||||
submit.removeAttr('disabled');
|
||||
const div = document.createElement("div");
|
||||
div.textContent = title;
|
||||
preview.appendChild(div);
|
||||
submit.removeAttribute('disabled');
|
||||
}
|
||||
} else {
|
||||
if (curMeta && curMeta.preview_url) {
|
||||
title = curMeta.name || '';
|
||||
entry = $('<span>').append(
|
||||
$('<img>').attr('src', curMeta.preview_url),
|
||||
title
|
||||
);
|
||||
entry = document.createElement('span');
|
||||
const img = document.createElement("img");
|
||||
img.src = curMeta.preview_url;
|
||||
entry.appendChild(img);
|
||||
entry.appendChild(document.createTextNode(title))
|
||||
} else {
|
||||
entry = $('<img>').attr('src', response);
|
||||
entry = document.createElement("img");
|
||||
entry.src = response;
|
||||
}
|
||||
|
||||
if (curMeta) {
|
||||
preview.children().each(function () {
|
||||
if ($(this).data('id') === id) {
|
||||
$(this).html(entry);
|
||||
submit.removeAttr('disabled');
|
||||
Array.from(preview.children).forEach(function(element) {
|
||||
if (element.dataset.id === id) {
|
||||
element.appendChild(entry);
|
||||
submit.removeAttribute('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
preview.append($('<div>').append(entry));
|
||||
submit.removeAttr('disabled');
|
||||
const div = document.createElement("div");
|
||||
div.appendChild(entry);
|
||||
preview.appendChild(div);
|
||||
submit.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -325,6 +331,23 @@ export default {
|
||||
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
||||
}
|
||||
|
||||
function toggleMultiLoop() {
|
||||
$.each(multiArr, function (i) {
|
||||
const type = this[0];
|
||||
const data = this[1];
|
||||
if (type === 'svg') {
|
||||
svgCanvas.importSvgString(data);
|
||||
} else {
|
||||
importImage(data);
|
||||
}
|
||||
svgCanvas.moveSelectedElements(i * 20, i * 20, false);
|
||||
});
|
||||
while(preview.firstChild)
|
||||
preview.removeChild(preview.firstChild);
|
||||
multiArr = [];
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} show
|
||||
* @returns {void}
|
||||
@@ -339,56 +362,18 @@ export default {
|
||||
preview.setAttribute('style', `position: absolute;top: 45px;right: 10px;width: 180px;bottom: 45px;background: #fff;overflow: auto;`);
|
||||
insertAfter($id('lib_framewrap'), preview);
|
||||
|
||||
/* submit = document.createElement('button');
|
||||
submit = document.createElement('button');
|
||||
submit.setAttribute('content', 'Import selected');
|
||||
submit.setAttribute('disabled', true);
|
||||
submit.textContent = 'Import selected';
|
||||
submit.setAttribute('style', `position: absolute;bottom: 10px;right: -10px;`);
|
||||
$id('imgbrowse').appendChild(submit);
|
||||
submit.addEventListener('click', function () {
|
||||
$.each(multiArr, function (i) {
|
||||
const type = this[0];
|
||||
const data = this[1];
|
||||
if (type === 'svg') {
|
||||
svgCanvas.importSvgString(data);
|
||||
} else {
|
||||
importImage(data);
|
||||
}
|
||||
svgCanvas.moveSelectedElements(i * 20, i * 20, false);
|
||||
});
|
||||
$(preview).empty();
|
||||
multiArr = [];
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
})
|
||||
submit.style.display = (show) ? 'block' : 'none';
|
||||
*/
|
||||
|
||||
|
||||
submit = $('<button disabled>Import selected</button>')
|
||||
.appendTo('#imgbrowse')
|
||||
.on('click touchend', function () {
|
||||
$.each(multiArr, function (i) {
|
||||
const type = this[0];
|
||||
const data = this[1];
|
||||
if (type === 'svg') {
|
||||
svgCanvas.importSvgString(data);
|
||||
} else {
|
||||
importImage(data);
|
||||
}
|
||||
svgCanvas.moveSelectedElements(i * 20, i * 20, false);
|
||||
});
|
||||
$(preview).empty();
|
||||
multiArr = [];
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
bottom: 10,
|
||||
right: -10
|
||||
});
|
||||
submit.addEventListener('click', toggleMultiLoop);
|
||||
submit.addEventListener('touchend', toggleMultiLoop);
|
||||
}
|
||||
|
||||
submit.style.display = (show) ? 'block' : 'none';
|
||||
preview.style.display = (show) ? 'block' : 'none';
|
||||
submit.toggle(show);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,52 +381,79 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showBrowser () {
|
||||
let browser = $('#imgbrowse');
|
||||
if (!browser.length) {
|
||||
$('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>' +
|
||||
'</div></div>').insertAfter('#svg_editor');
|
||||
browser = $('#imgbrowse');
|
||||
let browser = $id('imgbrowse');
|
||||
if (!browser) {
|
||||
const div = document.createElement('div');
|
||||
div.id = 'imgbrowse_holder';
|
||||
div.innerHTML = '<div id=imgbrowse class=toolbar_button></div>';
|
||||
insertAfter($id('svg_editor'), div);
|
||||
browser = $id('imgbrowse');
|
||||
|
||||
const allLibs = imagelibStrings.select_lib;
|
||||
|
||||
const libOpts = $('<ul id=imglib_opts>').appendTo(browser);
|
||||
const frame = $('<iframe src="javascript:0"/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');
|
||||
const divFrameWrap = document.createElement('div');
|
||||
divFrameWrap.id = 'lib_framewrap';
|
||||
|
||||
const header = $('<h1>').prependTo(browser).text(allLibs).css({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%'
|
||||
const libOpts = document.createElement('ul');
|
||||
libOpts.id = 'imglib_opts';
|
||||
browser.append(libOpts);
|
||||
const frame = document.createElement('iframe');
|
||||
frame.src = "javascript:0";
|
||||
frame.style.display = 'none';
|
||||
divFrameWrap.append(frame);
|
||||
browser.prepend(divFrameWrap);
|
||||
|
||||
const header = document.createElement('h1');
|
||||
browser.prepend(header);
|
||||
header.textContent = allLibs;
|
||||
header.setAttribute('style', `position: absolute;top: 0;left: 0;width: 100%;`);
|
||||
|
||||
const button = document.createElement('button');
|
||||
// eslint-disable-next-line max-len
|
||||
button.innerHTML = '<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + uiStrings.common.cancel ;
|
||||
browser.appendChild(button);
|
||||
button.addEventListener('click', function () {
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
});
|
||||
button.addEventListener('touchend', function () {
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
});
|
||||
button.setAttribute('style', `position: absolute;top: 5;right: -10;`);
|
||||
|
||||
const leftBlock = document.createElement('span');
|
||||
leftBlock.setAttribute('style', `position: absolute;top: 5;left: 10;`);
|
||||
browser.appendChild(leftBlock);
|
||||
|
||||
const back = document.createElement('button');
|
||||
back.style.visibility = "hidden";
|
||||
// eslint-disable-next-line max-len
|
||||
$('<button><img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + uiStrings.common.cancel + '</button>')
|
||||
.appendTo(browser)
|
||||
.on('click touchend', function () {
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
top: 5,
|
||||
right: -10
|
||||
});
|
||||
back.innerHTML = '<img class="svg_icon" src="./images/library.svg" alt="icon" width="16" height="16" />' + imagelibStrings.show_list;
|
||||
leftBlock.appendChild(back);
|
||||
back.addEventListener('click', function () {
|
||||
frame.setAttribute('src', 'about:blank');
|
||||
frame.style.display = 'none';
|
||||
libOpts.style.display = 'block';
|
||||
header.textContent = allLibs;
|
||||
back.style.display = 'none';
|
||||
});
|
||||
back.addEventListener('touchend', function () {
|
||||
frame.setAttribute('src', 'about:blank');
|
||||
frame.style.display = 'none';
|
||||
libOpts.style.display = 'block';
|
||||
header.textContent = allLibs;
|
||||
back.style.display = 'none';
|
||||
});
|
||||
back.setAttribute('style', `margin-right: 5px;`);
|
||||
back.style.display = 'none';
|
||||
|
||||
const leftBlock = $('<span>').css({position: 'absolute', top: 5, left: 10}).appendTo(browser);
|
||||
// eslint-disable-next-line max-len
|
||||
const back = $('<button hidden><img class="svg_icon" src="./images/library.svg" alt="icon" width="16" height="16" />' + imagelibStrings.show_list + '</button>')
|
||||
.appendTo(leftBlock)
|
||||
.on('click touchend', function () {
|
||||
frame.attr('src', 'about:blank').hide();
|
||||
libOpts.show();
|
||||
header.text(allLibs);
|
||||
back.hide();
|
||||
}).css({
|
||||
'margin-right': 5
|
||||
}).hide();
|
||||
|
||||
/* const type = */ $('<select><option value=s>' +
|
||||
imagelibStrings.import_single + '</option><option value=m>' +
|
||||
imagelibStrings.import_multi + '</option><option value=o>' +
|
||||
imagelibStrings.open + '</option></select>').appendTo(leftBlock).change(function () {
|
||||
mode = $(this).val();
|
||||
const select = document.createElement('select');
|
||||
select.innerHTML = '<select><option value=s>' +
|
||||
imagelibStrings.import_single + '</option><option value=m>' +
|
||||
imagelibStrings.import_multi + '</option><option value=o>' +
|
||||
imagelibStrings.open + '</option>';
|
||||
leftBlock.appendChild(select);
|
||||
select.addEventListener('change', function () {
|
||||
mode = this.value;
|
||||
switch (mode) {
|
||||
case 's':
|
||||
case 'o':
|
||||
@@ -453,23 +465,30 @@ export default {
|
||||
toggleMulti(true);
|
||||
break;
|
||||
}
|
||||
}).css({
|
||||
'margin-top': 10
|
||||
});
|
||||
select.setAttribute('style', `margin-top: 10px;`);
|
||||
|
||||
imagelibStrings.imgLibs.forEach(function ({name, url, description}) {
|
||||
$('<li>')
|
||||
.appendTo(libOpts)
|
||||
.text(name)
|
||||
.on('click touchend', function () {
|
||||
frame.attr(
|
||||
'src',
|
||||
url
|
||||
).show();
|
||||
header.text(name);
|
||||
libOpts.hide();
|
||||
back.show();
|
||||
}).append(`<span>${description}</span>`);
|
||||
const li = document.createElement('li');
|
||||
libOpts.appendChild(li);
|
||||
li.textContent = name;
|
||||
li.addEventListener('click', function () {
|
||||
frame.setAttribute('src', url);
|
||||
frame.style.display = 'block';
|
||||
header.textContent = name;
|
||||
libOpts.style.display = 'none';
|
||||
back.style.display = 'block';
|
||||
});
|
||||
li.addEventListener('touchend', function () {
|
||||
frame.setAttribute('src', url);
|
||||
frame.style.display = 'block';
|
||||
header.textContent = name;
|
||||
libOpts.style.display = 'none';
|
||||
back.style.display = 'block';
|
||||
});
|
||||
var span = document.createElement("span");
|
||||
span.textContent = description;
|
||||
li.appendChild(span);
|
||||
});
|
||||
} else {
|
||||
$id("imgbrowse_holder").style.display = 'block';
|
||||
@@ -487,81 +506,81 @@ export default {
|
||||
svgicons: 'ext-imagelib.xml',
|
||||
events,
|
||||
callback () {
|
||||
$('<style>').text(
|
||||
'#imgbrowse_holder {' +
|
||||
'position: absolute;' +
|
||||
'top: 0;' +
|
||||
'left: 0;' +
|
||||
'width: 100%;' +
|
||||
'height: 100%;' +
|
||||
'background-color: rgba(0, 0, 0, .5);' +
|
||||
'z-index: 5;' +
|
||||
'}' +
|
||||
'#imgbrowse {' +
|
||||
'position: absolute;' +
|
||||
'top: 25px;' +
|
||||
'left: 25px;' +
|
||||
'right: 25px;' +
|
||||
'bottom: 25px;' +
|
||||
'min-width: 300px;' +
|
||||
'min-height: 200px;' +
|
||||
'background: #B0B0B0;' +
|
||||
'border: 1px outset #777;' +
|
||||
'}' +
|
||||
'#imgbrowse h1 {' +
|
||||
'font-size: 20px;' +
|
||||
'margin: .4em;' +
|
||||
'text-align: center;' +
|
||||
'}' +
|
||||
'#lib_framewrap,' +
|
||||
'#imgbrowse > ul {' +
|
||||
'position: absolute;' +
|
||||
'top: 45px;' +
|
||||
'left: 10px;' +
|
||||
'right: 10px;' +
|
||||
'bottom: 10px;' +
|
||||
'background: white;' +
|
||||
'margin: 0;' +
|
||||
'padding: 0;' +
|
||||
'}' +
|
||||
'#imgbrowse > ul {' +
|
||||
'overflow: auto;' +
|
||||
'}' +
|
||||
'#imgbrowse > div {' +
|
||||
'border: 1px solid #666;' +
|
||||
'}' +
|
||||
'#imglib_preview > div {' +
|
||||
'padding: 5px;' +
|
||||
'font-size: 12px;' +
|
||||
'}' +
|
||||
'#imglib_preview img {' +
|
||||
'display: block;' +
|
||||
'margin: 0 auto;' +
|
||||
'max-height: 100px;' +
|
||||
'}' +
|
||||
'#imgbrowse li {' +
|
||||
'list-style: none;' +
|
||||
'padding: .5em;' +
|
||||
'background: #E8E8E8;' +
|
||||
'border-bottom: 1px solid #B0B0B0;' +
|
||||
'line-height: 1.2em;' +
|
||||
'font-style: sans-serif;' +
|
||||
'}' +
|
||||
'#imgbrowse li > span {' +
|
||||
'color: #666;' +
|
||||
'font-size: 15px;' +
|
||||
'display: block;' +
|
||||
'}' +
|
||||
'#imgbrowse li:hover {' +
|
||||
'background: #FFC;' +
|
||||
'cursor: pointer;' +
|
||||
'}' +
|
||||
'#imgbrowse iframe {' +
|
||||
'width: 100%;' +
|
||||
'height: 100%;' +
|
||||
'border: 0;' +
|
||||
'}'
|
||||
).appendTo('head');
|
||||
const style = document.createElement('style');
|
||||
style.textContent = '#imgbrowse_holder {' +
|
||||
'position: absolute;' +
|
||||
'top: 0;' +
|
||||
'left: 0;' +
|
||||
'width: 100%;' +
|
||||
'height: 100%;' +
|
||||
'background-color: rgba(0, 0, 0, .5);' +
|
||||
'z-index: 5;' +
|
||||
'}' +
|
||||
'#imgbrowse {' +
|
||||
'position: absolute;' +
|
||||
'top: 25px;' +
|
||||
'left: 25px;' +
|
||||
'right: 25px;' +
|
||||
'bottom: 25px;' +
|
||||
'min-width: 300px;' +
|
||||
'min-height: 200px;' +
|
||||
'background: #B0B0B0;' +
|
||||
'border: 1px outset #777;' +
|
||||
'}' +
|
||||
'#imgbrowse h1 {' +
|
||||
'font-size: 20px;' +
|
||||
'margin: .4em;' +
|
||||
'text-align: center;' +
|
||||
'}' +
|
||||
'#lib_framewrap,' +
|
||||
'#imgbrowse > ul {' +
|
||||
'position: absolute;' +
|
||||
'top: 45px;' +
|
||||
'left: 10px;' +
|
||||
'right: 10px;' +
|
||||
'bottom: 10px;' +
|
||||
'background: white;' +
|
||||
'margin: 0;' +
|
||||
'padding: 0;' +
|
||||
'}' +
|
||||
'#imgbrowse > ul {' +
|
||||
'overflow: auto;' +
|
||||
'}' +
|
||||
'#imgbrowse > div {' +
|
||||
'border: 1px solid #666;' +
|
||||
'}' +
|
||||
'#imglib_preview > div {' +
|
||||
'padding: 5px;' +
|
||||
'font-size: 12px;' +
|
||||
'}' +
|
||||
'#imglib_preview img {' +
|
||||
'display: block;' +
|
||||
'margin: 0 auto;' +
|
||||
'max-height: 100px;' +
|
||||
'}' +
|
||||
'#imgbrowse li {' +
|
||||
'list-style: none;' +
|
||||
'padding: .5em;' +
|
||||
'background: #E8E8E8;' +
|
||||
'border-bottom: 1px solid #B0B0B0;' +
|
||||
'line-height: 1.2em;' +
|
||||
'font-style: sans-serif;' +
|
||||
'}' +
|
||||
'#imgbrowse li > span {' +
|
||||
'color: #666;' +
|
||||
'font-size: 15px;' +
|
||||
'display: block;' +
|
||||
'}' +
|
||||
'#imgbrowse li:hover {' +
|
||||
'background: #FFC;' +
|
||||
'cursor: pointer;' +
|
||||
'}' +
|
||||
'#imgbrowse iframe {' +
|
||||
'width: 100%;' +
|
||||
'height: 100%;' +
|
||||
'border: 0;' +
|
||||
'}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,49 +1,52 @@
|
||||
/* globals jQuery */
|
||||
const $ = jQuery;
|
||||
$('a').click(function () {
|
||||
const {href} = this;
|
||||
const target = window.parent;
|
||||
const post = (message) => {
|
||||
// Todo: Make origin customizable as set by opening window
|
||||
// Todo: If dropping IE9, avoid stringifying
|
||||
target.postMessage(JSON.stringify({
|
||||
namespace: 'imagelib',
|
||||
...message
|
||||
}), '*');
|
||||
};
|
||||
// Convert Non-SVG images to data URL first
|
||||
// (this could also have been done server-side by the library)
|
||||
// Send metadata (also indicates file is about to be sent)
|
||||
post({
|
||||
name: $(this).text(),
|
||||
id: href
|
||||
});
|
||||
if (!href.includes('.svg')) {
|
||||
const img = new Image();
|
||||
img.addEventListener('load', function () {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = this.width;
|
||||
canvas.height = this.height;
|
||||
// load the raster image into the canvas
|
||||
canvas.getContext('2d').drawImage(this, 0, 0);
|
||||
// retrieve the data: URL
|
||||
let data;
|
||||
try {
|
||||
data = canvas.toDataURL();
|
||||
} catch (err) {
|
||||
// This fails in Firefox with `file:///` URLs :(
|
||||
// Todo: This could use a generic alert library instead
|
||||
alert('Data URL conversion failed: ' + err);
|
||||
data = '';
|
||||
}
|
||||
post({href, data});
|
||||
const atags = document.querySelectorAll('a');
|
||||
Array.prototype.forEach.call(atags, function (aEle, i) {
|
||||
aEle.addEventListener('click', function (event) {
|
||||
const { href } = event.currentTarget;
|
||||
const target = window.parent;
|
||||
const post = (message) => {
|
||||
// Todo: Make origin customizable as set by opening window
|
||||
// Todo: If dropping IE9, avoid stringifying
|
||||
target.postMessage(JSON.stringify({
|
||||
namespace: 'imagelib',
|
||||
...message
|
||||
}), '*');
|
||||
};
|
||||
// Convert Non-SVG images to data URL first
|
||||
// (this could also have been done server-side by the library)
|
||||
// Send metadata (also indicates file is about to be sent)
|
||||
post({
|
||||
name: event.currentTarget.textContent,
|
||||
id: href
|
||||
});
|
||||
img.src = href;
|
||||
} else {
|
||||
// Do ajax request for image's href value
|
||||
$.get(href, function (data) {
|
||||
post({href, data});
|
||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||
}
|
||||
return false;
|
||||
if (!href.includes('.svg')) {
|
||||
const img = new Image();
|
||||
img.addEventListener('load', function () {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = this.width;
|
||||
canvas.height = this.height;
|
||||
// load the raster image into the canvas
|
||||
canvas.getContext('2d').drawImage(this, 0, 0);
|
||||
// retrieve the data: URL
|
||||
let data;
|
||||
try {
|
||||
data = canvas.toDataURL();
|
||||
} catch (err) {
|
||||
// This fails in Firefox with `file:///` URLs :(
|
||||
// Todo: This could use a generic alert library instead
|
||||
alert('Data URL conversion failed: ' + err);
|
||||
data = '';
|
||||
}
|
||||
post({ href, data });
|
||||
});
|
||||
img.src = href;
|
||||
} else {
|
||||
// Do ajax request for image's href value
|
||||
$.get(href, function (data) {
|
||||
post({ href, data });
|
||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||
}
|
||||
return false;
|
||||
})
|
||||
});
|
||||
|
||||
@@ -121,9 +121,17 @@ export default {
|
||||
*/
|
||||
function setIcon (pos, id) {
|
||||
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
||||
const ci = '#' + idPrefix + pos + '_' + id.substr(1);
|
||||
svgEditor.setIcon('#cur_' + pos + '_marker_list', $(ci).children());
|
||||
$(ci).addClass('current').siblings().removeClass('current');
|
||||
const ci = idPrefix + pos + '_' + id.substr(1);
|
||||
console.log(ci)
|
||||
console.log('cur_' + pos + '_marker_list')
|
||||
svgEditor.setIcon('cur_' + pos + '_marker_list', $id(ci).children);
|
||||
$id(ci).classList.add('current');
|
||||
const siblings = Array.prototype.filter.call($id(ci).parentNode.children, function(child){
|
||||
return child !== $id(ci);
|
||||
});
|
||||
Array.from(siblings).forEach(function(sibling) {
|
||||
sibling.classList.remove('current');
|
||||
});
|
||||
}
|
||||
|
||||
let selElems;
|
||||
@@ -134,7 +142,7 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
$('#marker_panel').toggle(on);
|
||||
$id('marker_panel').style.display = (on) ? 'block' : 'none';
|
||||
|
||||
if (on) {
|
||||
const el = selElems[0];
|
||||
@@ -142,11 +150,11 @@ export default {
|
||||
let val, ci;
|
||||
$.each(mtypes, function (i, pos) {
|
||||
const m = getLinked(el, 'marker-' + pos);
|
||||
const txtbox = $('#' + pos + '_marker');
|
||||
const txtbox = $id(pos + '_marker');
|
||||
if (!m) {
|
||||
val = '\\nomarker';
|
||||
ci = val;
|
||||
txtbox.hide(); // hide text box
|
||||
txtbox.style.display = 'none';
|
||||
} else {
|
||||
if (!m.attributes.se_type) { return; } // not created by this extension
|
||||
val = '\\' + m.attributes.se_type.textContent;
|
||||
@@ -155,10 +163,10 @@ export default {
|
||||
val = m.lastChild.textContent;
|
||||
// txtbox.show(); // show text box
|
||||
} else {
|
||||
txtbox.hide(); // hide text box
|
||||
txtbox.style.display = 'none';
|
||||
}
|
||||
}
|
||||
txtbox.val(val);
|
||||
txtbox.value = val;
|
||||
setIcon(pos, ci);
|
||||
});
|
||||
}
|
||||
@@ -302,7 +310,8 @@ export default {
|
||||
batchCmd.addSubCommand(new S.RemoveElementCommand(elem, elem.parentNode));
|
||||
batchCmd.addSubCommand(new S.InsertElementCommand(pline));
|
||||
|
||||
$(elem).after(pline).remove();
|
||||
elem.insertAdjacentElement('afterend', pline);
|
||||
elem.remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([pline]);
|
||||
@@ -320,7 +329,7 @@ export default {
|
||||
const markerName = 'marker-' + pos;
|
||||
const el = selElems[0];
|
||||
const marker = getLinked(el, markerName);
|
||||
if (marker) { $(marker).remove(); }
|
||||
if (marker) { marker.remove(); }
|
||||
el.removeAttribute(markerName);
|
||||
let val = this.value;
|
||||
if (val === '') { val = '\\nomarker'; }
|
||||
@@ -379,7 +388,7 @@ export default {
|
||||
const len = el.id.length;
|
||||
const linkid = url.substr(-len - 1, len);
|
||||
if (el.id !== linkid) {
|
||||
const val = $('#' + pos + '_marker').attr('value');
|
||||
const val = $id(pos + '_marker').getAttribute('value');
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
if (el.tagName === 'line' && pos === 'mid') { el = convertline(el); }
|
||||
@@ -396,11 +405,8 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function triggerTextEntry (pos, val) {
|
||||
$('#' + pos + '_marker').val(val);
|
||||
$('#' + pos + '_marker').change();
|
||||
// const txtbox = $('#'+pos+'_marker');
|
||||
// if (val.substr(0,1)=='\\') {txtbox.hide();}
|
||||
// else {txtbox.show();}
|
||||
$id(pos + '_marker').value = val;
|
||||
$id(pos + '_marker').change();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,7 +414,7 @@ export default {
|
||||
* @returns {void} Resolves to `undefined`
|
||||
*/
|
||||
function showTextPrompt (pos) {
|
||||
let def = $('#' + pos + '_marker').val();
|
||||
let def = $id(pos + '_marker').value;
|
||||
if (def.substr(0, 1) === '\\') { def = ''; }
|
||||
// eslint-disable-next-line no-alert
|
||||
const txt = prompt('Enter text for ' + pos + ' marker', def);
|
||||
|
||||
@@ -82,7 +82,7 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function saveMath () {
|
||||
const code = $('#mathjax_code_textarea').val();
|
||||
const code = $id('mathjax_code_textarea').value;
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
@@ -145,37 +145,30 @@ export default {
|
||||
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
|
||||
// From this point on it is very probable that it will be needed, so load it.
|
||||
if (mathjaxLoaded === false) {
|
||||
$(
|
||||
'<div id="mathjax">' +
|
||||
'<!-- Here is where MathJax creates the math -->' +
|
||||
'<div id="mathjax_creator" class="tex2jax_process" style="display:none">' +
|
||||
'$${}$$' +
|
||||
'</div>' +
|
||||
'<div id="mathjax_overlay"></div>' +
|
||||
'<div id="mathjax_container">' +
|
||||
'<div id="tool_mathjax_back" class="toolbar_button">' +
|
||||
'<button id="tool_mathjax_save">OK</button>' +
|
||||
'<button id="tool_mathjax_cancel">Cancel</button>' +
|
||||
'</div>' +
|
||||
'<fieldset>' +
|
||||
'<legend id="mathjax_legend">Mathematics Editor</legend>' +
|
||||
'<label>' +
|
||||
'<span id="mathjax_explication">Please type your mathematics in ' +
|
||||
'<a href="https://en.wikipedia.org/wiki/Help:' +
|
||||
'Displaying_a_formula" target="_blank">TeX</a> code.' +
|
||||
'</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
).insertAfter('#svg_prefs').hide();
|
||||
// Make the MathEditor draggable.
|
||||
// TODO: unable to reach this place
|
||||
/* $('#mathjax_container').draggable({
|
||||
cancel: 'button,fieldset',
|
||||
containment: 'window'
|
||||
}); */
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'mathjax';
|
||||
div.innerHTML = '<!-- Here is where MathJax creates the math -->' +
|
||||
'<div id="mathjax_creator" class="tex2jax_process" style="display:none">' +
|
||||
'$${}$$' +
|
||||
'</div>' +
|
||||
'<div id="mathjax_overlay"></div>' +
|
||||
'<div id="mathjax_container">' +
|
||||
'<div id="tool_mathjax_back" class="toolbar_button">' +
|
||||
'<button id="tool_mathjax_save">OK</button>' +
|
||||
'<button id="tool_mathjax_cancel">Cancel</button>' +
|
||||
'</div>' +
|
||||
'<fieldset>' +
|
||||
'<legend id="mathjax_legend">Mathematics Editor</legend>' +
|
||||
'<label>' +
|
||||
'<span id="mathjax_explication">Please type your mathematics in ' +
|
||||
'<a href="https://en.wikipedia.org/wiki/Help:' +
|
||||
'Displaying_a_formula" target="_blank">TeX</a> code.' +
|
||||
'</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>';
|
||||
$id('svg_prefs').parentNode.insertBefore(div, $id('svg_prefs').nextSibling);
|
||||
div.style.display = 'none';
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true))
|
||||
.on('click touched', function () {
|
||||
@@ -238,59 +231,57 @@ export default {
|
||||
return undefined;
|
||||
},
|
||||
callback () {
|
||||
$('<style>').text(
|
||||
'#mathjax fieldset{' +
|
||||
'padding: 5px;' +
|
||||
'margin: 5px;' +
|
||||
'border: 1px solid #DDD;' +
|
||||
'}' +
|
||||
'#mathjax label{' +
|
||||
'display: block;' +
|
||||
'margin: .5em;' +
|
||||
'}' +
|
||||
'#mathjax legend {' +
|
||||
'max-width:195px;' +
|
||||
'}' +
|
||||
'#mathjax_overlay {' +
|
||||
'position: absolute;' +
|
||||
'top: 0;' +
|
||||
'left: 0;' +
|
||||
'right: 0;' +
|
||||
'bottom: 0;' +
|
||||
'background-color: black;' +
|
||||
'opacity: 0.6;' +
|
||||
'z-index: 20000;' +
|
||||
'}' +
|
||||
'#mathjax_container {' +
|
||||
'position: absolute;' +
|
||||
'top: 50px;' +
|
||||
'padding: 10px;' +
|
||||
'background-color: #B0B0B0;' +
|
||||
'border: 1px outset #777;' +
|
||||
'opacity: 1.0;' +
|
||||
'font-family: Verdana, Helvetica, sans-serif;' +
|
||||
'font-size: .8em;' +
|
||||
'z-index: 20001;' +
|
||||
'}' +
|
||||
'#tool_mathjax_back {' +
|
||||
'margin-left: 1em;' +
|
||||
'overflow: auto;' +
|
||||
'}' +
|
||||
'#mathjax_legend{' +
|
||||
'font-weight: bold;' +
|
||||
'font-size:1.1em;' +
|
||||
'}' +
|
||||
'#mathjax_code_textarea {\\n' +
|
||||
'margin: 5px .7em;' +
|
||||
'overflow: hidden;' +
|
||||
'width: 416px;' +
|
||||
'display: block;' +
|
||||
'height: 100px;' +
|
||||
'}'
|
||||
).appendTo('head');
|
||||
|
||||
// Add the MathJax configuration.
|
||||
// $(mathjaxConfiguration).appendTo('head');
|
||||
const head = document.head || document.getElementsByTagName('head')[0],
|
||||
style = document.createElement('style');
|
||||
style.textContent = '#mathjax fieldset{' +
|
||||
'padding: 5px;' +
|
||||
'margin: 5px;' +
|
||||
'border: 1px solid #DDD;' +
|
||||
'}' +
|
||||
'#mathjax label{' +
|
||||
'display: block;' +
|
||||
'margin: .5em;' +
|
||||
'}' +
|
||||
'#mathjax legend {' +
|
||||
'max-width:195px;' +
|
||||
'}' +
|
||||
'#mathjax_overlay {' +
|
||||
'position: absolute;' +
|
||||
'top: 0;' +
|
||||
'left: 0;' +
|
||||
'right: 0;' +
|
||||
'bottom: 0;' +
|
||||
'background-color: black;' +
|
||||
'opacity: 0.6;' +
|
||||
'z-index: 20000;' +
|
||||
'}' +
|
||||
'#mathjax_container {' +
|
||||
'position: absolute;' +
|
||||
'top: 50px;' +
|
||||
'padding: 10px;' +
|
||||
'background-color: #B0B0B0;' +
|
||||
'border: 1px outset #777;' +
|
||||
'opacity: 1.0;' +
|
||||
'font-family: Verdana, Helvetica, sans-serif;' +
|
||||
'font-size: .8em;' +
|
||||
'z-index: 20001;' +
|
||||
'}' +
|
||||
'#tool_mathjax_back {' +
|
||||
'margin-left: 1em;' +
|
||||
'overflow: auto;' +
|
||||
'}' +
|
||||
'#mathjax_legend{' +
|
||||
'font-weight: bold;' +
|
||||
'font-size:1.1em;' +
|
||||
'}' +
|
||||
'#mathjax_code_textarea {\\n' +
|
||||
'margin: 5px .7em;' +
|
||||
'overflow: hidden;' +
|
||||
'width: 416px;' +
|
||||
'display: block;' +
|
||||
'height: 100px;' +
|
||||
'}';
|
||||
head.appendChild(style);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
$('#placemark_panel').toggle(on);
|
||||
$id('placemark_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,10 +104,11 @@ export default {
|
||||
const items = txt.split(';');
|
||||
selElems.forEach((elem) => {
|
||||
if (elem && elem.getAttribute('class').includes('placemark')) {
|
||||
$(elem).children().each((_, i) => {
|
||||
var elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type, n] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
$(i).text(items[n]);
|
||||
t.textContent = items[n];
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -124,10 +125,11 @@ export default {
|
||||
font = font.join(' ');
|
||||
selElems.forEach((elem) => {
|
||||
if (elem && elem.getAttribute('class').includes('placemark')) {
|
||||
$(elem).children().each((_, i) => {
|
||||
var elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
$(i).attr({'font-family': font, 'font-size': fontSize});
|
||||
i.style.cssText = 'font-family:' + font + ';font-size:'+fontSize+';';
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -141,13 +143,12 @@ export default {
|
||||
function addMarker (id, val) {
|
||||
let marker = svgCanvas.getElem(id);
|
||||
if (marker) { return undefined; }
|
||||
// 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;
|
||||
const strokeWidth = 10;
|
||||
let refX = 50;
|
||||
const refY = 50;
|
||||
@@ -200,7 +201,7 @@ export default {
|
||||
function setMarker (el, val) {
|
||||
const markerName = 'marker-start';
|
||||
const marker = getLinked(el, markerName);
|
||||
if (marker) { $(marker).remove(); }
|
||||
if (marker) { marker.remove(); }
|
||||
el.removeAttribute(markerName);
|
||||
if (val === 'nomarker') {
|
||||
svgCanvas.call('changed', [el]);
|
||||
@@ -249,7 +250,7 @@ export default {
|
||||
const len = el.id.length;
|
||||
const linkid = url.substr(-len - 1, len);
|
||||
if (el.id !== linkid) {
|
||||
const val = $('#placemark_marker').attr('value') || 'leftarrow';
|
||||
const val = $id('placemark_marker').getAttribute('value') || 'leftarrow';
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
svgCanvas.call('changed', selElems);
|
||||
@@ -264,7 +265,7 @@ export default {
|
||||
const parts = this.id.split('_');
|
||||
let val = parts[2];
|
||||
if (parts[3]) { val += '_' + parts[3]; }
|
||||
$('#placemark_marker').attr('value', val);
|
||||
$id('placemark_marker').setAttribute('value', val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,8 +369,8 @@ export default {
|
||||
if (svgCanvas.getMode() === 'placemark') {
|
||||
started = true;
|
||||
const id = svgCanvas.getNextId();
|
||||
const items = $('#placemarkText').val().split(';');
|
||||
let font = $('#placemarkFont').val().split(' ');
|
||||
const items = $id('placemarkText').value.split(';');
|
||||
let font = $id('placemarkFont').value.split(' ');
|
||||
const fontSize = Number.parseInt(font.pop());
|
||||
font = font.join(' ');
|
||||
const x0 = opts.start_x + 10, y0 = opts.start_y + 10;
|
||||
@@ -453,7 +454,7 @@ export default {
|
||||
});
|
||||
setMarker(
|
||||
newPM.firstElementChild,
|
||||
$('#placemark_marker').attr('value') || 'leftarrow'
|
||||
$id('placemark_marker').getAttribute('value') || 'leftarrow'
|
||||
);
|
||||
return {
|
||||
started: true
|
||||
@@ -468,11 +469,16 @@ export default {
|
||||
if (svgCanvas.getMode() === 'placemark') {
|
||||
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 fontSize = newPM.getAttribute('fontSize');
|
||||
const maxlen = newPM.getAttribute('maxlen');
|
||||
const lines = newPM.getAttribute('lines');
|
||||
const px = newPM.getAttribute('px');
|
||||
const py = newPM.getAttribute('py');
|
||||
|
||||
newPM.setAttribute('x', x);
|
||||
newPM.setAttribute('y', y);
|
||||
const elements = newPM.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type, n] = i.id.split('_');
|
||||
const y0 = y + (fontSize + 6) * n,
|
||||
x0 = x + maxlen * fontSize * 0.5 + fontSize;
|
||||
@@ -509,7 +515,10 @@ export default {
|
||||
},
|
||||
mouseUp () {
|
||||
if (svgCanvas.getMode() === 'placemark') {
|
||||
const {x, y, px, py} = $(newPM).attr(['x', 'y', 'px', 'py']);
|
||||
const x = newPM.getAttribute('x');
|
||||
const y = newPM.getAttribute('y');
|
||||
const px = newPM.getAttribute('px');
|
||||
const py = newPM.getAttribute('py');
|
||||
return {
|
||||
keep: (x != px && y != py), // eslint-disable-line eqeqeq
|
||||
element: newPM
|
||||
@@ -523,16 +532,17 @@ export default {
|
||||
selElems.forEach((elem) => {
|
||||
if (elem && elem.getAttribute('class').includes('placemark')) {
|
||||
const txt = [];
|
||||
$(elem).children().each((n, i) => {
|
||||
const elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i, n){
|
||||
const [, , type] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
$('#placemarkFont').val(
|
||||
$id('placemarkFont').value = (
|
||||
i.getAttribute('font-family') + ' ' + i.getAttribute('font-size')
|
||||
);
|
||||
txt.push($(i).text());
|
||||
txt.push(i.textContent);
|
||||
}
|
||||
});
|
||||
$('#placemarkText').val(txt.join(';'));
|
||||
$id('placemarkText').value = txt.join(';');
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
|
||||
@@ -24,42 +24,26 @@ export default {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const {$} = S, // {svgcontent}
|
||||
// addElem = svgCanvas.addSVGElementFromJson,
|
||||
editingitex = false;
|
||||
const {$} = S;
|
||||
const editingitex = false;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
let selElems,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID, modeChangeG,
|
||||
// edg = 0,
|
||||
// undoCommand = 'Not image';
|
||||
started, newFO;
|
||||
let selElems;
|
||||
let started;
|
||||
let newFO;
|
||||
/**
|
||||
* @param {boolean} on
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
let fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#polygon_panel').toggle(on);
|
||||
}
|
||||
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#polygon_save, #polygon_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
const showPanel = (on) => {
|
||||
$id('polygon_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} attr
|
||||
* @param {string|Float} val
|
||||
* @returns {void}
|
||||
*/
|
||||
function setAttr (attr, val) {
|
||||
const setAttr = (attr, val) => {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
@@ -68,88 +52,50 @@ export default {
|
||||
* @param {Float} n
|
||||
* @returns {Float}
|
||||
*/
|
||||
function cot (n) {
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
const cot = (n) => (1 / Math.tan(n));
|
||||
|
||||
/**
|
||||
* @param {Float} n
|
||||
* @returns {Float}
|
||||
*/
|
||||
function sec (n) {
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
const sec = (n) => (1 / Math.cos(n));
|
||||
|
||||
/**
|
||||
* Obtained from http://code.google.com/p/passenger-top/source/browse/instiki/public/svg-edit/editor/extensions/ext-itex.js?r=3
|
||||
* This function sets the content of of the currently-selected foreignObject element,
|
||||
* based on the itex contained in string.
|
||||
* @param {string} tex The itex text.
|
||||
* @returns {boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
const events = {
|
||||
id: 'tool_polygon',
|
||||
click () {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
};
|
||||
const contextTools = [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
id: 'polySides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}];
|
||||
return {
|
||||
name: strings.name,
|
||||
events,
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
|
||||
// The callback should be used to load the DOM with the appropriate UI items
|
||||
callback () {
|
||||
if($id("polygon_panel") !== null) $id("polygon_panel").style.display = 'none';
|
||||
const endChanges = function () {
|
||||
// Todo: Missing?
|
||||
};
|
||||
// Add the button and its handler(s)
|
||||
// Note: the star extension may also add the same flying button so we check first
|
||||
if ($id('tools_polygon') === null) {
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
||||
</se-flyingbutton>
|
||||
`
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
}
|
||||
$id('tool_polygon').addEventListener("click", () => {
|
||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* const save = */ $('#tool_source_save').clone().hide().attr(
|
||||
'id', 'polygon_save'
|
||||
).unbind().appendTo(
|
||||
'#tool_source_back'
|
||||
).click(function () {
|
||||
if (!editingitex) {
|
||||
return;
|
||||
}
|
||||
// Todo: Uncomment the setItexString() function above and handle ajaxEndpoint?
|
||||
/*
|
||||
if (!setItexString($('#svg_source_textarea').val())) {
|
||||
const ok = seConfirm('Errors found. Revert to original?', function (ok) {
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
endChanges();
|
||||
} else { */
|
||||
endChanges();
|
||||
// }
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* const cancel = */ $('#tool_source_cancel').clone().hide().attr(
|
||||
'id', 'polygon_cancel'
|
||||
).unbind().appendTo('#tool_source_back').click(function () {
|
||||
endChanges();
|
||||
});
|
||||
}, 3000);
|
||||
// Add the context panel and its handler(s)
|
||||
const panelTemplate = document.createElement("template");
|
||||
panelTemplate.innerHTML = `
|
||||
<div id="polygon_panel">
|
||||
<se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="sides">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
`
|
||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
||||
$id("polygon_panel").style.display = 'none';
|
||||
$id("polySides").addEventListener("change", (event) => {
|
||||
setAttr('sides', event.target.value);
|
||||
});
|
||||
},
|
||||
mouseDown (opts) {
|
||||
if (svgCanvas.getMode() !== 'polygon') {
|
||||
@@ -188,12 +134,18 @@ export default {
|
||||
if (!started || svgCanvas.getMode() !== 'polygon') {
|
||||
return undefined;
|
||||
}
|
||||
// const e = opts.event;
|
||||
const c = $(newFO).attr(['cx', 'cy', 'sides', 'orient', 'fill', 'strokecolor', 'strokeWidth']);
|
||||
const cx = Number(newFO.getAttribute('cx'));
|
||||
const cy = Number(newFO.getAttribute('cy'));
|
||||
const sides = Number(newFO.getAttribute('sides'));
|
||||
const orient = newFO.getAttribute('orient');
|
||||
const fill = newFO.getAttribute('fill');
|
||||
const strokecolor = newFO.getAttribute('strokecolor');
|
||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
const {cx, cy, fill, strokecolor, strokeWidth, sides} = c, // {orient} = c,
|
||||
edg = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
|
||||
const edg = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
newFO.setAttribute('edge', edg);
|
||||
|
||||
const inradius = (edg / 2) * cot(Math.PI / sides);
|
||||
@@ -212,10 +164,6 @@ export default {
|
||||
newFO.setAttribute('fill', fill);
|
||||
newFO.setAttribute('stroke', strokecolor);
|
||||
newFO.setAttribute('stroke-width', strokeWidth);
|
||||
// newFO.setAttribute('transform', 'rotate(-90)');
|
||||
// const shape = newFO.getAttribute('shape');
|
||||
// newFO.append(poly);
|
||||
// DrawPoly(cx, cy, sides, edg, orient);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
@@ -225,8 +173,8 @@ export default {
|
||||
if (svgCanvas.getMode() !== 'polygon') {
|
||||
return undefined;
|
||||
}
|
||||
const attrs = $(newFO).attr('edge');
|
||||
const keep = (attrs.edge !== '0');
|
||||
const edge = newFO.getAttribute('edge');
|
||||
const keep = (edge !== '0');
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep,
|
||||
@@ -242,7 +190,7 @@ export default {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.getAttribute('shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#polySides').val(elem.getAttribute('sides'));
|
||||
$id('polySides').value = elem.getAttribute('sides');
|
||||
|
||||
showPanel(true);
|
||||
} else {
|
||||
|
||||
@@ -27,15 +27,18 @@ export default {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const saveSvgAction = '/+modify';
|
||||
|
||||
// Create upload target (hidden iframe)
|
||||
// Hiding by size instead of display to avoid FF console errors
|
||||
// with `getBBox` in browser.js `supportsPathBBox_`)
|
||||
/* const target = */ $(
|
||||
`<iframe name="output_frame" title="${strings.hiddenframe}"
|
||||
style="width: 0; height: 0;" src="data:text/html;base64,PGh0bWw+PC9odG1sPg=="/>`
|
||||
).appendTo('body');
|
||||
const iframe = document.createElement('IFRAME');
|
||||
iframe.src="data:text/html;base64,PGh0bWw+PC9odG1sPg==";
|
||||
document.body.append(iframe);
|
||||
iframe.name = "output_frame";
|
||||
iframe.contentWindow.document.title = strings.hiddenframe;
|
||||
iframe.style.cssText = "width:0;height:0;";
|
||||
|
||||
svgEditor.setCustomHandlers({
|
||||
async save (win, data) {
|
||||
@@ -43,27 +46,33 @@ export default {
|
||||
const {pathname} = new URL(location);
|
||||
const name = pathname.replace(/\/+get\//, '');
|
||||
const svgData = encode64(svg);
|
||||
if (!$('#export_canvas').length) {
|
||||
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
||||
if (!$id('export_canvas')) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('id', 'export_canvas');
|
||||
canvas.style.display = 'none';
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
const c = $('#export_canvas')[0];
|
||||
c.width = svgCanvas.contentW;
|
||||
c.height = svgCanvas.contentH;
|
||||
const c = $id('export_canvas');
|
||||
c.style.width = svgCanvas.contentW;
|
||||
c.style.height = svgCanvas.contentH;
|
||||
await canvg(c, svg);
|
||||
const datauri = c.toDataURL('image/png');
|
||||
// const {uiStrings} = svgEditor;
|
||||
const pngData = encode64(datauri); // Brett: This encoding seems unnecessary
|
||||
/* const form = */ $('<form>').attr({
|
||||
method: 'post',
|
||||
action: saveSvgAction + '/' + name,
|
||||
target: 'output_frame'
|
||||
}).append(`
|
||||
<input type="hidden" name="png_data" value="${pngData}">
|
||||
<input type="hidden" name="filepath" value="${svgData}">
|
||||
<input type="hidden" name="filename" value="drawing.svg">
|
||||
<input type="hidden" name="contenttype" value="application/x-svgdraw">
|
||||
`).appendTo('body')
|
||||
.submit().remove();
|
||||
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', saveSvgAction + '/' + name);
|
||||
form.setAttribute('target', 'output_frame');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
form.innerHTML = `<input type="hidden" name="png_data" value="${pngData}">
|
||||
<input type="hidden" name="filepath" value="${svgData}">
|
||||
<input type="hidden" name="filename" value="drawing.svg">
|
||||
<input type="hidden" name="contenttype" value="application/x-svgdraw">`;
|
||||
document.body.append(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(strings.saved);
|
||||
top.window.location = '/' + name;
|
||||
|
||||
@@ -63,14 +63,16 @@ export default {
|
||||
if (avoidClientSide || avoidClientSideDownload) {
|
||||
return false;
|
||||
}
|
||||
const support = $('<a>')[0].download === '';
|
||||
const support = document.querySelector('a').download === '';
|
||||
let a;
|
||||
if (support) {
|
||||
a = $('<a>hidden</a>').attr({
|
||||
download: (filename || 'image') + suffix,
|
||||
href: uri
|
||||
}).css('display', 'none').appendTo('body');
|
||||
a[0].click();
|
||||
a = document.createElement("a");
|
||||
a.text = 'hidden';
|
||||
a.download = (filename || 'image') + suffix;
|
||||
a.href = uri;
|
||||
a.style.dispaly = 'none';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -84,10 +86,13 @@ export default {
|
||||
|
||||
// Hiding by size instead of display to avoid FF console errors
|
||||
// with `getBBox` in browser.js `supportsPathBBox_`)
|
||||
$(
|
||||
`<iframe name="output_frame" title="${strings.hiddenframe}"
|
||||
style="width: 0; height: 0;" src="data:text/html;base64,PGh0bWw+"/>`
|
||||
).appendTo('body');
|
||||
const iframe = document.createElement('IFRAME');
|
||||
iframe.src="data:text/html;base64,PGh0bWw+";
|
||||
document.body.append(iframe);
|
||||
iframe.name = "output_frame";
|
||||
iframe.contentWindow.document.title = strings.hiddenframe;
|
||||
iframe.style.cssText = "width:0;height:0;";
|
||||
|
||||
svgEditor.setCustomHandlers({
|
||||
save (win, data) {
|
||||
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
|
||||
@@ -97,15 +102,16 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: saveSvgAction,
|
||||
target: 'output_frame'
|
||||
}).append(`
|
||||
<input type="hidden" name="output_svg" value="${xhtmlEscape(svg)}">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">
|
||||
`).appendTo('body')
|
||||
.submit().remove();
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', saveSvgAction);
|
||||
form.setAttribute('target', 'output_frame');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
form.innerHTML = `<input type="hidden" name="output_svg" value="${xhtmlEscape(svg)}">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">`;
|
||||
document.body.append(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
},
|
||||
exportPDF (win, data) {
|
||||
const filename = getFileNameFromTitle(),
|
||||
@@ -113,28 +119,32 @@ export default {
|
||||
if (clientDownloadSupport(filename, '.pdf', datauri)) {
|
||||
return;
|
||||
}
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: saveImgAction,
|
||||
target: 'output_frame'
|
||||
}).append(`
|
||||
<input type="hidden" name="output_img" value="${datauri}">
|
||||
<input type="hidden" name="mime" value="application/pdf">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">
|
||||
`).appendTo('body')
|
||||
.submit().remove();
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', saveImgAction);
|
||||
form.setAttribute('target', 'output_frame');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
form.innerHTML = `<input type="hidden" name="output_img" value="${datauri}">
|
||||
<input type="hidden" name="mime" value="application/pdf">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">`;
|
||||
document.body.append(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
},
|
||||
// Todo: Integrate this extension with a new built-in exportWindowType, "download"
|
||||
async exportImage (win, data) {
|
||||
const {issues, mimeType, quality} = data;
|
||||
|
||||
if (!$('#export_canvas').length) {
|
||||
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
||||
if (!$id('export_canvas')) {
|
||||
const canvasx = document.createElement("CANVAS");
|
||||
canvasx.id = 'export_canvas';
|
||||
canvasx.style.display = 'none';
|
||||
document.body.appendChild(canvasx);
|
||||
}
|
||||
const c = $('#export_canvas')[0];
|
||||
const c = $id('export_canvas');
|
||||
|
||||
c.width = svgCanvas.contentW;
|
||||
c.height = svgCanvas.contentH;
|
||||
c.style.width = svgCanvas.contentW;
|
||||
c.style.height = svgCanvas.contentH;
|
||||
await canvg(c, data.svg);
|
||||
const datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType);
|
||||
// {uiStrings} = svgEditor;
|
||||
@@ -158,16 +168,17 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: saveImgAction,
|
||||
target: 'output_frame'
|
||||
}).append(`
|
||||
<input type="hidden" name="output_img" value="${datauri}">
|
||||
<input type="hidden" name="mime" value="${mimeType}">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">
|
||||
`).appendTo('body')
|
||||
.submit().remove();
|
||||
const form = document.createElement('form');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', saveImgAction);
|
||||
form.setAttribute('target', 'output_frame');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
form.innerHTML = `<input type="hidden" name="output_img" value="${datauri}">
|
||||
<input type="hidden" name="mime" value="${mimeType}">
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">`;
|
||||
document.body.append(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -209,19 +220,21 @@ export default {
|
||||
};
|
||||
|
||||
// Create upload form
|
||||
const openSvgForm = $('<form>');
|
||||
openSvgForm.attr({
|
||||
enctype: 'multipart/form-data',
|
||||
method: 'post',
|
||||
action: openSvgAction,
|
||||
target: 'output_frame'
|
||||
});
|
||||
|
||||
const openSvgForm = document.createElement("FORM");
|
||||
openSvgForm.action = openSvgAction;
|
||||
openSvgForm.enctype = 'multipart/form-data';
|
||||
openSvgForm.method = 'post';
|
||||
openSvgForm.target = 'output_frame';
|
||||
|
||||
|
||||
// Create import form
|
||||
const importSvgForm = openSvgForm.clone().attr('action', importSvgAction);
|
||||
const importSvgForm = openSvgForm.cloneNode(true);
|
||||
importSvgForm.action = importSvgAction;
|
||||
|
||||
// Create image form
|
||||
const importImgForm = openSvgForm.clone().attr('action', importImgAction);
|
||||
const importImgForm = openSvgForm.cloneNode(true);
|
||||
importImgForm.action = importImgAction;
|
||||
|
||||
// It appears necessary to rebuild this input every time a file is
|
||||
// selected so the same file can be picked and the change event can fire.
|
||||
@@ -233,7 +246,10 @@ export default {
|
||||
*/
|
||||
function rebuildInput (form) {
|
||||
form.empty();
|
||||
const inp = $('<input type="file" name="svg_file">').appendTo(form);
|
||||
const inp = document.createElement('input');
|
||||
inp.type = 'file';
|
||||
inp.name = 'svg_file';
|
||||
form.appendChild(inp);
|
||||
|
||||
/**
|
||||
* Submit the form, empty its contents for reuse and show
|
||||
@@ -276,8 +292,8 @@ export default {
|
||||
// Add forms to buttons
|
||||
$id("tool_open").style.display = 'block';
|
||||
$id("tool_import").style.display = 'block';
|
||||
$('#tool_open').prepend(openSvgForm);
|
||||
$('#tool_import').prepend(importSvgForm);
|
||||
$('#tool_image').prepend(importImgForm);
|
||||
$id('tool_open').insertBefore(openSvgForm, $id('tool_open').firstChild);
|
||||
$id('tool_import').insertBefore(importSvgForm, $id('tool_import').firstChild);
|
||||
$id('tool_image').insertBefore(importImgForm, $id('tool_image').firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,16 +25,9 @@ export default {
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const {$} = S; // {svgcontent},
|
||||
let
|
||||
selElems,
|
||||
// editingitex = false,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
started,
|
||||
newFO;
|
||||
// edg = 0,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID,
|
||||
// undoCommand = 'Not image',
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;
|
||||
let selElems;
|
||||
let started;
|
||||
let newFO;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
|
||||
/**
|
||||
@@ -42,93 +35,73 @@ export default {
|
||||
* @param {boolean} on
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
let fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#star_panel').toggle(on);
|
||||
const showPanel = (on) => {
|
||||
$id('star_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#star_save, #star_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} attr
|
||||
* @param {string|Float} val
|
||||
* @returns {void}
|
||||
*/
|
||||
function setAttr (attr, val) {
|
||||
const setAttr = (attr, val) => {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
|
||||
/*
|
||||
function cot(n){
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
|
||||
function sec(n){
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
*/
|
||||
const events = {
|
||||
id: 'tool_star',
|
||||
click () {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
};
|
||||
const contextTools = [{
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'starNumPoints',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'starRadiusMulitplier',
|
||||
size: 3,
|
||||
defval: 2.5
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'radialShift',
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
events,
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
// The callback should be used to load the DOM with the appropriate UI items
|
||||
callback () {
|
||||
if($id("star_panel") !== null) $id("star_panel").style.display = 'none';
|
||||
// const endChanges = function(){};
|
||||
// Add the button and its handler(s)
|
||||
// Note: the star extension may also add the same flying button so we check first
|
||||
if ($id('tools_polygon') === null) {
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
||||
</se-flyingbutton>
|
||||
`
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
}
|
||||
$id('tool_star').addEventListener("click", () => { showPanel(true);
|
||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
||||
svgCanvas.setMode('star');
|
||||
showPanel(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Add the context panel and its handler(s)
|
||||
const panelTemplate = document.createElement("template");
|
||||
panelTemplate.innerHTML = `
|
||||
<div id="star_panel">
|
||||
<se-spin-input id="starNumPoints" label="points" min=1 step=1 value=5 title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="RadiusMultiplier" label="Radis multiplier" min=1 step=2.5 value=5 title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="radialShift" min=0 step=1 value=0 label="radial shift" title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
`
|
||||
//add handlers for the panel
|
||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
||||
$id("starNumPoints").addEventListener("change", (event) => {
|
||||
setAttr('point', event.target.value);
|
||||
});
|
||||
$id("RadiusMultiplier").addEventListener("change", (event) => {
|
||||
setAttr('starRadiusMultiplier', event.target.value);
|
||||
});
|
||||
$id("radialShift").addEventListener("change", (event) => {
|
||||
setAttr('radialshift', event.target.value);
|
||||
});
|
||||
// don't display the star panel on start
|
||||
$id("star_panel").style.display = 'none';
|
||||
},
|
||||
mouseDown (opts) {
|
||||
const rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
const sRgb = svgCanvas.getColor('stroke');
|
||||
// const ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
const sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
@@ -162,13 +135,20 @@ export default {
|
||||
return undefined;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
const c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
|
||||
const cx = Number(newFO.getAttribute('cx'));
|
||||
const cy = Number(newFO.getAttribute('cy'));
|
||||
const point = Number(newFO.getAttribute('point'));
|
||||
const orient = newFO.getAttribute('orient');
|
||||
const fill = newFO.getAttribute('fill');
|
||||
const strokecolor = newFO.getAttribute('strokecolor');
|
||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
||||
const radialshift = Number(newFO.getAttribute('radialshift'));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
const {cx, cy, fill, strokecolor, strokeWidth, radialshift, point, orient} = c,
|
||||
circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5,
|
||||
inradius = circumradius / document.getElementById('starRadiusMulitplier').value;
|
||||
|
||||
const circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
const inradius = circumradius / document.getElementById('RadiusMultiplier').value;
|
||||
newFO.setAttribute('r', circumradius);
|
||||
newFO.setAttribute('r2', inradius);
|
||||
|
||||
@@ -215,10 +195,9 @@ export default {
|
||||
},
|
||||
mouseUp () {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
const attrs = $(newFO).attr(['r']);
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
const r = newFO.getAttribute('r');
|
||||
return {
|
||||
keep: (attrs.r !== '0'),
|
||||
keep: (r !== '0'),
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
@@ -233,9 +212,8 @@ export default {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.getAttribute('shape') === 'star') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
// $('#starRadiusMulitplier').val(elem.getAttribute('r2'));
|
||||
$('#starNumPoints').val(elem.getAttribute('point'));
|
||||
$('#radialShift').val(elem.getAttribute('radialshift'));
|
||||
$id('starNumPoints').value = elem.getAttribute('point');
|
||||
$id('radialShift').value = elem.getAttribute('radialshift');
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
|
||||
@@ -57,10 +57,6 @@ export default {
|
||||
case 'view':
|
||||
// Populate the contents
|
||||
svgEditor.loadFromString(content);
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'save-end':
|
||||
// eslint-disable-next-line no-alert
|
||||
|
||||
Reference in New Issue
Block a user