- 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:
Brett Zamir
2018-05-16 08:53:27 +08:00
parent 5bcbb948eb
commit 340915be4e
51 changed files with 12031 additions and 12108 deletions

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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);
}
};
});

View File

@@ -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));
}
}

View File

@@ -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];
}
};
});

View File

@@ -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();
}

View File

@@ -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);
}
}
};
});

View File

@@ -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');
}
};
});

View File

@@ -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
}
};
});

View File

@@ -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');
}
};
});

View File

@@ -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
};

View File

@@ -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,

View File

@@ -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

View File

@@ -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});
}
});
}

View File

@@ -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];
}
};
});

View File

@@ -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;
}
});
}
});

View File

@@ -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, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;'); // < 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);
}
});

View File

@@ -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
};
}
};
});

View File

@@ -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];
}
};

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}]
};
});
}());

View File

@@ -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);
}
});

View File

@@ -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);

View File

@@ -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;
?>
?>

View File

@@ -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>

View 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;
});