Merge pull request #109 from gec/layerTests
Fix rename layer, merge/cloneLayer. Migrate functions from Canvas to Draw. Tests.master
commit
e35413c5ad
|
@ -300,10 +300,20 @@ svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
|
||||||
/**
|
/**
|
||||||
* Set the current layer's name.
|
* Set the current layer's name.
|
||||||
* @param {string} name - The new name.
|
* @param {string} name - The new name.
|
||||||
* @returns {Object} If the name was changed, returns {title:SVGGElement, previousName:string}; otherwise null.
|
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
|
||||||
|
* @returns {string|null} The new name if changed; otherwise, null.
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.setCurrentLayerName = function (name) {
|
svgedit.draw.Drawing.prototype.setCurrentLayerName = function (name, hrService) {
|
||||||
return this.current_layer ? this.current_layer.setName(name) : null;
|
var finalName = null;
|
||||||
|
if (this.current_layer) {
|
||||||
|
var oldName = this.current_layer.getName();
|
||||||
|
finalName = this.current_layer.setName(name, hrService);
|
||||||
|
if (finalName) {
|
||||||
|
delete this.layer_map[oldName];
|
||||||
|
this.layer_map[finalName] = this.current_layer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalName;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -354,7 +364,7 @@ svgedit.draw.Drawing.prototype.setCurrentLayerPosition = function (newpos) {
|
||||||
svgedit.draw.Drawing.prototype.mergeLayer = function (hrService) {
|
svgedit.draw.Drawing.prototype.mergeLayer = function (hrService) {
|
||||||
var current_group = this.current_layer.getGroup();
|
var current_group = this.current_layer.getGroup();
|
||||||
var prevGroup = $(current_group).prev()[0];
|
var prevGroup = $(current_group).prev()[0];
|
||||||
if (!prevGroup) {return null;}
|
if (!prevGroup) {return;}
|
||||||
|
|
||||||
hrService.startBatchCommand('Merge Layer');
|
hrService.startBatchCommand('Merge Layer');
|
||||||
|
|
||||||
|
@ -509,12 +519,13 @@ svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new top-level layer in the drawing with the given name and
|
* Creates a new top-level layer in the drawing with the given name and
|
||||||
* sets the current layer to it.
|
* makes it the current layer.
|
||||||
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
|
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
|
||||||
|
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
|
||||||
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
||||||
* also the current layer of this drawing.
|
* also the current layer of this drawing.
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.createLayer = function(name) {
|
svgedit.draw.Drawing.prototype.createLayer = function(name, hrService) {
|
||||||
if (this.current_layer) {
|
if (this.current_layer) {
|
||||||
this.current_layer.deactivate();
|
this.current_layer.deactivate();
|
||||||
}
|
}
|
||||||
|
@ -522,13 +533,69 @@ svgedit.draw.Drawing.prototype.createLayer = function(name) {
|
||||||
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
||||||
name = getNewLayerName(Object.keys(this.layer_map));
|
name = getNewLayerName(Object.keys(this.layer_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Crate new layer and add to DOM as last layer
|
||||||
var layer = new svgedit.draw.Layer(name, null, this.svgElem_);
|
var layer = new svgedit.draw.Layer(name, null, this.svgElem_);
|
||||||
|
// Like to assume hrService exists, but this is backwards compatible with old version of createLayer.
|
||||||
|
if (hrService) {
|
||||||
|
hrService.startBatchCommand('Create Layer');
|
||||||
|
hrService.insertElement(layer.getGroup());
|
||||||
|
hrService.endBatchCommand();
|
||||||
|
}
|
||||||
|
|
||||||
this.all_layers.push(layer);
|
this.all_layers.push(layer);
|
||||||
this.layer_map[name] = layer;
|
this.layer_map[name] = layer;
|
||||||
this.current_layer = layer;
|
this.current_layer = layer;
|
||||||
return layer.getGroup();
|
return layer.getGroup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a copy of the current layer with the given name and makes it the current layer.
|
||||||
|
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
|
||||||
|
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
|
||||||
|
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
||||||
|
* also the current layer of this drawing.
|
||||||
|
*/
|
||||||
|
svgedit.draw.Drawing.prototype.cloneLayer = function(name, hrService) {
|
||||||
|
if (!this.current_layer) {return null;}
|
||||||
|
this.current_layer.deactivate();
|
||||||
|
// Check for duplicate name.
|
||||||
|
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
||||||
|
name = getNewLayerName(Object.keys(this.layer_map));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new group and add to DOM just after current_layer
|
||||||
|
var currentGroup = this.current_layer.getGroup();
|
||||||
|
var layer = new svgedit.draw.Layer(name, currentGroup, this.svgElem_);
|
||||||
|
var group = layer.getGroup();
|
||||||
|
|
||||||
|
// Clone children
|
||||||
|
var children = currentGroup.childNodes;
|
||||||
|
var index;
|
||||||
|
for (index = 0; index < children.length; index++) {
|
||||||
|
var ch = children[index];
|
||||||
|
if (ch.localName == 'title') {continue;}
|
||||||
|
group.appendChild(this.copyElem(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hrService) {
|
||||||
|
hrService.startBatchCommand('Duplicate Layer');
|
||||||
|
hrService.insertElement(group);
|
||||||
|
hrService.endBatchCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update layer containers and current_layer.
|
||||||
|
index = this.all_layers.indexOf(this.current_layer);
|
||||||
|
if (index >= 0) {
|
||||||
|
this.all_layers.splice(index + 1, 0, layer);
|
||||||
|
} else {
|
||||||
|
this.all_layers.push(layer);
|
||||||
|
}
|
||||||
|
this.layer_map[name] = layer;
|
||||||
|
this.current_layer = layer;
|
||||||
|
return group;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the layer is visible. If the layer name is not valid,
|
* Returns whether the layer is visible. If the layer name is not valid,
|
||||||
* then this function returns false.
|
* then this function returns false.
|
||||||
|
@ -589,4 +656,16 @@ svgedit.draw.Drawing.prototype.setLayerOpacity = function(layername, opacity) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a clone of an element, updating its ID and its children's IDs when needed
|
||||||
|
* @param {Element} el - DOM element to clone
|
||||||
|
* @returns {Element}
|
||||||
|
*/
|
||||||
|
svgedit.draw.Drawing.prototype.copyElem = function(el) {
|
||||||
|
var self = this;
|
||||||
|
var getNextIdClosure = function() { return self.getNextId();}
|
||||||
|
return svgedit.utilities.copyElem(el, getNextIdClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*globals svgedit*/
|
/*globals $ svgedit*/
|
||||||
/*jslint vars: true, eqeq: true */
|
/*jslint vars: true, eqeq: true */
|
||||||
/**
|
/**
|
||||||
* Package: svgedit.history
|
* Package: svgedit.history
|
||||||
|
@ -25,24 +25,37 @@ var NS = svgedit.NS;
|
||||||
/**
|
/**
|
||||||
* This class encapsulates the concept of a layer in the drawing. It can be constructed with
|
* This class encapsulates the concept of a layer in the drawing. It can be constructed with
|
||||||
* an existing group element or, with three parameters, will create a new layer group element.
|
* an existing group element or, with three parameters, will create a new layer group element.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* new Layer'name', group) // Use the existing group for this layer.
|
||||||
|
* new Layer('name', group, svgElem) // Create a new group and add it to the DOM after group.
|
||||||
|
* new Layer('name', null, svgElem) // Create a new group and add it to the DOM as the last layer.
|
||||||
|
*
|
||||||
* @param {string} name - Layer name
|
* @param {string} name - Layer name
|
||||||
* @param {SVGGElement} group - SVG group element that constitutes the layer or null if a group should be created and added to the DOM..
|
* @param {SVGGElement|null} group - An existing SVG group element or null.
|
||||||
* @param {SVGGElement} svgElem - The SVG DOM element. If defined, use this to add
|
* If group and no svgElem, use group for this layer.
|
||||||
|
* If group and svgElem, create a new group element and insert it in the DOM after group.
|
||||||
|
* If no group and svgElem, create a new group element and insert it in the DOM as the last layer.
|
||||||
|
* @param {SVGGElement=} svgElem - The SVG DOM element. If defined, use this to add
|
||||||
* a new layer to the document.
|
* a new layer to the document.
|
||||||
*/
|
*/
|
||||||
var Layer = svgedit.draw.Layer = function(name, group, svgElem) {
|
var Layer = svgedit.draw.Layer = function(name, group, svgElem) {
|
||||||
this.name_ = name;
|
this.name_ = name;
|
||||||
this.group_ = group;
|
this.group_ = svgElem ? null : group;
|
||||||
|
|
||||||
if (!group) {
|
if (svgElem) {
|
||||||
// Create a group element with title and add it to the DOM.
|
// Create a group element with title and add it to the DOM.
|
||||||
var svgdoc = svgElem.ownerDocument;
|
var svgdoc = svgElem.ownerDocument;
|
||||||
this.group_ = svgdoc.createElementNS(NS.SVG, "g");
|
this.group_ = svgdoc.createElementNS(NS.SVG, "g");
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
||||||
layer_title.textContent = name;
|
layer_title.textContent = name;
|
||||||
this.group_.appendChild(layer_title);
|
this.group_.appendChild(layer_title);
|
||||||
|
if (group) {
|
||||||
|
$(group).after(this.group_);
|
||||||
|
} else {
|
||||||
svgElem.appendChild(this.group_);
|
svgElem.appendChild(this.group_);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addLayerClass(this.group_);
|
addLayerClass(this.group_);
|
||||||
svgedit.utilities.walkTree(this.group_, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
svgedit.utilities.walkTree(this.group_, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
||||||
|
@ -155,7 +168,13 @@ Layer.prototype.getTitleElement = function() {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
Layer.prototype.setName = function(name) {
|
/**
|
||||||
|
* Set the name of this layer.
|
||||||
|
* @param {string} name - The new name.
|
||||||
|
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
|
||||||
|
* @returns {string|null} The new name if changed; otherwise, null.
|
||||||
|
*/
|
||||||
|
Layer.prototype.setName = function(name, hrService) {
|
||||||
var previousName = this.name_;
|
var previousName = this.name_;
|
||||||
name = svgedit.utilities.toXml(name);
|
name = svgedit.utilities.toXml(name);
|
||||||
// now change the underlying title element contents
|
// now change the underlying title element contents
|
||||||
|
@ -164,7 +183,10 @@ Layer.prototype.setName = function(name) {
|
||||||
while (title.firstChild) { title.removeChild(title.firstChild); }
|
while (title.firstChild) { title.removeChild(title.firstChild); }
|
||||||
title.textContent = name;
|
title.textContent = name;
|
||||||
this.name_ = name;
|
this.name_ = name;
|
||||||
return {title: title, previousName: previousName};
|
if (hrService) {
|
||||||
|
hrService.changeElement(title, {'#text':previousName});
|
||||||
|
}
|
||||||
|
return this.name_;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -355,6 +355,15 @@ var addCommandToHistory = function(cmd) {
|
||||||
canvas.undoMgr.addCommandToHistory(cmd);
|
canvas.undoMgr.addCommandToHistory(cmd);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a HistoryRecordingService.
|
||||||
|
* @param {svgedit.history.HistoryRecordingService=} hrService - if exists, return it instead of creating a new service.
|
||||||
|
* @returns {svgedit.history.HistoryRecordingService}
|
||||||
|
*/
|
||||||
|
function historyRecordingService(hrService) {
|
||||||
|
return hrService ? hrService : new svgedit.history.HistoryRecordingService(canvas.undoMgr);
|
||||||
|
}
|
||||||
|
|
||||||
// import from select.js
|
// import from select.js
|
||||||
svgedit.select.init(curConfig, {
|
svgedit.select.init(curConfig, {
|
||||||
createSVGElement: function(jsonMap) { return canvas.addSvgElementFromJson(jsonMap); },
|
createSVGElement: function(jsonMap) { return canvas.addSvgElementFromJson(jsonMap); },
|
||||||
|
@ -666,56 +675,6 @@ var groupSvgElem = this.groupSvgElem = function(elem) {
|
||||||
$(g).append(elem).data('gsvg', elem)[0].id = getNextId();
|
$(g).append(elem).data('gsvg', elem)[0].id = getNextId();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: copyElem
|
|
||||||
// Create a clone of an element, updating its ID and its children's IDs when needed
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// el - DOM element to clone
|
|
||||||
//
|
|
||||||
// Returns: The cloned element
|
|
||||||
var copyElem = function(el) {
|
|
||||||
// manually create a copy of the element
|
|
||||||
var new_el = document.createElementNS(el.namespaceURI, el.nodeName);
|
|
||||||
$.each(el.attributes, function(i, attr) {
|
|
||||||
if (attr.localName != '-moz-math-font-style') {
|
|
||||||
new_el.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// set the copied element's new id
|
|
||||||
new_el.removeAttribute('id');
|
|
||||||
new_el.id = getNextId();
|
|
||||||
|
|
||||||
// Opera's "d" value needs to be reset for Opera/Win/non-EN
|
|
||||||
// Also needed for webkit (else does not keep curved segments on clone)
|
|
||||||
if (svgedit.browser.isWebkit() && el.nodeName == 'path') {
|
|
||||||
var fixed_d = pathActions.convertPath(el);
|
|
||||||
new_el.setAttribute('d', fixed_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now create copies of all children
|
|
||||||
$.each(el.childNodes, function(i, child) {
|
|
||||||
switch(child.nodeType) {
|
|
||||||
case 1: // element node
|
|
||||||
new_el.appendChild(copyElem(child));
|
|
||||||
break;
|
|
||||||
case 3: // text node
|
|
||||||
new_el.textContent = child.nodeValue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($(el).data('gsvg')) {
|
|
||||||
$(new_el).data('gsvg', new_el.firstChild);
|
|
||||||
} else if ($(el).data('symbol')) {
|
|
||||||
var ref = $(el).data('symbol');
|
|
||||||
$(new_el).data('ref', ref).data('symbol', ref);
|
|
||||||
} else if (new_el.tagName == 'image') {
|
|
||||||
preventClickDefault(new_el);
|
|
||||||
}
|
|
||||||
return new_el;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set scope for these functions
|
// Set scope for these functions
|
||||||
var getId, getNextId;
|
var getId, getNextId;
|
||||||
|
@ -882,9 +841,6 @@ var recalculateAllSelectedDimensions = this.recalculateAllSelectedDimensions = f
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is how we map paths to our preferred relative segment types
|
|
||||||
var pathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
|
|
||||||
'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
|
|
||||||
|
|
||||||
// Debug tool to easily see the current matrix in the browser's console
|
// Debug tool to easily see the current matrix in the browser's console
|
||||||
var logMatrix = function(m) {
|
var logMatrix = function(m) {
|
||||||
|
@ -1404,7 +1360,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setHref(newImage, last_good_img_url);
|
setHref(newImage, last_good_img_url);
|
||||||
preventClickDefault(newImage);
|
svgedit.utilities.preventClickDefault(newImage);
|
||||||
break;
|
break;
|
||||||
case 'square':
|
case 'square':
|
||||||
// FIXME: once we create the rect, we lose information that this was a square
|
// FIXME: once we create the rect, we lose information that this was a square
|
||||||
|
@ -2353,14 +2309,6 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
// Function: preventClickDefault
|
|
||||||
// Prevents default browser click behaviour on the given element
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// img - The DOM element to prevent the cilck on
|
|
||||||
var preventClickDefault = function(img) {
|
|
||||||
$(img).click(function(e){e.preventDefault();});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Group: Text edit functions
|
// Group: Text edit functions
|
||||||
// Functions relating to editing text elements
|
// Functions relating to editing text elements
|
||||||
|
@ -3684,165 +3632,7 @@ pathActions = canvas.pathActions = function() {
|
||||||
if (svgedit.browser.isWebkit()) {resetD(elem);}
|
if (svgedit.browser.isWebkit()) {resetD(elem);}
|
||||||
},
|
},
|
||||||
// Convert a path to one with only absolute or relative values
|
// Convert a path to one with only absolute or relative values
|
||||||
convertPath: function(path, toRel) {
|
convertPath: svgedit.utilities.convertPath
|
||||||
var i;
|
|
||||||
var segList = path.pathSegList;
|
|
||||||
var len = segList.numberOfItems;
|
|
||||||
var curx = 0, cury = 0;
|
|
||||||
var d = '';
|
|
||||||
var last_m = null;
|
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
|
||||||
var seg = segList.getItem(i);
|
|
||||||
// if these properties are not in the segment, set them to zero
|
|
||||||
var x = seg.x || 0,
|
|
||||||
y = seg.y || 0,
|
|
||||||
x1 = seg.x1 || 0,
|
|
||||||
y1 = seg.y1 || 0,
|
|
||||||
x2 = seg.x2 || 0,
|
|
||||||
y2 = seg.y2 || 0;
|
|
||||||
|
|
||||||
var type = seg.pathSegType;
|
|
||||||
var letter = pathMap[type]['to'+(toRel?'Lower':'Upper')+'Case']();
|
|
||||||
|
|
||||||
var addToD = function(pnts, more, last) {
|
|
||||||
var str = '';
|
|
||||||
more = more ? ' ' + more.join(' ') : '';
|
|
||||||
last = last ? ' ' + svgedit.units.shortFloat(last) : '';
|
|
||||||
$.each(pnts, function(i, pnt) {
|
|
||||||
pnts[i] = svgedit.units.shortFloat(pnt);
|
|
||||||
});
|
|
||||||
d += letter + pnts.join(' ') + more + last;
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 1: // z,Z closepath (Z/z)
|
|
||||||
d += 'z';
|
|
||||||
break;
|
|
||||||
case 12: // absolute horizontal line (H)
|
|
||||||
x -= curx;
|
|
||||||
case 13: // relative horizontal line (h)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
letter = 'l';
|
|
||||||
} else {
|
|
||||||
x += curx;
|
|
||||||
curx = x;
|
|
||||||
letter = 'L';
|
|
||||||
}
|
|
||||||
// Convert to "line" for easier editing
|
|
||||||
addToD([[x, cury]]);
|
|
||||||
break;
|
|
||||||
case 14: // absolute vertical line (V)
|
|
||||||
y -= cury;
|
|
||||||
case 15: // relative vertical line (v)
|
|
||||||
if (toRel) {
|
|
||||||
cury += y;
|
|
||||||
letter = 'l';
|
|
||||||
} else {
|
|
||||||
y += cury;
|
|
||||||
cury = y;
|
|
||||||
letter = 'L';
|
|
||||||
}
|
|
||||||
// Convert to "line" for easier editing
|
|
||||||
addToD([[curx, y]]);
|
|
||||||
break;
|
|
||||||
case 2: // absolute move (M)
|
|
||||||
case 4: // absolute line (L)
|
|
||||||
case 18: // absolute smooth quad (T)
|
|
||||||
x -= curx;
|
|
||||||
y -= cury;
|
|
||||||
case 5: // relative line (l)
|
|
||||||
case 3: // relative move (m)
|
|
||||||
// If the last segment was a "z", this must be relative to
|
|
||||||
if (last_m && segList.getItem(i-1).pathSegType === 1 && !toRel) {
|
|
||||||
curx = last_m[0];
|
|
||||||
cury = last_m[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
case 19: // relative smooth quad (t)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
cury += y;
|
|
||||||
} else {
|
|
||||||
x += curx;
|
|
||||||
y += cury;
|
|
||||||
curx = x;
|
|
||||||
cury = y;
|
|
||||||
}
|
|
||||||
if (type === 3) {last_m = [curx, cury];}
|
|
||||||
|
|
||||||
addToD([[x, y]]);
|
|
||||||
break;
|
|
||||||
case 6: // absolute cubic (C)
|
|
||||||
x -= curx; x1 -= curx; x2 -= curx;
|
|
||||||
y -= cury; y1 -= cury; y2 -= cury;
|
|
||||||
case 7: // relative cubic (c)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
cury += y;
|
|
||||||
} else {
|
|
||||||
x += curx; x1 += curx; x2 += curx;
|
|
||||||
y += cury; y1 += cury; y2 += cury;
|
|
||||||
curx = x;
|
|
||||||
cury = y;
|
|
||||||
}
|
|
||||||
addToD([[x1, y1], [x2, y2], [x, y]]);
|
|
||||||
break;
|
|
||||||
case 8: // absolute quad (Q)
|
|
||||||
x -= curx; x1 -= curx;
|
|
||||||
y -= cury; y1 -= cury;
|
|
||||||
case 9: // relative quad (q)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
cury += y;
|
|
||||||
} else {
|
|
||||||
x += curx; x1 += curx;
|
|
||||||
y += cury; y1 += cury;
|
|
||||||
curx = x;
|
|
||||||
cury = y;
|
|
||||||
}
|
|
||||||
addToD([[x1, y1],[x, y]]);
|
|
||||||
break;
|
|
||||||
case 10: // absolute elliptical arc (A)
|
|
||||||
x -= curx;
|
|
||||||
y -= cury;
|
|
||||||
case 11: // relative elliptical arc (a)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
cury += y;
|
|
||||||
} else {
|
|
||||||
x += curx;
|
|
||||||
y += cury;
|
|
||||||
curx = x;
|
|
||||||
cury = y;
|
|
||||||
}
|
|
||||||
addToD([[seg.r1, seg.r2]], [
|
|
||||||
seg.angle,
|
|
||||||
(seg.largeArcFlag ? 1 : 0),
|
|
||||||
(seg.sweepFlag ? 1 : 0)
|
|
||||||
], [x, y]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 16: // absolute smooth cubic (S)
|
|
||||||
x -= curx; x2 -= curx;
|
|
||||||
y -= cury; y2 -= cury;
|
|
||||||
case 17: // relative smooth cubic (s)
|
|
||||||
if (toRel) {
|
|
||||||
curx += x;
|
|
||||||
cury += y;
|
|
||||||
} else {
|
|
||||||
x += curx; x2 += curx;
|
|
||||||
y += cury; y2 += cury;
|
|
||||||
curx = x;
|
|
||||||
cury = y;
|
|
||||||
}
|
|
||||||
addToD([[x2, y2],[x, y]]);
|
|
||||||
break;
|
|
||||||
} // switch on path segment type
|
|
||||||
} // for each segment
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
// end pathActions
|
// end pathActions
|
||||||
|
@ -4676,7 +4466,7 @@ this.setSvgString = function(xmlString) {
|
||||||
// change image href vals if possible
|
// change image href vals if possible
|
||||||
content.find('image').each(function() {
|
content.find('image').each(function() {
|
||||||
var image = this;
|
var image = this;
|
||||||
preventClickDefault(image);
|
svgedit.utilities.preventClickDefault(image);
|
||||||
var val = getHref(this);
|
var val = getHref(this);
|
||||||
if (val) {
|
if (val) {
|
||||||
if (val.indexOf('data:') === 0) {
|
if (val.indexOf('data:') === 0) {
|
||||||
|
@ -4966,44 +4756,25 @@ var identifyLayers = canvas.identifyLayers = function() {
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// name - The given name
|
// name - The given name
|
||||||
this.createLayer = function(name) {
|
this.createLayer = function(name, hrService) {
|
||||||
var batchCmd = new svgedit.history.BatchCommand('Create Layer');
|
var new_layer = getCurrentDrawing().createLayer(name, historyRecordingService(hrService));
|
||||||
var new_layer = getCurrentDrawing().createLayer(name);
|
|
||||||
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(new_layer));
|
|
||||||
addCommandToHistory(batchCmd);
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
call('changed', [new_layer]);
|
call('changed', [new_layer]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: cloneLayer
|
/**
|
||||||
// Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents
|
* Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents
|
||||||
// to it, and then clears the selection. This function then calls the 'changed' handler.
|
* to it, and then clears the selection. This function then calls the 'changed' handler.
|
||||||
// This is an undoable action.
|
* This is an undoable action.
|
||||||
//
|
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
|
||||||
// Parameters:
|
* @param {svgedit.history.HistoryRecordingService} hrService - History recording service
|
||||||
// name - The given name
|
*/
|
||||||
this.cloneLayer = function(name) {
|
this.cloneLayer = function(name, hrService) {
|
||||||
var batchCmd = new svgedit.history.BatchCommand('Duplicate Layer');
|
// Clone the current layer and make the cloned layer the new current layer
|
||||||
var new_layer = svgdoc.createElementNS(NS.SVG, 'g');
|
var new_layer = getCurrentDrawing().cloneLayer(name, historyRecordingService(hrService));
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, 'title');
|
|
||||||
layer_title.textContent = name;
|
|
||||||
new_layer.appendChild(layer_title);
|
|
||||||
var current_layer = getCurrentDrawing().getCurrentLayer();
|
|
||||||
$(current_layer).after(new_layer);
|
|
||||||
var childs = current_layer.childNodes;
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < childs.length; i++) {
|
|
||||||
var ch = childs[i];
|
|
||||||
if (ch.localName == 'title') {continue;}
|
|
||||||
new_layer.appendChild(copyElem(ch));
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
identifyLayers();
|
leaveContext();
|
||||||
|
|
||||||
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(new_layer));
|
|
||||||
addCommandToHistory(batchCmd);
|
|
||||||
canvas.setCurrentLayer(name);
|
|
||||||
call('changed', [new_layer]);
|
call('changed', [new_layer]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5058,11 +4829,8 @@ this.renameCurrentLayer = function(newname) {
|
||||||
var drawing = getCurrentDrawing();
|
var drawing = getCurrentDrawing();
|
||||||
var layer = drawing.getCurrentLayer();
|
var layer = drawing.getCurrentLayer();
|
||||||
if (layer) {
|
if (layer) {
|
||||||
var result = drawing.setCurrentLayerName( newname);
|
var result = drawing.setCurrentLayerName(newname, historyRecordingService());
|
||||||
if (result) {
|
if (result) {
|
||||||
var batchCmd = new svgedit.history.BatchCommand('Rename Layer');
|
|
||||||
batchCmd.addSubCommand(new svgedit.history.ChangeElementCommand(result.title, {'#text':result.previousName}));
|
|
||||||
addCommandToHistory(batchCmd);
|
|
||||||
call('changed', [layer]);
|
call('changed', [layer]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5158,20 +4926,14 @@ this.moveSelectedToLayer = function(layername) {
|
||||||
|
|
||||||
|
|
||||||
this.mergeLayer = function(hrService) {
|
this.mergeLayer = function(hrService) {
|
||||||
if (!hrService) {
|
getCurrentDrawing().mergeLayer(historyRecordingService(hrService));
|
||||||
hrService = new svgedit.history.HistoryRecordingService(this.undoMgr);
|
|
||||||
}
|
|
||||||
getCurrentDrawing().mergeLayer(hrService);
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
leaveContext();
|
leaveContext();
|
||||||
call('changed', [svgcontent]);
|
call('changed', [svgcontent]);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.mergeAllLayers = function(hrService) {
|
this.mergeAllLayers = function(hrService) {
|
||||||
if (!hrService) {
|
getCurrentDrawing().mergeAllLayers(historyRecordingService(hrService));
|
||||||
hrService = new svgedit.history.HistoryRecordingService(this.undoMgr);
|
|
||||||
}
|
|
||||||
getCurrentDrawing().mergeAllLayers(hrService);
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
leaveContext();
|
leaveContext();
|
||||||
call('changed', [svgcontent]);
|
call('changed', [svgcontent]);
|
||||||
|
@ -6622,19 +6384,19 @@ this.pasteElements = function(type, x, y) {
|
||||||
|
|
||||||
var pasted = [];
|
var pasted = [];
|
||||||
var batchCmd = new svgedit.history.BatchCommand('Paste elements');
|
var batchCmd = new svgedit.history.BatchCommand('Paste elements');
|
||||||
|
var drawing = getCurrentDrawing();
|
||||||
|
|
||||||
// Move elements to lastClickPoint
|
// Move elements to lastClickPoint
|
||||||
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
var elem = cb[len];
|
var elem = cb[len];
|
||||||
if (!elem) {continue;}
|
if (!elem) {continue;}
|
||||||
var copy = copyElem(elem);
|
var copy = drawing.copyElem(elem);
|
||||||
|
|
||||||
// See if elem with elem ID is in the DOM already
|
// See if elem with elem ID is in the DOM already
|
||||||
if (!svgedit.utilities.getElem(elem.id)) {copy.id = elem.id;}
|
if (!svgedit.utilities.getElem(elem.id)) {copy.id = elem.id;}
|
||||||
|
|
||||||
pasted.push(copy);
|
pasted.push(copy);
|
||||||
(current_group || getCurrentDrawing().getCurrentLayer()).appendChild(copy);
|
(current_group || drawing.getCurrentLayer()).appendChild(copy);
|
||||||
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(copy));
|
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(copy));
|
||||||
|
|
||||||
restoreRefElems(copy);
|
restoreRefElems(copy);
|
||||||
|
@ -6758,6 +6520,7 @@ var pushGroupProperties = this.pushGroupProperties = function(g, undoable) {
|
||||||
|
|
||||||
var gattrs = $(g).attr(['filter', 'opacity']);
|
var gattrs = $(g).attr(['filter', 'opacity']);
|
||||||
var gfilter, gblur, changes;
|
var gfilter, gblur, changes;
|
||||||
|
var drawing = getCurrentDrawing();
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
var elem = children[i];
|
var elem = children[i];
|
||||||
|
@ -6788,7 +6551,7 @@ var pushGroupProperties = this.pushGroupProperties = function(g, undoable) {
|
||||||
gfilter = svgedit.utilities.getRefElem(gattrs.filter);
|
gfilter = svgedit.utilities.getRefElem(gattrs.filter);
|
||||||
} else {
|
} else {
|
||||||
// Clone the group's filter
|
// Clone the group's filter
|
||||||
gfilter = copyElem(gfilter);
|
gfilter = drawing.copyElem(gfilter);
|
||||||
svgedit.utilities.findDefs().appendChild(gfilter);
|
svgedit.utilities.findDefs().appendChild(gfilter);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -7167,11 +6930,12 @@ this.cloneSelectedElements = function(x, y) {
|
||||||
this.clearSelection(true);
|
this.clearSelection(true);
|
||||||
// note that we loop in the reverse way because of the way elements are added
|
// note that we loop in the reverse way because of the way elements are added
|
||||||
// to the selectedElements array (top-first)
|
// to the selectedElements array (top-first)
|
||||||
|
var drawing = getCurrentDrawing();
|
||||||
i = copiedElements.length;
|
i = copiedElements.length;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
// clone each element and replace it within copiedElements
|
// clone each element and replace it within copiedElements
|
||||||
elem = copiedElements[i] = copyElem(copiedElements[i]);
|
elem = copiedElements[i] = drawing.copyElem(copiedElements[i]);
|
||||||
(current_group || getCurrentDrawing().getCurrentLayer()).appendChild(elem);
|
(current_group || drawing.getCurrentLayer()).appendChild(elem);
|
||||||
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(elem));
|
batchCmd.addSubCommand(new svgedit.history.InsertElementCommand(elem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7410,7 +7174,7 @@ this.getPrivateMethods = function() {
|
||||||
BatchCommand: BatchCommand,
|
BatchCommand: BatchCommand,
|
||||||
call: call,
|
call: call,
|
||||||
ChangeElementCommand: ChangeElementCommand,
|
ChangeElementCommand: ChangeElementCommand,
|
||||||
copyElem: copyElem,
|
copyElem: function(elem) {return getCurrentDrawing().copyElem(elem)},
|
||||||
ffClone: ffClone,
|
ffClone: ffClone,
|
||||||
findDefs: findDefs,
|
findDefs: findDefs,
|
||||||
findDuplicateGradient: findDuplicateGradient,
|
findDuplicateGradient: findDuplicateGradient,
|
||||||
|
@ -7428,7 +7192,7 @@ this.getPrivateMethods = function() {
|
||||||
logMatrix: logMatrix,
|
logMatrix: logMatrix,
|
||||||
matrixMultiply: matrixMultiply,
|
matrixMultiply: matrixMultiply,
|
||||||
MoveElementCommand: MoveElementCommand,
|
MoveElementCommand: MoveElementCommand,
|
||||||
preventClickDefault: preventClickDefault,
|
preventClickDefault: svgedit.utilities.preventClickDefault,
|
||||||
recalculateAllSelectedDimensions: recalculateAllSelectedDimensions,
|
recalculateAllSelectedDimensions: recalculateAllSelectedDimensions,
|
||||||
recalculateDimensions: recalculateDimensions,
|
recalculateDimensions: recalculateDimensions,
|
||||||
remapElement: remapElement,
|
remapElement: remapElement,
|
||||||
|
|
|
@ -1137,4 +1137,250 @@ svgedit.utilities.buildJSPDFCallback = function (callJSPDF) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevents default browser click behaviour on the given element
|
||||||
|
* @param img - The DOM element to prevent the click on
|
||||||
|
*/
|
||||||
|
svgedit.utilities.preventClickDefault = function(img) {
|
||||||
|
$(img).click(function(e){e.preventDefault();});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a clone of an element, updating its ID and its children's IDs when needed
|
||||||
|
* @param {Element} el - DOM element to clone
|
||||||
|
* @param {function()} getNextId - function the get the next unique ID.
|
||||||
|
* @returns {Element}
|
||||||
|
*/
|
||||||
|
svgedit.utilities.copyElem = function(el, getNextId) {
|
||||||
|
// manually create a copy of the element
|
||||||
|
var new_el = document.createElementNS(el.namespaceURI, el.nodeName);
|
||||||
|
$.each(el.attributes, function(i, attr) {
|
||||||
|
if (attr.localName != '-moz-math-font-style') {
|
||||||
|
new_el.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// set the copied element's new id
|
||||||
|
new_el.removeAttribute('id');
|
||||||
|
new_el.id = getNextId();
|
||||||
|
|
||||||
|
// Opera's "d" value needs to be reset for Opera/Win/non-EN
|
||||||
|
// Also needed for webkit (else does not keep curved segments on clone)
|
||||||
|
if (svgedit.browser.isWebkit() && el.nodeName == 'path') {
|
||||||
|
var fixed_d = svgedit.utilities.convertPath(el);
|
||||||
|
new_el.setAttribute('d', fixed_d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now create copies of all children
|
||||||
|
$.each(el.childNodes, function(i, child) {
|
||||||
|
switch(child.nodeType) {
|
||||||
|
case 1: // element node
|
||||||
|
new_el.appendChild(svgedit.utilities.copyElem(child, getNextId));
|
||||||
|
break;
|
||||||
|
case 3: // text node
|
||||||
|
new_el.textContent = child.nodeValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($(el).data('gsvg')) {
|
||||||
|
$(new_el).data('gsvg', new_el.firstChild);
|
||||||
|
} else if ($(el).data('symbol')) {
|
||||||
|
var ref = $(el).data('symbol');
|
||||||
|
$(new_el).data('ref', ref).data('symbol', ref);
|
||||||
|
} else if (new_el.tagName == 'image') {
|
||||||
|
preventClickDefault(new_el);
|
||||||
|
}
|
||||||
|
return new_el;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: refactor callers in convertPath to use getPathDFromSegments instead of this function.
|
||||||
|
* Legacy code refactored from svgcanvas.pathActions.convertPath
|
||||||
|
* @param letter - path segment command
|
||||||
|
* @param {Array.<Array.<number>>} points - x,y points.
|
||||||
|
* @param {Array.<Array.<number>>=} morePoints - x,y points
|
||||||
|
* @param {Array.<number>=}lastPoint - x,y point
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function pathDSegment(letter, points, morePoints, lastPoint) {
|
||||||
|
$.each(points, function(i, pnt) {
|
||||||
|
points[i] = svgedit.units.shortFloat(pnt);
|
||||||
|
});
|
||||||
|
var segment = letter + points.join(' ');
|
||||||
|
if (morePoints) {
|
||||||
|
segment += ' ' + morePoints.join(' ');
|
||||||
|
}
|
||||||
|
if (lastPoint) {
|
||||||
|
segment += ' ' + svgedit.units.shortFloat(lastPoint);
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is how we map paths to our preferred relative segment types
|
||||||
|
var pathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
|
||||||
|
'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: move to pathActions.js when migrating rest of pathActions out of svgcanvas.js
|
||||||
|
* Convert a path to one with only absolute or relative values
|
||||||
|
* @param {Object} path - the path to convert
|
||||||
|
* @param {boolean} toRel - true of convert to relative
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
svgedit.utilities.convertPath = function(path, toRel) {
|
||||||
|
var i;
|
||||||
|
var segList = path.pathSegList;
|
||||||
|
var len = segList.numberOfItems;
|
||||||
|
var curx = 0, cury = 0;
|
||||||
|
var d = '';
|
||||||
|
var last_m = null;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
var seg = segList.getItem(i);
|
||||||
|
// if these properties are not in the segment, set them to zero
|
||||||
|
var x = seg.x || 0,
|
||||||
|
y = seg.y || 0,
|
||||||
|
x1 = seg.x1 || 0,
|
||||||
|
y1 = seg.y1 || 0,
|
||||||
|
x2 = seg.x2 || 0,
|
||||||
|
y2 = seg.y2 || 0;
|
||||||
|
|
||||||
|
var type = seg.pathSegType;
|
||||||
|
var letter = pathMap[type]['to'+(toRel?'Lower':'Upper')+'Case']();
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 1: // z,Z closepath (Z/z)
|
||||||
|
d += 'z';
|
||||||
|
break;
|
||||||
|
case 12: // absolute horizontal line (H)
|
||||||
|
x -= curx;
|
||||||
|
case 13: // relative horizontal line (h)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
letter = 'l';
|
||||||
|
} else {
|
||||||
|
x += curx;
|
||||||
|
curx = x;
|
||||||
|
letter = 'L';
|
||||||
|
}
|
||||||
|
// Convert to "line" for easier editing
|
||||||
|
d += pathDSegment(letter,[[x, cury]]);
|
||||||
|
break;
|
||||||
|
case 14: // absolute vertical line (V)
|
||||||
|
y -= cury;
|
||||||
|
case 15: // relative vertical line (v)
|
||||||
|
if (toRel) {
|
||||||
|
cury += y;
|
||||||
|
letter = 'l';
|
||||||
|
} else {
|
||||||
|
y += cury;
|
||||||
|
cury = y;
|
||||||
|
letter = 'L';
|
||||||
|
}
|
||||||
|
// Convert to "line" for easier editing
|
||||||
|
d += pathDSegment(letter,[[curx, y]]);
|
||||||
|
break;
|
||||||
|
case 2: // absolute move (M)
|
||||||
|
case 4: // absolute line (L)
|
||||||
|
case 18: // absolute smooth quad (T)
|
||||||
|
x -= curx;
|
||||||
|
y -= cury;
|
||||||
|
case 5: // relative line (l)
|
||||||
|
case 3: // relative move (m)
|
||||||
|
// If the last segment was a "z", this must be relative to
|
||||||
|
if (last_m && segList.getItem(i-1).pathSegType === 1 && !toRel) {
|
||||||
|
curx = last_m[0];
|
||||||
|
cury = last_m[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
case 19: // relative smooth quad (t)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
} else {
|
||||||
|
x += curx;
|
||||||
|
y += cury;
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
}
|
||||||
|
if (type === 3) {last_m = [curx, cury];}
|
||||||
|
|
||||||
|
d += pathDSegment(letter,[[x, y]]);
|
||||||
|
break;
|
||||||
|
case 6: // absolute cubic (C)
|
||||||
|
x -= curx; x1 -= curx; x2 -= curx;
|
||||||
|
y -= cury; y1 -= cury; y2 -= cury;
|
||||||
|
case 7: // relative cubic (c)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
} else {
|
||||||
|
x += curx; x1 += curx; x2 += curx;
|
||||||
|
y += cury; y1 += cury; y2 += cury;
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
}
|
||||||
|
d += pathDSegment(letter,[[x1, y1], [x2, y2], [x, y]]);
|
||||||
|
break;
|
||||||
|
case 8: // absolute quad (Q)
|
||||||
|
x -= curx; x1 -= curx;
|
||||||
|
y -= cury; y1 -= cury;
|
||||||
|
case 9: // relative quad (q)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
} else {
|
||||||
|
x += curx; x1 += curx;
|
||||||
|
y += cury; y1 += cury;
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
}
|
||||||
|
d += pathDSegment(letter,[[x1, y1],[x, y]]);
|
||||||
|
break;
|
||||||
|
case 10: // absolute elliptical arc (A)
|
||||||
|
x -= curx;
|
||||||
|
y -= cury;
|
||||||
|
case 11: // relative elliptical arc (a)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
} else {
|
||||||
|
x += curx;
|
||||||
|
y += cury;
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
}
|
||||||
|
d += pathDSegment(letter,[[seg.r1, seg.r2]], [
|
||||||
|
seg.angle,
|
||||||
|
(seg.largeArcFlag ? 1 : 0),
|
||||||
|
(seg.sweepFlag ? 1 : 0)
|
||||||
|
], [x, y]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 16: // absolute smooth cubic (S)
|
||||||
|
x -= curx; x2 -= curx;
|
||||||
|
y -= cury; y2 -= cury;
|
||||||
|
case 17: // relative smooth cubic (s)
|
||||||
|
if (toRel) {
|
||||||
|
curx += x;
|
||||||
|
cury += y;
|
||||||
|
} else {
|
||||||
|
x += curx; x2 += curx;
|
||||||
|
y += cury; y2 += cury;
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
}
|
||||||
|
d += pathDSegment(letter,[[x2, y2],[x, y]]);
|
||||||
|
break;
|
||||||
|
} // switch on path segment type
|
||||||
|
} // for each segment
|
||||||
|
return d;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
<script src='../editor/svgedit.js'></script>
|
<script src='../editor/svgedit.js'></script>
|
||||||
<script src='../editor/pathseg.js'></script>
|
<script src='../editor/pathseg.js'></script>
|
||||||
<script src='../editor/browser.js'></script>
|
<script src='../editor/browser.js'></script>
|
||||||
|
<script src='../editor/units.js'></script>
|
||||||
<script src='../editor/svgutils.js'></script>
|
<script src='../editor/svgutils.js'></script>
|
||||||
<script src='../editor/draw.js'></script>
|
<script src='../editor/draw.js'></script>
|
||||||
<script src='../editor/layer.js'></script>
|
<script src='../editor/layer.js'></script>
|
||||||
<script src='qunit/qunit.js'></script>
|
<script src='qunit/qunit.js'></script>
|
||||||
|
<script src="sinon/sinon-1.17.3.js"></script>
|
||||||
|
<script src="sinon/sinon-qunit-1.0.0.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
// log function
|
// log function
|
||||||
|
@ -26,6 +29,15 @@
|
||||||
var LAYER1 = 'Layer 1';
|
var LAYER1 = 'Layer 1';
|
||||||
var LAYER2 = 'Layer 2';
|
var LAYER2 = 'Layer 2';
|
||||||
var LAYER3 = 'Layer 3';
|
var LAYER3 = 'Layer 3';
|
||||||
|
var PATH_ATTR = {
|
||||||
|
// clone will convert relative to absolute, so the test for equality fails.
|
||||||
|
//'d': 'm7.38867,57.38867c0,-27.62431 22.37569,-50 50,-50c27.62431,0 50,22.37569 50,50c0,27.62431 -22.37569,50 -50,50c-27.62431,0 -50,-22.37569 -50,-50z',
|
||||||
|
'd': 'M7.389,57.389C7.389,29.764 29.764,7.389 57.389,7.389C85.013,7.389 107.389,29.764 107.389,57.389C107.389,85.013 85.013,107.389 57.389,107.389C29.764,107.389 7.389,85.013 7.389,57.389z',
|
||||||
|
'transform': 'rotate(45 57.388671875000036,57.388671874999986) ',
|
||||||
|
'stroke-width': '5',
|
||||||
|
'stroke': '#660000',
|
||||||
|
'fill':'#ff0000'
|
||||||
|
};
|
||||||
|
|
||||||
var svg = document.createElementNS(NS.SVG, 'svg');
|
var svg = document.createElementNS(NS.SVG, 'svg');
|
||||||
var sandbox = document.getElementById('sandbox');
|
var sandbox = document.getElementById('sandbox');
|
||||||
|
@ -37,6 +49,19 @@
|
||||||
svg_n.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
|
svg_n.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
|
||||||
svg_n.setAttributeNS(NS.SE, 'se:nonce', NONCE);
|
svg_n.setAttributeNS(NS.SE, 'se:nonce', NONCE);
|
||||||
|
|
||||||
|
svgedit.units.init({
|
||||||
|
// used by svgedit.units.shortFloat - call path: cloneLayer -> copyElem -> convertPath -> pathDSegment -> shortFloat
|
||||||
|
getRoundDigits: function() { return 3; }
|
||||||
|
});
|
||||||
|
|
||||||
|
function createSVGElement(jsonMap) {
|
||||||
|
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||||
|
for (var attr in jsonMap['attr']) {
|
||||||
|
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||||
|
}
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
var setupSvgWith3Layers = function(svgElem) {
|
var setupSvgWith3Layers = function(svgElem) {
|
||||||
var layer1 = document.createElementNS(NS.SVG, 'g');
|
var layer1 = document.createElementNS(NS.SVG, 'g');
|
||||||
var layer1_title = document.createElementNS(NS.SVG, 'title');
|
var layer1_title = document.createElementNS(NS.SVG, 'title');
|
||||||
|
@ -55,12 +80,51 @@
|
||||||
layer3_title.appendChild(document.createTextNode(LAYER3));
|
layer3_title.appendChild(document.createTextNode(LAYER3));
|
||||||
layer3.appendChild(layer3_title);
|
layer3.appendChild(layer3_title);
|
||||||
svgElem.appendChild(layer3);
|
svgElem.appendChild(layer3);
|
||||||
|
|
||||||
|
return [layer1, layer2, layer3];
|
||||||
|
};
|
||||||
|
|
||||||
|
var createSomeElementsInGroup = function(group) {
|
||||||
|
group.appendChild(createSVGElement({
|
||||||
|
'element': 'path',
|
||||||
|
'attr': PATH_ATTR
|
||||||
|
}));
|
||||||
|
// group.appendChild(createSVGElement({
|
||||||
|
// 'element': 'path',
|
||||||
|
// 'attr': {'d': 'M0,1L2,3'}
|
||||||
|
// }));
|
||||||
|
group.appendChild(createSVGElement({
|
||||||
|
'element': 'rect',
|
||||||
|
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||||
|
}));
|
||||||
|
group.appendChild(createSVGElement({
|
||||||
|
'element': 'line',
|
||||||
|
'attr': {'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||||
|
}));
|
||||||
|
|
||||||
|
var g = createSVGElement({
|
||||||
|
'element': 'g',
|
||||||
|
'attr': {}
|
||||||
|
});
|
||||||
|
g.appendChild(createSVGElement({
|
||||||
|
'element': 'rect',
|
||||||
|
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||||
|
}));
|
||||||
|
group.appendChild(g);
|
||||||
|
return 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
var cleanupSvg = function(svgElem) {
|
var cleanupSvg = function(svgElem) {
|
||||||
while(svgElem.firstChild) {svgElem.removeChild(svgElem.firstChild);}
|
while(svgElem.firstChild) {svgElem.removeChild(svgElem.firstChild);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module('svgedit.draw.Drawing', {
|
||||||
|
setup: function() {
|
||||||
|
},
|
||||||
|
teardown: function() {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('Test draw module', function() {
|
test('Test draw module', function() {
|
||||||
expect(4);
|
expect(4);
|
||||||
|
|
||||||
|
@ -376,18 +440,55 @@
|
||||||
equals(typeof drawing.setCurrentLayer, typeof function(){});
|
equals(typeof drawing.setCurrentLayer, typeof function(){});
|
||||||
|
|
||||||
drawing.setCurrentLayer(LAYER2);
|
drawing.setCurrentLayer(LAYER2);
|
||||||
equals(drawing.getCurrentLayerName(LAYER2), LAYER2);
|
equals(drawing.getCurrentLayerName(), LAYER2);
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||||
|
|
||||||
drawing.setCurrentLayer(LAYER3);
|
drawing.setCurrentLayer(LAYER3);
|
||||||
equals(drawing.getCurrentLayerName(LAYER3), LAYER3);
|
equals(drawing.getCurrentLayerName(), LAYER3);
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||||
|
|
||||||
cleanupSvg(svg);
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Test setCurrentLayerName()', function() {
|
||||||
|
|
||||||
|
var mockHrService = {
|
||||||
|
changeElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
setupSvgWith3Layers(svg);
|
||||||
|
drawing.identifyLayers();
|
||||||
|
|
||||||
|
ok(drawing.setCurrentLayerName);
|
||||||
|
equals(typeof drawing.setCurrentLayerName, typeof function(){});
|
||||||
|
|
||||||
|
var oldName = drawing.getCurrentLayerName();
|
||||||
|
var newName = 'New Name'
|
||||||
|
ok(drawing.layer_map[oldName]);
|
||||||
|
equals(drawing.layer_map[newName], undefined); // newName shouldn't exist.
|
||||||
|
var result = drawing.setCurrentLayerName(newName, mockHrService);
|
||||||
|
equals(result, newName);
|
||||||
|
equals(drawing.getCurrentLayerName(), newName);
|
||||||
|
// Was the map updated?
|
||||||
|
equals(drawing.layer_map[oldName], undefined);
|
||||||
|
equals(drawing.layer_map[newName], drawing.current_layer);
|
||||||
|
// Was mockHrService called?
|
||||||
|
ok(mockHrService.changeElement.calledOnce);
|
||||||
|
equals(oldName, mockHrService.changeElement.getCall(0).args[1]['#text']);
|
||||||
|
equals(newName, mockHrService.changeElement.getCall(0).args[0].textContent);
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
|
});
|
||||||
|
|
||||||
test('Test createLayer()', function() {
|
test('Test createLayer()', function() {
|
||||||
expect(7);
|
expect(10);
|
||||||
|
|
||||||
|
var mockHrService = {
|
||||||
|
startBatchCommand: this.spy(),
|
||||||
|
endBatchCommand: this.spy(),
|
||||||
|
insertElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
var drawing = new svgedit.draw.Drawing(svg);
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
setupSvgWith3Layers(svg);
|
setupSvgWith3Layers(svg);
|
||||||
|
@ -397,13 +498,178 @@
|
||||||
equals(typeof drawing.createLayer, typeof function(){});
|
equals(typeof drawing.createLayer, typeof function(){});
|
||||||
|
|
||||||
var NEW_LAYER_NAME = 'Layer A';
|
var NEW_LAYER_NAME = 'Layer A';
|
||||||
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
var layer_g = drawing.createLayer(NEW_LAYER_NAME, mockHrService);
|
||||||
equals(drawing.getNumLayers(), 4);
|
equals(drawing.getNumLayers(), 4);
|
||||||
equals(layer_g, drawing.getCurrentLayer());
|
equals(layer_g, drawing.getCurrentLayer());
|
||||||
equals(layer_g.getAttribute('class'), LAYER_CLASS);
|
equals(layer_g.getAttribute('class'), LAYER_CLASS);
|
||||||
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
||||||
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
||||||
|
|
||||||
|
equals(layer_g, mockHrService.insertElement.getCall(0).args[0]);
|
||||||
|
ok(mockHrService.startBatchCommand.calledOnce);
|
||||||
|
ok(mockHrService.endBatchCommand.calledOnce);
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test mergeLayer()', function() {
|
||||||
|
var mockHrService = {
|
||||||
|
startBatchCommand: this.spy(),
|
||||||
|
endBatchCommand: this.spy(),
|
||||||
|
moveElement: this.spy(),
|
||||||
|
removeElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
var layers = setupSvgWith3Layers(svg);
|
||||||
|
var elementCount = createSomeElementsInGroup(layers[2]) + 1; // +1 for title element
|
||||||
|
equals(layers[1].childElementCount, 1);
|
||||||
|
equals(layers[2].childElementCount, elementCount);
|
||||||
|
drawing.identifyLayers();
|
||||||
|
equals(drawing.getCurrentLayer(), layers[2])
|
||||||
|
|
||||||
|
ok(drawing.mergeLayer);
|
||||||
|
equals(typeof drawing.mergeLayer, typeof function(){});
|
||||||
|
|
||||||
|
drawing.mergeLayer(mockHrService);
|
||||||
|
|
||||||
|
equals(drawing.getNumLayers(), 2);
|
||||||
|
equals(svg.childElementCount, 2);
|
||||||
|
equals(drawing.getCurrentLayer(), layers[1]);
|
||||||
|
equals(layers[1].childElementCount, elementCount);
|
||||||
|
|
||||||
|
|
||||||
|
// check history record
|
||||||
|
ok(mockHrService.startBatchCommand.calledOnce);
|
||||||
|
ok(mockHrService.endBatchCommand.calledOnce);
|
||||||
|
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge Layer');
|
||||||
|
equals(mockHrService.moveElement.callCount, elementCount - 1); // -1 because the title was not moved.
|
||||||
|
equals(mockHrService.removeElement.callCount, 2); // remove group and title.
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test mergeLayer() when no previous layer to merge', function() {
|
||||||
|
var mockHrService = {
|
||||||
|
startBatchCommand: this.spy(),
|
||||||
|
endBatchCommand: this.spy(),
|
||||||
|
moveElement: this.spy(),
|
||||||
|
removeElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
var layers = setupSvgWith3Layers(svg);
|
||||||
|
drawing.identifyLayers();
|
||||||
|
drawing.setCurrentLayer(LAYER1);
|
||||||
|
equals(drawing.getCurrentLayer(), layers[0]);
|
||||||
|
|
||||||
|
drawing.mergeLayer(mockHrService);
|
||||||
|
|
||||||
|
equals(drawing.getNumLayers(), 3);
|
||||||
|
equals(svg.childElementCount, 3);
|
||||||
|
equals(drawing.getCurrentLayer(), layers[0]);
|
||||||
|
equals(layers[0].childElementCount, 1);
|
||||||
|
equals(layers[1].childElementCount, 1);
|
||||||
|
equals(layers[2].childElementCount, 1);
|
||||||
|
|
||||||
|
|
||||||
|
// check history record
|
||||||
|
equals(mockHrService.startBatchCommand.callCount, 0);
|
||||||
|
equals(mockHrService.endBatchCommand.callCount, 0);
|
||||||
|
equals(mockHrService.moveElement.callCount, 0);
|
||||||
|
equals(mockHrService.removeElement.callCount, 0);
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test mergeAllLayers()', function() {
|
||||||
|
var mockHrService = {
|
||||||
|
startBatchCommand: this.spy(),
|
||||||
|
endBatchCommand: this.spy(),
|
||||||
|
moveElement: this.spy(),
|
||||||
|
removeElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
var layers = setupSvgWith3Layers(svg);
|
||||||
|
var elementCount = createSomeElementsInGroup(layers[0]) + 1; // +1 for title element
|
||||||
|
createSomeElementsInGroup(layers[1]);
|
||||||
|
createSomeElementsInGroup(layers[2]);
|
||||||
|
equals(layers[0].childElementCount, elementCount);
|
||||||
|
equals(layers[1].childElementCount, elementCount);
|
||||||
|
equals(layers[2].childElementCount, elementCount);
|
||||||
|
drawing.identifyLayers();
|
||||||
|
|
||||||
|
ok(drawing.mergeAllLayers);
|
||||||
|
equals(typeof drawing.mergeAllLayers, typeof function(){});
|
||||||
|
|
||||||
|
drawing.mergeAllLayers(mockHrService);
|
||||||
|
|
||||||
|
equals(drawing.getNumLayers(), 1);
|
||||||
|
equals(svg.childElementCount, 1);
|
||||||
|
equals(drawing.getCurrentLayer(), layers[0]);
|
||||||
|
equals(layers[0].childElementCount, elementCount * 3 - 2); // -2 because two titles were deleted.
|
||||||
|
|
||||||
|
// check history record
|
||||||
|
equals(mockHrService.startBatchCommand.callCount, 3); // mergeAllLayers + 2 * mergeLayer
|
||||||
|
equals(mockHrService.endBatchCommand.callCount, 3);
|
||||||
|
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge all Layers');
|
||||||
|
equals(mockHrService.startBatchCommand.getCall(1).args[0], 'Merge Layer');
|
||||||
|
equals(mockHrService.startBatchCommand.getCall(2).args[0], 'Merge Layer');
|
||||||
|
// moveElement count is times 3 instead of 2, because one layer's elements were moved twice.
|
||||||
|
// moveElement count is minus 3 because the three titles were not moved.
|
||||||
|
equals(mockHrService.moveElement.callCount, elementCount * 3 - 3);
|
||||||
|
equals(mockHrService.removeElement.callCount, 2 * 2); // remove group and title twice.
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test cloneLayer()', function() {
|
||||||
|
var mockHrService = {
|
||||||
|
startBatchCommand: this.spy(),
|
||||||
|
endBatchCommand: this.spy(),
|
||||||
|
insertElement: this.spy()
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
var layers = setupSvgWith3Layers(svg);
|
||||||
|
var layer3 = layers[2];
|
||||||
|
var elementCount = createSomeElementsInGroup(layer3) + 1; // +1 for title element
|
||||||
|
equals(layer3.childElementCount, elementCount);
|
||||||
|
drawing.identifyLayers();
|
||||||
|
|
||||||
|
ok(drawing.cloneLayer);
|
||||||
|
equals(typeof drawing.cloneLayer, typeof function(){});
|
||||||
|
|
||||||
|
var clone = drawing.cloneLayer('clone', mockHrService);
|
||||||
|
|
||||||
|
equals(drawing.getNumLayers(), 4);
|
||||||
|
equals(svg.childElementCount, 4);
|
||||||
|
equals(drawing.getCurrentLayer(), clone);
|
||||||
|
equals(clone.childElementCount, elementCount);
|
||||||
|
|
||||||
|
// check history record
|
||||||
|
ok(mockHrService.startBatchCommand.calledOnce); // mergeAllLayers + 2 * mergeLayer
|
||||||
|
ok(mockHrService.endBatchCommand.calledOnce);
|
||||||
|
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Duplicate Layer');
|
||||||
|
equals(mockHrService.insertElement.callCount, 1);
|
||||||
|
equals(mockHrService.insertElement.getCall(0).args[0], clone);
|
||||||
|
|
||||||
|
// check that path is cloned properly
|
||||||
|
equals(clone.childNodes.length, elementCount);
|
||||||
|
var path = clone.childNodes[1]
|
||||||
|
equals(path.id, 'svg_1');
|
||||||
|
equals(path.getAttribute('d'), PATH_ATTR.d);
|
||||||
|
equals(path.getAttribute('transform'), PATH_ATTR.transform);
|
||||||
|
equals(path.getAttribute('fill'), PATH_ATTR.fill);
|
||||||
|
equals(path.getAttribute('stroke'), PATH_ATTR.stroke);
|
||||||
|
equals(path.getAttribute('stroke-width'), PATH_ATTR['stroke-width']);
|
||||||
|
|
||||||
|
// check that g is cloned properly
|
||||||
|
var g = clone.childNodes[4]
|
||||||
|
equals(g.childNodes.length, 1);
|
||||||
|
equals(g.id, 'svg_4');
|
||||||
|
|
||||||
cleanupSvg(svg);
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* sinon-qunit 1.0.0, 2010/12/09
|
||||||
|
*
|
||||||
|
* @author Christian Johansen (christian@cjohansen.no)
|
||||||
|
*
|
||||||
|
* (The BSD License)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Christian Johansen nor the names of his contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
/*global sinon, QUnit, test*/
|
||||||
|
sinon.assert.fail = function (msg) {
|
||||||
|
QUnit.ok(false, msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
sinon.assert.pass = function (assertion) {
|
||||||
|
QUnit.ok(true, assertion);
|
||||||
|
};
|
||||||
|
|
||||||
|
sinon.config = {
|
||||||
|
injectIntoThis: true,
|
||||||
|
injectInto: null,
|
||||||
|
properties: ["spy", "stub", "mock", "clock", "sandbox"],
|
||||||
|
useFakeTimers: true,
|
||||||
|
useFakeServer: false
|
||||||
|
};
|
||||||
|
|
||||||
|
(function (global) {
|
||||||
|
var qTest = QUnit.test;
|
||||||
|
|
||||||
|
QUnit.test = global.test = function (testName, expected, callback, async) {
|
||||||
|
if (arguments.length === 2) {
|
||||||
|
callback = expected;
|
||||||
|
expected = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qTest(testName, expected, sinon.test(callback), async);
|
||||||
|
};
|
||||||
|
}(this));
|
Loading…
Reference in New Issue