1 | // This file contains a modified version of the set function from the Backbone
|
2 | // (see
|
3 | // https://github.com/jashkenas/backbone/blob/05fde9e201f7e2137796663081105cd6dad12a98/backbone.js#L460,
|
4 | // with changes below marked with an EDIT comment). This file in Backbone has the following license.
|
5 | var __assign = (this && this.__assign) || function () {
|
6 | __assign = Object.assign || function(t) {
|
7 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
8 | s = arguments[i];
|
9 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
10 | t[p] = s[p];
|
11 | }
|
12 | return t;
|
13 | };
|
14 | return __assign.apply(this, arguments);
|
15 | };
|
16 | // (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
17 | // Backbone may be freely distributed under the MIT license.
|
18 | // For all details and documentation:
|
19 | // http://backbonejs.org
|
20 | // Backbone's full license is below (from https://github.com/jashkenas/backbone/blob/05fde9e201f7e2137796663081105cd6dad12a98/LICENSE)
|
21 | /*
|
22 | Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
|
23 |
|
24 | Permission is hereby granted, free of charge, to any person
|
25 | obtaining a copy of this software and associated documentation
|
26 | files (the "Software"), to deal in the Software without
|
27 | restriction, including without limitation the rights to use,
|
28 | copy, modify, merge, publish, distribute, sublicense, and/or sell
|
29 | copies of the Software, and to permit persons to whom the
|
30 | Software is furnished to do so, subject to the following
|
31 | conditions:
|
32 |
|
33 | The above copyright notice and this permission notice shall be
|
34 | included in all copies or substantial portions of the Software.
|
35 |
|
36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
37 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
38 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
39 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
40 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
41 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
42 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
43 | OTHER DEALINGS IN THE SOFTWARE.
|
44 | */
|
45 | import * as utils from './utils';
|
46 | // Set a hash of model attributes on the object, firing `"change"`. This is
|
47 | // the core primitive operation of a model, updating the data and notifying
|
48 | // anyone who needs to know about the change in state. The heart of the beast.
|
49 | // This *MUST* be called with the model as the `this` context.
|
50 | export function set(key, val, options) {
|
51 | /* tslint:disable:no-invalid-this */
|
52 | if (key == null) {
|
53 | return this;
|
54 | }
|
55 | // Handle both `"key", value` and `{key: value}` -style arguments.
|
56 | var attrs;
|
57 | if (typeof key === 'object') {
|
58 | attrs = key;
|
59 | options = val;
|
60 | }
|
61 | else {
|
62 | (attrs = {})[key] = val;
|
63 | }
|
64 | options || (options = {});
|
65 | // Run validation.
|
66 | if (!this._validate(attrs, options)) {
|
67 | return false;
|
68 | }
|
69 | // Extract attributes and options.
|
70 | var unset = options.unset;
|
71 | var silent = options.silent;
|
72 | var changes = [];
|
73 | var changing = this._changing;
|
74 | this._changing = true;
|
75 | if (!changing) {
|
76 | // EDIT: changed to use object spread instead of _.clone
|
77 | this._previousAttributes = __assign({}, this.attributes);
|
78 | this.changed = {};
|
79 | }
|
80 | var current = this.attributes;
|
81 | var changed = this.changed;
|
82 | var prev = this._previousAttributes;
|
83 | // For each `set` attribute, update or delete the current value.
|
84 | for (var attr in attrs) {
|
85 | val = attrs[attr];
|
86 | // EDIT: the following two lines use our isEqual instead of _.isEqual
|
87 | if (!utils.isEqual(current[attr], val)) {
|
88 | changes.push(attr);
|
89 | }
|
90 | if (!utils.isEqual(prev[attr], val)) {
|
91 | changed[attr] = val;
|
92 | }
|
93 | else {
|
94 | delete changed[attr];
|
95 | }
|
96 | unset ? delete current[attr] : current[attr] = val;
|
97 | }
|
98 | // Update the `id`.
|
99 | this.id = this.get(this.idAttribute);
|
100 | // Trigger all relevant attribute changes.
|
101 | if (!silent) {
|
102 | if (changes.length) {
|
103 | this._pending = options;
|
104 | }
|
105 | for (var i = 0; i < changes.length; i++) {
|
106 | this.trigger('change:' + changes[i], this, current[changes[i]], options);
|
107 | }
|
108 | }
|
109 | // You might be wondering why there's a `while` loop here. Changes can
|
110 | // be recursively nested within `"change"` events.
|
111 | if (changing) {
|
112 | return this;
|
113 | }
|
114 | if (!silent) {
|
115 | while (this._pending) {
|
116 | options = this._pending;
|
117 | this._pending = false;
|
118 | this.trigger('change', this, options);
|
119 | }
|
120 | }
|
121 | this._pending = false;
|
122 | this._changing = false;
|
123 | return this;
|
124 | /* tslint:enable:no-invalid-this */
|
125 | }
|