Merge branch 'bzr/golem' of /Users/distler/Sites/code/instiki
This commit is contained in:
commit
459891b6c9
|
@ -87,6 +87,7 @@ function setupSVGedit(path){
|
||||||
} else {
|
} else {
|
||||||
var editor = window.open(path, 'Spoons!');
|
var editor = window.open(path, 'Spoons!');
|
||||||
}
|
}
|
||||||
|
editor.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var t = $('content');
|
var t = $('content');
|
||||||
|
@ -131,6 +132,9 @@ function setupSVGedit(path){
|
||||||
Event.observe(window, "message", function(event){
|
Event.observe(window, "message", function(event){
|
||||||
if(event.origin !== my_loc) { return;}
|
if(event.origin !== my_loc) { return;}
|
||||||
t.value = before + event.data + after;
|
t.value = before + event.data + after;
|
||||||
|
t.focus();
|
||||||
|
SVGeditButton.disabled = true;
|
||||||
|
SVGeditButton.value = 'Create SVG graphic';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
{"id": "tool_zoom", "title": "ज़ूम उपकरण"},
|
{"id": "tool_zoom", "title": "ज़ूम उपकरण"},
|
||||||
{"id": "zoom", "title": "बदलें स्तर ज़ूम"},
|
{"id": "zoom", "title": "बदलें स्तर ज़ूम"},
|
||||||
{"id": "zoomLabel", "textContent": "जूम:"},
|
{"id": "zoomLabel", "textContent": "जूम:"},
|
||||||
{"id": "sidepanel_handle", "textContent": "परतें", "title": "दायें/बाएं घसीट कर आकार बदलें"},
|
{"id": "sidepanel_handle","textContent":"प र तें","title":"दायें/बाएं घसीट कर आकार बदलें"},
|
||||||
{
|
{
|
||||||
"js_strings": {
|
"js_strings": {
|
||||||
"QerrorsRevertToSource": "आपके एस.वी.जी. स्रोत में त्रुटियों थी.\nक्या आप मूल एस.वी.जी स्रोत पर वापिस जाना चाहते हैं?",
|
"QerrorsRevertToSource": "आपके एस.वी.जी. स्रोत में त्रुटियों थी.\nक्या आप मूल एस.वी.जी स्रोत पर वापिस जाना चाहते हैं?",
|
||||||
|
|
|
@ -87,12 +87,12 @@
|
||||||
{"id":"tool_aligntop","title":"頂端對齊"},
|
{"id":"tool_aligntop","title":"頂端對齊"},
|
||||||
{"id":"tool_bold","title":"粗體"},
|
{"id":"tool_bold","title":"粗體"},
|
||||||
{"id":"tool_circle","title":"圓"},
|
{"id":"tool_circle","title":"圓"},
|
||||||
{"id":"tool_clear","title":"清空圖像"},
|
{"id":"tool_clear","textContent":"清空圖像"},
|
||||||
{"id":"tool_clone","title":"複製"},
|
{"id":"tool_clone","title":"複製"},
|
||||||
{"id":"tool_clone_multi","title":"複製所選元素"},
|
{"id":"tool_clone_multi","title":"複製所選元素"},
|
||||||
{"id":"tool_delete","title":"刪除"},
|
{"id":"tool_delete","title":"刪除"},
|
||||||
{"id":"tool_delete_multi","title":"刪除所選元素"},
|
{"id":"tool_delete_multi","title":"刪除所選元素"},
|
||||||
{"id":"tool_docprops","title":"文件屬性"},
|
{"id":"tool_docprops","textContent":"文件屬性"},
|
||||||
{"id":"tool_docprops_cancel","textContent":"取消"},
|
{"id":"tool_docprops_cancel","textContent":"取消"},
|
||||||
{"id":"tool_docprops_save","textContent":"保存"},
|
{"id":"tool_docprops_save","textContent":"保存"},
|
||||||
{"id":"tool_ellipse","title":"橢圓"},
|
{"id":"tool_ellipse","title":"橢圓"},
|
||||||
|
@ -108,12 +108,12 @@
|
||||||
{"id":"tool_node_clone","title":"增加節點"},
|
{"id":"tool_node_clone","title":"增加節點"},
|
||||||
{"id":"tool_node_delete","title":"刪除節點"},
|
{"id":"tool_node_delete","title":"刪除節點"},
|
||||||
{"id":"tool_node_link","title":"將控制點連起來"},
|
{"id":"tool_node_link","title":"將控制點連起來"},
|
||||||
{"id":"tool_open","title":"打開圖像"},
|
{"id":"tool_open","textContent":"打開圖像"},
|
||||||
{"id":"tool_path","title":"路徑工具"},
|
{"id":"tool_path","title":"路徑工具"},
|
||||||
{"id":"tool_rect","title":"矩形"},
|
{"id":"tool_rect","title":"矩形"},
|
||||||
{"id":"tool_redo","title":"復原"},
|
{"id":"tool_redo","title":"復原"},
|
||||||
{"id":"tool_reorient","title":"調整路徑"},
|
{"id":"tool_reorient","title":"調整路徑"},
|
||||||
{"id":"tool_save","title":"保存圖像"},
|
{"id":"tool_save","textContent":"保存圖像"},
|
||||||
{"id":"tool_select","title":"選擇工具"},
|
{"id":"tool_select","title":"選擇工具"},
|
||||||
{"id":"tool_source","title":"編輯SVG原始碼"},
|
{"id":"tool_source","title":"編輯SVG原始碼"},
|
||||||
{"id":"tool_source_cancel","textContent":"取消"},
|
{"id":"tool_source_cancel","textContent":"取消"},
|
||||||
|
@ -125,8 +125,6 @@
|
||||||
{"id":"tool_ungroup","title":"取消群組"},
|
{"id":"tool_ungroup","title":"取消群組"},
|
||||||
{"id":"tool_wireframe","title":"框線模式(只瀏覽線條)"},
|
{"id":"tool_wireframe","title":"框線模式(只瀏覽線條)"},
|
||||||
{"id":"tool_zoom","title":"縮放工具"},
|
{"id":"tool_zoom","title":"縮放工具"},
|
||||||
{"id":"tools_ellipse_show","title":"橢圓/圓工具"},
|
|
||||||
{"id":"tools_rect_show","title":"矩形/方形工具"},
|
|
||||||
{"id":"zoom","title":"更改縮放級別"},
|
{"id":"zoom","title":"更改縮放級別"},
|
||||||
{"id":"zoomLabel","textContent":"調整頁面大小:"},
|
{"id":"zoomLabel","textContent":"調整頁面大小:"},
|
||||||
{"id":"sidepanel_handle","textContent":"圖層","title":"拖拉以改變側邊面板的大小"},
|
{"id":"sidepanel_handle","textContent":"圖層","title":"拖拉以改變側邊面板的大小"},
|
||||||
|
|
|
@ -179,7 +179,6 @@ function svg_edit_setup() {
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=308590
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=308590
|
||||||
var saveHandler = function(window,svg) {
|
var saveHandler = function(window,svg) {
|
||||||
window.opener.postMessage(svg, window.location.protocol + '//' + window.location.host);
|
window.opener.postMessage(svg, window.location.protocol + '//' + window.location.host);
|
||||||
// window.open("data:image/svg+xml;base64," + Utils.encode64(svg));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// called when we've selected a different element
|
// called when we've selected a different element
|
||||||
|
@ -383,12 +382,23 @@ function svg_edit_setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var extAdded = function(window, ext) {
|
var extAdded = function(window, ext) {
|
||||||
if("buttons" in ext) {
|
|
||||||
|
var cb_called = false;
|
||||||
|
|
||||||
|
var runCallback = function() {
|
||||||
|
if(ext.callback && !cb_called) {
|
||||||
|
cb_called = true;
|
||||||
|
ext.callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ext.buttons) {
|
||||||
var fallback_obj = {},
|
var fallback_obj = {},
|
||||||
placement_obj = {},
|
placement_obj = {},
|
||||||
svgicons = ext.svgicons;
|
svgicons = ext.svgicons;
|
||||||
|
|
||||||
var holders = {};
|
var holders = {};
|
||||||
|
|
||||||
|
|
||||||
// Add buttons given by extension
|
// Add buttons given by extension
|
||||||
$.each(ext.buttons, function(i, btn) {
|
$.each(ext.buttons, function(i, btn) {
|
||||||
|
@ -515,10 +525,70 @@ function svg_edit_setup() {
|
||||||
setIconSize('m');
|
setIconSize('m');
|
||||||
setIconSize(old);
|
setIconSize(old);
|
||||||
}
|
}
|
||||||
|
runCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(ext.context_tools) {
|
||||||
|
$.each(ext.context_tools, function(i, tool) {
|
||||||
|
// Add select tool
|
||||||
|
var cont_id = tool.container_id?(' id="' + tool.container_id + '"'):"";
|
||||||
|
|
||||||
|
var panel = $('#' + tool.panel);
|
||||||
|
|
||||||
|
if(!panel.length) {
|
||||||
|
panel = $('<div>', {id: tool.panel}).appendTo("#tools_top");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Allow support for other types, or adding to existing tool
|
||||||
|
switch (tool.type) {
|
||||||
|
case 'select':
|
||||||
|
var html = '<label' + cont_id + '>'
|
||||||
|
+ '<select id="' + tool.id + '">';
|
||||||
|
$.each(tool.options, function(val, text) {
|
||||||
|
var sel = (val == tool.defval) ? " selected":"";
|
||||||
|
html += '<option value="'+val+'"' + sel + '>' + text + '</option>';
|
||||||
|
});
|
||||||
|
html += "</select></label>";
|
||||||
|
// Creates the tool, hides & adds it, returns the select element
|
||||||
|
var sel = $(html).appendTo(panel).find('select');
|
||||||
|
|
||||||
|
$.each(tool.events, function(evt, func) {
|
||||||
|
$(sel).bind(evt, func);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'input':
|
||||||
|
var html = '<label' + cont_id + '">'
|
||||||
|
+ '<span id="' + tool.id + '_label">'
|
||||||
|
+ tool.label + ':</span>'
|
||||||
|
+ '<input id="' + tool.id + '" title="' + tool.title
|
||||||
|
+ '" size="' + (tool.size || "4") + '" value="' + (tool.defval || "") + '" type="text"/></label>'
|
||||||
|
|
||||||
|
// Creates the tool, hides & adds it, returns the select element
|
||||||
|
|
||||||
|
// Add to given tool.panel
|
||||||
|
var inp = $(html).appendTo(panel).find('input');
|
||||||
|
|
||||||
|
if(tool.spindata) {
|
||||||
|
inp.SpinButton(tool.spindata);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tool.events) {
|
||||||
|
$.each(tool.events, function(evt, func) {
|
||||||
|
$(sel).bind(evt, func);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
runCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
var getPaint = function(color, opac) {
|
var getPaint = function(color, opac) {
|
||||||
|
@ -1865,7 +1935,7 @@ function svg_edit_setup() {
|
||||||
var bNoFill = (svgCanvas.getFillColor() == 'none');
|
var bNoFill = (svgCanvas.getFillColor() == 'none');
|
||||||
var bNoStroke = (svgCanvas.getStrokeColor() == 'none');
|
var bNoStroke = (svgCanvas.getStrokeColor() == 'none');
|
||||||
var buttonsNeedingStroke = [ '#tool_fhpath', '#tool_line' ];
|
var buttonsNeedingStroke = [ '#tool_fhpath', '#tool_line' ];
|
||||||
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text' ];
|
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text', '#tool_path'];
|
||||||
if (bNoStroke) {
|
if (bNoStroke) {
|
||||||
for (index in buttonsNeedingStroke) {
|
for (index in buttonsNeedingStroke) {
|
||||||
var button = buttonsNeedingStroke[index];
|
var button = buttonsNeedingStroke[index];
|
||||||
|
@ -2634,7 +2704,7 @@ function svg_edit_setup() {
|
||||||
updateCanvas(true);
|
updateCanvas(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// var revnums = "svg-editor.js ($Rev: 1342 $) ";
|
// var revnums = "svg-editor.js ($Rev: 1347 $) ";
|
||||||
// revnums += svgCanvas.getVersion();
|
// revnums += svgCanvas.getVersion();
|
||||||
// $('#copyright')[0].setAttribute("title", revnums);
|
// $('#copyright')[0].setAttribute("title", revnums);
|
||||||
return svgCanvas;
|
return svgCanvas;
|
||||||
|
|
|
@ -984,27 +984,6 @@ function BatchCommand(text) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addExtension = function(name, ext_func) {
|
|
||||||
if(!(name in extensions)) {
|
|
||||||
// Provide constants here (or should these be accessed through getSomething()?
|
|
||||||
var ext = ext_func({
|
|
||||||
content: svgcontent,
|
|
||||||
root: svgroot,
|
|
||||||
call: call,
|
|
||||||
getNextId: getNextId,
|
|
||||||
getElem: getElem,
|
|
||||||
addSvgElementFromJson: addSvgElementFromJson,
|
|
||||||
selectorManager: selectorManager,
|
|
||||||
findDefs: findDefs,
|
|
||||||
recalculateDimensions: recalculateDimensions
|
|
||||||
});
|
|
||||||
extensions[name] = ext;
|
|
||||||
call("extension_added", ext);
|
|
||||||
} else {
|
|
||||||
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This method rounds the incoming value to the nearest value based on the current_zoom
|
// This method rounds the incoming value to the nearest value based on the current_zoom
|
||||||
var round = function(val){
|
var round = function(val){
|
||||||
return parseInt(val*current_zoom)/current_zoom;
|
return parseInt(val*current_zoom)/current_zoom;
|
||||||
|
@ -2322,6 +2301,51 @@ function BatchCommand(text) {
|
||||||
return (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0);
|
return (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// expects three points to be sent, each point must have an x,y field
|
||||||
|
// returns an array of two points that are the smoothed
|
||||||
|
this.smoothControlPoints = function(ct1, ct2, pt) {
|
||||||
|
// each point must not be the origin
|
||||||
|
var x1 = ct1.x - pt.x,
|
||||||
|
y1 = ct1.y - pt.y,
|
||||||
|
x2 = ct2.x - pt.x,
|
||||||
|
y2 = ct2.y - pt.y;
|
||||||
|
|
||||||
|
if ( (x1 != 0 || y1 != 0) && (x2 != 0 || y2 != 0) ) {
|
||||||
|
var anglea = Math.atan2(y1,x1),
|
||||||
|
angleb = Math.atan2(y2,x2),
|
||||||
|
r1 = Math.sqrt(x1*x1+y1*y1),
|
||||||
|
r2 = Math.sqrt(x2*x2+y2*y2),
|
||||||
|
nct1 = svgroot.createSVGPoint(),
|
||||||
|
nct2 = svgroot.createSVGPoint();
|
||||||
|
if (anglea < 0) { anglea += 2*Math.PI; }
|
||||||
|
if (angleb < 0) { angleb += 2*Math.PI; }
|
||||||
|
|
||||||
|
var angleBetween = Math.abs(anglea - angleb),
|
||||||
|
angleDiff = Math.abs(Math.PI - angleBetween)/2;
|
||||||
|
|
||||||
|
var new_anglea, new_angleb;
|
||||||
|
if (anglea - angleb > 0) {
|
||||||
|
new_anglea = angleBetween < Math.PI ? (anglea + angleDiff) : (anglea - angleDiff);
|
||||||
|
new_angleb = angleBetween < Math.PI ? (angleb - angleDiff) : (angleb + angleDiff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_anglea = angleBetween < Math.PI ? (anglea - angleDiff) : (anglea + angleDiff);
|
||||||
|
new_angleb = angleBetween < Math.PI ? (angleb + angleDiff) : (angleb - angleDiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate the points
|
||||||
|
nct1.x = r1 * Math.cos(new_anglea) + pt.x;
|
||||||
|
nct1.y = r1 * Math.sin(new_anglea) + pt.y;
|
||||||
|
nct2.x = r2 * Math.cos(new_angleb) + pt.x;
|
||||||
|
nct2.y = r2 * Math.sin(new_angleb) + pt.y;
|
||||||
|
|
||||||
|
return [nct1, nct2];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
var smoothControlPoints = this.smoothControlPoints;
|
||||||
|
|
||||||
|
|
||||||
// matrixMultiply() is provided because WebKit didn't implement multiply() correctly
|
// matrixMultiply() is provided because WebKit didn't implement multiply() correctly
|
||||||
// on the SVGMatrix interface. See https://bugs.webkit.org/show_bug.cgi?id=16062
|
// on the SVGMatrix interface. See https://bugs.webkit.org/show_bug.cgi?id=16062
|
||||||
// This function tries to return a SVGMatrix that is the multiplication m1*m2.
|
// This function tries to return a SVGMatrix that is the multiplication m1*m2.
|
||||||
|
@ -3521,6 +3545,18 @@ function BatchCommand(text) {
|
||||||
var N = points.numberOfItems;
|
var N = points.numberOfItems;
|
||||||
if (N >= 4) {
|
if (N >= 4) {
|
||||||
// loop through every 3 points and convert to a cubic bezier curve segment
|
// loop through every 3 points and convert to a cubic bezier curve segment
|
||||||
|
//
|
||||||
|
// NOTE: this is cheating, it means that every 3 points has the potential to
|
||||||
|
// be a corner instead of treating each point in an equal manner. In general,
|
||||||
|
// this technique does not look that good.
|
||||||
|
//
|
||||||
|
// I am open to better ideas!
|
||||||
|
//
|
||||||
|
// Reading:
|
||||||
|
// - http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm
|
||||||
|
// - http://www.codeproject.com/KB/graphics/BezierSpline.aspx?msg=2956963
|
||||||
|
// - http://www.ian-ko.com/ET_GeoWizards/UserGuide/smooth.htm
|
||||||
|
// - http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-der.html
|
||||||
var curpos = points.getItem(0), prevCtlPt = null;
|
var curpos = points.getItem(0), prevCtlPt = null;
|
||||||
var d = [];
|
var d = [];
|
||||||
d.push(["M",curpos.x,",",curpos.y," C"].join(""));
|
d.push(["M",curpos.x,",",curpos.y," C"].join(""));
|
||||||
|
@ -3532,7 +3568,14 @@ function BatchCommand(text) {
|
||||||
// if the previous segment had a control point, we want to smooth out
|
// if the previous segment had a control point, we want to smooth out
|
||||||
// the control points on both sides
|
// the control points on both sides
|
||||||
if (prevCtlPt) {
|
if (prevCtlPt) {
|
||||||
// TODO: fancy processing here :)
|
var newpts = smoothControlPoints( prevCtlPt, ct1, curpos );
|
||||||
|
if (newpts && newpts.length == 2) {
|
||||||
|
var prevArr = d[d.length-1].split(',');
|
||||||
|
prevArr[2] = newpts[0].x;
|
||||||
|
prevArr[3] = newpts[0].y;
|
||||||
|
d[d.length-1] = prevArr.join(',');
|
||||||
|
ct1 = newpts[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.push([ct1.x,ct1.y,ct2.x,ct2.y,end.x,end.y].join(','));
|
d.push([ct1.x,ct1.y,ct2.x,ct2.y,end.x,end.y].join(','));
|
||||||
|
@ -5223,9 +5266,8 @@ function BatchCommand(text) {
|
||||||
if(opts) $.extend(save_options, opts);
|
if(opts) $.extend(save_options, opts);
|
||||||
save_options.apply = true;
|
save_options.apply = true;
|
||||||
|
|
||||||
var str = "<?xml version=\"1.0\" standalone=\"no\"?>\n";
|
|
||||||
// no need for doctype, see http://jwatt.org/svg/authoring/#doctype-declaration
|
// no need for doctype, see http://jwatt.org/svg/authoring/#doctype-declaration
|
||||||
str += svgCanvasToString();
|
var str = svgCanvasToString();
|
||||||
call("saved", str);
|
call("saved", str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6550,6 +6592,9 @@ function BatchCommand(text) {
|
||||||
// selector if the element is in that array
|
// selector if the element is in that array
|
||||||
if ($.inArray(elem, selectedElements) != -1) {
|
if ($.inArray(elem, selectedElements) != -1) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
// Due to element replacement, this element may no longer
|
||||||
|
// be part of the DOM
|
||||||
|
if(!elem.parentNode) return;
|
||||||
selectorManager.requestSelector(elem).resize();
|
selectorManager.requestSelector(elem).resize();
|
||||||
},0);
|
},0);
|
||||||
}
|
}
|
||||||
|
@ -7392,7 +7437,7 @@ function BatchCommand(text) {
|
||||||
// Function: getVersion
|
// Function: getVersion
|
||||||
// Returns a string which describes the revision number of SvgCanvas.
|
// Returns a string which describes the revision number of SvgCanvas.
|
||||||
this.getVersion = function() {
|
this.getVersion = function() {
|
||||||
return "svgcanvas.js ($Rev: 1341 $)";
|
return "svgcanvas.js ($Rev: 1349 $)";
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setUiStrings = function(strs) {
|
this.setUiStrings = function(strs) {
|
||||||
|
@ -7427,6 +7472,78 @@ function BatchCommand(text) {
|
||||||
// return svgdoc.getElementById(id);
|
// return svgdoc.getElementById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Being able to access private methods publicly seems wrong somehow,
|
||||||
|
// but currently appears to be the best way to allow testing and provide
|
||||||
|
// access to them to plugins.
|
||||||
|
this.getPrivateMethods = function() {
|
||||||
|
return {
|
||||||
|
addCommandToHistory: addCommandToHistory,
|
||||||
|
addGradient: addGradient,
|
||||||
|
addSvgElementFromJson: addSvgElementFromJson,
|
||||||
|
assignAttributes: assignAttributes,
|
||||||
|
BatchCommand: BatchCommand,
|
||||||
|
call: call,
|
||||||
|
ChangeElementCommand: ChangeElementCommand,
|
||||||
|
cleanupElement: cleanupElement,
|
||||||
|
copyElem: copyElem,
|
||||||
|
ffClone: ffClone,
|
||||||
|
findDefs: findDefs,
|
||||||
|
findDuplicateGradient: findDuplicateGradient,
|
||||||
|
fromXml: fromXml,
|
||||||
|
getElem: getElem,
|
||||||
|
getId: getId,
|
||||||
|
getIntersectionList: getIntersectionList,
|
||||||
|
getNextId: getNextId,
|
||||||
|
getPathBBox: getPathBBox,
|
||||||
|
getUrlFromAttr: getUrlFromAttr,
|
||||||
|
hasMatrixTransform: hasMatrixTransform,
|
||||||
|
identifyLayers: identifyLayers,
|
||||||
|
InsertElementCommand: InsertElementCommand,
|
||||||
|
isIdentity: isIdentity,
|
||||||
|
logMatrix: logMatrix,
|
||||||
|
matrixMultiply: matrixMultiply,
|
||||||
|
MoveElementCommand: MoveElementCommand,
|
||||||
|
preventClickDefault: preventClickDefault,
|
||||||
|
recalculateAllSelectedDimensions: recalculateAllSelectedDimensions,
|
||||||
|
recalculateDimensions: recalculateDimensions,
|
||||||
|
remapElement: remapElement,
|
||||||
|
RemoveElementCommand: RemoveElementCommand,
|
||||||
|
removeUnusedGrads: removeUnusedGrads,
|
||||||
|
resetUndoStack: resetUndoStack,
|
||||||
|
round: round,
|
||||||
|
runExtensions: runExtensions,
|
||||||
|
sanitizeSvg: sanitizeSvg,
|
||||||
|
Selector: Selector,
|
||||||
|
SelectorManager: SelectorManager,
|
||||||
|
shortFloat: shortFloat,
|
||||||
|
svgCanvasToString: svgCanvasToString,
|
||||||
|
SVGEditTransformList: SVGEditTransformList,
|
||||||
|
svgToString: svgToString,
|
||||||
|
toString: toString,
|
||||||
|
toXml: toXml,
|
||||||
|
transformBox: transformBox,
|
||||||
|
transformListToTransform: transformListToTransform,
|
||||||
|
transformPoint: transformPoint,
|
||||||
|
transformToObj: transformToObj,
|
||||||
|
walkTree: walkTree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addExtension = function(name, ext_func) {
|
||||||
|
if(!(name in extensions)) {
|
||||||
|
// Provide private vars/funcs here. Is there a better way to do this?
|
||||||
|
var ext = ext_func($.extend(canvas.getPrivateMethods(), {
|
||||||
|
svgroot: svgroot,
|
||||||
|
svgcontent: svgcontent,
|
||||||
|
selectorManager: selectorManager
|
||||||
|
}));
|
||||||
|
extensions[name] = ext;
|
||||||
|
call("extension_added", ext);
|
||||||
|
} else {
|
||||||
|
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Test support for features/bugs
|
// Test support for features/bugs
|
||||||
(function() {
|
(function() {
|
||||||
// segList functions (for FF1.5 and 2.0)
|
// segList functions (for FF1.5 and 2.0)
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
svgCanvas.addExtension("Arrows", function(S) {
|
svgCanvas.addExtension("Arrows", function(S) {
|
||||||
var svgcontent = S.content,
|
var svgcontent = S.svgcontent,
|
||||||
getElem = S.getElem,
|
|
||||||
addElem = S.addSvgElementFromJson,
|
addElem = S.addSvgElementFromJson,
|
||||||
selElems;
|
selElems;
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ $(function() {
|
||||||
|
|
||||||
function addMarker(id, type) {
|
function addMarker(id, type) {
|
||||||
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
||||||
var marker = getElem(id);
|
var marker = S.getElem(id);
|
||||||
|
|
||||||
var pathdata = {
|
var pathdata = {
|
||||||
se_arrow_fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8},
|
se_arrow_fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8},
|
||||||
|
@ -104,7 +103,8 @@ $(function() {
|
||||||
marker.setAttribute('refX', data.refx);
|
marker.setAttribute('refX', data.refx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setArrow(type) {
|
function setArrow() {
|
||||||
|
var type = this.value;
|
||||||
resetMarker();
|
resetMarker();
|
||||||
|
|
||||||
if(type == "none") {
|
if(type == "none") {
|
||||||
|
@ -114,7 +114,6 @@ $(function() {
|
||||||
var fw_id = "se_arrow_fw";
|
var fw_id = "se_arrow_fw";
|
||||||
var bk_id = "se_arrow_bk";
|
var bk_id = "se_arrow_bk";
|
||||||
|
|
||||||
|
|
||||||
// Set marker on element
|
// Set marker on element
|
||||||
var id = fw_id;
|
var id = fw_id;
|
||||||
if(type == "mid_bk") {
|
if(type == "mid_bk") {
|
||||||
|
@ -134,24 +133,29 @@ $(function() {
|
||||||
S.call("changed", selElems);
|
S.call("changed", selElems);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init code
|
|
||||||
(function() {
|
|
||||||
var conn_tools = $('<div id="arrow_panel">\
|
|
||||||
<label><select id="arrow_list">\
|
|
||||||
<option value="none">No arrow</option>\
|
|
||||||
<option value="end">----></option>\
|
|
||||||
<option value="start"><----</option>\
|
|
||||||
<option value="both"><---></option>\
|
|
||||||
<option value="mid">-->--</option>\
|
|
||||||
<option value="mid_bk">--<--</option>\
|
|
||||||
</select></label></div>"').hide().appendTo("#tools_top");
|
|
||||||
$('#arrow_list').change(function() {
|
|
||||||
setArrow(this.value);
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: "Arrows",
|
name: "Arrows",
|
||||||
|
context_tools: [{
|
||||||
|
type: "select",
|
||||||
|
panel: "arrow_panel",
|
||||||
|
title: "Select arrow type",
|
||||||
|
id: "arrow_list",
|
||||||
|
options: {
|
||||||
|
none: "No arrow",
|
||||||
|
end: "---->",
|
||||||
|
start: "<----",
|
||||||
|
both: "<--->",
|
||||||
|
mid: "-->--",
|
||||||
|
mid_bk: "--<--"
|
||||||
|
},
|
||||||
|
defval: "none",
|
||||||
|
events: {
|
||||||
|
change: setArrow
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
callback: function() {
|
||||||
|
$('#arrow_panel').hide();
|
||||||
|
},
|
||||||
addLangData: function(lang) {
|
addLangData: function(lang) {
|
||||||
return {
|
return {
|
||||||
data: lang_list[lang]
|
data: lang_list[lang]
|
||||||
|
@ -180,4 +184,4 @@ $(function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
svgCanvas.addExtension("Connector", function(S) {
|
svgCanvas.addExtension("Connector", function(S) {
|
||||||
var svgcontent = S.content,
|
var svgcontent = S.svgcontent,
|
||||||
svgroot = S.root,
|
svgroot = S.svgroot,
|
||||||
getNextId = S.getNextId,
|
getNextId = S.getNextId,
|
||||||
getElem = S.getElem,
|
getElem = S.getElem,
|
||||||
addElem = S.addSvgElementFromJson,
|
addElem = S.addSvgElementFromJson,
|
||||||
|
@ -104,14 +104,29 @@ $(function() {
|
||||||
svgCanvas.removeFromSelection($(conn_sel).toArray());
|
svgCanvas.removeFromSelection($(conn_sel).toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loop through selected elements
|
||||||
while(i--) {
|
while(i--) {
|
||||||
var elem = all_els[i];
|
var elem = all_els[i];
|
||||||
if(!elem) continue;
|
if(!elem) continue;
|
||||||
|
|
||||||
|
// Element was deleted, so delete connector
|
||||||
|
var was_deleted = !elem.parentNode;
|
||||||
|
|
||||||
|
// Skip connector
|
||||||
if($(elem).data('c_start')) continue;
|
if($(elem).data('c_start')) continue;
|
||||||
|
|
||||||
|
// Loop through connectors to see if one is connected to the element
|
||||||
connectors.each(function() {
|
connectors.each(function() {
|
||||||
var start = $(this).data("c_start");
|
var start = $(this).data("c_start");
|
||||||
var end = $(this).data("c_end");
|
var end = $(this).data("c_end");
|
||||||
|
|
||||||
|
// Connector found for this element
|
||||||
if(start == elem.id || end == elem.id) {
|
if(start == elem.id || end == elem.id) {
|
||||||
|
|
||||||
|
if(was_deleted) {
|
||||||
|
$(this).remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||||
connections.push({
|
connections.push({
|
||||||
elem: elem,
|
elem: elem,
|
||||||
|
@ -138,8 +153,8 @@ $(function() {
|
||||||
var line = conn.connector;
|
var line = conn.connector;
|
||||||
var elem = conn.elem;
|
var elem = conn.elem;
|
||||||
|
|
||||||
var pre = conn.is_start?'start':'end';
|
|
||||||
var sw = line.getAttribute('stroke-width');
|
var sw = line.getAttribute('stroke-width');
|
||||||
|
var pre = conn.is_start?'start':'end';
|
||||||
|
|
||||||
// Update bbox for this element
|
// Update bbox for this element
|
||||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||||
|
@ -458,6 +473,7 @@ $(function() {
|
||||||
se_ns = svgCanvas.getEditorNS(true);
|
se_ns = svgCanvas.getEditorNS(true);
|
||||||
cur_line.setAttributeNS(se_ns, "se:connector", conn_str);
|
cur_line.setAttributeNS(se_ns, "se:connector", conn_str);
|
||||||
cur_line.setAttribute('class', conn_sel.substr(1));
|
cur_line.setAttribute('class', conn_sel.substr(1));
|
||||||
|
cur_line.setAttribute('opacity', 1);
|
||||||
svgCanvas.addToSelection([cur_line]);
|
svgCanvas.addToSelection([cur_line]);
|
||||||
svgCanvas.moveToBottomSelectedElement();
|
svgCanvas.moveToBottomSelectedElement();
|
||||||
selManager.requestSelector(cur_line).showGrips(false);
|
selManager.requestSelector(cur_line).showGrips(false);
|
||||||
|
@ -507,11 +523,40 @@ $(function() {
|
||||||
elem.getAttribute("marker-end")
|
elem.getAttribute("marker-end")
|
||||||
)) {
|
)) {
|
||||||
var start = elem.getAttribute("marker-start");
|
var start = elem.getAttribute("marker-start");
|
||||||
|
var mid = elem.getAttribute("marker-mid");
|
||||||
var end = elem.getAttribute("marker-end");
|
var end = elem.getAttribute("marker-end");
|
||||||
cur_line = elem;
|
cur_line = elem;
|
||||||
$(elem)
|
$(elem)
|
||||||
.data("start_off", !!start)
|
.data("start_off", !!start)
|
||||||
.data("end_off", !!end);
|
.data("end_off", !!end);
|
||||||
|
|
||||||
|
if(elem.tagName == "line" && mid) {
|
||||||
|
// Convert to polyline to accept mid-arrow
|
||||||
|
|
||||||
|
var x1 = elem.getAttribute('x1')-0;
|
||||||
|
var x2 = elem.getAttribute('x2')-0;
|
||||||
|
var y1 = elem.getAttribute('y1')-0;
|
||||||
|
var y2 = elem.getAttribute('y2')-0;
|
||||||
|
var id = elem.id;
|
||||||
|
|
||||||
|
var mid_pt = (' '+((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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(elem).after(pline).remove();
|
||||||
|
svgCanvas.clearSelection();
|
||||||
|
pline.id = id;
|
||||||
|
svgCanvas.addToSelection([pline]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
updateConnectors();
|
updateConnectors();
|
||||||
},
|
},
|
||||||
|
|
52
public/svg-edit/extras/tojson.py
Normal file
52
public/svg-edit/extras/tojson.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import sys, json, codecs
|
||||||
|
infile = codecs.open(sys.argv[1], "r", "utf-8")
|
||||||
|
outfile = codecs.open(sys.argv[1][:-3], "w", "utf-8")
|
||||||
|
indata = infile.readlines()
|
||||||
|
look = False
|
||||||
|
out = "[\n"
|
||||||
|
js = []
|
||||||
|
jss = ""
|
||||||
|
|
||||||
|
def readfrompos(pos):
|
||||||
|
global out
|
||||||
|
global js
|
||||||
|
|
||||||
|
if (indata[pos].startswith("#, -x-svg-edit-title")) or (indata[pos].startswith("#, -x-svg-edit-textContent")):
|
||||||
|
out += '{'
|
||||||
|
out += '"id": '
|
||||||
|
out += " ".join(indata[pos+1].split()[1:]) + ", "
|
||||||
|
out += '"' + line[15:].strip() + '": '
|
||||||
|
out += " ".join(indata[pos+2].split()[1:])
|
||||||
|
out += '}'
|
||||||
|
elif (indata[pos].startswith("#, -x-svg-edit-both")):
|
||||||
|
out += '{'
|
||||||
|
out += '"id": '
|
||||||
|
out += " ".join(indata[pos+1].split()[1:]) + ", "
|
||||||
|
out += '"textContent": '
|
||||||
|
out += '"' + " ".join(indata[pos+2].split()[1:]).split('|')[1] + ', '
|
||||||
|
out += '"title": '
|
||||||
|
out += " ".join(indata[pos+2].split()[1:]).split('|')[0] + '"'
|
||||||
|
out += '}'
|
||||||
|
elif (indata[pos].startswith("#, -x-svg-edit-js_strings")):
|
||||||
|
js.append((" ".join(indata[pos+1].split()[1:]), " ".join(indata[pos+2].split()[1:])))
|
||||||
|
|
||||||
|
for pos, line in enumerate(indata):
|
||||||
|
if (not look) and (line.startswith('# ---')):
|
||||||
|
look = True
|
||||||
|
marker = pos
|
||||||
|
elif (look) and (line.startswith('#, -x-svg-edit')):
|
||||||
|
readfrompos(pos)
|
||||||
|
|
||||||
|
js.sort()
|
||||||
|
|
||||||
|
for j in js:
|
||||||
|
jss += " %s: %s,\n" % (j[0], j[1])
|
||||||
|
|
||||||
|
out += '{\n "js_strings": {\n'
|
||||||
|
out += str(jss)
|
||||||
|
out += ' "": ""\n }'
|
||||||
|
out += "\n}"
|
||||||
|
out += "\n]"
|
||||||
|
out = out.replace('}{', '},\n{')
|
||||||
|
|
||||||
|
outfile.write(out)
|
39
public/svg-edit/extras/topo.py
Normal file
39
public/svg-edit/extras/topo.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import sys, json, codecs
|
||||||
|
infile = json.load(codecs.open(sys.argv[1], "r", "utf-8"))
|
||||||
|
outfile = codecs.open(sys.argv[1] + ".po", "w", "utf-8")
|
||||||
|
out = []
|
||||||
|
|
||||||
|
out.append("""# LANGUAGE FILE FOR SVG-EDIT, AUTOGENERATED BY TOPO.PY
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Content-Type: text/plain; charset=utf-8\\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\\n"
|
||||||
|
|
||||||
|
# ---
|
||||||
|
|
||||||
|
""")
|
||||||
|
|
||||||
|
def printstr(flag, i, s):
|
||||||
|
out.append('\n')
|
||||||
|
if flag == '-x-svg-edit-both':
|
||||||
|
out.append("# Enter the title first, then the contents, seperated by a pipe char (|)\n")
|
||||||
|
out.append("#, " + flag + '\n')
|
||||||
|
out.append("msgid \"" + i + "\"" + '\n')
|
||||||
|
out.append("msgstr \"" + s.replace('\n', '\\n') + "\"" + '\n')
|
||||||
|
|
||||||
|
for line in infile:
|
||||||
|
if line.has_key('title') and line.has_key('textContent'):
|
||||||
|
printstr('-x-svg-edit-both', line['id'], "|".join(((line['title'], line['textContent']))))
|
||||||
|
elif line.has_key('title'):
|
||||||
|
printstr('-x-svg-edit-title', line['id'], line['title'])
|
||||||
|
elif line.has_key('textContent'):
|
||||||
|
printstr('-x-svg-edit-textContent', line['id'], line['textContent'])
|
||||||
|
elif line.has_key('js_strings'):
|
||||||
|
for i, s in line['js_strings'].items():
|
||||||
|
printstr('-x-svg-edit-js_strings', i, s)
|
||||||
|
else:
|
||||||
|
pass # The line wasn't really a string
|
||||||
|
|
||||||
|
outfile.writelines(out)
|
||||||
|
outfile.close()
|
Loading…
Reference in a new issue