govuk_publishing_components 15.3.0 → 16.0.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/govspeak.js +26 -0
  3. data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/barchart-enhancement.js +26 -0
  4. data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js +96 -0
  5. data/app/assets/javascripts/govuk_publishing_components/vendor/jquery-ui-1.10.2.custom.js +1639 -0
  6. data/app/assets/javascripts/govuk_publishing_components/vendor/jquery.player.min.js +25 -0
  7. data/app/assets/javascripts/govuk_publishing_components/vendor/magna-charta.min.js +4 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_accessible-autocomplete.scss +1 -7
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_error-alert.scss +1 -1
  10. data/app/assets/stylesheets/govuk_publishing_components/components/_govspeak-html-publication.scss +5 -5
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_success-alert.scss +1 -1
  12. data/app/assets/stylesheets/govuk_publishing_components/components/_textarea.scss +0 -4
  13. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_advisory.scss +1 -1
  14. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_attachment.scss +5 -5
  15. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_charts.scss +1 -0
  16. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_contact.scss +3 -3
  17. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/{form-download.scss → _form-download.scss} +1 -1
  18. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_fraction.scss +1 -1
  19. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_highlight-answer.scss +4 -4
  20. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_images.scss +1 -1
  21. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_media-player.scss +7 -0
  22. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_place.scss +2 -2
  23. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_stat-headline.scss +3 -3
  24. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_summary.scss +2 -2
  25. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_tables.scss +2 -2
  26. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_typography.scss +11 -9
  27. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_warning-callout.scss +2 -2
  28. data/app/views/govuk_publishing_components/components/_accessible_autocomplete.html.erb +17 -19
  29. data/app/views/govuk_publishing_components/components/_details.html.erb +2 -1
  30. data/app/views/govuk_publishing_components/components/_government_navigation.html.erb +2 -2
  31. data/app/views/govuk_publishing_components/components/_govspeak.html.erb +1 -1
  32. data/app/views/govuk_publishing_components/components/_inset_text.html.erb +1 -4
  33. data/app/views/govuk_publishing_components/components/_label.html.erb +5 -4
  34. data/app/views/govuk_publishing_components/components/_radio.html.erb +4 -5
  35. data/app/views/govuk_publishing_components/components/_textarea.html.erb +2 -0
  36. data/app/views/govuk_publishing_components/components/_warning_text.html.erb +1 -5
  37. data/app/views/govuk_publishing_components/components/docs/accessible_autocomplete.yml +0 -8
  38. data/app/views/govuk_publishing_components/components/docs/details.yml +6 -0
  39. data/app/views/govuk_publishing_components/components/docs/govspeak.yml +3 -4
  40. data/app/views/govuk_publishing_components/components/docs/label.yml +9 -0
  41. data/app/views/govuk_publishing_components/components/docs/layout_footer.yml +2 -2
  42. data/lib/govuk_publishing_components/version.rb +1 -1
  43. data/node_modules/accessible-autocomplete/package.json +1 -1
  44. metadata +10 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8684d7e01c2e01dfbb03bf69bb6aaeeadc8137f0eaa4691de731bc90c101c25
4
- data.tar.gz: 8e7ddb8c6c6eeb1b2ad98b2c9c1601c1c5af8f3b35a33e62b7c8eb642b02f8de
3
+ metadata.gz: 545946feac7107939d0fcbc6203e3a788e0d1883f3c1e21bb5671c3ea9f39ed1
4
+ data.tar.gz: 1e15babbf28f8844cdcc1c35e87f0ff59bfd8c4d92ec357f69e801626fa4a29a
5
5
  SHA512:
6
- metadata.gz: 2398ddae0a45b6770c797348043821fe27201eeb37a034c626b2006f45b9daaa1b6f07cb0d88ecd1d28e7e767e90caf14e03c1e41d1e691292983ff9149a91b2
7
- data.tar.gz: aa30213e3ce4771e7ec04d69835a653a6324d5e1e860c66ce74c13637b6e0eccfc851404524f89ee9dd3bd5bf1c1375c3240acae618a900b11055afbfd1cd1d6
6
+ metadata.gz: 1457f8b2260f3caf6d533e4ab9325986f08e71d45760838ac22fe54ebd84ad4b15b72e86a5066a9da60f147f05b20a8ea0f03608ca185d4c02edfe44cad92fc5
7
+ data.tar.gz: 0a653dae71525be265024133260fc4a13d0e764ebef2b79afc56db7c2e05e5db786bcc43486c0d4b8e5d9ac211375bee84e3d65c8b88091b319e49cb33299502
@@ -0,0 +1,26 @@
1
+ window.GOVUK = window.GOVUK || {}
2
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
3
+
4
+ (function (Modules) {
5
+ 'use strict'
6
+
7
+ Modules.Govspeak = function () {
8
+ this.start = function ($element) {
9
+ if (!$element.hasClass('disable-youtube')) {
10
+ this.embedYoutube($element)
11
+ }
12
+
13
+ this.createBarcharts($element)
14
+ }
15
+
16
+ this.embedYoutube = function ($element) {
17
+ var enhancement = new window.GOVUK.GovspeakYoutubeLinkEnhancement($element)
18
+ enhancement.init()
19
+ }
20
+
21
+ this.createBarcharts = function ($element) {
22
+ var enhancement = new window.GOVUK.GovspeakBarchartEnhancement($element)
23
+ enhancement.init()
24
+ }
25
+ }
26
+ })(window.GOVUK.Modules)
@@ -0,0 +1,26 @@
1
+ //= require govuk_publishing_components/vendor/magna-charta.min
2
+
3
+ window.GOVUK = window.GOVUK || {};
4
+
5
+ (function (GOVUK, $) {
6
+ 'use strict'
7
+
8
+ var BarchartEnhancement = function ($element) {
9
+ this.$element = $element
10
+ }
11
+
12
+ BarchartEnhancement.prototype.init = function () {
13
+ // the not selectors are protection against initialising twice since that
14
+ // causes quite a mess. The not .mc-chart is because it creates a second
15
+ // .js-barchart-table element with .mc-chart and then the
16
+ // .js-barchart-table-init is given when we initialise
17
+ var $barcharts = this.$element.find('.js-barchart-table:not(.mc-chart):not(.js-barchart-table-init)')
18
+ $barcharts.each(function () {
19
+ var $table = $(this)
20
+ $.magnaCharta($table, { toggleText: 'Change between chart and table' })
21
+ $table.addClass('js-barchart-table-init')
22
+ })
23
+ }
24
+
25
+ GOVUK.GovspeakBarchartEnhancement = BarchartEnhancement
26
+ }(window.GOVUK, window.jQuery))
@@ -0,0 +1,96 @@
1
+ //= require govuk_publishing_components/vendor/jquery-ui-1.10.2.custom
2
+ //= require govuk_publishing_components/vendor/jquery.player.min
3
+
4
+ window.GOVUK = window.GOVUK || {};
5
+
6
+ (function (GOVUK, $) {
7
+ 'use strict'
8
+
9
+ var YoutubeLinkEnhancement = function ($element) {
10
+ this.$element = $element
11
+ }
12
+
13
+ YoutubeLinkEnhancement.prototype.init = function () {
14
+ var $youtubeLinks = this.$element.find('a[href*="youtube.com"], a[href*="youtu.be"]')
15
+ var _this = this
16
+ $youtubeLinks.each(function () {
17
+ var $link = $(this)
18
+
19
+ if (_this.hasDisabledEmbed($link)) {
20
+ return true
21
+ }
22
+
23
+ var videoId = YoutubeLinkEnhancement.parseVideoId($link.attr('href'))
24
+ if (videoId) {
25
+ _this.embedVideo($link, videoId)
26
+ }
27
+ })
28
+ }
29
+
30
+ YoutubeLinkEnhancement.prototype.hasDisabledEmbed = function ($link) {
31
+ return $link.attr('data-youtube-player') === 'off'
32
+ }
33
+
34
+ YoutubeLinkEnhancement.prototype.embedVideo = function ($link, videoId) {
35
+ var $mediaPlayer = $('<span class="media-player" />')
36
+
37
+ $link.parent().replaceWith($mediaPlayer)
38
+
39
+ var protocol = this.protocol()
40
+
41
+ $mediaPlayer.player({
42
+ id: YoutubeLinkEnhancement.nextId(),
43
+ media: videoId,
44
+ captions: this.captions($link),
45
+ url: protocol + '//www.youtube.com/apiplayer?enablejsapi=1&version=3&playerapiid='
46
+ })
47
+ }
48
+
49
+ YoutubeLinkEnhancement.prototype.protocol = function () {
50
+ var scheme = document.location.protocol
51
+ if (scheme === 'file:') {
52
+ scheme = 'https:'
53
+ }
54
+ return scheme
55
+ }
56
+
57
+ YoutubeLinkEnhancement.prototype.captions = function ($link) {
58
+ var $captions = $link.siblings('.captions')
59
+ if ($captions.length) {
60
+ return $captions.first().attr('href')
61
+ }
62
+ }
63
+
64
+ YoutubeLinkEnhancement.nextId = function () {
65
+ this.embedCount = this.embedCount || 0
66
+ this.embedCount += 1
67
+ return 'youtube-' + this.embedCount
68
+ }
69
+
70
+ // This is a public class method so it can be used outside of this embed to
71
+ // check that user input for videos will be supported in govspeak
72
+ YoutubeLinkEnhancement.parseVideoId = function (url) {
73
+ var parts
74
+
75
+ if (url.indexOf('youtube.com') > -1) {
76
+ var params = {}
77
+ parts = url.split('?')
78
+ if (parts.length === 1) {
79
+ return
80
+ }
81
+ parts = parts[1].split('&')
82
+ for (var i = 0; i < parts.length; i++) {
83
+ var part = parts[i].split('=')
84
+ params[part[0]] = part[1]
85
+ }
86
+ return params.v
87
+ }
88
+
89
+ if (url.indexOf('youtu.be') > -1) {
90
+ parts = url.split('/')
91
+ return parts.pop()
92
+ }
93
+ }
94
+
95
+ GOVUK.GovspeakYoutubeLinkEnhancement = YoutubeLinkEnhancement
96
+ })(window.GOVUK, window.jQuery)
@@ -0,0 +1,1639 @@
1
+ /*! jQuery UI - v1.10.2 - 2013-03-19
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.slider.js
4
+ * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
5
+
6
+ (function( $, undefined ) {
7
+
8
+ var uuid = 0,
9
+ runiqueId = /^ui-id-\d+$/;
10
+
11
+ // $.ui might exist from components with no dependencies, e.g., $.ui.position
12
+ $.ui = $.ui || {};
13
+
14
+ $.extend( $.ui, {
15
+ version: "1.10.2",
16
+
17
+ keyCode: {
18
+ BACKSPACE: 8,
19
+ COMMA: 188,
20
+ DELETE: 46,
21
+ DOWN: 40,
22
+ END: 35,
23
+ ENTER: 13,
24
+ ESCAPE: 27,
25
+ HOME: 36,
26
+ LEFT: 37,
27
+ NUMPAD_ADD: 107,
28
+ NUMPAD_DECIMAL: 110,
29
+ NUMPAD_DIVIDE: 111,
30
+ NUMPAD_ENTER: 108,
31
+ NUMPAD_MULTIPLY: 106,
32
+ NUMPAD_SUBTRACT: 109,
33
+ PAGE_DOWN: 34,
34
+ PAGE_UP: 33,
35
+ PERIOD: 190,
36
+ RIGHT: 39,
37
+ SPACE: 32,
38
+ TAB: 9,
39
+ UP: 38
40
+ }
41
+ });
42
+
43
+ // plugins
44
+ $.fn.extend({
45
+ focus: (function( orig ) {
46
+ return function( delay, fn ) {
47
+ return typeof delay === "number" ?
48
+ this.each(function() {
49
+ var elem = this;
50
+ setTimeout(function() {
51
+ $( elem ).focus();
52
+ if ( fn ) {
53
+ fn.call( elem );
54
+ }
55
+ }, delay );
56
+ }) :
57
+ orig.apply( this, arguments );
58
+ };
59
+ })( $.fn.focus ),
60
+
61
+ scrollParent: function() {
62
+ var scrollParent;
63
+ if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64
+ scrollParent = this.parents().filter(function() {
65
+ return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66
+ }).eq(0);
67
+ } else {
68
+ scrollParent = this.parents().filter(function() {
69
+ return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70
+ }).eq(0);
71
+ }
72
+
73
+ return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74
+ },
75
+
76
+ zIndex: function( zIndex ) {
77
+ if ( zIndex !== undefined ) {
78
+ return this.css( "zIndex", zIndex );
79
+ }
80
+
81
+ if ( this.length ) {
82
+ var elem = $( this[ 0 ] ), position, value;
83
+ while ( elem.length && elem[ 0 ] !== document ) {
84
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
85
+ // This makes behavior of this function consistent across browsers
86
+ // WebKit always returns auto if the element is positioned
87
+ position = elem.css( "position" );
88
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89
+ // IE returns 0 when zIndex is not specified
90
+ // other browsers return a string
91
+ // we ignore the case of nested elements with an explicit value of 0
92
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93
+ value = parseInt( elem.css( "zIndex" ), 10 );
94
+ if ( !isNaN( value ) && value !== 0 ) {
95
+ return value;
96
+ }
97
+ }
98
+ elem = elem.parent();
99
+ }
100
+ }
101
+
102
+ return 0;
103
+ },
104
+
105
+ uniqueId: function() {
106
+ return this.each(function() {
107
+ if ( !this.id ) {
108
+ this.id = "ui-id-" + (++uuid);
109
+ }
110
+ });
111
+ },
112
+
113
+ removeUniqueId: function() {
114
+ return this.each(function() {
115
+ if ( runiqueId.test( this.id ) ) {
116
+ $( this ).removeAttr( "id" );
117
+ }
118
+ });
119
+ }
120
+ });
121
+
122
+ // selectors
123
+ function focusable( element, isTabIndexNotNaN ) {
124
+ var map, mapName, img,
125
+ nodeName = element.nodeName.toLowerCase();
126
+ if ( "area" === nodeName ) {
127
+ map = element.parentNode;
128
+ mapName = map.name;
129
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130
+ return false;
131
+ }
132
+ img = $( "img[usemap=#" + mapName + "]" )[0];
133
+ return !!img && visible( img );
134
+ }
135
+ return ( /input|select|textarea|button|object/.test( nodeName ) ?
136
+ !element.disabled :
137
+ "a" === nodeName ?
138
+ element.href || isTabIndexNotNaN :
139
+ isTabIndexNotNaN) &&
140
+ // the element and all of its ancestors must be visible
141
+ visible( element );
142
+ }
143
+
144
+ function visible( element ) {
145
+ return $.expr.filters.visible( element ) &&
146
+ !$( element ).parents().addBack().filter(function() {
147
+ return $.css( this, "visibility" ) === "hidden";
148
+ }).length;
149
+ }
150
+
151
+ $.extend( $.expr[ ":" ], {
152
+ data: $.expr.createPseudo ?
153
+ $.expr.createPseudo(function( dataName ) {
154
+ return function( elem ) {
155
+ return !!$.data( elem, dataName );
156
+ };
157
+ }) :
158
+ // support: jQuery <1.8
159
+ function( elem, i, match ) {
160
+ return !!$.data( elem, match[ 3 ] );
161
+ },
162
+
163
+ focusable: function( element ) {
164
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165
+ },
166
+
167
+ tabbable: function( element ) {
168
+ var tabIndex = $.attr( element, "tabindex" ),
169
+ isTabIndexNaN = isNaN( tabIndex );
170
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171
+ }
172
+ });
173
+
174
+ // support: jQuery <1.8
175
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176
+ $.each( [ "Width", "Height" ], function( i, name ) {
177
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178
+ type = name.toLowerCase(),
179
+ orig = {
180
+ innerWidth: $.fn.innerWidth,
181
+ innerHeight: $.fn.innerHeight,
182
+ outerWidth: $.fn.outerWidth,
183
+ outerHeight: $.fn.outerHeight
184
+ };
185
+
186
+ function reduce( elem, size, border, margin ) {
187
+ $.each( side, function() {
188
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189
+ if ( border ) {
190
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191
+ }
192
+ if ( margin ) {
193
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194
+ }
195
+ });
196
+ return size;
197
+ }
198
+
199
+ $.fn[ "inner" + name ] = function( size ) {
200
+ if ( size === undefined ) {
201
+ return orig[ "inner" + name ].call( this );
202
+ }
203
+
204
+ return this.each(function() {
205
+ $( this ).css( type, reduce( this, size ) + "px" );
206
+ });
207
+ };
208
+
209
+ $.fn[ "outer" + name] = function( size, margin ) {
210
+ if ( typeof size !== "number" ) {
211
+ return orig[ "outer" + name ].call( this, size );
212
+ }
213
+
214
+ return this.each(function() {
215
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
216
+ });
217
+ };
218
+ });
219
+ }
220
+
221
+ // support: jQuery <1.8
222
+ if ( !$.fn.addBack ) {
223
+ $.fn.addBack = function( selector ) {
224
+ return this.add( selector == null ?
225
+ this.prevObject : this.prevObject.filter( selector )
226
+ );
227
+ };
228
+ }
229
+
230
+ // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231
+ if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232
+ $.fn.removeData = (function( removeData ) {
233
+ return function( key ) {
234
+ if ( arguments.length ) {
235
+ return removeData.call( this, $.camelCase( key ) );
236
+ } else {
237
+ return removeData.call( this );
238
+ }
239
+ };
240
+ })( $.fn.removeData );
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ // deprecated
248
+ $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
+
250
+ $.support.selectstart = "onselectstart" in document.createElement( "div" );
251
+ $.fn.extend({
252
+ disableSelection: function() {
253
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254
+ ".ui-disableSelection", function( event ) {
255
+ event.preventDefault();
256
+ });
257
+ },
258
+
259
+ enableSelection: function() {
260
+ return this.unbind( ".ui-disableSelection" );
261
+ }
262
+ });
263
+
264
+ $.extend( $.ui, {
265
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
266
+ plugin: {
267
+ add: function( module, option, set ) {
268
+ var i,
269
+ proto = $.ui[ module ].prototype;
270
+ for ( i in set ) {
271
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
272
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
273
+ }
274
+ },
275
+ call: function( instance, name, args ) {
276
+ var i,
277
+ set = instance.plugins[ name ];
278
+ if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279
+ return;
280
+ }
281
+
282
+ for ( i = 0; i < set.length; i++ ) {
283
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
284
+ set[ i ][ 1 ].apply( instance.element, args );
285
+ }
286
+ }
287
+ }
288
+ },
289
+
290
+ // only used by resizable
291
+ hasScroll: function( el, a ) {
292
+
293
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
294
+ if ( $( el ).css( "overflow" ) === "hidden") {
295
+ return false;
296
+ }
297
+
298
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299
+ has = false;
300
+
301
+ if ( el[ scroll ] > 0 ) {
302
+ return true;
303
+ }
304
+
305
+ // TODO: determine which cases actually cause this to happen
306
+ // if the element doesn't have the scroll set, see if it's possible to
307
+ // set the scroll
308
+ el[ scroll ] = 1;
309
+ has = ( el[ scroll ] > 0 );
310
+ el[ scroll ] = 0;
311
+ return has;
312
+ }
313
+ });
314
+
315
+ })( jQuery );
316
+ (function( $, undefined ) {
317
+
318
+ var uuid = 0,
319
+ slice = Array.prototype.slice,
320
+ _cleanData = $.cleanData;
321
+ $.cleanData = function( elems ) {
322
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323
+ try {
324
+ $( elem ).triggerHandler( "remove" );
325
+ // http://bugs.jquery.com/ticket/8235
326
+ } catch( e ) {}
327
+ }
328
+ _cleanData( elems );
329
+ };
330
+
331
+ $.widget = function( name, base, prototype ) {
332
+ var fullName, existingConstructor, constructor, basePrototype,
333
+ // proxiedPrototype allows the provided prototype to remain unmodified
334
+ // so that it can be used as a mixin for multiple widgets (#8876)
335
+ proxiedPrototype = {},
336
+ namespace = name.split( "." )[ 0 ];
337
+
338
+ name = name.split( "." )[ 1 ];
339
+ fullName = namespace + "-" + name;
340
+
341
+ if ( !prototype ) {
342
+ prototype = base;
343
+ base = $.Widget;
344
+ }
345
+
346
+ // create selector for plugin
347
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348
+ return !!$.data( elem, fullName );
349
+ };
350
+
351
+ $[ namespace ] = $[ namespace ] || {};
352
+ existingConstructor = $[ namespace ][ name ];
353
+ constructor = $[ namespace ][ name ] = function( options, element ) {
354
+ // allow instantiation without "new" keyword
355
+ if ( !this._createWidget ) {
356
+ return new constructor( options, element );
357
+ }
358
+
359
+ // allow instantiation without initializing for simple inheritance
360
+ // must use "new" keyword (the code above always passes args)
361
+ if ( arguments.length ) {
362
+ this._createWidget( options, element );
363
+ }
364
+ };
365
+ // extend with the existing constructor to carry over any static properties
366
+ $.extend( constructor, existingConstructor, {
367
+ version: prototype.version,
368
+ // copy the object used to create the prototype in case we need to
369
+ // redefine the widget later
370
+ _proto: $.extend( {}, prototype ),
371
+ // track widgets that inherit from this widget in case this widget is
372
+ // redefined after a widget inherits from it
373
+ _childConstructors: []
374
+ });
375
+
376
+ basePrototype = new base();
377
+ // we need to make the options hash a property directly on the new instance
378
+ // otherwise we'll modify the options hash on the prototype that we're
379
+ // inheriting from
380
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
381
+ $.each( prototype, function( prop, value ) {
382
+ if ( !$.isFunction( value ) ) {
383
+ proxiedPrototype[ prop ] = value;
384
+ return;
385
+ }
386
+ proxiedPrototype[ prop ] = (function() {
387
+ var _super = function() {
388
+ return base.prototype[ prop ].apply( this, arguments );
389
+ },
390
+ _superApply = function( args ) {
391
+ return base.prototype[ prop ].apply( this, args );
392
+ };
393
+ return function() {
394
+ var __super = this._super,
395
+ __superApply = this._superApply,
396
+ returnValue;
397
+
398
+ this._super = _super;
399
+ this._superApply = _superApply;
400
+
401
+ returnValue = value.apply( this, arguments );
402
+
403
+ this._super = __super;
404
+ this._superApply = __superApply;
405
+
406
+ return returnValue;
407
+ };
408
+ })();
409
+ });
410
+ constructor.prototype = $.widget.extend( basePrototype, {
411
+ // TODO: remove support for widgetEventPrefix
412
+ // always use the name + a colon as the prefix, e.g., draggable:start
413
+ // don't prefix for widgets that aren't DOM-based
414
+ widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415
+ }, proxiedPrototype, {
416
+ constructor: constructor,
417
+ namespace: namespace,
418
+ widgetName: name,
419
+ widgetFullName: fullName
420
+ });
421
+
422
+ // If this widget is being redefined then we need to find all widgets that
423
+ // are inheriting from it and redefine all of them so that they inherit from
424
+ // the new version of this widget. We're essentially trying to replace one
425
+ // level in the prototype chain.
426
+ if ( existingConstructor ) {
427
+ $.each( existingConstructor._childConstructors, function( i, child ) {
428
+ var childPrototype = child.prototype;
429
+
430
+ // redefine the child widget using the same prototype that was
431
+ // originally used, but inherit from the new version of the base
432
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433
+ });
434
+ // remove the list of existing child constructors from the old constructor
435
+ // so the old child constructors can be garbage collected
436
+ delete existingConstructor._childConstructors;
437
+ } else {
438
+ base._childConstructors.push( constructor );
439
+ }
440
+
441
+ $.widget.bridge( name, constructor );
442
+ };
443
+
444
+ $.widget.extend = function( target ) {
445
+ var input = slice.call( arguments, 1 ),
446
+ inputIndex = 0,
447
+ inputLength = input.length,
448
+ key,
449
+ value;
450
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
451
+ for ( key in input[ inputIndex ] ) {
452
+ value = input[ inputIndex ][ key ];
453
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454
+ // Clone objects
455
+ if ( $.isPlainObject( value ) ) {
456
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
457
+ $.widget.extend( {}, target[ key ], value ) :
458
+ // Don't extend strings, arrays, etc. with objects
459
+ $.widget.extend( {}, value );
460
+ // Copy everything else by reference
461
+ } else {
462
+ target[ key ] = value;
463
+ }
464
+ }
465
+ }
466
+ }
467
+ return target;
468
+ };
469
+
470
+ $.widget.bridge = function( name, object ) {
471
+ var fullName = object.prototype.widgetFullName || name;
472
+ $.fn[ name ] = function( options ) {
473
+ var isMethodCall = typeof options === "string",
474
+ args = slice.call( arguments, 1 ),
475
+ returnValue = this;
476
+
477
+ // allow multiple hashes to be passed on init
478
+ options = !isMethodCall && args.length ?
479
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
480
+ options;
481
+
482
+ if ( isMethodCall ) {
483
+ this.each(function() {
484
+ var methodValue,
485
+ instance = $.data( this, fullName );
486
+ if ( !instance ) {
487
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
488
+ "attempted to call method '" + options + "'" );
489
+ }
490
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492
+ }
493
+ methodValue = instance[ options ].apply( instance, args );
494
+ if ( methodValue !== instance && methodValue !== undefined ) {
495
+ returnValue = methodValue && methodValue.jquery ?
496
+ returnValue.pushStack( methodValue.get() ) :
497
+ methodValue;
498
+ return false;
499
+ }
500
+ });
501
+ } else {
502
+ this.each(function() {
503
+ var instance = $.data( this, fullName );
504
+ if ( instance ) {
505
+ instance.option( options || {} )._init();
506
+ } else {
507
+ $.data( this, fullName, new object( options, this ) );
508
+ }
509
+ });
510
+ }
511
+
512
+ return returnValue;
513
+ };
514
+ };
515
+
516
+ $.Widget = function( /* options, element */ ) {};
517
+ $.Widget._childConstructors = [];
518
+
519
+ $.Widget.prototype = {
520
+ widgetName: "widget",
521
+ widgetEventPrefix: "",
522
+ defaultElement: "<div>",
523
+ options: {
524
+ disabled: false,
525
+
526
+ // callbacks
527
+ create: null
528
+ },
529
+ _createWidget: function( options, element ) {
530
+ element = $( element || this.defaultElement || this )[ 0 ];
531
+ this.element = $( element );
532
+ this.uuid = uuid++;
533
+ this.eventNamespace = "." + this.widgetName + this.uuid;
534
+ this.options = $.widget.extend( {},
535
+ this.options,
536
+ this._getCreateOptions(),
537
+ options );
538
+
539
+ this.bindings = $();
540
+ this.hoverable = $();
541
+ this.focusable = $();
542
+
543
+ if ( element !== this ) {
544
+ $.data( element, this.widgetFullName, this );
545
+ this._on( true, this.element, {
546
+ remove: function( event ) {
547
+ if ( event.target === element ) {
548
+ this.destroy();
549
+ }
550
+ }
551
+ });
552
+ this.document = $( element.style ?
553
+ // element within the document
554
+ element.ownerDocument :
555
+ // element is window or document
556
+ element.document || element );
557
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558
+ }
559
+
560
+ this._create();
561
+ this._trigger( "create", null, this._getCreateEventData() );
562
+ this._init();
563
+ },
564
+ _getCreateOptions: $.noop,
565
+ _getCreateEventData: $.noop,
566
+ _create: $.noop,
567
+ _init: $.noop,
568
+
569
+ destroy: function() {
570
+ this._destroy();
571
+ // we can probably remove the unbind calls in 2.0
572
+ // all event bindings should go through this._on()
573
+ this.element
574
+ .unbind( this.eventNamespace )
575
+ // 1.9 BC for #7810
576
+ // TODO remove dual storage
577
+ .removeData( this.widgetName )
578
+ .removeData( this.widgetFullName )
579
+ // support: jquery <1.6.3
580
+ // http://bugs.jquery.com/ticket/9413
581
+ .removeData( $.camelCase( this.widgetFullName ) );
582
+ this.widget()
583
+ .unbind( this.eventNamespace )
584
+ .removeAttr( "aria-disabled" )
585
+ .removeClass(
586
+ this.widgetFullName + "-disabled " +
587
+ "ui-state-disabled" );
588
+
589
+ // clean up events and states
590
+ this.bindings.unbind( this.eventNamespace );
591
+ this.hoverable.removeClass( "ui-state-hover" );
592
+ this.focusable.removeClass( "ui-state-focus" );
593
+ },
594
+ _destroy: $.noop,
595
+
596
+ widget: function() {
597
+ return this.element;
598
+ },
599
+
600
+ option: function( key, value ) {
601
+ var options = key,
602
+ parts,
603
+ curOption,
604
+ i;
605
+
606
+ if ( arguments.length === 0 ) {
607
+ // don't return a reference to the internal hash
608
+ return $.widget.extend( {}, this.options );
609
+ }
610
+
611
+ if ( typeof key === "string" ) {
612
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613
+ options = {};
614
+ parts = key.split( "." );
615
+ key = parts.shift();
616
+ if ( parts.length ) {
617
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618
+ for ( i = 0; i < parts.length - 1; i++ ) {
619
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620
+ curOption = curOption[ parts[ i ] ];
621
+ }
622
+ key = parts.pop();
623
+ if ( value === undefined ) {
624
+ return curOption[ key ] === undefined ? null : curOption[ key ];
625
+ }
626
+ curOption[ key ] = value;
627
+ } else {
628
+ if ( value === undefined ) {
629
+ return this.options[ key ] === undefined ? null : this.options[ key ];
630
+ }
631
+ options[ key ] = value;
632
+ }
633
+ }
634
+
635
+ this._setOptions( options );
636
+
637
+ return this;
638
+ },
639
+ _setOptions: function( options ) {
640
+ var key;
641
+
642
+ for ( key in options ) {
643
+ this._setOption( key, options[ key ] );
644
+ }
645
+
646
+ return this;
647
+ },
648
+ _setOption: function( key, value ) {
649
+ this.options[ key ] = value;
650
+
651
+ if ( key === "disabled" ) {
652
+ this.widget()
653
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654
+ .attr( "aria-disabled", value );
655
+ this.hoverable.removeClass( "ui-state-hover" );
656
+ this.focusable.removeClass( "ui-state-focus" );
657
+ }
658
+
659
+ return this;
660
+ },
661
+
662
+ enable: function() {
663
+ return this._setOption( "disabled", false );
664
+ },
665
+ disable: function() {
666
+ return this._setOption( "disabled", true );
667
+ },
668
+
669
+ _on: function( suppressDisabledCheck, element, handlers ) {
670
+ var delegateElement,
671
+ instance = this;
672
+
673
+ // no suppressDisabledCheck flag, shuffle arguments
674
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
675
+ handlers = element;
676
+ element = suppressDisabledCheck;
677
+ suppressDisabledCheck = false;
678
+ }
679
+
680
+ // no element argument, shuffle and use this.element
681
+ if ( !handlers ) {
682
+ handlers = element;
683
+ element = this.element;
684
+ delegateElement = this.widget();
685
+ } else {
686
+ // accept selectors, DOM elements
687
+ element = delegateElement = $( element );
688
+ this.bindings = this.bindings.add( element );
689
+ }
690
+
691
+ $.each( handlers, function( event, handler ) {
692
+ function handlerProxy() {
693
+ // allow widgets to customize the disabled handling
694
+ // - disabled as an array instead of boolean
695
+ // - disabled class as method for disabling individual parts
696
+ if ( !suppressDisabledCheck &&
697
+ ( instance.options.disabled === true ||
698
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
699
+ return;
700
+ }
701
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
702
+ .apply( instance, arguments );
703
+ }
704
+
705
+ // copy the guid so direct unbinding works
706
+ if ( typeof handler !== "string" ) {
707
+ handlerProxy.guid = handler.guid =
708
+ handler.guid || handlerProxy.guid || $.guid++;
709
+ }
710
+
711
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
712
+ eventName = match[1] + instance.eventNamespace,
713
+ selector = match[2];
714
+ if ( selector ) {
715
+ delegateElement.delegate( selector, eventName, handlerProxy );
716
+ } else {
717
+ element.bind( eventName, handlerProxy );
718
+ }
719
+ });
720
+ },
721
+
722
+ _off: function( element, eventName ) {
723
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724
+ element.unbind( eventName ).undelegate( eventName );
725
+ },
726
+
727
+ _delay: function( handler, delay ) {
728
+ function handlerProxy() {
729
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
730
+ .apply( instance, arguments );
731
+ }
732
+ var instance = this;
733
+ return setTimeout( handlerProxy, delay || 0 );
734
+ },
735
+
736
+ _hoverable: function( element ) {
737
+ this.hoverable = this.hoverable.add( element );
738
+ this._on( element, {
739
+ mouseenter: function( event ) {
740
+ $( event.currentTarget ).addClass( "ui-state-hover" );
741
+ },
742
+ mouseleave: function( event ) {
743
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
744
+ }
745
+ });
746
+ },
747
+
748
+ _focusable: function( element ) {
749
+ this.focusable = this.focusable.add( element );
750
+ this._on( element, {
751
+ focusin: function( event ) {
752
+ $( event.currentTarget ).addClass( "ui-state-focus" );
753
+ },
754
+ focusout: function( event ) {
755
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
756
+ }
757
+ });
758
+ },
759
+
760
+ _trigger: function( type, event, data ) {
761
+ var prop, orig,
762
+ callback = this.options[ type ];
763
+
764
+ data = data || {};
765
+ event = $.Event( event );
766
+ event.type = ( type === this.widgetEventPrefix ?
767
+ type :
768
+ this.widgetEventPrefix + type ).toLowerCase();
769
+ // the original event may come from any element
770
+ // so we need to reset the target on the new event
771
+ event.target = this.element[ 0 ];
772
+
773
+ // copy original event properties over to the new event
774
+ orig = event.originalEvent;
775
+ if ( orig ) {
776
+ for ( prop in orig ) {
777
+ if ( !( prop in event ) ) {
778
+ event[ prop ] = orig[ prop ];
779
+ }
780
+ }
781
+ }
782
+
783
+ this.element.trigger( event, data );
784
+ return !( $.isFunction( callback ) &&
785
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786
+ event.isDefaultPrevented() );
787
+ }
788
+ };
789
+
790
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792
+ if ( typeof options === "string" ) {
793
+ options = { effect: options };
794
+ }
795
+ var hasOptions,
796
+ effectName = !options ?
797
+ method :
798
+ options === true || typeof options === "number" ?
799
+ defaultEffect :
800
+ options.effect || defaultEffect;
801
+ options = options || {};
802
+ if ( typeof options === "number" ) {
803
+ options = { duration: options };
804
+ }
805
+ hasOptions = !$.isEmptyObject( options );
806
+ options.complete = callback;
807
+ if ( options.delay ) {
808
+ element.delay( options.delay );
809
+ }
810
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811
+ element[ method ]( options );
812
+ } else if ( effectName !== method && element[ effectName ] ) {
813
+ element[ effectName ]( options.duration, options.easing, callback );
814
+ } else {
815
+ element.queue(function( next ) {
816
+ $( this )[ method ]();
817
+ if ( callback ) {
818
+ callback.call( element[ 0 ] );
819
+ }
820
+ next();
821
+ });
822
+ }
823
+ };
824
+ });
825
+
826
+ })( jQuery );
827
+ (function( $, undefined ) {
828
+
829
+ var mouseHandled = false;
830
+ $( document ).mouseup( function() {
831
+ mouseHandled = false;
832
+ });
833
+
834
+ $.widget("ui.mouse", {
835
+ version: "1.10.2",
836
+ options: {
837
+ cancel: "input,textarea,button,select,option",
838
+ distance: 1,
839
+ delay: 0
840
+ },
841
+ _mouseInit: function() {
842
+ var that = this;
843
+
844
+ this.element
845
+ .bind("mousedown."+this.widgetName, function(event) {
846
+ return that._mouseDown(event);
847
+ })
848
+ .bind("click."+this.widgetName, function(event) {
849
+ if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850
+ $.removeData(event.target, that.widgetName + ".preventClickEvent");
851
+ event.stopImmediatePropagation();
852
+ return false;
853
+ }
854
+ });
855
+
856
+ this.started = false;
857
+ },
858
+
859
+ // TODO: make sure destroying one instance of mouse doesn't mess with
860
+ // other instances of mouse
861
+ _mouseDestroy: function() {
862
+ this.element.unbind("."+this.widgetName);
863
+ if ( this._mouseMoveDelegate ) {
864
+ $(document)
865
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867
+ }
868
+ },
869
+
870
+ _mouseDown: function(event) {
871
+ // don't let more than one widget handle mouseStart
872
+ if( mouseHandled ) { return; }
873
+
874
+ // we may have missed mouseup (out of window)
875
+ (this._mouseStarted && this._mouseUp(event));
876
+
877
+ this._mouseDownEvent = event;
878
+
879
+ var that = this,
880
+ btnIsLeft = (event.which === 1),
881
+ // event.target.nodeName works around a bug in IE 8 with
882
+ // disabled inputs (#7620)
883
+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885
+ return true;
886
+ }
887
+
888
+ this.mouseDelayMet = !this.options.delay;
889
+ if (!this.mouseDelayMet) {
890
+ this._mouseDelayTimer = setTimeout(function() {
891
+ that.mouseDelayMet = true;
892
+ }, this.options.delay);
893
+ }
894
+
895
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896
+ this._mouseStarted = (this._mouseStart(event) !== false);
897
+ if (!this._mouseStarted) {
898
+ event.preventDefault();
899
+ return true;
900
+ }
901
+ }
902
+
903
+ // Click event may never have fired (Gecko & Opera)
904
+ if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905
+ $.removeData(event.target, this.widgetName + ".preventClickEvent");
906
+ }
907
+
908
+ // these delegates are required to keep context
909
+ this._mouseMoveDelegate = function(event) {
910
+ return that._mouseMove(event);
911
+ };
912
+ this._mouseUpDelegate = function(event) {
913
+ return that._mouseUp(event);
914
+ };
915
+ $(document)
916
+ .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917
+ .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
+
919
+ event.preventDefault();
920
+
921
+ mouseHandled = true;
922
+ return true;
923
+ },
924
+
925
+ _mouseMove: function(event) {
926
+ // IE mouseup check - mouseup happened when mouse was out of window
927
+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928
+ return this._mouseUp(event);
929
+ }
930
+
931
+ if (this._mouseStarted) {
932
+ this._mouseDrag(event);
933
+ return event.preventDefault();
934
+ }
935
+
936
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937
+ this._mouseStarted =
938
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
939
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940
+ }
941
+
942
+ return !this._mouseStarted;
943
+ },
944
+
945
+ _mouseUp: function(event) {
946
+ $(document)
947
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
+
950
+ if (this._mouseStarted) {
951
+ this._mouseStarted = false;
952
+
953
+ if (event.target === this._mouseDownEvent.target) {
954
+ $.data(event.target, this.widgetName + ".preventClickEvent", true);
955
+ }
956
+
957
+ this._mouseStop(event);
958
+ }
959
+
960
+ return false;
961
+ },
962
+
963
+ _mouseDistanceMet: function(event) {
964
+ return (Math.max(
965
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
966
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
967
+ ) >= this.options.distance
968
+ );
969
+ },
970
+
971
+ _mouseDelayMet: function(/* event */) {
972
+ return this.mouseDelayMet;
973
+ },
974
+
975
+ // These are placeholder methods, to be overriden by extending plugin
976
+ _mouseStart: function(/* event */) {},
977
+ _mouseDrag: function(/* event */) {},
978
+ _mouseStop: function(/* event */) {},
979
+ _mouseCapture: function(/* event */) { return true; }
980
+ });
981
+
982
+ })(jQuery);
983
+ (function( $, undefined ) {
984
+
985
+ // number of pages in a slider
986
+ // (how many times can you page up/down to go through the whole range)
987
+ var numPages = 5;
988
+
989
+ $.widget( "ui.slider", $.ui.mouse, {
990
+ version: "1.10.2",
991
+ widgetEventPrefix: "slide",
992
+
993
+ options: {
994
+ animate: false,
995
+ distance: 0,
996
+ max: 100,
997
+ min: 0,
998
+ orientation: "horizontal",
999
+ range: false,
1000
+ step: 1,
1001
+ value: 0,
1002
+ values: null,
1003
+
1004
+ // callbacks
1005
+ change: null,
1006
+ slide: null,
1007
+ start: null,
1008
+ stop: null
1009
+ },
1010
+
1011
+ _create: function() {
1012
+ this._keySliding = false;
1013
+ this._mouseSliding = false;
1014
+ this._animateOff = true;
1015
+ this._handleIndex = null;
1016
+ this._detectOrientation();
1017
+ this._mouseInit();
1018
+
1019
+ this.element
1020
+ .addClass( "ui-slider" +
1021
+ " ui-slider-" + this.orientation +
1022
+ " ui-widget" +
1023
+ " ui-widget-content" +
1024
+ " ui-corner-all");
1025
+
1026
+ this._refresh();
1027
+ this._setOption( "disabled", this.options.disabled );
1028
+
1029
+ this._animateOff = false;
1030
+ },
1031
+
1032
+ _refresh: function() {
1033
+ this._createRange();
1034
+ this._createHandles();
1035
+ this._setupEvents();
1036
+ this._refreshValue();
1037
+ },
1038
+
1039
+ _createHandles: function() {
1040
+ var i, handleCount,
1041
+ options = this.options,
1042
+ existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
1043
+ handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
1044
+ handles = [];
1045
+
1046
+ handleCount = ( options.values && options.values.length ) || 1;
1047
+
1048
+ if ( existingHandles.length > handleCount ) {
1049
+ existingHandles.slice( handleCount ).remove();
1050
+ existingHandles = existingHandles.slice( 0, handleCount );
1051
+ }
1052
+
1053
+ for ( i = existingHandles.length; i < handleCount; i++ ) {
1054
+ handles.push( handle );
1055
+ }
1056
+
1057
+ this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
1058
+
1059
+ this.handle = this.handles.eq( 0 );
1060
+
1061
+ this.handles.each(function( i ) {
1062
+ $( this ).data( "ui-slider-handle-index", i );
1063
+ });
1064
+ },
1065
+
1066
+ _createRange: function() {
1067
+ var options = this.options,
1068
+ classes = "";
1069
+
1070
+ if ( options.range ) {
1071
+ if ( options.range === true ) {
1072
+ if ( !options.values ) {
1073
+ options.values = [ this._valueMin(), this._valueMin() ];
1074
+ } else if ( options.values.length && options.values.length !== 2 ) {
1075
+ options.values = [ options.values[0], options.values[0] ];
1076
+ } else if ( $.isArray( options.values ) ) {
1077
+ options.values = options.values.slice(0);
1078
+ }
1079
+ }
1080
+
1081
+ if ( !this.range || !this.range.length ) {
1082
+ this.range = $( "<div></div>" )
1083
+ .appendTo( this.element );
1084
+
1085
+ classes = "ui-slider-range" +
1086
+ // note: this isn't the most fittingly semantic framework class for this element,
1087
+ // but worked best visually with a variety of themes
1088
+ " ui-widget-header ui-corner-all";
1089
+ } else {
1090
+ this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
1091
+ // Handle range switching from true to min/max
1092
+ .css({
1093
+ "left": "",
1094
+ "bottom": ""
1095
+ });
1096
+ }
1097
+
1098
+ this.range.addClass( classes +
1099
+ ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
1100
+ } else {
1101
+ this.range = $([]);
1102
+ }
1103
+ },
1104
+
1105
+ _setupEvents: function() {
1106
+ var elements = this.handles.add( this.range ).filter( "a" );
1107
+ this._off( elements );
1108
+ this._on( elements, this._handleEvents );
1109
+ this._hoverable( elements );
1110
+ this._focusable( elements );
1111
+ },
1112
+
1113
+ _destroy: function() {
1114
+ this.handles.remove();
1115
+ this.range.remove();
1116
+
1117
+ this.element
1118
+ .removeClass( "ui-slider" +
1119
+ " ui-slider-horizontal" +
1120
+ " ui-slider-vertical" +
1121
+ " ui-widget" +
1122
+ " ui-widget-content" +
1123
+ " ui-corner-all" );
1124
+
1125
+ this._mouseDestroy();
1126
+ },
1127
+
1128
+ _mouseCapture: function( event ) {
1129
+ var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
1130
+ that = this,
1131
+ o = this.options;
1132
+
1133
+ if ( o.disabled ) {
1134
+ return false;
1135
+ }
1136
+
1137
+ this.elementSize = {
1138
+ width: this.element.outerWidth(),
1139
+ height: this.element.outerHeight()
1140
+ };
1141
+ this.elementOffset = this.element.offset();
1142
+
1143
+ position = { x: event.pageX, y: event.pageY };
1144
+ normValue = this._normValueFromMouse( position );
1145
+ distance = this._valueMax() - this._valueMin() + 1;
1146
+ this.handles.each(function( i ) {
1147
+ var thisDistance = Math.abs( normValue - that.values(i) );
1148
+ if (( distance > thisDistance ) ||
1149
+ ( distance === thisDistance &&
1150
+ (i === that._lastChangedValue || that.values(i) === o.min ))) {
1151
+ distance = thisDistance;
1152
+ closestHandle = $( this );
1153
+ index = i;
1154
+ }
1155
+ });
1156
+
1157
+ allowed = this._start( event, index );
1158
+ if ( allowed === false ) {
1159
+ return false;
1160
+ }
1161
+ this._mouseSliding = true;
1162
+
1163
+ this._handleIndex = index;
1164
+
1165
+ closestHandle
1166
+ .addClass( "ui-state-active" )
1167
+ .focus();
1168
+
1169
+ offset = closestHandle.offset();
1170
+ mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
1171
+ this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
1172
+ left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
1173
+ top: event.pageY - offset.top -
1174
+ ( closestHandle.height() / 2 ) -
1175
+ ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
1176
+ ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
1177
+ ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
1178
+ };
1179
+
1180
+ if ( !this.handles.hasClass( "ui-state-hover" ) ) {
1181
+ this._slide( event, index, normValue );
1182
+ }
1183
+ this._animateOff = true;
1184
+ return true;
1185
+ },
1186
+
1187
+ _mouseStart: function() {
1188
+ return true;
1189
+ },
1190
+
1191
+ _mouseDrag: function( event ) {
1192
+ var position = { x: event.pageX, y: event.pageY },
1193
+ normValue = this._normValueFromMouse( position );
1194
+
1195
+ this._slide( event, this._handleIndex, normValue );
1196
+
1197
+ return false;
1198
+ },
1199
+
1200
+ _mouseStop: function( event ) {
1201
+ this.handles.removeClass( "ui-state-active" );
1202
+ this._mouseSliding = false;
1203
+
1204
+ this._stop( event, this._handleIndex );
1205
+ this._change( event, this._handleIndex );
1206
+
1207
+ this._handleIndex = null;
1208
+ this._clickOffset = null;
1209
+ this._animateOff = false;
1210
+
1211
+ return false;
1212
+ },
1213
+
1214
+ _detectOrientation: function() {
1215
+ this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
1216
+ },
1217
+
1218
+ _normValueFromMouse: function( position ) {
1219
+ var pixelTotal,
1220
+ pixelMouse,
1221
+ percentMouse,
1222
+ valueTotal,
1223
+ valueMouse;
1224
+
1225
+ if ( this.orientation === "horizontal" ) {
1226
+ pixelTotal = this.elementSize.width;
1227
+ pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
1228
+ } else {
1229
+ pixelTotal = this.elementSize.height;
1230
+ pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
1231
+ }
1232
+
1233
+ percentMouse = ( pixelMouse / pixelTotal );
1234
+ if ( percentMouse > 1 ) {
1235
+ percentMouse = 1;
1236
+ }
1237
+ if ( percentMouse < 0 ) {
1238
+ percentMouse = 0;
1239
+ }
1240
+ if ( this.orientation === "vertical" ) {
1241
+ percentMouse = 1 - percentMouse;
1242
+ }
1243
+
1244
+ valueTotal = this._valueMax() - this._valueMin();
1245
+ valueMouse = this._valueMin() + percentMouse * valueTotal;
1246
+
1247
+ return this._trimAlignValue( valueMouse );
1248
+ },
1249
+
1250
+ _start: function( event, index ) {
1251
+ var uiHash = {
1252
+ handle: this.handles[ index ],
1253
+ value: this.value()
1254
+ };
1255
+ if ( this.options.values && this.options.values.length ) {
1256
+ uiHash.value = this.values( index );
1257
+ uiHash.values = this.values();
1258
+ }
1259
+ return this._trigger( "start", event, uiHash );
1260
+ },
1261
+
1262
+ _slide: function( event, index, newVal ) {
1263
+ var otherVal,
1264
+ newValues,
1265
+ allowed;
1266
+
1267
+ if ( this.options.values && this.options.values.length ) {
1268
+ otherVal = this.values( index ? 0 : 1 );
1269
+
1270
+ if ( ( this.options.values.length === 2 && this.options.range === true ) &&
1271
+ ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
1272
+ ) {
1273
+ newVal = otherVal;
1274
+ }
1275
+
1276
+ if ( newVal !== this.values( index ) ) {
1277
+ newValues = this.values();
1278
+ newValues[ index ] = newVal;
1279
+ // A slide can be canceled by returning false from the slide callback
1280
+ allowed = this._trigger( "slide", event, {
1281
+ handle: this.handles[ index ],
1282
+ value: newVal,
1283
+ values: newValues
1284
+ } );
1285
+ otherVal = this.values( index ? 0 : 1 );
1286
+ if ( allowed !== false ) {
1287
+ this.values( index, newVal, true );
1288
+ }
1289
+ }
1290
+ } else {
1291
+ if ( newVal !== this.value() ) {
1292
+ // A slide can be canceled by returning false from the slide callback
1293
+ allowed = this._trigger( "slide", event, {
1294
+ handle: this.handles[ index ],
1295
+ value: newVal
1296
+ } );
1297
+ if ( allowed !== false ) {
1298
+ this.value( newVal );
1299
+ }
1300
+ }
1301
+ }
1302
+ },
1303
+
1304
+ _stop: function( event, index ) {
1305
+ var uiHash = {
1306
+ handle: this.handles[ index ],
1307
+ value: this.value()
1308
+ };
1309
+ if ( this.options.values && this.options.values.length ) {
1310
+ uiHash.value = this.values( index );
1311
+ uiHash.values = this.values();
1312
+ }
1313
+
1314
+ this._trigger( "stop", event, uiHash );
1315
+ },
1316
+
1317
+ _change: function( event, index ) {
1318
+ if ( !this._keySliding && !this._mouseSliding ) {
1319
+ var uiHash = {
1320
+ handle: this.handles[ index ],
1321
+ value: this.value()
1322
+ };
1323
+ if ( this.options.values && this.options.values.length ) {
1324
+ uiHash.value = this.values( index );
1325
+ uiHash.values = this.values();
1326
+ }
1327
+
1328
+ //store the last changed value index for reference when handles overlap
1329
+ this._lastChangedValue = index;
1330
+
1331
+ this._trigger( "change", event, uiHash );
1332
+ }
1333
+ },
1334
+
1335
+ value: function( newValue ) {
1336
+ if ( arguments.length ) {
1337
+ this.options.value = this._trimAlignValue( newValue );
1338
+ this._refreshValue();
1339
+ this._change( null, 0 );
1340
+ return;
1341
+ }
1342
+
1343
+ return this._value();
1344
+ },
1345
+
1346
+ values: function( index, newValue ) {
1347
+ var vals,
1348
+ newValues,
1349
+ i;
1350
+
1351
+ if ( arguments.length > 1 ) {
1352
+ this.options.values[ index ] = this._trimAlignValue( newValue );
1353
+ this._refreshValue();
1354
+ this._change( null, index );
1355
+ return;
1356
+ }
1357
+
1358
+ if ( arguments.length ) {
1359
+ if ( $.isArray( arguments[ 0 ] ) ) {
1360
+ vals = this.options.values;
1361
+ newValues = arguments[ 0 ];
1362
+ for ( i = 0; i < vals.length; i += 1 ) {
1363
+ vals[ i ] = this._trimAlignValue( newValues[ i ] );
1364
+ this._change( null, i );
1365
+ }
1366
+ this._refreshValue();
1367
+ } else {
1368
+ if ( this.options.values && this.options.values.length ) {
1369
+ return this._values( index );
1370
+ } else {
1371
+ return this.value();
1372
+ }
1373
+ }
1374
+ } else {
1375
+ return this._values();
1376
+ }
1377
+ },
1378
+
1379
+ _setOption: function( key, value ) {
1380
+ var i,
1381
+ valsLength = 0;
1382
+
1383
+ if ( key === "range" && this.options.range === true ) {
1384
+ if ( value === "min" ) {
1385
+ this.options.value = this._values( 0 );
1386
+ this.options.values = null;
1387
+ } else if ( value === "max" ) {
1388
+ this.options.value = this._values( this.options.values.length-1 );
1389
+ this.options.values = null;
1390
+ }
1391
+ }
1392
+
1393
+ if ( $.isArray( this.options.values ) ) {
1394
+ valsLength = this.options.values.length;
1395
+ }
1396
+
1397
+ $.Widget.prototype._setOption.apply( this, arguments );
1398
+
1399
+ switch ( key ) {
1400
+ case "orientation":
1401
+ this._detectOrientation();
1402
+ this.element
1403
+ .removeClass( "ui-slider-horizontal ui-slider-vertical" )
1404
+ .addClass( "ui-slider-" + this.orientation );
1405
+ this._refreshValue();
1406
+ break;
1407
+ case "value":
1408
+ this._animateOff = true;
1409
+ this._refreshValue();
1410
+ this._change( null, 0 );
1411
+ this._animateOff = false;
1412
+ break;
1413
+ case "values":
1414
+ this._animateOff = true;
1415
+ this._refreshValue();
1416
+ for ( i = 0; i < valsLength; i += 1 ) {
1417
+ this._change( null, i );
1418
+ }
1419
+ this._animateOff = false;
1420
+ break;
1421
+ case "min":
1422
+ case "max":
1423
+ this._animateOff = true;
1424
+ this._refreshValue();
1425
+ this._animateOff = false;
1426
+ break;
1427
+ case "range":
1428
+ this._animateOff = true;
1429
+ this._refresh();
1430
+ this._animateOff = false;
1431
+ break;
1432
+ }
1433
+ },
1434
+
1435
+ //internal value getter
1436
+ // _value() returns value trimmed by min and max, aligned by step
1437
+ _value: function() {
1438
+ var val = this.options.value;
1439
+ val = this._trimAlignValue( val );
1440
+
1441
+ return val;
1442
+ },
1443
+
1444
+ //internal values getter
1445
+ // _values() returns array of values trimmed by min and max, aligned by step
1446
+ // _values( index ) returns single value trimmed by min and max, aligned by step
1447
+ _values: function( index ) {
1448
+ var val,
1449
+ vals,
1450
+ i;
1451
+
1452
+ if ( arguments.length ) {
1453
+ val = this.options.values[ index ];
1454
+ val = this._trimAlignValue( val );
1455
+
1456
+ return val;
1457
+ } else if ( this.options.values && this.options.values.length ) {
1458
+ // .slice() creates a copy of the array
1459
+ // this copy gets trimmed by min and max and then returned
1460
+ vals = this.options.values.slice();
1461
+ for ( i = 0; i < vals.length; i+= 1) {
1462
+ vals[ i ] = this._trimAlignValue( vals[ i ] );
1463
+ }
1464
+
1465
+ return vals;
1466
+ } else {
1467
+ return [];
1468
+ }
1469
+ },
1470
+
1471
+ // returns the step-aligned value that val is closest to, between (inclusive) min and max
1472
+ _trimAlignValue: function( val ) {
1473
+ if ( val <= this._valueMin() ) {
1474
+ return this._valueMin();
1475
+ }
1476
+ if ( val >= this._valueMax() ) {
1477
+ return this._valueMax();
1478
+ }
1479
+ var step = ( this.options.step > 0 ) ? this.options.step : 1,
1480
+ valModStep = (val - this._valueMin()) % step,
1481
+ alignValue = val - valModStep;
1482
+
1483
+ if ( Math.abs(valModStep) * 2 >= step ) {
1484
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
1485
+ }
1486
+
1487
+ // Since JavaScript has problems with large floats, round
1488
+ // the final value to 5 digits after the decimal point (see #4124)
1489
+ return parseFloat( alignValue.toFixed(5) );
1490
+ },
1491
+
1492
+ _valueMin: function() {
1493
+ return this.options.min;
1494
+ },
1495
+
1496
+ _valueMax: function() {
1497
+ return this.options.max;
1498
+ },
1499
+
1500
+ _refreshValue: function() {
1501
+ var lastValPercent, valPercent, value, valueMin, valueMax,
1502
+ oRange = this.options.range,
1503
+ o = this.options,
1504
+ that = this,
1505
+ animate = ( !this._animateOff ) ? o.animate : false,
1506
+ _set = {};
1507
+
1508
+ if ( this.options.values && this.options.values.length ) {
1509
+ this.handles.each(function( i ) {
1510
+ valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
1511
+ _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
1512
+ $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
1513
+ if ( that.options.range === true ) {
1514
+ if ( that.orientation === "horizontal" ) {
1515
+ if ( i === 0 ) {
1516
+ that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
1517
+ }
1518
+ if ( i === 1 ) {
1519
+ that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
1520
+ }
1521
+ } else {
1522
+ if ( i === 0 ) {
1523
+ that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
1524
+ }
1525
+ if ( i === 1 ) {
1526
+ that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
1527
+ }
1528
+ }
1529
+ }
1530
+ lastValPercent = valPercent;
1531
+ });
1532
+ } else {
1533
+ value = this.value();
1534
+ valueMin = this._valueMin();
1535
+ valueMax = this._valueMax();
1536
+ valPercent = ( valueMax !== valueMin ) ?
1537
+ ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
1538
+ 0;
1539
+ _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
1540
+ this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
1541
+
1542
+ if ( oRange === "min" && this.orientation === "horizontal" ) {
1543
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
1544
+ }
1545
+ if ( oRange === "max" && this.orientation === "horizontal" ) {
1546
+ this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
1547
+ }
1548
+ if ( oRange === "min" && this.orientation === "vertical" ) {
1549
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
1550
+ }
1551
+ if ( oRange === "max" && this.orientation === "vertical" ) {
1552
+ this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
1553
+ }
1554
+ }
1555
+ },
1556
+
1557
+ _handleEvents: {
1558
+ keydown: function( event ) {
1559
+ /*jshint maxcomplexity:25*/
1560
+ var allowed, curVal, newVal, step,
1561
+ index = $( event.target ).data( "ui-slider-handle-index" );
1562
+
1563
+ switch ( event.keyCode ) {
1564
+ case $.ui.keyCode.HOME:
1565
+ case $.ui.keyCode.END:
1566
+ case $.ui.keyCode.PAGE_UP:
1567
+ case $.ui.keyCode.PAGE_DOWN:
1568
+ case $.ui.keyCode.UP:
1569
+ case $.ui.keyCode.RIGHT:
1570
+ case $.ui.keyCode.DOWN:
1571
+ case $.ui.keyCode.LEFT:
1572
+ event.preventDefault();
1573
+ if ( !this._keySliding ) {
1574
+ this._keySliding = true;
1575
+ $( event.target ).addClass( "ui-state-active" );
1576
+ allowed = this._start( event, index );
1577
+ if ( allowed === false ) {
1578
+ return;
1579
+ }
1580
+ }
1581
+ break;
1582
+ }
1583
+
1584
+ step = this.options.step;
1585
+ if ( this.options.values && this.options.values.length ) {
1586
+ curVal = newVal = this.values( index );
1587
+ } else {
1588
+ curVal = newVal = this.value();
1589
+ }
1590
+
1591
+ switch ( event.keyCode ) {
1592
+ case $.ui.keyCode.HOME:
1593
+ newVal = this._valueMin();
1594
+ break;
1595
+ case $.ui.keyCode.END:
1596
+ newVal = this._valueMax();
1597
+ break;
1598
+ case $.ui.keyCode.PAGE_UP:
1599
+ newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
1600
+ break;
1601
+ case $.ui.keyCode.PAGE_DOWN:
1602
+ newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
1603
+ break;
1604
+ case $.ui.keyCode.UP:
1605
+ case $.ui.keyCode.RIGHT:
1606
+ if ( curVal === this._valueMax() ) {
1607
+ return;
1608
+ }
1609
+ newVal = this._trimAlignValue( curVal + step );
1610
+ break;
1611
+ case $.ui.keyCode.DOWN:
1612
+ case $.ui.keyCode.LEFT:
1613
+ if ( curVal === this._valueMin() ) {
1614
+ return;
1615
+ }
1616
+ newVal = this._trimAlignValue( curVal - step );
1617
+ break;
1618
+ }
1619
+
1620
+ this._slide( event, index, newVal );
1621
+ },
1622
+ click: function( event ) {
1623
+ event.preventDefault();
1624
+ },
1625
+ keyup: function( event ) {
1626
+ var index = $( event.target ).data( "ui-slider-handle-index" );
1627
+
1628
+ if ( this._keySliding ) {
1629
+ this._keySliding = false;
1630
+ this._stop( event, index );
1631
+ this._change( event, index );
1632
+ $( event.target ).removeClass( "ui-state-active" );
1633
+ }
1634
+ }
1635
+ }
1636
+
1637
+ });
1638
+
1639
+ }(jQuery));