forgot to set proper style guide when auto-formatting

This commit is contained in:
inssein 2015-05-27 13:59:56 -07:00
parent 8c7ce62b81
commit 1067ac028a
4 changed files with 386 additions and 386 deletions

View file

@ -1,41 +1,41 @@
(function () {
/**
* Override _setObjectScale and add Textbox specific resizing behavior. Resizing
* a Textbox doesn't scale text, it only changes width and makes text wrap automatically.
*/
var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;
fabric.Canvas.prototype._setObjectScale = function (localMouse, transform,
lockScalingX, lockScalingY, by, lockScalingFlip) {
/**
* Override _setObjectScale and add Textbox specific resizing behavior. Resizing
* a Textbox doesn't scale text, it only changes width and makes text wrap automatically.
*/
var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;
fabric.Canvas.prototype._setObjectScale = function (localMouse, transform,
lockScalingX, lockScalingY, by, lockScalingFlip) {
var t = transform.target;
if (t instanceof fabric.Textbox) {
var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));
if (w >= t.minWidth) {
t.set('width', w);
}
}
else {
setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,
lockScalingX, lockScalingY, by, lockScalingFlip);
}
};
var t = transform.target;
if (t instanceof fabric.Textbox) {
var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth));
if (w >= t.minWidth) {
t.set('width', w);
}
}
else {
setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,
lockScalingX, lockScalingY, by, lockScalingFlip);
}
};
/**
* Sets controls of this group to the Textbox's special configuration if
* one is present in the group. Deletes _controlsVisibility otherwise, so that
* it gets initialized to default value at runtime.
*/
fabric.Group.prototype._refreshControlsVisibility = function () {
if (typeof fabric.Textbox === 'undefined') {
return;
}
for (var i = this._objects.length; i--;) {
if (this._objects[i] instanceof fabric.Textbox) {
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
return;
}
}
};
/**
* Sets controls of this group to the Textbox's special configuration if
* one is present in the group. Deletes _controlsVisibility otherwise, so that
* it gets initialized to default value at runtime.
*/
fabric.Group.prototype._refreshControlsVisibility = function () {
if (typeof fabric.Textbox === 'undefined') {
return;
}
for (var i = this._objects.length; i--;) {
if (this._objects[i] instanceof fabric.Textbox) {
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
return;
}
}
};
})();
})();

View file

@ -1,22 +1,22 @@
(function () {
var getNewSelectionStartFromOffsetOverriden = fabric.IText.prototype._getNewSelectionStartFromOffset;
/**
* Overrides the IText implementation and always sends lineIndex as 0 for Textboxes.
* @param {Number} mouseOffset
* @param {Number} prevWidth
* @param {Number} width
* @param {Number} index
* @param {Number} lineIndex
* @param {Number} jlen
* @returns {Number}
*/
fabric.IText.prototype._getNewSelectionStartFromOffset = function (mouseOffset,
prevWidth, width, index, lineIndex, jlen) {
if (this instanceof fabric.Textbox) {
lineIndex = 0;
}
return getNewSelectionStartFromOffsetOverriden
.call(this, mouseOffset,
prevWidth, width, index, lineIndex, jlen);
};
})();
var getNewSelectionStartFromOffsetOverriden = fabric.IText.prototype._getNewSelectionStartFromOffset;
/**
* Overrides the IText implementation and always sends lineIndex as 0 for Textboxes.
* @param {Number} mouseOffset
* @param {Number} prevWidth
* @param {Number} width
* @param {Number} index
* @param {Number} lineIndex
* @param {Number} jlen
* @returns {Number}
*/
fabric.IText.prototype._getNewSelectionStartFromOffset = function (mouseOffset,
prevWidth, width, index, lineIndex, jlen) {
if (this instanceof fabric.Textbox) {
lineIndex = 0;
}
return getNewSelectionStartFromOffsetOverriden
.call(this, mouseOffset,
prevWidth, width, index, lineIndex, jlen);
};
})();

View file

@ -1,22 +1,22 @@
fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.Textbox.prototype */ {
/**
* Overrides superclass function and adjusts cursor offset value because
* lines do not necessarily end with a newline in Textbox.
* @param {Event} e
* @param {Boolean} isRight
* @returns {Number}
*/
getDownCursorOffset: function (e, isRight) {
return fabric.IText.prototype.getDownCursorOffset.apply(this, [e, isRight]) - 1;
},
/**
* Overrides superclass function and adjusts cursor offset value because
* lines do not necessarily end with a newline in Textbox.
* @param {Event} e
* @param {Boolean} isRight
* @returns {Number}
*/
getUpCursorOffset: function (e, isRight) {
return fabric.IText.prototype.getUpCursorOffset.apply(this, [e, isRight]) - 1;
}
});
/**
* Overrides superclass function and adjusts cursor offset value because
* lines do not necessarily end with a newline in Textbox.
* @param {Event} e
* @param {Boolean} isRight
* @returns {Number}
*/
getDownCursorOffset: function (e, isRight) {
return fabric.IText.prototype.getDownCursorOffset.apply(this, [e, isRight]) - 1;
},
/**
* Overrides superclass function and adjusts cursor offset value because
* lines do not necessarily end with a newline in Textbox.
* @param {Event} e
* @param {Boolean} isRight
* @returns {Number}
*/
getUpCursorOffset: function (e, isRight) {
return fabric.IText.prototype.getUpCursorOffset.apply(this, [e, isRight]) - 1;
}
});

View file

@ -1,317 +1,317 @@
(function () {
var clone = fabric.util.object.clone;
var clone = fabric.util.object.clone;
/**
* Textbox class, based on IText, allows the user to resize the text rectangle
* and wraps lines automatically. Textboxes have their Y scaling locked, the
* user can only change width. Height is adjusted automatically based on the
* wrapping of lines.
* @class fabric.Textbox
* @extends fabric.IText
* @mixes fabric.Observable
* @return {fabric.Textbox} thisArg
* @see {@link fabric.Textbox#initialize} for constructor definition
*/
fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {
/**
* Textbox class, based on IText, allows the user to resize the text rectangle
* and wraps lines automatically. Textboxes have their Y scaling locked, the
* user can only change width. Height is adjusted automatically based on the
* wrapping of lines.
* @class fabric.Textbox
* @extends fabric.IText
* @mixes fabric.Observable
* @return {fabric.Textbox} thisArg
* @see {@link fabric.Textbox#initialize} for constructor definition
* Type of an object
* @type String
* @default
*/
fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {
/**
* Type of an object
* @type String
* @default
*/
type: 'textbox',
/**
* Minimum width of textbox, in pixels.
* @type Number
* @default
*/
minWidth: 20,
/**
* Cached array of text wrapping.
* @type Array
*/
__cachedLines: null,
/**
* Constructor. Some scaling related property values are forced. Visibility
* of controls is also fixed; only the rotation and width controls are
* made available.
* @param {String} text Text string
* @param {Object} [options] Options object
* @return {fabric.Textbox} thisArg
*/
initialize: function (text, options) {
this.ctx = fabric.util.createCanvasElement().getContext('2d');
this.callSuper('initialize', text, options);
this.set({
lockUniScaling: false,
lockScalingY: true,
lockScalingFlip: true,
hasBorders: true
});
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
// add width to this list of props that effect line wrapping.
this._dimensionAffectingProps.width = true;
},
/**
* Unlike superclass's version of this function, Textbox does not update
* its width.
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @private
* @override
*/
_initDimensions: function (ctx) {
if (this.__skipDimension) {
return;
}
if (!ctx) {
ctx = fabric.util.createCanvasElement().getContext('2d');
this._setTextStyles(ctx);
}
this._textLines = this._splitTextIntoLines();
this._clearCache();
this.height = this._getTextHeight(ctx);
},
/**
* Wraps text using the 'width' property of Textbox. First this function
* splits text on newlines, so we preserve newlines entered by the user.
* Then it wraps each line using the width of the Textbox by calling
* _wrapLine().
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @param {String} text The string of text that is split into lines
* @returns {Array} Array of lines
*/
_wrapText: function (ctx, text) {
var lines = text.split(this._reNewline), wrapped = [], i;
for (i = 0; i < lines.length; i++) {
wrapped = wrapped.concat(this._wrapLine(ctx, lines[i]));
}
return wrapped;
},
/**
* Wraps a line of text using the width of the Textbox and a context.
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @param {String} text The string of text to split into lines
* @returns {Array} Array of line(s) into which the given text is wrapped
* to.
*/
_wrapLine: function (ctx, text) {
var maxWidth = this.width, words = text.split(' '),
lines = [],
line = '';
if (ctx.measureText(text).width < maxWidth) {
lines.push(text);
}
else {
while (words.length > 0) {
/*
* If the textbox's width is less than the widest letter.
* TODO: Performance improvement - cache the width of W whenever
* fontSize changes.
*/
if (maxWidth <= ctx.measureText('W').width) {
return text.split('');
}
/*
* This handles a word that is longer than the width of the
* text area.
*/
while (Math.ceil(ctx.measureText(words[0]).width) >= maxWidth) {
var tmp = words[0];
words[0] = tmp.slice(0, -1);
if (words.length > 1) {
words[1] = tmp.slice(-1) + words[1];
}
else {
words.push(tmp.slice(-1));
}
}
if (Math.ceil(ctx.measureText(line + words[0]).width) < maxWidth) {
line += words.shift() + ' ';
}
else {
lines.push(line);
line = '';
}
if (words.length === 0) {
lines.push(line.substring(0, line.length - 1));
}
}
}
return lines;
},
/**
* Gets lines of text to render in the Textbox. This function calculates
* text wrapping on the fly everytime it is called.
* @returns {Array} Array of lines in the Textbox.
* @override
*/
_splitTextIntoLines: function () {
this.ctx.save();
this._setTextStyles(this.ctx);
lines = this._wrapText(this.ctx, this.text);
this.ctx.restore();
return lines;
},
/**
* When part of a group, we don't want the Textbox's scale to increase if
* the group's increases. That's why we reduce the scale of the Textbox by
* the amount that the group's increases. This is to maintain the effective
* scale of the Textbox at 1, so that font-size values make sense. Otherwise
* the same font-size value would result in different actual size depending
* on the value of the scale.
* @param {String} key
* @param {Any} value
*/
setOnGroup: function (key, value) {
if (key === 'scaleX') {
this.set(key, Math.abs(1 / value));
this.set('width', (this.get('width') * value) /
(typeof this.__oldScaleX === 'undefined' ? 1 : this.__oldScaleX));
this.__oldScaleX = value;
}
},
/**
* Returns 2d representation (lineIndex and charIndex) of cursor (or selection start).
* Overrides the superclass function to take into account text wrapping.
* @param {Number} selectionStart Optional index. When not given, current selectionStart is used.
* @returns {Object} This object has 'lineIndex' and 'charIndex' properties set to Numbers.
*/
get2DCursorLocation: function (selectionStart) {
if (typeof selectionStart === 'undefined') {
selectionStart = this.selectionStart;
}
/*
* We use `temp` to populate linesBeforeCursor instead of simply splitting
* textBeforeCursor with newlines to handle the case of the
* selectionStart value being on a word that, because of its length,
* needs to be wrapped to the next line.
*/
var lineIndex = 0,
linesBeforeCursor = [],
allLines = this._textLines, temp = selectionStart;
while (temp >= 0) {
if (lineIndex > allLines.length - 1) {
break;
}
temp -= allLines[lineIndex].length;
if (temp < 0) {
linesBeforeCursor[linesBeforeCursor.length] = allLines[lineIndex].slice(0,
temp + allLines[lineIndex].length);
}
else {
linesBeforeCursor[linesBeforeCursor.length] = allLines[lineIndex];
}
lineIndex++;
}
lineIndex--;
var lastLine = linesBeforeCursor[linesBeforeCursor.length - 1],
charIndex = lastLine.length;
if (linesBeforeCursor[lineIndex] === allLines[lineIndex]) {
if (lineIndex + 1 < allLines.length - 1) {
lineIndex++;
charIndex = 0;
}
}
return {
lineIndex: lineIndex,
charIndex: charIndex
};
},
/**
* Overrides superclass function and uses text wrapping data to get cursor
* boundary offsets instead of the array of chars.
* @param {Array} chars Unused
* @param {String} typeOfBoundaries Can be 'cursor' or 'selection'
* @returns {Object} Object with 'top', 'left', and 'lineLeft' properties set.
*/
_getCursorBoundariesOffsets: function (chars, typeOfBoundaries) {
var topOffset = 0,
leftOffset = 0,
cursorLocation = this.get2DCursorLocation(),
lineChars = this._textLines[cursorLocation.lineIndex].split(''),
lineLeftOffset = this._getCachedLineOffset(cursorLocation.lineIndex);
for (var i = 0; i < cursorLocation.charIndex; i++) {
leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i);
}
for (i = 0; i < cursorLocation.lineIndex; i++) {
topOffset += this._getHeightOfLine(this.ctx, i);
}
if (typeOfBoundaries === 'cursor') {
topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex) / this.lineHeight
- this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex) * (1 - this._fontSizeFraction);
}
return {
top: topOffset,
left: leftOffset,
lineLeft: lineLeftOffset
};
},
/**
* Returns object representation of an instance
* @method toObject
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {Object} object representation of an instance
*/
toObject: function (propertiesToInclude) {
return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), {
minWidth: this.minWidth
});
}
});
type: 'textbox',
/**
* Returns fabric.Textbox instance from an object representation
* @static
* @memberOf fabric.Textbox
* @param {Object} object Object to create an instance from
* @return {fabric.Textbox} instance of fabric.Textbox
* Minimum width of textbox, in pixels.
* @type Number
* @default
*/
fabric.Textbox.fromObject = function (object) {
return new fabric.Textbox(object.text, clone(object));
};
minWidth: 20,
/**
* Returns the default controls visibility required for Textboxes.
* @returns {Object}
*/
fabric.Textbox.getTextboxControlVisibility = function () {
return {
tl: false,
tr: false,
br: false,
bl: false,
ml: true,
mt: false,
mr: true,
mb: false,
mtr: true
};
};
/**
* Contains all fabric.Textbox objects that have been created
* @static
* @memberof fabric.Textbox
* Cached array of text wrapping.
* @type Array
*/
fabric.Textbox.instances = [];
})();
__cachedLines: null,
/**
* Constructor. Some scaling related property values are forced. Visibility
* of controls is also fixed; only the rotation and width controls are
* made available.
* @param {String} text Text string
* @param {Object} [options] Options object
* @return {fabric.Textbox} thisArg
*/
initialize: function (text, options) {
this.ctx = fabric.util.createCanvasElement().getContext('2d');
this.callSuper('initialize', text, options);
this.set({
lockUniScaling: false,
lockScalingY: true,
lockScalingFlip: true,
hasBorders: true
});
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
// add width to this list of props that effect line wrapping.
this._dimensionAffectingProps.width = true;
},
/**
* Unlike superclass's version of this function, Textbox does not update
* its width.
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @private
* @override
*/
_initDimensions: function (ctx) {
if (this.__skipDimension) {
return;
}
if (!ctx) {
ctx = fabric.util.createCanvasElement().getContext('2d');
this._setTextStyles(ctx);
}
this._textLines = this._splitTextIntoLines();
this._clearCache();
this.height = this._getTextHeight(ctx);
},
/**
* Wraps text using the 'width' property of Textbox. First this function
* splits text on newlines, so we preserve newlines entered by the user.
* Then it wraps each line using the width of the Textbox by calling
* _wrapLine().
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @param {String} text The string of text that is split into lines
* @returns {Array} Array of lines
*/
_wrapText: function (ctx, text) {
var lines = text.split(this._reNewline), wrapped = [], i;
for (i = 0; i < lines.length; i++) {
wrapped = wrapped.concat(this._wrapLine(ctx, lines[i]));
}
return wrapped;
},
/**
* Wraps a line of text using the width of the Textbox and a context.
* @param {CanvasRenderingContext2D} ctx Context to use for measurements
* @param {String} text The string of text to split into lines
* @returns {Array} Array of line(s) into which the given text is wrapped
* to.
*/
_wrapLine: function (ctx, text) {
var maxWidth = this.width, words = text.split(' '),
lines = [],
line = '';
if (ctx.measureText(text).width < maxWidth) {
lines.push(text);
}
else {
while (words.length > 0) {
/*
* If the textbox's width is less than the widest letter.
* TODO: Performance improvement - cache the width of W whenever
* fontSize changes.
*/
if (maxWidth <= ctx.measureText('W').width) {
return text.split('');
}
/*
* This handles a word that is longer than the width of the
* text area.
*/
while (Math.ceil(ctx.measureText(words[0]).width) >= maxWidth) {
var tmp = words[0];
words[0] = tmp.slice(0, -1);
if (words.length > 1) {
words[1] = tmp.slice(-1) + words[1];
}
else {
words.push(tmp.slice(-1));
}
}
if (Math.ceil(ctx.measureText(line + words[0]).width) < maxWidth) {
line += words.shift() + ' ';
}
else {
lines.push(line);
line = '';
}
if (words.length === 0) {
lines.push(line.substring(0, line.length - 1));
}
}
}
return lines;
},
/**
* Gets lines of text to render in the Textbox. This function calculates
* text wrapping on the fly everytime it is called.
* @returns {Array} Array of lines in the Textbox.
* @override
*/
_splitTextIntoLines: function () {
this.ctx.save();
this._setTextStyles(this.ctx);
lines = this._wrapText(this.ctx, this.text);
this.ctx.restore();
return lines;
},
/**
* When part of a group, we don't want the Textbox's scale to increase if
* the group's increases. That's why we reduce the scale of the Textbox by
* the amount that the group's increases. This is to maintain the effective
* scale of the Textbox at 1, so that font-size values make sense. Otherwise
* the same font-size value would result in different actual size depending
* on the value of the scale.
* @param {String} key
* @param {Any} value
*/
setOnGroup: function (key, value) {
if (key === 'scaleX') {
this.set(key, Math.abs(1 / value));
this.set('width', (this.get('width') * value) /
(typeof this.__oldScaleX === 'undefined' ? 1 : this.__oldScaleX));
this.__oldScaleX = value;
}
},
/**
* Returns 2d representation (lineIndex and charIndex) of cursor (or selection start).
* Overrides the superclass function to take into account text wrapping.
* @param {Number} selectionStart Optional index. When not given, current selectionStart is used.
* @returns {Object} This object has 'lineIndex' and 'charIndex' properties set to Numbers.
*/
get2DCursorLocation: function (selectionStart) {
if (typeof selectionStart === 'undefined') {
selectionStart = this.selectionStart;
}
/*
* We use `temp` to populate linesBeforeCursor instead of simply splitting
* textBeforeCursor with newlines to handle the case of the
* selectionStart value being on a word that, because of its length,
* needs to be wrapped to the next line.
*/
var lineIndex = 0,
linesBeforeCursor = [],
allLines = this._textLines, temp = selectionStart;
while (temp >= 0) {
if (lineIndex > allLines.length - 1) {
break;
}
temp -= allLines[lineIndex].length;
if (temp < 0) {
linesBeforeCursor[linesBeforeCursor.length] = allLines[lineIndex].slice(0,
temp + allLines[lineIndex].length);
}
else {
linesBeforeCursor[linesBeforeCursor.length] = allLines[lineIndex];
}
lineIndex++;
}
lineIndex--;
var lastLine = linesBeforeCursor[linesBeforeCursor.length - 1],
charIndex = lastLine.length;
if (linesBeforeCursor[lineIndex] === allLines[lineIndex]) {
if (lineIndex + 1 < allLines.length - 1) {
lineIndex++;
charIndex = 0;
}
}
return {
lineIndex: lineIndex,
charIndex: charIndex
};
},
/**
* Overrides superclass function and uses text wrapping data to get cursor
* boundary offsets instead of the array of chars.
* @param {Array} chars Unused
* @param {String} typeOfBoundaries Can be 'cursor' or 'selection'
* @returns {Object} Object with 'top', 'left', and 'lineLeft' properties set.
*/
_getCursorBoundariesOffsets: function (chars, typeOfBoundaries) {
var topOffset = 0,
leftOffset = 0,
cursorLocation = this.get2DCursorLocation(),
lineChars = this._textLines[cursorLocation.lineIndex].split(''),
lineLeftOffset = this._getCachedLineOffset(cursorLocation.lineIndex);
for (var i = 0; i < cursorLocation.charIndex; i++) {
leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i);
}
for (i = 0; i < cursorLocation.lineIndex; i++) {
topOffset += this._getHeightOfLine(this.ctx, i);
}
if (typeOfBoundaries === 'cursor') {
topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex) / this.lineHeight
- this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex) * (1 - this._fontSizeFraction);
}
return {
top: topOffset,
left: leftOffset,
lineLeft: lineLeftOffset
};
},
/**
* Returns object representation of an instance
* @method toObject
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {Object} object representation of an instance
*/
toObject: function (propertiesToInclude) {
return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), {
minWidth: this.minWidth
});
}
});
/**
* Returns fabric.Textbox instance from an object representation
* @static
* @memberOf fabric.Textbox
* @param {Object} object Object to create an instance from
* @return {fabric.Textbox} instance of fabric.Textbox
*/
fabric.Textbox.fromObject = function (object) {
return new fabric.Textbox(object.text, clone(object));
};
/**
* Returns the default controls visibility required for Textboxes.
* @returns {Object}
*/
fabric.Textbox.getTextboxControlVisibility = function () {
return {
tl: false,
tr: false,
br: false,
bl: false,
ml: true,
mt: false,
mr: true,
mb: false,
mtr: true
};
};
/**
* Contains all fabric.Textbox objects that have been created
* @static
* @memberof fabric.Textbox
* @type Array
*/
fabric.Textbox.instances = [];
})();