@awayjs/scene
Version:
AwayJS scene classes
1,226 lines (1,223 loc) • 131 kB
JavaScript
import { __extends } from "tslib";
import { ColorUtils, Matrix, Rectangle, Point, Vector3D } from '@awayjs/core';
import { ImageSampler, Float2Attributes } from '@awayjs/stage';
import { Style, TriangleElements } from '@awayjs/renderer';
import { Graphics, Shape, GraphicsFactoryHelper, MaterialManager, SolidFillStyle, TextureAtlas } from '@awayjs/graphics';
import { TextFieldAutoSize } from '../text/TextFieldAutoSize';
import { TextFieldType } from '../text/TextFieldType';
import { TextFormat } from '../text/TextFormat';
import { TextLineMetrics } from '../text/TextLineMetrics';
import { KeyboardEvent } from '../events/KeyboardEvent';
import { TextfieldEvent } from '../events/TextfieldEvent';
import { DisplayObjectContainer } from './DisplayObjectContainer';
import { Sprite } from './Sprite';
import { TextSprite } from './TextSprite';
import { TextShape } from '../text/TextShape';
import { HTMLTextProcessor } from '../text/HTMLTextProcessor';
import { TextFormatAlign } from '../text/TextFormatAlign';
import { MouseEvent } from '../events/MouseEvent';
import { Settings } from '../Settings';
var WordStore = /** @class */ (function () {
function WordStore(size) {
if (size === void 0) { size = 40; }
this.index = -1;
this.store = Array.from({ length: size }, function (e) { return ({
x: Infinity, y: Infinity, start: 0, width: 0, len: 0
}); });
}
WordStore.prototype.put = function (start, x, y, width, len) {
this.index++;
var word = this.store[this.index] || (this.store[this.index] = {});
word.start = start;
word.x = x;
word.y = y;
word.width = width;
word.len = len;
return word;
};
Object.defineProperty(WordStore.prototype, "last", {
get: function () {
return this.store[this.index];
},
enumerable: false,
configurable: true
});
Object.defineProperty(WordStore.prototype, "length", {
get: function () {
return this.index + 1;
},
set: function (v) {
this.index = v - 1;
},
enumerable: false,
configurable: true
});
WordStore.prototype.get = function (index) {
return this.store[index];
};
WordStore.prototype.free = function () {
this.index = -1;
};
WordStore.prototype.dispose = function () {
this.store = null;
this.index = 0;
};
return WordStore;
}());
var MNEMOS = [
{
test: /'/g,
replace: '\''
},
{
test: />/g,
replace: '>'
}
];
/**
* The TextField class is used to create display objects for text display and
* input. <ph outputclass="flexonly">You can use the TextField class to
* perform low-level text rendering. However, in Flex, you typically use the
* Label, Text, TextArea, and TextInput controls to process text. <ph
* outputclass="flashonly">You can give a text field an instance name in the
* Property inspector and use the methods and properties of the TextField
* class to manipulate it with ActionScript. TextField instance names are
* displayed in the Movie Explorer and in the Insert Target Path dialog box in
* the Actions panel.
*
* <p>To create a text field dynamically, use the <code>TextField()</code>
* constructor.</p>
*
* <p>The methods of the TextField class let you set, select, and manipulate
* text in a dynamic or input text field that you create during authoring or
* at runtime. </p>
*
* <p>ActionScript provides several ways to format your text at runtime. The
* TextFormat class lets you set character and paragraph formatting for
* TextField objects. You can apply Cascading Style Sheets(CSS) styles to
* text fields by using the <code>TextField.styleSheet</code> property and the
* StyleSheet class. You can use CSS to style built-in HTML tags, define new
* formatting tags, or apply styles. You can assign HTML formatted text, which
* optionally uses CSS styles, directly to a text field. HTML text that you
* assign to a text field can contain embedded media(movie clips, SWF files,
* GIF files, PNG files, and JPEG files). The text wraps around the embedded
* media in the same way that a web browser wraps text around media embedded
* in an HTML document. </p>
*
* <p>Flash Player supports a subset of HTML tags that you can use to format
* text. See the list of supported HTML tags in the description of the
* <code>htmlText</code> property.</p>
*
* @event change Dispatched after a control value is
* modified, unlike the
* <code>textInput</code> event, which is
* dispatched before the value is modified.
* Unlike the W3C DOM Event Model version of
* the <code>change</code> event, which
* dispatches the event only after the
* control loses focus, the ActionScript 3.0
* version of the <code>change</code> event
* is dispatched any time the control
* changes. For example, if a user types text
* into a text field, a <code>change</code>
* event is dispatched after every keystroke.
* @event link Dispatched when a user clicks a hyperlink
* in an HTML-enabled text field, where the
* URL begins with "event:". The remainder of
* the URL after "event:" is placed in the
* text property of the LINK event.
*
* <p><b>Note:</b> The default behavior,
* adding the text to the text field, occurs
* only when Flash Player generates the
* event, which in this case happens when a
* user attempts to input text. You cannot
* put text into a text field by sending it
* <code>textInput</code> events.</p>
* @event scroll Dispatched by a TextField object
* <i>after</i> the user scrolls.
* @event textInput Flash Player dispatches the
* <code>textInput</code> event when a user
* enters one or more characters of text.
* Various text input methods can generate
* this event, including standard keyboards,
* input method editors(IMEs), voice or
* speech recognition systems, and even the
* act of pasting plain text with no
* formatting or style information.
* @event textInteractionModeChange Flash Player dispatches the
* <code>textInteractionModeChange</code>
* event when a user changes the interaction
* mode of a text field. for example on
* Android, one can toggle from NORMAL mode
* to SELECTION mode using context menu
* options
*/
var TextField = /** @class */ (function (_super) {
__extends(TextField, _super);
/**
* Creates a new TextField instance. After you create the TextField instance,
* call the <code>addChild()</code> or <code>addChildAt()</code> method of
* the parent DisplayObjectContainer object to add the TextField instance to
* the display list.
*
* <p>The default size for a text field is 100 x 100 pixels.</p>
*/
function TextField() {
var _this = _super.call(this) || this;
_this.textOffsetX = 0;
_this.textOffsetY = 0;
_this._selectionBeginIndex = 0;
_this._selectionEndIndex = 0;
_this._biggestLine = 0;
/**
* Renderable text, used for computing a glyphs
* @private
*/
_this._iText = '';
/**
* Place where is diff is begun to end
* @private
*/
_this._iTextDiffStart = 0;
/**
* Original text passed to field
* @private
*/
_this._text = '';
_this._iTextWoLineBreaks = ''; // _iText without line breaks
_this._newTextFormat = new TextFormat();
_this.cursorIntervalID = -1;
_this.chars_codes = [];
_this.chars_width = [];
_this.tf_per_char = [];
// stores offset and length and width for each word
_this.words = new WordStore(10);
_this._textRuns_formats = []; // stores textFormat for each textrun
// stores words-offset, word-count and width for each textrun
_this._textRuns_words = [];
_this._paragraph_textRuns_indices = []; // stores textFormat for each textrun
_this._maxWidthLine = 0;
_this._labelData = null;
_this.lines_wordStartIndices = [];
_this.lines_wordEndIndices = [];
_this.lines_start_y = [];
_this.lines_start_x = [];
_this.lines_charIdx_start = [];
_this.lines_charIdx_end = [];
_this.lines_width = [];
_this.lines_height = [];
_this.lines_numSpacesPerline = [];
_this.char_positions_x = [];
_this.char_positions_y = [];
// keeping track of the original textfield that was used for cloning this one.
_this.sourceTextField = null;
_this._maskWidth = 0;
_this._maskHeight = 0;
_this._maskTextOffsetX = 0;
_this._maskTextOffsetY = 0;
_this.isStatic = false;
_this._internalScale = new Vector3D(1, 1, 1);
_this.onKeyDelegate = function (event) { return _this.onKey(event); };
_this.startSelectionByMouseDelegate = function (event) { return _this.startSelectionByMouse(event); };
_this.stopSelectionByMouseDelegate = function (event) { return _this.stopSelectionByMouse(event); };
_this.updateSelectionByMouseDelegate = function (event) { return _this.updateSelectionByMouse(event); };
_this._onClipboardPasteDelegate = function (event) { return _this.onClipboardPaste(event); };
_this.cursorIntervalID = -1;
_this._tabEnabled = true;
_this.cursorType = '';
_this.textOffsetX = 0;
_this.textOffsetY = 0;
_this.textShapes = {};
_this._textColor = 0;
_this._width = 100;
_this._height = 100;
_this._textWidth = 0;
_this._textHeight = 0;
_this._type = TextFieldType.DYNAMIC;
_this._selectable = false;
_this._numLines = 0;
_this.multiline = false;
_this._autoSize = TextFieldAutoSize.NONE;
_this._wordWrap = false;
_this._background = false;
_this._backgroundColor = 0xffffff;
_this._border = false;
_this._borderColor = 0x000000;
_this.html = false;
_this.maxChars = 0;
_this._selectionBeginIndex = 0;
_this._selectionEndIndex = 0;
_this._scrollH = 0;
_this._scrollV = 0;
_this._textFormats = [];
_this._graphics = Graphics.getGraphics(); //unique graphics object for each TextField
_this.mouseEnabled = _this._selectable;
return _this;
}
TextField.getNewTextField = function () {
return (TextField._textFields.length) ? TextField._textFields.pop() : new TextField();
};
TextField.clearPool = function () {
TextField._textFields = [];
};
TextField.prototype.updateMaskMode = function () {
// mask needed
if (this.inMaskMode) {
if (this._maskWidth != this._width || this._maskHeight != this._height ||
this._maskTextOffsetX != this.textOffsetX || this._maskTextOffsetY != this.textOffsetY) {
this._maskWidth = this._width;
this._maskHeight = this._height;
this._maskTextOffsetX = this.textOffsetX;
this._maskTextOffsetY = this.textOffsetY;
this.maskChild.graphics.clear();
this.maskChild.graphics.beginFill(0xffffff);
this.maskChild.graphics.drawRect(this.textOffsetX, this.textOffsetY, this._width, this._height);
this.maskChild.graphics.endFill();
}
this._graphics.clear();
}
if (!this.inMaskMode) {
// masking already setup
// just make sure the mask has correct size
this.inMaskMode = true;
if (!this.maskChild)
this.maskChild = new Sprite();
if (!this.textChild)
this.textChild = new TextSprite();
this.textChild.mouseEnabled = false;
this.textChild.parentTextField = this;
this.maskChild.mouseEnabled = false;
this.maskChild.graphics.beginFill(0xffffff);
this.maskChild.graphics.drawRect(this.textOffsetX, this.textOffsetY, this._width, this._height);
this.maskChild.graphics.endFill();
this.addChild(this.maskChild);
this.addChild(this.textChild);
this.maskChild.visible = false;
this._graphics.clear();
this.targetGraphics = this.textChild.graphics;
}
// only use masking if needed:
if (this._textWidth > this._width || this._textHeight > this._height) {
this.textChild.scriptMask = this.maskChild;
}
else {
this.textChild.scriptMask = null;
}
return;
};
TextField.prototype.getMouseCursor = function () {
return this.cursorType;
};
Object.defineProperty(TextField.prototype, "isInFocus", {
get: function () {
return this._isInFocus;
},
set: function (value) {
},
enumerable: false,
configurable: true
});
TextField.prototype.setFocus = function (value, fromMouseDown, sendSoftKeyEvent) {
if (fromMouseDown === void 0) { fromMouseDown = false; }
if (sendSoftKeyEvent === void 0) { sendSoftKeyEvent = true; }
if (this._isInFocus == value) {
return;
}
_super.prototype.setFocus.call(this, value, fromMouseDown, sendSoftKeyEvent);
this.enableInput(value);
if (!this._selectable) {
return;
}
// if (value) {
// this.setSelection(0, this._iText.length);
// // check if a adapter exists
// if (sendSoftKeyEvent && this.adapter != this) {
// // todo: create a ITextFieldAdapter, so we can use selectText() without casting to any
// (<any> this.adapter).selectTextField(fromMouseDown);
// }
// } else {
// this.setSelection(0, 0);
// }
this.setSelection(0, 0);
this._glyphsDirty = true;
this.invalidate();
};
TextField.prototype.enableInput = function (enable) {
if (enable === void 0) { enable = true; }
if (this.cursorIntervalID >= 0) {
window.clearInterval(this.cursorIntervalID);
this.cursorIntervalID = -1;
}
if (enable && this._isInFocus && this.selectable) {
this.drawSelectionGraphics();
var myThis_1 = this;
this.cursorIntervalID = window.setInterval(function () {
myThis_1.cursorBlinking = !myThis_1.cursorBlinking;
if (!myThis_1.selectable) {
myThis_1.cursorBlinking = true;
}
myThis_1._shapesDirty = true;
myThis_1.invalidate();
}, 500);
}
// FFUUU, this not working because we prevent events, and Ctrl + V/C not bubbled to document
// will use mannual handling a Ctrl + V/C
/*
if (enable) {
document.addEventListener('paste', this._onClipboardPasteDelegate);
} else {
document.removeEventListener('paste', this._onClipboardPasteDelegate);
}*/
};
TextField.prototype.findCharIdxForMouse = function (event) {
var myPoint = new Point(event.position.x, event.position.y);
var lineIdx = this.getLineIndexAtPoint(myPoint.x, myPoint.y);
var charIdx = this.getCharIndexAtPoint(myPoint.x, myPoint.y, lineIdx);
if (lineIdx >= this.lines_start_x.length) {
lineIdx = this.lines_start_x.length - 1;
}
if (lineIdx < 0) {
lineIdx = 0;
}
if (lineIdx >= 0 && charIdx < 0 && this.lines_start_x[lineIdx] !== undefined) {
if (myPoint.x <= this.lines_start_x[lineIdx]) {
charIdx = this.lines_charIdx_start[lineIdx];
}
else {
charIdx = this.lines_charIdx_end[lineIdx];
}
}
if (lineIdx < 0 || charIdx < 0) {
charIdx = 0;
}
return charIdx;
};
TextField.prototype.startSelectionByMouse = function (event) {
this._selectionBeginIndex = this.findCharIdxForMouse(event);
this._selectionEndIndex = this._selectionBeginIndex;
if (this.cursorShape)
this.cursorShape.invalidate();
this.cursorShape = undefined;
if (this.bgShapeSelect)
this.bgShapeSelect.invalidate();
this.bgShapeSelect = undefined;
this._glyphsDirty = true;
this._shapesDirty = true;
this._textShapesDirty = true;
this.cursorBlinking = false;
this.drawSelectionGraphics();
};
TextField.prototype.stopSelectionByMouse = function (event) {
this._selectionEndIndex = this.findCharIdxForMouse(event);
//console.log("stopSelectionByMouse", this._selectionBeginIndex, this._selectionEndIndex);
this._glyphsDirty = true;
this.reConstruct();
this.drawSelectionGraphics();
};
TextField.prototype.updateSelectionByMouse = function (event) {
this._selectionEndIndex = this.findCharIdxForMouse(event);
if (this.bgShapeSelect)
this.bgShapeSelect.invalidate();
this.bgShapeSelect = undefined;
//console.log("updateSelectionByMouse", this._selectionBeginIndex, this._selectionEndIndex);
this._glyphsDirty = true;
this.reConstruct();
this.drawSelectionGraphics();
};
TextField.prototype.drawSelectionGraphics = function () {
if (this._selectionBeginIndex < 0) {
this._selectionBeginIndex = 0;
}
if (this._selectionBeginIndex > this.char_positions_x.length) {
this._selectionBeginIndex = this.char_positions_x.length;
}
if (this._selectionEndIndex < 0) {
this._selectionEndIndex = 0;
}
if (this._selectionEndIndex > this.char_positions_x.length) {
this._selectionEndIndex = this.char_positions_x.length;
}
if (this._selectionBeginIndex === this._selectionEndIndex) {
this.showSelection = false;
this.drawCursor();
}
else {
this.showSelection = true;
this.cursorBlinking = true; // disable cursor if text select mode
this.drawSelectedBG();
}
};
TextField.prototype.scrollToCursor = function (x, y) {
// if(!this.textChild){
// return;
// }
// if(x>this._width){
// this.textChild.x-=10;
// }
// if(x<Math.abs(this.textChild.x)){
// this.textChild.x=this.textChild.x+x+2;
// }
// if(this.textChild.x<(this._width-this.textChild.width)){
// this.textChild.x=this._width-this.textChild.width;
// }
// if(this.textChild.x>0){
// this.textChild.x=0;
// }
};
TextField.prototype.drawCursor = function () {
this._shapesDirty = true;
if (this.cursorBlinking || !this.selectable || this.selectionBeginIndex !== this.selectionEndIndex) {
return;
}
var x = 0;
var y = 0;
var tf = this._newTextFormat;
if (this.char_positions_x.length == 0) {
x = this.textOffsetX + (this._width / 2) + this._textWidth / 2;
if (tf.align == 'justify') {
// do nothing
}
else if (tf.align == 'center') {
// do nothing
}
else if (tf.align == 'right') {
x = this.textOffsetX + this._width - 2;
}
else if (tf.align == 'left') {
x = this.textOffsetX + 4 + this._textWidth;
}
}
else if (this._selectionBeginIndex == this.char_positions_x.length) {
x = this.char_positions_x[this._selectionBeginIndex - 1] + this.chars_width[this._selectionBeginIndex - 1];
y = this.char_positions_y[this._selectionBeginIndex - 1];
tf = this.tf_per_char[this._selectionBeginIndex - 1];
}
else {
x = this.char_positions_x[this._selectionBeginIndex];
y = this.char_positions_y[this._selectionBeginIndex];
tf = this.tf_per_char[this._selectionBeginIndex];
}
tf.font_table.initFontSize(tf.size);
var height = tf.font_table.getLineHeight();
var color = this.getTextColorForTextFormat(tf);
var cursorScale = this.internalScale.x;
if (cursorScale <= 0) {
cursorScale = 1;
}
var cursorRect = [x - (0.5 * cursorScale), y, cursorScale, height];
if (!this.cursorShape) {
this.cursorShape = GraphicsFactoryHelper.drawRectangles(cursorRect, color, 1);
this.cursorShape.usages++; //TODO: get rid of this memory lea
}
else {
GraphicsFactoryHelper.updateRectanglesShape(this.cursorShape, cursorRect);
}
if (this.cursorShape.style.color !== color) {
var solid = new SolidFillStyle(color, ColorUtils.float32ColorToARGB(color)[0] / 255 || 1);
var material = MaterialManager.getMaterialForColor(solid);
var shape = this.cursorShape;
shape.material = material;
if (material.getNumTextures()) {
shape.style = new Style();
shape.style.image = TextureAtlas.getTextureForColor(solid);
shape.style.uvMatrix = solid.getUVMatrix();
}
}
this.scrollToCursor(x, y);
};
TextField.prototype.drawSelectedBG = function () {
this._shapesDirty = true;
this._textShapesDirty = true;
if (this._selectionBeginIndex < 0) {
this._selectionBeginIndex = 0;
}
if (this._selectionBeginIndex > this.char_positions_x.length) {
this._selectionBeginIndex = this.char_positions_x.length;
}
var select_start = this._selectionBeginIndex;
var select_end = this._selectionEndIndex;
if (this._selectionEndIndex < this._selectionBeginIndex) {
select_start = this._selectionEndIndex;
select_end = this._selectionBeginIndex;
}
var x = 0;
var y = 0;
var oldy = -1;
var tf = null;
var startx = -1;
var width = 0;
var height = 0;
var rectangles = [];
if (this.char_positions_x.length != 0 && this._selectionEndIndex != this._selectionBeginIndex) {
var len = (select_end > this.char_positions_x.length) ? this.char_positions_x.length : select_end;
//console.log(select_start, select_end);
for (var i = select_start; i < len; i++) {
if (i == this.char_positions_x.length) {
x = this.char_positions_x[i - 1] + this.chars_width[i - 1];
y = this.char_positions_y[i - 1];
tf = this.tf_per_char[i - 1];
}
else {
x = this.char_positions_x[i];
y = this.char_positions_y[i];
tf = this.tf_per_char[i];
}
if (startx < 0) {
startx = x;
}
if (oldy >= 0 && oldy != y) {
// new line
rectangles.push(startx, oldy, width, height);
width = 0;
startx = x;
}
width += this.chars_width[i];
oldy = y;
tf.font_table.initFontSize(tf.size);
height = Math.max(height, tf.font_table.getLineHeight());
}
}
// if (this.bgShapeSelect) {
// this.bgShapeSelect.dispose();
// this.bgShapeSelect=null;
// }
if (width > 0) {
rectangles.push(startx, oldy, width, height);
if (!this.bgShapeSelect) {
this.bgShapeSelect = GraphicsFactoryHelper.drawRectangles(rectangles, 0x0, 1);
this.bgShapeSelect.usages++; //TODO: get rid of this memory leak
}
else {
GraphicsFactoryHelper.updateRectanglesShape(this.bgShapeSelect, rectangles);
}
return;
}
this.scrollToCursor(startx + width, oldy + height);
};
TextField.prototype.drawBG = function () {
//TODO this fixes masking using static textfields, but dynamic textfields still have problems. (see addChild(this.maskChild))
if (this._background) {
this._graphics.beginFill(this.backgroundColor, 1);
this._graphics.drawRect(this.textOffsetX, this.textOffsetY, this.width, this.height);
this._graphics.endFill();
}
//create a hitArea for the textfield
var pickObject = this.pickObject;
if (!pickObject) {
this.pickObject = pickObject || (pickObject = new Sprite());
pickObject.pickObjectFromTimeline = true;
}
var graphics = pickObject.graphics;
graphics.clear();
graphics.beginFill(0x000000, 1);
graphics.drawRect(this.textOffsetX, this.textOffsetY, this.width, this.height);
graphics.endFill();
};
TextField.prototype.drawBorder = function () {
var half_thickness_x = this.border ? 0.25 * this.internalScale.x : 0;
var half_thickness_y = this.border ? 0.25 * this.internalScale.y : 0;
this._graphics.beginFill(this._borderColor, 1);
this._graphics.drawRect(this.textOffsetX, this.textOffsetY, this._width, half_thickness_y * 2);
this._graphics.drawRect(this.textOffsetX, this.textOffsetY + this._height - half_thickness_y * 2, this._width, half_thickness_y * 2);
this._graphics.drawRect(this.textOffsetX, this.textOffsetY + half_thickness_y * 2, half_thickness_x * 2, this._height - half_thickness_y * 2);
this._graphics.drawRect(this.textOffsetX + this._width - half_thickness_x * 2, this.textOffsetY + half_thickness_y * 2, half_thickness_x * 2, this._height - half_thickness_y * 2);
this._graphics.endFill();
};
TextField.prototype.getTextShapeForIdentifierAndFormat = function (id, format) {
if (this.textShapes[id]) {
return this.textShapes[id];
}
return (this.textShapes[id] = new TextShape(format, id));
};
Object.defineProperty(TextField.prototype, "autoSize", {
get: function () {
return this._autoSize;
},
set: function (value) {
if (this._autoSize == value)
return;
if (typeof value === 'string') {
if (value != TextFieldAutoSize.CENTER &&
value != TextFieldAutoSize.NONE &&
value != TextFieldAutoSize.LEFT &&
value != TextFieldAutoSize.RIGHT) {
return;
}
}
else {
if (typeof value === 'boolean') {
if (value)
value = TextFieldAutoSize.LEFT;
else
value = TextFieldAutoSize.NONE;
}
if (typeof value === 'number') {
if (value > 0)
value = TextFieldAutoSize.LEFT;
else
value = TextFieldAutoSize.NONE;
}
}
this._autoSize = value;
this._positionsDirty = true;
if (this._autoSize != TextFieldAutoSize.NONE)
this.invalidate();
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "internalScale", {
get: function () {
return this._internalScale;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "assetType", {
/**
*
* @returns {string}
*/
get: function () {
return TextField.assetType;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "background", {
get: function () {
return this._background;
},
set: function (value) {
if (this._background == value)
return;
this._background = value;
this._shapesDirty = true;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "backgroundColor", {
get: function () {
return this._backgroundColor;
},
set: function (value) {
this._backgroundColor = value;
this._shapesDirty = true;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "border", {
get: function () {
return this._border;
},
set: function (value) {
if (value == this._border)
return;
this._border = value;
this._shapesDirty = true;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "borderColor", {
get: function () {
return this._borderColor;
},
set: function (value) {
if (value == this.borderColor)
return;
this._borderColor = value;
this._shapesDirty = true;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "bottomScrollV", {
/**
* An integer(1-based index) that indicates the bottommost line that is
* currently visible in the specified text field. Think of the text field as
* a window onto a block of text. The <code>scrollV</code> property is the
* 1-based index of the topmost visible line in the window.
*
* <p>All the text between the lines indicated by <code>scrollV</code> and
* <code>bottomScrollV</code> is currently visible in the text field.</p>
*/
get: function () {
return this._bottomScrollV;
},
set: function (value) {
if (value == this._bottomScrollV)
return;
this._bottomScrollV = value;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "caretIndex", {
/**
* The index of the insertion point(caret) position. If no insertion point
* is displayed, the value is the position the insertion point would be if
* you restored focus to the field(typically where the insertion point last
* was, or 0 if the field has not had focus).
*
* <p>Selection span indexes are zero-based(for example, the first position
* is 0, the second position is 1, and so on).</p>
*/
get: function () {
return this._caretIndex;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "height", {
/**
*
*/
get: function () {
if (this._autoSize != TextFieldAutoSize.NONE)
this.reConstruct();
return this._height;
},
set: function (val) {
if (this._height == val)
return;
if (this._autoSize != TextFieldAutoSize.NONE)
return;
this._height = val;
this._positionsDirty = true;
this.invalidate();
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "htmlText", {
get: function () {
return this._htmlText;
},
set: function (value) {
value = (value == undefined) ? '' : value.toString();
if (value == this._htmlText)
return;
this._htmlText = value;
var processedText = HTMLTextProcessor.get().processHTML(this, value);
// text might be the same,
// we still need to set textDirty, because formatting might have changed
//console.log("html out", textProps.text);
this._labelData = null;
this._text = processedText;
this._iText = processedText;
this._iTextWoLineBreaks = processedText.replace(/(\r\n|\n|\\n|\r)/gm, '');
this._textDirty = true;
//console.log("set text", value, "on" , this);
this.invalidate();
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "length", {
/**
* The number of characters in a text field. A character such as tab
* (<code>\t</code>) counts as one character.
*/
get: function () {
return this._iText.length;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "maxScrollH", {
/**
* The maximum value of <code>scrollH</code>.
*/
get: function () {
this.reConstruct();
return this._maxScrollH;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "maxScrollV", {
/**
* The maximum value of <code>scrollV</code>.
*/
get: function () {
this.reConstruct();
return this._maxScrollV;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "numLines", {
/**
* Defines the number of text lines in a multiline text field. If
* <code>wordWrap</code> property is set to <code>true</code>, the number of
* lines increases when text wraps.
*/
get: function () {
this.reConstruct();
return this._numLines;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "restrict", {
get: function () {
return this._restrict;
},
set: function (value) {
if (value == this._restrict)
return;
this._restrict = value;
this._restrictRegex = null;
if (typeof value == 'undefined')
return;
value = value.toString();
// flash allows something like -9 to be used instaed 0-9. fix this here:
if (value.length >= 2 && value[0] == '-' && !isNaN(parseInt(value[1])))
value = '0' + value;
// remove all backslashes. flash does not allow to use backslash as allowed char
value = value.replace(/\\/g, '');
// remove all ^. flash does not allow to use ^ as allowed char
value = value.replace(/\^/g, '');
// make sure all "-" are escaped if they are not used to define a range
// eslint-disable-next-line no-useless-escape
value = value.replace(/([^a-zA-Z0-9])\-/g, '$1\\-');
// escape all special chars so that regex will be valid
//todo: should be able to do the following with a single regex:
value = value.replace(/\./g, '\\.');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\</g, '\\<');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\>/g, '\\>');
value = value.replace(/\+/g, '\\+');
value = value.replace(/\*/g, '\\*');
value = value.replace(/\?/g, '\\?');
value = value.replace(/\[/g, '\\[');
value = value.replace(/\]/g, '\\]');
value = value.replace(/\$/g, '\\$');
value = value.replace(/\(/g, '\\(');
value = value.replace(/\)/g, '\\)');
value = value.replace(/\{/g, '\\{');
value = value.replace(/\}/g, '\\}');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\=/g, '\\=');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\!/g, '\\!');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\:/g, '\\:');
value = value.replace(/\|/g, '\\|');
value = value.replace(/\//g, '\\/');
// eslint-disable-next-line no-useless-escape
value = value.replace(/\%/g, '\\%');
this._restrictRegex = new RegExp('[^' + value + ']', 'g');
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "scrollH", {
get: function () {
return this._scrollH;
},
set: function (value) {
if (value == this._scrollH)
return;
this._scrollH = value;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "scrollV", {
get: function () {
return this._scrollV;
},
set: function (value) {
var rounded = Math.round(value);
if (rounded === this._scrollV)
return;
this._scrollV = rounded;
if (this._scrollV > this._maxScrollV)
this._scrollV = this._maxScrollV;
if (this._scrollV <= 0) {
this._scrollV = 0;
}
if (!this.textChild) {
return;
}
// unsafe
this.textChild.y = -this.lines_start_y[this._scrollV];
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "selectable", {
get: function () {
return this._selectable;
},
set: function (value) {
if (this.selectable == value) {
return;
}
this._selectable = value;
this.mouseEnabled = value;
this.cursorType = value ? 'text' : '';
if (value) {
this.addEventListener(MouseEvent.DRAG_START, this.startSelectionByMouseDelegate);
this.addEventListener(MouseEvent.DRAG_STOP, this.stopSelectionByMouseDelegate);
this.addEventListener(MouseEvent.DRAG_MOVE, this.updateSelectionByMouseDelegate);
}
else {
this.removeEventListener(MouseEvent.DRAG_START, this.startSelectionByMouseDelegate);
this.removeEventListener(MouseEvent.DRAG_STOP, this.stopSelectionByMouseDelegate);
this.removeEventListener(MouseEvent.DRAG_MOVE, this.updateSelectionByMouseDelegate);
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "selectionBeginIndex", {
/**
* The zero-based character index value of the first character in the current
* selection. For example, the first character is 0, the second character is
* 1, and so on. If no text is selected, this property is the value of
* <code>caretIndex</code>.
*/
get: function () {
return this._selectionBeginIndex;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "selectionEndIndex", {
/**
* The zero-based character index value of the last character in the current
* selection. For example, the first character is 0, the second character is
* 1, and so on. If no text is selected, this property is the value of
* <code>caretIndex</code>.
*/
get: function () {
return this._selectionEndIndex;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "text", {
/**
* A string that is the current text in the text field. Lines are separated
* by the carriage return character(<code>'\r'</code>, ASCII 13). This
* property contains unformatted text in the text field, without HTML tags.
*
* <p>To get the text in HTML form, use the <code>htmlText</code>
* property.</p>
*/
get: function () {
return this._text;
},
set: function (value) {
value = (value == undefined) ? '' : value.toString();
value = value.replace(String.fromCharCode(160), ' ');
if (this._text == value && !this._newFormatDirty)
return;
this._newFormatDirty = false;
this._labelData = null;
this._text = value;
if (value != '' && ((value.charCodeAt(value.length - 1) == 13) || (value.charCodeAt(value.length - 1) == 10))) {
value = value.slice(0, value.length - 1);
}
if (value != '' && (value.length >= 3
&& value[value.length - 1] == 'n' && value[value.length - 2] == '\\' && value[value.length - 3] == '\\')) {
value = value.slice(0, value.length - 3);
}
if (value != '' && (value.length >= 3 && value[value.length - 1] == 'n' && value[value.length - 2] == '\\')) {
value = value.slice(0, value.length - 2);
}
for (var _i = 0, MNEMOS_1 = MNEMOS; _i < MNEMOS_1.length; _i++) {
var m = MNEMOS_1[_i];
value = value.replace(m.test, m.replace);
}
this._iText = value;
this._iTextWoLineBreaks = value.replace(/(\r\n|\n|\\n|\r)/gm, '');
this._textFormats = [this.newTextFormat];
this._textFormatsIdx = [this._iText.length];
this._textDirty = true;
//console.log("set text", value, "on" , this);
this.invalidate();
},
enumerable: false,
configurable: true
});
TextField.prototype.setLabelData = function (labelData) {
this._labelData = labelData;
this.isStatic = true;
this._iText = '';
this._iTextWoLineBreaks = '';
this._textDirty = false;
this._positionsDirty = false;
this._glyphsDirty = true;
this.invalidate();
};
Object.defineProperty(TextField.prototype, "newTextFormat", {
get: function () {
return this._newTextFormat.clone();
},
set: function (value) {
if (!value)
throw new Error('TextField::: set newTextFormat - no value!');
if (value.equal(this._newTextFormat))
return;
this._newTextFormat = value.clone();
this._newFormatDirty = true;
this._textShapesDirty = true;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "scaleX", {
/**
* Indicates the horizontal scale(percentage) of the object as applied from
* the registration point. The default registration point is(0,0). 1.0
* equals 100% scale.
*
* <p>Scaling the local coordinate system changes the <code>x</code> and
* <code>y</code> property values, which are defined in whole pixels. </p>
*/
get: function () {
return this._transform.scale.x;
},
set: function (val) {
if (this._transform.scale.x == val) {
return;
}
this._setScaleX(val);
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "scaleY", {
/**
* Indicates the vertical scale(percentage) of an object as applied from the
* registration point of the object. The default registration point is(0,0).
* 1.0 is 100% scale.
*
* <p>Scaling the local coordinate system changes the <code>x</code> and
* <code>y</code> property values, which are defined in whole pixels. </p>
*/
get: function () {
return this._transform.scale.y;
},
set: function (val) {
if (this._transform.scale.y == val) {
return;
}
this._setScaleY(val);
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "textColor", {
get: function () {
return this._textColor;
},
set: function (value) {
if (this._textColor == value) {
return;
}
this._textColor = value;
//this._textFormat.color=value;
if (this._textFormats) {
var i = this._textFormats.length;
while (i > 0) {
i--;
if (this._textFormats[i])
this._textFormats[i].color = value;
}
this._textDirty = true;
}
/*if (this._textFormat
&& !this._textFormat.font_table.isAsset(TesselatedFontTable)
&& !this._textFormat.material) {
if (!this.transform.colorTransform)
this.transform.colorTransform = new ColorTransform();
this.transform.colorTransform.color = value;
this._invalidateHierarchicalProperties(HierarchicalProperties.COLOR_TRANSFORM);
} else {
this._glyphsDirty = true;
if (this._implicitPartition)
this._implicitPartition.invalidateEntity(this);
//}*/
this._glyphsDirty = true;
this.invalidate();
},
enumerable: false,
configurable: true
});
TextField.prototype.getTextColorForTextFormat = function (format) {
if (format.hasPropertySet('color')) {
return format.color;
}
return this._textColor;
};
Object.defineProperty(TextField.prototype, "textInteractionMode", {
/**
* The interaction mode property, Default value is
* TextInteractionMode.NORMAL. On mobile platforms, the normal mode implies
* that the text can be scrolled but not selected. One can switch to the
* selectable mode through the in-built context menu on the text field. On
* Desktop, the normal mode implies that the text is in scrollable as well as
* selection mode.
*/
get: function () {
return this._textInteractionMode;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "textWidth", {
/**
* The width of the text in pixels.
*/
get: function () {
this.reConstruct();
return this._textWidth;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "textHeight", {
/**
* The width of the text in pixels.
*/
get: function () {
this.reConstruct();
if (this.type == TextFieldType.INPUT && this._iText == '') {
this._newTextFormat.font_table.initFontSize(this._newTextFormat.size);
return this._newTextFormat.font_table.getLineHeight();
}
return this._textHeight;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "type", {
get: function () {
return this._type;
},
set: function (value) {
if (this._type == value)
return;
this._type = value;
this._textDirty = true;
if (value == TextFieldType.INPUT) {
//this._selectable=true;
this.enableInput(true);
this.addEventListener(KeyboardEvent.KEYDOWN, this.onKeyDelegate);
}
else {
this.enableInput(false);
this.removeEventListener(KeyboardEvent.KEYDOWN, this.onKeyDelegate);
}
this.invalidate();
},
enumerable: f