Make Embedded MathML Visible
Thanks to Jeff Schiller for tracking down the problem (and committing preliminary MathML support to SVG-Edit).
This commit is contained in:
parent
7114e46817
commit
d362b886c2
75
public/svg-edit/editor/extensions/ext-closepath.js
Normal file
75
public/svg-edit/editor/extensions/ext-closepath.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* ext-closepath.js
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2
|
||||||
|
*
|
||||||
|
* Copyright(c) 2010 Jeff Schiller
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This extension adds a simple button to the contextual panel for paths
|
||||||
|
// The button toggles whether the path is open or closed
|
||||||
|
$(function() {
|
||||||
|
svgCanvas.addExtension("ClosePath", function(S) {
|
||||||
|
var selElems,
|
||||||
|
updateButton = function(path) {
|
||||||
|
var seglist = path.pathSegList,
|
||||||
|
button = $('#closepath_panel > div.tool_button')[0];
|
||||||
|
$(button).html(seglist.getItem(seglist.numberOfItems - 1).pathSegType==1 ? "open":"close");
|
||||||
|
},
|
||||||
|
showPanel = function(on) {
|
||||||
|
$('#closepath_panel').toggle(on);
|
||||||
|
if (on) {
|
||||||
|
var path = selElems[0];
|
||||||
|
if (path) updateButton(path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleClosed = function() {
|
||||||
|
var path = selElems[0];
|
||||||
|
if (path) {
|
||||||
|
var seglist = path.pathSegList,
|
||||||
|
last = seglist.numberOfItems - 1;
|
||||||
|
// is closed
|
||||||
|
if(seglist.getItem(last).pathSegType == 1) {
|
||||||
|
seglist.removeItem(last);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
seglist.appendItem(path.createSVGPathSegClosePath());
|
||||||
|
}
|
||||||
|
updateButton(path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: "ClosePath",
|
||||||
|
context_tools: [{
|
||||||
|
type: "tool_button",
|
||||||
|
panel: "closepath_panel",
|
||||||
|
title: "Open or Close path",
|
||||||
|
id: "close",
|
||||||
|
events: { mousedown: toggleClosed }
|
||||||
|
}],
|
||||||
|
callback: function() {
|
||||||
|
$('#closepath_panel').hide();
|
||||||
|
},
|
||||||
|
selectedChanged: function(opts) {
|
||||||
|
selElems = opts.elems;
|
||||||
|
var i = selElems.length;
|
||||||
|
|
||||||
|
while(i--) {
|
||||||
|
var elem = selElems[i];
|
||||||
|
if(elem && elem.tagName == 'path') {
|
||||||
|
if(opts.selectedElement && !opts.multiselected) {
|
||||||
|
showPanel(true);
|
||||||
|
} else {
|
||||||
|
showPanel(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showPanel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
body {
|
body {
|
||||||
background: #E8E8E8;
|
background: #E8E8E8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 640px;
|
width: 640px;
|
||||||
height: 480px;
|
height: 480px;
|
||||||
|
line-height:normal;
|
||||||
-apple-dashboard-region:dashboard-region(control rectangle 0px 0px 0px 0px); /* for widget regions that shouldn't react to dragging */
|
-apple-dashboard-region:dashboard-region(control rectangle 0px 0px 0px 0px); /* for widget regions that shouldn't react to dragging */
|
||||||
position: relative;
|
position: relative;
|
||||||
/*
|
/*
|
||||||
|
@ -957,3 +958,4 @@ button#tool_docprops_cancel {
|
||||||
-webkit-border-radius: 0px;
|
-webkit-border-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreignObject { line-height:1.0; }
|
|
@ -18,6 +18,7 @@
|
||||||
<script type="text/javascript" src="locale/locale.js"></script>
|
<script type="text/javascript" src="locale/locale.js"></script>
|
||||||
<script type="text/javascript" src="svgcanvas.js"></script>
|
<script type="text/javascript" src="svgcanvas.js"></script>
|
||||||
<script type="text/javascript" src="svg-editor.js"></script>
|
<script type="text/javascript" src="svg-editor.js"></script>
|
||||||
|
<script type="text/javascript" src="extensions/ext-closepath.js"></script>
|
||||||
<script type="text/javascript" src="extensions/ext-arrows.js"></script>
|
<script type="text/javascript" src="extensions/ext-arrows.js"></script>
|
||||||
<script type="text/javascript" src="extensions/ext-connector.js"></script>
|
<script type="text/javascript" src="extensions/ext-connector.js"></script>
|
||||||
|
|
||||||
|
|
|
@ -166,8 +166,6 @@ function svg_edit_setup() {
|
||||||
var multiselected = false;
|
var multiselected = false;
|
||||||
var editingsource = false;
|
var editingsource = false;
|
||||||
var docprops = false;
|
var docprops = false;
|
||||||
var length_attrs = ['x','y','x1','x2','y1','y2','cx','cy','width','height','r','rx','ry','width','height','radius'];
|
|
||||||
var length_types = ['em','ex','px','cm','mm','in','pt','pc','%'];
|
|
||||||
|
|
||||||
var fillPaint = new $.jGraduate.Paint({solidColor: "FF0000"}); // solid red
|
var fillPaint = new $.jGraduate.Paint({solidColor: "FF0000"}); // solid red
|
||||||
var strokePaint = new $.jGraduate.Paint({solidColor: "000000"}); // solid black
|
var strokePaint = new $.jGraduate.Paint({solidColor: "000000"}); // solid black
|
||||||
|
@ -177,7 +175,7 @@ function svg_edit_setup() {
|
||||||
// with a gradient will appear black in Firefox, etc. See bug 308590
|
// with a gradient will appear black in Firefox, etc. See bug 308590
|
||||||
// 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
// called when we've selected a different element
|
// called when we've selected a different element
|
||||||
|
@ -542,6 +540,15 @@ function svg_edit_setup() {
|
||||||
|
|
||||||
// TODO: Allow support for other types, or adding to existing tool
|
// TODO: Allow support for other types, or adding to existing tool
|
||||||
switch (tool.type) {
|
switch (tool.type) {
|
||||||
|
case 'tool_button':
|
||||||
|
var html = '<div class="tool_button">' + tool.id + '</div>';
|
||||||
|
var div = $(html).appendTo(panel);
|
||||||
|
if (tool.events) {
|
||||||
|
$.each(tool.events, function(evt, func) {
|
||||||
|
$(div).bind(evt, func);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'select':
|
case 'select':
|
||||||
var html = '<label' + cont_id + '>'
|
var html = '<label' + cont_id + '>'
|
||||||
+ '<select id="' + tool.id + '">';
|
+ '<select id="' + tool.id + '">';
|
||||||
|
@ -977,20 +984,7 @@ function svg_edit_setup() {
|
||||||
$('.attr_changer').change(function() {
|
$('.attr_changer').change(function() {
|
||||||
var attr = this.getAttribute("data-attr");
|
var attr = this.getAttribute("data-attr");
|
||||||
var val = this.value;
|
var val = this.value;
|
||||||
var valid = false;
|
var valid = svgCanvas.isValidUnit(attr, val);
|
||||||
if($.inArray(attr, length_attrs) != -1) {
|
|
||||||
if(!isNaN(val)) {
|
|
||||||
valid = true;
|
|
||||||
} else {
|
|
||||||
//TODO: Allow the values in length_types, then uncomment this:
|
|
||||||
// val = val.toLowerCase();
|
|
||||||
// $.each(length_types, function(i, unit) {
|
|
||||||
// if(valid) return;
|
|
||||||
// var re = new RegExp('^-?[\\d\\.]+' + unit + '$');
|
|
||||||
// if(re.test(val)) valid = true;
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
} else valid = true;
|
|
||||||
|
|
||||||
if(!valid) {
|
if(!valid) {
|
||||||
$.alert(uiStrings.invalidAttrValGiven);
|
$.alert(uiStrings.invalidAttrValGiven);
|
||||||
|
@ -2711,7 +2705,7 @@ function svg_edit_setup() {
|
||||||
updateCanvas(true);
|
updateCanvas(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// var revnums = "svg-editor.js ($Rev: 1362 $) ";
|
// var revnums = "svg-editor.js ($Rev: 1367 $) ";
|
||||||
// revnums += svgCanvas.getVersion();
|
// revnums += svgCanvas.getVersion();
|
||||||
// $('#copyright')[0].setAttribute("title", revnums);
|
// $('#copyright')[0].setAttribute("title", revnums);
|
||||||
return svgCanvas;
|
return svgCanvas;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* svgcanvas.js
|
* svgcanvas.js
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2
|
* Licensed under the Apache License, Version 2
|
||||||
|
@ -90,6 +90,7 @@ var isOpera = !!window.opera,
|
||||||
|
|
||||||
// this defines which elements and attributes that we support
|
// this defines which elements and attributes that we support
|
||||||
svgWhiteList = {
|
svgWhiteList = {
|
||||||
|
// SVG Elements
|
||||||
"a": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform", "xlink:href", "xlink:title"],
|
"a": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform", "xlink:href", "xlink:title"],
|
||||||
"circle": ["class", "clip-path", "clip-rule", "cx", "cy", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "r", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
"circle": ["class", "clip-path", "clip-rule", "cx", "cy", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "r", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
||||||
"clipPath": ["class", "clipPathUnits", "id"],
|
"clipPath": ["class", "clipPathUnits", "id"],
|
||||||
|
@ -98,7 +99,7 @@ var isOpera = !!window.opera,
|
||||||
"ellipse": ["class", "clip-path", "clip-rule", "cx", "cy", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "requiredFeatures", "rx", "ry", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
"ellipse": ["class", "clip-path", "clip-rule", "cx", "cy", "fill", "fill-opacity", "fill-rule", "filter", "id", "mask", "opacity", "requiredFeatures", "rx", "ry", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
||||||
"feGaussianBlur": ["class", "id", "requiredFeatures", "stdDeviation"],
|
"feGaussianBlur": ["class", "id", "requiredFeatures", "stdDeviation"],
|
||||||
"filter": ["class", "filterRes", "filterUnits", "height", "id", "primitiveUnits", "requiredFeatures", "width", "x", "xlink:href", "y"],
|
"filter": ["class", "filterRes", "filterUnits", "height", "id", "primitiveUnits", "requiredFeatures", "width", "x", "xlink:href", "y"],
|
||||||
"foreignObject": ["class", "font-size", "height", "id", "markdown", "opacity", "requiredFeatures", "style", "width", "x", "y"],
|
"foreignObject": ["class", "font-size", "height", "id", "markdown", "opacity", "overflow", "requiredFeatures", "style", "width", "x", "y"],
|
||||||
"g": ["class", "clip-path", "clip-rule", "id", "display", "fill", "fill-opacity", "fill-rule", "filter", "mask", "opacity", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
"g": ["class", "clip-path", "clip-rule", "id", "display", "fill", "fill-opacity", "fill-rule", "filter", "mask", "opacity", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform"],
|
||||||
"image": ["class", "clip-path", "clip-rule", "filter", "height", "id", "mask", "opacity", "requiredFeatures", "style", "systemLanguage", "transform", "width", "x", "xlink:href", "xlink:title", "y"],
|
"image": ["class", "clip-path", "clip-rule", "filter", "height", "id", "mask", "opacity", "requiredFeatures", "style", "systemLanguage", "transform", "width", "x", "xlink:href", "xlink:title", "y"],
|
||||||
"line": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "id", "marker-end", "marker-mid", "marker-start", "mask", "opacity", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform", "x1", "x2", "y1", "y2"],
|
"line": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "id", "marker-end", "marker-mid", "marker-start", "mask", "opacity", "requiredFeatures", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "transform", "x1", "x2", "y1", "y2"],
|
||||||
|
@ -121,6 +122,8 @@ var isOpera = !!window.opera,
|
||||||
"title": [],
|
"title": [],
|
||||||
"tspan": ["class", "clip-path", "clip-rule", "dx", "dy", "fill", "fill-opacity", "fill-rule", "filter", "font-family", "font-size", "font-style", "font-weight", "id", "mask", "opacity", "requiredFeatures", "rotate", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "text-anchor", "textLength", "transform", "x", "xml:space", "y"],
|
"tspan": ["class", "clip-path", "clip-rule", "dx", "dy", "fill", "fill-opacity", "fill-rule", "filter", "font-family", "font-size", "font-style", "font-weight", "id", "mask", "opacity", "requiredFeatures", "rotate", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "text-anchor", "textLength", "transform", "x", "xml:space", "y"],
|
||||||
"use": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "height", "id", "mask", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "transform", "width", "x", "xlink:href", "y"],
|
"use": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "height", "id", "mask", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "transform", "width", "x", "xlink:href", "y"],
|
||||||
|
|
||||||
|
// MathML Elements
|
||||||
"annotation-xml": ["encoding"],
|
"annotation-xml": ["encoding"],
|
||||||
"maction": ["actiontype", "other", "selection"],
|
"maction": ["actiontype", "other", "selection"],
|
||||||
"math": ["class", "id", "display", "xmlns"],
|
"math": ["class", "id", "display", "xmlns"],
|
||||||
|
@ -905,64 +908,6 @@ function BatchCommand(text) {
|
||||||
return canvas.updateElementFromJson(data)
|
return canvas.updateElementFromJson(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
var assignAttributes = function(node, attrs, suspendLength) {
|
|
||||||
if(!suspendLength) suspendLength = 0;
|
|
||||||
// Opera has a problem with suspendRedraw() apparently
|
|
||||||
var handle = null;
|
|
||||||
if (!window.opera) svgroot.suspendRedraw(suspendLength);
|
|
||||||
|
|
||||||
for (var i in attrs) {
|
|
||||||
var ns = (i.substr(0,4) == "xml:" ? xmlns :
|
|
||||||
i.substr(0,6) == "xlink:" ? xlinkns : null);
|
|
||||||
node.setAttributeNS(ns, i, attrs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window.opera) svgroot.unsuspendRedraw(handle);
|
|
||||||
};
|
|
||||||
|
|
||||||
// remove unneeded attributes
|
|
||||||
// makes resulting SVG smaller
|
|
||||||
var cleanupElement = function(element) {
|
|
||||||
var handle = svgroot.suspendRedraw(60);
|
|
||||||
var defaults = {
|
|
||||||
'fill-opacity':1,
|
|
||||||
'opacity':1,
|
|
||||||
'stroke':'none',
|
|
||||||
'stroke-dasharray':'none',
|
|
||||||
'stroke-opacity':1,
|
|
||||||
'stroke-width':1,
|
|
||||||
'rx':0,
|
|
||||||
'ry':0,
|
|
||||||
'display':'inline'
|
|
||||||
}
|
|
||||||
for(var attr in defaults) {
|
|
||||||
var val = defaults[attr];
|
|
||||||
if(element.getAttribute(attr) == val) {
|
|
||||||
element.removeAttribute(attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
svgroot.unsuspendRedraw(handle);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.updateElementFromJson = function(data) {
|
|
||||||
var shape = getElem(data.attr.id);
|
|
||||||
// if shape is a path but we need to create a rect/ellipse, then remove the path
|
|
||||||
if (shape && data.element != shape.tagName) {
|
|
||||||
current_layer.removeChild(shape);
|
|
||||||
shape = null;
|
|
||||||
}
|
|
||||||
if (!shape) {
|
|
||||||
shape = svgdoc.createElementNS(svgns, data.element);
|
|
||||||
if (current_layer) {
|
|
||||||
current_layer.appendChild(shape);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assignAttributes(shape, data.attr, 100);
|
|
||||||
cleanupElement(shape);
|
|
||||||
return shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: declare the variables and set them as null, then move this setup stuff to
|
// TODO: declare the variables and set them as null, then move this setup stuff to
|
||||||
// an initialization function - probably just use clear()
|
// an initialization function - probably just use clear()
|
||||||
var canvas = this,
|
var canvas = this,
|
||||||
|
@ -994,6 +939,157 @@ function BatchCommand(text) {
|
||||||
"xmlns:xlink": xlinkns
|
"xmlns:xlink": xlinkns
|
||||||
}).appendTo(svgroot);
|
}).appendTo(svgroot);
|
||||||
|
|
||||||
|
var convertToNum, convertToUnit, setUnitAttr;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var w_attrs = ['x', 'x1', 'cx', 'rx', 'width'];
|
||||||
|
var h_attrs = ['y', 'y1', 'cy', 'ry', 'height'];
|
||||||
|
var unit_attrs = $.merge(['r','radius'], w_attrs);
|
||||||
|
$.merge(unit_attrs, h_attrs);
|
||||||
|
|
||||||
|
// Converts given values to numbers. Attributes must be supplied in
|
||||||
|
// case a percentage is given
|
||||||
|
convertToNum = function(attr, val) {
|
||||||
|
// Return a number if that's what it already is
|
||||||
|
if(!isNaN(val)) return val-0;
|
||||||
|
|
||||||
|
if(val.substr(-1) === '%') {
|
||||||
|
// Deal with percentage, depends on attribute
|
||||||
|
var num = val.substr(0, val.length-1)/100;
|
||||||
|
var res = canvas.getResolution();
|
||||||
|
|
||||||
|
if($.inArray(attr, w_attrs) !== -1) {
|
||||||
|
return num * res.w;
|
||||||
|
} else if($.inArray(attr, w_attrs) !== -1) {
|
||||||
|
return num * res.h;
|
||||||
|
} else {
|
||||||
|
return num * Math.sqrt((res.w*res.w) + (res.h*res.h))/Math.sqrt(2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var unit = val.substr(-2);
|
||||||
|
var num = val.substr(0, val.length-2);
|
||||||
|
// Note that this multiplication turns the string into a number
|
||||||
|
return num * unit_types[unit];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setUnitAttr = function(elem, attr, val) {
|
||||||
|
if(!isNaN(val)) {
|
||||||
|
// New value is a number, so check currently used unit
|
||||||
|
var old_val = elem.getAttribute(attr);
|
||||||
|
|
||||||
|
if(old_val !== null && isNaN(old_val)) {
|
||||||
|
// Old value was a number, so get unit, then convert
|
||||||
|
var unit;
|
||||||
|
if(old_val.substr(-1) === '%') {
|
||||||
|
var res = canvas.getResolution();
|
||||||
|
unit = '%';
|
||||||
|
val *= 100;
|
||||||
|
if($.inArray(attr, w_attrs) !== -1) {
|
||||||
|
val = val / res.w;
|
||||||
|
} else if($.inArray(attr, w_attrs) !== -1) {
|
||||||
|
val = val / res.h;
|
||||||
|
} else {
|
||||||
|
return val / Math.sqrt((res.w*res.w) + (res.h*res.h))/Math.sqrt(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
unit = old_val.substr(-2);
|
||||||
|
val = val / unit_types[unit];
|
||||||
|
}
|
||||||
|
|
||||||
|
val += unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.setAttribute(attr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.isValidUnit = function(attr, val) {
|
||||||
|
var valid = false;
|
||||||
|
if($.inArray(attr, unit_attrs) != -1) {
|
||||||
|
// True if it's just a number
|
||||||
|
if(!isNaN(val)) {
|
||||||
|
valid = true;
|
||||||
|
} else {
|
||||||
|
// Not a number, check if it has a valid unit
|
||||||
|
val = val.toLowerCase();
|
||||||
|
$.each(unit_types, function(unit) {
|
||||||
|
if(valid) return;
|
||||||
|
var re = new RegExp('^-?[\\d\\.]+' + unit + '$');
|
||||||
|
if(re.test(val)) valid = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else valid = true;
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
var assignAttributes = function(node, attrs, suspendLength, unitCheck) {
|
||||||
|
if(!suspendLength) suspendLength = 0;
|
||||||
|
// Opera has a problem with suspendRedraw() apparently
|
||||||
|
var handle = null;
|
||||||
|
if (!window.opera) svgroot.suspendRedraw(suspendLength);
|
||||||
|
|
||||||
|
for (var i in attrs) {
|
||||||
|
var ns = (i.substr(0,4) == "xml:" ? xmlns :
|
||||||
|
i.substr(0,6) == "xlink:" ? xlinkns : null);
|
||||||
|
|
||||||
|
if(ns || !unitCheck) {
|
||||||
|
node.setAttributeNS(ns, i, attrs[i]);
|
||||||
|
} else {
|
||||||
|
setUnitAttr(node, i, attrs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.opera) svgroot.unsuspendRedraw(handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
// remove unneeded attributes
|
||||||
|
// makes resulting SVG smaller
|
||||||
|
var cleanupElement = function(element) {
|
||||||
|
var handle = svgroot.suspendRedraw(60);
|
||||||
|
var defaults = {
|
||||||
|
'fill-opacity':1,
|
||||||
|
'opacity':1,
|
||||||
|
'stroke':'none',
|
||||||
|
'stroke-dasharray':'none',
|
||||||
|
'stroke-opacity':1,
|
||||||
|
'stroke-width':1,
|
||||||
|
'rx':0,
|
||||||
|
'ry':0
|
||||||
|
}
|
||||||
|
for(var attr in defaults) {
|
||||||
|
var val = defaults[attr];
|
||||||
|
if(element.localName != 'math' && element.getAttribute(attr) == val) {
|
||||||
|
element.removeAttribute(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svgroot.unsuspendRedraw(handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.updateElementFromJson = function(data) {
|
||||||
|
var shape = getElem(data.attr.id);
|
||||||
|
// if shape is a path but we need to create a rect/ellipse, then remove the path
|
||||||
|
if (shape && data.element != shape.tagName) {
|
||||||
|
current_layer.removeChild(shape);
|
||||||
|
shape = null;
|
||||||
|
}
|
||||||
|
if (!shape) {
|
||||||
|
shape = svgdoc.createElementNS(svgns, data.element);
|
||||||
|
if (current_layer) {
|
||||||
|
current_layer.appendChild(shape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assignAttributes(shape, data.attr, 100);
|
||||||
|
cleanupElement(shape);
|
||||||
|
return shape;
|
||||||
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
// TODO: make this string optional and set by the client
|
// TODO: make this string optional and set by the client
|
||||||
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
|
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
|
||||||
|
@ -1392,7 +1488,7 @@ function BatchCommand(text) {
|
||||||
for (var i=attrs.length-1; i>=0; i--) {
|
for (var i=attrs.length-1; i>=0; i--) {
|
||||||
attr = attrs.item(i);
|
attr = attrs.item(i);
|
||||||
var attrVal = attr.nodeValue;
|
var attrVal = attr.nodeValue;
|
||||||
|
if (attr.localName == '-moz-math-font-style') continue;
|
||||||
if (attrVal != "") {
|
if (attrVal != "") {
|
||||||
if(attrVal.indexOf('pointer-events') == 0) continue;
|
if(attrVal.indexOf('pointer-events') == 0) continue;
|
||||||
if(attr.localName == "class" && attrVal.indexOf('se_') == 0) continue;
|
if(attr.localName == "class" && attrVal.indexOf('se_') == 0) continue;
|
||||||
|
@ -1702,10 +1798,10 @@ function BatchCommand(text) {
|
||||||
changes.y = changes.y-0 + Math.min(0,changes.height);
|
changes.y = changes.y-0 + Math.min(0,changes.height);
|
||||||
changes.width = Math.abs(changes.width);
|
changes.width = Math.abs(changes.width);
|
||||||
changes.height = Math.abs(changes.height);
|
changes.height = Math.abs(changes.height);
|
||||||
assignAttributes(selected, changes, 1000);
|
assignAttributes(selected, changes, 1000, true);
|
||||||
break;
|
break;
|
||||||
case "use":
|
case "use":
|
||||||
assignAttributes(selected, changes, 1000);
|
assignAttributes(selected, changes, 1000, true);
|
||||||
break;
|
break;
|
||||||
case "ellipse":
|
case "ellipse":
|
||||||
changes.rx = Math.abs(changes.rx);
|
changes.rx = Math.abs(changes.rx);
|
||||||
|
@ -1714,7 +1810,7 @@ function BatchCommand(text) {
|
||||||
if(changes.r) changes.r = Math.abs(changes.r);
|
if(changes.r) changes.r = Math.abs(changes.r);
|
||||||
case "line":
|
case "line":
|
||||||
case "text":
|
case "text":
|
||||||
assignAttributes(selected, changes, 1000);
|
assignAttributes(selected, changes, 1000, true);
|
||||||
break;
|
break;
|
||||||
case "polyline":
|
case "polyline":
|
||||||
case "polygon":
|
case "polygon":
|
||||||
|
@ -1860,12 +1956,18 @@ function BatchCommand(text) {
|
||||||
|
|
||||||
if(attrs.length) {
|
if(attrs.length) {
|
||||||
changes = $(selected).attr(attrs);
|
changes = $(selected).attr(attrs);
|
||||||
|
$.each(changes, function(attr, val) {
|
||||||
|
changes[attr] = convertToNum(attr, val);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we haven't created an initial array in polygon/polyline/path, then
|
// if we haven't created an initial array in polygon/polyline/path, then
|
||||||
// make a copy of initial values and include the transform
|
// make a copy of initial values and include the transform
|
||||||
if (initial == null) {
|
if (initial == null) {
|
||||||
initial = $.extend(true, {}, changes);
|
initial = $.extend(true, {}, changes);
|
||||||
|
$.each(initial, function(attr, val) {
|
||||||
|
initial[attr] = convertToNum(attr, val);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// save the start transform value too
|
// save the start transform value too
|
||||||
initial["transform"] = start_transform ? start_transform : "";
|
initial["transform"] = start_transform ? start_transform : "";
|
||||||
|
@ -6006,6 +6108,7 @@ function BatchCommand(text) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getOffset = function() {
|
this.getOffset = function() {
|
||||||
return $(svgcontent).attr(['x', 'y']);
|
return $(svgcontent).attr(['x', 'y']);
|
||||||
}
|
}
|
||||||
|
@ -7515,7 +7618,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: 1363 $)";
|
return "svgcanvas.js ($Rev: 1367 $)";
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setUiStrings = function(strs) {
|
this.setUiStrings = function(strs) {
|
||||||
|
|
Loading…
Reference in a new issue