version 1.7.9 (#3804)

* fixes

* fix style typer egressions

* support svg crossorigin on images

* rebuilt
This commit is contained in:
Andrea Bogazzi 2017-03-25 19:05:57 +01:00 committed by GitHub
parent b69d7ed59b
commit 6e2deabcb3
13 changed files with 111 additions and 71 deletions

View file

@ -1,3 +1,10 @@
**Version 1.7.9**
- Fix: Avoid textarea wrapping from chome v57+ [#3804](https://github.com/kangax/fabric.js/pull/3804)
- Fix: double click needed to move cursor when enterEditing is called programatically [#3804](https://github.com/kangax/fabric.js/pull/3804)
- Fix: Style regression when inputing new style objects [#3804](https://github.com/kangax/fabric.js/pull/3804)
- Add: try to support crossOrigin for svg image tags [#3804](https://github.com/kangax/fabric.js/pull/3804)
**Version 1.7.8**
- Fix: Fix dirty flag propagation [#3782](https://github.com/kangax/fabric.js/pull/3782)

View file

@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.7.8" };
var fabric = fabric || { version: "1.7.9" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}

56
dist/fabric.js vendored
View file

@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.7.8" };
var fabric = fabric || { version: "1.7.9" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@ -3803,8 +3803,10 @@ if (typeof console !== 'undefined') {
* @param {Function} callback Callback to call when parsing is finished;
* It's being passed an array of elements (parsed from a document).
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [parsingOptions] options for parsing document
* @param {String} [parsingOptions.crossOrigin] crossOrigin settings
*/
fabric.parseSVGDocument = function(doc, callback, reviver) {
fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {
if (!doc) {
return;
}
@ -3814,7 +3816,7 @@ if (typeof console !== 'undefined') {
var svgUid = fabric.Object.__uid++,
options = applyViewboxTransform(doc),
descendants = fabric.util.toArray(doc.getElementsByTagName('*'));
options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
options.svgUid = svgUid;
if (descendants.length === 0 && fabric.isLikelyNode) {
@ -3846,7 +3848,7 @@ if (typeof console !== 'undefined') {
if (callback) {
callback(instances, options);
}
}, clone(options), reviver);
}, clone(options), reviver, parsingOptions);
};
var reFontDeclaration = new RegExp(
@ -3998,8 +4000,8 @@ if (typeof console !== 'undefined') {
* @param {Object} [options] Options object
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
*/
parseElements: function(elements, callback, options, reviver) {
new fabric.ElementsParser(elements, callback, options, reviver).parse();
parseElements: function(elements, callback, options, reviver, parsingOptions) {
new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();
},
/**
@ -4125,8 +4127,10 @@ if (typeof console !== 'undefined') {
* @param {String} url
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
*/
loadSVGFromURL: function(url, callback, reviver) {
loadSVGFromURL: function(url, callback, reviver, options) {
url = url.replace(/^\n\s*/, '').trim();
new fabric.util.request(url, {
@ -4147,9 +4151,9 @@ if (typeof console !== 'undefined') {
callback && callback(null);
}
fabric.parseSVGDocument(xml.documentElement, function (results, options) {
callback && callback(results, options);
}, reviver);
fabric.parseSVGDocument(xml.documentElement, function (results, _options) {
callback && callback(results, _options);
}, reviver, options);
}
},
@ -4159,8 +4163,10 @@ if (typeof console !== 'undefined') {
* @param {String} string
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
*/
loadSVGFromString: function(string, callback, reviver) {
loadSVGFromString: function(string, callback, reviver, options) {
string = string.trim();
var doc;
if (typeof DOMParser !== 'undefined') {
@ -4176,21 +4182,22 @@ if (typeof console !== 'undefined') {
doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ''));
}
fabric.parseSVGDocument(doc.documentElement, function (results, options) {
callback(results, options);
}, reviver);
fabric.parseSVGDocument(doc.documentElement, function (results, _options) {
callback(results, _options);
}, reviver, options);
}
});
})(typeof exports !== 'undefined' ? exports : this);
fabric.ElementsParser = function(elements, callback, options, reviver) {
fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
this.elements = elements;
this.callback = callback;
this.options = options;
this.reviver = reviver;
this.svgUid = (options && options.svgUid) || 0;
this.parsingOptions = parsingOptions;
};
fabric.ElementsParser.prototype.parse = function() {
@ -19222,7 +19229,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}
*/
fabric.Image.ATTRIBUTE_NAMES =
fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href'.split(' '));
fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));
/**
* Returns {@link fabric.Image} instance from an SVG element
@ -24209,7 +24216,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
this.isEditing = true;
this.selected = true;
this.initHiddenTextarea(e);
this.hiddenTextarea.focus();
this._updateTextarea();
@ -24594,7 +24601,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
}
}
var newStyle = style || currentLineStyles[charIndex - 1];
var newStyle = style || clone(currentLineStyles[charIndex - 1]);
newStyle && (this.styles[lineIndex][charIndex] = newStyle);
this._forceClearCache = true;
},
@ -24630,8 +24637,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
* @param {Number} offset Can be -1 or +1
*/
shiftLineStyles: function(lineIndex, offset) {
// shift all line styles by 1 upward
// shift all line styles by 1 upward or downward
var clonedStyles = clone(this.styles);
for (var line in clonedStyles) {
var numericLine = parseInt(line, 10);
if (numericLine <= lineIndex) {
delete clonedStyles[numericLine];
}
}
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
@ -24846,7 +24859,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
return;
}
var pointer = this.canvas.getPointer(options.e);
this.__mousedownX = pointer.x;
this.__mousedownY = pointer.y;
this.__isMousedown = true;
@ -25003,8 +25015,8 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
this.hiddenTextarea = fabric.document.createElement('textarea');
this.hiddenTextarea.setAttribute('autocapitalize', 'off');
var style = this._calcTextareaPosition();
this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + '; left: ' + style.left + ';'
+ ' opacity: 0; width: 0px; height: 0px; z-index: -999;';
this.hiddenTextarea.style.cssText = 'white-space: nowrap; position: absolute; top: ' + style.top +
'; left: ' + style.left + '; opacity: 0; width: 1px; height: 1px; z-index: -999;';
fabric.document.body.appendChild(this.hiddenTextarea);
fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));

18
dist/fabric.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/fabric.min.js.gz vendored

Binary file not shown.

View file

@ -1,5 +1,5 @@
var fabric = fabric || {
version: "1.7.8"
version: "1.7.9"
};
if (typeof exports !== "undefined") {
@ -2089,12 +2089,13 @@ if (typeof console !== "undefined") {
}
return false;
}
fabric.parseSVGDocument = function(doc, callback, reviver) {
fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {
if (!doc) {
return;
}
parseUseDirectives(doc);
var svgUid = fabric.Object.__uid++, options = applyViewboxTransform(doc), descendants = fabric.util.toArray(doc.getElementsByTagName("*"));
options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
options.svgUid = svgUid;
if (descendants.length === 0 && fabric.isLikelyNode) {
descendants = doc.selectNodes('//*[name(.)!="svg"]');
@ -2118,7 +2119,7 @@ if (typeof console !== "undefined") {
if (callback) {
callback(instances, options);
}
}, clone(options), reviver);
}, clone(options), reviver, parsingOptions);
};
var reFontDeclaration = new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*" + "(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(" + fabric.reNum + "(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|" + fabric.reNum + "))?\\s+(.*)");
extend(fabric, {
@ -2197,8 +2198,8 @@ if (typeof console !== "undefined") {
var mergedAttrs = extend(parentAttributes, normalizedStyle);
return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
},
parseElements: function(elements, callback, options, reviver) {
new fabric.ElementsParser(elements, callback, options, reviver).parse();
parseElements: function(elements, callback, options, reviver, parsingOptions) {
new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();
},
parseStyleAttribute: function(element) {
var oStyle = {}, style = element.getAttribute("style");
@ -2263,7 +2264,7 @@ if (typeof console !== "undefined") {
}
return allRules;
},
loadSVGFromURL: function(url, callback, reviver) {
loadSVGFromURL: function(url, callback, reviver, options) {
url = url.replace(/^\n\s*/, "").trim();
new fabric.util.request(url, {
method: "get",
@ -2279,12 +2280,12 @@ if (typeof console !== "undefined") {
if (!xml || !xml.documentElement) {
callback && callback(null);
}
fabric.parseSVGDocument(xml.documentElement, function(results, options) {
callback && callback(results, options);
}, reviver);
fabric.parseSVGDocument(xml.documentElement, function(results, _options) {
callback && callback(results, _options);
}, reviver, options);
}
},
loadSVGFromString: function(string, callback, reviver) {
loadSVGFromString: function(string, callback, reviver, options) {
string = string.trim();
var doc;
if (typeof DOMParser !== "undefined") {
@ -2297,19 +2298,20 @@ if (typeof console !== "undefined") {
doc.async = "false";
doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ""));
}
fabric.parseSVGDocument(doc.documentElement, function(results, options) {
callback(results, options);
}, reviver);
fabric.parseSVGDocument(doc.documentElement, function(results, _options) {
callback(results, _options);
}, reviver, options);
}
});
})(typeof exports !== "undefined" ? exports : this);
fabric.ElementsParser = function(elements, callback, options, reviver) {
fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
this.elements = elements;
this.callback = callback;
this.options = options;
this.reviver = reviver;
this.svgUid = options && options.svgUid || 0;
this.parsingOptions = parsingOptions;
};
fabric.ElementsParser.prototype.parse = function() {
@ -9285,7 +9287,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
callback && callback(new fabric.Image(img, imgOptions));
}, null, imgOptions && imgOptions.crossOrigin);
};
fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" "));
fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" "));
fabric.Image.fromElement = function(element, callback, options) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), preserveAR;
if (parsedAttributes.preserveAspectRatio) {
@ -11421,6 +11423,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
this.exitEditingOnOthers(this.canvas);
}
this.isEditing = true;
this.selected = true;
this.initHiddenTextarea(e);
this.hiddenTextarea.focus();
this._updateTextarea();
@ -11685,7 +11688,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
}
}
var newStyle = style || currentLineStyles[charIndex - 1];
var newStyle = style || clone(currentLineStyles[charIndex - 1]);
newStyle && (this.styles[lineIndex][charIndex] = newStyle);
this._forceClearCache = true;
},
@ -11702,6 +11705,12 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
},
shiftLineStyles: function(lineIndex, offset) {
var clonedStyles = clone(this.styles);
for (var line in clonedStyles) {
var numericLine = parseInt(line, 10);
if (numericLine <= lineIndex) {
delete clonedStyles[numericLine];
}
}
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
@ -11930,7 +11939,7 @@ fabric.util.object.extend(fabric.IText.prototype, {
this.hiddenTextarea = fabric.document.createElement("textarea");
this.hiddenTextarea.setAttribute("autocapitalize", "off");
var style = this._calcTextareaPosition();
this.hiddenTextarea.style.cssText = "position: absolute; top: " + style.top + "; left: " + style.left + ";" + " opacity: 0; width: 0px; height: 0px; z-index: -999;";
this.hiddenTextarea.style.cssText = "white-space: nowrap; position: absolute; top: " + style.top + "; left: " + style.left + "; opacity: 0; width: 1px; height: 1px; z-index: -999;";
fabric.document.body.appendChild(this.hiddenTextarea);
fabric.util.addListener(this.hiddenTextarea, "keydown", this.onKeyDown.bind(this));
fabric.util.addListener(this.hiddenTextarea, "keyup", this.onKeyUp.bind(this));

View file

@ -2,7 +2,7 @@
"name": "fabric",
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
"homepage": "http://fabricjs.com/",
"version": "1.7.8",
"version": "1.7.9",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"contributors": [
{

View file

@ -1,9 +1,10 @@
fabric.ElementsParser = function(elements, callback, options, reviver) {
fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
this.elements = elements;
this.callback = callback;
this.options = options;
this.reviver = reviver;
this.svgUid = (options && options.svgUid) || 0;
this.parsingOptions = parsingOptions;
};
fabric.ElementsParser.prototype.parse = function() {

View file

@ -345,7 +345,7 @@
}
this.isEditing = true;
this.selected = true;
this.initHiddenTextarea(e);
this.hiddenTextarea.focus();
this._updateTextarea();
@ -730,7 +730,7 @@
}
}
}
var newStyle = style || currentLineStyles[charIndex - 1];
var newStyle = style || clone(currentLineStyles[charIndex - 1]);
newStyle && (this.styles[lineIndex][charIndex] = newStyle);
this._forceClearCache = true;
},
@ -766,8 +766,14 @@
* @param {Number} offset Can be -1 or +1
*/
shiftLineStyles: function(lineIndex, offset) {
// shift all line styles by 1 upward
// shift all line styles by 1 upward or downward
var clonedStyles = clone(this.styles);
for (var line in clonedStyles) {
var numericLine = parseInt(line, 10);
if (numericLine <= lineIndex) {
delete clonedStyles[numericLine];
}
}
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {

View file

@ -87,7 +87,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
return;
}
var pointer = this.canvas.getPointer(options.e);
this.__mousedownX = pointer.x;
this.__mousedownY = pointer.y;
this.__isMousedown = true;

View file

@ -7,8 +7,8 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
this.hiddenTextarea = fabric.document.createElement('textarea');
this.hiddenTextarea.setAttribute('autocapitalize', 'off');
var style = this._calcTextareaPosition();
this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + '; left: ' + style.left + ';'
+ ' opacity: 0; width: 0px; height: 0px; z-index: -999;';
this.hiddenTextarea.style.cssText = 'white-space: nowrap; position: absolute; top: ' + style.top +
'; left: ' + style.left + '; opacity: 0; width: 1px; height: 1px; z-index: -999;';
fabric.document.body.appendChild(this.hiddenTextarea);
fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));

View file

@ -602,8 +602,10 @@
* @param {Function} callback Callback to call when parsing is finished;
* It's being passed an array of elements (parsed from a document).
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [parsingOptions] options for parsing document
* @param {String} [parsingOptions.crossOrigin] crossOrigin settings
*/
fabric.parseSVGDocument = function(doc, callback, reviver) {
fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {
if (!doc) {
return;
}
@ -613,7 +615,7 @@
var svgUid = fabric.Object.__uid++,
options = applyViewboxTransform(doc),
descendants = fabric.util.toArray(doc.getElementsByTagName('*'));
options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
options.svgUid = svgUid;
if (descendants.length === 0 && fabric.isLikelyNode) {
@ -645,7 +647,7 @@
if (callback) {
callback(instances, options);
}
}, clone(options), reviver);
}, clone(options), reviver, parsingOptions);
};
var reFontDeclaration = new RegExp(
@ -797,8 +799,8 @@
* @param {Object} [options] Options object
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
*/
parseElements: function(elements, callback, options, reviver) {
new fabric.ElementsParser(elements, callback, options, reviver).parse();
parseElements: function(elements, callback, options, reviver, parsingOptions) {
new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();
},
/**
@ -924,8 +926,10 @@
* @param {String} url
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
*/
loadSVGFromURL: function(url, callback, reviver) {
loadSVGFromURL: function(url, callback, reviver, options) {
url = url.replace(/^\n\s*/, '').trim();
new fabric.util.request(url, {
@ -946,9 +950,9 @@
callback && callback(null);
}
fabric.parseSVGDocument(xml.documentElement, function (results, options) {
callback && callback(results, options);
}, reviver);
fabric.parseSVGDocument(xml.documentElement, function (results, _options) {
callback && callback(results, _options);
}, reviver, options);
}
},
@ -958,8 +962,10 @@
* @param {String} string
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
*/
loadSVGFromString: function(string, callback, reviver) {
loadSVGFromString: function(string, callback, reviver, options) {
string = string.trim();
var doc;
if (typeof DOMParser !== 'undefined') {
@ -975,9 +981,9 @@
doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ''));
}
fabric.parseSVGDocument(doc.documentElement, function (results, options) {
callback(results, options);
}, reviver);
fabric.parseSVGDocument(doc.documentElement, function (results, _options) {
callback(results, _options);
}, reviver, options);
}
});

View file

@ -655,7 +655,7 @@
* @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}
*/
fabric.Image.ATTRIBUTE_NAMES =
fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href'.split(' '));
fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));
/**
* Returns {@link fabric.Image} instance from an SVG element