var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var Activator; (function (Activator) { /** * @param properties 如果这个属性定义集合是一个object,则应该是一个IProperty接口的字典对象 */ function CreateInstance(properties) { var target = Object.create({}); var propertyInfo; if (Array.isArray(properties)) { for (var _i = 0, _a = properties; _i < _a.length; _i++) { var property = _a[_i]; propertyInfo = property.value; Object.defineProperty(target, property.name, { get: propertyInfo.get, set: propertyInfo.set }); } } else { for (var name_1 in properties) { propertyInfo = properties[name_1]; Object.defineProperty(target, name_1, { get: propertyInfo.get, set: propertyInfo.set }); } } return target; } Activator.CreateInstance = CreateInstance; /** * 利用一个名称字符串集合创建一个js对象 * * @param names object的属性名称列表 * @param init 使用这个函数为该属性指定一个初始值 */ function EmptyObject(names, init) { var obj = {}; if (typeof init == "function") { // 通过函数来进行初始化,则每一个属性值可能会不一样 // 例如使用随机数函数来初始化 var create_1 = init; if (Array.isArray(names)) { names.forEach(function (name) { return obj[name] = create_1(); }); } else { names.ForEach(function (name) { return obj[name] = create_1(); }); } } else { // 直接是一个值的时候,则所有的属性值都是一样的 if (Array.isArray(names)) { names.forEach(function (name) { return obj[name] = init; }); } else { names.ForEach(function (name) { return obj[name] = init; }); } } return obj; } Activator.EmptyObject = EmptyObject; /** * 从键值对集合创建object对象,键名或者名称属性会作为object对象的属性名称 */ function CreateObject(nameValues) { var obj = {}; var type = TypeInfo.typeof(nameValues); if (type.IsArray && type.class == "MapTuple") { nameValues.forEach(function (map) { return obj[map.key] = map.value; }); } else if (type.IsArray && type.class == "NamedValue") { nameValues.forEach(function (nv) { return obj[nv.name] = nv.value; }); } else if (type.class == "IEnumerator") { var seq = nameValues; type = seq.ElementType; if (type.class == "MapTuple") { nameValues .ForEach(function (map) { obj[map.key] = map.value; }); } else if (type.class == "NamedValue") { nameValues .ForEach(function (nv) { obj[nv.name] = nv.value; }); } else { console.error(type); throw "Unsupport data type: " + type.class; } } else { throw "Unsupport data type: " + JSON.stringify(type); } return obj; } Activator.CreateObject = CreateObject; })(Activator || (Activator = {})); var data; (function (data) { var sprintf; (function (sprintf) { /** * 对占位符的匹配结果 */ var match = /** @class */ (function () { function match() { } match.prototype.toString = function () { return JSON.stringify(this); }; return match; }()); sprintf.match = match; /** * 格式化占位符 * * Possible format values: * * + ``%%`` – Returns a percent sign * + ``%b`` – Binary number * + ``%c`` – The character according to the ASCII value * + ``%d`` – Signed decimal number * + ``%f`` – Floating-point number * + ``%o`` – Octal number * + ``%s`` – String * + ``%x`` – Hexadecimal number (lowercase letters) * + ``%X`` – Hexadecimal number (uppercase letters) * * Additional format values. These are placed between the % and the letter (example %.2f): * * + ``+`` (Forces both + and – in front of numbers. By default, only negative numbers are marked) * + ``–`` (Left-justifies the variable value) * + ``0`` zero will be used for padding the results to the right string size * + ``[0-9]`` (Specifies the minimum width held of to the variable value) * + ``.[0-9]`` (Specifies the number of decimal digits or maximum string length) * */ sprintf.placeholder = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g); /** * @param argumentList ERROR - "arguments" cannot be redeclared in strict mode */ function parseFormat(string, argumentList) { var stringPosStart = 0; var stringPosEnd = 0; var matchPosEnd = 0; var convCount = 0; var match = null; var matches = []; var strings = []; while (match = sprintf.placeholder.exec(string)) { stringPosStart = matchPosEnd; stringPosEnd = sprintf.placeholder.lastIndex - match[0].length; strings[strings.length] = string.substring(stringPosStart, stringPosEnd); matchPosEnd = sprintf.placeholder.lastIndex; matches[matches.length] = { match: match[0], left: match[3] ? true : false, sign: match[4] || '', pad: match[5] || ' ', min: match[6] || 0, precision: match[8], code: match[9] || '%', negative: parseInt(argumentList[convCount]) < 0 ? true : false, argument: String(argumentList[convCount]) }; if (match[9]) { convCount += 1; } } strings[strings.length] = string.substring(matchPosEnd); return { matches: matches, convCount: convCount, strings: strings }; } sprintf.parseFormat = parseFormat; /** * ### Javascript sprintf * * > http://www.webtoolkit.info/javascript-sprintf.html#.W5sf9FozaM8 * * Several programming languages implement a sprintf function, to output a * formatted string. It originated from the C programming language, printf * function. Its a string manipulation function. * * This is limited sprintf Javascript implementation. Function returns a * string formatted by the usual printf conventions. See below for more details. * You must specify the string and how to format the variables in it. */ function doFormat(format) { var argv = []; for (var _i = 1; _i < arguments.length; _i++) { argv[_i - 1] = arguments[_i]; } if (typeof arguments == "undefined") { return null; } if (arguments.length < 1) { return null; } if (typeof arguments[0] != "string") { return null; } if (typeof RegExp == "undefined") { return null; } var parsed = sprintf.parseFormat(format, argv); var convCount = parsed.convCount; if (parsed.matches.length == 0) { // 没有格式化参数的占位符,则直接输出原本的字符串 return format; } else { // console.log(parsed); } if (argv.length < convCount) { // 格式化参数的数量少于占位符的数量,则抛出错误 throw "Mismatch format argument numbers (" + argv.length + " !== " + convCount + ")!"; } else { return sprintf.doSubstitute(parsed.matches, parsed.strings); } } sprintf.doFormat = doFormat; /** * 进行格式化占位符对格式化参数的字符串替换操作 */ function doSubstitute(matches, strings) { var i = null; var substitution = null; var numVal = 0; var newString = ''; for (i = 0; i < matches.length; i++) { if (matches[i].code == '%') { substitution = '%'; } else if (matches[i].code == 'b') { matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2)); substitution = sprintf.convert(matches[i], true); } else if (matches[i].code == 'c') { numVal = Math.abs(parseInt(matches[i].argument)); matches[i].argument = String(String.fromCharCode(parseInt(String(numVal)))); substitution = sprintf.convert(matches[i], true); } else if (matches[i].code == 'd') { matches[i].argument = String(Math.abs(parseInt(matches[i].argument))); substitution = sprintf.convert(matches[i]); } else if (matches[i].code == 'f') { numVal = matches[i].precision ? parseFloat(matches[i].precision) : 6; matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(numVal)); substitution = sprintf.convert(matches[i]); } else if (matches[i].code == 'o') { matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8)); substitution = sprintf.convert(matches[i]); } else if (matches[i].code == 's') { numVal = matches[i].precision ? parseFloat(matches[i].precision) : matches[i].argument.length; matches[i].argument = matches[i].argument.substring(0, numVal); substitution = sprintf.convert(matches[i], true); } else if (matches[i].code == 'x') { matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); substitution = sprintf.convert(matches[i]); } else if (matches[i].code == 'X') { matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); substitution = sprintf.convert(matches[i]).toUpperCase(); } else { substitution = matches[i].match; } newString += strings[i]; newString += substitution; } return newString + strings[i]; } sprintf.doSubstitute = doSubstitute; function convert(match, nosign) { if (nosign === void 0) { nosign = false; } if (nosign) { match.sign = ''; } else { match.sign = match.negative ? '-' : match.sign; } var l = parseFloat(match.min) - match.argument.length + 1 - match.sign.length; var pad = new Array(l < 0 ? 0 : l).join(match.pad); if (!match.left) { if (match.pad == "0" || nosign) { return match.sign + pad + match.argument; } else { return pad + match.sign + match.argument; } } else { if (match.pad == "0" || nosign) { return match.sign + match.argument + pad.replace(/0/g, ' '); } else { return match.sign + match.argument + pad; } } } sprintf.convert = convert; })(sprintf = data.sprintf || (data.sprintf = {})); })(data || (data = {})); /** * 可用于ES6的for循环的泛型迭代器对象,这个也是这个框架之中的所有序列模型的基础 * * ```js * var it = makeIterator(['a', 'b']); * * it.next() // { value: "a", done: false } * it.next() // { value: "b", done: false } * it.next() // { value: undefined, done: true } * * function makeIterator(array) { * var nextIndex = 0; * * return { * next: function() { * return nextIndex < array.length ? * {value: array[nextIndex++], done: false} : * {value: undefined, done: true}; * } * }; * } * ``` */ var LINQIterator = /** @class */ (function () { function LINQIterator(array) { this.i = 0; this.sequence = array; } /** * 实现迭代器的关键元素之1 */ LINQIterator.prototype[Symbol.iterator] = function () { return this; }; Object.defineProperty(LINQIterator.prototype, "Count", { /** * The number of elements in the data sequence. */ get: function () { return this.sequence.length; }, enumerable: true, configurable: true }); LINQIterator.prototype.reset = function () { this.i = 0; return this; }; /** * 实现迭代器的关键元素之2 */ LINQIterator.prototype.next = function () { return this.i < this.sequence.length ? { value: this.sequence[this.i++], done: false } : { value: undefined, done: true }; }; return LINQIterator; }()); //// /** * The linq pipline implements at here. (在这个模块之中实现具体的数据序列算法) */ var Enumerable; (function (Enumerable) { function Range(from, to, steps) { if (steps === void 0) { steps = 1; } return new data.NumericRange(from, to).PopulateNumbers(steps); } Enumerable.Range = Range; function Min() { var v = []; for (var _i = 0; _i < arguments.length; _i++) { v[_i] = arguments[_i]; } var min = 99999999999; for (var _a = 0, v_1 = v; _a < v_1.length; _a++) { var x = v_1[_a]; if (x < min) { min = x; } } return min; } Enumerable.Min = Min; /** * 进行数据序列的投影操作 * */ function Select(source, project) { var projections = []; source.forEach(function (o, i) { projections.push(project(o, i)); }); return new IEnumerator(projections); } Enumerable.Select = Select; /** * 进行数据序列的排序操作 * */ function OrderBy(source, key) { // array clone var clone = source.slice(); clone.sort(function (a, b) { // a - b return key(a) - key(b); }); // console.log("clone"); // console.log(clone); return new IEnumerator(clone); } Enumerable.OrderBy = OrderBy; function OrderByDescending(source, key) { return Enumerable.OrderBy(source, function (e) { // b - a return -key(e); }); } Enumerable.OrderByDescending = OrderByDescending; function Take(source, n) { var takes = []; var len = source.length; if (len <= n) { takes = source; } else { takes = []; for (var i = 0; i < n; i++) { if (i >= len) { break; } else { takes.push(source[i]); } } } return new IEnumerator(takes); } Enumerable.Take = Take; function Skip(source, n) { var takes = []; if (n >= source.length) { return new IEnumerator([]); } for (var i = n; i < source.length; i++) { takes.push(source[i]); } return new IEnumerator(takes); } Enumerable.Skip = Skip; function TakeWhile(source, predicate) { var takes = []; for (var i = 0; i < source.length; i++) { if (predicate(source[i])) { takes.push(source[i]); } else { break; } } return new IEnumerator(takes); } Enumerable.TakeWhile = TakeWhile; function Where(source, predicate) { var takes = []; source.forEach(function (o) { if (true == predicate(o)) { takes.push(o); } }); return new IEnumerator(takes); } Enumerable.Where = Where; function SkipWhile(source, predicate) { for (var i = 0; i < source.length; i++) { if (true == predicate(source[i])) { // skip } else { // end skip return Enumerable.Skip(source, i); } } // skip all return new IEnumerator([]); } Enumerable.SkipWhile = SkipWhile; function All(source, predicate) { for (var i = 0; i < source.length; i++) { if (!predicate(source[i])) { return false; } } return true; } Enumerable.All = All; function Any(source, predicate) { for (var i = 0; i < source.length; i++) { if (true == predicate(source[i])) { return true; } } return false; } Enumerable.Any = Any; /** * Implements a ``group by`` operation by binary tree data structure. */ function GroupBy(source, getKey, compares) { var tree = new algorithm.BTree.binaryTree(compares); source.forEach(function (obj) { var key = getKey(obj); var list = tree.find(key); if (list) { list.push(obj); } else { tree.add(key, [obj]); } }); console.log(tree); return tree.AsEnumerable().Select(function (node) { return new Group(node.key, node.value); }); } Enumerable.GroupBy = GroupBy; function AllKeys(sequence) { return From(sequence) .Select(function (o) { return Object.keys(o); }) .Unlist() .Distinct() .ToArray(); } Enumerable.AllKeys = AllKeys; var JoinHelper = /** @class */ (function () { function JoinHelper(x, y) { this.xset = x; this.yset = y; this.keysT = AllKeys(x); this.keysU = AllKeys(y); } JoinHelper.prototype.JoinProject = function (x, y) { var out = {}; this.keysT.forEach(function (k) { return out[k] = x[k]; }); this.keysU.forEach(function (k) { return out[k] = y[k]; }); return out; }; JoinHelper.prototype.Union = function (tKey, uKey, compare, project) { if (project === void 0) { project = this.JoinProject; } var tree = this.buildUtree(uKey, compare); var output = []; var keyX = new algorithm.BTree.binaryTree(compare); this.xset.forEach(function (x) { var key = tKey(x); var list = tree.find(key); if (list) { // 有交集,则进行叠加投影 list.forEach(function (y) { return output.push(project(x, y)); }); if (!keyX.find(key)) { keyX.add(key); } } else { // 没有交集,则投影空对象 output.push(project(x, {})); } }); this.yset.forEach(function (y) { var key = uKey(y); if (!keyX.find(key)) { // 没有和X进行join,则需要union到最终的结果之中 // 这个y是找不到对应的x元素的 output.push(project({}, y)); } }); return new IEnumerator(output); }; JoinHelper.prototype.buildUtree = function (uKey, compare) { var tree = new algorithm.BTree.binaryTree(compare); this.yset.forEach(function (obj) { var key = uKey(obj); var list = tree.find(key); if (list) { list.push(obj); } else { tree.add(key, [obj]); } }); return tree; }; JoinHelper.prototype.LeftJoin = function (tKey, uKey, compare, project) { if (project === void 0) { project = this.JoinProject; } var tree = this.buildUtree(uKey, compare); var output = []; this.xset.forEach(function (x) { var key = tKey(x); var list = tree.find(key); if (list) { // 有交集,则进行叠加投影 list.forEach(function (y) { return output.push(project(x, y)); }); } else { // 没有交集,则投影空对象 output.push(project(x, {})); } }); return new IEnumerator(output); }; return JoinHelper; }()); Enumerable.JoinHelper = JoinHelper; })(Enumerable || (Enumerable = {})); /// /// /** * Provides a set of static (Shared in Visual Basic) methods for querying * objects that implement ``System.Collections.Generic.IEnumerable``. * * (这个枚举器类型是构建出一个Linq查询表达式所必须的基础类型,这是一个静态的集合,不会发生元素的动态添加或者删除) */ var IEnumerator = /** @class */ (function (_super) { __extends(IEnumerator, _super); //#endregion /** * 可以从一个数组或者枚举器构建出一个Linq序列 * * @param source The enumerator data source, this constructor will perform * a sequence copy action on this given data source sequence at here. */ function IEnumerator(source) { return _super.call(this, IEnumerator.getArray(source)) || this; } Object.defineProperty(IEnumerator.prototype, "ElementType", { //#region "readonly property" /** * 获取序列的元素类型 */ get: function () { return TypeInfo.typeof(this.First); }, enumerable: true, configurable: true }); ; /** * Get the element value at a given index position * of this data sequence. * * @param index index value should be an integer value. */ IEnumerator.prototype.ElementAt = function (index) { if (index === void 0) { index = null; } if (!index) { index = 0; } else if (typeof index == "string") { throw "Item index='" + index + "' must be an integer!"; } return this.sequence[index]; }; IEnumerator.getArray = function (source) { if (!source) { return []; } else if (Array.isArray(source)) { // 2018-07-31 为了防止外部修改source导致sequence数组被修改 // 在这里进行数组复制,防止出现这种情况 return source.slice(); } else { return source.sequence.slice(); } }; IEnumerator.prototype.indexOf = function (x) { return this.sequence.indexOf(x); }; Object.defineProperty(IEnumerator.prototype, "First", { /** * Get the first element in this sequence */ get: function () { return this.sequence[0]; }, enumerable: true, configurable: true }); Object.defineProperty(IEnumerator.prototype, "Last", { /** * Get the last element in this sequence */ get: function () { return this.sequence[this.Count - 1]; }, enumerable: true, configurable: true }); /** * If the sequence length is zero, then returns the default value. */ IEnumerator.prototype.FirstOrDefault = function (Default) { if (Default === void 0) { Default = null; } if (this.Count == 0) { return Default; } else { return this.sequence[0]; } }; /** * 两个序列求总和 */ IEnumerator.prototype.Union = function (another, tKey, uKey, compare, project) { if (project === void 0) { project = null; } if (!Array.isArray(another)) { another = another.ToArray(); } var join = new Enumerable.JoinHelper(this.sequence, another); return join.Union(tKey, uKey, compare, project); }; /** * 如果在another序列之中找不到对应的对象,则当前序列会和一个空对象合并 * 如果another序列之中有多余的元素,即该元素在当前序列之中找不到的元素,会被扔弃 * * @param project 如果这个参数被忽略掉了的话,将会直接进行属性的合并 */ IEnumerator.prototype.Join = function (another, tKey, uKey, compare, project) { if (project === void 0) { project = null; } if (!Array.isArray(another)) { another = another.ToArray(); } var join = new Enumerable.JoinHelper(this.sequence, another); return join.LeftJoin(tKey, uKey, compare, project); }; /** * Projects each element of a sequence into a new form. * * @typedef TOut The type of the value returned by selector. * * @param selector A transform function to apply to each element. * * @returns An ``System.Collections.Generic.IEnumerable`` * whose elements are the result of invoking the * transform function on each element of source. */ IEnumerator.prototype.Select = function (selector) { return Enumerable.Select(this.sequence, selector); }; /** * Groups the elements of a sequence according to a key selector function. * The keys are compared by using a comparer and each group's elements * are projected by using a specified function. * * @param compares 注意,javascript在进行中文字符串的比较的时候存在bug,如果当key的类型是字符串的时候, * 在这里需要将key转换为数值进行比较,遇到中文字符串可能会出现bug */ IEnumerator.prototype.GroupBy = function (keySelector, compares) { if (isNullOrUndefined(compares)) { var x = keySelector(this.First); switch (typeof x) { case "string": compares = Strings.CompareTo; break; case "number": compares = (function (x, y) { return x - y; }); break; case "boolean": compares = (function (x, y) { if (x == y) { return 0; } // 有一个肯定是false if (x == true) { return 1; } else { return -1; } }); break; default: throw "No element comparer was specific!"; } } return Enumerable.GroupBy(this.sequence, keySelector, compares); }; /** * Filters a sequence of values based on a predicate. * * @param predicate A test condition function. * * @returns Sub sequence of the current sequence with all * element test pass by the ``predicate`` function. */ IEnumerator.prototype.Where = function (predicate) { return Enumerable.Where(this.sequence, predicate); }; IEnumerator.prototype.Which = function (predicate, first) { if (first === void 0) { first = true; } var index; if (!first) { index = []; } for (var i = 0; i < this.sequence.length; i++) { if (predicate(this.sequence[i])) { if (first) { return i; } else { index.push(i); } } } return new IEnumerator(index); }; /** * Get the min value in current sequence. * (求取这个序列集合的最小元素,使用这个函数要求序列之中的元素都必须能够被转换为数值) */ IEnumerator.prototype.Min = function (project) { if (project === void 0) { project = function (e) { return DataExtensions.as_numeric(e); }; } return Enumerable.OrderBy(this.sequence, project).First; }; /** * Get the max value in current sequence. * (求取这个序列集合的最大元素,使用这个函数要求序列之中的元素都必须能够被转换为数值) */ IEnumerator.prototype.Max = function (project) { if (project === void 0) { project = function (e) { return DataExtensions.as_numeric(e); }; } return Enumerable.OrderByDescending(this.sequence, project).First; }; /** * 求取这个序列集合的平均值,使用这个函数要求序列之中的元素都必须能够被转换为数值 */ IEnumerator.prototype.Average = function (project) { if (project === void 0) { project = null; } if (this.Count == 0) { return 0; } else { return this.Sum(project) / this.sequence.length; } }; /** * 求取这个序列集合的和,使用这个函数要求序列之中的元素都必须能够被转换为数值 */ IEnumerator.prototype.Sum = function (project) { if (project === void 0) { project = null; } var x = 0; if (!project) project = function (e) { return Number(e); }; for (var i = 0; i < this.sequence.length; i++) { x += project(this.sequence[i]); } return x; }; /** * Sorts the elements of a sequence in ascending order according to a key. * * @param key A function to extract a key from an element. * * @returns An ``System.Linq.IOrderedEnumerable`` whose elements are * sorted according to a key. */ IEnumerator.prototype.OrderBy = function (key) { return Enumerable.OrderBy(this.sequence, key); }; /** * Sorts the elements of a sequence in descending order according to a key. * * @param key A function to extract a key from an element. * * @returns An ``System.Linq.IOrderedEnumerable`` whose elements are * sorted in descending order according to a key. */ IEnumerator.prototype.OrderByDescending = function (key) { return Enumerable.OrderByDescending(this.sequence, key); }; /** * Split a sequence by elements count */ IEnumerator.prototype.Split = function (size) { var seq = []; var row = []; for (var _i = 0, _a = this.sequence; _i < _a.length; _i++) { var element = _a[_i]; if (row.length < size) { row.push(element); } else { seq.push(row); row = []; } } if (row.length > 0) { seq.push(row); } return new IEnumerator(seq); }; /** * 取出序列之中的前n个元素 */ IEnumerator.prototype.Take = function (n) { return Enumerable.Take(this.sequence, n); }; /** * 跳过序列的前n个元素之后返回序列之中的所有剩余元素 */ IEnumerator.prototype.Skip = function (n) { return Enumerable.Skip(this.sequence, n); }; /** * 序列元素的位置反转 */ IEnumerator.prototype.Reverse = function () { var rseq = this.ToArray().reverse(); var seq = new IEnumerator(rseq); return seq; }; /** * Returns elements from a sequence as long as a specified condition is true. * (与Where类似,只不过这个函数只要遇到第一个不符合条件的,就会立刻终止迭代) */ IEnumerator.prototype.TakeWhile = function (predicate) { return Enumerable.TakeWhile(this.sequence, predicate); }; /** * Bypasses elements in a sequence as long as a specified condition is true * and then returns the remaining elements. */ IEnumerator.prototype.SkipWhile = function (predicate) { return Enumerable.SkipWhile(this.sequence, predicate); }; /** * 判断这个序列之中的所有元素是否都满足特定条件 */ IEnumerator.prototype.All = function (predicate) { return Enumerable.All(this.sequence, predicate); }; /** * 判断这个序列之中的任意一个元素是否满足特定的条件 */ IEnumerator.prototype.Any = function (predicate) { if (predicate === void 0) { predicate = null; } if (predicate) { return Enumerable.Any(this.sequence, predicate); } else { if (!this.sequence || this.sequence.length == 0) { return false; } else { return true; } } }; /** * 对序列中的元素进行去重 */ IEnumerator.prototype.Distinct = function (key) { if (key === void 0) { key = function (o) { return o.toString(); }; } return this .GroupBy(key, Strings.CompareTo) .Select(function (group) { return group.First; }); }; /** * 将序列按照符合条件的元素分成区块 * * @param isDelimiter 一个用于判断当前的元素是否是分割元素的函数 * @param reserve 是否保留下这个分割对象?默认不保留 */ IEnumerator.prototype.ChunkWith = function (isDelimiter, reserve) { if (reserve === void 0) { reserve = false; } var chunks = new List(); var buffer = []; this.sequence.forEach(function (x) { if (isDelimiter(x)) { chunks.Add(buffer); if (reserve) { buffer = [x]; } else { buffer = []; } } else { buffer.push(x); } }); if (buffer.length > 0) { chunks.Add(buffer); } return chunks; }; /** * Performs the specified action for each element in an array. * * @param callbackfn A function that accepts up to three arguments. forEach * calls the callbackfn function one time for each element in the array. * */ IEnumerator.prototype.ForEach = function (callbackfn) { this.sequence.forEach(callbackfn); }; /** * Contract the data sequence to string * * @param deli Delimiter string that using for the string.join function * @param toString A lambda that describ how to convert the generic type object to string token * * @returns A contract string. */ IEnumerator.prototype.JoinBy = function (deli, toString) { if (toString === void 0) { toString = function (x) { if (typeof x === "string") { return x; } else { return x.toString(); } }; } return this.Select(function (x) { return toString(x); }) .ToArray() .join(deli); }; /** * 如果当前的这个数据序列之中的元素的类型是某一种元素类型的集合,或者该元素 * 可以描述为另一种类型的元素的集合,则可以通过这个函数来进行降维操作处理。 * * @param project 这个投影函数描述了如何将某一种类型的元素降维至另外一种元素类型的集合。 * 如果这个函数被忽略掉的话,会尝试强制将当前集合的元素类型转换为目标元素类型的数组集合。 */ IEnumerator.prototype.Unlist = function (project) { if (project === void 0) { project = function (obj) { return obj; }; } var list = []; this.ForEach(function (a) { project(a).forEach(function (x) { return list.push(x); }); }); return new IEnumerator(list); }; //#region "conversion" /** * This function returns a clone copy of the source sequence. * * @param clone If this parameter is false, then this function will * returns the origin array sequence directly. */ IEnumerator.prototype.ToArray = function (clone) { if (clone === void 0) { clone = true; } if (clone) { return this.sequence.slice(); } else { return this.sequence; } }; /** * 将当前的这个不可变的只读序列对象转换为可动态增添删除元素的列表对象 */ IEnumerator.prototype.ToList = function () { return new List(this.sequence); }; /** * 将当前的这个数据序列对象转换为键值对字典对象,方便用于数据的查找操作 */ IEnumerator.prototype.ToDictionary = function (keySelector, elementSelector) { if (elementSelector === void 0) { elementSelector = function (X) { return X; }; } var maps = {}; this.sequence.forEach(function (x) { // 2018-08-11 键名只能够是字符串类型的 var key = keySelector(x); var value = elementSelector(x); maps[key] = value; }); return new Dictionary(maps); }; /** * 将当前的这个数据序列转换为包含有内部位置指针数据的指针对象 */ IEnumerator.prototype.ToPointer = function () { return new Pointer(this); }; /** * 将当前的这个序列转换为一个滑窗数据的集合 */ IEnumerator.prototype.SlideWindows = function (winSize, step) { if (step === void 0) { step = 1; } return SlideWindow.Split(this, winSize, step); }; return IEnumerator; }(LINQIterator)); /// // 2018-12-06 // 为了方便书写代码,在其他脚本之中添加变量类型申明,在这里就不进行命名空间的包裹了 // /** // * Creates an instance of the element for the specified tag. // * @param tagName The name of an element. // */ // createElement(tagName: K, options ?: ElementCreationOptions): HTMLElementTagNameMap[K]; var DOMEnumerator = /** @class */ (function (_super) { __extends(DOMEnumerator, _super); /** * 1. IEnumerator * 2. NodeListOf * 3. HTMLCollection */ function DOMEnumerator(elements) { return _super.call(this, DOMEnumerator.ensureElements(elements)) || this; } /** * 这个函数确保所传递进来的集合总是输出一个数组,方便当前的集合对象向其基类型传递数据源 */ DOMEnumerator.ensureElements = function (elements) { var type = TypeInfo.typeof(elements); var list; /** * TypeInfo {typeOf: "object", class: "NodeList", property: Array(2), methods: Array(5)} * IsArray: false * IsEnumerator: false * IsPrimitive: false * class: "NodeList" * methods: (5) ["item", "entries", "forEach", "keys", "values"] * property: (2) ["0", "1"] * typeOf: "object" */ if (type.class == "NodeList") { list = []; elements.forEach(function (x) { return list.push(x); }); } else if (type.class == "HTMLCollection") { var collection = elements; list = []; for (var i = 0; i < collection.length; i++) { list.push(collection.item(i)); } } else { list = Framework.Extensions.EnsureArray(elements); } // 在最后进行元素拓展 for (var _i = 0, list_1 = list; _i < list_1.length; _i++) { var node = list_1[_i]; TypeExtensions.Extends(node); } return list; }; /** * 使用这个函数进行节点值的设置或者获取 * * 这个函数不传递任何参数则表示获取值 * * @param value 如果需要批量清除节点之中的值的话,需要传递一个空字符串,而非空值 */ DOMEnumerator.prototype.val = function (value) { if (value === void 0) { value = null; } if (isNullOrUndefined(value)) { return this.Select(function (element) { return DOMEnumerator.getVal(element); }); } else { if (typeof value == "string" || typeof value == "number") { // 所有元素都设置同一个值 this.ForEach(function (e) { return DOMEnumerator.setVal(e, value); }); } else if (Array.isArray(value)) { this.ForEach(function (e, i) { return DOMEnumerator.setVal(e, value[i]); }); } else { this.ForEach(function (e, i) { return DOMEnumerator.setVal(e, value.ElementAt(i)); }); } } }; DOMEnumerator.setVal = function (element, text) { if (element instanceof HTMLInputElement) { element.value = text; } else { element.textContent = text; } }; DOMEnumerator.getVal = function (element) { if (element instanceof HTMLInputElement) { return element.value; } else { return element.textContent; } }; /** * 使用这个函数设置或者获取属性值 * * @param attrName 属性名称 * @param val + 如果为字符串值,则当前的结合之中的所有的节点的指定属性都将设置为相同的属性值 * + 如果为字符串集合或者字符串数组,则会分别设置对应的index的属性值 * + 如果是一个函数,则会设置根据该节点所生成的字符串为属性值 * * @returns 函数总是会返回所设置的或者读取得到的属性值的字符串集合 */ DOMEnumerator.prototype.attr = function (attrName, val) { if (val === void 0) { val = null; } if (val) { if (typeof val == "function") { return this.Select(function (x) { var value = val(x); x.setAttribute(attrName, value); return value; }); } else { var array = Framework.Extensions.EnsureArray(val, this.Count); return this.Select(function (x, i) { var value = array[i]; x.setAttribute(attrName, value); return value; }); } } else { return this.Select(function (x) { return x.getAttribute(attrName); }); } }; DOMEnumerator.prototype.addClass = function (className) { this.ForEach(function (node) { if (!node.classList.contains(className)) { node.classList.add(className); } }); return this; }; DOMEnumerator.prototype.addEvent = function (eventName, handler) { this.ForEach(function (element) { var event = function (Event) { handler(element, Event); }; DOM.Events.addEvent(element, eventName, event); }); }; DOMEnumerator.prototype.onChange = function (handler) { this.addEvent("onchange", handler); }; /** * 为当前的html节点集合添加鼠标点击事件处理函数 */ DOMEnumerator.prototype.onClick = function (handler) { this.ForEach(function (element) { element.onclick = function (ev) { handler(this, ev); return false; }; }); }; DOMEnumerator.prototype.removeClass = function (className) { this.ForEach(function (x) { if (x.classList.contains(className)) { x.classList.remove(className); } }); return this; }; /** * 通过设置css之中的display值来将集合之中的所有的节点元素都隐藏掉 */ DOMEnumerator.prototype.hide = function () { this.ForEach(function (x) { return x.style.display = "none"; }); return this; }; /** * 通过设置css之中的display值来将集合之中的所有的节点元素都显示出来 */ DOMEnumerator.prototype.show = function () { this.ForEach(function (x) { return x.style.display = "block"; }); return this; }; /** * 将所选定的节点批量删除 */ DOMEnumerator.prototype.delete = function () { this.ForEach(function (x) { return x.parentNode.removeChild(x); }); }; return DOMEnumerator; }(IEnumerator)); /// var Internal; (function (Internal) { var Handlers; (function (Handlers) { var events = { onclick: "onclick" }; var eventFuncNames = Object.keys(events); function hasKey(object, key) { // hasOwnProperty = Object.prototype.hasOwnProperty return object ? window.hasOwnProperty.call(object, key) : false; } Handlers.hasKey = hasKey; /** * 这个函数确保给定的id字符串总是以符号``#``开始的 */ function EnsureNodeId(str) { if (!str) { throw "The given node id value is nothing!"; } else if (str[0] == "#") { return str; } else { return "#" + str; } } Handlers.EnsureNodeId = EnsureNodeId; /** * 字符串格式的值意味着对html文档节点的查询 */ var stringEval = /** @class */ (function () { function stringEval() { } stringEval.ensureArguments = function (args) { if (isNullOrUndefined(args)) { return Internal.Arguments.Default(); } else { var opts = args; // 2018-10-16 // 如果不在这里进行判断赋值,则nativeModel属性的值为undefined // 会导致总会判断为true的bug出现 if (isNullOrUndefined(opts.nativeModel)) { // 为了兼容以前的代码,在这里总是默认为TRUE opts.nativeModel = true; } return opts; } }; /** * @param query 函数会在这里自动的处理转义问题 * @param context 默认为当前的窗口文档 */ stringEval.select = function (query, context) { if (context === void 0) { context = window; } // https://mathiasbynens.be/notes/css-escapes var cssSelector = query.replace(":", "\\:"); // 返回节点集合 var nodes; if (context instanceof Window) { nodes = context .document .querySelectorAll(cssSelector); } else if (context instanceof HTMLElement) { nodes = context.querySelectorAll(cssSelector); } else { throw "Unsupported context type: " + TypeInfo.getClass(context); } var it = new DOMEnumerator(nodes); return it; }; stringEval.prototype.doEval = function (expr, type, args) { var query = DOM.Query.parseQuery(expr); var argument = stringEval.ensureArguments(args); // 默认查询的上下文环境为当前的文档 var context = argument.context || window; if (query.type == DOM.QueryTypes.id) { // 按照id查询 var node = context .document .getElementById(query.expression); if (isNullOrUndefined(node)) { if (TypeScript.logging.outputWarning) { console.warn("Unable to found a node which its ID='" + expr + "'!"); } return null; } else { if (argument.nativeModel) { return TypeExtensions.Extends(node); } else { return new HTMLTsElement(node); } } } else if (query.type == DOM.QueryTypes.NoQuery) { return stringEval.createNew(expr, argument, context); } else if (!query.singleNode) { return stringEval.select(query.expression, context); } else if (query.type == DOM.QueryTypes.QueryMeta) { // meta标签查询默认是可以在父节点文档之中查询的 // 所以在这里不需要context上下文环境 return DOM.InputValueGetter.metaValue(query.expression, (args || {})["default"], context != window); } else { if (TypeScript.logging.outputEverything) { console.warn("Apply querySelector for expression: '" + query.expression + "', no typescript extension was made!"); } // 只返回第一个满足条件的节点 return context .document .querySelector(query.expression); } }; /** * 创建新的HTML节点元素 */ stringEval.createNew = function (expr, args, context) { if (context === void 0) { context = window; } var declare = DOM.ParseNodeDeclare(expr); var node = context .document .createElement(declare.tag); // 赋值节点申明的字符串表达式之中所定义的属性 declare.attrs .forEach(function (attr) { if (eventFuncNames.indexOf(attr.name) < 0) { node.setAttribute(attr.name, attr.value); } }); // 赋值额外的属性参数 if (args) { stringEval.setAttributes(node, args); } if (args.nativeModel) { return TypeExtensions.Extends(node); } else { return new HTMLTsElement(node); } }; stringEval.setAttributes = function (node, attrs) { var setAttr = function (name) { if (eventFuncNames.indexOf(name) > -1) { return; } if (name == "class") { var classVals = attrs[name]; if (Array.isArray(classVals)) { classVals.forEach(function (c) { return node.classList.add(c); }); } else { node.setAttribute(name, classVals); } } else if (name == "style") { if (typeof attrs == "string") { node.setAttribute(name, attrs); } else { // node.style是一个只读属性,无法直接赋值 for (var propertyName in attrs) { node.style[propertyName] = attrs[propertyName]; } } } else if (name == "visible") { if (attrs[name]) { node.style.display = "block"; } else { node.style.display = "none"; } } else { node.setAttribute(name, attrs[name]); } }; Internal.Arguments.nameFilter(attrs).forEach(function (name) { return setAttr(name); }); // 添加事件 if (hasKey(attrs, events.onclick)) { var onclick_1 = attrs[events.onclick]; if (typeof onclick_1 == "string") { node.setAttribute(events.onclick, onclick_1); } else { node.onclick = onclick_1; } } }; return stringEval; }()); Handlers.stringEval = stringEval; })(Handlers = Internal.Handlers || (Internal.Handlers = {})); })(Internal || (Internal = {})); /// var Internal; (function (Internal) { var Handlers; (function (Handlers) { /** * 在这个字典之中的键名称主要有两大类型: * * + typeof 类型判断结果 * + TypeInfo.class 类型名称 */ Handlers.Shared = { /** * HTML document query handler */ string: function () { return new Handlers.stringEval(); }, /** * Create a linq object */ array: function () { return new arrayEval(); }, NodeListOf: function () { return new DOMCollection(); }, HTMLCollection: function () { return new DOMCollection(); } }; /** * Create a Linq Enumerator */ var arrayEval = /** @class */ (function () { function arrayEval() { } arrayEval.prototype.doEval = function (expr, type, args) { return From(expr); }; return arrayEval; }()); Handlers.arrayEval = arrayEval; var DOMCollection = /** @class */ (function () { function DOMCollection() { } DOMCollection.prototype.doEval = function (expr, type, args) { return new DOMEnumerator(expr); }; return DOMCollection; }()); Handlers.DOMCollection = DOMCollection; })(Handlers = Internal.Handlers || (Internal.Handlers = {})); })(Internal || (Internal = {})); /** * 通用数据拓展函数集合 */ var DataExtensions; (function (DataExtensions) { function arrayBufferToBase64(buffer) { var binary = ''; var bytes = new Uint8Array(buffer); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary); } DataExtensions.arrayBufferToBase64 = arrayBufferToBase64; /** * 将uri之中的base64字符串数据转换为一个byte数据流 */ function uriToBlob(uri) { var byteString = window.atob(uri.split(',')[1]); var mimeString = uri.split(',')[0].split(':')[1].split(';')[0]; var buffer = new ArrayBuffer(byteString.length); var intArray = new Uint8Array(buffer); for (var i = 0; i < byteString.length; i++) { intArray[i] = byteString.charCodeAt(i); } return new Blob([buffer], { type: mimeString }); } DataExtensions.uriToBlob = uriToBlob; /** * 将URL查询字符串解析为字典对象,所传递的查询字符串应该是查询参数部分,即问号之后的部分,而非完整的url * * @param queryString URL查询参数 * @param lowerName 是否将所有的参数名称转换为小写形式? * * @returns 键值对形式的字典对象 */ function parseQueryString(queryString, lowerName) { if (lowerName === void 0) { lowerName = false; } // stuff after # is not part of query string, so get rid of it // split our query string into its component parts var arr = queryString.split('#')[0].split('&'); // we'll store the parameters here var obj = {}; for (var i = 0; i < arr.length; i++) { // separate the keys and the values var a = arr[i].split('='); // in case params look like: list[]=thing1&list[]=thing2 var paramNum = undefined; var paramName = a[0].replace(/\[\d*\]/, function (v) { paramNum = v.slice(1, -1); return ''; }); // set parameter value (use 'true' if empty) var paramValue = typeof (a[1]) === 'undefined' ? "true" : a[1]; if (lowerName) { paramName = paramName.toLowerCase(); } // if parameter name already exists if (obj[paramName]) { // convert value to array (if still string) if (typeof obj[paramName] === 'string') { obj[paramName] = [obj[paramName]]; } if (typeof paramNum === 'undefined') { // if no array index number specified... // put the value on the end of the array obj[paramName].push(paramValue); } else { // if array index number specified... // put the value at that index number obj[paramName][paramNum] = paramValue; } } else { // if param name doesn't exist yet, set it obj[paramName] = paramValue; } } return obj; } DataExtensions.parseQueryString = parseQueryString; /** * 尝试将任意类型的目标对象转换为数值类型 * * @returns 一个数值 */ function as_numeric(obj) { return AsNumeric(obj)(obj); } DataExtensions.as_numeric = as_numeric; /** * 因为在js之中没有类型信息,所以如果要取得类型信息必须要有一个目标对象实例 * 所以在这里,函数会需要一个实例对象来取得类型值 */ function AsNumeric(obj) { if (obj == null || obj == undefined) { return null; } if (typeof obj === 'number') { return function (x) { return x; }; } else if (typeof obj === 'boolean') { return function (x) { if (x == true) { return 1; } else { return -1; } }; } else if (typeof obj == 'undefined') { return function (x) { return 0; }; } else if (typeof obj == 'string') { return function (x) { return Strings.Val(x); }; } else { // 其他的所有情况都转换为零 return function (x) { return 0; }; } } DataExtensions.AsNumeric = AsNumeric; /** * @param fill 进行向量填充的初始值,可能不适用于引用类型,推荐应用于初始的基元类型 */ function Dim(len, fill) { if (fill === void 0) { fill = null; } var vector = []; for (var i = 0; i < len; i++) { vector.push(fill); } return vector; } DataExtensions.Dim = Dim; })(DataExtensions || (DataExtensions = {})); /** * 描述了一个键值对集合 */ var MapTuple = /** @class */ (function () { /** * 创建一个新的键值对集合 * */ function MapTuple(key, value) { if (key === void 0) { key = null; } if (value === void 0) { value = null; } this.key = key; this.value = value; } MapTuple.prototype.valueOf = function () { return this.value; }; MapTuple.prototype.ToArray = function () { return [this.key, this.value]; }; MapTuple.prototype.toString = function () { return "[" + this.key.toString() + ", " + this.value.toString() + "]"; }; return MapTuple; }()); /** * 描述了一个带有名字属性的变量值 */ var NamedValue = /** @class */ (function () { function NamedValue(name, val) { if (name === void 0) { name = null; } if (val === void 0) { val = null; } this.name = name; this.value = val; } Object.defineProperty(NamedValue.prototype, "TypeOfValue", { /** * 获取得到变量值的类型定义信息 */ get: function () { return TypeInfo.typeof(this.value); }, enumerable: true, configurable: true }); Object.defineProperty(NamedValue.prototype, "IsEmpty", { /** * 这个之对象是否是空的? */ get: function () { return Strings.Empty(this.name) && (!this.value || this.value == undefined); }, enumerable: true, configurable: true }); NamedValue.prototype.valueOf = function () { return this.value; }; NamedValue.prototype.ToArray = function () { return [this.name, this.value]; }; NamedValue.prototype.toString = function () { return this.name; }; return NamedValue; }()); /// /** * TypeScript string helpers. * (这个模块之中的大部分的字符串处理函数的行为是和VisualBasic之中的字符串函数的行为是相似的) */ var Strings; (function (Strings) { Strings.x0 = "0".charCodeAt(0); Strings.x9 = "9".charCodeAt(0); Strings.asterisk = "*".charCodeAt(0); Strings.cr = "\c".charCodeAt(0); Strings.lf = "\r".charCodeAt(0); Strings.a = "a".charCodeAt(0); Strings.z = "z".charCodeAt(0); Strings.A = "A".charCodeAt(0); Strings.Z = "Z".charCodeAt(0); Strings.numericPattern = /[-]?\d+(\.\d+)?/g; /** * 判断所给定的字符串文本是否是任意实数的正则表达式模式 */ function isNumericPattern(text) { return IsPattern(text, Strings.numericPattern); } Strings.isNumericPattern = isNumericPattern; /** * 对bytes数值进行格式自动优化显示 * * @param bytes * * @return 经过自动格式优化过后的大小显示字符串 */ function Lanudry(bytes) { var symbols = ["B", "KB", "MB", "GB", "TB"]; var exp = Math.floor(Math.log(bytes) / Math.log(1000)); var symbol = symbols[exp]; var val = (bytes / Math.pow(1000, Math.floor(exp))); return Strings.sprintf("%.2f " + symbol, val); } Strings.Lanudry = Lanudry; /** * how to escape xml entities in javascript? * * > https://stackoverflow.com/questions/7918868/how-to-escape-xml-entities-in-javascript */ function escapeXml(unsafe) { return unsafe.replace(/[<>&'"]/g, function (c) { switch (c) { case '<': return '<'; case '>': return '>'; case '&': return '&'; case '\'': return '''; case '"': return '"'; } }); } Strings.escapeXml = escapeXml; /** * 这个函数会将字符串起始的数字给匹配出来 * 如果匹配失败会返回零 * * 与VB之中的val函数的行为相似,但是这个函数返回整形数 * * @param text 这个函数并没有执行trim操作,所以如果字符串的起始为空白符的话 * 会导致解析结果为零 */ function parseInt(text) { var number; var c; var ascii; if (Strings.Empty(text, true)) { return 0; } else { number = []; } for (var i = 0; i < text.length; i++) { c = text.charAt(i); ascii = c.charCodeAt(0); if (ascii >= Strings.x0 && ascii <= Strings.x9) { number.push(c); } else { break; } } if (number.length == 0) { return 0; } else { return Number(number.join("")); } } Strings.parseInt = parseInt; /** * Create new string value by repeats a given char n times. * * @param c A single char * @param n n chars */ function New(c, n) { if (n == 0) { return ""; } else if (n == 1) { return c; } else { var s = ""; for (var i = 1; i < n; ++i) { s = s + c; } return s; } } Strings.New = New; /** * Round the number value or number text in given decimals. * * @param decimals 默认是保留3位有效数字的 */ function round(x, decimals) { if (decimals === void 0) { decimals = 3; } var floatX = typeof x == "number" ? x : parseFloat(x); var n = Math.pow(10, decimals); if (isNaN(floatX)) { if (TypeScript.logging.outputWarning) { console.warn("Invalid number value: '" + x + "'"); } return false; } else { return Math.round(floatX * n) / n; } } Strings.round = round; /** * 判断当前的这个字符是否是一个数字? * * @param c A single character, length = 1 */ function isNumber(c) { var code = c.charCodeAt(0); return code >= Strings.x0 && code <= Strings.x9; } Strings.isNumber = isNumber; /** * 判断当前的这个字符是否是一个字母? * * @param c A single character, length = 1 */ function isAlphabet(c) { var code = c.charCodeAt(0); return (code >= Strings.a && code <= Strings.z) || (code >= Strings.A && code <= Strings.Z); } Strings.isAlphabet = isAlphabet; /** * 将字符串转换为一个实数 * 这个函数是直接使用parseFloat函数来工作的,如果不是符合格式的字符串,则可能会返回NaN */ function Val(str) { if (str == null || str == '' || str == undefined || str == "undefined") { // 将空字符串转换为零 return 0; } else if (str == "NA" || str == "NaN") { return Number.NaN; } else if (str == "Inf") { return Number.POSITIVE_INFINITY; } else if (str == "-Inf") { return Number.NEGATIVE_INFINITY; } else { return parseFloat(str); } } Strings.Val = Val; /** * 将文本字符串按照newline进行分割 */ function lineTokens(text) { return (!text) ? [] : text.trim().split("\n"); } Strings.lineTokens = lineTokens; /** * 如果不存在``tag``分隔符,则返回来的``tuple``里面,``name``是输入的字符串,``value``则是空字符串 * * @param tag 分割name和value的分隔符,默认是一个空白符号 */ function GetTagValue(str, tag) { if (tag === void 0) { tag = " "; } if (!str) { return new NamedValue(); } else { return tagValueImpl(str, tag); } } Strings.GetTagValue = GetTagValue; function tagValueImpl(str, tag) { var i = str.indexOf(tag); var tagLen = Len(tag); if (i > -1) { var name = str.substr(0, i); var value = str.substr(i + tagLen); return new NamedValue(name, value); } else { return new NamedValue(str, ""); } } /** * 取出大文本之中指定的前n行文本 */ function PeekLines(text, n) { var p = 0; var out = []; for (var i = 0; i < n; i++) { var pn = text.indexOf("\n", p); if (pn > -1) { out.push(text.substr(p, pn - p)); p = pn; } else { // 已经到头了 break; } } return out; } Strings.PeekLines = PeekLines; /** * Get all regex pattern matches in target text value. */ function getAllMatches(text, pattern) { var match = null; var out = []; if (typeof pattern == "string") { pattern = new RegExp(pattern); } if (pattern.global) { while (match = pattern.exec(text)) { out.push(match); } } else { if (match = pattern.exec(text)) { out.push(match); } } return out; } Strings.getAllMatches = getAllMatches; /** * Removes the given chars from the begining of the given * string and the end of the given string. * * @param chars A collection of characters that will be trimmed. * (如果这个参数为空值,则会直接使用字符串对象自带的trim函数来完成工作) * * @returns 这个函数总是会确保返回来的值不是空值,如果输入的字符串参数为空值,则会直接返回零长度的空字符串 */ function Trim(str, chars) { if (chars === void 0) { chars = null; } if (Strings.Empty(str, false)) { return ""; } else if (isNullOrUndefined(chars)) { return str.trim(); } if (typeof chars == "string") { chars = From(Strings.ToCharArray(chars)) .Select(function (c) { return c.charCodeAt(0); }) .ToArray(false); } return function (chars) { return From(Strings.ToCharArray(str)) .SkipWhile(function (c) { return chars.indexOf(c.charCodeAt(0)) > -1; }) .Reverse() .SkipWhile(function (c) { return chars.indexOf(c.charCodeAt(0)) > -1; }) .Reverse() .JoinBy(""); }(chars); } Strings.Trim = Trim; function LTrim(str, chars) { if (chars === void 0) { chars = " "; } if (Strings.Empty(str, false)) { return ""; } if (typeof chars == "string") { chars = From(Strings.ToCharArray(chars)) .Select(function (c) { return c.charCodeAt(0); }) .ToArray(false); } return function (chars) { return From(Strings.ToCharArray(str)) .SkipWhile(function (c) { return chars.indexOf(c.charCodeAt(0)) > -1; }) .JoinBy(""); }(chars); } Strings.LTrim = LTrim; function RTrim(str, chars) { if (chars === void 0) { chars = " "; } if (Strings.Empty(str, false)) { return ""; } if (typeof chars == "string") { chars = From(Strings.ToCharArray(chars)) .Select(function (c) { return c.charCodeAt(0); }) .ToArray(false); } var strChars = Strings.ToCharArray(str); var lefts = 0; for (var i = strChars.length - 1; i > 0; i--) { if (chars.indexOf(strChars[i].charCodeAt(0)) == -1) { lefts = i; break; } } if (lefts == 0) { return ""; } else { return str.substr(0, lefts + 1); } } Strings.RTrim = RTrim; /** * Determine that the given string is empty string or not? * (判断给定的字符串是否是空值?) * * @param stringAsFactor 假若这个参数为真的话,那么字符串``undefined``或者``NULL``以及``null``也将会被当作为空值处理 */ function Empty(str, stringAsFactor) { if (stringAsFactor === void 0) { stringAsFactor = false; } if (!str) { return true; } else if (str == undefined || typeof str == "undefined") { return true; } else if (str.length == 0) { return true; } else if (stringAsFactor && (str == "undefined" || str == "null" || str == "NULL")) { return true; } else { return false; } } Strings.Empty = Empty; /** * 测试字符串是否是空白集合 * * @param stringAsFactor 如果这个参数为真,则``\t``和``\s``等也会被当作为空白 */ function Blank(str, stringAsFactor) { if (stringAsFactor === void 0) { stringAsFactor = false; } if (!str || IsPattern(str, /\s+/g)) { return true; } else if (str == undefined || typeof str == "undefined") { return true; } else if (str.length == 0) { return true; } else if (stringAsFactor && (str == "\\s" || str == "\\t")) { return true; } else { return false; } } Strings.Blank = Blank; /** * Determine that the whole given string is match a given regex pattern. */ function IsPattern(str, pattern) { if (!str) { // 字符串是空的,则肯定不满足 return false; } var matches = str.match(ensureRegexp(pattern)); if (isNullOrUndefined(matches)) { return false; } else { var match = matches[0]; var test = match == str; return test; } } Strings.IsPattern = IsPattern; function ensureRegexp(pattern) { if (typeof pattern == "string") { return new RegExp(pattern); } else { return pattern; } } /** * Remove duplicate string values from JS array * * https://stackoverflow.com/questions/9229645/remove-duplicate-values-from-js-array */ function Unique(a) { var seen = {}; return a.filter(function (item) { return seen.hasOwnProperty(item) ? false : (seen[item] = true); }); } Strings.Unique = Unique; /** * 将字符串转换为字符数组 * * @description > https://jsperf.com/convert-string-to-char-code-array/9 * 经过测试,使用数组push的效率最高 * * @param charCode 返回来的数组是否应该是一组字符的ASCII值而非字符本身?默认是返回字符数组的。 * * @returns A character array, all of the string element in the array * is one character length. */ function ToCharArray(str, charCode) { if (charCode === void 0) { charCode = false; } var cc = []; var strLen = str.length; if (charCode) { for (var i = 0; i < strLen; ++i) { cc.push(str.charCodeAt(i)); } } else { for (var i = 0; i < strLen; ++i) { cc.push(str.charAt(i)); } } return cc; } Strings.ToCharArray = ToCharArray; /** * Measure the string length, a null string value or ``undefined`` * variable will be measured as ZERO length. */ function Len(s) { if (!s || s == undefined) { return 0; } else { return s.length; } } Strings.Len = Len; /** * 比较两个字符串的大小,可以同于字符串的分组操作 */ function CompareTo(s1, s2) { var l1 = Strings.Len(s1); var l2 = Strings.Len(s2); var minl = Math.min(l1, l2); for (var i = 0; i < minl; i++) { var x = s1.charCodeAt(i); var y = s2.charCodeAt(i); if (x > y) { return 1; } else if (x < y) { return -1; } } if (l1 > l2) { return 1; } else if (l1 < l2) { return -1; } else { return 0; } } Strings.CompareTo = CompareTo; Strings.sprintf = data.sprintf.doFormat; /** * @param charsPerLine 每一行文本之中的字符数量的最大值 */ function WrappingLines(text, charsPerLine, lineTrim) { if (charsPerLine === void 0) { charsPerLine = 200; } if (lineTrim === void 0) { lineTrim = false; } var sb = ""; var lines = Strings.lineTokens(text); var p; for (var i = 0; i < lines.length; i++) { var line = lineTrim ? Strings.Trim(lines[i]) : lines[i]; if (line.length < charsPerLine) { sb = sb + line + "\n"; } else { p = 0; while (true) { sb = sb + line.substr(p, charsPerLine) + "\n"; p += charsPerLine; if ((p + charsPerLine) > line.length) { // 下一个起始的位置已经超过文本行的长度了 // 则是终止的时候了 sb = sb + line.substr(p) + "\n"; break; } } } } return sb; } Strings.WrappingLines = WrappingLines; })(Strings || (Strings = {})); /** * 类似于反射类型 */ var TypeInfo = /** @class */ (function () { function TypeInfo() { } Object.defineProperty(TypeInfo.prototype, "IsPrimitive", { /** * 是否是js之中的基础类型? */ get: function () { return !this.class; }, enumerable: true, configurable: true }); Object.defineProperty(TypeInfo.prototype, "IsArray", { /** * 是否是一个数组集合对象? */ get: function () { return this.typeOf == "array"; }, enumerable: true, configurable: true }); Object.defineProperty(TypeInfo.prototype, "IsEnumerator", { /** * 是否是一个枚举器集合对象? */ get: function () { return this.typeOf == "object" && this.class == "IEnumerator"; }, enumerable: true, configurable: true }); /** * 当前的对象是某种类型的数组集合对象 */ TypeInfo.prototype.IsArrayOf = function (genericType) { return this.IsArray && this.class == genericType; }; /** * 获取得到类型名称 */ TypeInfo.getClass = function (obj) { var type = typeof obj; var isObject = type == "object"; var isArray = Array.isArray(obj); var isNull = isNullOrUndefined(obj); return TypeInfo.getClassInternal(obj, isArray, isObject, isNull); }; TypeInfo.getClassInternal = function (obj, isArray, isObject, isNull) { if (isArray) { var x = obj[0]; var className; if ((className = typeof x) == "object") { className = x.constructor.name; } else { // do nothing } return className; } else if (isObject) { if (isNull) { if (TypeScript.logging.outputWarning) { console.warn(TypeExtensions.objectIsNothing); } return "null"; } else { return obj.constructor.name; } } else { return ""; } }; /** * 获取某一个对象的类型信息 */ TypeInfo.typeof = function (obj) { var type = typeof obj; var isObject = type == "object"; var isArray = Array.isArray(obj); var isNull = isNullOrUndefined(obj); var typeInfo = new TypeInfo; var className = TypeInfo.getClassInternal(obj, isArray, isObject, isNull); typeInfo.typeOf = isArray ? "array" : type; typeInfo.class = className; if (isNull) { typeInfo.property = []; typeInfo.methods = []; } else { typeInfo.property = isObject ? Object.keys(obj) : []; typeInfo.methods = TypeInfo.GetObjectMethods(obj); } return typeInfo; }; /** * 获取object对象上所定义的所有的函数 */ TypeInfo.GetObjectMethods = function (obj) { var res = []; for (var m in obj) { if (typeof obj[m] == "function") { res.push(m); } } return res; }; TypeInfo.prototype.toString = function () { if (this.typeOf == "object") { return "<" + this.typeOf + "> " + this.class; } else { return this.typeOf; } }; /** * MetaReader对象和字典相似,只不过是没有类型约束,并且为只读集合 */ TypeInfo.CreateMetaReader = function (nameValues) { return new TypeScript.Data.MetaReader(Activator.CreateObject(nameValues)); }; return TypeInfo; }()); /** * JavaScript MD5 1.0.1 * https://github.com/blueimp/JavaScript-MD5 * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT * * Based on * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ var MD5; (function (MD5) { // jslint bitwise: true // global unescape, define /** * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } MD5.safe_add = safe_add; /** * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } MD5.bit_rol = bit_rol; //#region "These functions implement the four basic operations the algorithm uses." function md5_cmn(q, a, b, x, s, t) { return MD5.safe_add(MD5.bit_rol(MD5.safe_add(MD5.safe_add(a, q), MD5.safe_add(x, t)), s), b); } MD5.md5_cmn = md5_cmn; function md5_ff(a, b, c, d, x, s, t) { return MD5.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); } MD5.md5_ff = md5_ff; function md5_gg(a, b, c, d, x, s, t) { return MD5.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); } MD5.md5_gg = md5_gg; function md5_hh(a, b, c, d, x, s, t) { return MD5.md5_cmn(b ^ c ^ d, a, b, x, s, t); } MD5.md5_hh = md5_hh; function md5_ii(a, b, c, d, x, s, t) { return MD5.md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } MD5.md5_ii = md5_ii; //#endregion /** * Calculate the MD5 of an array of little-endian words, and a bit length. */ function binl_md5(x, len) { var olda, oldb, oldc, oldd, a = 1732584193, b = -271733879, c = -1732584194, d = 271733878; // append padding x[len >> 5] |= 0x80 << (len % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; for (var i = 0; i < x.length; i += 16) { olda = a; oldb = b; oldc = c; oldd = d; a = MD5.md5_ff(a, b, c, d, x[i], 7, -680876936); d = MD5.md5_ff(d, a, b, c, x[i + 1], 12, -389564586); c = MD5.md5_ff(c, d, a, b, x[i + 2], 17, 606105819); b = MD5.md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); a = MD5.md5_ff(a, b, c, d, x[i + 4], 7, -176418897); d = MD5.md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); c = MD5.md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); b = MD5.md5_ff(b, c, d, a, x[i + 7], 22, -45705983); a = MD5.md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); d = MD5.md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); c = MD5.md5_ff(c, d, a, b, x[i + 10], 17, -42063); b = MD5.md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); a = MD5.md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); d = MD5.md5_ff(d, a, b, c, x[i + 13], 12, -40341101); c = MD5.md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); b = MD5.md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); a = MD5.md5_gg(a, b, c, d, x[i + 1], 5, -165796510); d = MD5.md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); c = MD5.md5_gg(c, d, a, b, x[i + 11], 14, 643717713); b = MD5.md5_gg(b, c, d, a, x[i], 20, -373897302); a = MD5.md5_gg(a, b, c, d, x[i + 5], 5, -701558691); d = MD5.md5_gg(d, a, b, c, x[i + 10], 9, 38016083); c = MD5.md5_gg(c, d, a, b, x[i + 15], 14, -660478335); b = MD5.md5_gg(b, c, d, a, x[i + 4], 20, -405537848); a = MD5.md5_gg(a, b, c, d, x[i + 9], 5, 568446438); d = MD5.md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); c = MD5.md5_gg(c, d, a, b, x[i + 3], 14, -187363961); b = MD5.md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); a = MD5.md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); d = MD5.md5_gg(d, a, b, c, x[i + 2], 9, -51403784); c = MD5.md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); b = MD5.md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); a = MD5.md5_hh(a, b, c, d, x[i + 5], 4, -378558); d = MD5.md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); c = MD5.md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); b = MD5.md5_hh(b, c, d, a, x[i + 14], 23, -35309556); a = MD5.md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); d = MD5.md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); c = MD5.md5_hh(c, d, a, b, x[i + 7], 16, -155497632); b = MD5.md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); a = MD5.md5_hh(a, b, c, d, x[i + 13], 4, 681279174); d = MD5.md5_hh(d, a, b, c, x[i], 11, -358537222); c = MD5.md5_hh(c, d, a, b, x[i + 3], 16, -722521979); b = MD5.md5_hh(b, c, d, a, x[i + 6], 23, 76029189); a = MD5.md5_hh(a, b, c, d, x[i + 9], 4, -640364487); d = MD5.md5_hh(d, a, b, c, x[i + 12], 11, -421815835); c = MD5.md5_hh(c, d, a, b, x[i + 15], 16, 530742520); b = MD5.md5_hh(b, c, d, a, x[i + 2], 23, -995338651); a = MD5.md5_ii(a, b, c, d, x[i], 6, -198630844); d = MD5.md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); c = MD5.md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); b = MD5.md5_ii(b, c, d, a, x[i + 5], 21, -57434055); a = MD5.md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); d = MD5.md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); c = MD5.md5_ii(c, d, a, b, x[i + 10], 15, -1051523); b = MD5.md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); a = MD5.md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); d = MD5.md5_ii(d, a, b, c, x[i + 15], 10, -30611744); c = MD5.md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); b = MD5.md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); a = MD5.md5_ii(a, b, c, d, x[i + 4], 6, -145523070); d = MD5.md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); c = MD5.md5_ii(c, d, a, b, x[i + 2], 15, 718787259); b = MD5.md5_ii(b, c, d, a, x[i + 9], 21, -343485551); a = MD5.safe_add(a, olda); b = MD5.safe_add(b, oldb); c = MD5.safe_add(c, oldc); d = MD5.safe_add(d, oldd); } return [a, b, c, d]; } MD5.binl_md5 = binl_md5; /** * Convert an array of little-endian words to a string */ function binl2rstr(input) { var output = ''; for (var i = 0; i < input.length * 32; i += 8) { output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); } return output; } MD5.binl2rstr = binl2rstr; /** * Convert a raw string to an array of little-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binl(input) { var output = []; output[(input.length >> 2) - 1] = undefined; for (var i = 0; i < output.length; i += 1) { output[i] = 0; } for (var i = 0; i < input.length * 8; i += 8) { output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); } return output; } MD5.rstr2binl = rstr2binl; /** * Calculate the MD5 of a raw string */ function rstr_md5(s) { return MD5.binl2rstr(MD5.binl_md5(MD5.rstr2binl(s), s.length * 8)); } MD5.rstr_md5 = rstr_md5; /** * Calculate the HMAC-MD5, of a key and some data (raw strings) */ function rstr_hmac_md5(key, data) { var bkey = MD5.rstr2binl(key), ipad = [], opad = []; ipad[15] = opad[15] = undefined; if (bkey.length > 16) { bkey = MD5.binl_md5(bkey, key.length * 8); } for (var i = 0; i < 16; i += 1) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash; hash = ipad.concat(MD5.rstr2binl(data)); hash = MD5.binl_md5(hash, 512 + data.length * 8); hash = opad.concat(hash); hash = MD5.binl_md5(hash, 512 + 128); return MD5.binl2rstr(hash); } MD5.rstr_hmac_md5 = rstr_hmac_md5; var hex_tab = '0123456789abcdef'; /** * Convert a raw string to a hex string */ function rstr2hex(input) { var output = '', x; for (var i = 0; i < input.length; i += 1) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F); } return output; } MD5.rstr2hex = rstr2hex; /** * Encode a string as utf-8 */ function str2rstr_utf8(input) { return unescape(encodeURIComponent(input)); } MD5.str2rstr_utf8 = str2rstr_utf8; /** * Take string arguments and return either raw or hex encoded strings */ function raw_md5(s) { return MD5.rstr_md5(MD5.str2rstr_utf8(s)); } MD5.raw_md5 = raw_md5; function hex_md5(s) { return MD5.rstr2hex(MD5.raw_md5(s)); } MD5.hex_md5 = hex_md5; function raw_hmac_md5(k, d) { return MD5.rstr_hmac_md5(MD5.str2rstr_utf8(k), MD5.str2rstr_utf8(d)); } MD5.raw_hmac_md5 = raw_hmac_md5; function hex_hmac_md5(k, d) { return MD5.rstr2hex(MD5.raw_hmac_md5(k, d)); } MD5.hex_hmac_md5 = hex_hmac_md5; /** * 利用这个函数来进行字符串的MD5值的计算操作 */ function calculate(string, key, raw) { if (key === void 0) { key = null; } if (raw === void 0) { raw = null; } if (!key) { if (!raw) { return MD5.hex_md5(string); } return MD5.raw_md5(string); } if (!raw) { return MD5.hex_hmac_md5(key, string); } return MD5.raw_hmac_md5(key, string); } MD5.calculate = calculate; })(MD5 || (MD5 = {})); /// var Internal; (function (Internal) { /** * 程序的堆栈追踪信息 * * 这个对象是调用堆栈``StackFrame``片段对象的序列集合 */ var StackTrace = /** @class */ (function (_super) { __extends(StackTrace, _super); function StackTrace(frames) { return _super.call(this, frames) || this; } /** * 导出当前的程序运行位置的调用堆栈信息 */ StackTrace.Dump = function () { var err = new Error().stack.split("\n"); var trace = From(err) // 1 是第一行 err 字符串, // + 1 是跳过当前的这个Dump函数的栈信息 .Skip(1 + 1) .Select(Internal.StackFrame.Parse); return new StackTrace(trace); }; /** * 获取函数调用者的名称的帮助函数 */ StackTrace.GetCallerMember = function () { var trace = StackTrace.Dump().ToArray(); // index = 1 是GetCallerMemberName这个函数的caller的栈片段 // index = 2 就是caller的caller的栈片段,即该caller的CallerMemberName var caller = trace[1 + 1]; return caller; }; StackTrace.prototype.toString = function () { var sb = new StringBuilder(); this.ForEach(function (frame) { sb.AppendLine(" at " + frame.toString()); }); return sb.toString(); }; return StackTrace; }(IEnumerator)); Internal.StackTrace = StackTrace; })(Internal || (Internal = {})); /// /// /** * 键值对映射哈希表 * * ``` * IEnumerator> * ``` */ var Dictionary = /** @class */ (function (_super) { __extends(Dictionary, _super); /** * 将目标对象转换为一个类型约束的映射序列集合 */ function Dictionary(maps) { if (maps === void 0) { maps = null; } var _this = _super.call(this, Dictionary.ObjectMaps(maps)) || this; if (isNullOrUndefined(maps)) { _this.maps = {}; } else if (Array.isArray(maps)) { _this.maps = Activator.CreateObject(maps); } else if (TypeInfo.typeof(maps).class == "IEnumerator") { _this.maps = Activator.CreateObject(maps); } else { _this.maps = maps; } return _this; } Object.defineProperty(Dictionary.prototype, "Object", { /** * 返回一个被复制的当前的map对象 */ get: function () { return Framework.Extensions.extend(this.maps); }, enumerable: true, configurable: true }); ///** // * 可以使用``for (var [key, value] of Maps) {}``的语法来进行迭代 //*/ //public get Maps(): Map { // var maps: Map = new Map(); // // 将内部的object转换为可以被迭代的ES6的Map对象 // Object.keys(this.maps) // .forEach(key => maps.set(key, this.maps[key])); // return maps; //} /** * 如果键名称是空值的话,那么这个函数会自动使用caller的函数名称作为键名进行值的获取 * * https://stackoverflow.com/questions/280389/how-do-you-find-out-the-caller-function-in-javascript * * @param key 键名或者序列的索引号 */ Dictionary.prototype.Item = function (key) { if (key === void 0) { key = null; } if (!key) { key = Internal.StackTrace.GetCallerMember().memberName; } if (typeof key == "string") { return (this.maps[key]); } else { return this.sequence[key].value; } }; Object.defineProperty(Dictionary.prototype, "Keys", { /** * 获取这个字典对象之中的所有的键名 */ get: function () { return From(Object.keys(this.maps)); }, enumerable: true, configurable: true }); Object.defineProperty(Dictionary.prototype, "Values", { /** * 获取这个字典对象之中的所有的键值 */ get: function () { return this.Select(function (m) { return m.value; }); }, enumerable: true, configurable: true }); Dictionary.FromMaps = function (maps) { return new Dictionary(maps); }; Dictionary.FromNamedValues = function (values) { return new Dictionary(Activator.CreateObject(values)); }; Dictionary.MapSequence = function (maps) { return new IEnumerator(this.ObjectMaps(maps)); }; /** * 将目标对象转换为一个类型约束的映射序列集合 */ Dictionary.ObjectMaps = function (maps) { var type = TypeInfo.typeof(maps); if (isNullOrUndefined(maps)) { return []; } if (Array.isArray(maps)) { return maps; } else if (type.class == "IEnumerator") { return maps.ToArray(); } else { return From(Object.keys(maps)) .Select(function (key) { return new MapTuple(key, maps[key]); }) .ToArray(); } }; /** * 查看这个字典集合之中是否存在所给定的键名 */ Dictionary.prototype.ContainsKey = function (key) { return key in this.maps; }; /** * 向这个字典对象之中添加一个键值对,请注意,如果key已经存在这个字典对象中了,这个函数会自动覆盖掉key所对应的原来的值 */ Dictionary.prototype.Add = function (key, value) { this.maps[key] = value; this.sequence = Dictionary.ObjectMaps(this.maps); return this; }; /** * 删除一个给定键名所指定的键值对 */ Dictionary.prototype.Delete = function (key) { if (key in this.maps) { delete this.maps[key]; this.sequence = Dictionary.ObjectMaps(this.maps); } return this; }; return Dictionary; }(IEnumerator)); /// /// var TypeScript; (function (TypeScript) { var URLPatterns; (function (URLPatterns) { URLPatterns.hostNamePattern = /:\/\/(www[0-9]?\.)?(.[^/:]+)/i; /** * Regexp pattern for data uri string */ URLPatterns.uriPattern = /data[:]\S+[/]\S+;base64,[a-zA-Z0-9/=+]/ig; /** * Regexp pattern for web browser url string */ URLPatterns.urlPattern = /((https?)|(ftp))[:]\/{2}\S+\.[a-z]+[^ >"]*/ig; })(URLPatterns = TypeScript.URLPatterns || (TypeScript.URLPatterns = {})); /** * URL组成字符串解析模块 */ var URL = /** @class */ (function () { /** * 在这里解析一个URL字符串 */ function URL(url) { // http://localhost/router.html#http://localhost/b.html var token = Strings.GetTagValue(url, "://"); this.protocol = token.name; token = Strings.GetTagValue(token.value, "/"); this.origin = token.name; token = Strings.GetTagValue(token.value, "?"); this.path = token.name; this.fileName = Strings.Empty(this.path) ? "" : TsLinq.PathHelper.basename(this.path); this.hash = From(url.split("#")).Last; if (url.indexOf("#") < 0) { this.hash = ""; } // 将页面的路径标准化 // 应该是一个从wwwroot起始的绝对路径 if (this.path.charAt(0) !== "/") { this.path = "/" + this.path; } var args = URL.UrlQuery(token.value); this.queryArguments = Dictionary .MapSequence(args) .Select(function (m) { return new NamedValue(m.key, m.value); }); } Object.defineProperty(URL.prototype, "query", { /** * URL查询参数 */ get: function () { return this.queryArguments.ToArray(false); }, enumerable: true, configurable: true }); ; URL.prototype.getArgument = function (queryName, caseSensitive, Default) { if (caseSensitive === void 0) { caseSensitive = true; } if (Default === void 0) { Default = ""; } if (Strings.Empty(queryName, false)) { return ""; } else if (!caseSensitive) { queryName = queryName.toLowerCase(); } return this.queryArguments .Where(function (map) { return caseSensitive ? map.name == queryName : map.name.toLowerCase() == queryName; }) .FirstOrDefault({ value: Default }) .value; }; /** * 将URL之中的query部分解析为字典对象 */ URL.UrlQuery = function (args) { if (args) { return DataExtensions.parseQueryString(args, false); } else { return {}; } }; /** * 跳转到url之中的hash编号的文档位置处 * * @param hash ``#xxx``文档节点编号表达式 */ URL.JumpToHash = function (hash) { // Getting Y of target element // Go there directly or some transition window.scrollTo(0, $ts(hash).offsetTop); }; /** * Set url hash without url jump in document */ URL.SetHash = function (hash) { if (history.pushState) { history.pushState(null, null, hash); } else { location.hash = hash; } }; /** * 获取得到当前的url */ URL.WindowLocation = function () { return new URL(window.location.href); }; URL.prototype.toString = function () { var query = From(this.query) .Select(function (q) { return q.name + "=" + encodeURIComponent(q.value); }) .JoinBy("&"); var url = this.protocol + "://" + this.origin + "/" + this.path; if (query) { url = url + "?" + query; } if (this.hash) { url = url + "#" + this.hash; } return url; }; URL.Refresh = function (url) { return url + "&refresh=" + Math.random() * 10000; }; /** * 获取所给定的URL之中的host名称字符串,如果解析失败会返回空值 */ URL.getHostName = function (url) { var match = url.match(URLPatterns.hostNamePattern); if (match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0) { return match[2]; } else { return null; } }; /** * 将目标文本之中的所有的url字符串匹配出来 */ URL.ParseAllUrlStrings = function (text) { var urls = []; for (var _i = 0, _a = Strings.getAllMatches(text, URLPatterns.urlPattern); _i < _a.length; _i++) { var url = _a[_i]; urls.push(url[0]); } return urls; }; URL.IsWellFormedUriString = function (uri) { var matches = uri.match(URLPatterns.uriPattern); if (isNullOrUndefined(matches)) { return false; } var match = matches[0]; if (!Strings.Empty(match, true)) { return uri.indexOf(match) == 0; } else { return false; } }; return URL; }()); TypeScript.URL = URL; })(TypeScript || (TypeScript = {})); var TsLinq; (function (TsLinq) { /** * String helpers for the file path string. */ var PathHelper; (function (PathHelper) { /** * 只保留文件名(已经去除了文件夹路径以及文件名最后的拓展名部分) */ function basename(fileName) { var nameTokens = From(Strings.RTrim(fileName, "/").split("/")).Last.split("."); if (nameTokens.length == 1) { return nameTokens[0]; } var name = new IEnumerator(nameTokens) .Take(nameTokens.length - 1) .JoinBy("."); return name; } PathHelper.basename = basename; function extensionName(fileName) { var nameTokens = From(Strings.RTrim(fileName, "/").split("/")).Last.split("."); if (nameTokens.length == 1) { // 没有拓展名 return ""; } else { return nameTokens[nameTokens.length - 1]; } } PathHelper.extensionName = extensionName; /** * 函数返回文件名或者文件夹的名称 */ function fileName(path) { return From(Strings.RTrim(path, "/").split("/")).Last; } PathHelper.fileName = fileName; })(PathHelper = TsLinq.PathHelper || (TsLinq.PathHelper = {})); })(TsLinq || (TsLinq = {})); /** * 这个枚举选项的值会影响框架之中的调试器的终端输出行为 */ var Modes; (function (Modes) { /** * Framework debug level * (这个等级下会输出所有信息) */ Modes[Modes["debug"] = 0] = "debug"; /** * development level * (这个等级下会输出警告信息) */ Modes[Modes["development"] = 10] = "development"; /** * production level * (只会输出错误信息,默认等级) */ Modes[Modes["production"] = 200] = "production"; })(Modes || (Modes = {})); /** * HTML文档操作帮助函数 */ var DOM; (function (DOM) { /** * File download helper * * @param name The file save name for download operation * @param uri The file object to download */ function download(name, uri) { if (navigator.msSaveOrOpenBlob) { navigator.msSaveOrOpenBlob(DataExtensions.uriToBlob(uri), name); } else { downloadImpl(name, uri); } } DOM.download = download; function downloadImpl(name, uri) { var saveLink = $ts(''); var downloadSupported = 'download' in saveLink; if (downloadSupported) { saveLink.download = name; saveLink.style.display = 'none'; document.body.appendChild(saveLink); try { var blob = DataExtensions.uriToBlob(uri); var url = URL.createObjectURL(blob); saveLink.href = url; saveLink.onclick = function () { requestAnimationFrame(function () { URL.revokeObjectURL(url); }); }; } catch (e) { if (TypeScript.logging.outputWarning) { console.warn('This browser does not support object URLs. Falling back to string URL.'); } saveLink.href = uri; } saveLink.click(); document.body.removeChild(saveLink); } else { window.open(uri, '_temp', 'menubar=no,toolbar=no,status=no'); } } /** * 尝试获取当前的浏览器的大小 */ function clientSize() { var w = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0], x = w.innerWidth || e.clientWidth || g.clientWidth, y = w.innerHeight || e.clientHeight || g.clientHeight; return [x, y]; } DOM.clientSize = clientSize; /** * 向指定id编号的div添加select标签的组件 * * @param containerID 这个编号不带有``#``前缀,这个容器可以是一个空白的div或者目标````标签的时候,则要求selectName和className都必须要是空值 * @param items 这个数组应该是一个``[title => value]``的键值对列表 */ function AddSelectOptions(items, containerID, selectName, className) { if (selectName === void 0) { selectName = null; } if (className === void 0) { className = null; } var options = From(items) .Select(function (item) { return ""; }) .JoinBy("\n"); var html; if (isNullOrUndefined(selectName) && isNullOrUndefined(className)) { // 是一个\n " + options + "\n "; } $ts("#" + containerID).innerHTML = html; } DOM.AddSelectOptions = AddSelectOptions; /** * @param headers 表格之中所显示的表头列表,也可以通过这个参数来对表格之中 * 所需要进行显示的列进行筛选以及显示控制: * + 如果这个参数为默认的空值,则说明显示所有的列数据 * + 如果这个参数不为空值,则会显示这个参数所指定的列出来 * + 可以通过``map [propertyName => display title]``来控制表头的标题输出 */ function CreateHTMLTableNode(rows, headers, attrs) { if (headers === void 0) { headers = null; } if (attrs === void 0) { attrs = null; } var thead = $ts(""); var tbody = $ts(""); var fields; if (Array.isArray(rows)) { fields = headerMaps(headers || $ts(Object.keys(rows[0]))); } else { fields = headerMaps(headers || $ts(Object.keys(rows.First))); } var rowHTML = function (r) { var tr = $ts(""); // 在这里将会控制列的显示 fields.forEach(function (m) { return tr.appendChild($ts("").display(r[m.key])); }); return tr; }; if (Array.isArray(rows)) { rows.forEach(function (r) { return tbody.appendChild(rowHTML(r)); }); } else { rows.ForEach(function (r) { return tbody.appendChild(rowHTML(r)); }); } fields.forEach(function (r) { return thead.appendChild($ts("", { id: r.value }).display(r.value)); }); return $ts("", attrs) .asExtends .append(thead) .append(tbody) .HTMLElement; } DOM.CreateHTMLTableNode = CreateHTMLTableNode; /** * 向给定编号的div对象之中添加一个表格对象 * * @param headers 表头 * @param div 新生成的table将会被添加在这个div之中,应该是一个带有``#``符号的节点id查询表达式 * @param attrs ``
``的属性值,包括id,class等 */ function AddHTMLTable(rows, div, headers, attrs) { if (headers === void 0) { headers = null; } if (attrs === void 0) { attrs = null; } var id = div + "-table"; if (attrs) { if (!attrs.id) { attrs.id = id; } } else { attrs = { id: id }; } $ts(div).appendChild(CreateHTMLTableNode(rows, headers, attrs)); } DOM.AddHTMLTable = AddHTMLTable; /** * @param headers ``[propertyName => displayTitle]`` */ function headerMaps(headers) { var type = TypeInfo.typeof(headers); if (type.IsArrayOf("string")) { return From(headers) .Select(function (h) { return new MapTuple(h, h); }) .ToArray(); } else if (type.IsArrayOf(TypeExtensions.DictionaryMap)) { return headers; } else if (type.IsEnumerator && typeof headers.First == "string") { return headers .Select(function (h) { return new MapTuple(h, h); }) .ToArray(); } else if (type.IsEnumerator && TypeInfo.getClass(headers.First) == TypeExtensions.DictionaryMap) { return headers.ToArray(); } else { throw "Invalid sequence type: " + type.class; } } })(DOM || (DOM = {})); var DOM; (function (DOM) { var InputValueGetter; (function (InputValueGetter) { /** * Query meta tag content value by name * * @param allowQueryParent 当当前的文档之中不存在目标meta标签的时候, * 如果当前文档为iframe文档,则是否允许继续往父节点的文档做查询? * 默认为False,即只在当前文档环境之中进行查询操作 * @param Default 查询失败的时候所返回来的默认值 */ function metaValue(name, Default, allowQueryParent) { if (Default === void 0) { Default = null; } if (allowQueryParent === void 0) { allowQueryParent = false; } var selector = "meta[name~=\"" + name + "\"]"; var meta = document.querySelector(selector); var getContent = function () { if (meta) { var content = meta.getAttribute("content"); return content ? content : Default; } else { if (TypeScript.logging.outputWarning) { console.warn(selector + " not found in current context!"); } return Default; } }; if (!meta && allowQueryParent) { meta = parent.window .document .querySelector(selector); } return getContent(); } InputValueGetter.metaValue = metaValue; function getValue(id, strict) { if (strict === void 0) { strict = true; } var input = $ts(Internal.Handlers.EnsureNodeId(id)); switch (input.tagName.toLowerCase()) { case "input": return inputValue(input); case "select": return selectOptionValues(input); case "textarea": return largeText(input); default: if (strict) { throw "Get value of <" + input.tagName + "> is not supported!"; } else { // 强制读取目标节点的value属性值 return input.getAttribute("value"); } } } InputValueGetter.getValue = getValue; function inputValue(input) { if (input.type == "checkbox") { return checkboxInput(input); } else { return input.value; } } InputValueGetter.inputValue = inputValue; /** * 这个函数所返回来的值是和checkbox的数量相关的, * 1. 如果有多个checkbox,则会返回一个数组 * 2. 反之如果只有一个checkbox,则只会返回一个逻辑值,用来表示是否选中该选项 */ function checkboxInput(input) { var inputs = document.getElementsByName(input.name); var values = []; if (inputs.length == 1) { return input.checked; } else { inputs.forEach(function (box) { var value = box.value; if (box.checked) { values.push(value); } }); return values; } } InputValueGetter.checkboxInput = checkboxInput; ; /** * 获取被选中的选项的值的列表 */ function selectOptionValues(input) { var selects = getSelectedOptions(input); var values = []; for (var _i = 0, selects_1 = selects; _i < selects_1.length; _i++) { var sel = selects_1[_i]; var value = sel.value; if (!value) { value = sel.innerText; } values.push(value); } return values; } InputValueGetter.selectOptionValues = selectOptionValues; /** * return array containing references to selected option elements */ function getSelectedOptions(sel) { var opts = []; var opt; // loop through options in select list for (var i = 0, len = sel.options.length; i < len; i++) { opt = sel.options[i]; // check if selected if (opt.selected) { // add to array of option elements to return from this function opts.push(opt); } } return opts; } InputValueGetter.getSelectedOptions = getSelectedOptions; function largeText(text) { } InputValueGetter.largeText = largeText; })(InputValueGetter = DOM.InputValueGetter || (DOM.InputValueGetter = {})); })(DOM || (DOM = {})); var data; (function (data_1) { /** * A numeric range model. * (一个数值范围) */ var NumericRange = /** @class */ (function () { // #endregion // #region Constructors (1) /** * Create a new numeric range object */ function NumericRange(min, max) { if (max === void 0) { max = null; } if (typeof min == "number" && (!isNullOrUndefined(max))) { this.min = min; this.max = max; } else { var range = min; this.min = range.min; this.max = range.max; } } Object.defineProperty(NumericRange.prototype, "range", { /** * ``[min, max]`` */ get: function () { return [this.min, this.max]; }, enumerable: true, configurable: true }); Object.defineProperty(NumericRange.prototype, "Length", { // #endregion // #region Public Accessors (1) /** * The delta length between the max and the min value. */ get: function () { return this.max - this.min; }, enumerable: true, configurable: true }); // #endregion // #region Public Static Methods (1) /** * 从一个数值序列之中创建改数值序列的值范围 * * @param numbers A given numeric data sequence. */ NumericRange.Create = function (numbers) { var seq = Array.isArray(numbers) ? $ts(numbers) : numbers; var min = seq.Min(); var max = seq.Max(); return new NumericRange(min, max); }; // #endregion // #region Public Methods (3) /** * 判断目标数值是否在当前的这个数值范围之内 */ NumericRange.prototype.IsInside = function (x) { return x >= this.min && x <= this.max; }; /** * 将一个位于此区间内的实数映射到另外一个区间之中 */ NumericRange.prototype.ScaleMapping = function (x, range) { var percentage = (x - this.min) / this.Length; var y = percentage * (range.max - range.min) + range.min; return y; }; /** * Get a numeric sequence within current range with a given step * * @param step The delta value of the step forward, * by default is 10% of the range length. */ NumericRange.prototype.PopulateNumbers = function (step) { if (step === void 0) { step = (this.Length / 10); } var data = []; for (var x = this.min; x < this.max; x += step) { data.push(x); } return data; }; /** * Display the range in format ``[min, max]`` */ NumericRange.prototype.toString = function () { return "[" + this.min + ", " + this.max + "]"; }; return NumericRange; }()); data_1.NumericRange = NumericRange; })(data || (data = {})); /// /// /// /// /// /// /// /** * The internal implementation of the ``$ts`` object. */ var Internal; (function (Internal) { Internal.StringEval = new Internal.Handlers.stringEval(); /** * 对``$ts``对象的内部实现过程在这里 */ function Static() { var handle = Internal.Handlers.Shared; var ins = function (any, args) { return queryFunction(handle, any, args); }; var stringEval = handle.string(); ins.mode = Modes.production; ins = extendsUtils(ins, stringEval); ins = extendsLINQ(ins); ins = extendsHttpHelpers(ins); ins = extendsSelector(ins); return ins; } Internal.Static = Static; function extendsHttpHelpers(ts) { ts.post = function (url, data, callback, options) { var contentType = HttpHelpers.measureContentType(data); var post = { type: contentType, data: data, sendContentType: (options || {}).sendContentType || true }; HttpHelpers.POST(urlSolver(url), post, function (response) { if (callback) { callback(handleJSON(response)); } }); }; ts.getText = function (url, callback, options) { if (options === void 0) { options = { nullForNotFound: false }; } HttpHelpers.GetAsyn(urlSolver(url), function (text, code) { if (code != 200) { if (options.nullForNotFound) { callback(""); } else { callback(text); } } else { callback(text); } }); }; ts.get = function (url, callback) { HttpHelpers.GetAsyn(urlSolver(url), function (response) { if (callback) { callback(handleJSON(response)); } }); }; ts.upload = function (url, file, callback) { HttpHelpers.UploadFile(urlSolver(url), file, null, function (response) { if (callback) { callback(handleJSON(response)); } }); }; ts.location = buildURLHelper(); ts.parseURL = (function (url) { return new TypeScript.URL(url); }); ts.goto = function (url, opt) { if (opt === void 0) { opt = { currentFrame: false, lambda: false }; } if (url.charAt(0) == "#") { // url是一个文档节点id表达式,则执行文档内跳转 TypeScript.URL.JumpToHash(url); } else if (opt.lambda) { return function () { Goto(url, opt.currentFrame); }; } else { Goto(url, opt.currentFrame); } }; return ts; } function buildURLHelper() { var url = TypeScript.URL.WindowLocation(); var location = function (arg, caseSensitive, Default) { if (caseSensitive === void 0) { caseSensitive = true; } if (Default === void 0) { Default = ""; } return url.getArgument(arg, caseSensitive, Default); }; location.path = url.path || "/"; location.fileName = url.fileName; location.hash = function (arg, urlhash) { if (arg === void 0) { arg = { trimprefix: true, doJump: false }; } if (urlhash === void 0) { urlhash = null; } if (!isNullOrUndefined(urlhash)) { if (((typeof arg == "boolean") && (arg === true)) || arg.doJump) { window.location.hash = urlhash; } else { TypeScript.URL.SetHash(urlhash); } } else { // 获取当前url字符串之中hash标签值 var tag = window.location.hash; var trimprefix; if (typeof arg == "boolean") { trimprefix = arg; } else { trimprefix = arg.trimprefix; } if (tag && trimprefix && (tag.length > 1)) { return tag.substr(1); } else { return isNullOrUndefined(tag) ? "" : tag; } } }; return location; } var querySymbols = [":", "_"]; function isValidSymbol(c) { if (querySymbols.indexOf(c) > -1) { return true; } else { return Strings.isNumber(c) || Strings.isAlphabet(c); } } /** * 支持对meta标签解析内容的还原 * * @param url 对于meta标签,只会转义字符串最开始的url部分 */ function urlSolver(url, currentFrame) { // var url = "@view:task/user/xyz"; // 在这里指定标签规则: // 1. 以@符号起始,能够包含的符号为冒号:,下划线_,字母和数字,其他的符号都会被看作为结束符号 // 2. meta查询标签必须位于url字符串的起始位置,否则不进行解析 if (currentFrame === void 0) { currentFrame = false; } if (url.charAt(0) == "@") { // 可能是对meta标签的查询 // 去除第一个@标记符号之后进行查询 // 因为url可能会带有@,所以可能会出现误查询的情况,所以在这里默认值设置为url // 当误查询的时候就会查询不到结果的时候,就可以返回当前的url值了 var tag = []; var c; var metaQuery; // 第一个符号是@符号,跳过 for (var i = 1; i < url.length; i++) { if (isValidSymbol(c = url.charAt(i))) { tag.push(c); } else { break; } } metaQuery = tag.join(""); url = DOM.InputValueGetter.metaValue(metaQuery, metaQuery, !currentFrame) + url.substr(tag.length + 1); } return url; } Internal.urlSolver = urlSolver; function handleJSON(response) { if (typeof response == "string") { /* if (TsLinq.URL.IsWellFormedUriString(response)) { // 是一个uri字符串,则不做解析 return response; }*/ // 尝试以json的格式进行结果的解析 try { return JSON.parse(response); } catch (ex) { console.error("Invalid json text: "); console.error(response); throw ex; } } else { return response; } } function extendsUtils(ts, stringEval) { ts.imports = function (jsURL, callback, onErrorResumeNext, echo) { if (callback === void 0) { callback = DoNothing; } if (onErrorResumeNext === void 0) { onErrorResumeNext = false; } if (echo === void 0) { echo = false; } return new HttpHelpers.Imports(jsURL, onErrorResumeNext, echo).doLoad(callback); }; ts.eval = function (script, lzw, callback) { if (lzw === void 0) { lzw = false; } if (lzw) { script = LZW.decode(script); } HttpHelpers.Imports.doEval(script, callback); }; ts.value = DOM.InputValueGetter.getValue; ts.inject = function (iframe, fun) { var frame = $ts(iframe); var envir = frame.contentWindow; if (TypeScript.logging.outputEverything) { console.log(fun); } if (Array.isArray(fun)) { for (var _i = 0, fun_1 = fun; _i < fun_1.length; _i++) { var p = fun_1[_i]; envir.eval(p.toString()); } } else if (typeof fun == "string") { envir.eval(fun); } else { envir.eval(fun.toString()); } }; ts.text = function (id, htmlText) { if (htmlText === void 0) { htmlText = false; } var nodeID = Internal.Handlers.EnsureNodeId(id); var node = stringEval.doEval(nodeID, null, null); return htmlText ? node.innerHTML : node.innerText; }; ts.loadJSON = function (id) { return JSON.parse(ts.text(id)); }; // file path helpers ts.parseFileName = TsLinq.PathHelper.fileName; /** * 得到不带有拓展名的文件名部分的字符串 * * @param path Full name */ ts.baseName = TsLinq.PathHelper.basename; /** * 得到不带小数点的文件拓展名字符串 * * @param path Full name */ ts.extensionName = TsLinq.PathHelper.extensionName; ts.withExtensionName = function (path, ext) { var fileExt = $ts.extensionName(path); var equals = fileExt.toLowerCase() == ext.toLowerCase(); return equals; }; ts.doubleRange = data.NumericRange.Create; return ts; } function extendsLINQ(ts) { ts.isNullOrEmpty = function (obj) { return IsNullOrEmpty(obj); }; ts.from = From; ts.csv = { toObjects: function (data) { return csv.dataframe.Parse(data).Objects(); }, toText: function (data) { return csv.toDataFrame(data).buildDoc(); } }; ts.evalHTML = { table: DOM.CreateHTMLTableNode, selectOptions: DOM.AddSelectOptions }; ts.appendTable = DOM.AddHTMLTable; return ts; } function extendsSelector(ts) { ts.select = function (query, context) { if (context === void 0) { context = window; } return Internal.Handlers.stringEval.select(query, context); }; ts.select.getSelectedOptions = function (query, context) { if (context === void 0) { context = window; } var sel = $ts(query, { context: context }); var options = DOM.InputValueGetter.getSelectedOptions(sel); return new DOMEnumerator(options); }; ts.select.getOption = function (query, context) { if (context === void 0) { context = window; } var sel = $ts(query, { context: context }); var options = DOM.InputValueGetter.getSelectedOptions(sel); if (options.length == 0) { return null; } else { return options[0].value; } }; return ts; } function queryFunction(handle, any, args) { var type = TypeInfo.typeof(any); var typeOf = type.typeOf; // symbol renames due to problem in js compress tool // // ERROR - "eval" cannot be redeclared in strict mode // var queryEval = typeOf in handle ? handle[typeOf]() : null; var isHtmlCollection = (typeOf == "object") && (type.class == "HTMLCollection" || type.class == "NodeListOf"); if (isHtmlCollection) { return Internal.Handlers.Shared.HTMLCollection().doEval(any, type, args); } else if (type.IsArray) { // 转化为序列集合对象,相当于from函数 return queryEval.doEval(any, type, args); } else if (type.typeOf == "function") { // 当html文档加载完毕之后就会执行传递进来的这个 // 函数进行初始化 if (TypeScript.logging.outputEverything && !isNullOrUndefined(args) && TypeInfo.getClass(args) == "HTMLIFrameElement") { console.log("Apply a new ready event on iframe:"); console.log(args); } DOM.Events.ready(any, ["interactive", "complete"], args); } else if (!isNullOrUndefined(eval)) { // 对html文档之中的节点元素进行查询操作 // 或者创建新的节点 return queryEval.doEval(any, type, args); } else { // Fix for js compress tool error: // // ERROR - the "eval" object cannot be reassigned in strict mode var unsureEval = handle[type.class]; if (!isNullOrUndefined(unsureEval)) { return unsureEval().doEval(any, type, args); } else { throw "Unsupported data type: " + type.toString(); } } } Internal.queryFunction = queryFunction; })(Internal || (Internal = {})); /// /// /// /// /// /// /// /// // note: 2018-12-25 // this module just working on browser, some of the DOM api // related function may not works as expected on server side // ``nodejs`` Environment. if (typeof String.prototype['startsWith'] != 'function') { String.prototype['startsWith'] = function (str) { return this.slice(0, str.length) == str; }; } /** * 动态加载脚本文件,然后在完成脚本文件的加载操作之后,执行一个指定的函数操作 * * @param callback 如果这个函数之中存在有HTML文档的操作,则可能会需要将代码放在``$ts(() => {...})``之中, * 等待整个html文档加载完毕之后再做程序的执行,才可能会得到正确的执行结果 */ function $imports(jsURL, callback, onErrorResumeNext, echo) { if (callback === void 0) { callback = DoNothing; } if (onErrorResumeNext === void 0) { onErrorResumeNext = false; } if (echo === void 0) { echo = false; } return new HttpHelpers .Imports(jsURL, onErrorResumeNext, echo) .doLoad(callback); } /** * 使用script标签进行脚本文件的加载 * 因为需要向body添加script标签,所以这个函数会需要等到文档加载完成之后才会被执行 */ function $include(jsURL) { if (typeof jsURL == "string") { jsURL = [jsURL]; } $ts(function () { return jsURL.forEach(function (js) { var script = $ts("