1e484b35bSopenharmony_ci/* eslint-disable */
2e484b35bSopenharmony_ci
3e484b35bSopenharmony_ciimport { def, Log } from '../../utils/index.ts';
4e484b35bSopenharmony_ci
5e484b35bSopenharmony_ciconst arrayProto = Array.prototype;
6e484b35bSopenharmony_ciexport const arrayMethods = Object.create(arrayProto);
7e484b35bSopenharmony_ci
8e484b35bSopenharmony_ci/*
9e484b35bSopenharmony_ci * Intercept mutating methods and emit events
10e484b35bSopenharmony_ci */
11e484b35bSopenharmony_ci
12e484b35bSopenharmony_ci;[
13e484b35bSopenharmony_ci  'push',
14e484b35bSopenharmony_ci  'pop',
15e484b35bSopenharmony_ci  'shift',
16e484b35bSopenharmony_ci  'unshift',
17e484b35bSopenharmony_ci  'splice',
18e484b35bSopenharmony_ci  'sort',
19e484b35bSopenharmony_ci  'reverse'
20e484b35bSopenharmony_ci]
21e484b35bSopenharmony_ci.forEach(function (method) {
22e484b35bSopenharmony_ci  // cache original method
23e484b35bSopenharmony_ci  const original = arrayProto[method];
24e484b35bSopenharmony_ci  def(arrayMethods, method, function mutator() {
25e484b35bSopenharmony_ci    // avoid leaking arguments:
26e484b35bSopenharmony_ci    // http://jsperf.com/closure-with-arguments
27e484b35bSopenharmony_ci    let i = arguments.length;
28e484b35bSopenharmony_ci    const args = new Array(i);
29e484b35bSopenharmony_ci    while (i--) {
30e484b35bSopenharmony_ci      args[i] = arguments[i];
31e484b35bSopenharmony_ci    }
32e484b35bSopenharmony_ci    const result = original.apply(this, args);
33e484b35bSopenharmony_ci    const ob = this.__ob__;
34e484b35bSopenharmony_ci    let inserted;
35e484b35bSopenharmony_ci    switch (method) {
36e484b35bSopenharmony_ci      case 'push':
37e484b35bSopenharmony_ci        inserted = args;
38e484b35bSopenharmony_ci        break;
39e484b35bSopenharmony_ci      case 'unshift':
40e484b35bSopenharmony_ci        inserted = args;
41e484b35bSopenharmony_ci        break;
42e484b35bSopenharmony_ci      case 'splice':
43e484b35bSopenharmony_ci        inserted = args.slice(2);
44e484b35bSopenharmony_ci        break;
45e484b35bSopenharmony_ci    }
46e484b35bSopenharmony_ci    if (inserted) {
47e484b35bSopenharmony_ci      ob.observeArray(inserted);
48e484b35bSopenharmony_ci    }
49e484b35bSopenharmony_ci    // Notify change.
50e484b35bSopenharmony_ci    ob.dep.notify();
51e484b35bSopenharmony_ci    return result;
52e484b35bSopenharmony_ci  })
53e484b35bSopenharmony_ci})
54e484b35bSopenharmony_ci
55e484b35bSopenharmony_ci/**
56e484b35bSopenharmony_ci * Swap the element at the given index with a new value and emits corresponding event.
57e484b35bSopenharmony_ci * @param {Number} index
58e484b35bSopenharmony_ci * @param {*} val
59e484b35bSopenharmony_ci * @return {*} - replaced element
60e484b35bSopenharmony_ci */
61e484b35bSopenharmony_ci
62e484b35bSopenharmony_cidef(
63e484b35bSopenharmony_ci  arrayProto,
64e484b35bSopenharmony_ci  '$set',
65e484b35bSopenharmony_ci  function $set (index, val) {
66e484b35bSopenharmony_ci    Log.warn(`"Array.prototype.$set" is not a standard API, `
67e484b35bSopenharmony_ci      + `it will be removed in the next version.`);
68e484b35bSopenharmony_ci    if (index >= this.length) {
69e484b35bSopenharmony_ci      this.length = index + 1;
70e484b35bSopenharmony_ci    }
71e484b35bSopenharmony_ci    return this.splice(index, 1, val)[0];
72e484b35bSopenharmony_ci  }
73e484b35bSopenharmony_ci)
74e484b35bSopenharmony_ci
75e484b35bSopenharmony_ci/**
76e484b35bSopenharmony_ci * Convenience method to remove the element at given index.
77e484b35bSopenharmony_ci * @param {Number} index
78e484b35bSopenharmony_ci * @param {*} val
79e484b35bSopenharmony_ci */
80e484b35bSopenharmony_ci
81e484b35bSopenharmony_cidef(
82e484b35bSopenharmony_ci  arrayProto,
83e484b35bSopenharmony_ci  '$remove',
84e484b35bSopenharmony_ci  function $remove (index) {
85e484b35bSopenharmony_ci    Log.warn(`"Array.prototype.$remove" is not a standard API,`
86e484b35bSopenharmony_ci      + ` it will be removed in the next version.`);
87e484b35bSopenharmony_ci    if (!this.length) {
88e484b35bSopenharmony_ci      return;
89e484b35bSopenharmony_ci    }
90e484b35bSopenharmony_ci    if (typeof index !== 'number') {
91e484b35bSopenharmony_ci      index = this.indexOf(index);
92e484b35bSopenharmony_ci    }
93e484b35bSopenharmony_ci    if (index > -1) {
94e484b35bSopenharmony_ci      this.splice(index, 1);
95e484b35bSopenharmony_ci    }
96e484b35bSopenharmony_ci  }
97e484b35bSopenharmony_ci)
98e484b35bSopenharmony_ci
99e484b35bSopenharmony_ci/**
100e484b35bSopenharmony_ci * Support includes for panda.
101e484b35bSopenharmony_ci * @param {Number} index
102e484b35bSopenharmony_ci * @param {*} val
103e484b35bSopenharmony_ci * @return {Boolean}
104e484b35bSopenharmony_ci */
105e484b35bSopenharmony_ci
106e484b35bSopenharmony_cidef(
107e484b35bSopenharmony_ci  arrayProto,
108e484b35bSopenharmony_ci  'includes',
109e484b35bSopenharmony_ci  function includes(param, start = 0) {
110e484b35bSopenharmony_ci    if (start >= this.length) return false
111e484b35bSopenharmony_ci    if (start < 0) {
112e484b35bSopenharmony_ci      start = start + this.length < 0 ? 0 : start + this.length;
113e484b35bSopenharmony_ci    }
114e484b35bSopenharmony_ci    if (Number.isNaN(param)) {
115e484b35bSopenharmony_ci      for (let i = start; i < this.length; i++) {
116e484b35bSopenharmony_ci        if (Number.isNaN(this[i])) return true;
117e484b35bSopenharmony_ci      }
118e484b35bSopenharmony_ci    } else {
119e484b35bSopenharmony_ci      for (let i = start; i < this.length; i++) {
120e484b35bSopenharmony_ci        if (this[i] === param) return true;
121e484b35bSopenharmony_ci      }
122e484b35bSopenharmony_ci    }
123e484b35bSopenharmony_ci    return false
124e484b35bSopenharmony_ci  }
125e484b35bSopenharmony_ci)
126