@awayfl/avm2
Version:
Virtual machine for executing AS3 code
267 lines (266 loc) • 8.7 kB
JavaScript
/**
* 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(''');
break;
case XMLSpecialChars.AMP:
parts.push('&');
break;
case XMLSpecialChars.QUOT:
parts.push('"');
break;
case XMLSpecialChars.LT:
parts.push('<');
break;
case XMLSpecialChars.GT:
parts.push('>');
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 };