From: Alexander Ebert Date: Thu, 15 Oct 2020 17:47:12 +0000 (+0200) Subject: Updated the Dictionary implementation X-Git-Tag: 5.4.0_Alpha_1~704^2~67 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=592ea62f99d5bd58e625a8940bfc905046f09720;p=GitHub%2FWoltLab%2FWCF.git Updated the Dictionary implementation --- diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js index 266180e087..17be029c99 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Core.js @@ -66,7 +66,7 @@ define(["require", "exports"], function (require, exports) { function extend(out, ...args) { out = out || {}; const newObj = clone(out); - for (let i = 1, length = args.length; i < length; i++) { + for (let i = 0, length = args.length; i < length; i++) { const obj = args[i]; if (!obj) continue; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js index 2467e33314..798fd1fdb3 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Dictionary.js @@ -1,174 +1,92 @@ -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -define(["require", "exports", "./Core"], function (require, exports, Core) { +define(["require", "exports"], function (require, exports) { "use strict"; - Core = __importStar(Core); - var _hasMap = window.hasOwnProperty('Map') && typeof window.Map === 'function'; + /** + * Dictionary implementation relying on an object or if supported on a Map to hold key => value data. + * + * If you're looking for a dictionary with object keys, please see `WoltLabSuite/Core/ObjectMap`. + * + * This is a legacy implementation, that does not implement all methods of `Map`, furthermore it has + * the side effect of converting all numeric keys to string values, treating 1 === "1". + * + * @author Tim Duesterhus, Alexander Ebert + * @copyright 2001-2019 WoltLab GmbH + * @license GNU Lesser General Public License + * @module Dictionary (alias) + * @module WoltLabSuite/Core/Dictionary + * @deprecated 5.4 + */ /** * @constructor */ - function Dictionary() { - this._dictionary = (_hasMap) ? new Map() : {}; - } - Dictionary.prototype = { + class Dictionary { + constructor() { + this._dictionary = new Map(); + } /** * Sets a new key with given value, will overwrite an existing key. - * - * @param {(number|string)} key key - * @param {?} value value */ - set: function (key, value) { - if (typeof key === 'number') - key = key.toString(); - if (typeof key !== 'string') { - throw new TypeError('Only strings can be used as keys, rejected \'' + key + '\' (' + typeof key + ').'); - } - if (_hasMap) - this._dictionary.set(key, value); - else - this._dictionary[key] = value; - }, + set(key, value) { + this._dictionary.set(key.toString(), value); + } /** * Removes a key from the dictionary. - * - * @param {(number|string)} key key */ - 'delete': function (key) { - if (typeof key === 'number') - key = key.toString(); - if (_hasMap) - this._dictionary['delete'](key); - else - this._dictionary[key] = undefined; - }, + delete(key) { + return this._dictionary.delete(key.toString()); + } /** * Returns true if dictionary contains a value for given key and is not undefined. - * - * @param {(number|string)} key key - * @return {boolean} true if key exists and value is not undefined */ - has: function (key) { - if (typeof key === 'number') - key = key.toString(); - if (_hasMap) - return this._dictionary.has(key); - else { - return (this._dictionary.hasOwnProperty(key) && typeof this._dictionary[key] !== 'undefined'); - } - }, + has(key) { + return this._dictionary.has(key.toString()); + } /** * Retrieves a value by key, returns undefined if there is no match. - * - * @param {(number|string)} key key - * @return {*} */ - get: function (key) { - if (typeof key === 'number') - key = key.toString(); - if (this.has(key)) { - if (_hasMap) - return this._dictionary.get(key); - else - return this._dictionary[key]; - } - return undefined; - }, + get(key) { + return this._dictionary.get(key.toString()); + } /** * Iterates over the dictionary keys and values, callback function should expect the * value as first parameter and the key name second. - * - * @param {function<*, string>} callback callback for each iteration */ - forEach: function (callback) { - if (typeof callback !== 'function') { - throw new TypeError('forEach() expects a callback as first parameter.'); - } - if (_hasMap) { - this._dictionary.forEach(callback); - } - else { - var keys = Object.keys(this._dictionary); - for (var i = 0, length = keys.length; i < length; i++) { - callback(this._dictionary[keys[i]], keys[i]); - } - } - }, + forEach(callback) { + this._dictionary.forEach(callback); + } /** * Merges one or more Dictionary instances into this one. - * - * @param {...Dictionary} var_args one or more Dictionary instances */ - merge: function () { - for (var i = 0, length = arguments.length; i < length; i++) { - var dictionary = arguments[i]; - if (!(dictionary instanceof Dictionary)) { - throw new TypeError('Expected an object of type Dictionary, but argument ' + i + ' is not.'); - } - dictionary.forEach((function (value, key) { - this.set(key, value); - }).bind(this)); + merge(...dictionaries) { + for (let i = 0, length = dictionaries.length; i < length; i++) { + const dictionary = dictionaries[i]; + dictionary.forEach((value, key) => this.set(key, value)); } - }, + } /** * Returns the object representation of the dictionary. - * - * @return {object} dictionary's object representation */ - toObject: function () { - if (!_hasMap) - return Core.clone(this._dictionary); - var object = {}; - this._dictionary.forEach(function (value, key) { - object[key] = value; - }); + toObject() { + const object = {}; + this._dictionary.forEach((value, key) => object[key] = value); return object; - }, - }; - /** - * Creates a new Dictionary based on the given object. - * All properties that are owned by the object will be added - * as keys to the resulting Dictionary. - * - * @param {object} object - * @return {Dictionary} - */ - Dictionary.fromObject = function (object) { - var result = new Dictionary(); - for (var key in object) { - if (object.hasOwnProperty(key)) { - result.set(key, object[key]); - } } - return result; - }; - Object.defineProperty(Dictionary.prototype, 'size', { - enumerable: false, - configurable: true, - get: function () { - if (_hasMap) { - return this._dictionary.size; - } - else { - return Object.keys(this._dictionary).length; + /** + * Creates a new Dictionary based on the given object. + * All properties that are owned by the object will be added + * as keys to the resulting Dictionary. + */ + static fromObject(object) { + const result = new Dictionary(); + for (const key in object) { + if (object.hasOwnProperty(key)) { + result.set(key, object[key]); + } } - }, - }); + return result; + } + get size() { + return this._dictionary.size; + } + } return Dictionary; }); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts index 7e31a9135b..ee0524bb97 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Core.ts @@ -71,7 +71,7 @@ export function extend(out: object, ...args: object[]): object { out = out || {}; const newObj = clone(out); - for (let i = 1, length = args.length; i < length; i++) { + for (let i = 0, length = args.length; i < length; i++) { const obj = args[i]; if (!obj) continue; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts index 0c9dfa5619..b8c93704cd 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Dictionary.ts @@ -2,172 +2,100 @@ * Dictionary implementation relying on an object or if supported on a Map to hold key => value data. * * If you're looking for a dictionary with object keys, please see `WoltLabSuite/Core/ObjectMap`. + * + * This is a legacy implementation, that does not implement all methods of `Map`, furthermore it has + * the side effect of converting all numeric keys to string values, treating 1 === "1". * * @author Tim Duesterhus, Alexander Ebert * @copyright 2001-2019 WoltLab GmbH * @license GNU Lesser General Public License * @module Dictionary (alias) * @module WoltLabSuite/Core/Dictionary + * @deprecated 5.4 */ -import * as Core from './Core'; - -var _hasMap = window.hasOwnProperty('Map') && typeof window.Map === 'function'; - /** * @constructor */ -function Dictionary() { - this._dictionary = (_hasMap) ? new Map() : {}; -} +class Dictionary { + private readonly _dictionary = new Map(); -Dictionary.prototype = { /** * Sets a new key with given value, will overwrite an existing key. - * - * @param {(number|string)} key key - * @param {?} value value */ - set: function (key, value) { - if (typeof key === 'number') key = key.toString(); - - if (typeof key !== 'string') { - throw new TypeError('Only strings can be used as keys, rejected \'' + key + '\' (' + typeof key + ').'); - } - - if (_hasMap) this._dictionary.set(key, value); - else this._dictionary[key] = value; - }, + set(key: number | string, value: any): void { + this._dictionary.set(key.toString(), value); + } /** * Removes a key from the dictionary. - * - * @param {(number|string)} key key */ - 'delete': function (key) { - if (typeof key === 'number') key = key.toString(); - - if (_hasMap) this._dictionary['delete'](key); - else this._dictionary[key] = undefined; - }, + delete(key: number | string): boolean { + return this._dictionary.delete(key.toString()); + } /** * Returns true if dictionary contains a value for given key and is not undefined. - * - * @param {(number|string)} key key - * @return {boolean} true if key exists and value is not undefined */ - has: function (key) { - if (typeof key === 'number') key = key.toString(); - - if (_hasMap) return this._dictionary.has(key); - else { - return (this._dictionary.hasOwnProperty(key) && typeof this._dictionary[key] !== 'undefined'); - } - }, + has(key: number | string): boolean { + return this._dictionary.has(key.toString()); + } /** * Retrieves a value by key, returns undefined if there is no match. - * - * @param {(number|string)} key key - * @return {*} */ - get: function (key) { - if (typeof key === 'number') key = key.toString(); - - if (this.has(key)) { - if (_hasMap) return this._dictionary.get(key); - else return this._dictionary[key]; - } - - return undefined; - }, + get(key: number | string): any { + return this._dictionary.get(key.toString()); + } /** * Iterates over the dictionary keys and values, callback function should expect the * value as first parameter and the key name second. - * - * @param {function<*, string>} callback callback for each iteration */ - forEach: function (callback) { - if (typeof callback !== 'function') { - throw new TypeError('forEach() expects a callback as first parameter.'); - } - - if (_hasMap) { - this._dictionary.forEach(callback); - } else { - var keys = Object.keys(this._dictionary); - for (var i = 0, length = keys.length; i < length; i++) { - callback(this._dictionary[keys[i]], keys[i]); - } - } - }, + forEach(callback: (value: any, key: string) => void): void { + this._dictionary.forEach(callback); + } /** * Merges one or more Dictionary instances into this one. - * - * @param {...Dictionary} var_args one or more Dictionary instances */ - merge: function () { - for (var i = 0, length = arguments.length; i < length; i++) { - var dictionary = arguments[i]; - if (!(dictionary instanceof Dictionary)) { - throw new TypeError('Expected an object of type Dictionary, but argument ' + i + ' is not.'); - } + merge(...dictionaries: Dictionary[]): void { + for (let i = 0, length = dictionaries.length; i < length; i++) { + const dictionary = dictionaries[i]; - (dictionary as any).forEach((function (value, key) { - this.set(key, value); - }).bind(this)); + dictionary.forEach((value, key) => this.set(key, value)); } - }, + } /** * Returns the object representation of the dictionary. - * - * @return {object} dictionary's object representation */ - toObject: function () { - if (!_hasMap) return Core.clone(this._dictionary); - - var object = {}; - this._dictionary.forEach(function (value, key) { - object[key] = value; - }); + toObject(): object { + const object = {}; + this._dictionary.forEach((value, key) => object[key] = value); return object; - }, -}; - -/** - * Creates a new Dictionary based on the given object. - * All properties that are owned by the object will be added - * as keys to the resulting Dictionary. - * - * @param {object} object - * @return {Dictionary} - */ -Dictionary.fromObject = function (object) { - var result = new Dictionary(); - - for (var key in object) { - if (object.hasOwnProperty(key)) { - result.set(key, object[key]); - } } - return result; -}; + /** + * Creates a new Dictionary based on the given object. + * All properties that are owned by the object will be added + * as keys to the resulting Dictionary. + */ + static fromObject (object: object): Dictionary { + const result = new Dictionary(); -Object.defineProperty(Dictionary.prototype, 'size', { - enumerable: false, - configurable: true, - get: function () { - if (_hasMap) { - return this._dictionary.size; - } else { - return Object.keys(this._dictionary).length; + for (const key in object) { + if (object.hasOwnProperty(key)) { + result.set(key, object[key]); + } } - }, -}); + + return result; + } + + get size(): number { + return this._dictionary.size; + } +} export = Dictionary;