(function() {
var emptyImageCanvasData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAH7ElEQVR4nO3VMQ0AMAzAsPInvYHoMS2yEeTLHADge/M6AADYM3QACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIuMjH4b7osLFBAAAAAElFTkSuQmCC";
var CANVAS_SVG = '\n'+
'';
var CANVAS_SVG_VIEWBOX = '\n'+
'';
var PATH_JSON = '{"objects": [{"type": "path", "originX": "center", "originY": "center", "left": 268, "top": 266, "width": 51, "height": 49,'+
' "fill": "rgb(0,0,0)", "overlayFill": null, "stroke": null, "strokeWidth": 1, "scaleX": 1, "scaleY": 1, '+
'"angle": 0, "flipX": false, "flipY": false, "opacity": 1, "path": [["M", 18.511, 13.99],'+
' ["c", 0, 0, -2.269, -4.487, -12.643, 4.411], ["c", 0, 0, 4.824, -14.161, 19.222, -9.059],'+
' ["l", 0.379, -2.1], ["c", -0.759, -0.405, -1.375, -1.139, -1.645, -2.117], ["c", -0.531, '+
'-1.864, 0.371, -3.854, 1.999, -4.453], ["c", 0.312, -0.118, 0.633, -0.169, 0.953, -0.169], '+
'["c", 1.299, 0, 2.514, 0.953, 2.936, 2.455], ["c", 0.522, 1.864, -0.372, 3.854, -1.999, '+
'4.453], ["c", -0.229, 0.084, -0.464, 0.127, -0.692, 0.152], ["l", -0.379, 2.37], ["c", '+
'1.146, 0.625, 2.024, 1.569, 2.674, 2.758], ["c", 3.213, 2.514, 8.561, 4.184, 11.774, -8.232],'+
' ["c", 0, 0, 0.86, 16.059, -12.424, 14.533], ["c", 0.008, 2.859, 0.615, 5.364, -0.076, 8.224],'+
' ["c", 8.679, 3.146, 15.376, 14.389, 17.897, 18.168], ["l", 2.497, -2.151], ["l", 1.206, 1.839],'+
' ["l", -3.889, 3.458], ["C", 46.286, 48.503, 31.036, 32.225, 22.72, 35.81], ["c", -1.307, 2.851,'+
' -3.56, 6.891, -7.481, 8.848], ["c", -4.689, 2.336, -9.084, -0.802, -11.277, -2.868], ["l",'+
' -1.948, 3.104], ["l", -1.628, -1.333], ["l", 3.138, -4.689], ["c", 0.025, 0, 9, 1.932, 9, 1.932], '+
'["c", 0.877, -9.979, 2.893, -12.905, 4.942, -15.621], ["C", 17.878, 21.775, 18.713, 17.397, 18.511, '+
'13.99], ["z", null]]}], "background": "#ff5555"}';
var PATH_DATALESS_JSON = '{"objects":[{"type":"path","originX":"center","originY":"center","left":200,"top":200,"width":200,"height":200,"fill":"rgb(0,0,0)",'+
'"overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":true,"transparentCorners":true,'+
'"perPixelTargetFind":false,"shadow":null,"visible":true,"clipTo":null,"path":"http://example.com/","pathOffset":{"x":100,"y":100}}],"background":""}';
var RECT_JSON = '{"objects":[{"type":"rect","originX":"center","originY":"center","left":0,"top":0,"width":10,"height":10,"fill":"rgb(0,0,0)","overlayFill":null,'+
'"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":true,'+
'"transparentCorners":true,"perPixelTargetFind":false,"shadow":null,"visible":true,"clipTo":null,"rx":0,"ry":0,"x":0,"y":0}],"background":"#ff5555"}';
var RECT_JSON_WITH_PADDING = '{"objects":[{"type":"rect","originX":"center","originY":"center","left":0,"top":0,"width":10,"height":20,"fill":"rgb(0,0,0)","overlayFill":null,'+
'"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":true,'+
'"transparentCorners":true,"perPixelTargetFind":false,"shadow":null,"visible":true,"clipTo":null,"padding":123,"foo":"bar","rx":0,"ry":0,"x":0,"y":0}],"background":""}';
// force creation of static canvas
// TODO: fix this
var Canvas = fabric.Canvas;
fabric.Canvas = null;
var el = fabric.document.createElement('canvas');
el.width = 600; el.height = 600;
var canvas = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.StaticCanvas(el);
fabric.Canvas = Canvas;
var lowerCanvasEl = canvas.lowerCanvasEl;
function makeRect(options) {
var defaultOptions = { width: 10, height: 10 };
return new fabric.Rect(fabric.util.object.extend(defaultOptions, options || { }));
}
QUnit.module('fabric.StaticCanvas', {
teardown: function() {
canvas.clear();
canvas.backgroundColor = fabric.StaticCanvas.prototype.backgroundColor;
canvas.calcOffset();
}
});
test('initialProperties', function() {
ok('backgroundColor' in canvas);
equal(canvas.includeDefaultValues, true);
});
test('getObjects', function() {
ok(typeof canvas.getObjects == 'function', 'should respond to `getObjects` method');
deepEqual([], canvas.getObjects(), 'should return empty array for `getObjects` when empty');
equal(canvas.getObjects().length, 0, 'should have a 0 length when empty');
});
test('getElement', function() {
ok(typeof canvas.getElement == 'function', 'should respond to `getElement` method');
equal(canvas.getElement(), lowerCanvasEl, 'should return a proper element');
});
test('item', function() {
var rect = makeRect();
ok(typeof canvas.item == 'function', 'should respond to item');
canvas.add(rect);
equal(canvas.item(0), rect, 'should return proper item');
});
test('calcOffset', function() {
ok(typeof canvas.calcOffset == 'function', 'should respond to `calcOffset`');
equal(canvas, canvas.calcOffset());
});
test('add', function() {
var rect = makeRect();
ok(typeof canvas.add == 'function');
ok(canvas === canvas.add(rect), 'should be chainable');
equal(canvas.item(0), rect);
canvas.add(makeRect(), makeRect(), makeRect());
equal(canvas.getObjects().length, 4, 'should support multiple arguments');
});
test('add renderOnAddRemove disabled', function() {
var rect = makeRect(),
originalRenderOnAddition,
renderAllCount = 0;
function countRenderAll() {
renderAllCount++;
}
originalRenderOnAddition = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
canvas.on('after:render', countRenderAll);
ok(canvas === canvas.add(rect), 'should be chainable');
equal(renderAllCount, 0);
equal(canvas.item(0), rect);
canvas.add(makeRect(), makeRect(), makeRect());
equal(canvas.getObjects().length, 4, 'should support multiple arguments');
equal(renderAllCount, 0);
canvas.renderAll();
equal(renderAllCount, 1);
canvas.off('after:render', countRenderAll);
canvas.renderOnAddRemove = originalRenderOnAddition;
});
test('insertAt', function() {
var rect1 = makeRect(),
rect2 = makeRect();
canvas.add(rect1, rect2);
ok(typeof canvas.insertAt == 'function', 'should respond to `insertAt` method');
var rect = makeRect();
canvas.insertAt(rect, 1);
equal(canvas.item(1), rect);
canvas.insertAt(rect, 2);
equal(canvas.item(2), rect);
equal(canvas, canvas.insertAt(rect, 2), 'should be chainable');
});
test('insertAt renderOnAddRemove disabled', function() {
var rect1 = makeRect(),
rect2 = makeRect(),
originalRenderOnAddition,
renderAllCount = 0;
function countRenderAll() {
renderAllCount++;
}
originalRenderOnAddition = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
canvas.on('after:render', countRenderAll);
canvas.add(rect1, rect2);
equal(renderAllCount, 0);
var rect = makeRect();
canvas.insertAt(rect, 1);
equal(renderAllCount, 0);
equal(canvas.item(1), rect);
canvas.insertAt(rect, 2);
equal(renderAllCount, 0);
canvas.renderAll();
equal(renderAllCount, 1);
canvas.off('after:render', countRenderAll);
canvas.renderOnAddRemove = originalRenderOnAddition;
});
test('clearContext', function() {
ok(typeof canvas.clearContext == 'function');
equal(canvas, canvas.clearContext(canvas.contextContainer), 'chainable');
});
test('clear', function() {
ok(typeof canvas.clear == 'function');
equal(canvas, canvas.clear());
equal(canvas.getObjects().length, 0);
});
test('renderAll', function() {
ok(typeof canvas.renderAll == 'function');
equal(canvas, canvas.renderAll());
});
test('renderTop', function() {
ok(typeof canvas.renderTop == 'function');
equal(canvas, canvas.renderTop());
});
test('toDataURL', function() {
ok(typeof canvas.toDataURL == 'function');
if (!fabric.Canvas.supports('toDataURL')) {
alert("toDataURL is not supported by this environment. Some of the tests can not be run.");
}
else {
var dataURL = canvas.toDataURL();
// don't compare actual data url, as it is often browser-dependent
// this.assertIdentical(emptyImageCanvasData, canvas.toDataURL('png'));
equal(typeof dataURL, 'string');
equal(dataURL.substring(0, 21), 'data:image/png;base64');
}
});
test('centerObjectH', function() {
ok(typeof canvas.centerObjectH == 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
equal(canvas.centerObjectH(rect), canvas, 'should be chainable');
equal(rect.get('left'), lowerCanvasEl.width / 2, 'object\'s "left" property should correspond to canvas element\'s center');
});
test('centerObjectV', function() {
ok(typeof canvas.centerObjectV == 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
equal(canvas.centerObjectV(rect), canvas, 'should be chainable');
equal(rect.get('top'), lowerCanvasEl.height / 2, 'object\'s "top" property should correspond to canvas element\'s center');
});
test('centerObject', function() {
ok(typeof canvas.centerObject == 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
equal(canvas.centerObject(rect), canvas, 'should be chainable');
equal(rect.get('top'), lowerCanvasEl.height / 2, 'object\'s "top" property should correspond to canvas element\'s center');
equal(rect.get('left'), lowerCanvasEl.height / 2, 'object\'s "left" property should correspond to canvas element\'s center');
});
test('straightenObject', function() {
ok(typeof canvas.straightenObject == 'function');
var rect = makeRect({ angle: 10 })
canvas.add(rect);
equal(canvas.straightenObject(rect), canvas, 'should be chainable');
equal(rect.getAngle(), 0, 'angle should be coerced to 0 (from 10)');
rect.setAngle('60');
canvas.straightenObject(rect);
equal(rect.getAngle(), 90, 'angle should be coerced to 90 (from 60)');
rect.setAngle('100');
canvas.straightenObject(rect);
equal(rect.getAngle(), 90, 'angle should be coerced to 90 (from 100)');
});
test('toSVG', function() {
ok(typeof canvas.toSVG == 'function');
canvas.clear();
var svg = canvas.toSVG();
equal(svg, CANVAS_SVG);
});
test('toSVG with different encoding (ISO-8859-1)', function() {
ok(typeof canvas.toSVG == 'function');
canvas.clear();
var svg = canvas.toSVG({encoding: 'ISO-8859-1'});
var svgDefaultEncoding = canvas.toSVG();
ok(svg != svgDefaultEncoding);
equal(svg, CANVAS_SVG.replace('encoding="UTF-8"', 'encoding="ISO-8859-1"'));
});
test('toSVG without preamble', function() {
ok(typeof canvas.toSVG == 'function');
var withPreamble = canvas.toSVG();
var withoutPreamble = canvas.toSVG({suppressPreamble: true});
ok(withPreamble != withoutPreamble);
equal(withoutPreamble.slice(0, 4), '