UNPKG

@awayfl/avm2

Version:

Virtual machine for executing AS3 code

267 lines (266 loc) 8.7 kB
/** * Copyright 2015 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { __extends } from "tslib"; import { XMLParserBase } from './xml'; import { ASObject } from '../nat/ASObject'; import { warning } from '@awayfl/swf-loader'; import { axCoerceString } from '../run/axCoerceString'; var XMLSpecialChars; (function (XMLSpecialChars) { XMLSpecialChars[XMLSpecialChars["APOS"] = 39] = "APOS"; XMLSpecialChars[XMLSpecialChars["AMP"] = 38] = "AMP"; XMLSpecialChars[XMLSpecialChars["QUOT"] = 34] = "QUOT"; XMLSpecialChars[XMLSpecialChars["LT"] = 60] = "LT"; XMLSpecialChars[XMLSpecialChars["GT"] = 62] = "GT"; })(XMLSpecialChars || (XMLSpecialChars = {})); var XMLNode = /** @class */ (function (_super) { __extends(XMLNode, _super); function XMLNode(type /*uint*/, value) { type = type >>> 0; value = axCoerceString(value); return _super.call(this) || this; } // Static JS -> AS Bindings // Static AS -> JS Bindings XMLNode.escapeXML = function (value) { value = axCoerceString(value); var length = value.length; var i = 0, ch; while (i < length) { ch = value.charCodeAt(i); if (ch === XMLSpecialChars.APOS || ch === XMLSpecialChars.AMP || ch === XMLSpecialChars.QUOT || ch === XMLSpecialChars.LT || ch === XMLSpecialChars.GT) { break; } i++; } if (i >= length) { return value; } var parts = [value.substring(0, i)]; while (i < length) { switch (ch) { case XMLSpecialChars.APOS: parts.push('&apos;'); break; case XMLSpecialChars.AMP: parts.push('&amp;'); break; case XMLSpecialChars.QUOT: parts.push('&quot;'); break; case XMLSpecialChars.LT: parts.push('&lt;'); break; case XMLSpecialChars.GT: parts.push('&gt;'); break; } ++i; var j = i; while (i < length) { ch = value.charCodeAt(i); if (ch === XMLSpecialChars.APOS || ch === XMLSpecialChars.AMP || ch === XMLSpecialChars.QUOT || ch === XMLSpecialChars.LT || ch === XMLSpecialChars.GT) { break; } i++; } if (j < i) { parts.push(value.substring(j, i)); } } return parts.join(''); }; return XMLNode; }(ASObject)); export { XMLNode }; var XMLDocument = /** @class */ (function (_super) { __extends(XMLDocument, _super); function XMLDocument(text) { if (text === void 0) { text = null; } text = axCoerceString(text); return _super.call(this, 1, '') || this; } return XMLDocument; }(XMLNode)); export { XMLDocument }; var XMLTag = /** @class */ (function (_super) { __extends(XMLTag, _super); function XMLTag() { var _this = _super.call(this) || this; _this._type = 0; _this._value = null; _this._empty = false; _this._attrs = null; return _this; } Object.defineProperty(XMLTag.prototype, "type", { // Static JS -> AS Bindings // Static AS -> JS Bindings // Instance JS -> AS Bindings // Instance AS -> JS Bindings get: function () { return this._type; }, set: function (value /*uint*/) { value = value >>> 0; this._type = value; }, enumerable: false, configurable: true }); Object.defineProperty(XMLTag.prototype, "empty", { get: function () { return this._empty; }, set: function (value) { value = !!value; this._empty = value; }, enumerable: false, configurable: true }); Object.defineProperty(XMLTag.prototype, "value", { get: function () { return this._value; }, set: function (v) { v = axCoerceString(v); this._value = v; }, enumerable: false, configurable: true }); Object.defineProperty(XMLTag.prototype, "attrs", { get: function () { return this._attrs; }, set: function (value) { this._attrs = value; }, enumerable: false, configurable: true }); return XMLTag; }(ASObject)); export { XMLTag }; var XMLNodeType = /** @class */ (function (_super) { __extends(XMLNodeType, _super); function XMLNodeType() { return _super.call(this) || this; } return XMLNodeType; }(ASObject)); export { XMLNodeType }; function isWhitespace(s) { for (var i = 0; i < s.length; i++) { var ch = s[i]; if (!(ch === ' ' || ch === '\n' || ch === '\r' || ch === '\t')) { return false; } } return true; } var XMLParserForXMLDocument = /** @class */ (function (_super) { __extends(XMLParserForXMLDocument, _super); function XMLParserForXMLDocument(sec) { var _this = _super.call(this) || this; _this.sec = sec; _this.queue = []; _this.ignoreWhitespace = false; return _this; } XMLParserForXMLDocument.prototype.onError = function (code) { this.queue.push(code); }; XMLParserForXMLDocument.prototype.onPi = function (name, value) { warning('Unhandled XMLParserForXMLDocument.onPi'); }; XMLParserForXMLDocument.prototype.onComment = function (text) { warning('Unhandled XMLParserForXMLDocument.onComment'); }; XMLParserForXMLDocument.prototype.onCdata = function (text) { this.queue.push({ type: 4, value: text }); }; XMLParserForXMLDocument.prototype.onDoctype = function (doctypeContent) { warning('Unhandled XMLParserForXMLDocument.onDoctype'); }; XMLParserForXMLDocument.prototype.onBeginElement = function (name, attributes, isEmpty) { var attrObj = this.sec.createObject(); attributes.forEach(function (a) { attrObj.axSetPublicProperty(a.name, a.value); }); this.queue.push({ type: 1, value: name, empty: isEmpty, attrs: attrObj }); }; XMLParserForXMLDocument.prototype.onEndElement = function (name) { this.queue.push({ type: 1, value: '/' + name }); }; XMLParserForXMLDocument.prototype.onText = function (text) { if (this.ignoreWhitespace && isWhitespace(text)) { return; } this.queue.push({ type: 3, value: text }); }; return XMLParserForXMLDocument; }(XMLParserBase)); var XMLParser = /** @class */ (function (_super) { __extends(XMLParser, _super); function XMLParser() { return _super.call(this) || this; } XMLParser.prototype.startParse = function (source, ignoreWhite) { source = axCoerceString(source); ignoreWhite = !!ignoreWhite; var parser = new XMLParserForXMLDocument(this.sec); parser.ignoreWhitespace = ignoreWhite; parser.parseXml(source); this.queue = parser.queue; }; XMLParser.prototype.getNext = function (tag) { if (this.queue.length === 0) { return -1 /* XMLParserErrorCode.EndOfDocument */; } var nextItem = this.queue.shift(); if (typeof nextItem === 'number') { return nextItem; } var parseResult = nextItem; tag.type = parseResult.type; tag.value = parseResult.value; tag.empty = parseResult.empty || false; tag.attrs = parseResult.attrs || null; return 0 /* XMLParserErrorCode.NoError */; }; return XMLParser; }(ASObject)); export { XMLParser };