UNPKG

4.76 kBJavaScriptView Raw
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.
5var __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/*
22Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
23
24Permission is hereby granted, free of charge, to any person
25obtaining a copy of this software and associated documentation
26files (the "Software"), to deal in the Software without
27restriction, including without limitation the rights to use,
28copy, modify, merge, publish, distribute, sublicense, and/or sell
29copies of the Software, and to permit persons to whom the
30Software is furnished to do so, subject to the following
31conditions:
32
33The above copyright notice and this permission notice shall be
34included in all copies or substantial portions of the Software.
35
36THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
38OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
40HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43OTHER DEALINGS IN THE SOFTWARE.
44*/
45import * 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.
50export 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}