spotlight-frontend 3.5.0-beta.1
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/LICENSE +13 -0
- package/README.md +114 -0
- package/app/assets/images/blacklight/arrow-alt-circle-left.svg +1 -0
- package/app/assets/images/blacklight/arrow-alt-circle-right.svg +1 -0
- package/app/assets/images/blacklight/arrow_back_ios.svg +1 -0
- package/app/assets/images/blacklight/arrow_forward_ios.svg +1 -0
- package/app/assets/images/blacklight/check.svg +1 -0
- package/app/assets/images/blacklight/check_circle.svg +1 -0
- package/app/assets/images/blacklight/chevron_right.svg +1 -0
- package/app/assets/images/blacklight/close.svg +1 -0
- package/app/assets/images/blacklight/edit.svg +1 -0
- package/app/assets/images/blacklight/error.svg +1 -0
- package/app/assets/images/blacklight/highlight_off.svg +1 -0
- package/app/assets/images/blacklight/info.svg +1 -0
- package/app/assets/images/blacklight/warning.svg +1 -0
- package/app/assets/images/blacklight/zoom_in.svg +1 -0
- package/app/assets/images/blacklight/zoom_out.svg +1 -0
- package/app/assets/images/spotlight/.keep +0 -0
- package/app/assets/images/spotlight/blocks/sir-trevor-icons.svg +320 -0
- package/app/assets/images/spotlight/default_browse_thumbnail.jpg +0 -0
- package/app/assets/images/spotlight/default_thumbnail.jpg +0 -0
- package/app/assets/images/spotlight/fallback/default.png +0 -0
- package/app/assets/javascripts/spotlight/admin/add_another.js +22 -0
- package/app/assets/javascripts/spotlight/admin/add_new_button.js +81 -0
- package/app/assets/javascripts/spotlight/admin/appearance.js +24 -0
- package/app/assets/javascripts/spotlight/admin/attachments.js +2 -0
- package/app/assets/javascripts/spotlight/admin/blacklight_configuration.js +63 -0
- package/app/assets/javascripts/spotlight/admin/block_mixins/autocompleteable.js +72 -0
- package/app/assets/javascripts/spotlight/admin/block_mixins/formable.js +78 -0
- package/app/assets/javascripts/spotlight/admin/block_mixins/plustextable.js +57 -0
- package/app/assets/javascripts/spotlight/admin/blocks/block.js +23 -0
- package/app/assets/javascripts/spotlight/admin/blocks/browse_block.js +87 -0
- package/app/assets/javascripts/spotlight/admin/blocks/browse_group_categories_block.js +88 -0
- package/app/assets/javascripts/spotlight/admin/blocks/iframe_block.js +34 -0
- package/app/assets/javascripts/spotlight/admin/blocks/link_to_search_block.js +16 -0
- package/app/assets/javascripts/spotlight/admin/blocks/oembed_block.js +40 -0
- package/app/assets/javascripts/spotlight/admin/blocks/pages_block.js +22 -0
- package/app/assets/javascripts/spotlight/admin/blocks/resources_block.js +145 -0
- package/app/assets/javascripts/spotlight/admin/blocks/rule_block.js +25 -0
- package/app/assets/javascripts/spotlight/admin/blocks/search_result_block.js +44 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_base_block.js +108 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_block.js +25 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_carousel_block.js +103 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_embed_block.js +17 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_features_block.js +41 -0
- package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_grid_block.js +14 -0
- package/app/assets/javascripts/spotlight/admin/blocks/uploaded_items_block.js +145 -0
- package/app/assets/javascripts/spotlight/admin/catalog_edit.js +16 -0
- package/app/assets/javascripts/spotlight/admin/copy_email_addresses.js +9 -0
- package/app/assets/javascripts/spotlight/admin/crop.es6 +310 -0
- package/app/assets/javascripts/spotlight/admin/croppable.js +25 -0
- package/app/assets/javascripts/spotlight/admin/edit_in_place.js +54 -0
- package/app/assets/javascripts/spotlight/admin/exhibit_tag_autocomplete.js +37 -0
- package/app/assets/javascripts/spotlight/admin/exhibits.js +58 -0
- package/app/assets/javascripts/spotlight/admin/form_observer.js +86 -0
- package/app/assets/javascripts/spotlight/admin/iiif.es6 +54 -0
- package/app/assets/javascripts/spotlight/admin/index.js +16 -0
- package/app/assets/javascripts/spotlight/admin/locks.js +12 -0
- package/app/assets/javascripts/spotlight/admin/multi_image_selector.js +158 -0
- package/app/assets/javascripts/spotlight/admin/pages.js.erb +40 -0
- package/app/assets/javascripts/spotlight/admin/progress_monitor.js +148 -0
- package/app/assets/javascripts/spotlight/admin/readonly_checkbox.js +6 -0
- package/app/assets/javascripts/spotlight/admin/search_typeahead.js +108 -0
- package/app/assets/javascripts/spotlight/admin/select_related_input.js +34 -0
- package/app/assets/javascripts/spotlight/admin/sir-trevor/block_controls.js +120 -0
- package/app/assets/javascripts/spotlight/admin/sir-trevor/block_limits.js +37 -0
- package/app/assets/javascripts/spotlight/admin/sir-trevor/locales.js +120 -0
- package/app/assets/javascripts/spotlight/admin/spotlight_nestable.js +72 -0
- package/app/assets/javascripts/spotlight/admin/tabs.js +6 -0
- package/app/assets/javascripts/spotlight/admin/translation_progress.js +23 -0
- package/app/assets/javascripts/spotlight/admin/users.js +79 -0
- package/app/assets/javascripts/spotlight/application.js +14 -0
- package/app/assets/javascripts/spotlight/spotlight.js +23 -0
- package/app/assets/javascripts/spotlight/user/analytics.js +9 -0
- package/app/assets/javascripts/spotlight/user/browse_group_categories.js +59 -0
- package/app/assets/javascripts/spotlight/user/carousel.js +3 -0
- package/app/assets/javascripts/spotlight/user/clear_form_button.js +27 -0
- package/app/assets/javascripts/spotlight/user/index.js +8 -0
- package/app/assets/javascripts/spotlight/user/report_a_problem.js +39 -0
- package/app/assets/javascripts/spotlight/user/zpr_links.js.erb +45 -0
- package/app/assets/stylesheets/spotlight/_accessibility.scss +8 -0
- package/app/assets/stylesheets/spotlight/_attachments.css +4 -0
- package/app/assets/stylesheets/spotlight/_blacklight_configuration.scss +82 -0
- package/app/assets/stylesheets/spotlight/_blacklight_overrides.scss +21 -0
- package/app/assets/stylesheets/spotlight/_bootstrap_overrides.scss +105 -0
- package/app/assets/stylesheets/spotlight/_breadcrumbs.scss +6 -0
- package/app/assets/stylesheets/spotlight/_browse.scss +158 -0
- package/app/assets/stylesheets/spotlight/_catalog.scss +161 -0
- package/app/assets/stylesheets/spotlight/_collapse_toggle.scss +14 -0
- package/app/assets/stylesheets/spotlight/_croppable.scss +4 -0
- package/app/assets/stylesheets/spotlight/_curation.scss +224 -0
- package/app/assets/stylesheets/spotlight/_edit_in_place.scss +9 -0
- package/app/assets/stylesheets/spotlight/_exhibit_admin.scss +81 -0
- package/app/assets/stylesheets/spotlight/_exhibit_navbar.scss +10 -0
- package/app/assets/stylesheets/spotlight/_exhibits_index.scss +147 -0
- package/app/assets/stylesheets/spotlight/_featured_browse_categories_block.scss +269 -0
- package/app/assets/stylesheets/spotlight/_footer.scss +12 -0
- package/app/assets/stylesheets/spotlight/_header.scss +155 -0
- package/app/assets/stylesheets/spotlight/_item_text_block.scss +50 -0
- package/app/assets/stylesheets/spotlight/_mixins.scss +17 -0
- package/app/assets/stylesheets/spotlight/_modals.scss +3 -0
- package/app/assets/stylesheets/spotlight/_multi_image_selector.scss +22 -0
- package/app/assets/stylesheets/spotlight/_multi_up_item_grid.scss +63 -0
- package/app/assets/stylesheets/spotlight/_nestable.scss +124 -0
- package/app/assets/stylesheets/spotlight/_pages.scss +282 -0
- package/app/assets/stylesheets/spotlight/_report_a_problem.scss +14 -0
- package/app/assets/stylesheets/spotlight/_sir-trevor_overrides.scss +87 -0
- package/app/assets/stylesheets/spotlight/_slideshow_block.scss +87 -0
- package/app/assets/stylesheets/spotlight/_spotlight.scss +49 -0
- package/app/assets/stylesheets/spotlight/_translations.scss +86 -0
- package/app/assets/stylesheets/spotlight/_upload.scss +0 -0
- package/app/assets/stylesheets/spotlight/_uploaded_items_block.scss +7 -0
- package/app/assets/stylesheets/spotlight/_utilities.scss +7 -0
- package/app/assets/stylesheets/spotlight/_variables.scss +42 -0
- package/app/assets/stylesheets/spotlight/_variables_bootstrap.scss +7 -0
- package/app/assets/stylesheets/spotlight/_view_larger.scss +22 -0
- package/app/assets/stylesheets/spotlight/browse_group_categories_block.scss +92 -0
- package/app/assets/stylesheets/spotlight/typeahead.css +77 -0
- package/package.json +29 -0
- package/vendor/assets/images/sir-trevor-icons.svg +263 -0
- package/vendor/assets/javascripts/Leaflet.Editable.js +1917 -0
- package/vendor/assets/javascripts/MutationObserver.js +625 -0
- package/vendor/assets/javascripts/Path.Drag.js +137 -0
- package/vendor/assets/javascripts/bootstrap-tagsinput.js +530 -0
- package/vendor/assets/javascripts/eventable.js +205 -0
- package/vendor/assets/javascripts/jquery.serializejson.js +234 -0
- package/vendor/assets/javascripts/jquery.waitforimages.min.js +2 -0
- package/vendor/assets/javascripts/leaflet-iiif.js +323 -0
- package/vendor/assets/javascripts/nestable.js +645 -0
- package/vendor/assets/javascripts/parameterize.js +137 -0
- package/vendor/assets/javascripts/polyfill.min.js +4 -0
- package/vendor/assets/javascripts/sir-trevor.js +21639 -0
- package/vendor/assets/javascripts/tiny-slider.js +3218 -0
- package/vendor/assets/javascripts/typeahead.bundle.min.js +7 -0
- package/vendor/assets/stylesheets/bootstrap-tagsinput.css +46 -0
- package/vendor/assets/stylesheets/leaflet-areaselect.css +15 -0
- package/vendor/assets/stylesheets/sir-trevor/_icons.scss +6 -0
- package/vendor/assets/stylesheets/sir-trevor/_variables.scss +22 -0
- package/vendor/assets/stylesheets/sir-trevor/base.scss +17 -0
- package/vendor/assets/stylesheets/sir-trevor/block-addition-top.scss +95 -0
- package/vendor/assets/stylesheets/sir-trevor/block-addition.scss +72 -0
- package/vendor/assets/stylesheets/sir-trevor/block-controls.scss +34 -0
- package/vendor/assets/stylesheets/sir-trevor/block-positioner.scss +34 -0
- package/vendor/assets/stylesheets/sir-trevor/block-replacer.scss +43 -0
- package/vendor/assets/stylesheets/sir-trevor/block-ui.scss +120 -0
- package/vendor/assets/stylesheets/sir-trevor/block.scss +300 -0
- package/vendor/assets/stylesheets/sir-trevor/errors.scss +21 -0
- package/vendor/assets/stylesheets/sir-trevor/format-bar.scss +65 -0
- package/vendor/assets/stylesheets/sir-trevor/inputs.scss +45 -0
- package/vendor/assets/stylesheets/sir-trevor/main.scss +24 -0
- package/vendor/assets/stylesheets/sir-trevor/patterns/ui-popup.scss +38 -0
- package/vendor/assets/stylesheets/sir-trevor/utils.scss +10 -0
- package/vendor/assets/stylesheets/tiny-slider.css +1 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof define === 'function' && define.amd) {
|
|
3
|
+
// AMD. Register as a module.
|
|
4
|
+
define('eventable', function() {
|
|
5
|
+
return (root.Eventable = factory());
|
|
6
|
+
});
|
|
7
|
+
} else if (typeof exports !== 'undefined') {
|
|
8
|
+
// Node. Does not work with strict CommonJS, but only CommonJS-like
|
|
9
|
+
// enviroments that support module.exports, like Node.
|
|
10
|
+
module.exports = factory();
|
|
11
|
+
} else {
|
|
12
|
+
// Browser globals
|
|
13
|
+
root.Eventable = factory();
|
|
14
|
+
}
|
|
15
|
+
}(this, function() {
|
|
16
|
+
|
|
17
|
+
// Copy and pasted straight out of Backbone 1.0.0
|
|
18
|
+
// We'll try and keep this updated to the latest
|
|
19
|
+
|
|
20
|
+
var array = [];
|
|
21
|
+
var slice = array.slice;
|
|
22
|
+
|
|
23
|
+
function once(func) {
|
|
24
|
+
var memo, times = 2;
|
|
25
|
+
|
|
26
|
+
return function() {
|
|
27
|
+
if (--times > 0) {
|
|
28
|
+
memo = func.apply(this, arguments);
|
|
29
|
+
} else {
|
|
30
|
+
func = null;
|
|
31
|
+
}
|
|
32
|
+
return memo;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Backbone.Events
|
|
37
|
+
// ---------------
|
|
38
|
+
|
|
39
|
+
// A module that can be mixed in to *any object* in order to provide it with
|
|
40
|
+
// custom events. You may bind with `on` or remove with `off` callback
|
|
41
|
+
// functions to an event; `trigger`-ing an event fires all callbacks in
|
|
42
|
+
// succession.
|
|
43
|
+
//
|
|
44
|
+
// var object = {};
|
|
45
|
+
// extend(object, Backbone.Events);
|
|
46
|
+
// object.on('expand', function(){ alert('expanded'); });
|
|
47
|
+
// object.trigger('expand');
|
|
48
|
+
//
|
|
49
|
+
var Eventable = {
|
|
50
|
+
|
|
51
|
+
// Bind an event to a `callback` function. Passing `"all"` will bind
|
|
52
|
+
// the callback to all events fired.
|
|
53
|
+
on: function(name, callback, context) {
|
|
54
|
+
if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
|
|
55
|
+
this._events || (this._events = {});
|
|
56
|
+
var events = this._events[name] || (this._events[name] = []);
|
|
57
|
+
events.push({callback: callback, context: context, ctx: context || this});
|
|
58
|
+
return this;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Bind an event to only be triggered a single time. After the first time
|
|
62
|
+
// the callback is invoked, it will be removed.
|
|
63
|
+
once: function(name, callback, context) {
|
|
64
|
+
if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
|
|
65
|
+
var self = this;
|
|
66
|
+
var func = once(function() {
|
|
67
|
+
self.off(name, func);
|
|
68
|
+
callback.apply(this, arguments);
|
|
69
|
+
});
|
|
70
|
+
func._callback = callback;
|
|
71
|
+
return this.on(name, func, context);
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Remove one or many callbacks. If `context` is null, removes all
|
|
75
|
+
// callbacks with that function. If `callback` is null, removes all
|
|
76
|
+
// callbacks for the event. If `name` is null, removes all bound
|
|
77
|
+
// callbacks for all events.
|
|
78
|
+
off: function(name, callback, context) {
|
|
79
|
+
var retain, ev, events, names, i, l, j, k;
|
|
80
|
+
if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
|
|
81
|
+
if (!name && !callback && !context) {
|
|
82
|
+
this._events = {};
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
names = name ? [name] : Object.keys(this._events);
|
|
87
|
+
for (i = 0, l = names.length; i < l; i++) {
|
|
88
|
+
name = names[i];
|
|
89
|
+
if (events = this._events[name]) {
|
|
90
|
+
this._events[name] = retain = [];
|
|
91
|
+
if (callback || context) {
|
|
92
|
+
for (j = 0, k = events.length; j < k; j++) {
|
|
93
|
+
ev = events[j];
|
|
94
|
+
if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
|
|
95
|
+
(context && context !== ev.context)) {
|
|
96
|
+
retain.push(ev);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!retain.length) delete this._events[name];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return this;
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Trigger one or many events, firing all bound callbacks. Callbacks are
|
|
108
|
+
// passed the same arguments as `trigger` is, apart from the event name
|
|
109
|
+
// (unless you're listening on `"all"`, which will cause your callback to
|
|
110
|
+
// receive the true name of the event as the first argument).
|
|
111
|
+
trigger: function(name) {
|
|
112
|
+
if (!this._events) return this;
|
|
113
|
+
var args = slice.call(arguments, 1);
|
|
114
|
+
if (!eventsApi(this, 'trigger', name, args)) return this;
|
|
115
|
+
var events = this._events[name];
|
|
116
|
+
var allEvents = this._events.all;
|
|
117
|
+
if (events) triggerEvents(events, args);
|
|
118
|
+
if (allEvents) triggerEvents(allEvents, arguments);
|
|
119
|
+
return this;
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
// Tell this object to stop listening to either specific events ... or
|
|
123
|
+
// to every object it's currently listening to.
|
|
124
|
+
stopListening: function(obj, name, callback) {
|
|
125
|
+
var listeners = this._listeners;
|
|
126
|
+
if (!listeners) return this;
|
|
127
|
+
var deleteListener = !name && !callback;
|
|
128
|
+
if (typeof name === 'object') callback = this;
|
|
129
|
+
if (obj) (listeners = {})[obj._listenerId] = obj;
|
|
130
|
+
for (var id in listeners) {
|
|
131
|
+
listeners[id].off(name, callback, this);
|
|
132
|
+
if (deleteListener) delete this._listeners[id];
|
|
133
|
+
}
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Regular expression used to split event strings.
|
|
140
|
+
var eventSplitter = /\s+/;
|
|
141
|
+
|
|
142
|
+
// Implement fancy features of the Events API such as multiple event
|
|
143
|
+
// names `"change blur"` and jQuery-style event maps `{change: action}`
|
|
144
|
+
// in terms of the existing API.
|
|
145
|
+
var eventsApi = function(obj, action, name, rest) {
|
|
146
|
+
if (!name) return true;
|
|
147
|
+
|
|
148
|
+
// Handle event maps.
|
|
149
|
+
if (typeof name === 'object') {
|
|
150
|
+
for (var key in name) {
|
|
151
|
+
obj[action].apply(obj, [key, name[key]].concat(rest));
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Handle space separated event names.
|
|
157
|
+
if (eventSplitter.test(name)) {
|
|
158
|
+
var names = name.split(eventSplitter);
|
|
159
|
+
for (var i = 0, l = names.length; i < l; i++) {
|
|
160
|
+
obj[action].apply(obj, [names[i]].concat(rest));
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return true;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// A difficult-to-believe, but optimized internal dispatch function for
|
|
169
|
+
// triggering events. Tries to keep the usual cases speedy (most internal
|
|
170
|
+
// Backbone events have 3 arguments).
|
|
171
|
+
var triggerEvents = function(events, args) {
|
|
172
|
+
var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
|
|
173
|
+
switch (args.length) {
|
|
174
|
+
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
|
|
175
|
+
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
|
|
176
|
+
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
|
|
177
|
+
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
|
|
178
|
+
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// Inversion-of-control versions of `on` and `once`. Tell *this* object to
|
|
183
|
+
// listen to an event in another object ... keeping track of what it's
|
|
184
|
+
// listening to.
|
|
185
|
+
function addListenMethod(method, implementation) {
|
|
186
|
+
Eventable[method] = function(obj, name, callback) {
|
|
187
|
+
var listeners = this._listeners || (this._listeners = {});
|
|
188
|
+
var id = obj._listenerId || (obj._listenerId = (new Date()).getTime());
|
|
189
|
+
listeners[id] = obj;
|
|
190
|
+
if (typeof name === 'object') callback = this;
|
|
191
|
+
obj[implementation](name, callback, this);
|
|
192
|
+
return this;
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
addListenMethod('listenTo', 'on');
|
|
197
|
+
addListenMethod('listenToOnce', 'once');
|
|
198
|
+
|
|
199
|
+
// Aliases for backwards compatibility.
|
|
200
|
+
Eventable.bind = Eventable.on;
|
|
201
|
+
Eventable.unbind = Eventable.off;
|
|
202
|
+
|
|
203
|
+
return Eventable;
|
|
204
|
+
|
|
205
|
+
}));
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
SerializeJSON jQuery plugin.
|
|
3
|
+
https://github.com/marioizquierdo/jquery.serializeJSON
|
|
4
|
+
version 2.4.2 (Oct, 2014)
|
|
5
|
+
|
|
6
|
+
Copyright (c) 2014 Mario Izquierdo
|
|
7
|
+
Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
8
|
+
and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
|
9
|
+
*/
|
|
10
|
+
(function ($) {
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
// jQuery('form').serializeJSON()
|
|
14
|
+
$.fn.serializeJSON = function (options) {
|
|
15
|
+
var serializedObject, formAsArray, keys, type, value, _ref, f, opts;
|
|
16
|
+
f = $.serializeJSON;
|
|
17
|
+
opts = f.optsWithDefaults(options); // calculate values for options {parseNumbers, parseBoolens, parseNulls}
|
|
18
|
+
f.validateOptions(opts);
|
|
19
|
+
formAsArray = this.serializeArray(); // array of objects {name, value}
|
|
20
|
+
f.readCheckboxUncheckedValues(formAsArray, this, opts); // add {name, value} of unchecked checkboxes if needed
|
|
21
|
+
|
|
22
|
+
serializedObject = {};
|
|
23
|
+
$.each(formAsArray, function (i, input) {
|
|
24
|
+
keys = f.splitInputNameIntoKeysArray(input.name);
|
|
25
|
+
type = keys.pop(); // the last element is always the type ("string" by default)
|
|
26
|
+
if (type !== 'skip') { // easy way to skip a value
|
|
27
|
+
value = f.parseValue(input.value, type, opts); // string, number, boolean or null
|
|
28
|
+
if (opts.parseWithFunction && type === '_') value = opts.parseWithFunction(value, input.name); // allow for custom parsing
|
|
29
|
+
f.deepSet(serializedObject, keys, value, opts);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return serializedObject;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Use $.serializeJSON as namespace for the auxiliar functions
|
|
36
|
+
// and to define defaults
|
|
37
|
+
$.serializeJSON = {
|
|
38
|
+
|
|
39
|
+
defaultOptions: {
|
|
40
|
+
parseNumbers: false, // convert values like "1", "-2.33" to 1, -2.33
|
|
41
|
+
parseBooleans: false, // convert "true", "false" to true, false
|
|
42
|
+
parseNulls: false, // convert "null" to null
|
|
43
|
+
parseAll: false, // all of the above
|
|
44
|
+
parseWithFunction: null, // to use custom parser, a function like: function(val){ return parsed_val; }
|
|
45
|
+
checkboxUncheckedValue: undefined, // to include that value for unchecked checkboxes (instead of ignoring them)
|
|
46
|
+
useIntKeysAsArrayIndex: false // name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// Merge options with defaults to get {parseNumbers, parseBoolens, parseNulls, useIntKeysAsArrayIndex}
|
|
50
|
+
optsWithDefaults: function(options) {
|
|
51
|
+
var f, parseAll;
|
|
52
|
+
if (options == null) options = {}; // arg default value = {}
|
|
53
|
+
f = $.serializeJSON;
|
|
54
|
+
parseAll = f.optWithDefaults('parseAll', options);
|
|
55
|
+
return {
|
|
56
|
+
parseNumbers: parseAll || f.optWithDefaults('parseNumbers', options),
|
|
57
|
+
parseBooleans: parseAll || f.optWithDefaults('parseBooleans', options),
|
|
58
|
+
parseNulls: parseAll || f.optWithDefaults('parseNulls', options),
|
|
59
|
+
parseWithFunction: f.optWithDefaults('parseWithFunction', options),
|
|
60
|
+
checkboxUncheckedValue: f.optWithDefaults('checkboxUncheckedValue', options),
|
|
61
|
+
useIntKeysAsArrayIndex: f.optWithDefaults('useIntKeysAsArrayIndex', options)
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
optWithDefaults: function(key, options) {
|
|
66
|
+
return (options[key] !== false) && (options[key] !== '') && (options[key] || $.serializeJSON.defaultOptions[key]);
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
validateOptions: function(opts) {
|
|
70
|
+
var opt, validOpts;
|
|
71
|
+
validOpts = ['parseNumbers', 'parseBooleans', 'parseNulls', 'parseAll', 'parseWithFunction', 'checkboxUncheckedValue', 'useIntKeysAsArrayIndex']
|
|
72
|
+
for (opt in opts) {
|
|
73
|
+
if (validOpts.indexOf(opt) === -1) {
|
|
74
|
+
throw new Error("serializeJSON ERROR: invalid option '" + opt + "'. Please use one of " + validOpts.join(','));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// Convert the string to a number, boolean or null, depending on the enable option and the string format.
|
|
80
|
+
parseValue: function(str, type, opts) {
|
|
81
|
+
var value, f;
|
|
82
|
+
f = $.serializeJSON;
|
|
83
|
+
if (type == 'string') return str; // force string
|
|
84
|
+
if (type == 'number' || (opts.parseNumbers && f.isNumeric(str))) return Number(str); // number
|
|
85
|
+
if (type == 'boolean' || (opts.parseBooleans && (str === "true" || str === "false"))) return (["false", "null", "undefined", "", "0"].indexOf(str) === -1); // boolean
|
|
86
|
+
if (type == 'null' || (opts.parseNulls && str == "null")) return ["false", "null", "undefined", "", "0"].indexOf(str) !== -1 ? null : str; // null
|
|
87
|
+
if (type == 'array' || type == 'object') return JSON.parse(str); // array or objects require JSON
|
|
88
|
+
if (type == 'auto') return f.parseValue(str, null, {parseNumbers: true, parseBooleans: true, parseNulls: true}); // try again with something like "parseAll"
|
|
89
|
+
return str; // otherwise, keep same string
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
isObject: function(obj) { return obj === Object(obj); }, // is this variable an object?
|
|
93
|
+
isUndefined: function(obj) { return obj === void 0; }, // safe check for undefined values
|
|
94
|
+
isValidArrayIndex: function(val) { return /^[0-9]+$/.test(String(val)); }, // 1,2,3,4 ... are valid array indexes
|
|
95
|
+
isNumeric: function(obj) { return obj - parseFloat(obj) >= 0; }, // taken from jQuery.isNumeric implementation. Not using jQuery.isNumeric to support old jQuery and Zepto versions
|
|
96
|
+
|
|
97
|
+
// Split the input name in programatically readable keys.
|
|
98
|
+
// The last element is always the type (default "_").
|
|
99
|
+
// Examples:
|
|
100
|
+
// "foo" => ['foo', '_']
|
|
101
|
+
// "foo:string" => ['foo', 'string']
|
|
102
|
+
// "foo:boolean" => ['foo', 'boolean']
|
|
103
|
+
// "[foo]" => ['foo', '_']
|
|
104
|
+
// "foo[inn][bar]" => ['foo', 'inn', 'bar', '_']
|
|
105
|
+
// "foo[inn[bar]]" => ['foo', 'inn', 'bar', '_']
|
|
106
|
+
// "foo[inn][arr][0]" => ['foo', 'inn', 'arr', '0', '_']
|
|
107
|
+
// "arr[][val]" => ['arr', '', 'val', '_']
|
|
108
|
+
// "arr[][val]:null" => ['arr', '', 'val', 'null']
|
|
109
|
+
splitInputNameIntoKeysArray: function (name) {
|
|
110
|
+
var keys, nameWithoutType, type, _ref, f;
|
|
111
|
+
f = $.serializeJSON;
|
|
112
|
+
_ref = f.extractTypeFromInputName(name), nameWithoutType = _ref[0], type = _ref[1];
|
|
113
|
+
keys = nameWithoutType.split('['); // split string into array
|
|
114
|
+
keys = $.map(keys, function (key) { return key.replace(/]/g, ''); }); // remove closing brackets
|
|
115
|
+
if (keys[0] === '') { keys.shift(); } // ensure no opening bracket ("[foo][inn]" should be same as "foo[inn]")
|
|
116
|
+
keys.push(type); // add type at the end
|
|
117
|
+
return keys;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Returns [name-without-type, type] from name.
|
|
121
|
+
// "foo" => ["foo", "_"]
|
|
122
|
+
// "foo:boolean" => ["foo", "boolean"]
|
|
123
|
+
// "foo[bar]:null" => ["foo[bar]", "null"]
|
|
124
|
+
extractTypeFromInputName: function(name) {
|
|
125
|
+
var match, f;
|
|
126
|
+
f = $.serializeJSON;
|
|
127
|
+
if (match = name.match(/(.*):([^:]+)$/)){
|
|
128
|
+
var validTypes = ['string', 'number', 'boolean', 'null', 'array', 'object', 'skip', 'auto']; // validate type
|
|
129
|
+
if (validTypes.indexOf(match[2]) !== -1) {
|
|
130
|
+
return [match[1], match[2]];
|
|
131
|
+
} else {
|
|
132
|
+
throw new Error("serializeJSON ERROR: Invalid type " + match[2] + " found in input name '" + name + "', please use one of " + validTypes.join(', '))
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
return [name, '_']; // no defined type, then use parse options
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
// Set a value in an object or array, using multiple keys to set in a nested object or array:
|
|
140
|
+
//
|
|
141
|
+
// deepSet(obj, ['foo'], v) // obj['foo'] = v
|
|
142
|
+
// deepSet(obj, ['foo', 'inn'], v) // obj['foo']['inn'] = v // Create the inner obj['foo'] object, if needed
|
|
143
|
+
// deepSet(obj, ['foo', 'inn', '123'], v) // obj['foo']['arr']['123'] = v //
|
|
144
|
+
//
|
|
145
|
+
// deepSet(obj, ['0'], v) // obj['0'] = v
|
|
146
|
+
// deepSet(arr, ['0'], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v
|
|
147
|
+
// deepSet(arr, [''], v) // arr.push(v)
|
|
148
|
+
// deepSet(obj, ['arr', ''], v) // obj['arr'].push(v)
|
|
149
|
+
//
|
|
150
|
+
// arr = [];
|
|
151
|
+
// deepSet(arr, ['', v] // arr => [v]
|
|
152
|
+
// deepSet(arr, ['', 'foo'], v) // arr => [v, {foo: v}]
|
|
153
|
+
// deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}]
|
|
154
|
+
// deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}, {bar: v}]
|
|
155
|
+
//
|
|
156
|
+
deepSet: function (o, keys, value, opts) {
|
|
157
|
+
var key, nextKey, tail, lastIdx, lastVal, f;
|
|
158
|
+
if (opts == null) opts = {};
|
|
159
|
+
f = $.serializeJSON;
|
|
160
|
+
if (f.isUndefined(o)) { throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined"); }
|
|
161
|
+
if (!keys || keys.length === 0) { throw new Error("ArgumentError: param 'keys' expected to be an array with least one element"); }
|
|
162
|
+
|
|
163
|
+
key = keys[0];
|
|
164
|
+
|
|
165
|
+
// Only one key, then it's not a deepSet, just assign the value.
|
|
166
|
+
if (keys.length === 1) {
|
|
167
|
+
if (key === '') {
|
|
168
|
+
o.push(value); // '' is used to push values into the array (assume o is an array)
|
|
169
|
+
} else {
|
|
170
|
+
o[key] = value; // other keys can be used as object keys or array indexes
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// With more keys is a deepSet. Apply recursively.
|
|
174
|
+
} else {
|
|
175
|
+
|
|
176
|
+
nextKey = keys[1];
|
|
177
|
+
|
|
178
|
+
// '' is used to push values into the array,
|
|
179
|
+
// with nextKey, set the value into the same object, in object[nextKey].
|
|
180
|
+
// Covers the case of ['', 'foo'] and ['', 'var'] to push the object {foo, var}, and the case of nested arrays.
|
|
181
|
+
if (key === '') {
|
|
182
|
+
lastIdx = o.length - 1; // asume o is array
|
|
183
|
+
lastVal = o[lastIdx];
|
|
184
|
+
if (f.isObject(lastVal) && (f.isUndefined(lastVal[nextKey]) || keys.length > 2)) { // if nextKey is not present in the last object element, or there are more keys to deep set
|
|
185
|
+
key = lastIdx; // then set the new value in the same object element
|
|
186
|
+
} else {
|
|
187
|
+
key = lastIdx + 1; // otherwise, point to set the next index in the array
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// o[key] defaults to object or array, depending if nextKey is an array index (int or '') or an object key (string)
|
|
192
|
+
if (f.isUndefined(o[key])) {
|
|
193
|
+
if (nextKey === '') { // '' is used to push values into the array.
|
|
194
|
+
o[key] = [];
|
|
195
|
+
} else if (opts.useIntKeysAsArrayIndex && f.isValidArrayIndex(nextKey)) { // if 1, 2, 3 ... then use an array, where nextKey is the index
|
|
196
|
+
o[key] = [];
|
|
197
|
+
} else { // for anything else, use an object, where nextKey is going to be the attribute name
|
|
198
|
+
o[key] = {};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Recursively set the inner object
|
|
203
|
+
tail = keys.slice(1);
|
|
204
|
+
f.deepSet(o[key], tail, value, opts);
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// Fill the formAsArray object with values for the unchecked checkbox inputs,
|
|
209
|
+
// using the same format as the jquery.serializeArray function.
|
|
210
|
+
// The value of the unchecked values is determined from the opts.checkboxUncheckedValue
|
|
211
|
+
// and/or the data-unchecked-value attribute of the inputs.
|
|
212
|
+
readCheckboxUncheckedValues: function (formAsArray, $form, opts) {
|
|
213
|
+
var selector, $uncheckedCheckboxes, $el, dataUncheckedValue, f;
|
|
214
|
+
if (opts == null) opts = {};
|
|
215
|
+
f = $.serializeJSON;
|
|
216
|
+
|
|
217
|
+
selector = 'input[type=checkbox][name]:not(:checked,[disabled])';
|
|
218
|
+
$uncheckedCheckboxes = $form.find(selector).add($form.filter(selector));
|
|
219
|
+
$uncheckedCheckboxes.each(function (i, el) {
|
|
220
|
+
$el = $(el);
|
|
221
|
+
dataUncheckedValue = $el.attr('data-unchecked-value');
|
|
222
|
+
if(dataUncheckedValue) { // data-unchecked-value has precedence over option opts.checkboxUncheckedValue
|
|
223
|
+
formAsArray.push({name: el.name, value: dataUncheckedValue});
|
|
224
|
+
} else {
|
|
225
|
+
if (!f.isUndefined(opts.checkboxUncheckedValue)) {
|
|
226
|
+
formAsArray.push({name: el.name, value: opts.checkboxUncheckedValue});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
}(window.jQuery || window.Zepto || window.$));
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! waitForImages jQuery Plugin 2013-07-20 */
|
|
2
|
+
!function(a){var b="waitForImages";a.waitForImages={hasImageProperties:["backgroundImage","listStyleImage","borderImage","borderCornerImage","cursor"]},a.expr[":"].uncached=function(b){if(!a(b).is('img[src!=""]'))return!1;var c=new Image;return c.src=b.src,!c.complete},a.fn.waitForImages=function(c,d,e){var f=0,g=0;if(a.isPlainObject(arguments[0])&&(e=arguments[0].waitForAll,d=arguments[0].each,c=arguments[0].finished),c=c||a.noop,d=d||a.noop,e=!!e,!a.isFunction(c)||!a.isFunction(d))throw new TypeError("An invalid callback was supplied.");return this.each(function(){var h=a(this),i=[],j=a.waitForImages.hasImageProperties||[],k=/url\(\s*(['"]?)(.*?)\1\s*\)/g;e?h.find("*").addBack().each(function(){var b=a(this);b.is("img:uncached")&&i.push({src:b.attr("src"),element:b[0]}),a.each(j,function(a,c){var d,e=b.css(c);if(!e)return!0;for(;d=k.exec(e);)i.push({src:d[2],element:b[0]})})}):h.find("img:uncached").each(function(){i.push({src:this.src,element:this})}),f=i.length,g=0,0===f&&c.call(h[0]),a.each(i,function(e,i){var j=new Image;a(j).on("load."+b+" error."+b,function(a){return g++,d.call(i.element,g,f,"load"==a.type),g==f?(c.call(h[0]),!1):void 0}),j.src=i.src})})}}(jQuery);
|