Start on a units JS package. Rename BrowserSupport and Utilities packages to lower-case

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1844 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Jeff Schiller 2010-11-05 17:00:32 +00:00
parent 8ed4d6b0d8
commit 071a562c41
7 changed files with 212 additions and 161 deletions

View File

@ -1,5 +1,5 @@
/** /**
* Browser Support module for SVG-edit * Package: svgedit.browsersupport
* *
* Licensed under the Apache License, Version 2 * Licensed under the Apache License, Version 2
* *
@ -16,17 +16,17 @@ if (!window.svgedit) {
window.svgedit = {}; window.svgedit = {};
} }
if (!svgedit.BrowserSupport) { if (!svgedit.browsersupport) {
svgedit.BrowserSupport = {}; svgedit.browsersupport = {};
} }
var svgns = 'http://www.w3.org/2000/svg'; var svgns = 'http://www.w3.org/2000/svg';
var userAgent = navigator.userAgent; var userAgent = navigator.userAgent;
// Note: Browser sniffing should only be used if no other detection method is possible // Note: Browser sniffing should only be used if no other detection method is possible
svgedit.BrowserSupport.isOpera = !!window.opera; svgedit.browsersupport.isOpera = !!window.opera;
svgedit.BrowserSupport.isWebkit = userAgent.indexOf("AppleWebKit") >= 0; svgedit.browsersupport.isWebkit = userAgent.indexOf("AppleWebKit") >= 0;
svgedit.BrowserSupport.isGecko = userAgent.indexOf('Gecko/') >= 0; svgedit.browsersupport.isGecko = userAgent.indexOf('Gecko/') >= 0;
// segList functions (for FF1.5 and 2.0) // segList functions (for FF1.5 and 2.0)
function supportPathReplaceItem() { function supportPathReplaceItem() {
@ -71,7 +71,7 @@ function supportTextCharPos() {
function supportEditableText() { function supportEditableText() {
// TODO: Find better way to check support for this // TODO: Find better way to check support for this
return svgedit.BrowserSupport.isOpera; return svgedit.browsersupport.isOpera;
} }
function supportGoodDecimals() { function supportGoodDecimals() {
@ -93,11 +93,11 @@ function supportNonScalingStroke() {
return rect.style.vectorEffect === 'non-scaling-stroke'; return rect.style.vectorEffect === 'non-scaling-stroke';
} }
svgedit.BrowserSupport.pathReplaceItem = supportPathReplaceItem(); svgedit.browsersupport.pathReplaceItem = supportPathReplaceItem();
svgedit.BrowserSupport.pathInsertItemBefore = supportPathInsertItemBefore(); svgedit.browsersupport.pathInsertItemBefore = supportPathInsertItemBefore();
svgedit.BrowserSupport.textCharPos = supportTextCharPos(); svgedit.browsersupport.textCharPos = supportTextCharPos();
svgedit.BrowserSupport.editableText = supportEditableText(); svgedit.browsersupport.editableText = supportEditableText();
svgedit.BrowserSupport.goodDecimals = supportGoodDecimals(); svgedit.browsersupport.goodDecimals = supportGoodDecimals();
svgedit.BrowserSupport.nonScalingStroke = supportNonScalingStroke(); svgedit.browsersupport.nonScalingStroke = supportNonScalingStroke();
})(); })();

View File

@ -1,5 +1,5 @@
/** /**
* SVG-edit Math Utilities * Package: svedit.math
* *
* Licensed under the Apache License, Version 2 * Licensed under the Apache License, Version 2
* *

View File

@ -21,6 +21,7 @@
<script type="text/javascript" src="browsersupport.js"></script> <script type="text/javascript" src="browsersupport.js"></script>
<script type="text/javascript" src="svgtransformlist.js"></script> <script type="text/javascript" src="svgtransformlist.js"></script>
<script type="text/javascript" src="math.js"></script> <script type="text/javascript" src="math.js"></script>
<script type="text/javascript" src="units.js"></script>
<script type="text/javascript" src="svgutils.js"></script> <script type="text/javascript" src="svgutils.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>

View File

@ -15,6 +15,7 @@
// 3) svgtransformlist.js // 3) svgtransformlist.js
// 4) math.js // 4) math.js
// 5) svgutils.js // 5) svgutils.js
// 6) units.js
if(!window.console) { if(!window.console) {
window.console = {}; window.console = {};
@ -96,10 +97,49 @@ if(window.opera) {
// config - An object that contains configuration data // config - An object that contains configuration data
$.SvgCanvas = function(container, config) $.SvgCanvas = function(container, config)
{ {
var support = svgedit.BrowserSupport,
isOpera = support.isOpera, // import svgtransformlist.js
isWebkit = support.isWebkit, var getTransformList = this.getTransformList = svgedit.transformlist.getTransformList;
isGecko = support.isGecko,
// import from math.js.
var transformPoint = svgedit.math.transformPoint;
var isIdentity = svgedit.math.isIdentity;
var matrixMultiply = this.matrixMultiply = svgedit.math.matrixMultiply;
var hasMatrixTransform = this.hasMatrixTransform = svgedit.math.hasMatrixTransform;
var transformBox = this.transformBox = svgedit.math.transformBox;
var transformListToTransform = this.transformListToTransform = svgedit.math.transformListToTransform;
var snapToAngle = svgedit.math.snapToAngle;
// import from units.js
svgedit.units.init();
var unit_types = svgedit.units.typeMap;
// import from svgutils.js
var getUrlFromAttr = this.getUrlFromAttr = svgedit.utilities.getUrlFromAttr;
var getHref = this.getHref = svgedit.utilities.getHref;
var setHref = this.setHref = svgedit.utilities.setHref;
var getPathBBox = svgedit.utilities.getPathBBox;
var getBBox = this.getBBox = svgedit.utilities.getBBox;
var getRotationAngle = this.getRotationAngle = svgedit.utilities.getRotationAngle;
// Function: snapToGrid
// round value to for snapping
// NOTE: This function did not move to svgutils.js since it depends on curConfig.
svgedit.utilities.snapToGrid = function(value){
var stepSize = curConfig.snappingStep;
var unit = curConfig.baseUnit;
if(unit !== "px") {
stepSize *= svgedit.units.typeMap[unit];
}
value = Math.round(value/stepSize)*stepSize;
return value;
};
var snapToGrid = svgedit.utilities.snapToGrid;
var isOpera = svgedit.browsersupport.isOpera,
isWebkit = svgedit.browsersupport.isWebkit,
isGecko = svgedit.browsersupport.isGecko,
// this defines which elements and attributes that we support // this defines which elements and attributes that we support
svgWhiteList = { svgWhiteList = {
@ -187,12 +227,9 @@ var support = svgedit.BrowserSupport,
dimensions: [640, 480] dimensions: [640, 480]
}; };
var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'; var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use';
var ref_attrs = ["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"]; var ref_attrs = ["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"];
// Update config with new one if given // Update config with new one if given
if(config) { if(config) {
$.extend(curConfig, config); $.extend(curConfig, config);
@ -213,9 +250,6 @@ var canvas = this,
htmlns = "http://www.w3.org/1999/xhtml", htmlns = "http://www.w3.org/1999/xhtml",
mathns = "http://www.w3.org/1998/Math/MathML", mathns = "http://www.w3.org/1998/Math/MathML",
// Map of units, updated later based on px conversion.
unit_types = {px: 1},
//nonce to uniquify id's //nonce to uniquify id's
nonce = Math.floor(Math.random()*100001), nonce = Math.floor(Math.random()*100001),
@ -229,7 +263,7 @@ var canvas = this,
dimensions = curConfig.dimensions; dimensions = curConfig.dimensions;
// Create Root SVG element. This is a container for the document being edited, not the document itself. // Create Root SVG element. This is a container for the document being edited, not the document itself.
var svgroot = svgdoc.importNode(svgedit.Utilities.text2xml( var svgroot = svgdoc.importNode(svgedit.utilities.text2xml(
'<svg id="svgroot" xmlns="' + svgns + '" xlinkns="' + xlinkns + '" ' + '<svg id="svgroot" xmlns="' + svgns + '" xlinkns="' + xlinkns + '" ' +
'width="' + dimensions[0] + '" height="' + dimensions[1] + '" x="' + dimensions[0] + '" y="' + dimensions[1] + '" overflow="visible">' + 'width="' + dimensions[0] + '" height="' + dimensions[1] + '" x="' + dimensions[0] + '" y="' + dimensions[1] + '" overflow="visible">' +
'<defs>' + '<defs>' +
@ -325,7 +359,6 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
pc: 10 pc: 10
}; };
$.merge(unit_attrs, h_attrs); $.merge(unit_attrs, h_attrs);
// Function: convertToNum // Function: convertToNum
@ -400,7 +433,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
// } // }
} }
elem.setAttribute(attr, val); elem.setAttribute(attr, val);
} };
// Function: isValidUnit // Function: isValidUnit
// Check if an attribute's value is in a valid format // Check if an attribute's value is in a valid format
@ -440,13 +473,13 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
} else valid = true; } else valid = true;
return valid; return valid;
} };
// Function: getUnits // Function: getUnits
// Returns the unit object with values for each unit // Returns the unit object with values for each unit
canvas.getUnits = function() { canvas.getUnits = function() {
return unit_types; return unit_types;
} };
// Function: convertUnit // Function: convertUnit
// Converts the number to given unit or baseUnit // Converts the number to given unit or baseUnit
@ -456,7 +489,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
// var val = baseVal.valueInSpecifiedUnits; // var val = baseVal.valueInSpecifiedUnits;
// baseVal.convertToSpecifiedUnits(1); // baseVal.convertToSpecifiedUnits(1);
return shortFloat(val / unit_types[unit]); return shortFloat(val / unit_types[unit]);
} };
// Function: unitConvertAttrs // Function: unitConvertAttrs
// Converts all applicable attributes to the given baseUnit // Converts all applicable attributes to the given baseUnit
@ -498,9 +531,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
} }
} }
} }
};
}
})(); })();
@ -1412,41 +1443,6 @@ var SelectorManager;
}; };
}()); }());
// import svgtransformlist.js
var getTransformList = this.getTransformList = svgedit.transformlist.getTransformList;
// import from svgutils.js
var getUrlFromAttr = this.getUrlFromAttr = svgedit.Utilities.getUrlFromAttr;
var getHref = this.getHref = svgedit.Utilities.getHref;
var setHref = this.setHref = svgedit.Utilities.setHref;
var getPathBBox = svgedit.Utilities.getPathBBox;
var getBBox = this.getBBox = svgedit.Utilities.getBBox;
var getRotationAngle = this.getRotationAngle = svgedit.Utilities.getRotationAngle;
// Function: snapToGrid
// round value to for snapping
// NOTE: This function did not move to svgutils.js since it depends on unit_types and curConfig.
svgedit.Utilities.snapToGrid = function(value){
var stepSize = curConfig.snappingStep;
var unit = curConfig.baseUnit;
if(unit !== "px") {
stepSize *= unit_types[unit];
}
value = Math.round(value/stepSize)*stepSize;
return value;
};
var snapToGrid = svgedit.Utilities.snapToGrid;
// import from math.js.
var transformPoint = svgedit.math.transformPoint;
var isIdentity = svgedit.math.isIdentity;
var matrixMultiply = this.matrixMultiply = svgedit.math.matrixMultiply;
var hasMatrixTransform = this.hasMatrixTransform = svgedit.math.hasMatrixTransform;
var transformBox = this.transformBox = svgedit.math.transformBox;
var transformListToTransform = this.transformListToTransform = svgedit.math.transformListToTransform;
var snapToAngle = svgedit.math.snapToAngle;
// Function: assignAttributes // Function: assignAttributes
// Assigns multiple attributes to an element. // Assigns multiple attributes to an element.
// //
@ -1782,7 +1778,7 @@ var getIntersectionList = this.getIntersectionList = function(rect) {
var i = curBBoxes.length; var i = curBBoxes.length;
while (i--) { while (i--) {
if(!rubberBBox.width || !rubberBBox.width) continue; if(!rubberBBox.width || !rubberBBox.width) continue;
if (svgedit.Utilities.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) { if (svgedit.utilities.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) {
resultList.push(curBBoxes[i].elem); resultList.push(curBBoxes[i].elem);
} }
} }
@ -1842,7 +1838,7 @@ var getStrokedBBox = this.getStrokedBBox = function(elems) {
var parent = elem.parentNode; var parent = elem.parentNode;
parent.appendChild(g); parent.appendChild(g);
g.appendChild(clone); g.appendChild(clone);
bb = svgedit.Utilities.bboxToObj(g.getBBox()); bb = svgedit.utilities.bboxToObj(g.getBBox());
parent.removeChild(g); parent.removeChild(g);
} }
@ -3865,7 +3861,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
tlist.appendItem(svgroot.createSVGTransform()); tlist.appendItem(svgroot.createSVGTransform());
tlist.appendItem(svgroot.createSVGTransform()); tlist.appendItem(svgroot.createSVGTransform());
if(support.nonScalingStroke) { if(svgedit.browsersupport.nonScalingStroke) {
mouse_target.style.vectorEffect = 'non-scaling-stroke'; mouse_target.style.vectorEffect = 'non-scaling-stroke';
var all = mouse_target.getElementsByTagName('*'), len = all.length; var all = mouse_target.getElementsByTagName('*'), len = all.length;
for(var i = 0; i < all.length; i++) { for(var i = 0; i < all.length; i++) {
@ -4525,10 +4521,10 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} // no change in mouse position } // no change in mouse position
// Remove non-scaling stroke // Remove non-scaling stroke
if(support.nonScalingStroke) { if(svgedit.browsersupport.nonScalingStroke) {
var elem = selectedElements[0]; var elem = selectedElements[0];
elem.removeAttribute('style'); elem.removeAttribute('style');
svgedit.Utilities.walkTree(elem, function(elem) { svgedit.utilities.walkTree(elem, function(elem) {
elem.removeAttribute('style'); elem.removeAttribute('style');
}); });
} }
@ -5086,7 +5082,7 @@ var textActions = canvas.textActions = function() {
// TODO: Find a way to make this work: Use transformed BBox instead of evt.target // TODO: Find a way to make this work: Use transformed BBox instead of evt.target
// if(last_x === mouse_x && last_y === mouse_y // if(last_x === mouse_x && last_y === mouse_y
// && !svgedit.Utilities.rectsIntersect(transbb, {x: pt.x, y: pt.y, width:0, height:0})) { // && !svgedit.utilities.rectsIntersect(transbb, {x: pt.x, y: pt.y, width:0, height:0})) {
// textActions.toSelectMode(true); // textActions.toSelectMode(true);
// } // }
if(last_x === mouse_x && last_y === mouse_y && evt.target !== curtext) { if(last_x === mouse_x && last_y === mouse_y && evt.target !== curtext) {
@ -5106,7 +5102,7 @@ var textActions = canvas.textActions = function() {
$(curtext).css('cursor', 'text'); $(curtext).css('cursor', 'text');
// if(support.editableText) { // if(svgedit.browsersupport.editableText) {
// curtext.setAttribute('editable', 'simple'); // curtext.setAttribute('editable', 'simple');
// return; // return;
// } // }
@ -5146,7 +5142,7 @@ var textActions = canvas.textActions = function() {
curtext = false; curtext = false;
// if(support.editableText) { // if(svgedit.browsersupport.editableText) {
// curtext.removeAttribute('editable'); // curtext.removeAttribute('editable');
// } // }
}, },
@ -5162,7 +5158,7 @@ var textActions = canvas.textActions = function() {
init: function(inputElem) { init: function(inputElem) {
if(!curtext) return; if(!curtext) return;
// if(support.editableText) { // if(svgedit.browsersupport.editableText) {
// curtext.select(); // curtext.select();
// return; // return;
// } // }
@ -5250,7 +5246,7 @@ var pathActions = this.pathActions = function() {
// Support insertItemBefore on paths for FF2 // Support insertItemBefore on paths for FF2
var list = elem.pathSegList; var list = elem.pathSegList;
if(support.pathInsertItemBefore) { if(svgedit.browsersupport.pathInsertItemBefore) {
list.insertItemBefore(newseg, index); list.insertItemBefore(newseg, index);
return; return;
} }
@ -6097,7 +6093,7 @@ var pathActions = this.pathActions = function() {
var func = 'createSVGPathSeg' + pathFuncs[type]; var func = 'createSVGPathSeg' + pathFuncs[type];
var seg = path[func].apply(path, pts); var seg = path[func].apply(path, pts);
if(support.pathReplaceItem) { if(svgedit.browsersupport.pathReplaceItem) {
path.pathSegList.replaceItem(seg, index); path.pathSegList.replaceItem(seg, index);
} else { } else {
var segList = path.pathSegList; var segList = path.pathSegList;
@ -6549,7 +6545,7 @@ var pathActions = this.pathActions = function() {
height: 0 height: 0
}; };
var sel = svgedit.Utilities.rectsIntersect(rbb, pt_bb); var sel = svgedit.utilities.rectsIntersect(rbb, pt_bb);
this.select(sel); this.select(sel);
//Note that addPtsToSelection is not being run //Note that addPtsToSelection is not being run
@ -7286,9 +7282,8 @@ var svgCanvasToString = this.svgCanvasToString = function() {
// Returns: // Returns:
// String with the given element as an SVG tag // String with the given element as an SVG tag
var svgToString = this.svgToString = function(elem, indent) { var svgToString = this.svgToString = function(elem, indent) {
var out = new Array(), toXml = svgedit.Utilities.toXml; var out = new Array(), toXml = svgedit.utilities.toXml;
var unit = curConfig.baseUnit;
var unit = curConfig.baseUnit
var unit_re = new RegExp('^-?[\\d\\.]+' + unit + '$'); var unit_re = new RegExp('^-?[\\d\\.]+' + unit + '$');
if (elem) { if (elem) {
@ -7574,7 +7569,7 @@ var uniquifyElems = this.uniquifyElems = function(g) {
var ids = {}; var ids = {};
var ref_elems = ["filter", "linearGradient", "pattern", "radialGradient", "textPath", "use"]; var ref_elems = ["filter", "linearGradient", "pattern", "radialGradient", "textPath", "use"];
svgedit.Utilities.walkTree(g, function(n) { svgedit.utilities.walkTree(g, function(n) {
// if it's an element node // if it's an element node
if (n.nodeType == 1) { if (n.nodeType == 1) {
// and the element has an ID // and the element has an ID
@ -7811,7 +7806,7 @@ var convertToGroup = this.convertToGroup = function(elem) {
// recalculate dimensions on the top-level children so that unnecessary transforms // recalculate dimensions on the top-level children so that unnecessary transforms
// are removed // are removed
svgedit.Utilities.walkTreePost(g, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}}); svgedit.utilities.walkTreePost(g, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
// Give ID for any visible element missing one // Give ID for any visible element missing one
$(g).find(visElems).each(function() { $(g).find(visElems).each(function() {
@ -7841,7 +7836,7 @@ var convertToGroup = this.convertToGroup = function(elem) {
this.setSvgString = function(xmlString) { this.setSvgString = function(xmlString) {
try { try {
// convert string into XML document // convert string into XML document
var newDoc = svgedit.Utilities.text2xml(xmlString); var newDoc = svgedit.utilities.text2xml(xmlString);
// run it through our sanitizer to remove anything we do not support // run it through our sanitizer to remove anything we do not support
sanitizeSvg(newDoc.documentElement); sanitizeSvg(newDoc.documentElement);
@ -7925,7 +7920,7 @@ this.setSvgString = function(xmlString) {
// recalculate dimensions on the top-level children so that unnecessary transforms // recalculate dimensions on the top-level children so that unnecessary transforms
// are removed // are removed
svgedit.Utilities.walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}}); svgedit.utilities.walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
var attrs = { var attrs = {
id: 'svgcontent', id: 'svgcontent',
@ -8024,7 +8019,7 @@ this.setSvgString = function(xmlString) {
this.importSvgString = function(xmlString) { this.importSvgString = function(xmlString) {
try { try {
// convert string into XML document // convert string into XML document
var newDoc = svgedit.Utilities.text2xml(xmlString); var newDoc = svgedit.utilities.text2xml(xmlString);
// run it through our sanitizer to remove anything we do not support // run it through our sanitizer to remove anything we do not support
sanitizeSvg(newDoc.documentElement); sanitizeSvg(newDoc.documentElement);
@ -8134,7 +8129,7 @@ var identifyLayers = function() {
layernames.push(name); layernames.push(name);
all_layers.push( [name,child] ); all_layers.push( [name,child] );
current_layer = child; current_layer = child;
svgedit.Utilities.walkTree(child, function(e){e.setAttribute("style", "pointer-events:inherit");}); svgedit.utilities.walkTree(child, function(e){e.setAttribute("style", "pointer-events:inherit");});
current_layer.setAttribute("style", "pointer-events:none"); current_layer.setAttribute("style", "pointer-events:none");
} }
// if group did not have a name, it is an orphan // if group did not have a name, it is an orphan
@ -8164,7 +8159,7 @@ var identifyLayers = function() {
current_layer = svgcontent.appendChild(current_layer); current_layer = svgcontent.appendChild(current_layer);
all_layers.push( [newname, current_layer] ); all_layers.push( [newname, current_layer] );
} }
svgedit.Utilities.walkTree(current_layer, function(e){e.setAttribute("style","pointer-events:inherit");}); svgedit.utilities.walkTree(current_layer, function(e){e.setAttribute("style","pointer-events:inherit");});
current_layer.setAttribute("style","pointer-events:all"); current_layer.setAttribute("style","pointer-events:all");
}; };
@ -8298,7 +8293,7 @@ this.getCurrentLayer = function() {
// Returns: // Returns:
// true if the current layer was switched, otherwise false // true if the current layer was switched, otherwise false
this.setCurrentLayer = function(name) { this.setCurrentLayer = function(name) {
name = svgedit.Utilities.toXml(name); name = svgedit.utilities.toXml(name);
for (var i = 0; i < all_layers.length; ++i) { for (var i = 0; i < all_layers.length; ++i) {
if (name == all_layers[i][0]) { if (name == all_layers[i][0]) {
if (current_layer != all_layers[i][1]) { if (current_layer != all_layers[i][1]) {
@ -8334,7 +8329,7 @@ this.renameCurrentLayer = function(newname) {
if (all_layers[i][1] == oldLayer) break; if (all_layers[i][1] == oldLayer) break;
} }
var oldname = all_layers[i][0]; var oldname = all_layers[i][0];
all_layers[i][0] = svgedit.Utilities.toXml(newname); all_layers[i][0] = svgedit.utilities.toXml(newname);
// now change the underlying title element contents // now change the underlying title element contents
var len = oldLayer.childNodes.length; var len = oldLayer.childNodes.length;
@ -9016,7 +9011,7 @@ this.setColor = function(type, val, preventUndo) {
var elem = selectedElements[i]; var elem = selectedElements[i];
if (elem) { if (elem) {
if (elem.tagName == "g") if (elem.tagName == "g")
svgedit.Utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);}); svgedit.utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);});
else { else {
if(type == 'fill') { if(type == 'fill') {
if(elem.tagName != "polyline" && elem.tagName != "line") { if(elem.tagName != "polyline" && elem.tagName != "line") {
@ -9236,7 +9231,7 @@ this.setStrokeWidth = function(val) {
var elem = selectedElements[i]; var elem = selectedElements[i];
if (elem) { if (elem) {
if (elem.tagName == "g") if (elem.tagName == "g")
svgedit.Utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);}); svgedit.utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);});
else else
elems.push(elem); elems.push(elem);
} }
@ -9261,7 +9256,7 @@ this.setStrokeAttr = function(attr, val) {
var elem = selectedElements[i]; var elem = selectedElements[i];
if (elem) { if (elem) {
if (elem.tagName == "g") if (elem.tagName == "g")
svgedit.Utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);}); svgedit.utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);});
else else
elems.push(elem); elems.push(elem);
} }
@ -10806,7 +10801,7 @@ this.getPrivateMethods = function() {
transformBox: transformBox, transformBox: transformBox,
transformListToTransform: transformListToTransform, transformListToTransform: transformListToTransform,
transformPoint: transformPoint, transformPoint: transformPoint,
walkTree: svgedit.Utilities.walkTree walkTree: svgedit.utilities.walkTree
} }
return obj; return obj;
}; };
@ -10835,28 +10830,9 @@ function disableAdvancedTextEdit() {
} }
(function() { (function() {
if (!svgedit.BrowserSupport.textCharPos) { if (!svgedit.browsersupport.textCharPos) {
disableAdvancedTextEdit(); disableAdvancedTextEdit();
} }
// Get correct em/ex values
var rect = document.createElementNS(svgns,'rect');
rect.setAttribute('width',"1em");
rect.setAttribute('height',"1ex");
rect.setAttribute('x',"1in");
svgcontent.appendChild(rect);
var bb = rect.getBBox();
rect.parentNode.removeChild(rect);
unit_types.em = bb.width;
unit_types.ex = bb.height;
var inch = bb.x;
unit_types['in'] = inch;
unit_types.cm = inch / 2.54;
unit_types.mm = inch / 25.4;
unit_types.pt = inch / 72;
unit_types.pc = inch / 6;
unit_types['%'] = 0;
})(); })();
} }

View File

@ -8,7 +8,7 @@
*/ */
// Dependencies: // Dependencies:
// 1) browwsersupport.js // 1) browsersupport.js
(function() { (function() {
@ -230,7 +230,7 @@ svgedit.transformlist.SVGTransformList = function(elem) {
// Parameters: // Parameters:
// elem - DOM element to get a transformlist from // elem - DOM element to get a transformlist from
svgedit.transformlist.getTransformList = function(elem) { svgedit.transformlist.getTransformList = function(elem) {
if (svgedit.BrowserSupport.isWebkit) { if (svgedit.browsersupport.isWebkit) {
var id = elem.id; var id = elem.id;
if(!id) { if(!id) {
// Get unique ID for temporary element // Get unique ID for temporary element

View File

@ -1,5 +1,5 @@
/** /**
* Package: svgedit.Utilities * Package: svgedit.utilities
* *
* Licensed under the Apache License, Version 2 * Licensed under the Apache License, Version 2
* *
@ -18,8 +18,8 @@ if (!window.svgedit) {
window.svgedit = {}; window.svgedit = {};
} }
if (!svgedit.Utilities) { if (!svgedit.utilities) {
svgedit.Utilities = {}; svgedit.utilities = {};
} }
// Constants // Constants
@ -33,7 +33,7 @@ var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polylin
var visElems_arr = visElems.split(','); var visElems_arr = visElems.split(',');
//var hidElems = 'clipPath,defs,desc,feGaussianBlur,filter,linearGradient,marker,mask,metadata,pattern,radialGradient,stop,switch,symbol,title,textPath'; //var hidElems = 'clipPath,defs,desc,feGaussianBlur,filter,linearGradient,marker,mask,metadata,pattern,radialGradient,stop,switch,symbol,title,textPath';
// Function: svgedit.Utilities.toXml // Function: svgedit.utilities.toXml
// Converts characters in a string to XML-friendly entities. // Converts characters in a string to XML-friendly entities.
// //
// Example: "&" becomes "&amp;" // Example: "&" becomes "&amp;"
@ -43,11 +43,11 @@ var visElems_arr = visElems.split(',');
// //
// Returns: // Returns:
// The converted string // The converted string
svgedit.Utilities.toXml = function(str) { svgedit.utilities.toXml = function(str) {
return $('<p/>').text(str).html(); return $('<p/>').text(str).html();
}; };
// Function: svgedit.Utilities.fromXml // Function: svgedit.utilities.fromXml
// Converts XML entities in a string to single characters. // Converts XML entities in a string to single characters.
// Example: "&amp;" becomes "&" // Example: "&amp;" becomes "&"
// //
@ -56,7 +56,7 @@ svgedit.Utilities.toXml = function(str) {
// //
// Returns: // Returns:
// The converted string // The converted string
svgedit.Utilities.fromXml = function(str) { svgedit.utilities.fromXml = function(str) {
return $('<p/>').html(str).text(); return $('<p/>').html(str).text();
}; };
@ -68,12 +68,12 @@ svgedit.Utilities.fromXml = function(str) {
// schiller: Removed string concatenation in favour of Array.join() optimization, // schiller: Removed string concatenation in favour of Array.join() optimization,
// also precalculate the size of the array needed. // also precalculate the size of the array needed.
// Function: svgedit.Utilities.encode64 // Function: svgedit.utilities.encode64
// Converts a string to base64 // Converts a string to base64
svgedit.Utilities.encode64 = function(input) { svgedit.utilities.encode64 = function(input) {
// base64 strings are 4/3 larger than the original string // base64 strings are 4/3 larger than the original string
// input = svgedit.Utilities.encodeUTF8(input); // convert non-ASCII characters // input = svgedit.utilities.encodeUTF8(input); // convert non-ASCII characters
input = svgedit.Utilities.convertToXMLReferences(input); input = svgedit.utilities.convertToXMLReferences(input);
if(window.btoa) return window.btoa(input); // Use native if available if(window.btoa) return window.btoa(input); // Use native if available
var output = new Array( Math.floor( (input.length + 2) / 3 ) * 4 ); var output = new Array( Math.floor( (input.length + 2) / 3 ) * 4 );
var chr1, chr2, chr3; var chr1, chr2, chr3;
@ -105,9 +105,9 @@ svgedit.Utilities.encode64 = function(input) {
return output.join(''); return output.join('');
}; };
// Function: svgedit.Utilities.decode64 // Function: svgedit.utilities.decode64
// Converts a string from base64 // Converts a string from base64
svgedit.Utilities.decode64 = function(input) { svgedit.utilities.decode64 = function(input) {
if(window.atob) return window.atob(input); if(window.atob) return window.atob(input);
var output = ""; var output = "";
var chr1, chr2, chr3 = ""; var chr1, chr2, chr3 = "";
@ -167,9 +167,9 @@ svgedit.Utilities.decode64 = function(input) {
// return output; // return output;
// }, // },
// Function: svgedit.Utilities.convertToXMLReferences // Function: svgedit.utilities.convertToXMLReferences
// Converts a string to use XML references // Converts a string to use XML references
svgedit.Utilities.convertToXMLReferences = function(input) { svgedit.utilities.convertToXMLReferences = function(input) {
var output = ''; var output = '';
for (var n = 0; n < input.length; n++){ for (var n = 0; n < input.length; n++){
var c = input.charCodeAt(n); var c = input.charCodeAt(n);
@ -192,7 +192,7 @@ svgedit.Utilities.convertToXMLReferences = function(input) {
// //
// Returns: // Returns:
// Boolean that's true if rectangles intersect // Boolean that's true if rectangles intersect
svgedit.Utilities.rectsIntersect = function(r1, r2) { svgedit.utilities.rectsIntersect = function(r1, r2) {
return r2.x < (r1.x+r1.width) && return r2.x < (r1.x+r1.width) &&
(r2.x+r2.width) > r1.x && (r2.x+r2.width) > r1.x &&
r2.y < (r1.y+r1.height) && r2.y < (r1.y+r1.height) &&
@ -202,7 +202,7 @@ svgedit.Utilities.rectsIntersect = function(r1, r2) {
// Function: text2xml // Function: text2xml
// Cross-browser compatible method of converting a string to an XML tree // Cross-browser compatible method of converting a string to an XML tree
// found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f // found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f
svgedit.Utilities.text2xml = function(sXML) { svgedit.utilities.text2xml = function(sXML) {
if(sXML.indexOf('<svg:svg') >= 0) { if(sXML.indexOf('<svg:svg') >= 0) {
sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns'); sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns');
} }
@ -230,7 +230,7 @@ svgedit.Utilities.text2xml = function(sXML) {
// //
// Returns: // Returns:
// An object with properties names x, y, width, height. // An object with properties names x, y, width, height.
svgedit.Utilities.bboxToObj = function(bbox) { svgedit.utilities.bboxToObj = function(bbox) {
return { return {
x: bbox.x, x: bbox.x,
y: bbox.y, y: bbox.y,
@ -245,12 +245,12 @@ svgedit.Utilities.bboxToObj = function(bbox) {
// Parameters: // Parameters:
// elem - DOM element to traverse // elem - DOM element to traverse
// cbFn - Callback function to run on each element // cbFn - Callback function to run on each element
svgedit.Utilities.walkTree = function(elem, cbFn){ svgedit.utilities.walkTree = function(elem, cbFn){
if (elem && elem.nodeType == 1) { if (elem && elem.nodeType == 1) {
cbFn(elem); cbFn(elem);
var i = elem.childNodes.length; var i = elem.childNodes.length;
while (i--) { while (i--) {
svgedit.Utilities.walkTree(elem.childNodes.item(i), cbFn); svgedit.utilities.walkTree(elem.childNodes.item(i), cbFn);
} }
} }
}; };
@ -262,17 +262,17 @@ svgedit.Utilities.walkTree = function(elem, cbFn){
// Parameters: // Parameters:
// elem - DOM element to traverse // elem - DOM element to traverse
// cbFn - Callback function to run on each element // cbFn - Callback function to run on each element
svgedit.Utilities.walkTreePost = function(elem, cbFn) { svgedit.utilities.walkTreePost = function(elem, cbFn) {
if (elem && elem.nodeType == 1) { if (elem && elem.nodeType == 1) {
var i = elem.childNodes.length; var i = elem.childNodes.length;
while (i--) { while (i--) {
svgedit.Utilities.walkTree(elem.childNodes.item(i), cbFn); svgedit.utilities.walkTree(elem.childNodes.item(i), cbFn);
} }
cbFn(elem); cbFn(elem);
} }
}; };
// Function: svgedit.Utilities.getUrlFromAttr // Function: svgedit.utilities.getUrlFromAttr
// Extracts the URL from the url(...) syntax of some attributes. // Extracts the URL from the url(...) syntax of some attributes.
// Three variants: // Three variants:
// * <circle fill="url(someFile.svg#foo)" /> // * <circle fill="url(someFile.svg#foo)" />
@ -284,7 +284,7 @@ svgedit.Utilities.walkTreePost = function(elem, cbFn) {
// //
// Returns: // Returns:
// String with just the URL, like someFile.svg#foo // String with just the URL, like someFile.svg#foo
svgedit.Utilities.getUrlFromAttr = function(attrVal) { svgedit.utilities.getUrlFromAttr = function(attrVal) {
if (attrVal) { if (attrVal) {
// url("#somegrad") // url("#somegrad")
if (attrVal.indexOf('url("') === 0) { if (attrVal.indexOf('url("') === 0) {
@ -301,15 +301,15 @@ svgedit.Utilities.getUrlFromAttr = function(attrVal) {
return null; return null;
}; };
// Function: svgedit.Utilities.getHref // Function: svgedit.utilities.getHref
// Returns the given element's xlink:href value // Returns the given element's xlink:href value
svgedit.Utilities.getHref = function(elem) { svgedit.utilities.getHref = function(elem) {
return elem.getAttributeNS(XLINKNS, "href"); return elem.getAttributeNS(XLINKNS, "href");
} }
// Function: svgedit.Utilities.setHref // Function: svgedit.utilities.setHref
// Sets the given element's xlink:href value // Sets the given element's xlink:href value
svgedit.Utilities.setHref = function(elem, val) { svgedit.utilities.setHref = function(elem, val) {
elem.setAttributeNS(XLINKNS, "xlink:href", val); elem.setAttributeNS(XLINKNS, "xlink:href", val);
} }
@ -319,7 +319,7 @@ svgedit.Utilities.setHref = function(elem, val) {
// //
// Returns: // Returns:
// The document's <defs> element, create it first if necessary // The document's <defs> element, create it first if necessary
svgedit.Utilities.findDefs = function(svgElement) { svgedit.utilities.findDefs = function(svgElement) {
var svgElement = svgDoc.documentElement; var svgElement = svgDoc.documentElement;
var defs = svgElement.getElementsByTagNameNS(svgns, "defs"); var defs = svgElement.getElementsByTagNameNS(svgns, "defs");
if (defs.length > 0) { if (defs.length > 0) {
@ -332,7 +332,7 @@ svgedit.Utilities.findDefs = function(svgElement) {
return defs; return defs;
}; };
// Function: svgedit.Utilities.getPathBBox // Function: svgedit.utilities.getPathBBox
// Get correct BBox for a path in Webkit // Get correct BBox for a path in Webkit
// Converted from code found here: // Converted from code found here:
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html // http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
@ -342,7 +342,7 @@ svgedit.Utilities.findDefs = function(svgElement) {
// //
// Returns: // Returns:
// A BBox-like object // A BBox-like object
svgedit.Utilities.getPathBBox = function(path) { svgedit.utilities.getPathBBox = function(path) {
var seglist = path.pathSegList; var seglist = path.pathSegList;
var tot = seglist.numberOfItems; var tot = seglist.numberOfItems;
@ -413,13 +413,13 @@ svgedit.Utilities.getPathBBox = function(path) {
}; };
}; };
// Function: svgedit.Utilities.getBBox // Function: svgedit.utilities.getBBox
// Get the given/selected element's bounding box object, convert it to be more // Get the given/selected element's bounding box object, convert it to be more
// usable when necessary // usable when necessary
// //
// Parameters: // Parameters:
// elem - Optional DOM element to get the BBox for // elem - Optional DOM element to get the BBox for
svgedit.Utilities.getBBox = function(elem) { svgedit.utilities.getBBox = function(elem) {
var selected = elem || selectedElements[0]; var selected = elem || selectedElements[0];
if (elem.nodeType != 1) return null; if (elem.nodeType != 1) return null;
var ret = null; var ret = null;
@ -429,9 +429,9 @@ svgedit.Utilities.getBBox = function(elem) {
selected.textContent = 'a'; // Some character needed for the selector to use. selected.textContent = 'a'; // Some character needed for the selector to use.
ret = selected.getBBox(); ret = selected.getBBox();
selected.textContent = ''; selected.textContent = '';
} else if(elname === 'path' && svgedit.BrowserSupport.isWebkit) { } else if(elname === 'path' && svgedit.browsersupport.isWebkit) {
ret = svgedit.Utilities.getPathBBox(selected); ret = svgedit.utilities.getPathBBox(selected);
} else if(elname === 'use' && !svgedit.BrowserSupport.isWebkit || elname === 'foreignObject') { } else if(elname === 'use' && !svgedit.browsersupport.isWebkit || elname === 'foreignObject') {
ret = selected.getBBox(); ret = selected.getBBox();
var bb = {}; var bb = {};
bb.width = ret.width; bb.width = ret.width;
@ -456,14 +456,14 @@ svgedit.Utilities.getBBox = function(elem) {
} }
} }
if(ret) { if(ret) {
ret = svgedit.Utilities.bboxToObj(ret); ret = svgedit.utilities.bboxToObj(ret);
} }
// get the bounding box from the DOM (which is in that element's coordinate system) // get the bounding box from the DOM (which is in that element's coordinate system)
return ret; return ret;
}; };
// Function: svgedit.Utilities.getRotationAngle // Function: svgedit.utilities.getRotationAngle
// Get the rotation angle of the given/selected DOM element // Get the rotation angle of the given/selected DOM element
// //
// Parameters: // Parameters:
@ -472,7 +472,7 @@ svgedit.Utilities.getBBox = function(elem) {
// //
// Returns: // Returns:
// Float with the angle in degrees or radians // Float with the angle in degrees or radians
svgedit.Utilities.getRotationAngle = function(elem, to_rad) { svgedit.utilities.getRotationAngle = function(elem, to_rad) {
var selected = elem || selectedElements[0]; var selected = elem || selectedElements[0];
// find the rotation transform (if any) and set it // find the rotation transform (if any) and set it
var tlist = svgedit.transformlist.getTransformList(selected); var tlist = svgedit.transformlist.getTransformList(selected);

74
editor/units.js Normal file
View File

@ -0,0 +1,74 @@
/**
* Package: svgedit.units
*
* Licensed under the Apache License, Version 2
*
* Copyright(c) 2010 Alexis Deveria
* Copyright(c) 2010 Jeff Schiller
*/
// Dependencies:
// 1) jQuery
(function() {
if (!window.svgedit) {
window.svgedit = {};
}
if (!svgedit.units) {
svgedit.units = {};
}
var w_attrs = ['x', 'x1', 'cx', 'rx', 'width'];
var h_attrs = ['y', 'y1', 'cy', 'ry', 'height'];
var unit_attrs = $.merge(['r','radius'], w_attrs);
var unitNumMap = {
'%': 2,
'em': 3,
'ex': 4,
'px': 5,
'cm': 6,
'mm': 7,
'in': 8,
'pt': 9,
'pc': 10
};
$.merge(unit_attrs, h_attrs);
/**
* Stores mapping of unit type to user coordinates.
*/
svgedit.units.typeMap = {px: 1};
/**
* Initializes this module.
*/
svgedit.units.init = function() {
var svgns = 'http://www.w3.org/2000/svg';
// Get correct em/ex values by creating a temporary SVG.
var svg = document.createElementNS(svgns, 'svg');
document.body.appendChild(svg);
var rect = document.createElementNS(svgns,'rect');
rect.setAttribute('width',"1em");
rect.setAttribute('height',"1ex");
rect.setAttribute('x',"1in");
svg.appendChild(rect);
var bb = rect.getBBox();
document.body.removeChild(svg);
var inch = bb.x;
svgedit.units.typeMap['em'] = bb.width;
svgedit.units.typeMap['ex'] = bb.height;
svgedit.units.typeMap['in'] = inch;
svgedit.units.typeMap['cm'] = inch / 2.54;
svgedit.units.typeMap['mm'] = inch / 25.4;
svgedit.units.typeMap['pt'] = inch / 72;
svgedit.units.typeMap['pc'] = inch / 6;
svgedit.units.typeMap['%'] = 0;
};
})();