UNPKG

@awayjs/scene

Version:
1,226 lines (1,223 loc) 131 kB
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: /&apos;/g, replace: '\'' }, { test: /&gt;/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