- Linting (ESLint): Finish extensions and most files in editor/; unfinished: editor/svg-editor.js, editor/svgcanvas.js
- Linting (ESLint): Fix ignore file paths - History `elem` fix
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgCanvas, $*/
|
||||
/*jslint vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-arrows.js
|
||||
*
|
||||
@@ -9,65 +9,64 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('Arrows', function(S) {
|
||||
var svgcontent = S.svgcontent,
|
||||
svgEditor.addExtension('Arrows', function (S) {
|
||||
var // svgcontent = S.svgcontent,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
nonce = S.nonce,
|
||||
randomize_ids = S.randomize_ids,
|
||||
randomizeIds = S.randomize_ids,
|
||||
selElems, pathdata,
|
||||
lang_list = {
|
||||
'en':[
|
||||
{'id': 'arrow_none', 'textContent': 'No arrow' }
|
||||
langList = {
|
||||
'en': [
|
||||
{'id': 'arrow_none', 'textContent': 'No arrow'}
|
||||
],
|
||||
'fr':[
|
||||
{'id': 'arrow_none', 'textContent': 'Sans flèche' }
|
||||
'fr': [
|
||||
{'id': 'arrow_none', 'textContent': 'Sans flèche'}
|
||||
]
|
||||
},
|
||||
arrowprefix,
|
||||
prefix = 'se_arrow_';
|
||||
|
||||
function setArrowNonce(window, n) {
|
||||
randomize_ids = true;
|
||||
function setArrowNonce (window, n) {
|
||||
randomizeIds = true;
|
||||
arrowprefix = prefix + n + '_';
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
|
||||
function unsetArrowNonce(window) {
|
||||
randomize_ids = false;
|
||||
function unsetArrowNonce (window) {
|
||||
randomizeIds = false;
|
||||
arrowprefix = prefix;
|
||||
pathdata.fw.id = arrowprefix + 'fw';
|
||||
pathdata.bk.id = arrowprefix + 'bk';
|
||||
}
|
||||
|
||||
|
||||
svgCanvas.bind('setnonce', setArrowNonce);
|
||||
svgCanvas.bind('unsetnonce', unsetArrowNonce);
|
||||
|
||||
if (randomize_ids) {
|
||||
if (randomizeIds) {
|
||||
arrowprefix = prefix + nonce + '_';
|
||||
} else {
|
||||
arrowprefix = prefix;
|
||||
}
|
||||
|
||||
pathdata = {
|
||||
fw: {d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw'},
|
||||
fw: {d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw'},
|
||||
bk: {d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk'}
|
||||
};
|
||||
|
||||
function getLinked(elem, attr) {
|
||||
function getLinked (elem, attr) {
|
||||
var str = elem.getAttribute(attr);
|
||||
if(!str) {return null;}
|
||||
var m = str.match(/\(\#(.*)\)/);
|
||||
if(!m || m.length !== 2) {
|
||||
if (!str) { return null; }
|
||||
var m = str.match(/\(#(.*)\)/);
|
||||
if (!m || m.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
return S.getElem(m[1]);
|
||||
}
|
||||
|
||||
function showPanel(on) {
|
||||
function showPanel (on) {
|
||||
$('#arrow_panel').toggle(on);
|
||||
if(on) {
|
||||
if (on) {
|
||||
var el = selElems[0];
|
||||
var end = el.getAttribute('marker-end');
|
||||
var start = el.getAttribute('marker-start');
|
||||
@@ -95,21 +94,21 @@ svgEditor.addExtension('Arrows', function(S) {
|
||||
}
|
||||
}
|
||||
|
||||
function resetMarker() {
|
||||
function resetMarker () {
|
||||
var el = selElems[0];
|
||||
el.removeAttribute('marker-start');
|
||||
el.removeAttribute('marker-mid');
|
||||
el.removeAttribute('marker-end');
|
||||
}
|
||||
|
||||
function addMarker(dir, type, id) {
|
||||
function addMarker (dir, type, id) {
|
||||
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
||||
id = id || arrowprefix + dir;
|
||||
|
||||
var marker = S.getElem(id);
|
||||
var data = pathdata[dir];
|
||||
|
||||
if (type == 'mid') {
|
||||
if (type === 'mid') {
|
||||
data.refx = 5;
|
||||
}
|
||||
|
||||
@@ -143,25 +142,25 @@ svgEditor.addExtension('Arrows', function(S) {
|
||||
return marker;
|
||||
}
|
||||
|
||||
function setArrow() {
|
||||
function setArrow () {
|
||||
var type = this.value;
|
||||
resetMarker();
|
||||
|
||||
if (type == 'none') {
|
||||
if (type === 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set marker on element
|
||||
var dir = 'fw';
|
||||
if (type == 'mid_bk') {
|
||||
if (type === 'mid_bk') {
|
||||
type = 'mid';
|
||||
dir = 'bk';
|
||||
} else if (type == 'both') {
|
||||
} else if (type === 'both') {
|
||||
addMarker('bk', type);
|
||||
svgCanvas.changeSelectedAttribute('marker-start', 'url(#' + pathdata.bk.id + ')');
|
||||
type = 'end';
|
||||
dir = 'fw';
|
||||
} else if (type == 'start') {
|
||||
} else if (type === 'start') {
|
||||
dir = 'bk';
|
||||
}
|
||||
|
||||
@@ -170,57 +169,57 @@ svgEditor.addExtension('Arrows', function(S) {
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
function colorChanged(elem) {
|
||||
function colorChanged (elem) {
|
||||
var color = elem.getAttribute('stroke');
|
||||
var mtypes = ['start', 'mid', 'end'];
|
||||
var defs = S.findDefs();
|
||||
|
||||
$.each(mtypes, function(i, type) {
|
||||
var marker = getLinked(elem, 'marker-'+type);
|
||||
if(!marker) {return;}
|
||||
$.each(mtypes, function (i, type) {
|
||||
var marker = getLinked(elem, 'marker-' + type);
|
||||
if (!marker) { return; }
|
||||
|
||||
var cur_color = $(marker).children().attr('fill');
|
||||
var cur_d = $(marker).children().attr('d');
|
||||
var new_marker = null;
|
||||
if(cur_color === color) {return;}
|
||||
var curColor = $(marker).children().attr('fill');
|
||||
var curD = $(marker).children().attr('d');
|
||||
var newMarker = null;
|
||||
if (curColor === color) { return; }
|
||||
|
||||
var all_markers = $(defs).find('marker');
|
||||
var allMarkers = $(defs).find('marker');
|
||||
// Different color, check if already made
|
||||
all_markers.each(function() {
|
||||
allMarkers.each(function () {
|
||||
var attrs = $(this).children().attr(['fill', 'd']);
|
||||
if(attrs.fill === color && attrs.d === cur_d) {
|
||||
if (attrs.fill === color && attrs.d === curD) {
|
||||
// Found another marker with this color and this path
|
||||
new_marker = this;
|
||||
newMarker = this;
|
||||
}
|
||||
});
|
||||
|
||||
if(!new_marker) {
|
||||
if (!newMarker) {
|
||||
// Create a new marker with this color
|
||||
var last_id = marker.id;
|
||||
var dir = last_id.indexOf('_fw') !== -1?'fw':'bk';
|
||||
var lastId = marker.id;
|
||||
var dir = lastId.indexOf('_fw') !== -1 ? 'fw' : 'bk';
|
||||
|
||||
new_marker = addMarker(dir, type, arrowprefix + dir + all_markers.length);
|
||||
newMarker = addMarker(dir, type, arrowprefix + dir + allMarkers.length);
|
||||
|
||||
$(new_marker).children().attr('fill', color);
|
||||
$(newMarker).children().attr('fill', color);
|
||||
}
|
||||
|
||||
$(elem).attr('marker-'+type, 'url(#' + new_marker.id + ')');
|
||||
$(elem).attr('marker-' + type, 'url(#' + newMarker.id + ')');
|
||||
|
||||
// Check if last marker can be removed
|
||||
var remove = true;
|
||||
$(S.svgcontent).find('line, polyline, path, polygon').each(function() {
|
||||
$(S.svgcontent).find('line, polyline, path, polygon').each(function () {
|
||||
var elem = this;
|
||||
$.each(mtypes, function(j, mtype) {
|
||||
if($(elem).attr('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
$.each(mtypes, function (j, mtype) {
|
||||
if ($(elem).attr('marker-' + mtype) === 'url(#' + marker.id + ')') {
|
||||
remove = false;
|
||||
return remove;
|
||||
}
|
||||
});
|
||||
if(!remove) {return false;}
|
||||
if (!remove) { return false; }
|
||||
});
|
||||
|
||||
// Not found, so can safely remove
|
||||
if(remove) {
|
||||
if (remove) {
|
||||
$(marker).remove();
|
||||
}
|
||||
});
|
||||
@@ -246,26 +245,26 @@ svgEditor.addExtension('Arrows', function(S) {
|
||||
change: setArrow
|
||||
}
|
||||
}],
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
$('#arrow_panel').hide();
|
||||
// Set ID so it can be translated in locale file
|
||||
$('#arrow_list option')[0].id = 'connector_no_arrow';
|
||||
},
|
||||
addLangData: function(lang) {
|
||||
addLangData: function (lang) {
|
||||
return {
|
||||
data: lang_list[lang]
|
||||
data: langList[lang]
|
||||
};
|
||||
},
|
||||
selectedChanged: function(opts) {
|
||||
selectedChanged: function (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
var marker_elems = ['line', 'path', 'polyline', 'polygon'];
|
||||
while(i--) {
|
||||
var markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if(elem && $.inArray(elem.tagName, marker_elems) !== -1) {
|
||||
if(opts.selectedElement && !opts.multiselected) {
|
||||
if (elem && $.inArray(elem.tagName, markerElems) !== -1) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
@@ -275,16 +274,16 @@ svgEditor.addExtension('Arrows', function(S) {
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function(opts) {
|
||||
elementChanged: function (opts) {
|
||||
var elem = opts.elems[0];
|
||||
if(elem && (
|
||||
if (elem && (
|
||||
elem.getAttribute('marker-start') ||
|
||||
elem.getAttribute('marker-mid') ||
|
||||
elem.getAttribute('marker-end')
|
||||
)) {
|
||||
// var start = elem.getAttribute('marker-start');
|
||||
// var mid = elem.getAttribute('marker-mid');
|
||||
// var end = elem.getAttribute('marker-end');
|
||||
// var start = elem.getAttribute('marker-start');
|
||||
// var mid = elem.getAttribute('marker-mid');
|
||||
// var end = elem.getAttribute('marker-end');
|
||||
// Has marker, so see if it should match color
|
||||
colorChanged(elem);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, $*/
|
||||
/*jslint vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, $ */
|
||||
/*
|
||||
* ext-closepath.js
|
||||
*
|
||||
@@ -11,30 +11,31 @@
|
||||
|
||||
// This extension adds a simple button to the contextual panel for paths
|
||||
// The button toggles whether the path is open or closed
|
||||
svgEditor.addExtension('ClosePath', function() {'use strict';
|
||||
svgEditor.addExtension('ClosePath', function () {
|
||||
'use strict';
|
||||
var selElems,
|
||||
updateButton = function(path) {
|
||||
updateButton = function (path) {
|
||||
var seglist = path.pathSegList,
|
||||
closed = seglist.getItem(seglist.numberOfItems - 1).pathSegType == 1,
|
||||
closed = seglist.getItem(seglist.numberOfItems - 1).pathSegType === 1,
|
||||
showbutton = closed ? '#tool_openpath' : '#tool_closepath',
|
||||
hidebutton = closed ? '#tool_closepath' : '#tool_openpath';
|
||||
$(hidebutton).hide();
|
||||
$(showbutton).show();
|
||||
$(hidebutton).hide();
|
||||
$(showbutton).show();
|
||||
},
|
||||
showPanel = function(on) {
|
||||
showPanel = function (on) {
|
||||
$('#closepath_panel').toggle(on);
|
||||
if (on) {
|
||||
var path = selElems[0];
|
||||
if (path) {updateButton(path);}
|
||||
if (path) { updateButton(path); }
|
||||
}
|
||||
},
|
||||
toggleClosed = function() {
|
||||
toggleClosed = function () {
|
||||
var path = selElems[0];
|
||||
if (path) {
|
||||
var seglist = path.pathSegList,
|
||||
last = seglist.numberOfItems - 1;
|
||||
// is closed
|
||||
if (seglist.getItem(last).pathSegType == 1) {
|
||||
if (seglist.getItem(last).pathSegType === 1) {
|
||||
seglist.removeItem(last);
|
||||
} else {
|
||||
seglist.appendItem(path.createSVGPathSegClosePath());
|
||||
@@ -52,7 +53,7 @@ svgEditor.addExtension('ClosePath', function() {'use strict';
|
||||
panel: 'closepath_panel',
|
||||
title: 'Open path',
|
||||
events: {
|
||||
click: function() {
|
||||
click: function () {
|
||||
toggleClosed();
|
||||
}
|
||||
}
|
||||
@@ -63,20 +64,20 @@ svgEditor.addExtension('ClosePath', function() {'use strict';
|
||||
panel: 'closepath_panel',
|
||||
title: 'Close path',
|
||||
events: {
|
||||
click: function() {
|
||||
click: function () {
|
||||
toggleClosed();
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
$('#closepath_panel').hide();
|
||||
},
|
||||
selectedChanged: function(opts) {
|
||||
selectedChanged: function (opts) {
|
||||
selElems = opts.elems;
|
||||
var i = selElems.length;
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.tagName == 'path') {
|
||||
if (elem && elem.tagName === 'path') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgCanvas, $*/
|
||||
/*jslint vars: true, continue: true, eqeq: true, todo: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-connector.js
|
||||
*
|
||||
@@ -8,8 +8,8 @@
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("Connector", function(S) {
|
||||
|
||||
svgEditor.addExtension('Connector', function (S) {
|
||||
var svgcontent = S.svgcontent,
|
||||
svgroot = S.svgroot,
|
||||
getNextId = S.getNextId,
|
||||
@@ -18,153 +18,151 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
selManager = S.selectorManager,
|
||||
curConfig = svgEditor.curConfig,
|
||||
started = false,
|
||||
start_x,
|
||||
start_y,
|
||||
cur_line,
|
||||
start_elem,
|
||||
end_elem,
|
||||
startX,
|
||||
startY,
|
||||
curLine,
|
||||
startElem,
|
||||
endElem,
|
||||
connections = [],
|
||||
conn_sel = ".se_connector",
|
||||
se_ns,
|
||||
// connect_str = "-SE_CONNECT-",
|
||||
connSel = '.se_connector',
|
||||
seNs,
|
||||
// connect_str = '-SE_CONNECT-',
|
||||
selElems = [],
|
||||
elData = $.data;
|
||||
|
||||
var lang_list = {
|
||||
"en":[
|
||||
{"id": "mode_connect", "title": "Connect two objects" }
|
||||
|
||||
var langList = {
|
||||
'en': [
|
||||
{'id': 'mode_connect', 'title': 'Connect two objects'}
|
||||
],
|
||||
"fr":[
|
||||
{"id": "mode_connect", "title": "Connecter deux objets"}
|
||||
'fr': [
|
||||
{'id': 'mode_connect', 'title': 'Connecter deux objets'}
|
||||
]
|
||||
};
|
||||
|
||||
function getBBintersect(x, y, bb, offset) {
|
||||
if(offset) {
|
||||
function getBBintersect (x, y, bb, offset) {
|
||||
if (offset) {
|
||||
offset -= 0;
|
||||
bb = $.extend({}, bb);
|
||||
bb.width += offset;
|
||||
bb.height += offset;
|
||||
bb.x -= offset/2;
|
||||
bb.y -= offset/2;
|
||||
bb.x -= offset / 2;
|
||||
bb.y -= offset / 2;
|
||||
}
|
||||
|
||||
var mid_x = bb.x + bb.width/2;
|
||||
var mid_y = bb.y + bb.height/2;
|
||||
var len_x = x - mid_x;
|
||||
var len_y = y - mid_y;
|
||||
|
||||
var slope = Math.abs(len_y/len_x);
|
||||
|
||||
|
||||
var midX = bb.x + bb.width / 2;
|
||||
var midY = bb.y + bb.height / 2;
|
||||
var lenX = x - midX;
|
||||
var lenY = y - midY;
|
||||
|
||||
var slope = Math.abs(lenY / lenX);
|
||||
|
||||
var ratio;
|
||||
|
||||
if(slope < bb.height/bb.width) {
|
||||
ratio = (bb.width/2) / Math.abs(len_x);
|
||||
|
||||
if (slope < bb.height / bb.width) {
|
||||
ratio = (bb.width / 2) / Math.abs(lenX);
|
||||
} else {
|
||||
ratio = (bb.height/2) / Math.abs(len_y);
|
||||
ratio = (bb.height / 2) / Math.abs(lenY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return {
|
||||
x: mid_x + len_x * ratio,
|
||||
y: mid_y + len_y * ratio
|
||||
x: midX + lenX * ratio,
|
||||
y: midY + lenY * ratio
|
||||
};
|
||||
}
|
||||
|
||||
function getOffset(side, line) {
|
||||
var give_offset = !!line.getAttribute('marker-' + side);
|
||||
// var give_offset = $(line).data(side+'_off');
|
||||
function getOffset (side, line) {
|
||||
var giveOffset = !!line.getAttribute('marker-' + side);
|
||||
// var giveOffset = $(line).data(side+'_off');
|
||||
|
||||
// TODO: Make this number (5) be based on marker width/height
|
||||
var size = line.getAttribute('stroke-width') * 5;
|
||||
return give_offset ? size : 0;
|
||||
return giveOffset ? size : 0;
|
||||
}
|
||||
|
||||
function showPanel(on) {
|
||||
var conn_rules = $('#connector_rules');
|
||||
if(!conn_rules.length) {
|
||||
conn_rules = $('<style id="connector_rules"></style>').appendTo('head');
|
||||
}
|
||||
conn_rules.text(!on?"":"#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }");
|
||||
|
||||
function showPanel (on) {
|
||||
var connRules = $('#connector_rules');
|
||||
if (!connRules.length) {
|
||||
connRules = $('<style id="connector_rules"></style>').appendTo('head');
|
||||
}
|
||||
connRules.text(!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
||||
$('#connector_panel').toggle(on);
|
||||
}
|
||||
|
||||
function setPoint(elem, pos, x, y, setMid) {
|
||||
|
||||
function setPoint (elem, pos, x, y, setMid) {
|
||||
var i, pts = elem.points;
|
||||
var pt = svgroot.createSVGPoint();
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
if (pos === 'end') {pos = pts.numberOfItems - 1;}
|
||||
if (pos === 'end') { pos = pts.numberOfItems - 1; }
|
||||
// TODO: Test for this on init, then use alt only if needed
|
||||
try {
|
||||
pts.replaceItem(pt, pos);
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
// Should only occur in FF which formats points attr as "n,n n,n", so just split
|
||||
var pt_arr = elem.getAttribute("points").split(" ");
|
||||
for (i = 0; i < pt_arr.length; i++) {
|
||||
var ptArr = elem.getAttribute('points').split(' ');
|
||||
for (i = 0; i < ptArr.length; i++) {
|
||||
if (i === pos) {
|
||||
pt_arr[i] = x + ',' + y;
|
||||
ptArr[i] = x + ',' + y;
|
||||
}
|
||||
}
|
||||
elem.setAttribute("points",pt_arr.join(" "));
|
||||
elem.setAttribute('points', ptArr.join(' '));
|
||||
}
|
||||
|
||||
if(setMid) {
|
||||
|
||||
if (setMid) {
|
||||
// Add center point
|
||||
var pt_start = pts.getItem(0);
|
||||
var pt_end = pts.getItem(pts.numberOfItems-1);
|
||||
setPoint(elem, 1, (pt_end.x + pt_start.x)/2, (pt_end.y + pt_start.y)/2);
|
||||
var ptStart = pts.getItem(0);
|
||||
var ptEnd = pts.getItem(pts.numberOfItems - 1);
|
||||
setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLine(diff_x, diff_y) {
|
||||
|
||||
function updateLine (diffX, diffY) {
|
||||
// Update line with element
|
||||
var i = connections.length;
|
||||
while(i--) {
|
||||
while (i--) {
|
||||
var conn = connections[i];
|
||||
var line = conn.connector;
|
||||
var elem = conn.elem;
|
||||
|
||||
var pre = conn.is_start?'start':'end';
|
||||
// var sw = line.getAttribute('stroke-width') * 5;
|
||||
|
||||
// Update bbox for this element
|
||||
var bb = elData(line, pre+'_bb');
|
||||
bb.x = conn.start_x + diff_x;
|
||||
bb.y = conn.start_y + diff_y;
|
||||
elData(line, pre+'_bb', bb);
|
||||
|
||||
var alt_pre = conn.is_start?'end':'start';
|
||||
|
||||
// Get center pt of connected element
|
||||
var bb2 = elData(line, alt_pre+'_bb');
|
||||
var src_x = bb2.x + bb2.width/2;
|
||||
var src_y = bb2.y + bb2.height/2;
|
||||
|
||||
// Set point of element being moved
|
||||
var pt = getBBintersect(src_x, src_y, bb, getOffset(pre, line)); // $(line).data(pre+'_off')?sw:0
|
||||
setPoint(line, conn.is_start ? 0 : 'end', pt.x, pt.y, true);
|
||||
|
||||
// Set point of connected element
|
||||
var pt2 = getBBintersect(pt.x, pt.y, elData(line, alt_pre + '_bb'), getOffset(alt_pre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
// var elem = conn.elem;
|
||||
|
||||
var pre = conn.is_start ? 'start' : 'end';
|
||||
// var sw = line.getAttribute('stroke-width') * 5;
|
||||
|
||||
// Update bbox for this element
|
||||
var bb = elData(line, pre + '_bb');
|
||||
bb.x = conn.start_x + diffX;
|
||||
bb.y = conn.start_y + diffY;
|
||||
elData(line, pre + '_bb', bb);
|
||||
|
||||
var altPre = conn.is_start ? 'end' : 'start';
|
||||
|
||||
// Get center pt of connected element
|
||||
var bb2 = elData(line, altPre + '_bb');
|
||||
var srcX = bb2.x + bb2.width / 2;
|
||||
var srcY = bb2.y + bb2.height / 2;
|
||||
|
||||
// Set point of element being moved
|
||||
var pt = getBBintersect(srcX, srcY, bb, getOffset(pre, line)); // $(line).data(pre+'_off')?sw:0
|
||||
setPoint(line, conn.is_start ? 0 : 'end', pt.x, pt.y, true);
|
||||
|
||||
// Set point of connected element
|
||||
var pt2 = getBBintersect(pt.x, pt.y, elData(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
}
|
||||
}
|
||||
|
||||
function findConnectors(elems) {
|
||||
|
||||
function findConnectors (elems) {
|
||||
var i;
|
||||
if (!elems) {elems = selElems;}
|
||||
var connectors = $(svgcontent).find(conn_sel);
|
||||
if (!elems) { elems = selElems; }
|
||||
var connectors = $(svgcontent).find(connSel);
|
||||
connections = [];
|
||||
|
||||
// Loop through connectors to see if one is connected to the element
|
||||
connectors.each(function() {
|
||||
var add_this;
|
||||
connectors.each(function () {
|
||||
var addThis;
|
||||
function add () {
|
||||
if ($.inArray(this, elems) !== -1) {
|
||||
// Pretend this element is selected
|
||||
add_this = true;
|
||||
addThis = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,42 +171,42 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
['start', 'end'].forEach(function (pos, i) {
|
||||
var key = 'c_' + pos;
|
||||
var part = elData(this, key);
|
||||
if(part == null) {
|
||||
if (part == null) {
|
||||
part = document.getElementById(
|
||||
this.attributes['se:connector'].value.split(' ')[i]
|
||||
);
|
||||
elData(this, 'c_'+pos, part.id);
|
||||
elData(this, pos+'_bb', svgCanvas.getStrokedBBox([part]));
|
||||
elData(this, 'c_' + pos, part.id);
|
||||
elData(this, pos + '_bb', svgCanvas.getStrokedBBox([part]));
|
||||
} else part = document.getElementById(part);
|
||||
parts.push(part);
|
||||
}.bind(this));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
var c_elem = parts[i];
|
||||
var cElem = parts[i];
|
||||
|
||||
add_this = false;
|
||||
addThis = false;
|
||||
// The connected element might be part of a selected group
|
||||
$(c_elem).parents().each(add);
|
||||
|
||||
if(!c_elem || !c_elem.parentNode) {
|
||||
$(cElem).parents().each(add);
|
||||
|
||||
if (!cElem || !cElem.parentNode) {
|
||||
$(this).remove();
|
||||
continue;
|
||||
}
|
||||
if($.inArray(c_elem, elems) !== -1 || add_this) {
|
||||
var bb = svgCanvas.getStrokedBBox([c_elem]);
|
||||
if ($.inArray(cElem, elems) !== -1 || addThis) {
|
||||
var bb = svgCanvas.getStrokedBBox([cElem]);
|
||||
connections.push({
|
||||
elem: c_elem,
|
||||
elem: cElem,
|
||||
connector: this,
|
||||
is_start: (i === 0),
|
||||
start_x: bb.x,
|
||||
start_y: bb.y
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateConnectors(elems) {
|
||||
|
||||
function updateConnectors (elems) {
|
||||
// Updates connector lines based on selected elements
|
||||
// Is not used on mousemove, as it runs getStrokedBBox every time,
|
||||
// which isn't necessary there.
|
||||
@@ -222,227 +220,222 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
var line = conn.connector;
|
||||
var elem = conn.elem;
|
||||
|
||||
var sw = line.getAttribute('stroke-width') * 5;
|
||||
var pre = conn.is_start?'start':'end';
|
||||
|
||||
// var sw = line.getAttribute('stroke-width') * 5;
|
||||
var pre = conn.is_start ? 'start' : 'end';
|
||||
|
||||
// Update bbox for this element
|
||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||
bb.x = conn.start_x;
|
||||
bb.y = conn.start_y;
|
||||
elData(line, pre+'_bb', bb);
|
||||
var add_offset = elData(line, pre+'_off');
|
||||
|
||||
var alt_pre = conn.is_start?'end':'start';
|
||||
|
||||
elData(line, pre + '_bb', bb);
|
||||
/* var addOffset = */ elData(line, pre + '_off');
|
||||
|
||||
var altPre = conn.is_start ? 'end' : 'start';
|
||||
|
||||
// Get center pt of connected element
|
||||
var bb2 = elData(line, alt_pre+'_bb');
|
||||
var src_x = bb2.x + bb2.width/2;
|
||||
var src_y = bb2.y + bb2.height/2;
|
||||
|
||||
var bb2 = elData(line, altPre + '_bb');
|
||||
var srcX = bb2.x + bb2.width / 2;
|
||||
var srcY = bb2.y + bb2.height / 2;
|
||||
|
||||
// Set point of element being moved
|
||||
var pt = getBBintersect(src_x, src_y, bb, getOffset(pre, line));
|
||||
var 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
|
||||
var pt2 = getBBintersect(pt.x, pt.y, elData(line, alt_pre + '_bb'), getOffset(alt_pre, line));
|
||||
var pt2 = getBBintersect(pt.x, pt.y, elData(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
|
||||
|
||||
// Update points attribute manually for webkit
|
||||
if (navigator.userAgent.indexOf('AppleWebKit') !== -1) {
|
||||
var pts = line.points;
|
||||
var len = pts.numberOfItems;
|
||||
var pt_arr = [];
|
||||
var ptArr = [];
|
||||
for (j = 0; j < len; j++) {
|
||||
pt = pts.getItem(j);
|
||||
pt_arr[j] = pt.x + ',' + pt.y;
|
||||
ptArr[j] = pt.x + ',' + pt.y;
|
||||
}
|
||||
line.setAttribute('points', pt_arr.join(' '));
|
||||
line.setAttribute('points', ptArr.join(' '));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do once
|
||||
(function() {
|
||||
(function () {
|
||||
var gse = svgCanvas.groupSelectedElements;
|
||||
|
||||
svgCanvas.groupSelectedElements = function() {
|
||||
svgCanvas.removeFromSelection($(conn_sel).toArray());
|
||||
|
||||
svgCanvas.groupSelectedElements = function () {
|
||||
svgCanvas.removeFromSelection($(connSel).toArray());
|
||||
return gse.apply(this, arguments);
|
||||
};
|
||||
|
||||
|
||||
var mse = svgCanvas.moveSelectedElements;
|
||||
|
||||
svgCanvas.moveSelectedElements = function() {
|
||||
|
||||
svgCanvas.moveSelectedElements = function () {
|
||||
var cmd = mse.apply(this, arguments);
|
||||
updateConnectors();
|
||||
return cmd;
|
||||
};
|
||||
|
||||
se_ns = svgCanvas.getEditorNS();
|
||||
|
||||
seNs = svgCanvas.getEditorNS();
|
||||
}());
|
||||
|
||||
|
||||
// Do on reset
|
||||
function init() {
|
||||
function init () {
|
||||
// Make sure all connectors have data set
|
||||
$(svgcontent).find('*').each(function() {
|
||||
var conn = this.getAttributeNS(se_ns, "connector");
|
||||
if(conn) {
|
||||
this.setAttribute('class', conn_sel.substr(1));
|
||||
var conn_data = conn.split(' ');
|
||||
var sbb = svgCanvas.getStrokedBBox([getElem(conn_data[0])]);
|
||||
var ebb = svgCanvas.getStrokedBBox([getElem(conn_data[1])]);
|
||||
$(this).data('c_start',conn_data[0])
|
||||
.data('c_end',conn_data[1])
|
||||
$(svgcontent).find('*').each(function () {
|
||||
var conn = this.getAttributeNS(seNs, 'connector');
|
||||
if (conn) {
|
||||
this.setAttribute('class', connSel.substr(1));
|
||||
var connData = conn.split(' ');
|
||||
var sbb = svgCanvas.getStrokedBBox([getElem(connData[0])]);
|
||||
var 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);
|
||||
svgCanvas.getEditorNS(true);
|
||||
}
|
||||
});
|
||||
// updateConnectors();
|
||||
// updateConnectors();
|
||||
}
|
||||
|
||||
// $(svgroot).parent().mousemove(function(e) {
|
||||
// // if(started
|
||||
// // || svgCanvas.getMode() != "connector"
|
||||
// // || e.target.parentNode.parentNode != svgcontent) return;
|
||||
//
|
||||
// console.log('y')
|
||||
// // if(e.target.parentNode.parentNode === svgcontent) {
|
||||
// //
|
||||
// // }
|
||||
// });
|
||||
// $(svgroot).parent().mousemove(function (e) {
|
||||
// // if (started
|
||||
// // || svgCanvas.getMode() !== 'connector'
|
||||
// // || e.target.parentNode.parentNode !== svgcontent) return;
|
||||
//
|
||||
// console.log('y')
|
||||
// // if (e.target.parentNode.parentNode === svgcontent) {
|
||||
// //
|
||||
// // }
|
||||
// });
|
||||
|
||||
return {
|
||||
name: "Connector",
|
||||
svgicons: svgEditor.curConfig.imgPath + "conn.svg",
|
||||
name: 'Connector',
|
||||
svgicons: svgEditor.curConfig.imgPath + 'conn.svg',
|
||||
buttons: [{
|
||||
id: "mode_connect",
|
||||
type: "mode",
|
||||
icon: svgEditor.curConfig.imgPath + "cut.png",
|
||||
title: "Connect two objects",
|
||||
id: 'mode_connect',
|
||||
type: 'mode',
|
||||
icon: svgEditor.curConfig.imgPath + 'cut.png',
|
||||
title: 'Connect two objects',
|
||||
includeWith: {
|
||||
button: '#tool_line',
|
||||
isDefault: false,
|
||||
position: 1
|
||||
},
|
||||
events: {
|
||||
'click': function() {
|
||||
svgCanvas.setMode("connector");
|
||||
'click': function () {
|
||||
svgCanvas.setMode('connector');
|
||||
}
|
||||
}
|
||||
}],
|
||||
addLangData: function(lang) {
|
||||
addLangData: function (lang) {
|
||||
return {
|
||||
data: lang_list[lang]
|
||||
data: langList[lang]
|
||||
};
|
||||
},
|
||||
mouseDown: function(opts) {
|
||||
mouseDown: function (opts) {
|
||||
var e = opts.event;
|
||||
start_x = opts.start_x;
|
||||
start_y = opts.start_y;
|
||||
startX = opts.start_x;
|
||||
startY = opts.start_y;
|
||||
var mode = svgCanvas.getMode();
|
||||
|
||||
if (mode == "connector") {
|
||||
|
||||
if (started) {return;}
|
||||
|
||||
var mouse_target = e.target;
|
||||
|
||||
var parents = $(mouse_target).parents();
|
||||
|
||||
if($.inArray(svgcontent, parents) !== -1) {
|
||||
if (mode === 'connector') {
|
||||
if (started) { return; }
|
||||
|
||||
var mouseTarget = e.target;
|
||||
|
||||
var parents = $(mouseTarget).parents();
|
||||
|
||||
if ($.inArray(svgcontent, parents) !== -1) {
|
||||
// Connectable element
|
||||
|
||||
|
||||
// If child of foreignObject, use parent
|
||||
var fo = $(mouse_target).closest("foreignObject");
|
||||
start_elem = fo.length ? fo[0] : mouse_target;
|
||||
|
||||
var fo = $(mouseTarget).closest('foreignObject');
|
||||
startElem = fo.length ? fo[0] : mouseTarget;
|
||||
|
||||
// Get center of source element
|
||||
var bb = svgCanvas.getStrokedBBox([start_elem]);
|
||||
var x = bb.x + bb.width/2;
|
||||
var y = bb.y + bb.height/2;
|
||||
|
||||
var bb = svgCanvas.getStrokedBBox([startElem]);
|
||||
var x = bb.x + bb.width / 2;
|
||||
var y = bb.y + bb.height / 2;
|
||||
|
||||
started = true;
|
||||
cur_line = addElem({
|
||||
"element": "polyline",
|
||||
"attr": {
|
||||
"id": getNextId(),
|
||||
"points": (x+','+y+' '+x+','+y+' '+start_x+','+start_y),
|
||||
"stroke": '#' + curConfig.initStroke.color,
|
||||
"stroke-width": (!start_elem.stroke_width || start_elem.stroke_width == 0) ? curConfig.initStroke.width : start_elem.stroke_width,
|
||||
"fill": "none",
|
||||
"opacity": curConfig.initStroke.opacity,
|
||||
"style": "pointer-events:none"
|
||||
curLine = addElem({
|
||||
'element': 'polyline',
|
||||
'attr': {
|
||||
'id': getNextId(),
|
||||
'points': (x + ',' + y + ' ' + x + ',' + y + ' ' + startX + ',' + startY),
|
||||
'stroke': '#' + curConfig.initStroke.color,
|
||||
'stroke-width': (!startElem.stroke_width || startElem.stroke_width === 0) ? curConfig.initStroke.width : startElem.stroke_width,
|
||||
'fill': 'none',
|
||||
'opacity': curConfig.initStroke.opacity,
|
||||
'style': 'pointer-events:none'
|
||||
}
|
||||
});
|
||||
elData(cur_line, 'start_bb', bb);
|
||||
elData(curLine, 'start_bb', bb);
|
||||
}
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
if (mode == "select") {
|
||||
if (mode === 'select') {
|
||||
findConnectors();
|
||||
}
|
||||
},
|
||||
mouseMove: function(opts) {
|
||||
mouseMove: function (opts) {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
var e = opts.event;
|
||||
var x = opts.mouse_x/zoom;
|
||||
var y = opts.mouse_y/zoom;
|
||||
|
||||
var diff_x = x - start_x,
|
||||
diff_y = y - start_y;
|
||||
|
||||
// var e = opts.event;
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var diffX = x - startX,
|
||||
diffY = y - startY;
|
||||
|
||||
var mode = svgCanvas.getMode();
|
||||
|
||||
if (mode == "connector" && started) {
|
||||
|
||||
var sw = cur_line.getAttribute('stroke-width') * 3;
|
||||
|
||||
if (mode === 'connector' && started) {
|
||||
// var sw = curLine.getAttribute('stroke-width') * 3;
|
||||
// Set start point (adjusts based on bb)
|
||||
var pt = getBBintersect(x, y, elData(cur_line, 'start_bb'), getOffset('start', cur_line));
|
||||
start_x = pt.x;
|
||||
start_y = pt.y;
|
||||
|
||||
setPoint(cur_line, 0, pt.x, pt.y, true);
|
||||
|
||||
var pt = getBBintersect(x, y, elData(curLine, 'start_bb'), getOffset('start', curLine));
|
||||
startX = pt.x;
|
||||
startY = pt.y;
|
||||
|
||||
setPoint(curLine, 0, pt.x, pt.y, true);
|
||||
|
||||
// Set end point
|
||||
setPoint(cur_line, 'end', x, y, true);
|
||||
} else if (mode == "select") {
|
||||
setPoint(curLine, 'end', x, y, true);
|
||||
} else if (mode === 'select') {
|
||||
var slen = selElems.length;
|
||||
|
||||
while(slen--) {
|
||||
|
||||
while (slen--) {
|
||||
var elem = selElems[slen];
|
||||
// Look for selected connector elements
|
||||
if(elem && elData(elem, 'c_start')) {
|
||||
if (elem && elData(elem, 'c_start')) {
|
||||
// Remove the "translate" transform given to move
|
||||
svgCanvas.removeFromSelection([elem]);
|
||||
svgCanvas.getTransformList(elem).clear();
|
||||
|
||||
}
|
||||
}
|
||||
if(connections.length) {
|
||||
updateLine(diff_x, diff_y);
|
||||
|
||||
|
||||
if (connections.length) {
|
||||
updateLine(diffX, diffY);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mouseUp: function(opts) {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
mouseUp: function (opts) {
|
||||
// var zoom = svgCanvas.getZoom();
|
||||
var e = opts.event,
|
||||
x = opts.mouse_x/zoom,
|
||||
y = opts.mouse_y/zoom,
|
||||
mouse_target = e.target;
|
||||
|
||||
if(svgCanvas.getMode() == "connector") {
|
||||
var fo = $(mouse_target).closest("foreignObject");
|
||||
if (fo.length) {mouse_target = fo[0];}
|
||||
|
||||
var parents = $(mouse_target).parents();
|
||||
// x = opts.mouse_x / zoom,
|
||||
// y = opts.mouse_y / zoom,
|
||||
mouseTarget = e.target;
|
||||
|
||||
if (mouse_target == start_elem) {
|
||||
if (svgCanvas.getMode() === 'connector') {
|
||||
var fo = $(mouseTarget).closest('foreignObject');
|
||||
if (fo.length) { mouseTarget = fo[0]; }
|
||||
|
||||
var parents = $(mouseTarget).parents();
|
||||
|
||||
if (mouseTarget === startElem) {
|
||||
// Start line through click
|
||||
started = true;
|
||||
return {
|
||||
@@ -453,7 +446,7 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
}
|
||||
if ($.inArray(svgcontent, parents) === -1) {
|
||||
// Not a valid target element, so remove line
|
||||
$(cur_line).remove();
|
||||
$(curLine).remove();
|
||||
started = false;
|
||||
return {
|
||||
keep: false,
|
||||
@@ -462,66 +455,66 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
};
|
||||
}
|
||||
// Valid end element
|
||||
end_elem = mouse_target;
|
||||
|
||||
var start_id = start_elem.id, end_id = end_elem.id;
|
||||
var conn_str = start_id + " " + end_id;
|
||||
var alt_str = end_id + " " + start_id;
|
||||
endElem = mouseTarget;
|
||||
|
||||
var startId = startElem.id, endId = endElem.id;
|
||||
var connStr = startId + ' ' + endId;
|
||||
var altStr = endId + ' ' + startId;
|
||||
// Don't create connector if one already exists
|
||||
var dupe = $(svgcontent).find(conn_sel).filter(function() {
|
||||
var conn = this.getAttributeNS(se_ns, "connector");
|
||||
if (conn == conn_str || conn == alt_str) {return true;}
|
||||
var dupe = $(svgcontent).find(connSel).filter(function () {
|
||||
var conn = this.getAttributeNS(seNs, 'connector');
|
||||
if (conn === connStr || conn === altStr) { return true; }
|
||||
});
|
||||
if(dupe.length) {
|
||||
$(cur_line).remove();
|
||||
if (dupe.length) {
|
||||
$(curLine).remove();
|
||||
return {
|
||||
keep: false,
|
||||
element: null,
|
||||
started: false
|
||||
};
|
||||
}
|
||||
|
||||
var bb = svgCanvas.getStrokedBBox([end_elem]);
|
||||
|
||||
var pt = getBBintersect(start_x, start_y, bb, getOffset('start', cur_line));
|
||||
setPoint(cur_line, 'end', pt.x, pt.y, true);
|
||||
$(cur_line)
|
||||
.data("c_start", start_id)
|
||||
.data("c_end", end_id)
|
||||
.data("end_bb", bb);
|
||||
se_ns = svgCanvas.getEditorNS(true);
|
||||
cur_line.setAttributeNS(se_ns, "se:connector", conn_str);
|
||||
cur_line.setAttribute('class', conn_sel.substr(1));
|
||||
cur_line.setAttribute('opacity', 1);
|
||||
svgCanvas.addToSelection([cur_line]);
|
||||
|
||||
var bb = svgCanvas.getStrokedBBox([endElem]);
|
||||
|
||||
var 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);
|
||||
seNs = svgCanvas.getEditorNS(true);
|
||||
curLine.setAttributeNS(seNs, 'se:connector', connStr);
|
||||
curLine.setAttribute('class', connSel.substr(1));
|
||||
curLine.setAttribute('opacity', 1);
|
||||
svgCanvas.addToSelection([curLine]);
|
||||
svgCanvas.moveToBottomSelectedElement();
|
||||
selManager.requestSelector(cur_line).showGrips(false);
|
||||
selManager.requestSelector(curLine).showGrips(false);
|
||||
started = false;
|
||||
return {
|
||||
keep: true,
|
||||
element: cur_line,
|
||||
element: curLine,
|
||||
started: started
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function(opts) {
|
||||
selectedChanged: function (opts) {
|
||||
// TODO: Find better way to skip operations if no connectors are in use
|
||||
if(!$(svgcontent).find(conn_sel).length) {return;}
|
||||
|
||||
if(svgCanvas.getMode() == 'connector') {
|
||||
if (!$(svgcontent).find(connSel).length) { return; }
|
||||
|
||||
if (svgCanvas.getMode() === 'connector') {
|
||||
svgCanvas.setMode('select');
|
||||
}
|
||||
|
||||
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
|
||||
var i = selElems.length;
|
||||
|
||||
while(i--) {
|
||||
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if(elem && elData(elem, 'c_start')) {
|
||||
if (elem && elData(elem, 'c_start')) {
|
||||
selManager.requestSelector(elem).showGrips(false);
|
||||
if(opts.selectedElement && !opts.multiselected) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
// TODO: Set up context tools and hide most regular line tools
|
||||
showPanel(true);
|
||||
} else {
|
||||
@@ -533,48 +526,48 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
}
|
||||
updateConnectors();
|
||||
},
|
||||
elementChanged: function(opts) {
|
||||
elementChanged: function (opts) {
|
||||
var elem = opts.elems[0];
|
||||
if (elem && elem.tagName === 'svg' && elem.id === 'svgcontent') {
|
||||
// Update svgcontent (can change on import)
|
||||
svgcontent = elem;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
// Has marker, so change offset
|
||||
var start;
|
||||
if (elem && (
|
||||
elem.getAttribute("marker-start") ||
|
||||
elem.getAttribute("marker-mid") ||
|
||||
elem.getAttribute("marker-end")
|
||||
elem.getAttribute('marker-start') ||
|
||||
elem.getAttribute('marker-mid') ||
|
||||
elem.getAttribute('marker-end')
|
||||
)) {
|
||||
start = elem.getAttribute("marker-start");
|
||||
var mid = elem.getAttribute("marker-mid");
|
||||
var end = elem.getAttribute("marker-end");
|
||||
cur_line = elem;
|
||||
start = elem.getAttribute('marker-start');
|
||||
var mid = elem.getAttribute('marker-mid');
|
||||
var end = elem.getAttribute('marker-end');
|
||||
curLine = elem;
|
||||
$(elem)
|
||||
.data("start_off", !!start)
|
||||
.data("end_off", !!end);
|
||||
|
||||
.data('start_off', !!start)
|
||||
.data('end_off', !!end);
|
||||
|
||||
if (elem.tagName === 'line' && mid) {
|
||||
// Convert to polyline to accept mid-arrow
|
||||
|
||||
|
||||
var x1 = Number(elem.getAttribute('x1'));
|
||||
var x2 = Number(elem.getAttribute('x2'));
|
||||
var y1 = Number(elem.getAttribute('y1'));
|
||||
var y2 = Number(elem.getAttribute('y2'));
|
||||
var id = elem.id;
|
||||
|
||||
var mid_pt = (' '+((x1+x2)/2)+','+((y1+y2)/2) + ' ');
|
||||
|
||||
var midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
|
||||
var pline = addElem({
|
||||
"element": "polyline",
|
||||
"attr": {
|
||||
"points": (x1+','+y1+ mid_pt +x2+','+y2),
|
||||
"stroke": elem.getAttribute('stroke'),
|
||||
"stroke-width": elem.getAttribute('stroke-width'),
|
||||
"marker-mid": mid,
|
||||
"fill": "none",
|
||||
"opacity": elem.getAttribute('opacity') || 1
|
||||
'element': 'polyline',
|
||||
'attr': {
|
||||
'points': (x1 + ',' + y1 + midPt + x2 + ',' + y2),
|
||||
'stroke': elem.getAttribute('stroke'),
|
||||
'stroke-width': elem.getAttribute('stroke-width'),
|
||||
'marker-mid': mid,
|
||||
'fill': 'none',
|
||||
'opacity': elem.getAttribute('opacity') || 1
|
||||
}
|
||||
});
|
||||
$(elem).after(pline).remove();
|
||||
@@ -585,36 +578,37 @@ svgEditor.addExtension("Connector", function(S) {
|
||||
}
|
||||
}
|
||||
// Update line if it's a connector
|
||||
if (elem.getAttribute('class') == conn_sel.substr(1)) {
|
||||
if (elem.getAttribute('class') === connSel.substr(1)) {
|
||||
start = getElem(elData(elem, 'c_start'));
|
||||
updateConnectors([start]);
|
||||
} else {
|
||||
updateConnectors();
|
||||
}
|
||||
},
|
||||
IDsUpdated: function(input) {
|
||||
IDsUpdated: function (input) {
|
||||
var remove = [];
|
||||
input.elems.forEach(function(elem){
|
||||
if('se:connector' in elem.attr) {
|
||||
input.elems.forEach(function (elem) {
|
||||
if ('se:connector' in elem.attr) {
|
||||
elem.attr['se:connector'] = elem.attr['se:connector'].split(' ')
|
||||
.map(function(oldID){ return input.changes[oldID] }).join(' ');
|
||||
.map(function (oldID) { return input.changes[oldID]; }).join(' ');
|
||||
|
||||
// Check validity - the field would be something like 'svg_21 svg_22', but
|
||||
// if one end is missing, it would be 'svg_21' and therefore fail this test
|
||||
if(!/. ./.test(elem.attr['se:connector']))
|
||||
if (!/. ./.test(elem.attr['se:connector'])) {
|
||||
remove.push(elem.attr.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
return {remove: remove};
|
||||
},
|
||||
toolButtonStateUpdate: function(opts) {
|
||||
toolButtonStateUpdate: function (opts) {
|
||||
if (opts.nostroke) {
|
||||
if ($('#mode_connect').hasClass('tool_button_current')) {
|
||||
svgEditor.clickSelect();
|
||||
}
|
||||
}
|
||||
$('#mode_connect')
|
||||
.toggleClass('disabled',opts.nostroke);
|
||||
.toggleClass('disabled', opts.nostroke);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, $*/
|
||||
/*jslint vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, $ */
|
||||
/*
|
||||
* ext-eyedropper.js
|
||||
*
|
||||
@@ -15,26 +15,27 @@
|
||||
// 3) svg_editor.js
|
||||
// 4) svgcanvas.js
|
||||
|
||||
svgEditor.addExtension("eyedropper", function(S) {'use strict';
|
||||
svgEditor.addExtension('eyedropper', function (S) {
|
||||
'use strict';
|
||||
var // NS = svgedit.NS,
|
||||
// svgcontent = S.svgcontent,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
svgCanvas = svgEditor.canvas,
|
||||
ChangeElementCommand = svgedit.history.ChangeElementCommand,
|
||||
addToHistory = function(cmd) { svgCanvas.undoMgr.addCommandToHistory(cmd); },
|
||||
addToHistory = function (cmd) { svgCanvas.undoMgr.addCommandToHistory(cmd); },
|
||||
currentStyle = {
|
||||
fillPaint: "red", fillOpacity: 1.0,
|
||||
strokePaint: "black", strokeOpacity: 1.0,
|
||||
fillPaint: 'red', fillOpacity: 1.0,
|
||||
strokePaint: 'black', strokeOpacity: 1.0,
|
||||
strokeWidth: 5, strokeDashArray: null,
|
||||
opacity: 1.0,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'miter'
|
||||
};
|
||||
|
||||
function getStyle(opts) {
|
||||
function getStyle (opts) {
|
||||
// if we are in eyedropper mode, we don't want to disable the eye-dropper tool
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode == "eyedropper") {return;}
|
||||
if (mode === 'eyedropper') { return; }
|
||||
|
||||
var elem = null;
|
||||
var tool = $('#tool_eyedropper');
|
||||
@@ -45,65 +46,63 @@ svgEditor.addExtension("eyedropper", function(S) {'use strict';
|
||||
elem = opts.elems[0];
|
||||
tool.removeClass('disabled');
|
||||
// grab the current style
|
||||
currentStyle.fillPaint = elem.getAttribute("fill") || "black";
|
||||
currentStyle.fillOpacity = elem.getAttribute("fill-opacity") || 1.0;
|
||||
currentStyle.strokePaint = elem.getAttribute("stroke");
|
||||
currentStyle.strokeOpacity = elem.getAttribute("stroke-opacity") || 1.0;
|
||||
currentStyle.strokeWidth = elem.getAttribute("stroke-width");
|
||||
currentStyle.strokeDashArray = elem.getAttribute("stroke-dasharray");
|
||||
currentStyle.strokeLinecap = elem.getAttribute("stroke-linecap");
|
||||
currentStyle.strokeLinejoin = elem.getAttribute("stroke-linejoin");
|
||||
currentStyle.opacity = elem.getAttribute("opacity") || 1.0;
|
||||
}
|
||||
currentStyle.fillPaint = elem.getAttribute('fill') || 'black';
|
||||
currentStyle.fillOpacity = elem.getAttribute('fill-opacity') || 1.0;
|
||||
currentStyle.strokePaint = elem.getAttribute('stroke');
|
||||
currentStyle.strokeOpacity = elem.getAttribute('stroke-opacity') || 1.0;
|
||||
currentStyle.strokeWidth = elem.getAttribute('stroke-width');
|
||||
currentStyle.strokeDashArray = elem.getAttribute('stroke-dasharray');
|
||||
currentStyle.strokeLinecap = elem.getAttribute('stroke-linecap');
|
||||
currentStyle.strokeLinejoin = elem.getAttribute('stroke-linejoin');
|
||||
currentStyle.opacity = elem.getAttribute('opacity') || 1.0;
|
||||
// disable eye-dropper tool
|
||||
else {
|
||||
} else {
|
||||
tool.addClass('disabled');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
name: "eyedropper",
|
||||
svgicons: svgEditor.curConfig.extPath + "eyedropper-icon.xml",
|
||||
name: 'eyedropper',
|
||||
svgicons: svgEditor.curConfig.extPath + 'eyedropper-icon.xml',
|
||||
buttons: [{
|
||||
id: "tool_eyedropper",
|
||||
type: "mode",
|
||||
title: "Eye Dropper Tool",
|
||||
key: "I",
|
||||
id: 'tool_eyedropper',
|
||||
type: 'mode',
|
||||
title: 'Eye Dropper Tool',
|
||||
key: 'I',
|
||||
events: {
|
||||
"click": function() {
|
||||
svgCanvas.setMode("eyedropper");
|
||||
click: function () {
|
||||
svgCanvas.setMode('eyedropper');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
|
||||
// if we have selected an element, grab its paint and enable the eye dropper button
|
||||
selectedChanged: getStyle,
|
||||
elementChanged: getStyle,
|
||||
|
||||
mouseDown: function(opts) {
|
||||
|
||||
mouseDown: function (opts) {
|
||||
var mode = svgCanvas.getMode();
|
||||
if (mode == "eyedropper") {
|
||||
if (mode === 'eyedropper') {
|
||||
var e = opts.event;
|
||||
var target = e.target;
|
||||
if ($.inArray(target.nodeName, ['svg', 'g', 'use']) === -1) {
|
||||
var changes = {};
|
||||
|
||||
var change = function(elem, attrname, newvalue) {
|
||||
var change = function (elem, attrname, newvalue) {
|
||||
changes[attrname] = elem.getAttribute(attrname);
|
||||
elem.setAttribute(attrname, newvalue);
|
||||
};
|
||||
|
||||
if (currentStyle.fillPaint) {change(target, "fill", currentStyle.fillPaint);}
|
||||
if (currentStyle.fillOpacity) {change(target, "fill-opacity", currentStyle.fillOpacity);}
|
||||
if (currentStyle.strokePaint) {change(target, "stroke", currentStyle.strokePaint);}
|
||||
if (currentStyle.strokeOpacity) {change(target, "stroke-opacity", currentStyle.strokeOpacity);}
|
||||
if (currentStyle.strokeWidth) {change(target, "stroke-width", currentStyle.strokeWidth);}
|
||||
if (currentStyle.strokeDashArray) {change(target, "stroke-dasharray", currentStyle.strokeDashArray);}
|
||||
if (currentStyle.opacity) {change(target, "opacity", currentStyle.opacity);}
|
||||
if (currentStyle.strokeLinecap) {change(target, "stroke-linecap", currentStyle.strokeLinecap);}
|
||||
if (currentStyle.strokeLinejoin) {change(target, "stroke-linejoin", currentStyle.strokeLinejoin);}
|
||||
|
||||
|
||||
if (currentStyle.fillPaint) { change(target, 'fill', currentStyle.fillPaint); }
|
||||
if (currentStyle.fillOpacity) { change(target, 'fill-opacity', currentStyle.fillOpacity); }
|
||||
if (currentStyle.strokePaint) { change(target, 'stroke', currentStyle.strokePaint); }
|
||||
if (currentStyle.strokeOpacity) { change(target, 'stroke-opacity', currentStyle.strokeOpacity); }
|
||||
if (currentStyle.strokeWidth) { change(target, 'stroke-width', currentStyle.strokeWidth); }
|
||||
if (currentStyle.strokeDashArray) { change(target, 'stroke-dasharray', currentStyle.strokeDashArray); }
|
||||
if (currentStyle.opacity) { change(target, 'opacity', currentStyle.opacity); }
|
||||
if (currentStyle.strokeLinecap) { change(target, 'stroke-linecap', currentStyle.strokeLinecap); }
|
||||
if (currentStyle.strokeLinejoin) { change(target, 'stroke-linejoin', currentStyle.strokeLinejoin); }
|
||||
|
||||
addToHistory(new ChangeElementCommand(target, changes));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*globals svgEditor, svgedit, svgCanvas, $*/
|
||||
/*jslint vars: true, eqeq: true, todo: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, svgCanvas, $ */
|
||||
/*
|
||||
* ext-foreignobject.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
*
|
||||
* Copyright(c) 2010 Jacques Distler
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* Copyright(c) 2010 Jacques Distler
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("foreignObject", function(S) {
|
||||
svgEditor.addExtension('foreignObject', function (S) {
|
||||
var NS = svgedit.NS,
|
||||
Utils = svgedit.utilities,
|
||||
svgcontent = S.svgcontent,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
// svgcontent = S.svgcontent,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
selElems,
|
||||
editingforeign = false,
|
||||
svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
@@ -27,16 +27,16 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
};
|
||||
|
||||
function showPanel(on) {
|
||||
var fc_rules = $('#fc_rules');
|
||||
if(!fc_rules.length) {
|
||||
fc_rules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
function showPanel (on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fc_rules.text(!on?"":" #tool_topath { display: none !important; }");
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#foreignObject_panel').toggle(on);
|
||||
}
|
||||
|
||||
function toggleSourceButtons(on) {
|
||||
function toggleSourceButtons (on) {
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#foreign_save, #foreign_cancel').toggle(on);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
//
|
||||
// Returns:
|
||||
// This function returns false if the set was unsuccessful, true otherwise.
|
||||
function setForeignString(xmlString) {
|
||||
function setForeignString (xmlString) {
|
||||
var elt = selElems[0];
|
||||
try {
|
||||
// convert string into XML document
|
||||
@@ -58,9 +58,9 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
// run it through our sanitizer to remove anything we do not support
|
||||
S.sanitizeSvg(newDoc.documentElement);
|
||||
elt.parentNode.replaceChild(svgdoc.importNode(newDoc.documentElement.firstChild, true), elt);
|
||||
S.call("changed", [elt]);
|
||||
S.call('changed', [elt]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
@@ -68,9 +68,9 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function showForeignEditor() {
|
||||
function showForeignEditor () {
|
||||
var elt = selElems[0];
|
||||
if (!elt || editingforeign) {return;}
|
||||
if (!elt || editingforeign) { return; }
|
||||
editingforeign = true;
|
||||
toggleSourceButtons(true);
|
||||
elt.removeAttribute('fill');
|
||||
@@ -82,78 +82,78 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
$('#svg_source_textarea').focus();
|
||||
}
|
||||
|
||||
function setAttr(attr, val) {
|
||||
function setAttr (attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call("changed", selElems);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
return {
|
||||
name: "foreignObject",
|
||||
svgicons: svgEditor.curConfig.extPath + "foreignobject-icons.xml",
|
||||
name: 'foreignObject',
|
||||
svgicons: svgEditor.curConfig.extPath + 'foreignobject-icons.xml',
|
||||
buttons: [{
|
||||
id: "tool_foreign",
|
||||
type: "mode",
|
||||
title: "Foreign Object Tool",
|
||||
id: 'tool_foreign',
|
||||
type: 'mode',
|
||||
title: 'Foreign Object Tool',
|
||||
events: {
|
||||
'click': function() {
|
||||
'click': function () {
|
||||
svgCanvas.setMode('foreign');
|
||||
}
|
||||
}
|
||||
},{
|
||||
id: "edit_foreign",
|
||||
type: "context",
|
||||
panel: "foreignObject_panel",
|
||||
title: "Edit ForeignObject Content",
|
||||
}, {
|
||||
id: 'edit_foreign',
|
||||
type: 'context',
|
||||
panel: 'foreignObject_panel',
|
||||
title: 'Edit ForeignObject Content',
|
||||
events: {
|
||||
'click': function() {
|
||||
'click': function () {
|
||||
showForeignEditor();
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: "input",
|
||||
panel: "foreignObject_panel",
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's width",
|
||||
id: "foreign_width",
|
||||
label: "w",
|
||||
id: 'foreign_width',
|
||||
label: 'w',
|
||||
size: 3,
|
||||
events: {
|
||||
change: function() {
|
||||
change: function () {
|
||||
setAttr('width', this.value);
|
||||
}
|
||||
}
|
||||
},{
|
||||
type: "input",
|
||||
panel: "foreignObject_panel",
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's height",
|
||||
id: "foreign_height",
|
||||
label: "h",
|
||||
id: 'foreign_height',
|
||||
label: 'h',
|
||||
events: {
|
||||
change: function() {
|
||||
change: function () {
|
||||
setAttr('height', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: "input",
|
||||
panel: "foreignObject_panel",
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's font size",
|
||||
id: "foreign_font_size",
|
||||
label: "font-size",
|
||||
id: 'foreign_font_size',
|
||||
label: 'font-size',
|
||||
size: 2,
|
||||
defval: 16,
|
||||
events: {
|
||||
change: function() {
|
||||
change: function () {
|
||||
setAttr('font-size', this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
callback: function() {
|
||||
callback: function () {
|
||||
$('#foreignObject_panel').hide();
|
||||
|
||||
var endChanges = function() {
|
||||
var endChanges = function () {
|
||||
$('#svg_source_editor').hide();
|
||||
editingforeign = false;
|
||||
$('#svg_source_textarea').blur();
|
||||
@@ -161,48 +161,46 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
var save = $('#tool_source_save').clone()
|
||||
/* var save = */ $('#tool_source_save').clone()
|
||||
.hide().attr('id', 'foreign_save').unbind()
|
||||
.appendTo("#tool_source_back").click(function() {
|
||||
|
||||
if (!editingforeign) {return;}
|
||||
.appendTo('#tool_source_back').click(function () {
|
||||
if (!editingforeign) { return; }
|
||||
|
||||
if (!setForeignString($('#svg_source_textarea').val())) {
|
||||
$.confirm("Errors found. Revert to original?", function(ok) {
|
||||
if(!ok) {return false;}
|
||||
$.confirm('Errors found. Revert to original?', function (ok) {
|
||||
if (!ok) { return false; }
|
||||
endChanges();
|
||||
});
|
||||
} else {
|
||||
endChanges();
|
||||
}
|
||||
// setSelectMode();
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
var cancel = $('#tool_source_cancel').clone()
|
||||
/* var cancel = */ $('#tool_source_cancel').clone()
|
||||
.hide().attr('id', 'foreign_cancel').unbind()
|
||||
.appendTo("#tool_source_back").click(function() {
|
||||
.appendTo('#tool_source_back').click(function () {
|
||||
endChanges();
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function(opts) {
|
||||
var e = opts.event;
|
||||
|
||||
if(svgCanvas.getMode() == "foreign") {
|
||||
mouseDown: function (opts) {
|
||||
// var e = opts.event;
|
||||
|
||||
if (svgCanvas.getMode() === 'foreign') {
|
||||
started = true;
|
||||
newFO = S.addSvgElementFromJson({
|
||||
"element": "foreignObject",
|
||||
"attr": {
|
||||
"x": opts.start_x,
|
||||
"y": opts.start_y,
|
||||
"id": S.getNextId(),
|
||||
"font-size": 16, //cur_text.font_size,
|
||||
"width": "48",
|
||||
"height": "20",
|
||||
"style": "pointer-events:inherit"
|
||||
'element': 'foreignObject',
|
||||
'attr': {
|
||||
'x': opts.start_x,
|
||||
'y': opts.start_y,
|
||||
'id': S.getNextId(),
|
||||
'font-size': 16, // cur_text.font_size,
|
||||
'width': '48',
|
||||
'height': '20',
|
||||
'style': 'pointer-events:inherit'
|
||||
}
|
||||
});
|
||||
var m = svgdoc.createElementNS(NS.MATH, 'math');
|
||||
@@ -210,11 +208,11 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
m.setAttribute('display', 'inline');
|
||||
var mi = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi.setAttribute('mathvariant', 'normal');
|
||||
mi.textContent = "\u03A6";
|
||||
mi.textContent = '\u03A6';
|
||||
var mo = svgdoc.createElementNS(NS.MATH, 'mo');
|
||||
mo.textContent = "\u222A";
|
||||
mo.textContent = '\u222A';
|
||||
var mi2 = svgdoc.createElementNS(NS.MATH, 'mi');
|
||||
mi2.textContent = "\u2133";
|
||||
mi2.textContent = '\u2133';
|
||||
m.appendChild(mi);
|
||||
m.appendChild(mo);
|
||||
m.appendChild(mi2);
|
||||
@@ -224,34 +222,32 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseUp: function(opts) {
|
||||
var e = opts.event;
|
||||
if(svgCanvas.getMode() == "foreign" && started) {
|
||||
var attrs = $(newFO).attr(["width", "height"]);
|
||||
var keep = (attrs.width != 0 || attrs.height != 0);
|
||||
mouseUp: function (opts) {
|
||||
// var e = opts.event;
|
||||
if (svgCanvas.getMode() === 'foreign' && started) {
|
||||
var attrs = $(newFO).attr(['width', 'height']);
|
||||
var keep = (attrs.width !== '0' || attrs.height !== '0');
|
||||
svgCanvas.addToSelection([newFO], true);
|
||||
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
selectedChanged: function(opts) {
|
||||
selectedChanged: function (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
|
||||
while(i--) {
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if(elem && elem.tagName === 'foreignObject') {
|
||||
if(opts.selectedElement && !opts.multiselected) {
|
||||
$('#foreign_font_size').val(elem.getAttribute("font-size"));
|
||||
$('#foreign_width').val(elem.getAttribute("width"));
|
||||
$('#foreign_height').val(elem.getAttribute("height"));
|
||||
if (elem && elem.tagName === 'foreignObject') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#foreign_font_size').val(elem.getAttribute('font-size'));
|
||||
$('#foreign_width').val(elem.getAttribute('width'));
|
||||
$('#foreign_height').val(elem.getAttribute('height'));
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
@@ -261,8 +257,8 @@ svgEditor.addExtension("foreignObject", function(S) {
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function(opts) {
|
||||
var elem = opts.elems[0];
|
||||
elementChanged: function (opts) {
|
||||
// var elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, svgCanvas, $*/
|
||||
/*jslint vars: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, svgCanvas, $ */
|
||||
/*
|
||||
* ext-grid.js
|
||||
*
|
||||
@@ -14,7 +14,8 @@
|
||||
// 1) units.js
|
||||
// 2) everything else
|
||||
|
||||
svgEditor.addExtension('view_grid', function() { 'use strict';
|
||||
svgEditor.addExtension('view_grid', function () {
|
||||
'use strict';
|
||||
|
||||
var NS = svgedit.NS,
|
||||
svgdoc = document.getElementById('svgcanvas').ownerDocument,
|
||||
@@ -44,8 +45,8 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
|
||||
assignAttributes(gridPattern, {
|
||||
'id': 'gridpattern',
|
||||
'patternUnits': 'userSpaceOnUse',
|
||||
'x': 0, //-(value.strokeWidth / 2), // position for strokewidth
|
||||
'y': 0, //-(value.strokeWidth / 2), // position for strokewidth
|
||||
'x': 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
'y': 0, // -(value.strokeWidth / 2), // position for strokewidth
|
||||
'width': 100,
|
||||
'height': 100
|
||||
});
|
||||
@@ -74,56 +75,56 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
|
||||
});
|
||||
$('#canvasGrid').append(gridBox);
|
||||
|
||||
function updateGrid(zoom) {
|
||||
function updateGrid (zoom) {
|
||||
var i;
|
||||
// TODO: Try this with <line> elements, then compare performance difference
|
||||
var unit = units[svgEditor.curConfig.baseUnit]; // 1 = 1px
|
||||
var u_multi = unit * zoom;
|
||||
var uMulti = unit * zoom;
|
||||
// Calculate the main number interval
|
||||
var raw_m = 100 / u_multi;
|
||||
var rawM = 100 / uMulti;
|
||||
var multi = 1;
|
||||
for (i = 0; i < intervals.length; i++) {
|
||||
var num = intervals[i];
|
||||
multi = num;
|
||||
if (raw_m <= num) {
|
||||
if (rawM <= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
var big_int = multi * u_multi;
|
||||
var bigInt = multi * uMulti;
|
||||
|
||||
// Set the canvas size to the width of the container
|
||||
hcanvas.width = big_int;
|
||||
hcanvas.height = big_int;
|
||||
hcanvas.width = bigInt;
|
||||
hcanvas.height = bigInt;
|
||||
var ctx = hcanvas.getContext('2d');
|
||||
var cur_d = 0.5;
|
||||
var part = big_int / 10;
|
||||
var curD = 0.5;
|
||||
var part = bigInt / 10;
|
||||
|
||||
ctx.globalAlpha = 0.2;
|
||||
ctx.strokeStyle = svgEditor.curConfig.gridColor;
|
||||
for (i = 1; i < 10; i++) {
|
||||
var sub_d = Math.round(part * i) + 0.5;
|
||||
// var line_num = (i % 2)?12:10;
|
||||
var line_num = 0;
|
||||
ctx.moveTo(sub_d, big_int);
|
||||
ctx.lineTo(sub_d, line_num);
|
||||
ctx.moveTo(big_int, sub_d);
|
||||
ctx.lineTo(line_num ,sub_d);
|
||||
var subD = Math.round(part * i) + 0.5;
|
||||
// var lineNum = (i % 2)?12:10;
|
||||
var lineNum = 0;
|
||||
ctx.moveTo(subD, bigInt);
|
||||
ctx.lineTo(subD, lineNum);
|
||||
ctx.moveTo(bigInt, subD);
|
||||
ctx.lineTo(lineNum, subD);
|
||||
}
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.moveTo(cur_d, big_int);
|
||||
ctx.lineTo(cur_d, 0);
|
||||
ctx.moveTo(curD, bigInt);
|
||||
ctx.lineTo(curD, 0);
|
||||
|
||||
ctx.moveTo(big_int, cur_d);
|
||||
ctx.lineTo(0, cur_d);
|
||||
ctx.moveTo(bigInt, curD);
|
||||
ctx.lineTo(0, curD);
|
||||
ctx.stroke();
|
||||
|
||||
var datauri = hcanvas.toDataURL('image/png');
|
||||
gridimg.setAttribute('width', big_int);
|
||||
gridimg.setAttribute('height', big_int);
|
||||
gridimg.parentNode.setAttribute('width', big_int);
|
||||
gridimg.parentNode.setAttribute('height', big_int);
|
||||
gridimg.setAttribute('width', bigInt);
|
||||
gridimg.setAttribute('height', bigInt);
|
||||
gridimg.parentNode.setAttribute('width', bigInt);
|
||||
gridimg.parentNode.setAttribute('height', bigInt);
|
||||
svgCanvas.setHref(gridimg, datauri);
|
||||
}
|
||||
|
||||
@@ -138,8 +139,8 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
|
||||
name: 'view_grid',
|
||||
svgicons: svgEditor.curConfig.extPath + 'grid-icon.xml',
|
||||
|
||||
zoomChanged: function(zoom) {
|
||||
if (showGrid) {updateGrid(zoom);}
|
||||
zoomChanged: function (zoom) {
|
||||
if (showGrid) { updateGrid(zoom); }
|
||||
},
|
||||
callback: function () {
|
||||
if (showGrid) {
|
||||
@@ -152,7 +153,7 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
|
||||
panel: 'editor_panel',
|
||||
title: 'Show/Hide Grid',
|
||||
events: {
|
||||
click: function() {
|
||||
click: function () {
|
||||
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgCanvas, $*/
|
||||
/*jslint vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-helloworld.js
|
||||
*
|
||||
@@ -8,73 +8,72 @@
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
This is a very basic SVG-Edit extension. It adds a "Hello World" button in
|
||||
the left panel. Clicking on the button, and then the canvas will show the
|
||||
user the point on the canvas that was clicked on.
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("Hello World", function() {'use strict';
|
||||
|
||||
return {
|
||||
name: "Hello World",
|
||||
// For more notes on how to make an icon file, see the source of
|
||||
// the helloworld-icon.xml
|
||||
svgicons: svgEditor.curConfig.extPath + "helloworld-icon.xml",
|
||||
|
||||
// Multiple buttons can be added in this array
|
||||
buttons: [{
|
||||
// Must match the icon ID in helloworld-icon.xml
|
||||
id: "hello_world",
|
||||
|
||||
// This indicates that the button will be added to the "mode"
|
||||
// button panel on the left side
|
||||
type: "mode",
|
||||
|
||||
// Tooltip text
|
||||
title: "Say 'Hello World'",
|
||||
|
||||
// Events
|
||||
events: {
|
||||
'click': function() {
|
||||
// The action taken when the button is clicked on.
|
||||
// For "mode" buttons, any other button will
|
||||
// automatically be de-pressed.
|
||||
svgCanvas.setMode("hello_world");
|
||||
}
|
||||
}
|
||||
}],
|
||||
// This is triggered when the main mouse button is pressed down
|
||||
// on the editor canvas (not the tool panels)
|
||||
mouseDown: function() {
|
||||
// Check the mode on mousedown
|
||||
if(svgCanvas.getMode() == "hello_world") {
|
||||
|
||||
// The returned object must include "started" with
|
||||
// a value of true in order for mouseUp to be triggered
|
||||
return {started: true};
|
||||
}
|
||||
},
|
||||
|
||||
// This is triggered from anywhere, but "started" must have been set
|
||||
// to true (see above). Note that "opts" is an object with event info
|
||||
mouseUp: function(opts) {
|
||||
// Check the mode on mouseup
|
||||
if(svgCanvas.getMode() == "hello_world") {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var text = "Hello World!\n\nYou clicked here: "
|
||||
+ x + ", " + y;
|
||||
|
||||
// Show the text using the custom alert function
|
||||
$.alert(text);
|
||||
svgEditor.addExtension('Hello World', function () {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
name: 'Hello World',
|
||||
// For more notes on how to make an icon file, see the source of
|
||||
// the helloworld-icon.xml
|
||||
svgicons: svgEditor.curConfig.extPath + 'helloworld-icon.xml',
|
||||
|
||||
// Multiple buttons can be added in this array
|
||||
buttons: [{
|
||||
// Must match the icon ID in helloworld-icon.xml
|
||||
id: 'hello_world',
|
||||
|
||||
// This indicates that the button will be added to the "mode"
|
||||
// button panel on the left side
|
||||
type: 'mode',
|
||||
|
||||
// Tooltip text
|
||||
title: "Say 'Hello World'",
|
||||
|
||||
// Events
|
||||
events: {
|
||||
'click': function () {
|
||||
// The action taken when the button is clicked on.
|
||||
// For "mode" buttons, any other button will
|
||||
// automatically be de-pressed.
|
||||
svgCanvas.setMode('hello_world');
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}],
|
||||
// This is triggered when the main mouse button is pressed down
|
||||
// on the editor canvas (not the tool panels)
|
||||
mouseDown: function () {
|
||||
// Check the mode on mousedown
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
// The returned object must include "started" with
|
||||
// a value of true in order for mouseUp to be triggered
|
||||
return {started: true};
|
||||
}
|
||||
},
|
||||
|
||||
// This is triggered from anywhere, but "started" must have been set
|
||||
// to true (see above). Note that "opts" is an object with event info
|
||||
mouseUp: function (opts) {
|
||||
// Check the mode on mouseup
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var text = 'Hello World!\n\nYou clicked here: ' +
|
||||
x + ', ' + y;
|
||||
|
||||
// Show the text using the custom alert function
|
||||
$.alert(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals $, svgEditor, svgedit, svgCanvas, DOMParser*/
|
||||
/*jslint vars: true, eqeq: true, es5: true, todo: true */
|
||||
/* eslint-disable no-var */
|
||||
/* globals $, svgEditor, svgedit, svgCanvas, DOMParser */
|
||||
/*
|
||||
* ext-imagelib.js
|
||||
*
|
||||
@@ -9,7 +9,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
svgEditor.addExtension('imagelib', function () {
|
||||
'use strict';
|
||||
|
||||
var uiStrings = svgEditor.uiStrings;
|
||||
|
||||
@@ -23,7 +24,8 @@ svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
}
|
||||
});
|
||||
|
||||
var img_libs = [{
|
||||
var imgLibs = [
|
||||
{
|
||||
name: 'Demo library (local)',
|
||||
url: svgEditor.curConfig.extPath + 'imagelib/index.html',
|
||||
description: 'Demonstration library for SVG-edit on this server'
|
||||
@@ -40,20 +42,20 @@ svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
}
|
||||
];
|
||||
|
||||
function closeBrowser() {
|
||||
function closeBrowser () {
|
||||
$('#imgbrowse_holder').hide();
|
||||
}
|
||||
|
||||
function importImage(url) {
|
||||
function importImage (url) {
|
||||
var newImage = svgCanvas.addSvgElementFromJson({
|
||||
"element": "image",
|
||||
"attr": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"id": svgCanvas.getNextId(),
|
||||
"style": "pointer-events:inherit"
|
||||
'element': 'image',
|
||||
'attr': {
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'width': 0,
|
||||
'height': 0,
|
||||
'id': svgCanvas.getNextId(),
|
||||
'style': 'pointer-events:inherit'
|
||||
}
|
||||
});
|
||||
svgCanvas.clearSelection();
|
||||
@@ -62,16 +64,16 @@ svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
}
|
||||
|
||||
var mode = 's';
|
||||
var multi_arr = [];
|
||||
var tranfer_stopped = false;
|
||||
var multiArr = [];
|
||||
var transferStopped = false;
|
||||
var pending = {};
|
||||
var preview, submit;
|
||||
|
||||
window.addEventListener("message", function(evt) {
|
||||
window.addEventListener('message', function (evt) {
|
||||
// Receive postMessage data
|
||||
var response = evt.data;
|
||||
|
||||
if (!response || typeof response !== "string") { // Todo: Should namespace postMessage API for this extension and filter out here
|
||||
|
||||
if (!response || typeof response !== 'string') { // Todo: Should namespace postMessage API for this extension and filter out here
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
@@ -80,172 +82,168 @@ svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
if (res.namespace) { // Part of embedAPI communications
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
} catch (e) {}
|
||||
|
||||
var char1 = response.charAt(0);
|
||||
var id;
|
||||
var svg_str;
|
||||
var img_str;
|
||||
|
||||
if (char1 != "{" && tranfer_stopped) {
|
||||
tranfer_stopped = false;
|
||||
var svgStr;
|
||||
var imgStr;
|
||||
|
||||
if (char1 !== '{' && transferStopped) {
|
||||
transferStopped = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (char1 == '|') {
|
||||
|
||||
if (char1 === '|') {
|
||||
var secondpos = response.indexOf('|', 1);
|
||||
id = response.substr(1, secondpos-1);
|
||||
response = response.substr(secondpos+1);
|
||||
id = response.substr(1, secondpos - 1);
|
||||
response = response.substr(secondpos + 1);
|
||||
char1 = response.charAt(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Hide possible transfer dialog box
|
||||
$('#dialog_box').hide();
|
||||
var entry, cur_meta;
|
||||
var entry, curMeta;
|
||||
switch (char1) {
|
||||
case '{':
|
||||
// Metadata
|
||||
tranfer_stopped = false;
|
||||
cur_meta = JSON.parse(response);
|
||||
|
||||
pending[cur_meta.id] = cur_meta;
|
||||
|
||||
var name = (cur_meta.name || 'file');
|
||||
|
||||
var message = uiStrings.notification.retrieving.replace('%s', name);
|
||||
|
||||
if (mode != 'm') {
|
||||
$.process_cancel(message, function() {
|
||||
tranfer_stopped = true;
|
||||
// Should a message be sent back to the frame?
|
||||
|
||||
$('#dialog_box').hide();
|
||||
case '{':
|
||||
// Metadata
|
||||
transferStopped = false;
|
||||
curMeta = JSON.parse(response);
|
||||
|
||||
pending[curMeta.id] = curMeta;
|
||||
|
||||
var name = (curMeta.name || 'file');
|
||||
|
||||
var message = uiStrings.notification.retrieving.replace('%s', name);
|
||||
|
||||
if (mode !== 'm') {
|
||||
$.process_cancel(message, function () {
|
||||
transferStopped = true;
|
||||
// Should a message be sent back to the frame?
|
||||
|
||||
$('#dialog_box').hide();
|
||||
});
|
||||
} else {
|
||||
entry = $('<div>' + message + '</div>').data('id', curMeta.id);
|
||||
preview.append(entry);
|
||||
curMeta.entry = entry;
|
||||
}
|
||||
|
||||
return;
|
||||
case '<':
|
||||
svgStr = true;
|
||||
break;
|
||||
case 'd':
|
||||
if (response.indexOf('data:image/svg+xml') === 0) {
|
||||
var pre = 'data:image/svg+xml;base64,';
|
||||
var src = response.substring(pre.length);
|
||||
response = svgedit.utilities.decode64(src);
|
||||
svgStr = true;
|
||||
break;
|
||||
} else if (response.indexOf('data:image/') === 0) {
|
||||
imgStr = true;
|
||||
break;
|
||||
}
|
||||
// Else fall through
|
||||
default:
|
||||
// TODO: See if there's a way to base64 encode the binary data stream
|
||||
// var str = 'data:;base64,' + svgedit.utilities.encode64(response, true);
|
||||
|
||||
// Assume it's raw image data
|
||||
// importImage(str);
|
||||
|
||||
// Don't give warning as postMessage may have been used by something else
|
||||
if (mode !== 'm') {
|
||||
closeBrowser();
|
||||
} else {
|
||||
pending[id].entry.remove();
|
||||
}
|
||||
// $.alert('Unexpected data was returned: ' + response, function() {
|
||||
// if (mode !== 'm') {
|
||||
// closeBrowser();
|
||||
// } else {
|
||||
// pending[id].entry.remove();
|
||||
// }
|
||||
// });
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case 's':
|
||||
// Import one
|
||||
if (svgStr) {
|
||||
svgCanvas.importSvgString(response);
|
||||
} else if (imgStr) {
|
||||
importImage(response);
|
||||
}
|
||||
closeBrowser();
|
||||
break;
|
||||
case 'm':
|
||||
// Import multiple
|
||||
multiArr.push([(svgStr ? 'svg' : 'img'), response]);
|
||||
var title;
|
||||
curMeta = pending[id];
|
||||
if (svgStr) {
|
||||
if (curMeta && curMeta.name) {
|
||||
title = curMeta.name;
|
||||
} else {
|
||||
// Try to find a title
|
||||
var xml = new DOMParser().parseFromString(response, 'text/xml').documentElement;
|
||||
title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
|
||||
}
|
||||
if (curMeta) {
|
||||
preview.children().each(function () {
|
||||
if ($(this).data('id') === id) {
|
||||
if (curMeta.preview_url) {
|
||||
$(this).html('<img src="' + curMeta.preview_url + '">' + title);
|
||||
} else {
|
||||
$(this).text(title);
|
||||
}
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
entry = $('<div>' + message + '</div>').data('id', cur_meta.id);
|
||||
preview.append(entry);
|
||||
cur_meta.entry = entry;
|
||||
preview.append('<div>' + title + '</div>');
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
|
||||
return;
|
||||
case '<':
|
||||
svg_str = true;
|
||||
break;
|
||||
case 'd':
|
||||
if (response.indexOf('data:image/svg+xml') === 0) {
|
||||
var pre = 'data:image/svg+xml;base64,';
|
||||
var src = response.substring(pre.length);
|
||||
response = svgedit.utilities.decode64(src);
|
||||
svg_str = true;
|
||||
break;
|
||||
} else if (response.indexOf('data:image/') === 0) {
|
||||
img_str = true;
|
||||
break;
|
||||
} else {
|
||||
if (curMeta && curMeta.preview_url) {
|
||||
title = curMeta.name || '';
|
||||
}
|
||||
// Else fall through
|
||||
default:
|
||||
// TODO: See if there's a way to base64 encode the binary data stream
|
||||
// var str = 'data:;base64,' + svgedit.utilities.encode64(response, true);
|
||||
|
||||
// Assume it's raw image data
|
||||
// importImage(str);
|
||||
|
||||
// Don't give warning as postMessage may have been used by something else
|
||||
if (mode !== 'm') {
|
||||
closeBrowser();
|
||||
if (curMeta && curMeta.preview_url) {
|
||||
entry = '<img src="' + curMeta.preview_url + '">' + title;
|
||||
} else {
|
||||
pending[id].entry.remove();
|
||||
entry = '<img src="' + response + '">';
|
||||
}
|
||||
// $.alert('Unexpected data was returned: ' + response, function() {
|
||||
// if (mode !== 'm') {
|
||||
// closeBrowser();
|
||||
// } else {
|
||||
// pending[id].entry.remove();
|
||||
// }
|
||||
// });
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case 's':
|
||||
// Import one
|
||||
if (svg_str) {
|
||||
svgCanvas.importSvgString(response);
|
||||
} else if (img_str) {
|
||||
importImage(response);
|
||||
}
|
||||
closeBrowser();
|
||||
break;
|
||||
case 'm':
|
||||
// Import multiple
|
||||
multi_arr.push([(svg_str ? 'svg' : 'img'), response]);
|
||||
var title;
|
||||
cur_meta = pending[id];
|
||||
if (svg_str) {
|
||||
if (cur_meta && cur_meta.name) {
|
||||
title = cur_meta.name;
|
||||
} else {
|
||||
// Try to find a title
|
||||
var xml = new DOMParser().parseFromString(response, 'text/xml').documentElement;
|
||||
title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
|
||||
}
|
||||
if (cur_meta) {
|
||||
preview.children().each(function() {
|
||||
if ($(this).data('id') == id) {
|
||||
if (cur_meta.preview_url) {
|
||||
$(this).html('<img src="' + cur_meta.preview_url + '">' + title);
|
||||
} else {
|
||||
$(this).text(title);
|
||||
}
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
preview.append('<div>'+title+'</div>');
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
} else {
|
||||
if (cur_meta && cur_meta.preview_url) {
|
||||
title = cur_meta.name || '';
|
||||
}
|
||||
if (cur_meta && cur_meta.preview_url) {
|
||||
entry = '<img src="' + cur_meta.preview_url + '">' + title;
|
||||
} else {
|
||||
entry = '<img src="' + response + '">';
|
||||
}
|
||||
|
||||
if (cur_meta) {
|
||||
preview.children().each(function() {
|
||||
if ($(this).data('id') == id) {
|
||||
$(this).html(entry);
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
preview.append($('<div>').append(entry));
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
|
||||
if (curMeta) {
|
||||
preview.children().each(function () {
|
||||
if ($(this).data('id') === id) {
|
||||
$(this).html(entry);
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
preview.append($('<div>').append(entry));
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
// Open
|
||||
if (!svg_str) {break;}
|
||||
svgEditor.openPrep(function(ok) {
|
||||
if (!ok) {return;}
|
||||
svgCanvas.clear();
|
||||
svgCanvas.setSvgString(response);
|
||||
// updateCanvas();
|
||||
});
|
||||
closeBrowser();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
// Open
|
||||
if (!svgStr) { break; }
|
||||
svgEditor.openPrep(function (ok) {
|
||||
if (!ok) { return; }
|
||||
svgCanvas.clear();
|
||||
svgCanvas.setSvgString(response);
|
||||
// updateCanvas();
|
||||
});
|
||||
closeBrowser();
|
||||
break;
|
||||
}
|
||||
}, true);
|
||||
|
||||
function toggleMulti(show) {
|
||||
|
||||
function toggleMulti (show) {
|
||||
$('#lib_framewrap, #imglib_opts').css({right: (show ? 200 : 10)});
|
||||
if (!preview) {
|
||||
preview = $('<div id=imglib_preview>').css({
|
||||
@@ -257,208 +255,202 @@ svgEditor.addExtension("imagelib", function() {'use strict';
|
||||
background: '#fff',
|
||||
overflow: 'auto'
|
||||
}).insertAfter('#lib_framewrap');
|
||||
|
||||
|
||||
submit = $('<button disabled>Import selected</button>')
|
||||
.appendTo('#imgbrowse')
|
||||
.on("click touchend", function() {
|
||||
$.each(multi_arr, function(i) {
|
||||
var type = this[0];
|
||||
var data = this[1];
|
||||
if (type == 'svg') {
|
||||
svgCanvas.importSvgString(data);
|
||||
} else {
|
||||
importImage(data);
|
||||
}
|
||||
svgCanvas.moveSelectedElements(i*20, i*20, false);
|
||||
.on('click touchend', function () {
|
||||
$.each(multiArr, function (i) {
|
||||
var type = this[0];
|
||||
var data = this[1];
|
||||
if (type === 'svg') {
|
||||
svgCanvas.importSvgString(data);
|
||||
} else {
|
||||
importImage(data);
|
||||
}
|
||||
svgCanvas.moveSelectedElements(i * 20, i * 20, false);
|
||||
});
|
||||
preview.empty();
|
||||
multiArr = [];
|
||||
$('#imgbrowse_holder').hide();
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
bottom: 10,
|
||||
right: -10
|
||||
});
|
||||
preview.empty();
|
||||
multi_arr = [];
|
||||
$('#imgbrowse_holder').hide();
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
bottom: 10,
|
||||
right: -10
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
preview.toggle(show);
|
||||
submit.toggle(show);
|
||||
}
|
||||
|
||||
function showBrowser() {
|
||||
|
||||
function showBrowser () {
|
||||
var browser = $('#imgbrowse');
|
||||
if (!browser.length) {
|
||||
$('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>\
|
||||
</div></div>').insertAfter('#svg_docprops');
|
||||
$('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>' +
|
||||
'</div></div>').insertAfter('#svg_docprops');
|
||||
browser = $('#imgbrowse');
|
||||
|
||||
var all_libs = uiStrings.imagelib.select_lib;
|
||||
var allLibs = uiStrings.imagelib.select_lib;
|
||||
|
||||
var lib_opts = $('<ul id=imglib_opts>').appendTo(browser);
|
||||
var libOpts = $('<ul id=imglib_opts>').appendTo(browser);
|
||||
var frame = $('<iframe/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');
|
||||
|
||||
var header = $('<h1>').prependTo(browser).text(all_libs).css({
|
||||
|
||||
var header = $('<h1>').prependTo(browser).text(allLibs).css({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%'
|
||||
});
|
||||
|
||||
|
||||
var cancel = $('<button>' + uiStrings.common.cancel + '</button>')
|
||||
.appendTo(browser)
|
||||
.on("click touchend", function() {
|
||||
$('#imgbrowse_holder').hide();
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
top: 5,
|
||||
right: -10
|
||||
});
|
||||
|
||||
var leftBlock = $('<span>').css({position:'absolute',top:5,left:10}).appendTo(browser);
|
||||
|
||||
.on('click touchend', function () {
|
||||
$('#imgbrowse_holder').hide();
|
||||
}).css({
|
||||
position: 'absolute',
|
||||
top: 5,
|
||||
right: -10
|
||||
});
|
||||
|
||||
var leftBlock = $('<span>').css({position: 'absolute', top: 5, left: 10}).appendTo(browser);
|
||||
|
||||
var back = $('<button hidden>' + uiStrings.imagelib.show_list + '</button>')
|
||||
.appendTo(leftBlock)
|
||||
.on("click touchend", function() {
|
||||
frame.attr('src', 'about:blank').hide();
|
||||
lib_opts.show();
|
||||
header.text(all_libs);
|
||||
back.hide();
|
||||
}).css({
|
||||
'margin-right': 5
|
||||
}).hide();
|
||||
|
||||
var type = $('<select><option value=s>' +
|
||||
uiStrings.imagelib.import_single + '</option><option value=m>' +
|
||||
uiStrings.imagelib.import_multi + '</option><option value=o>' +
|
||||
uiStrings.imagelib.open + '</option></select>').appendTo(leftBlock).change(function() {
|
||||
.on('click touchend', function () {
|
||||
frame.attr('src', 'about:blank').hide();
|
||||
libOpts.show();
|
||||
header.text(allLibs);
|
||||
back.hide();
|
||||
}).css({
|
||||
'margin-right': 5
|
||||
}).hide();
|
||||
|
||||
/* var type = */ $('<select><option value=s>' +
|
||||
uiStrings.imagelib.import_single + '</option><option value=m>' +
|
||||
uiStrings.imagelib.import_multi + '</option><option value=o>' +
|
||||
uiStrings.imagelib.open + '</option></select>').appendTo(leftBlock).change(function () {
|
||||
mode = $(this).val();
|
||||
switch (mode) {
|
||||
case 's':
|
||||
case 'o':
|
||||
toggleMulti(false);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
// Import multiple
|
||||
toggleMulti(true);
|
||||
break;
|
||||
case 's':
|
||||
case 'o':
|
||||
toggleMulti(false);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
// Import multiple
|
||||
toggleMulti(true);
|
||||
break;
|
||||
}
|
||||
}).css({
|
||||
'margin-top': 10
|
||||
});
|
||||
|
||||
|
||||
cancel.prepend($.getSvgIcon('cancel', true));
|
||||
back.prepend($.getSvgIcon('tool_imagelib', true));
|
||||
|
||||
$.each(img_libs, function(i, opts) {
|
||||
|
||||
$.each(imgLibs, function (i, opts) {
|
||||
$('<li>')
|
||||
.appendTo(lib_opts)
|
||||
.appendTo(libOpts)
|
||||
.text(opts.name)
|
||||
.on("click touchend", function() {
|
||||
frame.attr('src', opts.url).show();
|
||||
header.text(opts.name);
|
||||
lib_opts.hide();
|
||||
back.show();
|
||||
}).append('<span>' + opts.description + '</span>');
|
||||
.on('click touchend', function () {
|
||||
frame.attr('src', opts.url).show();
|
||||
header.text(opts.name);
|
||||
libOpts.hide();
|
||||
back.show();
|
||||
}).append('<span>' + opts.description + '</span>');
|
||||
});
|
||||
|
||||
} else {
|
||||
$('#imgbrowse_holder').show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
svgicons: svgEditor.curConfig.extPath + "ext-imagelib.xml",
|
||||
svgicons: svgEditor.curConfig.extPath + 'ext-imagelib.xml',
|
||||
buttons: [{
|
||||
id: "tool_imagelib",
|
||||
type: "app_menu", // _flyout
|
||||
id: 'tool_imagelib',
|
||||
type: 'app_menu', // _flyout
|
||||
position: 4,
|
||||
title: "Image library",
|
||||
title: 'Image library',
|
||||
events: {
|
||||
"mouseup": showBrowser
|
||||
'mouseup': showBrowser
|
||||
}
|
||||
}],
|
||||
callback: function() {
|
||||
|
||||
$('<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');
|
||||
callback: function () {
|
||||
$('<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');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*globals svgEditor, svgCanvas, $*/
|
||||
/*jslint vars: true, eqeq: true, todo: true */
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-markers.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
*
|
||||
* Copyright(c) 2010 Will Schleter
|
||||
* Copyright(c) 2010 Will Schleter
|
||||
* based on ext-arrows.js by Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
* This extension provides for the addition of markers to the either end
|
||||
* or the middle of a line, polyline, path, polygon.
|
||||
*
|
||||
* or the middle of a line, polyline, path, polygon.
|
||||
*
|
||||
* Markers may be either a graphic or arbitary text
|
||||
*
|
||||
*
|
||||
* to simplify the coding and make the implementation as robust as possible,
|
||||
* markers are not shared - every object has its own set of markers.
|
||||
* this relationship is maintained by a naming convention between the
|
||||
* ids of the markers and the ids of the object
|
||||
*
|
||||
*
|
||||
* The following restrictions exist for simplicty of use and programming
|
||||
* objects and their markers to have the same color
|
||||
* marker size is fixed
|
||||
@@ -32,236 +32,235 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("Markers", function(S) {
|
||||
svgEditor.addExtension('Markers', function (S) {
|
||||
var // svgcontent = S.svgcontent,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
selElems;
|
||||
|
||||
var mtypes = ['start','mid','end'];
|
||||
var mtypes = ['start', 'mid', 'end'];
|
||||
|
||||
var markerPrefix = 'se_marker_';
|
||||
var idPrefix = 'mkr_';
|
||||
|
||||
var marker_prefix = 'se_marker_';
|
||||
var id_prefix = 'mkr_';
|
||||
|
||||
// note - to add additional marker types add them below with a unique id
|
||||
// and add the associated icon(s) to marker-icons.svg
|
||||
// the geometry is normallized to a 100x100 box with the origin at lower left
|
||||
// Safari did not like negative values for low left of viewBox
|
||||
// remember that the coordinate system has +y downward
|
||||
var marker_types = {
|
||||
nomarker: {},
|
||||
leftarrow:
|
||||
{element:'path', attr:{d:'M0,50 L100,90 L70,50 L100,10 Z'}},
|
||||
var markerTypes = {
|
||||
nomarker: {},
|
||||
leftarrow:
|
||||
{element: 'path', attr: {d: 'M0,50 L100,90 L70,50 L100,10 Z'}},
|
||||
rightarrow:
|
||||
{element:'path', attr:{d:'M100,50 L0,90 L30,50 L0,10 Z'}},
|
||||
{element: 'path', attr: {d: 'M100,50 L0,90 L30,50 L0,10 Z'}},
|
||||
textmarker:
|
||||
{element:'text', attr: {x:0, y:0,'stroke-width':0,'stroke':'none','font-size':75,'font-family':'serif','text-anchor':'left',
|
||||
{element: 'text', attr: {x: 0, y: 0, 'stroke-width': 0, 'stroke': 'none', 'font-size': 75, 'font-family': 'serif', 'text-anchor': 'left',
|
||||
'xml:space': 'preserve'}},
|
||||
forwardslash:
|
||||
{element:'path', attr:{d:'M30,100 L70,0'}},
|
||||
{element: 'path', attr: {d: 'M30,100 L70,0'}},
|
||||
reverseslash:
|
||||
{element:'path', attr:{d:'M30,0 L70,100'}},
|
||||
{element: 'path', attr: {d: 'M30,0 L70,100'}},
|
||||
verticalslash:
|
||||
{element:'path', attr:{d:'M50,0 L50,100'}},
|
||||
{element: 'path', attr: {d: 'M50,0 L50,100'}},
|
||||
box:
|
||||
{element:'path', attr:{d:'M20,20 L20,80 L80,80 L80,20 Z'}},
|
||||
{element: 'path', attr: {d: 'M20,20 L20,80 L80,80 L80,20 Z'}},
|
||||
star:
|
||||
{element:'path', attr:{d:'M10,30 L90,30 L20,90 L50,10 L80,90 Z'}},
|
||||
{element: 'path', attr: {d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z'}},
|
||||
xmark:
|
||||
{element:'path', attr:{d:'M20,80 L80,20 M80,80 L20,20'}},
|
||||
{element: 'path', attr: {d: 'M20,80 L80,20 M80,80 L20,20'}},
|
||||
triangle:
|
||||
{element:'path', attr:{d:'M10,80 L50,20 L80,80 Z'}},
|
||||
{element: 'path', attr: {d: 'M10,80 L50,20 L80,80 Z'}},
|
||||
mcircle:
|
||||
{element:'circle', attr:{r:30, cx:50, cy:50}}
|
||||
{element: 'circle', attr: {r: 30, cx: 50, cy: 50}}
|
||||
};
|
||||
|
||||
|
||||
var lang_list = {
|
||||
"en":[
|
||||
{id: "start_marker_list", title: "Select start marker type" },
|
||||
{id: "mid_marker_list", title: "Select mid marker type" },
|
||||
{id: "end_marker_list", title: "Select end marker type" },
|
||||
{id: "nomarker", title: "No Marker" },
|
||||
{id: "leftarrow", title: "Left Arrow" },
|
||||
{id: "rightarrow", title: "Right Arrow" },
|
||||
{id: "textmarker", title: "Text Marker" },
|
||||
{id: "forwardslash", title: "Forward Slash" },
|
||||
{id: "reverseslash", title: "Reverse Slash" },
|
||||
{id: "verticalslash", title: "Vertical Slash" },
|
||||
{id: "box", title: "Box" },
|
||||
{id: "star", title: "Star" },
|
||||
{id: "xmark", title: "X" },
|
||||
{id: "triangle", title: "Triangle" },
|
||||
{id: "mcircle", title: "Circle" },
|
||||
{id: "leftarrow_o", title: "Open Left Arrow" },
|
||||
{id: "rightarrow_o", title: "Open Right Arrow" },
|
||||
{id: "box_o", title: "Open Box" },
|
||||
{id: "star_o", title: "Open Star" },
|
||||
{id: "triangle_o", title: "Open Triangle" },
|
||||
{id: "mcircle_o", title: "Open Circle" }
|
||||
|
||||
var langList = {
|
||||
'en': [
|
||||
{id: 'start_marker_list', title: 'Select start marker type'},
|
||||
{id: 'mid_marker_list', title: 'Select mid marker type'},
|
||||
{id: 'end_marker_list', title: 'Select end marker type'},
|
||||
{id: 'nomarker', title: 'No Marker'},
|
||||
{id: 'leftarrow', title: 'Left Arrow'},
|
||||
{id: 'rightarrow', title: 'Right Arrow'},
|
||||
{id: 'textmarker', title: 'Text Marker'},
|
||||
{id: 'forwardslash', title: 'Forward Slash'},
|
||||
{id: 'reverseslash', title: 'Reverse Slash'},
|
||||
{id: 'verticalslash', title: 'Vertical Slash'},
|
||||
{id: 'box', title: 'Box'},
|
||||
{id: 'star', title: 'Star'},
|
||||
{id: 'xmark', title: 'X'},
|
||||
{id: 'triangle', title: 'Triangle'},
|
||||
{id: 'mcircle', title: 'Circle'},
|
||||
{id: 'leftarrow_o', title: 'Open Left Arrow'},
|
||||
{id: 'rightarrow_o', title: 'Open Right Arrow'},
|
||||
{id: 'box_o', title: 'Open Box'},
|
||||
{id: 'star_o', title: 'Open Star'},
|
||||
{id: 'triangle_o', title: 'Open Triangle'},
|
||||
{id: 'mcircle_o', title: 'Open Circle'}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
// duplicate shapes to support unfilled (open) marker types with an _o suffix
|
||||
$.each(['leftarrow','rightarrow','box','star','mcircle','triangle'],function(i,v) {
|
||||
marker_types[v+'_o'] = marker_types[v];
|
||||
$.each(['leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle'], function (i, v) {
|
||||
markerTypes[v + '_o'] = markerTypes[v];
|
||||
});
|
||||
|
||||
|
||||
// elem = a graphic element will have an attribute like marker-start
|
||||
// attr - marker-start, marker-mid, or marker-end
|
||||
// returns the marker element that is linked to the graphic element
|
||||
function getLinked(elem, attr) {
|
||||
function getLinked (elem, attr) {
|
||||
var str = elem.getAttribute(attr);
|
||||
if(!str) {return null;}
|
||||
var m = str.match(/\(\#(.*)\)/);
|
||||
if(!m || m.length !== 2) {
|
||||
if (!str) { return null; }
|
||||
var m = str.match(/\(#(.*)\)/);
|
||||
if (!m || m.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
return S.getElem(m[1]);
|
||||
}
|
||||
|
||||
function setIcon(pos,id) {
|
||||
if (id.substr(0,1) !== '\\') {id = '\\textmarker';}
|
||||
var ci = '#'+id_prefix+pos+'_'+id.substr(1);
|
||||
svgEditor.setIcon('#cur_' + pos +'_marker_list', $(ci).children());
|
||||
function setIcon (pos, id) {
|
||||
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
||||
var ci = '#' + idPrefix + pos + '_' + id.substr(1);
|
||||
svgEditor.setIcon('#cur_' + pos + '_marker_list', $(ci).children());
|
||||
$(ci).addClass('current').siblings().removeClass('current');
|
||||
}
|
||||
|
||||
// toggles context tool panel off/on
|
||||
//sets the controls with the selected element's settings
|
||||
function showPanel(on) {
|
||||
// sets the controls with the selected element's settings
|
||||
function showPanel (on) {
|
||||
$('#marker_panel').toggle(on);
|
||||
|
||||
if(on) {
|
||||
if (on) {
|
||||
var el = selElems[0];
|
||||
var val;
|
||||
var ci;
|
||||
|
||||
$.each(mtypes, function(i, pos) {
|
||||
var m = getLinked(el, "marker-" + pos);
|
||||
$.each(mtypes, function (i, pos) {
|
||||
var m = getLinked(el, 'marker-' + pos);
|
||||
var txtbox = $('#' + pos + '_marker');
|
||||
if (!m) {
|
||||
val = '\\nomarker';
|
||||
ci = val;
|
||||
txtbox.hide(); // hide text box
|
||||
} else {
|
||||
if (!m.attributes.se_type) {return;} // not created by this extension
|
||||
if (!m.attributes.se_type) { return; } // not created by this extension
|
||||
val = '\\' + m.attributes.se_type.textContent;
|
||||
ci = val;
|
||||
if (val === '\\textmarker') {
|
||||
val = m.lastChild.textContent;
|
||||
//txtbox.show(); // show text box
|
||||
// txtbox.show(); // show text box
|
||||
} else {
|
||||
txtbox.hide(); // hide text box
|
||||
}
|
||||
}
|
||||
txtbox.val(val);
|
||||
setIcon(pos,ci);
|
||||
txtbox.val(val);
|
||||
setIcon(pos, ci);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMarker (id, val) {
|
||||
var txtBoxBg = '#ffffff';
|
||||
var txtBoxBorder = 'none';
|
||||
var txtBoxStrokeWidth = 0;
|
||||
|
||||
function addMarker(id, val) {
|
||||
var txt_box_bg = '#ffffff';
|
||||
var txt_box_border = 'none';
|
||||
var txt_box_stroke_width = 0;
|
||||
|
||||
var marker = S.getElem(id);
|
||||
|
||||
if (marker) {return;}
|
||||
if (marker) { return; }
|
||||
|
||||
if (val == '' || val == '\\nomarker') {return;}
|
||||
if (val === '' || val === '\\nomarker') { return; }
|
||||
|
||||
var el = selElems[0];
|
||||
var el = selElems[0];
|
||||
var color = el.getAttribute('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
|
||||
// NOTE: Safari didn't like a negative value in viewBox
|
||||
// so we use a standardized 0 0 100 100
|
||||
// with 50 50 being mapped to the marker position
|
||||
var refX = 50;
|
||||
var refY = 50;
|
||||
var viewBox = "0 0 100 100";
|
||||
var viewBox = '0 0 100 100';
|
||||
var markerWidth = 5;
|
||||
var markerHeight = 5;
|
||||
var strokeWidth = 10;
|
||||
var se_type;
|
||||
if (val.substr(0,1) === '\\') {se_type = val.substr(1);}
|
||||
else {se_type = 'textmarker';}
|
||||
var seType;
|
||||
if (val.substr(0, 1) === '\\') {
|
||||
seType = val.substr(1);
|
||||
} else { seType = 'textmarker'; }
|
||||
|
||||
if (!markerTypes[seType]) { return; } // an unknown type!
|
||||
|
||||
if (!marker_types[se_type]) {return;} // an unknown type!
|
||||
|
||||
// create a generic marker
|
||||
marker = addElem({
|
||||
"element": "marker",
|
||||
"attr": {
|
||||
"id": id,
|
||||
"markerUnits": "strokeWidth",
|
||||
"orient": "auto",
|
||||
"style": "pointer-events:none",
|
||||
"se_type": se_type
|
||||
}
|
||||
'element': 'marker',
|
||||
'attr': {
|
||||
'id': id,
|
||||
'markerUnits': 'strokeWidth',
|
||||
'orient': 'auto',
|
||||
'style': 'pointer-events:none',
|
||||
'se_type': seType
|
||||
}
|
||||
});
|
||||
|
||||
if (se_type != 'textmarker') {
|
||||
var mel = addElem(marker_types[se_type]);
|
||||
if (seType !== 'textmarker') {
|
||||
var mel = addElem(markerTypes[seType]);
|
||||
var fillcolor = color;
|
||||
if (se_type.substr(-2) === '_o') {fillcolor = 'none';}
|
||||
if (seType.substr(-2) === '_o') { fillcolor = 'none'; }
|
||||
mel.setAttribute('fill', fillcolor);
|
||||
mel.setAttribute('stroke', color);
|
||||
mel.setAttribute('stroke-width', strokeWidth);
|
||||
marker.appendChild(mel);
|
||||
} else {
|
||||
var text = addElem(marker_types[se_type]);
|
||||
var text = addElem(markerTypes[seType]);
|
||||
// have to add text to get bounding box
|
||||
text.textContent = val;
|
||||
var tb = text.getBBox();
|
||||
//alert( tb.x + " " + tb.y + " " + tb.width + " " + tb.height);
|
||||
// alert(tb.x + ' ' + tb.y + ' ' + tb.width + ' ' + tb.height);
|
||||
var pad = 1;
|
||||
var bb = tb;
|
||||
bb.x = 0;
|
||||
bb.y = 0;
|
||||
bb.width += pad*2;
|
||||
bb.height += pad*2;
|
||||
bb.width += pad * 2;
|
||||
bb.height += pad * 2;
|
||||
// shift text according to its size
|
||||
text.setAttribute('x', pad);
|
||||
text.setAttribute('y', bb.height - pad - tb.height/4); // kludge?
|
||||
text.setAttribute('fill',color);
|
||||
refX = bb.width/2 + pad;
|
||||
refY = bb.height/2 + pad;
|
||||
viewBox = bb.x + " " + bb.y + " " + bb.width + " " + bb.height;
|
||||
markerWidth = bb.width/10;
|
||||
markerHeight = bb.height/10;
|
||||
text.setAttribute('y', bb.height - pad - tb.height / 4); // kludge?
|
||||
text.setAttribute('fill', color);
|
||||
refX = bb.width / 2 + pad;
|
||||
refY = bb.height / 2 + pad;
|
||||
viewBox = bb.x + ' ' + bb.y + ' ' + bb.width + ' ' + bb.height;
|
||||
markerWidth = bb.width / 10;
|
||||
markerHeight = bb.height / 10;
|
||||
|
||||
var box = addElem({
|
||||
"element": "rect",
|
||||
"attr": {
|
||||
"x": bb.x,
|
||||
"y": bb.y,
|
||||
"width": bb.width,
|
||||
"height": bb.height,
|
||||
"fill": txt_box_bg,
|
||||
"stroke": txt_box_border,
|
||||
"stroke-width": txt_box_stroke_width
|
||||
'element': 'rect',
|
||||
'attr': {
|
||||
'x': bb.x,
|
||||
'y': bb.y,
|
||||
'width': bb.width,
|
||||
'height': bb.height,
|
||||
'fill': txtBoxBg,
|
||||
'stroke': txtBoxBorder,
|
||||
'stroke-width': txtBoxStrokeWidth
|
||||
}
|
||||
});
|
||||
marker.setAttribute("orient",0);
|
||||
marker.setAttribute('orient', 0);
|
||||
marker.appendChild(box);
|
||||
marker.appendChild(text);
|
||||
}
|
||||
}
|
||||
|
||||
marker.setAttribute("viewBox",viewBox);
|
||||
marker.setAttribute("markerWidth", markerWidth);
|
||||
marker.setAttribute("markerHeight", markerHeight);
|
||||
marker.setAttribute("refX", refX);
|
||||
marker.setAttribute("refY", refY);
|
||||
marker.setAttribute('viewBox', viewBox);
|
||||
marker.setAttribute('markerWidth', markerWidth);
|
||||
marker.setAttribute('markerHeight', markerHeight);
|
||||
marker.setAttribute('refX', refX);
|
||||
marker.setAttribute('refY', refY);
|
||||
S.findDefs().appendChild(marker);
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
function convertline(elem) {
|
||||
function convertline (elem) {
|
||||
// this routine came from the connectors extension
|
||||
// it is needed because midpoint markers don't work with line elements
|
||||
if (!(elem.tagName === 'line')) {return elem;}
|
||||
if (!(elem.tagName === 'line')) { return elem; }
|
||||
|
||||
// Convert to polyline to accept mid-arrow
|
||||
|
||||
@@ -271,27 +270,27 @@ svgEditor.addExtension("Markers", function(S) {
|
||||
var y2 = Number(elem.getAttribute('y2'));
|
||||
var id = elem.id;
|
||||
|
||||
var mid_pt = (' '+((x1+x2)/2)+','+((y1+y2)/2) + ' ');
|
||||
var midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
|
||||
var pline = addElem({
|
||||
"element": "polyline",
|
||||
"attr": {
|
||||
"points": (x1+','+y1+ mid_pt +x2+','+y2),
|
||||
"stroke": elem.getAttribute('stroke'),
|
||||
"stroke-width": elem.getAttribute('stroke-width'),
|
||||
"fill": "none",
|
||||
"opacity": elem.getAttribute('opacity') || 1
|
||||
'element': 'polyline',
|
||||
'attr': {
|
||||
'points': (x1 + ',' + y1 + midPt + x2 + ',' + y2),
|
||||
'stroke': elem.getAttribute('stroke'),
|
||||
'stroke-width': elem.getAttribute('stroke-width'),
|
||||
'fill': 'none',
|
||||
'opacity': elem.getAttribute('opacity') || 1
|
||||
}
|
||||
});
|
||||
$.each(mtypes, function(i, pos) { // get any existing marker definitions
|
||||
var nam = 'marker-'+pos;
|
||||
$.each(mtypes, function (i, pos) { // get any existing marker definitions
|
||||
var nam = 'marker-' + pos;
|
||||
var m = elem.getAttribute(nam);
|
||||
if (m) {pline.setAttribute(nam,elem.getAttribute(nam));}
|
||||
if (m) { pline.setAttribute(nam, elem.getAttribute(nam)); }
|
||||
});
|
||||
|
||||
|
||||
var batchCmd = new S.BatchCommand();
|
||||
batchCmd.addSubCommand(new S.RemoveElementCommand(elem, elem.parentNode));
|
||||
batchCmd.addSubCommand(new S.InsertElementCommand(pline));
|
||||
|
||||
|
||||
$(elem).after(pline).remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
@@ -300,85 +299,85 @@ svgEditor.addExtension("Markers", function(S) {
|
||||
return pline;
|
||||
}
|
||||
|
||||
function setMarker() {
|
||||
var poslist={'start_marker':'start','mid_marker':'mid','end_marker':'end'};
|
||||
function setMarker () {
|
||||
var poslist = {'start_marker': 'start', 'mid_marker': 'mid', 'end_marker': 'end'};
|
||||
var pos = poslist[this.id];
|
||||
var marker_name = 'marker-'+pos;
|
||||
var markerName = 'marker-' + pos;
|
||||
var val = this.value;
|
||||
var el = selElems[0];
|
||||
var marker = getLinked(el, marker_name);
|
||||
if (marker) {$(marker).remove();}
|
||||
el.removeAttribute(marker_name);
|
||||
if (val == '') {val = '\\nomarker';}
|
||||
if (val == '\\nomarker') {
|
||||
setIcon(pos,val);
|
||||
S.call("changed", selElems);
|
||||
var marker = getLinked(el, markerName);
|
||||
if (marker) { $(marker).remove(); }
|
||||
el.removeAttribute(markerName);
|
||||
if (val === '') { val = '\\nomarker'; }
|
||||
if (val === '\\nomarker') {
|
||||
setIcon(pos, val);
|
||||
S.call('changed', selElems);
|
||||
return;
|
||||
}
|
||||
// Set marker on element
|
||||
var id = marker_prefix + pos + '_' + el.id;
|
||||
var id = markerPrefix + pos + '_' + el.id;
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(marker_name, "url(#" + id + ")");
|
||||
if (el.tagName === 'line' && pos == 'mid') {el = convertline(el);}
|
||||
S.call("changed", selElems);
|
||||
setIcon(pos,val);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
if (el.tagName === 'line' && pos === 'mid') { el = convertline(el); }
|
||||
S.call('changed', selElems);
|
||||
setIcon(pos, val);
|
||||
}
|
||||
|
||||
// called when the main system modifies an object
|
||||
// this routine changes the associated markers to be the same color
|
||||
function colorChanged(elem) {
|
||||
function colorChanged (elem) {
|
||||
var color = elem.getAttribute('stroke');
|
||||
|
||||
$.each(mtypes, function(i, pos) {
|
||||
var marker = getLinked(elem, 'marker-'+pos);
|
||||
if (!marker) {return;}
|
||||
if (!marker.attributes.se_type) {return;} // not created by this extension
|
||||
$.each(mtypes, function (i, pos) {
|
||||
var marker = getLinked(elem, 'marker-' + pos);
|
||||
if (!marker) { return; }
|
||||
if (!marker.attributes.se_type) { return; } // not created by this extension
|
||||
var ch = marker.lastElementChild;
|
||||
if (!ch) {return;}
|
||||
if (!ch) { return; }
|
||||
var curfill = ch.getAttribute('fill');
|
||||
var curstroke = ch.getAttribute('stroke');
|
||||
if (curfill && curfill != 'none') {ch.setAttribute('fill', color);}
|
||||
if (curstroke && curstroke != 'none') {ch.setAttribute('stroke', color);}
|
||||
if (curfill && curfill !== 'none') { ch.setAttribute('fill', color); }
|
||||
if (curstroke && curstroke !== 'none') { ch.setAttribute('stroke', color); }
|
||||
});
|
||||
}
|
||||
|
||||
// called when the main system creates or modifies an object
|
||||
// primary purpose is create new markers for cloned objects
|
||||
function updateReferences(el) {
|
||||
function updateReferences (el) {
|
||||
$.each(mtypes, function (i, pos) {
|
||||
var id = marker_prefix + pos + '_' + el.id;
|
||||
var marker_name = 'marker-'+pos;
|
||||
var marker = getLinked(el, marker_name);
|
||||
if (!marker || !marker.attributes.se_type) {return;} // not created by this extension
|
||||
var url = el.getAttribute(marker_name);
|
||||
var id = markerPrefix + pos + '_' + el.id;
|
||||
var markerName = 'marker-' + pos;
|
||||
var marker = getLinked(el, markerName);
|
||||
if (!marker || !marker.attributes.se_type) { return; } // not created by this extension
|
||||
var url = el.getAttribute(markerName);
|
||||
if (url) {
|
||||
var len = el.id.length;
|
||||
var linkid = url.substr(-len-1, len);
|
||||
if (el.id != linkid) {
|
||||
var val = $('#'+pos + '_marker').attr('value');
|
||||
var linkid = url.substr(-len - 1, len);
|
||||
if (el.id !== linkid) {
|
||||
var val = $('#' + pos + '_marker').attr('value');
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(marker_name, "url(#" + id + ")");
|
||||
if (el.tagName === 'line' && pos == 'mid') {el = convertline(el);}
|
||||
S.call("changed", selElems);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
if (el.tagName === 'line' && pos === 'mid') { el = convertline(el); }
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// simulate a change event a text box that stores the current element's marker type
|
||||
function triggerTextEntry(pos, val) {
|
||||
$('#'+pos+'_marker').val(val);
|
||||
$('#'+pos+'_marker').change();
|
||||
function triggerTextEntry (pos, val) {
|
||||
$('#' + pos + '_marker').val(val);
|
||||
$('#' + pos + '_marker').change();
|
||||
// var txtbox = $('#'+pos+'_marker');
|
||||
// if (val.substr(0,1)=='\\') {txtbox.hide();}
|
||||
// else {txtbox.show();}
|
||||
}
|
||||
|
||||
function showTextPrompt(pos) {
|
||||
var def = $('#'+pos+'_marker').val();
|
||||
if (def.substr(0,1) === '\\') {def = '';}
|
||||
$.prompt('Enter text for ' + pos + ' marker', def , function(txt) {
|
||||
if (txt) {triggerTextEntry(pos, txt);}
|
||||
function showTextPrompt (pos) {
|
||||
var def = $('#' + pos + '_marker').val();
|
||||
if (def.substr(0, 1) === '\\') { def = ''; }
|
||||
$.prompt('Enter text for ' + pos + ' marker', def, function (txt) {
|
||||
if (txt) { triggerTextEntry(pos, txt); }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -406,66 +405,64 @@ svgEditor.addExtension("Markers", function(S) {
|
||||
}
|
||||
*/
|
||||
// callback function for a toolbar button click
|
||||
function setArrowFromButton(obj) {
|
||||
|
||||
function setArrowFromButton (obj) {
|
||||
var parts = this.id.split('_');
|
||||
var pos = parts[1];
|
||||
var val = parts[2];
|
||||
if (parts[3]) { val += '_' + parts[3];}
|
||||
|
||||
if (val != 'textmarker') {
|
||||
triggerTextEntry(pos, '\\'+val);
|
||||
if (parts[3]) { val += '_' + parts[3]; }
|
||||
|
||||
if (val !== 'textmarker') {
|
||||
triggerTextEntry(pos, '\\' + val);
|
||||
} else {
|
||||
showTextPrompt(pos);
|
||||
}
|
||||
}
|
||||
|
||||
function getTitle(lang, id) {
|
||||
var i, list = lang_list[lang];
|
||||
|
||||
function getTitle (lang, id) {
|
||||
var i, list = langList[lang];
|
||||
for (i in list) {
|
||||
if (list.hasOwnProperty(i) && list[i].id == id) {
|
||||
if (list.hasOwnProperty(i) && list[i].id === id) {
|
||||
return list[i].title;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// build the toolbar button array from the marker definitions
|
||||
// TODO: need to incorporate language specific titles
|
||||
function buildButtonList() {
|
||||
var buttons=[];
|
||||
function buildButtonList () {
|
||||
var buttons = [];
|
||||
// var i = 0;
|
||||
/*
|
||||
/*
|
||||
buttons.push({
|
||||
id:id_prefix + 'markers_off',
|
||||
title:'Turn off all markers',
|
||||
type:'context',
|
||||
id: idPrefix + 'markers_off',
|
||||
title: 'Turn off all markers',
|
||||
type: 'context',
|
||||
events: { 'click': setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
buttons.push({
|
||||
id:id_prefix + 'markers_dimension',
|
||||
title:'Dimension',
|
||||
type:'context',
|
||||
id: idPrefix + 'markers_dimension',
|
||||
title: 'Dimension',
|
||||
type: 'context',
|
||||
events: { 'click': setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
buttons.push({
|
||||
id:id_prefix + 'markers_label',
|
||||
title:'Label',
|
||||
type:'context',
|
||||
id: idPrefix + 'markers_label',
|
||||
title: 'Label',
|
||||
type: 'context',
|
||||
events: { 'click': setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
*/
|
||||
$.each(mtypes, function (k, pos) {
|
||||
var listname = pos + "_marker_list";
|
||||
var listname = pos + '_marker_list';
|
||||
var def = true;
|
||||
$.each(marker_types, function (id, v) {
|
||||
var title = getTitle('en', id);
|
||||
$.each(markerTypes, function (id, v) {
|
||||
var title = getTitle('en', String(id));
|
||||
buttons.push({
|
||||
id: id_prefix + pos + '_' + id,
|
||||
id: idPrefix + pos + '_' + id,
|
||||
svgicon: id,
|
||||
title: title,
|
||||
type: 'context',
|
||||
@@ -481,99 +478,98 @@ svgEditor.addExtension("Markers", function(S) {
|
||||
}
|
||||
|
||||
return {
|
||||
name: "Markers",
|
||||
svgicons: svgEditor.curConfig.extPath + "markers-icons.xml",
|
||||
name: 'Markers',
|
||||
svgicons: svgEditor.curConfig.extPath + 'markers-icons.xml',
|
||||
buttons: buildButtonList(),
|
||||
context_tools: [
|
||||
{
|
||||
type: "input",
|
||||
panel: "marker_panel",
|
||||
title: "Start marker",
|
||||
id: "start_marker",
|
||||
label: "s",
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
},{
|
||||
type: "button-select",
|
||||
panel: "marker_panel",
|
||||
title: getTitle('en', 'start_marker_list'),
|
||||
id: "start_marker_list",
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
},{
|
||||
type: "input",
|
||||
panel: "marker_panel",
|
||||
title: "Middle marker",
|
||||
id: "mid_marker",
|
||||
label: "m",
|
||||
defval: "",
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
},{
|
||||
type: "button-select",
|
||||
panel: "marker_panel",
|
||||
title: getTitle('en', 'mid_marker_list'),
|
||||
id: "mid_marker_list",
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
},{
|
||||
type: "input",
|
||||
panel: "marker_panel",
|
||||
title: "End marker",
|
||||
id: "end_marker",
|
||||
label: "e",
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
},{
|
||||
type: "button-select",
|
||||
panel: "marker_panel",
|
||||
title: getTitle('en', 'end_marker_list'),
|
||||
id: "end_marker_list",
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
} ],
|
||||
callback: function() {
|
||||
{
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'Start marker',
|
||||
id: 'start_marker',
|
||||
label: 's',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle('en', 'start_marker_list'),
|
||||
id: 'start_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'Middle marker',
|
||||
id: 'mid_marker',
|
||||
label: 'm',
|
||||
defval: '',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle('en', 'mid_marker_list'),
|
||||
id: 'mid_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'End marker',
|
||||
id: 'end_marker',
|
||||
label: 'e',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle('en', 'end_marker_list'),
|
||||
id: 'end_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}
|
||||
],
|
||||
callback: function () {
|
||||
$('#marker_panel').addClass('toolset').hide();
|
||||
|
||||
},
|
||||
addLangData: function(lang) {
|
||||
return { data: lang_list[lang] };
|
||||
addLangData: function (lang) {
|
||||
return { data: langList[lang] };
|
||||
},
|
||||
selectedChanged: function (opts) {
|
||||
// Use this to update the current selected elements
|
||||
// console.log('selectChanged',opts);
|
||||
selElems = opts.elems;
|
||||
|
||||
selectedChanged: function(opts) {
|
||||
// Use this to update the current selected elements
|
||||
//console.log('selectChanged',opts);
|
||||
selElems = opts.elems;
|
||||
var i = selElems.length;
|
||||
var markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
|
||||
var i = selElems.length;
|
||||
var marker_elems = ['line','path','polyline','polygon'];
|
||||
|
||||
while(i--) {
|
||||
var elem = selElems[i];
|
||||
if(elem && $.inArray(elem.tagName, marker_elems) !== -1) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && $.inArray(elem.tagName, markerElems) !== -1) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
elementChanged: function(opts) {
|
||||
//console.log('elementChanged',opts);
|
||||
var elem = opts.elems[0];
|
||||
if (elem && (
|
||||
elem.getAttribute("marker-start") ||
|
||||
elem.getAttribute("marker-mid") ||
|
||||
elem.getAttribute("marker-end")
|
||||
)) {
|
||||
colorChanged(elem);
|
||||
updateReferences(elem);
|
||||
elementChanged: function (opts) {
|
||||
// console.log('elementChanged',opts);
|
||||
var elem = opts.elems[0];
|
||||
if (elem && (
|
||||
elem.getAttribute('marker-start') ||
|
||||
elem.getAttribute('marker-mid') ||
|
||||
elem.getAttribute('marker-end')
|
||||
)) {
|
||||
colorChanged(elem);
|
||||
updateReferences(elem);
|
||||
}
|
||||
// changing_flag = false; // Not apparently in use
|
||||
}
|
||||
// changing_flag = false; // Not apparently in use
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals MathJax, svgEditor, svgCanvas, $*/
|
||||
/*jslint es5: true, todo: true, vars: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals MathJax, svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-mathjax.js
|
||||
*
|
||||
@@ -9,265 +9,256 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("mathjax", function() {'use strict';
|
||||
// Configuration of the MathJax extention.
|
||||
svgEditor.addExtension('mathjax', function () {
|
||||
'use strict';
|
||||
// Configuration of the MathJax extention.
|
||||
|
||||
// This will be added to the head tag before MathJax is loaded.
|
||||
var /*mathjaxConfiguration = '<script type="text/x-mathjax-config">\
|
||||
MathJax.Hub.Config({\
|
||||
extensions: ["tex2jax.js"],\
|
||||
jax: ["input/TeX","output/SVG"],\
|
||||
showProcessingMessages: true,\
|
||||
showMathMenu: false,\
|
||||
showMathMenuMSIE: false,\
|
||||
errorSettings: {\
|
||||
message: ["[Math Processing Error]"],\
|
||||
style: {color: "#CC0000", "font-style":"italic"}\
|
||||
},\
|
||||
elements: [],\
|
||||
tex2jax: {\
|
||||
ignoreClass: "tex2jax_ignore2", processClass: "tex2jax_process2",\
|
||||
},\
|
||||
TeX: {\
|
||||
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]\
|
||||
},\
|
||||
"SVG": {\
|
||||
}\
|
||||
});\
|
||||
</script>',*/
|
||||
// mathjaxSrc = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
|
||||
mathjaxSrcSecure = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG.js',
|
||||
math,
|
||||
locationX,
|
||||
locationY,
|
||||
mathjaxLoaded = false,
|
||||
uiStrings = svgEditor.uiStrings;
|
||||
// This will be added to the head tag before MathJax is loaded.
|
||||
var /* mathjaxConfiguration = '<script type="text/x-mathjax-config">\
|
||||
MathJax.Hub.Config({\
|
||||
extensions: ["tex2jax.js"],\
|
||||
jax: ["input/TeX","output/SVG"],\
|
||||
showProcessingMessages: true,\
|
||||
showMathMenu: false,\
|
||||
showMathMenuMSIE: false,\
|
||||
errorSettings: {\
|
||||
message: ["[Math Processing Error]"],\
|
||||
style: {color: "#CC0000", "font-style":"italic"}\
|
||||
},\
|
||||
elements: [],\
|
||||
tex2jax: {\
|
||||
ignoreClass: "tex2jax_ignore2", processClass: "tex2jax_process2",\
|
||||
},\
|
||||
TeX: {\
|
||||
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]\
|
||||
},\
|
||||
"SVG": {\
|
||||
}\
|
||||
});\
|
||||
</script>', */
|
||||
// mathjaxSrc = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
|
||||
mathjaxSrcSecure = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG.js',
|
||||
math,
|
||||
locationX,
|
||||
locationY,
|
||||
mathjaxLoaded = false,
|
||||
uiStrings = svgEditor.uiStrings;
|
||||
|
||||
// TODO: Implement language support. Move these uiStrings to the locale files and the code to the langReady callback.
|
||||
$.extend(uiStrings, {
|
||||
mathjax: {
|
||||
embed_svg: 'Save as mathematics',
|
||||
embed_mathml: 'Save as figure',
|
||||
svg_save_warning: 'The math will be transformed into a figure is manipulatable like everything else. You will not be able to manipulate the TeX-code anymore. ',
|
||||
mathml_save_warning: 'Advised. The math will be saved as a figure.',
|
||||
title: 'Mathematics code editor'
|
||||
}
|
||||
});
|
||||
// TODO: Implement language support. Move these uiStrings to the locale files and the code to the langReady callback.
|
||||
$.extend(uiStrings, {
|
||||
mathjax: {
|
||||
embed_svg: 'Save as mathematics',
|
||||
embed_mathml: 'Save as figure',
|
||||
svg_save_warning: 'The math will be transformed into a figure is manipulatable like everything else. You will not be able to manipulate the TeX-code anymore. ',
|
||||
mathml_save_warning: 'Advised. The math will be saved as a figure.',
|
||||
title: 'Mathematics code editor'
|
||||
}
|
||||
});
|
||||
|
||||
function saveMath () {
|
||||
var code = $('#mathjax_code_textarea').val();
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
|
||||
function saveMath() {
|
||||
var code = $('#mathjax_code_textarea').val();
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
* every symbol (glymph) you need only once. These are saved in a <svg> on
|
||||
* the top of your html document, just under the body tag. Each glymph has
|
||||
* its unique id and is saved as a <path> in the <defs> tag of the <svg>
|
||||
*
|
||||
* Then when the symbols are needed in the rest of your html document they
|
||||
* are refferd to by a <use> tag.
|
||||
* Because of bug 1076 we can't just grab the defs tag on the top and add it
|
||||
* to your formula's <svg> and copy the lot. So we have to replace each
|
||||
* <use> tag by it's <path>.
|
||||
*/
|
||||
MathJax.Hub.queue.Push(
|
||||
function () {
|
||||
var mathjaxMath = $('.MathJax_SVG');
|
||||
var svg = $(mathjaxMath.html());
|
||||
svg.find('use').each(function () {
|
||||
var x, y, id, transform;
|
||||
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
* every symbol (glymph) you need only once. These are saved in a <svg> on
|
||||
* the top of your html document, just under the body tag. Each glymph has
|
||||
* its unique id and is saved as a <path> in the <defs> tag of the <svg>
|
||||
*
|
||||
* Then when the symbols are needed in the rest of your html document they
|
||||
* are refferd to by a <use> tag.
|
||||
* Because of bug 1076 we can't just grab the defs tag on the top and add it
|
||||
* to your formula's <svg> and copy the lot. So we have to replace each
|
||||
* <use> tag by it's <path>.
|
||||
*/
|
||||
MathJax.Hub.queue.Push(
|
||||
function() {
|
||||
var mathjaxMath = $('.MathJax_SVG');
|
||||
var svg = $(mathjaxMath.html());
|
||||
svg.find('use').each(function() {
|
||||
var x, y, id, transform;
|
||||
// TODO: find a less pragmatic and more elegant solution to this.
|
||||
if ($(this).attr('href')) {
|
||||
id = $(this).attr('href').slice(1); // Works in Chrome.
|
||||
} else {
|
||||
id = $(this).attr('xlink:href').slice(1); // Works in Firefox.
|
||||
}
|
||||
|
||||
// TODO: find a less pragmatic and more elegant solution to this.
|
||||
if ($(this).attr('href')) {
|
||||
id = $(this).attr('href').slice(1); // Works in Chrome.
|
||||
} else {
|
||||
id = $(this).attr('xlink:href').slice(1); // Works in Firefox.
|
||||
}
|
||||
var glymph = $('#' + id).clone().removeAttr('id');
|
||||
x = $(this).attr('x');
|
||||
y = $(this).attr('y');
|
||||
transform = $(this).attr('transform');
|
||||
if (transform && (x || y)) {
|
||||
glymph.attr('transform', transform + ' translate(' + x + ',' + y + ')');
|
||||
} else if (transform) {
|
||||
glymph.attr('transform', transform);
|
||||
} else if (x || y) {
|
||||
glymph.attr('transform', 'translate(' + x + ',' + y + ')');
|
||||
}
|
||||
$(this).replaceWith(glymph);
|
||||
});
|
||||
// Remove the style tag because it interferes with SVG-Edit.
|
||||
svg.removeAttr('style');
|
||||
svg.attr('xmlns', 'http://www.w3.org/2000/svg');
|
||||
svgCanvas.importSvgString($('<div>').append(svg.clone()).html(), true);
|
||||
svgCanvas.ungroupSelectedElement();
|
||||
// TODO: To undo the adding of the Formula you now have to undo twice.
|
||||
// This should only be once!
|
||||
svgCanvas.moveSelectedElements(locationX, locationY, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var glymph = $('#' + id).clone().removeAttr('id');
|
||||
x = $(this).attr('x');
|
||||
y = $(this).attr('y');
|
||||
transform = $(this).attr('transform');
|
||||
if (transform && ( x || y )) {
|
||||
glymph.attr('transform', transform + ' translate(' + x + ',' + y + ')');
|
||||
}
|
||||
else if (transform) {
|
||||
glymph.attr('transform', transform);
|
||||
}
|
||||
else if (x || y) {
|
||||
glymph.attr('transform', 'translate(' + x + ',' + y + ')');
|
||||
}
|
||||
$(this).replaceWith(glymph);
|
||||
});
|
||||
// Remove the style tag because it interferes with SVG-Edit.
|
||||
svg.removeAttr('style');
|
||||
svg.attr('xmlns', 'http://www.w3.org/2000/svg');
|
||||
svgCanvas.importSvgString($('<div>').append(svg.clone()).html(), true);
|
||||
svgCanvas.ungroupSelectedElement();
|
||||
// TODO: To undo the adding of the Formula you now have to undo twice.
|
||||
// This should only be once!
|
||||
svgCanvas.moveSelectedElements(locationX, locationY, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
return {
|
||||
name: 'MathJax',
|
||||
svgicons: svgEditor.curConfig.extPath + 'mathjax-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
title: 'Add Mathematics',
|
||||
events: {
|
||||
click: function () {
|
||||
// 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="http://en.wikipedia.org/wiki/Help:Displaying_a_formula" target="_blank">TeX</a> code.</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
).insertAfter('#svg_prefs').hide();
|
||||
|
||||
return {
|
||||
name: "MathJax",
|
||||
svgicons: svgEditor.curConfig.extPath + "mathjax-icons.xml",
|
||||
buttons: [{
|
||||
id: "tool_mathjax",
|
||||
type: "mode",
|
||||
title: "Add Mathematics",
|
||||
events: {
|
||||
click: function() {
|
||||
// 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) {
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({cancel: 'button,fieldset', containment: 'window'});
|
||||
|
||||
$('<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="http://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();
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true))
|
||||
.on('click touched', function () {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({cancel: 'button,fieldset', containment: 'window'});
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true))
|
||||
.on('click touched', function () {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true))
|
||||
.on("click touched", function() {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true))
|
||||
.on("click touched", function() {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
// Now get (and run) the MathJax Library.
|
||||
$.getScript(mathjaxSrcSecure)
|
||||
.done(function (script, textStatus) {
|
||||
// When MathJax is loaded get the div where the math will be rendered.
|
||||
MathJax.Hub.queue.Push(function () {
|
||||
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
})
|
||||
// If it fails.
|
||||
.fail(function () {
|
||||
console.log('Failed loadeing MathJax.');
|
||||
$.alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
});
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode('mathjax');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
mouseDown: function () {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
return {started: true};
|
||||
}
|
||||
},
|
||||
mouseUp: function (opts) {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
// Get the coordinates from your mouse.
|
||||
var zoom = svgCanvas.getZoom();
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
locationX = opts.mouse_x / zoom;
|
||||
locationY = opts.mouse_y / zoom;
|
||||
|
||||
// Now get (and run) the MathJax Library.
|
||||
$.getScript(mathjaxSrcSecure)
|
||||
.done(function(script, textStatus) {
|
||||
$('#mathjax').show();
|
||||
return {started: false}; // Otherwise the last selected object dissapears.
|
||||
}
|
||||
},
|
||||
callback: function () {
|
||||
$('<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');
|
||||
|
||||
// When MathJax is loaded get the div where the math will be rendered.
|
||||
MathJax.Hub.queue.Push(function() {
|
||||
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
|
||||
})
|
||||
// If it fails.
|
||||
.fail(function() {
|
||||
console.log("Failed loadeing MathJax.");
|
||||
$.alert("Failed loading MathJax. You will not be able to change the mathematics.");
|
||||
});
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode("mathjax");
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
mouseDown: function() {
|
||||
if (svgCanvas.getMode() === "mathjax") {
|
||||
return {started: true};
|
||||
}
|
||||
},
|
||||
mouseUp: function(opts) {
|
||||
if (svgCanvas.getMode() === "mathjax") {
|
||||
// Get the coordinates from your mouse.
|
||||
var zoom = svgCanvas.getZoom();
|
||||
// Get the actual coordinate by dividing by the zoom value
|
||||
locationX = opts.mouse_x / zoom;
|
||||
locationY = opts.mouse_y / zoom;
|
||||
|
||||
$('#mathjax').show();
|
||||
return {started: false}; // Otherwise the last selected object dissapears.
|
||||
}
|
||||
},
|
||||
callback: function() {
|
||||
$('<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');
|
||||
}
|
||||
};
|
||||
// Add the MathJax configuration.
|
||||
// $(mathjaxConfiguration).appendTo('head');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, $ */
|
||||
/*jslint es5: true, vars: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, $ */
|
||||
/*
|
||||
* ext-overview_window.js
|
||||
*
|
||||
@@ -10,11 +10,12 @@
|
||||
*/
|
||||
|
||||
var overviewWindowGlobals = {};
|
||||
svgEditor.addExtension("overview_window", function() { 'use strict';
|
||||
svgEditor.addExtension('overview_window', function () {
|
||||
'use strict';
|
||||
// Disabled in Chrome 48-, see https://github.com/SVG-Edit/svgedit/issues/26 and
|
||||
// https://code.google.com/p/chromium/issues/detail?id=565120.
|
||||
if (svgedit.browser.isChrome()) {
|
||||
var verIndex = navigator.userAgent.indexOf("Chrome/") + 7;
|
||||
var verIndex = navigator.userAgent.indexOf('Chrome/') + 7;
|
||||
var chromeVersion = parseInt(navigator.userAgent.substring(verIndex), 10);
|
||||
if (chromeVersion < 49) {
|
||||
return;
|
||||
@@ -22,130 +23,129 @@ svgEditor.addExtension("overview_window", function() { 'use strict';
|
||||
}
|
||||
|
||||
// Define and insert the base html element.
|
||||
var propsWindowHtml= "\
|
||||
<div id=\"overview_window_content_pane\" style=\" width:100%; word-wrap:break-word; display:inline-block; margin-top:20px;\">\
|
||||
<div id=\"overview_window_content\" style=\"position:relative; left:12px; top:0px;\">\
|
||||
<div style=\"background-color:#A0A0A0; display:inline-block; overflow:visible;\">\
|
||||
<svg id=\"overviewMiniView\" width=\"150\" height=\"100\" x=\"0\" y=\"0\" viewBox=\"0 0 4800 3600\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\
|
||||
<use x=\"0\" y=\"0\" xlink:href=\"#svgroot\"> </use>\
|
||||
</svg>\
|
||||
<div id=\"overview_window_view_box\" style=\"min-width:50px; min-height:50px; position:absolute; top:30px; left:30px; z-index:5; background-color:rgba(255,0,102,0.3);\">\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>";
|
||||
$("#sidepanels").append(propsWindowHtml);
|
||||
var propsWindowHtml =
|
||||
'<div id="overview_window_content_pane" style="width:100%; word-wrap:break-word; display:inline-block; margin-top:20px;">' +
|
||||
'<div id="overview_window_content" style="position:relative; left:12px; top:0px;">' +
|
||||
'<div style="background-color:#A0A0A0; display:inline-block; overflow:visible;">' +
|
||||
'<svg id="overviewMiniView" width="150" height="100" x="0" y="0" viewBox="0 0 4800 3600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
|
||||
'<use x="0" y="0" xlink:href="#svgroot"> </use>' +
|
||||
'</svg>' +
|
||||
'<div id="overview_window_view_box" style="min-width:50px; min-height:50px; position:absolute; top:30px; left:30px; z-index:5; background-color:rgba(255,0,102,0.3);">' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
$('#sidepanels').append(propsWindowHtml);
|
||||
|
||||
// Define dynamic animation of the view box.
|
||||
var updateViewBox = function(){
|
||||
var portHeight=parseFloat($("#workarea").css("height"));
|
||||
var portWidth=parseFloat($("#workarea").css("width"));
|
||||
var portX=$("#workarea").scrollLeft();
|
||||
var portY=$("#workarea").scrollTop();
|
||||
var windowWidth=parseFloat($("#svgcanvas").css("width"));
|
||||
var windowHeight=parseFloat($("#svgcanvas").css("height"));
|
||||
var overviewWidth=$("#overviewMiniView").attr("width");
|
||||
var overviewHeight=$("#overviewMiniView").attr("height");
|
||||
|
||||
var viewBoxX=portX/windowWidth*overviewWidth;
|
||||
var viewBoxY=portY/windowHeight*overviewHeight;
|
||||
var viewBoxWidth=portWidth/windowWidth*overviewWidth;
|
||||
var viewBoxHeight=portHeight/windowHeight*overviewHeight;
|
||||
|
||||
$("#overview_window_view_box").css("min-width",viewBoxWidth+"px");
|
||||
$("#overview_window_view_box").css("min-height",viewBoxHeight+"px");
|
||||
$("#overview_window_view_box").css("top",viewBoxY+"px");
|
||||
$("#overview_window_view_box").css("left",viewBoxX+"px");
|
||||
var updateViewBox = function () {
|
||||
var portHeight = parseFloat($('#workarea').css('height'));
|
||||
var portWidth = parseFloat($('#workarea').css('width'));
|
||||
var portX = $('#workarea').scrollLeft();
|
||||
var portY = $('#workarea').scrollTop();
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
|
||||
var viewBoxX = portX / windowWidth * overviewWidth;
|
||||
var viewBoxY = portY / windowHeight * overviewHeight;
|
||||
var viewBoxWidth = portWidth / windowWidth * overviewWidth;
|
||||
var viewBoxHeight = portHeight / windowHeight * overviewHeight;
|
||||
|
||||
$('#overview_window_view_box').css('min-width', viewBoxWidth + 'px');
|
||||
$('#overview_window_view_box').css('min-height', viewBoxHeight + 'px');
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
};
|
||||
$("#workarea").scroll(function(){
|
||||
if(!(overviewWindowGlobals.viewBoxDragging)){
|
||||
$('#workarea').scroll(function () {
|
||||
if (!(overviewWindowGlobals.viewBoxDragging)) {
|
||||
updateViewBox();
|
||||
}
|
||||
});
|
||||
$("#workarea").resize(updateViewBox);
|
||||
$('#workarea').resize(updateViewBox);
|
||||
updateViewBox();
|
||||
|
||||
|
||||
// Compensate for changes in zoom and canvas size.
|
||||
var updateViewDimensions= function(){
|
||||
var viewWidth=$("#svgroot").attr("width");
|
||||
var viewHeight=$("#svgroot").attr("height");
|
||||
var viewX=640;
|
||||
var viewY=480;
|
||||
|
||||
if(svgedit.browser.isIE())
|
||||
{
|
||||
var updateViewDimensions = function () {
|
||||
var viewWidth = $('#svgroot').attr('width');
|
||||
var viewHeight = $('#svgroot').attr('height');
|
||||
var viewX = 640;
|
||||
var viewY = 480;
|
||||
|
||||
if (svgedit.browser.isIE()) {
|
||||
// This has only been tested with Firefox 10 and IE 9 (without chrome frame).
|
||||
// I am not sure if if is Firefox or IE that is being non compliant here.
|
||||
// Either way the one that is noncompliant may become more compliant later.
|
||||
//TAG:HACK
|
||||
//TAG:VERSION_DEPENDENT
|
||||
//TAG:BROWSER_SNIFFING
|
||||
viewX=0;
|
||||
viewY=0;
|
||||
// TAG:HACK
|
||||
// TAG:VERSION_DEPENDENT
|
||||
// TAG:BROWSER_SNIFFING
|
||||
viewX = 0;
|
||||
viewY = 0;
|
||||
}
|
||||
|
||||
var svgWidth_old=$("#overviewMiniView").attr("width");
|
||||
var svgHeight_new=viewHeight/viewWidth*svgWidth_old;
|
||||
$("#overviewMiniView").attr("viewBox",viewX+" "+viewY+" "+viewWidth+" "+viewHeight);
|
||||
$("#overviewMiniView").attr("height",svgHeight_new);
|
||||
|
||||
var svgWidthOld = $('#overviewMiniView').attr('width');
|
||||
var svgHeightNew = viewHeight / viewWidth * svgWidthOld;
|
||||
$('#overviewMiniView').attr('viewBox', viewX + ' ' + viewY + ' ' + viewWidth + ' ' + viewHeight);
|
||||
$('#overviewMiniView').attr('height', svgHeightNew);
|
||||
updateViewBox();
|
||||
};
|
||||
updateViewDimensions();
|
||||
|
||||
// Set up the overview window as a controller for the view port.
|
||||
overviewWindowGlobals.viewBoxDragging=false;
|
||||
var updateViewPortFromViewBox = function(){
|
||||
|
||||
var windowWidth =parseFloat($("#svgcanvas").css("width" ));
|
||||
var windowHeight=parseFloat($("#svgcanvas").css("height"));
|
||||
var overviewWidth =$("#overviewMiniView").attr("width" );
|
||||
var overviewHeight=$("#overviewMiniView").attr("height");
|
||||
var viewBoxX=parseFloat($("#overview_window_view_box").css("left"));
|
||||
var viewBoxY=parseFloat($("#overview_window_view_box").css("top" ));
|
||||
|
||||
var portX=viewBoxX/overviewWidth *windowWidth;
|
||||
var portY=viewBoxY/overviewHeight*windowHeight;
|
||||
|
||||
$("#workarea").scrollLeft(portX);
|
||||
$("#workarea").scrollTop(portY);
|
||||
// Set up the overview window as a controller for the view port.
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
var updateViewPortFromViewBox = function () {
|
||||
var windowWidth = parseFloat($('#svgcanvas').css('width'));
|
||||
var windowHeight = parseFloat($('#svgcanvas').css('height'));
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxX = parseFloat($('#overview_window_view_box').css('left'));
|
||||
var viewBoxY = parseFloat($('#overview_window_view_box').css('top'));
|
||||
|
||||
var portX = viewBoxX / overviewWidth * windowWidth;
|
||||
var portY = viewBoxY / overviewHeight * windowHeight;
|
||||
|
||||
$('#workarea').scrollLeft(portX);
|
||||
$('#workarea').scrollTop(portY);
|
||||
};
|
||||
$( "#overview_window_view_box" ).draggable({ containment: "parent"
|
||||
,drag: updateViewPortFromViewBox
|
||||
,start:function(){overviewWindowGlobals.viewBoxDragging=true; }
|
||||
,stop :function(){overviewWindowGlobals.viewBoxDragging=false;}
|
||||
});
|
||||
$("#overviewMiniView").click(function(evt){
|
||||
$('#overview_window_view_box').draggable({
|
||||
containment: 'parent',
|
||||
drag: updateViewPortFromViewBox,
|
||||
start: function () { overviewWindowGlobals.viewBoxDragging = true; },
|
||||
stop: function () { overviewWindowGlobals.viewBoxDragging = false; }
|
||||
});
|
||||
$('#overviewMiniView').click(function (evt) {
|
||||
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
||||
var mouseX=(evt.offsetX || evt.originalEvent.layerX);
|
||||
var mouseY=(evt.offsetY || evt.originalEvent.layerY);
|
||||
var overviewWidth =$("#overviewMiniView").attr("width" );
|
||||
var overviewHeight=$("#overviewMiniView").attr("height");
|
||||
var viewBoxWidth =parseFloat($("#overview_window_view_box").css("min-width" ));
|
||||
var viewBoxHeight=parseFloat($("#overview_window_view_box").css("min-height"));
|
||||
|
||||
var viewBoxX=mouseX - 0.5 * viewBoxWidth;
|
||||
var viewBoxY=mouseY- 0.5 * viewBoxHeight;
|
||||
//deal with constraints
|
||||
if(viewBoxX<0){
|
||||
viewBoxX=0;
|
||||
var mouseX = (evt.offsetX || evt.originalEvent.layerX);
|
||||
var mouseY = (evt.offsetY || evt.originalEvent.layerY);
|
||||
var overviewWidth = $('#overviewMiniView').attr('width');
|
||||
var overviewHeight = $('#overviewMiniView').attr('height');
|
||||
var viewBoxWidth = parseFloat($('#overview_window_view_box').css('min-width'));
|
||||
var viewBoxHeight = parseFloat($('#overview_window_view_box').css('min-height'));
|
||||
|
||||
var viewBoxX = mouseX - 0.5 * viewBoxWidth;
|
||||
var viewBoxY = mouseY - 0.5 * viewBoxHeight;
|
||||
// deal with constraints
|
||||
if (viewBoxX < 0) {
|
||||
viewBoxX = 0;
|
||||
}
|
||||
if(viewBoxY<0){
|
||||
viewBoxY=0;
|
||||
if (viewBoxY < 0) {
|
||||
viewBoxY = 0;
|
||||
}
|
||||
if(viewBoxX+viewBoxWidth>overviewWidth){
|
||||
viewBoxX=overviewWidth-viewBoxWidth;
|
||||
if (viewBoxX + viewBoxWidth > overviewWidth) {
|
||||
viewBoxX = overviewWidth - viewBoxWidth;
|
||||
}
|
||||
if(viewBoxY+viewBoxHeight>overviewHeight){
|
||||
viewBoxY=overviewHeight-viewBoxHeight;
|
||||
if (viewBoxY + viewBoxHeight > overviewHeight) {
|
||||
viewBoxY = overviewHeight - viewBoxHeight;
|
||||
}
|
||||
|
||||
$("#overview_window_view_box").css("top",viewBoxY+"px");
|
||||
$("#overview_window_view_box").css("left",viewBoxX+"px");
|
||||
|
||||
$('#overview_window_view_box').css('top', viewBoxY + 'px');
|
||||
$('#overview_window_view_box').css('left', viewBoxX + 'px');
|
||||
updateViewPortFromViewBox();
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
name: "overview window",
|
||||
name: 'overview window',
|
||||
canvasUpdated: updateViewDimensions,
|
||||
workareaResized: updateViewBox
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*globals svgEditor, svgCanvas*/
|
||||
/*jslint eqeq: true*/
|
||||
/* globals svgEditor, svgCanvas */
|
||||
/*
|
||||
* ext-panning.js
|
||||
*
|
||||
@@ -8,12 +7,13 @@
|
||||
* Copyright(c) 2013 Luis Aguirre
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
This is a very basic SVG-Edit extension to let tablet/mobile devices panning without problem
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('ext-panning', function() {'use strict';
|
||||
svgEditor.addExtension('ext-panning', function () {
|
||||
'use strict';
|
||||
return {
|
||||
name: 'Extension Panning',
|
||||
svgicons: svgEditor.curConfig.extPath + 'ext-panning.xml',
|
||||
@@ -22,19 +22,19 @@ svgEditor.addExtension('ext-panning', function() {'use strict';
|
||||
type: 'mode',
|
||||
title: 'Panning',
|
||||
events: {
|
||||
click: function() {
|
||||
click: function () {
|
||||
svgCanvas.setMode('ext-panning');
|
||||
}
|
||||
}
|
||||
}],
|
||||
mouseDown: function() {
|
||||
if (svgCanvas.getMode() == 'ext-panning') {
|
||||
mouseDown: function () {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(true);
|
||||
return {started: true};
|
||||
}
|
||||
},
|
||||
mouseUp: function() {
|
||||
if (svgCanvas.getMode() == 'ext-panning') {
|
||||
mouseUp: function () {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(false);
|
||||
return {
|
||||
keep: false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="ext-panning">
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
|
||||
<path fill="#7f0000" stroke="#000000" stroke-width="10" d="m1.00037,150.34581l55.30305,-55.30267l0,27.65093l22.17356,0l0,-44.21833l44.21825,0l0,-22.17357l-27.65095,0l55.30267,-55.30292l55.3035,55.30292l-27.65175,0l0,22.17357l44.21835,0l0,44.21833l22.17357,0l0,-27.65093l55.30345,55.30267l-55.30345,55.3035l0,-27.65175l-22.17357,0l0,44.21834l-44.21835,0l0,22.17355l27.65175,0l-55.3035,55.30348l-55.30267,-55.30348l27.65095,0l0,-22.17355l-44.21825,0l0,-44.21834l-22.17356,0l0,27.65175l-55.30305,-55.3035z"></path>
|
||||
<path fill="#7f0000" stroke="#000000" stroke-width="10" d="m1.00037,150.34581l55.30305,-55.30267l0,27.65093l22.17356,0l0,-44.21833l44.21825,0l0,-22.17357l-27.65095,0l55.30267,-55.30292l55.3035,55.30292l-27.65175,0l0,22.17357l44.21835,0l0,44.21833l22.17357,0l0,-27.65093l55.30345,55.30267l-55.30345,55.3035l0,-27.65175l-22.17357,0l0,44.21834l-44.21835,0l0,22.17355l27.65175,0l-55.3035,55.30348l-55.30267,-55.30348l27.65095,0l0,-22.17355l-44.21825,0l0,-44.21834l-22.17356,0l0,27.65175l-55.30305,-55.3035z"></path>
|
||||
</svg>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 724 B |
@@ -1,22 +1,22 @@
|
||||
/*globals $, svgCanvas, svgEditor*/
|
||||
/*jslint regexp:true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals $, svgCanvas, svgEditor */
|
||||
// TODO: Might add support for "exportImage" custom
|
||||
// handler as in "ext-server_opensave.js" (and in savefile.php)
|
||||
|
||||
svgEditor.addExtension("php_savefile", {
|
||||
callback: function() {
|
||||
svgEditor.addExtension('php_savefile', {
|
||||
callback: function () {
|
||||
'use strict';
|
||||
function getFileNameFromTitle () {
|
||||
var title = svgCanvas.getDocumentTitle();
|
||||
return $.trim(title);
|
||||
}
|
||||
var save_svg_action = svgEditor.curConfig.extPath + 'savefile.php';
|
||||
var saveSvgAction = svgEditor.curConfig.extPath + 'savefile.php';
|
||||
svgEditor.setCustomHandlers({
|
||||
save: function(win, data) {
|
||||
save: function (win, data) {
|
||||
var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data,
|
||||
filename = getFileNameFromTitle();
|
||||
|
||||
$.post(save_svg_action, {output_svg: svg, filename: filename});
|
||||
$.post(saveSvgAction, {output_svg: svg, filename: filename});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgCanvas, svgedit, $*/
|
||||
/*jslint vars: true, eqeq: true, todo: true */
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-polygon.js
|
||||
*
|
||||
@@ -8,9 +8,10 @@
|
||||
* All rights reserved
|
||||
*
|
||||
*/
|
||||
svgEditor.addExtension("polygon", function(S) {'use strict';
|
||||
svgEditor.addExtension('polygon', function (S) {
|
||||
'use strict';
|
||||
|
||||
var // NS = svgedit.NS,
|
||||
var // NS = svgedit.NS,
|
||||
// svgcontent = S.svgcontent,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
selElems,
|
||||
@@ -18,53 +19,51 @@ svgEditor.addExtension("polygon", function(S) {'use strict';
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID, modeChangeG,
|
||||
// edg = 0,
|
||||
// undoCommand = "Not image";
|
||||
// undoCommand = 'Not image';
|
||||
started, newFO;
|
||||
|
||||
// var ccZoom;
|
||||
// var wEl, hEl;
|
||||
// var wOffset, hOffset;
|
||||
// var ccRBG;
|
||||
var ccRgbEl;
|
||||
// var ccOpacity;
|
||||
// var brushW, brushH;
|
||||
var shape;
|
||||
|
||||
// var ccDebug = document.getElementById('debugpanel');
|
||||
|
||||
/* var properlySourceSizeTextArea = function(){
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
var height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
}; */
|
||||
function showPanel(on){
|
||||
var fc_rules = $('#fc_rules');
|
||||
if (!fc_rules.length) {
|
||||
fc_rules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fc_rules.text(!on ? "" : " #tool_topath { display: none !important; }");
|
||||
$('#polygon_panel').toggle(on);
|
||||
}
|
||||
|
||||
|
||||
// var ccZoom;
|
||||
// var wEl, hEl;
|
||||
// var wOffset, hOffset;
|
||||
// var ccRBG;
|
||||
// var ccOpacity;
|
||||
// var brushW, brushH;
|
||||
|
||||
// var ccDebug = document.getElementById('debugpanel');
|
||||
|
||||
/* var properlySourceSizeTextArea = function(){
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
var height = $('#svg_source_container').height() - 80;
|
||||
$('#svg_source_textarea').css('height', height);
|
||||
}; */
|
||||
function showPanel (on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#polygon_panel').toggle(on);
|
||||
}
|
||||
|
||||
/*
|
||||
function toggleSourceButtons(on){
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#polygon_save, #polygon_cancel').toggle(on);
|
||||
}
|
||||
function toggleSourceButtons(on){
|
||||
$('#tool_source_save, #tool_source_cancel').toggle(!on);
|
||||
$('#polygon_save, #polygon_cancel').toggle(on);
|
||||
}
|
||||
*/
|
||||
|
||||
function setAttr(attr, val){
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call("changed", selElems);
|
||||
}
|
||||
|
||||
function cot(n){
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
|
||||
function sec(n){
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
|
||||
function setAttr (attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
function cot (n) {
|
||||
return 1 / Math.tan(n);
|
||||
}
|
||||
|
||||
function sec (n) {
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtained from http://code.google.com/p/passenger-top/source/browse/instiki/public/svg-edit/editor/extensions/ext-itex.js?r=3
|
||||
@@ -95,13 +94,13 @@ svgEditor.addExtension("polygon", function(S) {'use strict';
|
||||
$.post(ajaxEndpoint, {'tex': tex, 'display': 'inline'}, function(data){
|
||||
var children = data.documentElement.childNodes;
|
||||
while (children.length > 0) {
|
||||
mrow.appendChild(svgdoc.adoptNode(children[0], true));
|
||||
mrow.appendChild(svgdoc.adoptNode(children[0], true));
|
||||
}
|
||||
S.sanitizeSvg(math);
|
||||
S.call("changed", [elt]);
|
||||
S.call('changed', [elt]);
|
||||
});
|
||||
elt.replaceChild(math, elt.firstChild);
|
||||
S.call("changed", [elt]);
|
||||
S.call('changed', [elt]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
@@ -111,184 +110,177 @@ svgEditor.addExtension("polygon", function(S) {'use strict';
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return {
|
||||
name: "polygon",
|
||||
svgicons: svgEditor.curConfig.extPath + "polygon-icons.svg",
|
||||
buttons: [{
|
||||
id: "tool_polygon",
|
||||
type: "mode",
|
||||
title: "Polygon Tool",
|
||||
position: 11,
|
||||
events: {
|
||||
'click': function(){
|
||||
svgCanvas.setMode('polygon');
|
||||
return {
|
||||
name: 'polygon',
|
||||
svgicons: svgEditor.curConfig.extPath + 'polygon-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_polygon',
|
||||
type: 'mode',
|
||||
title: 'Polygon Tool',
|
||||
position: 11,
|
||||
events: {
|
||||
'click': function () {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: "input",
|
||||
panel: "polygon_panel",
|
||||
title: "Number of Sides",
|
||||
id: "polySides",
|
||||
label: "sides",
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function(){
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
callback: function(){
|
||||
|
||||
$('#polygon_panel').hide();
|
||||
|
||||
var endChanges = function(){
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function(){
|
||||
// Create source save/cancel buttons
|
||||
var save = $('#tool_source_save').clone().hide().attr('id', 'polygon_save').unbind().appendTo("#tool_source_back").click(function(){
|
||||
|
||||
if (!editingitex) {
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'polySides',
|
||||
label: 'sides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function () {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
callback: function () {
|
||||
$('#polygon_panel').hide();
|
||||
|
||||
var endChanges = function () {
|
||||
};
|
||||
|
||||
// TODO: Needs to be done after orig icon loads
|
||||
setTimeout(function () {
|
||||
// Create source save/cancel buttons
|
||||
/* var 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())) {
|
||||
$.confirm("Errors found. Revert to original?", function(ok){
|
||||
if (!ok) {
|
||||
/*
|
||||
if (!setItexString($('#svg_source_textarea').val())) {
|
||||
$.confirm('Errors found. Revert to original?', function (ok) {
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
endChanges();
|
||||
});
|
||||
}
|
||||
else {
|
||||
endChanges();
|
||||
}
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
var cancel = $('#tool_source_cancel').clone().hide().attr('id', 'polygon_cancel').unbind().appendTo("#tool_source_back").click(function(){
|
||||
endChanges();
|
||||
});
|
||||
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function(opts){
|
||||
// var e = opts.event;
|
||||
var rgb = svgCanvas.getColor("fill");
|
||||
ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor("stroke");
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() == "polygon") {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
"element": "polygon",
|
||||
"attr": {
|
||||
"cx": opts.start_x,
|
||||
"cy": opts.start_y,
|
||||
"id": S.getNextId(),
|
||||
"shape": "regularPoly",
|
||||
"sides": document.getElementById("polySides").value,
|
||||
"orient": "x",
|
||||
"edge": 0,
|
||||
"fill": rgb,
|
||||
"strokecolor": sRgb,
|
||||
"strokeWidth": sWidth
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function(opts){
|
||||
if (!started) {
|
||||
return;
|
||||
endChanges();
|
||||
});
|
||||
} else { */
|
||||
endChanges();
|
||||
// }
|
||||
// setSelectMode();
|
||||
});
|
||||
|
||||
/* var cancel = */ $('#tool_source_cancel').clone().hide().attr('id', 'polygon_cancel').unbind().appendTo('#tool_source_back').click(function () {
|
||||
endChanges();
|
||||
});
|
||||
}, 3000);
|
||||
},
|
||||
mouseDown: function (opts) {
|
||||
// var e = opts.event;
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// var ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
'element': 'polygon',
|
||||
'attr': {
|
||||
'cx': opts.start_x,
|
||||
'cy': opts.start_y,
|
||||
'id': S.getNextId(),
|
||||
'shape': 'regularPoly',
|
||||
'sides': document.getElementById('polySides').value,
|
||||
'orient': 'x',
|
||||
'edge': 0,
|
||||
'fill': rgb,
|
||||
'strokecolor': sRgb,
|
||||
'strokeWidth': sWidth
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
if (svgCanvas.getMode() == "polygon") {
|
||||
// var e = opts.event;
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var c = $(newFO).attr(["cx", "cy", "sides", "orient", "fill", "strokecolor", "strokeWidth"]);
|
||||
var cx = c.cx, cy = c.cy, fill = c.fill, strokecolor = c.strokecolor, strokewidth = c.strokeWidth, sides = c.sides,
|
||||
},
|
||||
mouseMove: function (opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
// var e = opts.event;
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var c = $(newFO).attr(['cx', 'cy', 'sides', 'orient', 'fill', 'strokecolor', 'strokeWidth']);
|
||||
var cx = c.cx, cy = c.cy, fill = c.fill, strokecolor = c.strokecolor, strokewidth = c.strokeWidth, sides = c.sides,
|
||||
// orient = c.orient,
|
||||
edg = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
newFO.setAttributeNS(null, "edge", edg);
|
||||
|
||||
var inradius = (edg / 2) * cot(Math.PI / sides);
|
||||
var circumradius = inradius * sec(Math.PI / sides);
|
||||
var points = '';
|
||||
newFO.setAttributeNS(null, 'edge', edg);
|
||||
|
||||
var inradius = (edg / 2) * cot(Math.PI / sides);
|
||||
var circumradius = inradius * sec(Math.PI / sides);
|
||||
var points = '';
|
||||
var s;
|
||||
for (s = 0; sides >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * s / sides;
|
||||
x = (circumradius * Math.cos(angle)) + cx;
|
||||
y = (circumradius * Math.sin(angle)) + cy;
|
||||
|
||||
points += x + ',' + y + ' ';
|
||||
}
|
||||
|
||||
//var poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttributeNS(null, 'points', points);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokewidth);
|
||||
// newFO.setAttributeNS(null, 'transform', "rotate(-90)");
|
||||
shape = newFO.getAttributeNS(null, 'shape');
|
||||
//newFO.appendChild(poly);
|
||||
//DrawPoly(cx, cy, sides, edg, orient);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
mouseUp: function(opts){
|
||||
if (svgCanvas.getMode() == "polygon") {
|
||||
var attrs = $(newFO).attr("edge");
|
||||
var keep = (attrs.edge != 0);
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
selectedChanged: function(opts){
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#polySides').val(elem.getAttribute("sides"));
|
||||
|
||||
showPanel(true);
|
||||
}
|
||||
else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function(opts){
|
||||
// var elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
for (s = 0; sides >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * s / sides;
|
||||
x = (circumradius * Math.cos(angle)) + cx;
|
||||
y = (circumradius * Math.sin(angle)) + cy;
|
||||
|
||||
points += x + ',' + y + ' ';
|
||||
}
|
||||
|
||||
// var poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttributeNS(null, 'points', points);
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokewidth);
|
||||
// newFO.setAttributeNS(null, 'transform', 'rotate(-90)');
|
||||
// var shape = newFO.getAttributeNS(null, 'shape');
|
||||
// newFO.appendChild(poly);
|
||||
// DrawPoly(cx, cy, sides, edg, orient);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
mouseUp: function (opts) {
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
var attrs = $(newFO).attr('edge');
|
||||
var keep = (attrs.edge !== '0');
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
|
||||
while (i--) {
|
||||
var elem = selElems[i];
|
||||
if (elem && elem.getAttributeNS(null, 'shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$('#polySides').val(elem.getAttribute('sides'));
|
||||
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function (opts) {
|
||||
// var elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, svgCanvas, canvg, $, top*/
|
||||
/*jslint vars: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, svgCanvas, canvg, $, top */
|
||||
/*
|
||||
* ext-server_moinsave.js
|
||||
*
|
||||
@@ -12,48 +12,47 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("server_opensave", {
|
||||
callback: function() {'use strict';
|
||||
svgEditor.addExtension('server_opensave', {
|
||||
callback: function () {
|
||||
'use strict';
|
||||
var Utils = svgedit.utilities;
|
||||
var save_svg_action = '/+modify';
|
||||
|
||||
var saveSvgAction = '/+modify';
|
||||
|
||||
// Create upload target (hidden iframe)
|
||||
var target = $('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
|
||||
|
||||
/* var target = */ $('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
|
||||
|
||||
svgEditor.setCustomHandlers({
|
||||
save: function(win, data) {
|
||||
var svg = "<?xml version=\"1.0\"?>\n" + data;
|
||||
save: function (win, data) {
|
||||
var svg = '<?xml version="1.0"?>\n' + data;
|
||||
var qstr = $.param.querystring();
|
||||
var name = qstr.substr(9).split('/+get/')[1];
|
||||
var svg_data = Utils.encode64(svg);
|
||||
if(!$('#export_canvas').length) {
|
||||
var svgData = Utils.encode64(svg);
|
||||
if (!$('#export_canvas').length) {
|
||||
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
||||
}
|
||||
var c = $('#export_canvas')[0];
|
||||
c.width = svgCanvas.contentW;
|
||||
c.height = svgCanvas.contentH;
|
||||
Utils.buildCanvgCallback(function () {
|
||||
canvg(c, svg, {renderCallback: function() {
|
||||
canvg(c, svg, {renderCallback: function () {
|
||||
var datauri = c.toDataURL('image/png');
|
||||
// var uiStrings = svgEditor.uiStrings;
|
||||
var png_data = Utils.encode64(datauri); // Brett: This encoding seems unnecessary
|
||||
var form = $('<form>').attr({
|
||||
method: 'post',
|
||||
action: save_svg_action + '/' + name,
|
||||
target: 'output_frame'
|
||||
}).append('<input type="hidden" name="png_data" value="' + png_data + '">')
|
||||
.append('<input type="hidden" name="filepath" value="' + svg_data + '">')
|
||||
.append('<input type="hidden" name="filename" value="' + 'drawing.svg">')
|
||||
.append('<input type="hidden" name="contenttype" value="application/x-svgdraw">')
|
||||
.appendTo('body')
|
||||
.submit().remove();
|
||||
var pngData = Utils.encode64(datauri); // Brett: This encoding seems unnecessary
|
||||
/* var form = */ $('<form>').attr({
|
||||
method: 'post',
|
||||
action: saveSvgAction + '/' + name,
|
||||
target: 'output_frame'
|
||||
}).append('<input type="hidden" name="png_data" value="' + pngData + '">')
|
||||
.append('<input type="hidden" name="filepath" value="' + svgData + '">')
|
||||
.append('<input type="hidden" name="filename" value="' + 'drawing.svg">')
|
||||
.append('<input type="hidden" name="contenttype" value="application/x-svgdraw">')
|
||||
.appendTo('body')
|
||||
.submit().remove();
|
||||
}});
|
||||
})();
|
||||
alert("Saved! Return to Item View!");
|
||||
top.window.location = '/'+name;
|
||||
alert('Saved! Return to Item View!');
|
||||
top.window.location = '/' + name;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, svgCanvas, canvg, $*/
|
||||
/*jslint eqeq: true, browser:true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgedit, svgCanvas, canvg, $ */
|
||||
/*
|
||||
* ext-server_opensave.js
|
||||
*
|
||||
@@ -9,15 +9,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension("server_opensave", {
|
||||
callback: function() {
|
||||
svgEditor.addExtension('server_opensave', {
|
||||
callback: function () {
|
||||
'use strict';
|
||||
function getFileNameFromTitle () {
|
||||
var title = svgCanvas.getDocumentTitle();
|
||||
// We convert (to underscore) only those disallowed Win7 file name characters
|
||||
return $.trim(title).replace(/[\/\\:*?"<>|]/g, '_');
|
||||
return $.trim(title).replace(/[/\\:*?"<>|]/g, '_');
|
||||
}
|
||||
function xhtmlEscape(str) {
|
||||
function xhtmlEscape (str) {
|
||||
return str.replace(/&(?!amp;)/g, '&').replace(/"/g, '"').replace(/</g, '<'); // < is actually disallowed above anyways
|
||||
}
|
||||
function clientDownloadSupport (filename, suffix, uri) {
|
||||
@@ -29,17 +29,17 @@ svgEditor.addExtension("server_opensave", {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var open_svg_action, import_svg_action, import_img_action,
|
||||
open_svg_form, import_svg_form, import_img_form,
|
||||
save_svg_action = svgEditor.curConfig.extPath + 'filesave.php',
|
||||
save_img_action = svgEditor.curConfig.extPath + 'filesave.php',
|
||||
var openSvgAction, importSvgAction, importImgAction,
|
||||
openSvgForm, importSvgForm, importImgForm,
|
||||
saveSvgAction = svgEditor.curConfig.extPath + 'filesave.php',
|
||||
saveImgAction = svgEditor.curConfig.extPath + 'filesave.php',
|
||||
// Create upload target (hidden iframe)
|
||||
cancelled = false,
|
||||
Utils = svgedit.utilities;
|
||||
|
||||
|
||||
$('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
|
||||
svgEditor.setCustomHandlers({
|
||||
save: function(win, data) {
|
||||
save: function (win, data) {
|
||||
var 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
|
||||
filename = getFileNameFromTitle();
|
||||
|
||||
@@ -49,7 +49,7 @@ svgEditor.addExtension("server_opensave", {
|
||||
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: save_svg_action,
|
||||
action: saveSvgAction,
|
||||
target: 'output_frame'
|
||||
}).append('<input type="hidden" name="output_svg" value="' + xhtmlEscape(svg) + '">')
|
||||
.append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
|
||||
@@ -64,7 +64,7 @@ svgEditor.addExtension("server_opensave", {
|
||||
}
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: save_img_action,
|
||||
action: saveImgAction,
|
||||
target: 'output_frame'
|
||||
}).append('<input type="hidden" name="output_img" value="' + datauri + '">')
|
||||
.append('<input type="hidden" name="mime" value="application/pdf">')
|
||||
@@ -73,46 +73,46 @@ svgEditor.addExtension("server_opensave", {
|
||||
.submit().remove();
|
||||
},
|
||||
// Todo: Integrate this extension with a new built-in exportWindowType, "download"
|
||||
exportImage: function(win, data) {
|
||||
exportImage: function (win, data) {
|
||||
var c,
|
||||
issues = data.issues,
|
||||
mimeType = data.mimeType,
|
||||
quality = data.quality;
|
||||
|
||||
if(!$('#export_canvas').length) {
|
||||
|
||||
if (!$('#export_canvas').length) {
|
||||
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
||||
}
|
||||
c = $('#export_canvas')[0];
|
||||
|
||||
|
||||
c.width = svgCanvas.contentW;
|
||||
c.height = svgCanvas.contentH;
|
||||
Utils.buildCanvgCallback(function () {
|
||||
canvg(c, data.svg, {renderCallback: function() {
|
||||
canvg(c, data.svg, {renderCallback: function () {
|
||||
var pre, filename, suffix,
|
||||
datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType),
|
||||
// uiStrings = svgEditor.uiStrings,
|
||||
note = '';
|
||||
|
||||
|
||||
// Check if there are issues
|
||||
if (issues.length) {
|
||||
pre = "\n \u2022 ";
|
||||
note += ("\n\n" + pre + issues.join(pre));
|
||||
}
|
||||
|
||||
if(note.length) {
|
||||
pre = '\n \u2022 ';
|
||||
note += ('\n\n' + pre + issues.join(pre));
|
||||
}
|
||||
|
||||
if (note.length) {
|
||||
alert(note);
|
||||
}
|
||||
|
||||
|
||||
filename = getFileNameFromTitle();
|
||||
suffix = '.' + data.type.toLowerCase();
|
||||
|
||||
|
||||
if (clientDownloadSupport(filename, suffix, datauri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('<form>').attr({
|
||||
method: 'post',
|
||||
action: save_img_action,
|
||||
action: saveImgAction,
|
||||
target: 'output_frame'
|
||||
}).append('<input type="hidden" name="output_img" value="' + datauri + '">')
|
||||
.append('<input type="hidden" name="mime" value="' + mimeType + '">')
|
||||
@@ -125,81 +125,80 @@ svgEditor.addExtension("server_opensave", {
|
||||
});
|
||||
|
||||
// Do nothing if client support is found
|
||||
if (window.FileReader) {return;}
|
||||
|
||||
if (window.FileReader) { return; }
|
||||
|
||||
// Change these to appropriate script file
|
||||
open_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=load_svg';
|
||||
import_svg_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_svg';
|
||||
import_img_action = svgEditor.curConfig.extPath + 'fileopen.php?type=import_img';
|
||||
|
||||
openSvgAction = svgEditor.curConfig.extPath + 'fileopen.php?type=load_svg';
|
||||
importSvgAction = svgEditor.curConfig.extPath + 'fileopen.php?type=import_svg';
|
||||
importImgAction = svgEditor.curConfig.extPath + 'fileopen.php?type=import_img';
|
||||
|
||||
// Set up function for PHP uploader to use
|
||||
svgEditor.processFile = function(str64, type) {
|
||||
svgEditor.processFile = function (str64, type) {
|
||||
var xmlstr;
|
||||
if (cancelled) {
|
||||
cancelled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$('#dialog_box').hide();
|
||||
|
||||
if (type !== 'import_img') {
|
||||
xmlstr = Utils.decode64(str64);
|
||||
}
|
||||
|
||||
|
||||
switch (type) {
|
||||
case 'load_svg':
|
||||
svgCanvas.clear();
|
||||
svgCanvas.setSvgString(xmlstr);
|
||||
svgEditor.updateCanvas();
|
||||
break;
|
||||
case 'import_svg':
|
||||
svgCanvas.importSvgString(xmlstr);
|
||||
svgEditor.updateCanvas();
|
||||
break;
|
||||
case 'import_img':
|
||||
svgCanvas.setGoodImage(str64);
|
||||
break;
|
||||
case 'load_svg':
|
||||
svgCanvas.clear();
|
||||
svgCanvas.setSvgString(xmlstr);
|
||||
svgEditor.updateCanvas();
|
||||
break;
|
||||
case 'import_svg':
|
||||
svgCanvas.importSvgString(xmlstr);
|
||||
svgEditor.updateCanvas();
|
||||
break;
|
||||
case 'import_img':
|
||||
svgCanvas.setGoodImage(str64);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Create upload form
|
||||
open_svg_form = $('<form>');
|
||||
open_svg_form.attr({
|
||||
openSvgForm = $('<form>');
|
||||
openSvgForm.attr({
|
||||
enctype: 'multipart/form-data',
|
||||
method: 'post',
|
||||
action: open_svg_action,
|
||||
action: openSvgAction,
|
||||
target: 'output_frame'
|
||||
});
|
||||
|
||||
|
||||
// Create import form
|
||||
import_svg_form = open_svg_form.clone().attr('action', import_svg_action);
|
||||
importSvgForm = openSvgForm.clone().attr('action', importSvgAction);
|
||||
|
||||
// Create image form
|
||||
import_img_form = open_svg_form.clone().attr('action', import_img_action);
|
||||
|
||||
// It appears necessary to rebuild this input every time a file is
|
||||
importImgForm = openSvgForm.clone().attr('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.
|
||||
function rebuildInput(form) {
|
||||
function rebuildInput (form) {
|
||||
form.empty();
|
||||
var inp = $('<input type="file" name="svg_file">').appendTo(form);
|
||||
|
||||
|
||||
function submit() {
|
||||
|
||||
function submit () {
|
||||
// This submits the form, which returns the file data using svgEditor.processFile()
|
||||
form.submit();
|
||||
|
||||
|
||||
rebuildInput(form);
|
||||
$.process_cancel("Uploading...", function() {
|
||||
$.process_cancel('Uploading...', function () {
|
||||
cancelled = true;
|
||||
$('#dialog_box').hide();
|
||||
});
|
||||
}
|
||||
|
||||
if(form[0] == open_svg_form[0]) {
|
||||
inp.change(function() {
|
||||
|
||||
if (form[0] === openSvgForm[0]) {
|
||||
inp.change(function () {
|
||||
// This takes care of the "are you sure" dialog box
|
||||
svgEditor.openPrep(function(ok) {
|
||||
if(!ok) {
|
||||
svgEditor.openPrep(function (ok) {
|
||||
if (!ok) {
|
||||
rebuildInput(form);
|
||||
return;
|
||||
}
|
||||
@@ -207,22 +206,21 @@ svgEditor.addExtension("server_opensave", {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
inp.change(function() {
|
||||
inp.change(function () {
|
||||
// This submits the form, which returns the file data using svgEditor.processFile()
|
||||
submit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create the input elements
|
||||
rebuildInput(open_svg_form);
|
||||
rebuildInput(import_svg_form);
|
||||
rebuildInput(import_img_form);
|
||||
rebuildInput(openSvgForm);
|
||||
rebuildInput(importSvgForm);
|
||||
rebuildInput(importImgForm);
|
||||
|
||||
// Add forms to buttons
|
||||
$("#tool_open").show().prepend(open_svg_form);
|
||||
$("#tool_import").show().prepend(import_svg_form);
|
||||
$("#tool_image").prepend(import_img_form);
|
||||
$('#tool_open').show().prepend(openSvgForm);
|
||||
$('#tool_import').show().prepend(importSvgForm);
|
||||
$('#tool_image').prepend(importImgForm);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, $, DOMParser*/
|
||||
/*jslint es5: true, vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, $, DOMParser */
|
||||
/*
|
||||
* ext-shapes.js
|
||||
*
|
||||
@@ -10,11 +10,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('shapes', function() {'use strict';
|
||||
var current_d, cur_shape_id;
|
||||
svgEditor.addExtension('shapes', function () {
|
||||
'use strict';
|
||||
var currentD, curShapeId;
|
||||
var canv = svgEditor.canvas;
|
||||
var cur_shape;
|
||||
var start_x, start_y;
|
||||
var curShape;
|
||||
var startX, startY;
|
||||
var svgroot = canv.getRootElem();
|
||||
var lastBBox = {};
|
||||
|
||||
@@ -73,67 +74,66 @@ svgEditor.addExtension('shapes', function() {'use strict';
|
||||
}
|
||||
};
|
||||
|
||||
var cur_lib = library.basic;
|
||||
var mode_id = 'shapelib';
|
||||
var curLib = library.basic;
|
||||
var modeId = 'shapelib';
|
||||
var startClientPos = {};
|
||||
|
||||
function loadIcons() {
|
||||
$('#shape_buttons').empty().append(cur_lib.buttons);
|
||||
function loadIcons () {
|
||||
$('#shape_buttons').empty().append(curLib.buttons);
|
||||
}
|
||||
|
||||
function makeButtons(cat, shapes) {
|
||||
var size = cur_lib.size || 300;
|
||||
var fill = cur_lib.fill || false;
|
||||
function makeButtons (cat, shapes) {
|
||||
var size = curLib.size || 300;
|
||||
var fill = curLib.fill || false;
|
||||
var off = size * 0.05;
|
||||
var vb = [-off, -off, size + off*2, size + off*2].join(' ');
|
||||
var stroke = fill ? 0: (size/30);
|
||||
var shape_icon = new DOMParser().parseFromString(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="'+(fill?'#333':'none')+'" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>',
|
||||
var vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
var stroke = fill ? 0 : (size / 30);
|
||||
var shapeIcon = new DOMParser().parseFromString(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="' + (fill ? '#333' : 'none') + '" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>',
|
||||
'text/xml');
|
||||
|
||||
var width = 24;
|
||||
var height = 24;
|
||||
shape_icon.documentElement.setAttribute('width', width);
|
||||
shape_icon.documentElement.setAttribute('height', height);
|
||||
var svg_elem = $(document.importNode(shape_icon.documentElement,true));
|
||||
shapeIcon.documentElement.setAttribute('width', width);
|
||||
shapeIcon.documentElement.setAttribute('height', height);
|
||||
var svgElem = $(document.importNode(shapeIcon.documentElement, true));
|
||||
|
||||
var data = shapes.data;
|
||||
|
||||
cur_lib.buttons = [];
|
||||
curLib.buttons = [];
|
||||
var id;
|
||||
for (id in data) {
|
||||
var path_d = data[id];
|
||||
var icon = svg_elem.clone();
|
||||
icon.find('path').attr('d', path_d);
|
||||
var pathD = data[id];
|
||||
var icon = svgElem.clone();
|
||||
icon.find('path').attr('d', pathD);
|
||||
|
||||
var icon_btn = icon.wrap('<div class="tool_button">').parent().attr({
|
||||
id: mode_id + '_' + id,
|
||||
var iconBtn = icon.wrap('<div class="tool_button">').parent().attr({
|
||||
id: modeId + '_' + id,
|
||||
title: id
|
||||
});
|
||||
// Store for later use
|
||||
cur_lib.buttons.push(icon_btn[0]);
|
||||
curLib.buttons.push(iconBtn[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function loadLibrary(cat_id) {
|
||||
|
||||
var lib = library[cat_id];
|
||||
function loadLibrary (catId) {
|
||||
var lib = library[catId];
|
||||
|
||||
if (!lib) {
|
||||
$('#shape_buttons').html('Loading...');
|
||||
$.getJSON(svgEditor.curConfig.extPath + 'shapelib/' + cat_id + '.json', function(result) {
|
||||
cur_lib = library[cat_id] = {
|
||||
$.getJSON(svgEditor.curConfig.extPath + 'shapelib/' + catId + '.json', function (result) {
|
||||
curLib = library[catId] = {
|
||||
data: result.data,
|
||||
size: result.size,
|
||||
fill: result.fill
|
||||
};
|
||||
makeButtons(cat_id, result);
|
||||
makeButtons(catId, result);
|
||||
loadIcons();
|
||||
});
|
||||
return;
|
||||
}
|
||||
cur_lib = lib;
|
||||
if (!lib.buttons.length) {makeButtons(cat_id, lib);}
|
||||
curLib = lib;
|
||||
if (!lib.buttons.length) { makeButtons(catId, lib); }
|
||||
loadIcons();
|
||||
}
|
||||
|
||||
@@ -145,53 +145,52 @@ svgEditor.addExtension('shapes', function() {'use strict';
|
||||
position: 6,
|
||||
title: 'Shape library',
|
||||
events: {
|
||||
click: function() {
|
||||
canv.setMode(mode_id);
|
||||
click: function () {
|
||||
canv.setMode(modeId);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function() {
|
||||
$('<style>').text('\
|
||||
#shape_buttons {\
|
||||
overflow: auto;\
|
||||
width: 180px;\
|
||||
max-height: 300px;\
|
||||
display: table-cell;\
|
||||
vertical-align: middle;\
|
||||
}\
|
||||
\
|
||||
#shape_cats {\
|
||||
min-width: 110px;\
|
||||
display: table-cell;\
|
||||
vertical-align: middle;\
|
||||
height: 300px;\
|
||||
}\
|
||||
#shape_cats > div {\
|
||||
line-height: 1em;\
|
||||
padding: .5em;\
|
||||
border:1px solid #B0B0B0;\
|
||||
background: #E8E8E8;\
|
||||
margin-bottom: -1px;\
|
||||
}\
|
||||
#shape_cats div:hover {\
|
||||
background: #FFFFCC;\
|
||||
}\
|
||||
#shape_cats div.current {\
|
||||
font-weight: bold;\
|
||||
}').appendTo('head');
|
||||
callback: function () {
|
||||
$('<style>').text(
|
||||
'#shape_buttons {' +
|
||||
'overflow: auto;' +
|
||||
'width: 180px;' +
|
||||
'max-height: 300px;' +
|
||||
'display: table-cell;' +
|
||||
'vertical-align: middle;' +
|
||||
'}' +
|
||||
'#shape_cats {' +
|
||||
'min-width: 110px;' +
|
||||
'display: table-cell;' +
|
||||
'vertical-align: middle;' +
|
||||
'height: 300px;' +
|
||||
'}' +
|
||||
'#shape_cats > div {' +
|
||||
'line-height: 1em;' +
|
||||
'padding: .5em;' +
|
||||
'border:1px solid #B0B0B0;' +
|
||||
'background: #E8E8E8;' +
|
||||
'margin-bottom: -1px;' +
|
||||
'}' +
|
||||
'#shape_cats div:hover {' +
|
||||
'background: #FFFFCC;' +
|
||||
'}' +
|
||||
'#shape_cats div.current {' +
|
||||
'font-weight: bold;' +
|
||||
'}').appendTo('head');
|
||||
|
||||
var btn_div = $('<div id="shape_buttons">');
|
||||
$('#tools_shapelib > *').wrapAll(btn_div);
|
||||
var btnDiv = $('<div id="shape_buttons">');
|
||||
$('#tools_shapelib > *').wrapAll(btnDiv);
|
||||
|
||||
var shower = $('#tools_shapelib_show');
|
||||
|
||||
loadLibrary('basic');
|
||||
|
||||
// Do mouseup on parent element rather than each button
|
||||
$('#shape_buttons').mouseup(function(evt) {
|
||||
$('#shape_buttons').mouseup(function (evt) {
|
||||
var btn = $(evt.target).closest('div.tool_button');
|
||||
|
||||
if (!btn.length) {return;}
|
||||
if (!btn.length) { return; }
|
||||
|
||||
var copy = btn.children().clone();
|
||||
shower.children(':not(.flyout_arrow_horiz)').remove();
|
||||
@@ -199,22 +198,22 @@ svgEditor.addExtension('shapes', function() {'use strict';
|
||||
.append(copy)
|
||||
.attr('data-curopt', '#' + btn[0].id) // This sets the current mode
|
||||
.mouseup();
|
||||
canv.setMode(mode_id);
|
||||
canv.setMode(modeId);
|
||||
|
||||
cur_shape_id = btn[0].id.substr((mode_id+'_').length);
|
||||
current_d = cur_lib.data[cur_shape_id];
|
||||
curShapeId = btn[0].id.substr((modeId + '_').length);
|
||||
currentD = curLib.data[curShapeId];
|
||||
|
||||
$('.tools_flyout').fadeOut();
|
||||
});
|
||||
|
||||
var shape_cats = $('<div id="shape_cats">');
|
||||
var cat_str = '';
|
||||
var shapeCats = $('<div id="shape_cats">');
|
||||
var catStr = '';
|
||||
|
||||
$.each(categories, function(id, label) {
|
||||
cat_str += '<div data-cat=' + id + '>' + label + '</div>';
|
||||
$.each(categories, function (id, label) {
|
||||
catStr += '<div data-cat=' + id + '>' + label + '</div>';
|
||||
});
|
||||
|
||||
shape_cats.html(cat_str).children().bind('mouseup', function() {
|
||||
shapeCats.html(catStr).children().bind('mouseup', function () {
|
||||
var catlink = $(this);
|
||||
catlink.siblings().removeClass('current');
|
||||
catlink.addClass('current');
|
||||
@@ -224,134 +223,133 @@ svgEditor.addExtension('shapes', function() {'use strict';
|
||||
return false;
|
||||
});
|
||||
|
||||
shape_cats.children().eq(0).addClass('current');
|
||||
shapeCats.children().eq(0).addClass('current');
|
||||
|
||||
$('#tools_shapelib').append(shape_cats);
|
||||
$('#tools_shapelib').append(shapeCats);
|
||||
|
||||
shower.mouseup(function() {
|
||||
canv.setMode(current_d ? mode_id : 'select');
|
||||
shower.mouseup(function () {
|
||||
canv.setMode(currentD ? modeId : 'select');
|
||||
});
|
||||
$('#tool_shapelib').remove();
|
||||
|
||||
var h = $('#tools_shapelib').height();
|
||||
$('#tools_shapelib').css({
|
||||
'margin-top': -(h/2 - 15),
|
||||
'margin-top': -(h / 2 - 15),
|
||||
'margin-left': 3
|
||||
});
|
||||
},
|
||||
mouseDown: function(opts) {
|
||||
mouseDown: function (opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== mode_id) {return;}
|
||||
if (mode !== modeId) { return; }
|
||||
|
||||
startX = opts.start_x;
|
||||
var x = startX;
|
||||
startY = opts.start_y;
|
||||
var y = startY;
|
||||
var curStyle = canv.getStyle();
|
||||
|
||||
start_x = opts.start_x;
|
||||
var x = start_x;
|
||||
start_y = opts.start_y;
|
||||
var y = start_y;
|
||||
var cur_style = canv.getStyle();
|
||||
|
||||
startClientPos.x = opts.event.clientX;
|
||||
startClientPos.y = opts.event.clientY;
|
||||
|
||||
cur_shape = canv.addSvgElementFromJson({
|
||||
curShape = canv.addSvgElementFromJson({
|
||||
'element': 'path',
|
||||
'curStyles': true,
|
||||
'attr': {
|
||||
'd': current_d,
|
||||
'd': currentD,
|
||||
'id': canv.getNextId(),
|
||||
'opacity': cur_style.opacity / 2,
|
||||
'opacity': curStyle.opacity / 2,
|
||||
'style': 'pointer-events:none'
|
||||
}
|
||||
});
|
||||
|
||||
// Make sure shape uses absolute values
|
||||
if (/[a-z]/.test(current_d)) {
|
||||
current_d = cur_lib.data[cur_shape_id] = canv.pathActions.convertPath(cur_shape);
|
||||
cur_shape.setAttribute('d', current_d);
|
||||
canv.pathActions.fixEnd(cur_shape);
|
||||
if (/[a-z]/.test(currentD)) {
|
||||
currentD = curLib.data[curShapeId] = canv.pathActions.convertPath(curShape);
|
||||
curShape.setAttribute('d', currentD);
|
||||
canv.pathActions.fixEnd(curShape);
|
||||
}
|
||||
cur_shape.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(0.005) translate(' + -x + ',' + -y + ')');
|
||||
curShape.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(0.005) translate(' + -x + ',' + -y + ')');
|
||||
|
||||
canv.recalculateDimensions(cur_shape);
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
var tlist = canv.getTransformList(cur_shape);
|
||||
/* var tlist = */ canv.getTransformList(curShape);
|
||||
|
||||
lastBBox = cur_shape.getBBox();
|
||||
lastBBox = curShape.getBBox();
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
},
|
||||
mouseMove: function(opts) {
|
||||
mouseMove: function (opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== mode_id) {return;}
|
||||
if (mode !== modeId) { return; }
|
||||
|
||||
var zoom = canv.getZoom();
|
||||
var evt = opts.event;
|
||||
|
||||
var x = opts.mouse_x/zoom;
|
||||
var y = opts.mouse_y/zoom;
|
||||
var x = opts.mouse_x / zoom;
|
||||
var y = opts.mouse_y / zoom;
|
||||
|
||||
var tlist = canv.getTransformList(cur_shape),
|
||||
box = cur_shape.getBBox(),
|
||||
var tlist = canv.getTransformList(curShape),
|
||||
box = curShape.getBBox(),
|
||||
left = box.x, top = box.y, width = box.width,
|
||||
height = box.height;
|
||||
var dx = (x-start_x), dy = (y-start_y);
|
||||
var dx = (x - startX), dy = (y - startY);
|
||||
|
||||
var newbox = {
|
||||
'x': Math.min(start_x,x),
|
||||
'y': Math.min(start_y,y),
|
||||
'width': Math.abs(x-start_x),
|
||||
'height': Math.abs(y-start_y)
|
||||
'x': Math.min(startX, x),
|
||||
'y': Math.min(startY, y),
|
||||
'width': Math.abs(x - startX),
|
||||
'height': Math.abs(y - startY)
|
||||
};
|
||||
|
||||
var tx = 0, ty = 0,
|
||||
sy = height ? (height+dy)/height : 1,
|
||||
sx = width ? (width+dx)/width : 1;
|
||||
sy = height ? (height + dy) / height : 1,
|
||||
sx = width ? (width + dx) / width : 1;
|
||||
|
||||
sx = (newbox.width / lastBBox.width) || 1;
|
||||
sy = (newbox.height / lastBBox.height) || 1;
|
||||
|
||||
// Not perfect, but mostly works...
|
||||
if (x < start_x) {
|
||||
if (x < startX) {
|
||||
tx = lastBBox.width;
|
||||
}
|
||||
if (y < start_y) {ty = lastBBox.height;}
|
||||
if (y < startY) { ty = lastBBox.height; }
|
||||
|
||||
// update the transform list with translate,scale,translate
|
||||
var translateOrigin = svgroot.createSVGTransform(),
|
||||
scale = svgroot.createSVGTransform(),
|
||||
translateBack = svgroot.createSVGTransform();
|
||||
|
||||
translateOrigin.setTranslate(-(left+tx), -(top+ty));
|
||||
translateOrigin.setTranslate(-(left + tx), -(top + ty));
|
||||
if (!evt.shiftKey) {
|
||||
var max = Math.min(Math.abs(sx), Math.abs(sy));
|
||||
|
||||
sx = max * (sx < 0 ? -1 : 1);
|
||||
sy = max * (sy < 0 ? -1 : 1);
|
||||
}
|
||||
scale.setScale(sx,sy);
|
||||
scale.setScale(sx, sy);
|
||||
|
||||
translateBack.setTranslate(left+tx, top+ty);
|
||||
translateBack.setTranslate(left + tx, top + ty);
|
||||
tlist.appendItem(translateBack);
|
||||
tlist.appendItem(scale);
|
||||
tlist.appendItem(translateOrigin);
|
||||
|
||||
canv.recalculateDimensions(cur_shape);
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
lastBBox = cur_shape.getBBox();
|
||||
lastBBox = curShape.getBBox();
|
||||
},
|
||||
mouseUp: function(opts) {
|
||||
mouseUp: function (opts) {
|
||||
var mode = canv.getMode();
|
||||
if (mode !== mode_id) {return;}
|
||||
if (mode !== modeId) { return; }
|
||||
|
||||
var keepObject = (opts.event.clientX != startClientPos.x && opts.event.clientY != startClientPos.y);
|
||||
var keepObject = (opts.event.clientX !== startClientPos.x && opts.event.clientY !== startClientPos.y);
|
||||
|
||||
return {
|
||||
keep: keepObject,
|
||||
element: cur_shape,
|
||||
element: curShape,
|
||||
started: false
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgedit, svgCanvas, $*/
|
||||
/*jslint vars: true, eqeq: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $ */
|
||||
/*
|
||||
* ext-star.js
|
||||
*
|
||||
@@ -9,7 +9,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
svgEditor.addExtension('star', function(S){'use strict';
|
||||
svgEditor.addExtension('star', function (S) {
|
||||
'use strict';
|
||||
|
||||
var // NS = svgedit.NS,
|
||||
// svgcontent = S.svgcontent,
|
||||
@@ -17,19 +18,18 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
// editingitex = false,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
started,
|
||||
newFO,
|
||||
newFO;
|
||||
// edg = 0,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID,
|
||||
// undoCommand = 'Not image',
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH,
|
||||
shape;
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;
|
||||
|
||||
function showPanel(on){
|
||||
var fc_rules = $('#fc_rules');
|
||||
if (!fc_rules.length) {
|
||||
fc_rules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
function showPanel (on) {
|
||||
var fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
fcRules = $('<style id="fc_rules"></style>').appendTo('head');
|
||||
}
|
||||
fc_rules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
fcRules.text(!on ? '' : ' #tool_topath { display: none !important; }');
|
||||
$('#star_panel').toggle(on);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
}
|
||||
*/
|
||||
|
||||
function setAttr(attr, val){
|
||||
function setAttr (attr, val) {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
title: 'Star Tool',
|
||||
position: 12,
|
||||
events: {
|
||||
click: function(){
|
||||
click: function () {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
@@ -79,7 +79,7 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change: function(){
|
||||
change: function () {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
@@ -100,23 +100,23 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change: function(){
|
||||
change: function () {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
callback: function(){
|
||||
callback: function () {
|
||||
$('#star_panel').hide();
|
||||
// var endChanges = function(){};
|
||||
},
|
||||
mouseDown: function(opts){
|
||||
mouseDown: function (opts) {
|
||||
var rgb = svgCanvas.getColor('fill');
|
||||
// var ccRgbEl = rgb.substring(1, rgb.length);
|
||||
var sRgb = svgCanvas.getColor('stroke');
|
||||
// var ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
var sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() == 'star') {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
@@ -141,11 +141,11 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
};
|
||||
}
|
||||
},
|
||||
mouseMove: function(opts){
|
||||
mouseMove: function (opts) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
if (svgCanvas.getMode() == 'star') {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var x = opts.mouse_x;
|
||||
var y = opts.mouse_y;
|
||||
var c = $(newFO).attr(['cx', 'cy', 'point', 'orient', 'fill', 'strokecolor', 'strokeWidth', 'radialshift']);
|
||||
@@ -158,9 +158,9 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
var s;
|
||||
for (s = 0; point >= s; s++) {
|
||||
var angle = 2.0 * Math.PI * (s / point);
|
||||
if ('point' == orient) {
|
||||
if (orient === 'point') {
|
||||
angle -= (Math.PI / 2);
|
||||
} else if ('edge' == orient) {
|
||||
} else if (orient === 'edge') {
|
||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
||||
}
|
||||
|
||||
@@ -169,11 +169,11 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
|
||||
if (null != inradius) {
|
||||
if (inradius != null) {
|
||||
angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);
|
||||
if ('point' == orient) {
|
||||
if (orient === 'point') {
|
||||
angle -= (Math.PI / 2);
|
||||
} else if ('edge' == orient) {
|
||||
} else if (orient === 'edge') {
|
||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
||||
}
|
||||
angle += radialShift;
|
||||
@@ -188,25 +188,24 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
newFO.setAttributeNS(null, 'fill', fill);
|
||||
newFO.setAttributeNS(null, 'stroke', strokecolor);
|
||||
newFO.setAttributeNS(null, 'stroke-width', strokewidth);
|
||||
shape = newFO.getAttributeNS(null, 'shape');
|
||||
/* var shape = */ newFO.getAttributeNS(null, 'shape');
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
mouseUp: function(){
|
||||
if (svgCanvas.getMode() == 'star') {
|
||||
mouseUp: function () {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
var attrs = $(newFO).attr(['r']);
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep: (attrs.r != 0),
|
||||
keep: (attrs.r !== '0'),
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
},
|
||||
selectedChanged: function(opts){
|
||||
selectedChanged: function (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
@@ -220,8 +219,7 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
$('#starNumPoints').val(elem.getAttribute('point'));
|
||||
$('#radialShift').val(elem.getAttribute('radialshift'));
|
||||
showPanel(true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
@@ -229,7 +227,7 @@ svgEditor.addExtension('star', function(S){'use strict';
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged: function(opts){
|
||||
elementChanged: function (opts) {
|
||||
// var elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*globals svgEditor, svgCanvas, $, widget*/
|
||||
/*jslint vars: true, eqeq: true, regexp: true, continue: true*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas, $, widget */
|
||||
/*
|
||||
* ext-storage.js
|
||||
*
|
||||
@@ -26,7 +26,7 @@ TODOS
|
||||
2. We might provide control of storage settings through the UI besides the
|
||||
initial (or URL-forced) dialog.
|
||||
*/
|
||||
svgEditor.addExtension('storage', function() {
|
||||
svgEditor.addExtension('storage', function () {
|
||||
// We could empty any already-set data for users when they decline storage,
|
||||
// but it would be a risk for users who wanted to store but accidentally
|
||||
// said "no"; instead, we'll let those who already set it, delete it themselves;
|
||||
@@ -53,8 +53,7 @@ svgEditor.addExtension('storage', function() {
|
||||
loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
|
||||
return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
loc.href += (loc.href.indexOf('?') > -1 ? '&' : '?') + val;
|
||||
}
|
||||
}
|
||||
@@ -63,22 +62,21 @@ svgEditor.addExtension('storage', function() {
|
||||
var name = 'svgedit-' + svgEditor.curConfig.canvasName;
|
||||
if (!val) {
|
||||
storage.removeItem(name);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
storage.setItem(name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function expireCookie (cookie) {
|
||||
document.cookie = encodeURIComponent(cookie) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
}
|
||||
|
||||
|
||||
function removeStoragePrefCookie () {
|
||||
expireCookie('store');
|
||||
}
|
||||
|
||||
function emptyStorage() {
|
||||
|
||||
function emptyStorage () {
|
||||
setSVGContentStorage('');
|
||||
var name;
|
||||
for (name in svgEditor.curPrefs) {
|
||||
@@ -91,8 +89,8 @@ svgEditor.addExtension('storage', function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emptyStorage();
|
||||
|
||||
// emptyStorage();
|
||||
|
||||
/**
|
||||
* Listen for unloading: If and only if opted in by the user, set the content
|
||||
@@ -103,14 +101,14 @@ svgEditor.addExtension('storage', function() {
|
||||
* 3. Use localStorage (where available) or cookies to set preferences.
|
||||
*/
|
||||
function setupBeforeUnloadListener () {
|
||||
window.addEventListener('beforeunload', function(e) {
|
||||
window.addEventListener('beforeunload', function (e) {
|
||||
// Don't save anything unless the user opted in to storage
|
||||
if (!document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/)) {
|
||||
return;
|
||||
}
|
||||
var key;
|
||||
if (document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)) {
|
||||
setSVGContentStorage(svgCanvas.getSvgString());
|
||||
setSVGContentStorage(svgCanvas.getSvgString());
|
||||
}
|
||||
|
||||
svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on
|
||||
@@ -121,18 +119,16 @@ svgEditor.addExtension('storage', function() {
|
||||
for (key in curPrefs) {
|
||||
if (curPrefs.hasOwnProperty(key)) { // It's our own config, so we don't need to iterate up the prototype chain
|
||||
var val = curPrefs[key],
|
||||
store = (val != undefined);
|
||||
store = (val !== undefined);
|
||||
key = 'svg-edit-' + key;
|
||||
if (!store) {
|
||||
continue;
|
||||
}
|
||||
if (storage) {
|
||||
storage.setItem(key, val);
|
||||
}
|
||||
else if (window.widget) {
|
||||
} else if (window.widget) {
|
||||
widget.setPreferenceForKey(val, key);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val = encodeURIComponent(val);
|
||||
document.cookie = encodeURIComponent(key) + '=' + val + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
||||
}
|
||||
@@ -195,7 +191,6 @@ svgEditor.addExtension('storage', function() {
|
||||
)
|
||||
// ...then show the storage prompt.
|
||||
)) {
|
||||
|
||||
var options = [];
|
||||
if (storage) {
|
||||
options.unshift(
|
||||
@@ -203,8 +198,7 @@ svgEditor.addExtension('storage', function() {
|
||||
{value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefsOnly},
|
||||
{value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefsOrContent}
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
options.unshift(
|
||||
{value: 'prefsOnly', text: uiStrings.confirmSetStorage.storagePrefs},
|
||||
{value: 'noPrefsOrContent', text: uiStrings.confirmSetStorage.storageNoPrefs}
|
||||
@@ -242,8 +236,7 @@ svgEditor.addExtension('storage', function() {
|
||||
replaceStoragePrompt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else { // The user does not wish storage (or cancelled, which we treat equivalently)
|
||||
} else { // The user does not wish storage (or cancelled, which we treat equivalently)
|
||||
removeStoragePrefCookie();
|
||||
if (pref && // If the user explicitly expresses wish for no storage
|
||||
emptyStorageOnDecline
|
||||
@@ -259,21 +252,21 @@ svgEditor.addExtension('storage', function() {
|
||||
|
||||
// Reset width/height of dialog (e.g., for use by Export)
|
||||
$('#dialog_container')[0].style.width = oldContainerWidth;
|
||||
$('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
|
||||
$('#dialog_container')[0].style.marginLeft = oldContainerMarginLeft;
|
||||
$('#dialog_content')[0].style.height = oldContentHeight;
|
||||
$('#dialog_container')[0].style.height = oldContainerHeight;
|
||||
|
||||
|
||||
// It should be enough to (conditionally) add to storage on
|
||||
// beforeunload, but if we wished to update immediately,
|
||||
// we might wish to try setting:
|
||||
// svgEditor.setConfig({noStorageOnLoad: true});
|
||||
// and then call:
|
||||
// svgEditor.loadContentAndPrefs();
|
||||
|
||||
|
||||
// We don't check for noStorageOnLoad here because
|
||||
// the prompt gives the user the option to store data
|
||||
setupBeforeUnloadListener();
|
||||
|
||||
|
||||
svgEditor.storagePromptClosed = true;
|
||||
},
|
||||
null,
|
||||
@@ -284,8 +277,7 @@ svgEditor.addExtension('storage', function() {
|
||||
tooltip: uiStrings.confirmSetStorage.rememberTooltip
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (!noStorageOnLoad || forceStorage) {
|
||||
} else if (!noStorageOnLoad || forceStorage) {
|
||||
setupBeforeUnloadListener();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
/*globals svgEditor*/
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor */
|
||||
/*
|
||||
Depends on Firefox add-on and executables from https://github.com/brettz9/webappfind
|
||||
|
||||
Todos:
|
||||
1. See WebAppFind Readme for SVG-related todos
|
||||
*/
|
||||
(function () {'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var pathID,
|
||||
saveMessage = 'webapp-save',
|
||||
readMessage = 'webapp-read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
saveMessage = 'webapp-save',
|
||||
readMessage = 'webapp-read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
|
||||
window.addEventListener('message', function(e) {
|
||||
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
|
||||
(!Array.isArray(e.data) || excludedMessages.indexOf(e.data[0]) > -1) // Validate format and avoid our post below
|
||||
) {
|
||||
return;
|
||||
}
|
||||
var svgString,
|
||||
messageType = e.data[0];
|
||||
switch (messageType) {
|
||||
case 'webapp-view':
|
||||
// Populate the contents
|
||||
pathID = e.data[1];
|
||||
|
||||
svgString = e.data[2];
|
||||
svgEditor.loadFromString(svgString);
|
||||
|
||||
/*if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
}*/
|
||||
break;
|
||||
case 'webapp-save-end':
|
||||
alert('save complete for pathID ' + e.data[1] + '!');
|
||||
break;
|
||||
default:
|
||||
throw 'Unexpected mode';
|
||||
}
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
|
||||
(!Array.isArray(e.data) || excludedMessages.indexOf(e.data[0]) > -1) // Validate format and avoid our post below
|
||||
) {
|
||||
return;
|
||||
}
|
||||
var svgString,
|
||||
messageType = e.data[0];
|
||||
switch (messageType) {
|
||||
case 'webapp-view':
|
||||
// Populate the contents
|
||||
pathID = e.data[1];
|
||||
|
||||
svgString = e.data[2];
|
||||
svgEditor.loadFromString(svgString);
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'webapp-save-end':
|
||||
alert('save complete for pathID ' + e.data[1] + '!');
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected mode');
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.postMessage([readMessage], window.location.origin !== 'null' ? window.location.origin : '*'); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
|
||||
|
||||
svgEditor.addExtension('WebAppFind', function() {
|
||||
|
||||
return {
|
||||
name: 'WebAppFind',
|
||||
svgicons: svgEditor.curConfig.extPath + 'webappfind-icon.svg',
|
||||
buttons: [{
|
||||
id: 'webappfind_save', //
|
||||
type: 'app_menu',
|
||||
title: 'Save Image back to Disk',
|
||||
position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
|
||||
events: {
|
||||
click: function () {
|
||||
if (!pathID) { // Not ready yet as haven't received first payload
|
||||
return;
|
||||
}
|
||||
window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
svgEditor.addExtension('WebAppFind', function () {
|
||||
return {
|
||||
name: 'WebAppFind',
|
||||
svgicons: svgEditor.curConfig.extPath + 'webappfind-icon.svg',
|
||||
buttons: [{
|
||||
id: 'webappfind_save', //
|
||||
type: 'app_menu',
|
||||
title: 'Save Image back to Disk',
|
||||
position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
|
||||
events: {
|
||||
click: function () {
|
||||
if (!pathID) { // Not ready yet as haven't received first payload
|
||||
return;
|
||||
}
|
||||
window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
}());
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
/* eslint-disable no-var */
|
||||
/* globals svgEditor, svgCanvas */
|
||||
/**
|
||||
* Should not be needed for same domain control (just call via child frame),
|
||||
* but an API common for cross-domain and same domain use can be found
|
||||
* in embedapi.js with a demo at embedapi.html
|
||||
*/
|
||||
/*globals svgEditor, svgCanvas*/
|
||||
svgEditor.addExtension('xdomain-messaging', function() {'use strict';
|
||||
svgEditor.addExtension('xdomain-messaging', function () {
|
||||
'use strict';
|
||||
try {
|
||||
window.addEventListener('message', function(e) {
|
||||
window.addEventListener('message', function (e) {
|
||||
// We accept and post strings for the sake of IE9 support
|
||||
if (typeof e.data !== 'string' || e.data.charAt() === '|') {
|
||||
return;
|
||||
@@ -35,8 +37,7 @@ svgEditor.addExtension('xdomain-messaging', function() {'use strict';
|
||||
}
|
||||
e.source.postMessage(JSON.stringify(message), '*');
|
||||
}, false);
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
console.log('Error with xdomain message listener: ' + err);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,30 +11,30 @@
|
||||
*/
|
||||
// Very minimal PHP file, all we do is Base64 encode the uploaded file and
|
||||
// return it to the editor
|
||||
|
||||
|
||||
if (!isset($_REQUEST['type'])) {
|
||||
echo "No type given";
|
||||
echo 'No type given';
|
||||
exit;
|
||||
}
|
||||
$type = $_REQUEST['type'];
|
||||
if (!in_array($type, array('load_svg', 'import_svg', 'import_img'))) {
|
||||
echo "Not a recognized type";
|
||||
echo 'Not a recognized type';
|
||||
exit;
|
||||
}
|
||||
|
||||
require('allowedMimeTypes.php');
|
||||
|
||||
|
||||
$file = $_FILES['svg_file']['tmp_name'];
|
||||
|
||||
|
||||
$output = file_get_contents($file);
|
||||
|
||||
|
||||
$prefix = '';
|
||||
|
||||
// Make Data URL prefix for import image
|
||||
if ($type == 'import_img') {
|
||||
$info = getimagesize($file);
|
||||
if (!in_array($info['mime'], $allowedMimeTypesBySuffix)) {
|
||||
echo "Disallowed MIME for supplied file";
|
||||
echo 'Disallowed MIME for supplied file';
|
||||
exit;
|
||||
}
|
||||
$prefix = 'data:' . $info['mime'] . ';base64,';
|
||||
@@ -45,7 +45,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<script>
|
||||
|
||||
top.svgEditor.processFile("<?php
|
||||
top.svgEditor.processFile("<?php
|
||||
|
||||
// This should be safe since SVG edit does its own filtering (e.g., if an SVG file contains scripts)
|
||||
echo $prefix . base64_encode($output);
|
||||
|
||||
@@ -44,17 +44,17 @@ if ($suffix == '.svg') {
|
||||
$contents = base64_decode(substr($contents, $pos));
|
||||
}
|
||||
|
||||
header("Cache-Control: public");
|
||||
header("Content-Description: File Transfer");
|
||||
header('Cache-Control: public');
|
||||
header('Content-Description: File Transfer');
|
||||
|
||||
// See http://tools.ietf.org/html/rfc6266#section-4.1
|
||||
header("Content-Disposition: attachment; filename*=UTF-8''" . encodeRFC5987ValueChars(
|
||||
// preg_replace('@[\\\\/:*?"<>|]@', '', $file) // If we wanted to strip Windows-disallowed characters server-side (but not a security issue, so we can strip client-side instead)
|
||||
$file
|
||||
));
|
||||
header("Content-Type: " . $mime);
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header('Content-Type: ' . $mime);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
echo $contents;
|
||||
|
||||
?>
|
||||
|
||||
?>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>-</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -11,59 +12,6 @@
|
||||
<br>
|
||||
<a href="../../images/logo.png">logo.png</a>
|
||||
|
||||
<script>
|
||||
/* eslint-disable no-var */
|
||||
/* globals $ */
|
||||
$('a').click(function() {'use strict';
|
||||
var metaStr;
|
||||
var href = this.href;
|
||||
var target = window.parent;
|
||||
// Convert Non-SVG images to data URL first
|
||||
// (this could also have been done server-side by the library)
|
||||
if (this.href.indexOf('.svg') === -1) {
|
||||
|
||||
metaStr = JSON.stringify({
|
||||
name: $(this).text(),
|
||||
id: href
|
||||
});
|
||||
target.postMessage(metaStr, '*');
|
||||
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
var 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
|
||||
var dataurl;
|
||||
try {
|
||||
dataurl = canvas.toDataURL();
|
||||
} catch(err) {
|
||||
// This fails in Firefox with file:// URLs :(
|
||||
alert('Data URL conversion failed: ' + err);
|
||||
dataurl = '';
|
||||
}
|
||||
target.postMessage('|' + href + '|' + dataurl, '*');
|
||||
};
|
||||
img.src = href;
|
||||
} else {
|
||||
// Send metadata (also indicates file is about to be sent)
|
||||
metaStr = JSON.stringify({
|
||||
name: $(this).text(),
|
||||
id: href
|
||||
});
|
||||
target.postMessage(metaStr, '*');
|
||||
// Do ajax request for image's href value
|
||||
$.get(href, function (data) {
|
||||
data = '|' + href + '|' + data;
|
||||
// This is where the magic happens!
|
||||
target.postMessage(data, '*');
|
||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
51
editor/extensions/imagelib/index.js
Normal file
51
editor/extensions/imagelib/index.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/* eslint-disable no-var */
|
||||
/* globals $ */
|
||||
$('a').click(function () {
|
||||
'use strict';
|
||||
var metaStr;
|
||||
var href = this.href;
|
||||
var target = window.parent;
|
||||
// Convert Non-SVG images to data URL first
|
||||
// (this could also have been done server-side by the library)
|
||||
if (this.href.indexOf('.svg') === -1) {
|
||||
metaStr = JSON.stringify({
|
||||
name: $(this).text(),
|
||||
id: href
|
||||
});
|
||||
target.postMessage(metaStr, '*');
|
||||
|
||||
var img = new Image();
|
||||
img.onload = function () {
|
||||
var 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
|
||||
var dataurl;
|
||||
try {
|
||||
dataurl = canvas.toDataURL();
|
||||
} catch (err) {
|
||||
// This fails in Firefox with file:// URLs :(
|
||||
alert('Data URL conversion failed: ' + err);
|
||||
dataurl = '';
|
||||
}
|
||||
target.postMessage('|' + href + '|' + dataurl, '*');
|
||||
};
|
||||
img.src = href;
|
||||
} else {
|
||||
// Send metadata (also indicates file is about to be sent)
|
||||
metaStr = JSON.stringify({
|
||||
name: $(this).text(),
|
||||
id: href
|
||||
});
|
||||
target.postMessage(metaStr, '*');
|
||||
// Do ajax request for image's href value
|
||||
$.get(href, function (data) {
|
||||
data = '|' + href + '|' + data;
|
||||
// This is where the magic happens!
|
||||
target.postMessage(data, '*');
|
||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||
}
|
||||
return false;
|
||||
});
|
||||
Reference in New Issue
Block a user