????
Current Path : C:/inetpub/vhost/qnquyhoach.nextform.vn/api/node_modules/comment-json/src/ |
Current File : C:/inetpub/vhost/qnquyhoach.nextform.vn/api/node_modules/comment-json/src/array.js |
const {isArray} = require('core-util-is') const {sort} = require('array-timsort') const { SYMBOL_PREFIXES, UNDEFINED, symbol, copy_comments, swap_comments } = require('./common') const reverse_comments = array => { const {length} = array let i = 0 const max = length / 2 for (; i < max; i ++) { swap_comments(array, i, length - i - 1) } } const move_comment = (target, source, i, offset, remove) => { copy_comments(target, source, i + offset, i, remove) } const move_comments = ( // `Array` target array target, // `Array` source array source, // `number` start index start, // `number` number of indexes to move count, // `number` offset to move offset, // `boolean` whether should remove the comments from source remove ) => { if (offset > 0) { let i = count // | count | offset | // source: ------------- // target: ------------- // | remove | // => remove === offset // From [count - 1, 0] while (i -- > 0) { move_comment(target, source, start + i, offset, remove) } return } let i = 0 // | remove | count | // ------------- // ------------- // | offset | // From [0, count - 1] while (i < count) { const ii = i ++ move_comment(target, source, start + ii, offset, remove) } } const remove_comments = (array, key) => { SYMBOL_PREFIXES.forEach(prefix => { const prop = symbol(prefix, key) delete array[prop] }) } const get_mapped = (map, key) => { let mapped = key while (mapped in map) { mapped = map[mapped] } return mapped } class CommentArray extends Array { // - deleteCount + items.length // We should avoid `splice(begin, deleteCount, ...items)`, // because `splice(0, undefined)` is not equivalent to `splice(0)`, // as well as: // - slice splice (...args) { const {length} = this const ret = super.splice(...args) // #16 // If no element removed, we might still need to move comments, // because splice could add new items // if (!ret.length) { // return ret // } // JavaScript syntax is silly // eslint-disable-next-line prefer-const let [begin, deleteCount, ...items] = args if (begin < 0) { begin += length } if (arguments.length === 1) { deleteCount = length - begin } else { deleteCount = Math.min(length - begin, deleteCount) } const { length: item_length } = items // itemsToDelete: - // itemsToAdd: + // | dc | count | // =======-------------============ // =======++++++============ // | il | const offset = item_length - deleteCount const start = begin + deleteCount const count = length - start move_comments(this, this, start, count, offset, true) return ret } slice (...args) { const {length} = this const array = super.slice(...args) if (!array.length) { return new CommentArray() } let [begin, before] = args // Ref: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice if (before === UNDEFINED) { before = length } else if (before < 0) { before += length } if (begin < 0) { begin += length } else if (begin === UNDEFINED) { begin = 0 } move_comments(array, this, begin, before - begin, - begin) return array } unshift (...items) { const {length} = this const ret = super.unshift(...items) const { length: items_length } = items if (items_length > 0) { move_comments(this, this, 0, length, items_length, true) } return ret } shift () { const ret = super.shift() const {length} = this remove_comments(this, 0) move_comments(this, this, 1, length, - 1, true) return ret } reverse () { super.reverse() reverse_comments(this) return this } pop () { const ret = super.pop() // Removes comments remove_comments(this, this.length) return ret } concat (...items) { let {length} = this const ret = super.concat(...items) if (!items.length) { return ret } move_comments(ret, this, 0, this.length, 0) items.forEach(item => { const prev = length length += isArray(item) ? item.length : 1 if (!(item instanceof CommentArray)) { return } move_comments(ret, item, 0, item.length, prev) }) return ret } sort (...args) { const result = sort( this, // Make sure there is no more than one argument ...args.slice(0, 1) ) // For example, // if we sort ['b', 'd', 'c', 'a'], // then `result` will be [3, 0, 2, 1], and the array is ['a', 'b', 'c', 'd'] // First, we swap index 0 (b) and index 3 (a), then the array comments are // ['a.comments', 'd.comments', 'c.comments', 'b.comments'] // index 0 is finalized // index 3 is actually mapped to original index 0, we present as 0 -> 3 // Then swap index 1 (d) and index 0 (-> 3, b) // 1 (index) -> 0 (new index) -> 3 (real_index) // ['d.comments', 'b.comments', 'c.comments', 'd.comments'] // index 1 is finalized // index 3 is contains the item of original index 1 // - we present as 1 -> 3 // - it is ok that we don't remove mapping 0 -> 3 // Then index 2 should be skipped // Then swap index 3 (d) and index 1 (-> 3, b), skipped const map = Object.create(null) result.forEach((source_index, index) => { if (source_index === index) { return } const real_source_index = get_mapped(map, source_index) if (real_source_index === index) { return } // The item of index `index` gets the final value // delete map[index] map[index] = real_source_index swap_comments(this, index, real_source_index) }) return this } } module.exports = { CommentArray }