2012-08-10 15:14:56 +00:00
|
|
|
(function() {
|
|
|
|
|
|
2012-08-11 16:59:53 +00:00
|
|
|
QUnit.module('fabric.Text');
|
|
|
|
|
|
2012-08-10 15:14:56 +00:00
|
|
|
function createTextObject() {
|
2012-08-14 14:04:32 +00:00
|
|
|
return new fabric.Text('x');
|
2012-08-10 15:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-18 12:27:25 +00:00
|
|
|
var CHAR_WIDTH = 20;
|
2014-07-18 11:11:18 +00:00
|
|
|
|
2012-08-10 15:14:56 +00:00
|
|
|
var REFERENCE_TEXT_OBJECT = {
|
2014-09-21 18:55:00 +00:00
|
|
|
'type': 'text',
|
|
|
|
|
'originX': 'left',
|
|
|
|
|
'originY': 'top',
|
|
|
|
|
'left': 0,
|
|
|
|
|
'top': 0,
|
|
|
|
|
'width': CHAR_WIDTH,
|
2014-11-30 18:04:25 +00:00
|
|
|
'height': 52.43,
|
2014-09-21 18:55:00 +00:00
|
|
|
'fill': 'rgb(0,0,0)',
|
|
|
|
|
'stroke': null,
|
|
|
|
|
'strokeWidth': 1,
|
|
|
|
|
'strokeDashArray': null,
|
|
|
|
|
'strokeLineCap': 'butt',
|
|
|
|
|
'strokeLineJoin': 'miter',
|
|
|
|
|
'strokeMiterLimit': 10,
|
|
|
|
|
'scaleX': 1,
|
|
|
|
|
'scaleY': 1,
|
|
|
|
|
'angle': 0,
|
|
|
|
|
'flipX': false,
|
|
|
|
|
'flipY': false,
|
|
|
|
|
'opacity': 1,
|
|
|
|
|
'shadow': null,
|
|
|
|
|
'visible': true,
|
|
|
|
|
'clipTo': null,
|
|
|
|
|
'backgroundColor': '',
|
|
|
|
|
'text': 'x',
|
|
|
|
|
'fontSize': 40,
|
|
|
|
|
'fontWeight': 'normal',
|
|
|
|
|
'fontFamily': 'Times New Roman',
|
|
|
|
|
'fontStyle': '',
|
2014-11-30 18:04:25 +00:00
|
|
|
'lineHeight': 1.16,
|
2014-09-21 18:55:00 +00:00
|
|
|
'textDecoration': '',
|
|
|
|
|
'textAlign': 'left',
|
|
|
|
|
'textBackgroundColor': '',
|
2015-07-19 23:28:38 +00:00
|
|
|
'fillRule': 'nonzero',
|
|
|
|
|
'globalCompositeOperation': 'source-over',
|
2015-09-02 19:28:57 +00:00
|
|
|
'skewX': 0,
|
|
|
|
|
'skewY': 0,
|
2015-07-19 23:28:38 +00:00
|
|
|
'transformMatrix': null
|
2012-08-10 15:14:56 +00:00
|
|
|
};
|
|
|
|
|
|
2015-12-10 08:36:24 +00:00
|
|
|
var TEXT_SVG = '\t<g transform="translate(10.5 26.72)">\n\t\t<text font-family="Times New Roman" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" >\n\t\t\t<tspan x="-10" y="8.98" fill="rgb(0,0,0)">x</tspan>\n\t\t</text>\n\t</g>\n';
|
|
|
|
|
var TEXT_SVG_JUSTIFIED = '\t<g transform="translate(50.5 26.72)">\n\t\t<text font-family="Times New Roman" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" >\n\t\t\t<tspan x="-50" y="8.98" fill="rgb(0,0,0)">x</tspan>\n\t\t\t<tspan x="30" y="8.98" fill="rgb(0,0,0)">y</tspan>\n\t\t</text>\n\t</g>\n';
|
2013-08-29 20:06:24 +00:00
|
|
|
|
2012-08-10 15:14:56 +00:00
|
|
|
test('constructor', function() {
|
|
|
|
|
ok(fabric.Text);
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
|
|
|
|
|
ok(text);
|
|
|
|
|
ok(text instanceof fabric.Text);
|
|
|
|
|
ok(text instanceof fabric.Object);
|
|
|
|
|
|
|
|
|
|
equal(text.get('type'), 'text');
|
2012-08-14 14:04:32 +00:00
|
|
|
equal(text.get('text'), 'x');
|
2012-08-10 15:14:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('toString', function() {
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.toString == 'function');
|
2013-05-20 16:41:16 +00:00
|
|
|
equal(text.toString(), '#<fabric.Text (1): { "text": "x", "fontFamily": "Times New Roman" }>');
|
2012-08-10 15:14:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('toObject', function() {
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.toObject == 'function');
|
|
|
|
|
deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('complexity', function(){
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.complexity == 'function');
|
2013-05-20 16:41:16 +00:00
|
|
|
equal(text.complexity(), 1);
|
2012-08-10 15:14:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('set', function() {
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.set == 'function');
|
|
|
|
|
equal(text.set('text', 'bar'), text, 'should be chainable');
|
2012-09-07 17:15:42 +00:00
|
|
|
|
|
|
|
|
text.set({ left: 1234, top: 2345, angle: 55 });
|
|
|
|
|
|
|
|
|
|
equal(text.get('left'), 1234);
|
|
|
|
|
equal(text.get('top'), 2345);
|
|
|
|
|
equal(text.get('angle'), 55);
|
2012-08-10 15:14:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('set with "hash"', function() {
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
|
|
|
|
|
text.set({ opacity: 0.123, fill: 'red', fontFamily: 'blah' });
|
|
|
|
|
|
Parse SVG stroke-opacity and fill-opacity
- SVG attribute opacity is now used for object's opacity
- fill-opacity and stroke-opacity are added to stroke and fill color value
- Add hsl/hsla support (e.g. hsl(270, 80%, 10%), hsla(320, 10%, 66%, 0.5))
- Add support for rgb/rgba values with whitespaces around values (e.g. rgba( 255 , 100 , 50 , 0.1 )) and percentage values (e.g. rgb(100%, 67%, 15%, 0.8))
- Delete stroke and strokeWidth from fabric.Text (defined in fabric.Object)
- New unit test for parse stroke-opacity and fill-opacity
- Update unit tests (new tests for hsl/hsla and rgb/rgba (whitespaces and percentage values))
- Change equal and deepEqual parameter order (e.g. equal(actualValue, expectedValue, message))
- Doc additions
2013-05-25 09:03:09 +00:00
|
|
|
equal(text.getOpacity(), 0.123);
|
|
|
|
|
equal(text.getFill(), 'red');
|
|
|
|
|
equal(text.get('fontFamily'), 'blah');
|
2012-08-10 15:14:56 +00:00
|
|
|
});
|
|
|
|
|
|
[BACK_INCOMPAT] `fabric.Text#textShadow` has been removed - new `fabric.Text.shadow` property (type of fabric.Shadow)
[BACK_INCOMPAT] `fabric.BaseBrush`shadow properties are combined into one property => `fabric.BaseBrush.shadow`(shadowColor, shadowBlur, shadowOffsetX, shadowOffsetY no longer exist)
Removed fabric.Text.getText method => is generated with `fabric.util.createAccessors`
`fabric.Shadow` can now initialized with string or object (e.g. '10px 10px 5px rgb(0,0,255)', 'rgb(0,0,255) 10px 10px 5px', {color: 'gb(0,0,255)', offsetX: 10, offsetY: 10, blur: 5})
`fabric.Shadow.getShadow`to get css3 declaration of shadow (String)
`fabric.Object.set('shadow', value)`is now the same as `fabric.Shadow.setShadow(value)`
Add unit tests
2013-09-03 17:11:21 +00:00
|
|
|
test('setShadow', function(){
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.setShadow == 'function');
|
|
|
|
|
equal(text.setShadow('10px 8px 2px red'), text, 'should be chainable');
|
|
|
|
|
|
|
|
|
|
ok(text.shadow instanceof fabric.Shadow, 'should inherit from fabric.Shadow');
|
|
|
|
|
equal(text.shadow.color, 'red');
|
|
|
|
|
equal(text.shadow.offsetX, 10);
|
|
|
|
|
equal(text.shadow.offsetY, 8);
|
|
|
|
|
equal(text.shadow.blur, 2);
|
|
|
|
|
});
|
|
|
|
|
|
2013-02-18 15:22:48 +00:00
|
|
|
test('setFontSize', function(){
|
2012-08-10 15:14:56 +00:00
|
|
|
var text = createTextObject();
|
2013-02-18 15:22:48 +00:00
|
|
|
ok(typeof text.setFontSize == 'function');
|
2013-09-14 15:10:49 +00:00
|
|
|
equal(text.setFontSize(12), text, 'should be chainable');
|
2012-08-10 15:14:56 +00:00
|
|
|
equal(text.get('fontSize'), 12);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('getText', function(){
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.getText == 'function');
|
2012-08-14 14:04:32 +00:00
|
|
|
equal(text.getText(), 'x');
|
2012-08-10 15:14:56 +00:00
|
|
|
equal(text.getText(), text.get('text'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('setText', function(){
|
|
|
|
|
var text = createTextObject();
|
|
|
|
|
ok(typeof text.setText == 'function');
|
|
|
|
|
equal(text.setText('bar'), text, 'should be chainable');
|
|
|
|
|
equal(text.getText(), 'bar');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('fabric.Text.fromObject', function(){
|
|
|
|
|
ok(typeof fabric.Text.fromObject == 'function');
|
|
|
|
|
var text = fabric.Text.fromObject(REFERENCE_TEXT_OBJECT);
|
|
|
|
|
deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT);
|
|
|
|
|
});
|
|
|
|
|
|
2012-08-11 16:59:53 +00:00
|
|
|
test('fabric.Text.fromElement', function() {
|
|
|
|
|
ok(typeof fabric.Text.fromElement == 'function');
|
|
|
|
|
|
|
|
|
|
var elText = fabric.document.createElement('text');
|
2012-08-14 14:04:32 +00:00
|
|
|
elText.textContent = 'x';
|
2012-08-11 16:59:53 +00:00
|
|
|
|
|
|
|
|
var text = fabric.Text.fromElement(elText);
|
|
|
|
|
|
|
|
|
|
ok(text instanceof fabric.Text);
|
|
|
|
|
|
|
|
|
|
// temp workaround for text objects not obtaining width under node
|
2014-07-18 11:11:18 +00:00
|
|
|
// text.width = CHAR_WIDTH;
|
2012-08-11 16:59:53 +00:00
|
|
|
|
2013-02-17 12:26:53 +00:00
|
|
|
var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), {
|
2015-09-02 19:28:57 +00:00
|
|
|
left: 4.5,
|
|
|
|
|
top: -4.11,
|
2014-07-18 12:43:54 +00:00
|
|
|
width: 8,
|
2014-11-30 18:04:25 +00:00
|
|
|
height: 20.97,
|
2014-05-12 09:23:48 +00:00
|
|
|
fontSize: 16,
|
2014-07-18 16:03:21 +00:00
|
|
|
originX: 'left'
|
2012-10-30 23:19:13 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
deepEqual(text.toObject(), expectedObject);
|
2012-08-11 16:59:53 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('fabric.Text.fromElement with custom attributes', function() {
|
|
|
|
|
|
|
|
|
|
var elTextWithAttrs = fabric.document.createElement('text');
|
2012-08-14 14:04:32 +00:00
|
|
|
elTextWithAttrs.textContent = 'x';
|
2012-08-11 16:59:53 +00:00
|
|
|
|
|
|
|
|
elTextWithAttrs.setAttribute('x', 10);
|
|
|
|
|
elTextWithAttrs.setAttribute('y', 20);
|
|
|
|
|
elTextWithAttrs.setAttribute('fill', 'rgb(255,255,255)');
|
Parse SVG stroke-opacity and fill-opacity
- SVG attribute opacity is now used for object's opacity
- fill-opacity and stroke-opacity are added to stroke and fill color value
- Add hsl/hsla support (e.g. hsl(270, 80%, 10%), hsla(320, 10%, 66%, 0.5))
- Add support for rgb/rgba values with whitespaces around values (e.g. rgba( 255 , 100 , 50 , 0.1 )) and percentage values (e.g. rgb(100%, 67%, 15%, 0.8))
- Delete stroke and strokeWidth from fabric.Text (defined in fabric.Object)
- New unit test for parse stroke-opacity and fill-opacity
- Update unit tests (new tests for hsl/hsla and rgb/rgba (whitespaces and percentage values))
- Change equal and deepEqual parameter order (e.g. equal(actualValue, expectedValue, message))
- Doc additions
2013-05-25 09:03:09 +00:00
|
|
|
elTextWithAttrs.setAttribute('opacity', 0.45);
|
2012-08-11 16:59:53 +00:00
|
|
|
elTextWithAttrs.setAttribute('stroke', 'blue');
|
|
|
|
|
elTextWithAttrs.setAttribute('stroke-width', 3);
|
2013-05-18 11:01:34 +00:00
|
|
|
elTextWithAttrs.setAttribute('stroke-dasharray', '5, 2');
|
|
|
|
|
elTextWithAttrs.setAttribute('stroke-linecap', 'round');
|
|
|
|
|
elTextWithAttrs.setAttribute('stroke-linejoin', 'bevil');
|
|
|
|
|
elTextWithAttrs.setAttribute('stroke-miterlimit', 5);
|
2012-08-11 16:59:53 +00:00
|
|
|
elTextWithAttrs.setAttribute('font-family', 'Monaco');
|
|
|
|
|
elTextWithAttrs.setAttribute('font-style', 'italic');
|
|
|
|
|
elTextWithAttrs.setAttribute('font-weight', 'bold');
|
|
|
|
|
elTextWithAttrs.setAttribute('font-size', '123');
|
|
|
|
|
elTextWithAttrs.setAttribute('text-decoration', 'underline');
|
2014-07-18 16:03:21 +00:00
|
|
|
elTextWithAttrs.setAttribute('text-anchor', 'middle');
|
2012-08-11 16:59:53 +00:00
|
|
|
|
|
|
|
|
var textWithAttrs = fabric.Text.fromElement(elTextWithAttrs);
|
|
|
|
|
// temp workaround for text objects not obtaining width under node
|
2014-07-18 11:11:18 +00:00
|
|
|
textWithAttrs.width = CHAR_WIDTH;
|
2012-08-11 16:59:53 +00:00
|
|
|
|
|
|
|
|
ok(textWithAttrs instanceof fabric.Text);
|
|
|
|
|
|
2013-02-17 12:26:53 +00:00
|
|
|
var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), {
|
|
|
|
|
/* left varies slightly due to node-canvas rendering */
|
2013-05-18 11:01:34 +00:00
|
|
|
left: fabric.util.toFixed(textWithAttrs.left + '', 2),
|
2015-09-02 19:28:57 +00:00
|
|
|
top: -9.22,
|
2014-07-18 11:11:18 +00:00
|
|
|
width: CHAR_WIDTH,
|
2014-11-30 18:04:25 +00:00
|
|
|
height: 161.23,
|
2013-05-18 11:01:34 +00:00
|
|
|
fill: 'rgb(255,255,255)',
|
|
|
|
|
opacity: 0.45,
|
|
|
|
|
stroke: 'blue',
|
|
|
|
|
strokeWidth: 3,
|
|
|
|
|
strokeDashArray: [5, 2],
|
|
|
|
|
strokeLineCap: 'round',
|
|
|
|
|
strokeLineJoin: 'bevil',
|
|
|
|
|
strokeMiterLimit: 5,
|
|
|
|
|
fontFamily: 'Monaco',
|
|
|
|
|
fontStyle: 'italic',
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
fontSize: 123,
|
2014-05-12 09:23:48 +00:00
|
|
|
textDecoration: 'underline',
|
|
|
|
|
originX: 'center'
|
2012-08-11 16:59:53 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
deepEqual(textWithAttrs.toObject(), expectedObject);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('empty fromElement', function() {
|
|
|
|
|
ok(fabric.Text.fromElement() === null);
|
|
|
|
|
});
|
|
|
|
|
|
2012-09-07 17:30:32 +00:00
|
|
|
test('dimensions after text change', function() {
|
|
|
|
|
var text = new fabric.Text('x');
|
2014-07-18 11:11:18 +00:00
|
|
|
equal(text.width, CHAR_WIDTH);
|
2012-09-07 17:30:32 +00:00
|
|
|
|
|
|
|
|
text.setText('xx');
|
2014-07-18 11:11:18 +00:00
|
|
|
equal(text.width, CHAR_WIDTH * 2);
|
2012-09-07 17:30:32 +00:00
|
|
|
});
|
|
|
|
|
|
2012-09-10 23:45:25 +00:00
|
|
|
test('setting fontFamily', function() {
|
|
|
|
|
var text = new fabric.Text('x');
|
|
|
|
|
text.path = 'foobar.js';
|
|
|
|
|
|
|
|
|
|
text.set('fontFamily', 'foobar');
|
Parse SVG stroke-opacity and fill-opacity
- SVG attribute opacity is now used for object's opacity
- fill-opacity and stroke-opacity are added to stroke and fill color value
- Add hsl/hsla support (e.g. hsl(270, 80%, 10%), hsla(320, 10%, 66%, 0.5))
- Add support for rgb/rgba values with whitespaces around values (e.g. rgba( 255 , 100 , 50 , 0.1 )) and percentage values (e.g. rgb(100%, 67%, 15%, 0.8))
- Delete stroke and strokeWidth from fabric.Text (defined in fabric.Object)
- New unit test for parse stroke-opacity and fill-opacity
- Update unit tests (new tests for hsl/hsla and rgb/rgba (whitespaces and percentage values))
- Change equal and deepEqual parameter order (e.g. equal(actualValue, expectedValue, message))
- Doc additions
2013-05-25 09:03:09 +00:00
|
|
|
equal(text.get('fontFamily'), 'foobar');
|
2013-08-29 20:06:24 +00:00
|
|
|
|
|
|
|
|
text.set('fontFamily', '"Arial Black", Arial');
|
|
|
|
|
equal(text.get('fontFamily'), '"Arial Black", Arial');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('toSVG', function() {
|
|
|
|
|
var text = new fabric.Text('x');
|
|
|
|
|
|
2015-07-14 20:45:23 +00:00
|
|
|
function removeTranslate(str) {
|
|
|
|
|
return str.replace(/translate\(.*?\)/, '');
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-29 20:06:24 +00:00
|
|
|
// temp workaround for text objects not obtaining width under node
|
2014-07-18 11:11:18 +00:00
|
|
|
text.width = CHAR_WIDTH;
|
2013-08-29 20:06:24 +00:00
|
|
|
|
2015-07-14 20:45:23 +00:00
|
|
|
equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG));
|
2013-08-29 20:06:24 +00:00
|
|
|
|
|
|
|
|
text.setFontFamily('"Arial Black", Arial');
|
|
|
|
|
// temp workaround for text objects not obtaining width under node
|
2014-07-18 11:11:18 +00:00
|
|
|
text.width = CHAR_WIDTH;
|
2013-08-29 20:06:24 +00:00
|
|
|
|
2015-07-14 20:45:23 +00:00
|
|
|
equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG.replace('font-family="Times New Roman"', 'font-family="\'Arial Black\', Arial"')));
|
2012-09-10 23:45:25 +00:00
|
|
|
});
|
2015-12-10 08:36:24 +00:00
|
|
|
test('toSVG justified', function() {
|
|
|
|
|
var text = new fabric.Text('x y');
|
|
|
|
|
|
|
|
|
|
function removeTranslate(str) {
|
|
|
|
|
return str.replace(/translate\(.*?\)/, '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// temp workaround for text objects not obtaining width under node
|
|
|
|
|
text.width = 100;
|
2015-12-26 13:33:00 +00:00
|
|
|
text.textAlign = 'justify';
|
2015-12-10 08:36:24 +00:00
|
|
|
equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG_JUSTIFIED));
|
|
|
|
|
});
|
2012-09-10 23:45:25 +00:00
|
|
|
|
2013-04-04 12:03:08 +00:00
|
|
|
})();
|