@converse/skeletor 0.0.4 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/model.js~ DELETED
@@ -1,439 +0,0 @@
1
- // Backbone.js 1.4.0
2
- // (c) 2010-2019 Jeremy Ashkenas and DocumentCloud
3
- // Backbone may be freely distributed under the MIT license.
4
-
5
- // Model
6
- // -----
7
- // **Models** are the basic data object in the framework --
8
- // frequently representing a row in a table in a database on your server.
9
- // A discrete chunk of data and a bunch of useful, related methods for
10
- // performing computations and transformations on that data.
11
-
12
- // Create a new model with the specified attributes. A client id (`cid`)
13
- // is automatically generated and assigned for you.
14
-
15
- import {
16
- getResolveablePromise,
17
- getSyncMethod,
18
- inherits,
19
- urlError,
20
- wrapError
21
- } from './helpers.js';
22
- import { Events } from './events.js';
23
- import clone from "lodash-es/clone.js";
24
- import defaults from "lodash-es/defaults.js";
25
- import defer from "lodash-es/defer.js";
26
- import escape from "lodash-es/escape.js";
27
- import extend from "lodash-es/extend.js";
28
- import has from "lodash-es/has.js";
29
- import invert from "lodash-es/invert.js";
30
- import isElement from "lodash-es/isElement.js";
31
- import isEmpty from "lodash-es/isEmpty.js";
32
- import isEqual from "lodash-es/isEqual.js";
33
- import isFunction from "lodash-es/isFunction.js";
34
- import iteratee from "lodash-es/iteratee.js";
35
- import omit from "lodash-es/omit.js";
36
- import pick from "lodash-es/pick.js";
37
- import result from "lodash-es/result.js";
38
- import uniqueId from "lodash-es/uniqueId.js";
39
-
40
-
41
- export const Model = function(attributes, options) {
42
- let attrs = attributes || {};
43
- options || (options = {});
44
- this.preinitialize.apply(this, arguments);
45
- this.cid = uniqueId(this.cidPrefix);
46
- this.attributes = {};
47
- if (options.collection) this.collection = options.collection;
48
- if (options.parse) attrs = this.parse(attrs, options) || {};
49
- const default_attrs = result(this, 'defaults');
50
- attrs = defaults(extend({}, default_attrs, attrs), default_attrs);
51
- this.set(attrs, options);
52
- this.changed = {};
53
- this.initialize.apply(this, arguments);
54
- };
55
-
56
- Model.extend = inherits;
57
-
58
- // Attach all inheritable methods to the Model prototype.
59
- Object.assign(Model.prototype, Events, {
60
-
61
- // A hash of attributes whose current and previous value differ.
62
- changed: null,
63
-
64
- // The value returned during the last failed validation.
65
- validationError: null,
66
-
67
- // The default name for the JSON `id` attribute is `"id"`. MongoDB and
68
- // CouchDB users may want to set this to `"_id"`.
69
- idAttribute: 'id',
70
-
71
- // The prefix is used to create the client id which is used to identify models locally.
72
- // You may want to override this if you're experiencing name clashes with model ids.
73
- cidPrefix: 'c',
74
-
75
- // preinitialize is an empty function by default. You can override it with a function
76
- // or object. preinitialize will run before any instantiation logic is run in the Model.
77
- preinitialize: function(){},
78
-
79
- // Initialize is an empty function by default. Override it with your own
80
- // initialization logic.
81
- initialize: function(){},
82
-
83
- // Return a copy of the model's `attributes` object.
84
- toJSON: function(options) {
85
- return clone(this.attributes);
86
- },
87
-
88
- // Proxy `Backbone.sync` by default -- but override this if you need
89
- // custom syncing semantics for *this* particular model.
90
- sync: function(method, model, options) {
91
- return getSyncMethod(this)(method, model, options);
92
- },
93
-
94
- // Get the value of an attribute.
95
- get: function(attr) {
96
- return this.attributes[attr];
97
- },
98
-
99
- keys: function() {
100
- return Object.keys(this.attributes);
101
- },
102
-
103
- values: function() {
104
- return Object.values(this.attributes);
105
- },
106
-
107
- pairs: function() {
108
- return this.entries();
109
- },
110
-
111
- entries: function() {
112
- return Object.entries(this.attributes);
113
- },
114
-
115
- invert: function() {
116
- return invert(this.attributes);
117
- },
118
-
119
- pick: function(...args) {
120
- if (args.length === 1 && Array.isArray(args[0])) {
121
- args = args[0];
122
- }
123
- return pick(this.attributes, args);
124
- },
125
-
126
- omit: function(...args) {
127
- if (args.length === 1 && Array.isArray(args[0])) {
128
- args = args[0];
129
- }
130
- return omit(this.attributes, args);
131
- },
132
-
133
- isEmpty: function() {
134
- return isEmpty(this.attributes);
135
- },
136
-
137
- // Get the HTML-escaped value of an attribute.
138
- escape: function(attr) {
139
- return escape(this.get(attr));
140
- },
141
-
142
- // Returns `true` if the attribute contains a value that is not null
143
- // or undefined.
144
- has: function(attr) {
145
- return this.get(attr) != null;
146
- },
147
-
148
- // Special-cased proxy to lodash's `matches` method.
149
- matches: function(attrs) {
150
- return !!iteratee(attrs, this)(this.attributes);
151
- },
152
-
153
- // Set a hash of model attributes on the object, firing `"change"`. This is
154
- // the core primitive operation of a model, updating the data and notifying
155
- // anyone who needs to know about the change in state. The heart of the beast.
156
- set: function(key, val, options) {
157
- if (key == null) return this;
158
-
159
- // Handle both `"key", value` and `{key: value}` -style arguments.
160
- let attrs;
161
- if (typeof key === 'object') {
162
- attrs = key;
163
- options = val;
164
- } else {
165
- (attrs = {})[key] = val;
166
- }
167
-
168
- options || (options = {});
169
-
170
- // Run validation.
171
- if (!this._validate(attrs, options)) return false;
172
-
173
- // Extract attributes and options.
174
- const unset = options.unset;
175
- const silent = options.silent;
176
- const changes = [];
177
- const changing = this._changing;
178
- this._changing = true;
179
-
180
- if (!changing) {
181
- this._previousAttributes = clone(this.attributes);
182
- this.changed = {};
183
- }
184
-
185
- const current = this.attributes;
186
- const changed = this.changed;
187
- const prev = this._previousAttributes;
188
-
189
- // For each `set` attribute, update or delete the current value.
190
- for (const attr in attrs) {
191
- val = attrs[attr];
192
- if (!isEqual(current[attr], val)) changes.push(attr);
193
- if (!isEqual(prev[attr], val)) {
194
- changed[attr] = val;
195
- } else {
196
- delete changed[attr];
197
- }
198
- unset ? delete current[attr] : current[attr] = val;
199
- }
200
-
201
- // Update the `id`.
202
- if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
203
-
204
- // Trigger all relevant attribute changes.
205
- if (!silent) {
206
- if (changes.length) this._pending = options;
207
- for (let i = 0; i < changes.length; i++) {
208
- this.trigger('change:' + changes[i], this, current[changes[i]], options);
209
- }
210
- }
211
-
212
- // You might be wondering why there's a `while` loop here. Changes can
213
- // be recursively nested within `"change"` events.
214
- if (changing) return this;
215
- if (!silent) {
216
- while (this._pending) {
217
- options = this._pending;
218
- this._pending = false;
219
- this.trigger('change', this, options);
220
- }
221
- }
222
- this._pending = false;
223
- this._changing = false;
224
- return this;
225
- },
226
-
227
- // Remove an attribute from the model, firing `"change"`. `unset` is a noop
228
- // if the attribute doesn't exist.
229
- unset: function(attr, options) {
230
- return this.set(attr, undefined, extend({}, options, {unset: true}));
231
- },
232
-
233
- // Clear all attributes on the model, firing `"change"`.
234
- clear: function(options) {
235
- const attrs = {};
236
- for (const key in this.attributes) attrs[key] = undefined;
237
- return this.set(attrs, extend({}, options, {unset: true}));
238
- },
239
-
240
- // Determine if the model has changed since the last `"change"` event.
241
- // If you specify an attribute name, determine if that attribute has changed.
242
- hasChanged: function(attr) {
243
- if (attr == null) return !isEmpty(this.changed);
244
- return has(this.changed, attr);
245
- },
246
-
247
- // Return an object containing all the attributes that have changed, or
248
- // false if there are no changed attributes. Useful for determining what
249
- // parts of a view need to be updated and/or what attributes need to be
250
- // persisted to the server. Unset attributes will be set to undefined.
251
- // You can also pass an attributes object to diff against the model,
252
- // determining if there *would be* a change.
253
- changedAttributes: function(diff) {
254
- if (!diff) return this.hasChanged() ? clone(this.changed) : false;
255
- const old = this._changing ? this._previousAttributes : this.attributes;
256
- const changed = {};
257
- let hasChanged;
258
- for (const attr in diff) {
259
- const val = diff[attr];
260
- if (isEqual(old[attr], val)) continue;
261
- changed[attr] = val;
262
- hasChanged = true;
263
- }
264
- return hasChanged ? changed : false;
265
- },
266
-
267
- // Get the previous value of an attribute, recorded at the time the last
268
- // `"change"` event was fired.
269
- previous: function(attr) {
270
- if (attr == null || !this._previousAttributes) return null;
271
- return this._previousAttributes[attr];
272
- },
273
-
274
- // Get all of the attributes of the model at the time of the previous
275
- // `"change"` event.
276
- previousAttributes: function() {
277
- return clone(this._previousAttributes);
278
- },
279
-
280
- // Fetch the model from the server, merging the response with the model's
281
- // local attributes. Any changed attributes will trigger a "change" event.
282
- fetch: function(options) {
283
- options = extend({parse: true}, options);
284
- const model = this;
285
- const success = options.success;
286
- options.success = function(resp) {
287
- const serverAttrs = options.parse ? model.parse(resp, options) : resp;
288
- if (!model.set(serverAttrs, options)) return false;
289
- if (success) success.call(options.context, model, resp, options);
290
- model.trigger('sync', model, resp, options);
291
- };
292
- wrapError(this, options);
293
- return this.sync('read', this, options);
294
- },
295
-
296
- // Set a hash of model attributes, and sync the model to the server.
297
- // If the server returns an attributes hash that differs, the model's
298
- // state will be `set` again.
299
- save: function(key, val, options) {
300
- // Handle both `"key", value` and `{key: value}` -style arguments.
301
- let attrs;
302
- if (key == null || typeof key === 'object') {
303
- attrs = key;
304
- options = val;
305
- } else {
306
- (attrs = {})[key] = val;
307
- }
308
-
309
- options = extend({validate: true, parse: true}, options);
310
- const wait = options.wait;
311
- const return_promise = options.promise;
312
- const promise = return_promise && getResolveablePromise();
313
-
314
- // If we're not waiting and attributes exist, save acts as
315
- // `set(attr).save(null, opts)` with validation. Otherwise, check if
316
- // the model will be valid when the attributes, if any, are set.
317
- if (attrs && !wait) {
318
- if (!this.set(attrs, options)) return false;
319
- } else if (!this._validate(attrs, options)) {
320
- return false;
321
- }
322
-
323
- // After a successful server-side save, the client is (optionally)
324
- // updated with the server-side state.
325
- const model = this;
326
- const success = options.success;
327
- const error = options.error;
328
- const attributes = this.attributes;
329
- options.success = function(resp) {
330
- // Ensure attributes are restored during synchronous saves.
331
- model.attributes = attributes;
332
- let serverAttrs = options.parse ? model.parse(resp, options) : resp;
333
- if (wait) serverAttrs = extend({}, attrs, serverAttrs);
334
- if (serverAttrs && !model.set(serverAttrs, options)) return false;
335
- if (success) success.call(options.context, model, resp, options);
336
- model.trigger('sync', model, resp, options);
337
- return_promise && promise.resolve();
338
- };
339
- options.error = function(model, e, options) {
340
- error && error.call(options.context, e);
341
- return_promise && promise.reject(e);
342
- }
343
-
344
- wrapError(this, options);
345
-
346
- // Set temporary attributes if `{wait: true}` to properly find new ids.
347
- if (attrs && wait) this.attributes = extend({}, attributes, attrs);
348
-
349
- const method = this.isNew() ? 'create' : options.patch ? 'patch' : 'update';
350
- if (method === 'patch' && !options.attrs) options.attrs = attrs;
351
- const xhr = this.sync(method, this, options);
352
-
353
- // Restore attributes.
354
- this.attributes = attributes;
355
-
356
- if (return_promise) {
357
- return promise;
358
- } else {
359
- return xhr;
360
- }
361
-
362
- },
363
-
364
- // Destroy this model on the server if it was already persisted.
365
- // Optimistically removes the model from its collection, if it has one.
366
- // If `wait: true` is passed, waits for the server to respond before removal.
367
- destroy: function(options) {
368
- options = options ? clone(options) : {};
369
- const model = this;
370
- const success = options.success;
371
- const wait = options.wait;
372
-
373
- const destroy = function() {
374
- model.stopListening();
375
- model.trigger('destroy', model, model.collection, options);
376
- };
377
-
378
- options.success = function(resp) {
379
- if (wait) destroy();
380
- if (success) success.call(options.context, model, resp, options);
381
- if (!model.isNew()) model.trigger('sync', model, resp, options);
382
- };
383
-
384
- let xhr = false;
385
- if (this.isNew()) {
386
- defer(options.success);
387
- } else {
388
- wrapError(this, options);
389
- xhr = this.sync('delete', this, options);
390
- }
391
- if (!wait) destroy();
392
- return xhr;
393
- },
394
-
395
- // Default URL for the model's representation on the server -- if you're
396
- // using Backbone's restful methods, override this to change the endpoint
397
- // that will be called.
398
- url: function() {
399
- const base =
400
- result(this, 'urlRoot') ||
401
- result(this.collection, 'url') ||
402
- urlError();
403
- if (this.isNew()) return base;
404
- const id = this.get(this.idAttribute);
405
- return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
406
- },
407
-
408
- // **parse** converts a response into the hash of attributes to be `set` on
409
- // the model. The default implementation is just to pass the response along.
410
- parse: function(resp, options) {
411
- return resp;
412
- },
413
-
414
- // Create a new model with identical attributes to this one.
415
- clone: function() {
416
- return new this.constructor(this.attributes);
417
- },
418
-
419
- // A model is new if it has never been saved to the server, and lacks an id.
420
- isNew: function() {
421
- return !this.has(this.idAttribute);
422
- },
423
-
424
- // Check if the model is currently in a valid state.
425
- isValid: function(options) {
426
- return this._validate({}, extend({}, options, {validate: true}));
427
- },
428
-
429
- // Run validation against the next complete set of model attributes,
430
- // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
431
- _validate: function(attrs, options) {
432
- if (!options.validate || !this.validate) return true;
433
- attrs = extend({}, this.attributes, attrs);
434
- const error = this.validationError = this.validate(attrs, options) || null;
435
- if (!error) return true;
436
- this.trigger('invalid', this, error, extend(options, {validationError: error}));
437
- return false;
438
- }
439
- });
@@ -1,88 +0,0 @@
1
- import Overview from './overview.js';
2
- import debounce from 'lodash-es/debounce.js';
3
-
4
-
5
- const OrderedListView = Overview.extend({
6
- /* An OrderedListView is a special type of Overview which adds some
7
- * methods and conventions for rendering an ordered list of elements.
8
- */
9
- // The `listItems` attribute denotes the path (from this View) to the
10
- // list of items.
11
- listItems: 'model',
12
- // The `sortEvent` attribute specifies the event which should cause the
13
- // ordered list to be sorted.
14
- sortEvent: 'change',
15
- // If false, we debounce sorting and inserting the new item
16
- // (for improved performance when a large amount of items get added all at once)
17
- // Otherwise we immediately sort the items and insert the new item.
18
- sortImmediatelyOnAdd: false,
19
- // The `listSelector` is the selector used to query for the DOM list
20
- // element which contains the ordered items.
21
- listSelector: '.ordered-items',
22
- // The `itemView` is constructor which should be called to create a
23
- // View for a new item.
24
- ItemView: undefined,
25
- // The `subviewIndex` is the attribute of the list element model which
26
- // acts as the index of the subview in the overview.
27
- // An overview is a "Collection" of views, and they can be retrieved
28
- // via an index. By default this is the 'id' attribute, but it could be
29
- // set to something else.
30
- subviewIndex: 'id',
31
-
32
- initialize () {
33
- this.sortEventually = debounce(() => this.sortAndPositionAllItems(), 100);
34
- this.items = get(this, this.listItems);
35
- this.items.on('remove', this.removeView, this);
36
- this.items.on('reset', this.removeAll, this);
37
-
38
- this.items.on('add', (a, b) => {
39
- if (this.sortImmediatelyOnAdd) {
40
- this.sortAndPositionAllItems();
41
- } else {
42
- this.sortEventually();
43
- }
44
- });
45
-
46
- if (this.sortEvent) {
47
- this.items.on(this.sortEvent, this.sortEventually, this);
48
- }
49
- },
50
-
51
- createItemView (item) {
52
- let item_view = this.get(item.get(this.subviewIndex));
53
- if (!item_view) {
54
- item_view = new this.ItemView({model: item});
55
- this.add(item.get(this.subviewIndex), item_view);
56
- } else {
57
- item_view.model = item;
58
- item_view.initialize();
59
- }
60
- item_view.render();
61
- return item_view;
62
- },
63
-
64
- removeView (item) {
65
- this.remove(item.get(this.subviewIndex));
66
- },
67
-
68
- sortAndPositionAllItems () {
69
- if (!this.items.length) {
70
- return;
71
- }
72
- this.items.sort();
73
-
74
- const list_el = this.el.querySelector(this.listSelector);
75
- const div = document.createElement('div');
76
- list_el.parentNode.replaceChild(div, list_el);
77
- this.items.forEach(item => {
78
- let view = this.get(item.get(this.subviewIndex));
79
- if (!view) {
80
- view = this.createItemView(item)
81
- }
82
- list_el.insertAdjacentElement('beforeend', view.el);
83
- });
84
- div.parentNode.replaceChild(list_el, div);
85
- }
86
- });
87
-
88
- export default OrderedListView;
package/src/overview.js~ DELETED
@@ -1,111 +0,0 @@
1
- /*!
2
- * Copyright (c) JC Brand <jc@opkode.com>
3
- */
4
- import debounce from 'lodash-es/debounce.js';
5
- import difference from 'lodash-es/difference.js';
6
- import drop from 'lodash-es/drop.js';
7
- import every from 'lodash-es/every.js';
8
- import extend from 'lodash-es/extend.js';
9
- import filter from 'lodash-es/filter.js';
10
- import find from 'lodash-es/find.js';
11
- import first from 'lodash-es/first.js';
12
- import forEach from 'lodash-es/forEach.js';
13
- import get from 'lodash-es/get.js';
14
- import head from 'lodash-es/head.js';
15
- import includes from 'lodash-es/includes.js';
16
- import indexOf from 'lodash-es/indexOf.js';
17
- import initial from 'lodash-es/initial.js';
18
- import invoke from 'lodash-es/invoke.js';
19
- import isEmpty from 'lodash-es/isEmpty.js';
20
- import last from 'lodash-es/last.js';
21
- import lastIndexOf from 'lodash-es/lastIndexOf.js';
22
- import map from 'lodash-es/map.js';
23
- import max from 'lodash-es/max.js';
24
- import min from 'lodash-es/min.js';
25
- import reduce from 'lodash-es/reduce.js';
26
- import reduceRight from 'lodash-es/reduceRight.js';
27
- import reject from 'lodash-es/reject.js';
28
- import rest from 'lodash-es/rest.js';
29
- import sample from 'lodash-es/sample.js';
30
- import shuffle from 'lodash-es/shuffle.js';
31
- import size from 'lodash-es/size.js';
32
- import some from 'lodash-es/some.js';
33
- import sortBy from 'lodash-es/sortBy.js';
34
- import tail from 'lodash-es/tail.js';
35
- import take from 'lodash-es/take.js';
36
- import toArray from 'lodash-es/toArray.js';
37
- import without from 'lodash-es/without.js';
38
- import { View } from "./view";
39
-
40
-
41
- const Overview = function (options) {
42
- /* An Overview is a View that contains and keeps track of sub-views.
43
- * Kind of like what a Collection is to a Model.
44
- */
45
- this.views = {};
46
- this.keys = () => Object.keys(this.views);
47
- this.getAll = () => this.views;
48
- this.get = id => this.views[id];
49
-
50
- /* Exclusive get. Returns all instances except the given id. */
51
- this.xget = id => {
52
- return this.keys()
53
- .filter(k => (k !== id))
54
- .reduce((acc, k) => {
55
- acc[k] = this.views[k]
56
- return acc;
57
- }, {});
58
- }
59
-
60
- this.add = (id, view) => {
61
- this.views[id] = view;
62
- return view;
63
- };
64
-
65
- this.remove = id => {
66
- if (typeof id === "undefined") {
67
- new View().remove.apply(this);
68
- }
69
- const view = this.views[id];
70
- if (view) {
71
- delete this.views[id];
72
- view.remove();
73
- return view;
74
- }
75
- };
76
-
77
- this.removeAll = () => {
78
- this.keys().forEach(id => this.remove(id));
79
- return this;
80
- }
81
-
82
- };
83
-
84
-
85
- const Overview = function (const) {
86
- View.apply(this, Array.prototype.slice.apply(arguments));
87
- }
88
-
89
-
90
- const methods = {
91
- includes, difference, drop,
92
- every, filter, find,
93
- first, forEach, head,
94
- indexOf, initial, invoke, isEmpty,
95
- last, lastIndexOf, map, max, min, reduce,
96
- reduceRight, reject, rest, sample,
97
- shuffle, size, some, sortBy, tail, take,
98
- toArray, without
99
- }
100
- Object.keys(methods).forEach(name => {
101
- Overview.prototype[name] = function() {
102
- const args = Array.prototype.slice.call(arguments);
103
- args.unshift(this.views);
104
- return methods[name].apply(this, args);
105
- };
106
- });
107
-
108
- Object.assign(Overview.prototype, View.prototype);
109
- Overview.extend = View.extend;
110
-
111
- export default Overview;