1(function(UI) { 2 3 "use strict"; 4 5 var active = false, activeCount = 0, $html = UI.$html, body; 6 7 UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){ 8 UI.$('.uk-modal.uk-open').each(function(){ 9 return UI.$(this).data('modal') && UI.$(this).data('modal').resize(); 10 }); 11 }, 150)); 12 13 UI.component('modal', { 14 15 defaults: { 16 keyboard: true, 17 bgclose: true, 18 minScrollHeight: 150, 19 center: false, 20 modal: true 21 }, 22 23 scrollable: false, 24 transition: false, 25 hasTransitioned: true, 26 27 init: function() { 28 29 if (!body) body = UI.$('body'); 30 31 if (!this.element.length) return; 32 33 var $this = this; 34 35 this.paddingdir = 'padding-' + (UI.langdirection == 'left' ? 'right':'left'); 36 this.dialog = this.find('.uk-modal-dialog'); 37 38 this.active = false; 39 40 // Update ARIA 41 this.element.attr('aria-hidden', this.element.hasClass('uk-open')); 42 43 this.on('click', '.uk-modal-close', function(e) { 44 45 e.preventDefault(); 46 47 var modal = UI.$(e.target).closest('.uk-modal'); 48 if (modal[0] === $this.element[0]) $this.hide(); 49 50 }).on('click', function(e) { 51 52 var target = UI.$(e.target); 53 54 if (target[0] == $this.element[0] && $this.options.bgclose) { 55 $this.hide(); 56 } 57 }); 58 59 UI.domObserve(this.element, function(e) { $this.resize(); }); 60 }, 61 62 toggle: function() { 63 return this[this.isActive() ? 'hide' : 'show'](); 64 }, 65 66 show: function() { 67 68 if (!this.element.length) return; 69 70 var $this = this; 71 72 if (this.isActive()) return; 73 74 if (this.options.modal && active) { 75 active.hide(true); 76 } 77 78 this.element.removeClass('uk-open').show(); 79 this.resize(true); 80 81 if (this.options.modal) { 82 active = this; 83 } 84 85 this.active = true; 86 87 activeCount++; 88 89 if (UI.support.transition) { 90 this.hasTransitioned = false; 91 this.element.one(UI.support.transition.end, function(){ 92 $this.hasTransitioned = true; 93 UI.Utils.focus($this.dialog, 'a[href]'); 94 }).addClass('uk-open'); 95 } else { 96 this.element.addClass('uk-open'); 97 UI.Utils.focus(this.dialog, 'a[href]'); 98 } 99 100 $html.addClass('uk-modal-page').height(); // force browser engine redraw 101 102 // Update ARIA 103 this.element.attr('aria-hidden', 'false'); 104 105 this.element.trigger('show.uk.modal'); 106 107 UI.Utils.checkDisplay(this.dialog, true); 108 109 return this; 110 }, 111 112 hide: function(force) { 113 114 if (!force && UI.support.transition && this.hasTransitioned) { 115 116 var $this = this; 117 118 this.one(UI.support.transition.end, function() { 119 $this._hide(); 120 }).removeClass('uk-open'); 121 122 } else { 123 124 this._hide(); 125 } 126 127 return this; 128 }, 129 130 resize: function(force) { 131 132 if (!this.isActive() && !force) return; 133 134 var bodywidth = body.width(); 135 136 this.scrollbarwidth = window.innerWidth - bodywidth; 137 138 body.css(this.paddingdir, this.scrollbarwidth); 139 140 this.element.css('overflow-y', this.scrollbarwidth ? 'scroll' : 'auto'); 141 142 if (!this.updateScrollable() && this.options.center) { 143 144 var dh = this.dialog.outerHeight(), 145 pad = parseInt(this.dialog.css('margin-top'), 10) + parseInt(this.dialog.css('margin-bottom'), 10); 146 147 if ((dh + pad) < window.innerHeight) { 148 this.dialog.css({top: (window.innerHeight/2 - dh/2) - pad }); 149 } else { 150 this.dialog.css({top: ''}); 151 } 152 } 153 }, 154 155 updateScrollable: function() { 156 157 // has scrollable? 158 var scrollable = this.dialog.find('.uk-overflow-container:visible:first'); 159 160 if (scrollable.length) { 161 162 scrollable.css('height', 0); 163 164 var offset = Math.abs(parseInt(this.dialog.css('margin-top'), 10)), 165 dh = this.dialog.outerHeight(), 166 wh = window.innerHeight, 167 h = wh - 2*(offset < 20 ? 20:offset) - dh; 168 169 scrollable.css({ 170 maxHeight: (h < this.options.minScrollHeight ? '':h), 171 height:'' 172 }); 173 174 return true; 175 } 176 177 return false; 178 }, 179 180 _hide: function() { 181 182 this.active = false; 183 if (activeCount > 0) activeCount--; 184 else activeCount = 0; 185 186 this.element.hide().removeClass('uk-open'); 187 188 // Update ARIA 189 this.element.attr('aria-hidden', 'true'); 190 191 if (!activeCount) { 192 $html.removeClass('uk-modal-page'); 193 body.css(this.paddingdir, ""); 194 } 195 196 if (active===this) active = false; 197 198 this.trigger('hide.uk.modal'); 199 }, 200 201 isActive: function() { 202 return this.element.hasClass('uk-open'); 203 } 204 205 });
206 207 UI.component('modalTrigger', { 208 209 boot: function() { 210 211 // init code 212 UI.$html.on('click.modal.uikit', '[data-uk-modal]', function(e) { 213 214 var ele = UI.$(this); 215 216 if (ele.is('a')) { 217 e.preventDefault(); 218 } 219 220 if (!ele.data('modalTrigger')) { 221 var modal = UI.modalTrigger(ele, UI.Utils.options(ele.attr('data-uk-modal'))); 222 modal.show(); 223 } 224 225 }); 226 227 // close modal on esc button 228 UI.$html.on('keydown.modal.uikit', function (e) { 229 230 if (active && e.keyCode === 27 && active.options.keyboard) { // ESC 231 e.preventDefault(); 232 active.hide(); 233 } 234 }); 235 }, 236 237 init: function() { 238 239 var $this = this; 240 241 this.options = UI.$.extend({ 242 target: $this.element.is('a') ? $this.element.attr('href') : false 243 }, this.options); 244 245 this.modal = UI.modal(this.options.target, this.options); 246 247 this.on("click", function(e) { 248 e.preventDefault(); 249 $this.show(); 250 }); 251 252 //methods 253 this.proxy(this.modal, 'show hide isActive'); 254 } 255 }); 256 257 UI.modal.dialog = function(content, options) { 258 259 var modal = UI.modal(UI.$(UI.modal.dialog.template).appendTo('body'), options); 260 261 modal.on('hide.uk.modal', function(){ 262 if (modal.persist) { 263 modal.persist.appendTo(modal.persist.data('modalPersistParent')); 264 modal.persist = false; 265 } 266 modal.element.remove(); 267 }); 268 269 setContent(content, modal); 270 271 return modal; 272 }; 273 274 UI.modal.dialog.template = '<div class="uk-modal"><div class="uk-modal-dialog" style="min-height:0;"></div></div>'; 275 276 UI.modal.alert = function(content, options) { 277 278 options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options); 279 280 var modal = UI.modal.dialog(([ 281 '<div class="uk-margin uk-modal-content">'+String(content)+'</div>', 282 '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-button-primary uk-modal-close">'+options.labels.Ok+'</button></div>' 283 ]).join(""), options); 284 285 modal.on('show.uk.modal', function(){ 286 setTimeout(function(){ 287 modal.element.find('button:first').focus(); 288 }, 50); 289 }); 290 291 return modal.show(); 292 }; 293 294 UI.modal.confirm = function(content, onconfirm, oncancel) { 295 296 var options = arguments.length > 1 && arguments[arguments.length-1] ? arguments[arguments.length-1] : {}; 297 298 onconfirm = UI.$.isFunction(onconfirm) ? onconfirm : function(){}; 299 oncancel = UI.$.isFunction(oncancel) ? oncancel : function(){}; 300 options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, UI.$.isFunction(options) ? {}:options); 301 302 var modal = UI.modal.dialog(([ 303 '<div class="uk-margin uk-modal-content">'+String(content)+'</div>', 304 '<div class="uk-modal-footer uk-text-right">
304<button class="uk-button js-modal-confirm-cancel">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-confirm">'+options.labels.Ok+'</button></div>' 305 ]).join(""), options); 306 307 modal.element.find(".js-modal-confirm, .js-modal-confirm-cancel").on("click", function(){ 308 UI.$(this).is('.js-modal-confirm') ? onconfirm() : oncancel(); 309 modal.hide(); 310 }); 311 312 modal.on('show.uk.modal', function(){ 313 setTimeout(function(){ 314 modal.element.find('.js-modal-confirm').focus(); 315 }, 50); 316 }); 317 318 return modal.show(); 319 }; 320 321 UI.modal.prompt = function(text, value, onsubmit, options) { 322 323 onsubmit = UI.$.isFunction(onsubmit) ? onsubmit : function(value){}; 324 options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options); 325 326 var modal = UI.modal.dialog(([ 327 text ? '<div class="uk-modal-content uk-form">'+String(text)+'</div>':'', 328 '<div class="uk-margin-small-top uk-modal-content uk-form"><p><input type="text" class="uk-width-1-1"></p></div>', 329 '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-modal-close">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-ok">'+options.labels.Ok+'</button></div>' 330 ]).join(""), options), 331 332 input = modal.element.find("input[type='text']").val(value || '').on('keyup', function(e){ 333 if (e.keyCode == 13) { 334 modal.element.find('.js-modal-ok').trigger('click'); 335 } 336 }); 337 338 modal.element.find('.js-modal-ok').on('click', function(){ 339 if (onsubmit(input.val())!==false){ 340 modal.hide(); 341 } 342 }); 343 344 return modal.show(); 345 }; 346 347 UI.modal.blockUI = function(content, options) { 348 349 var modal = UI.modal.dialog(([ 350 '<div class="uk-margin uk-modal-content">'+String(content || '<div class="uk-text-center">...</div>')+'</div>' 351 ]).join(""), UI.$.extend({bgclose:false, keyboard:false, modal:false}, options)); 352 353 modal.content = modal.element.find('.uk-modal-content:first'); 354 355 return modal.show(); 356 }; 357 358 UI.modal.labels = { 359 Ok: 'Ok', 360 Cancel: 'Cancel' 361 }; 362 363 // helper functions 364 function setContent(content, modal){ 365 366 if(!modal) return; 367 368 if (typeof content === 'object') { 369 370 // convert DOM object to a jQuery object 371 content = content instanceof jQuery ? content : UI.$(content); 372 373 if(content.parent().length) { 374 modal.persist = content; 375 modal.persist.data('modalPersistParent', content.parent()); 376 } 377 }else if (typeof content === 'string' || typeof content === 'number') { 378 // just insert the data as innerHTML 379 content = UI.$('<div></div>').html(content); 380 }else { 381 // unsupported data type! 382 content = UI.$('<div></div>').html('UIkit2.modal Error: Unsupported data type: ' + typeof content); 383 } 384 385 content.appendTo(modal.element.find('.uk-modal-dialog'));
386 387 return modal; 388 } 389 390})(UIkit2);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.