1/* 2 * nyroModal v2.0.0 3 * Core 4 * 5 * Commit a771d6237dc7c3a278f6 (05/07/2011) * 6 * 7 * Included parts: 8 * - anims.fade 9 * - filters.title 10 * - filters.gallery 11 * - filters.link 12 * - filters.dom 13 * - filters.data 14 * - filters.formFile 15 */ 16/* 17 * nyroModal v2.0.0 18 * Core 19 * 20 */ 21jQuery(function($, undefined) { 22 23 var $w = $(window), 24 $d = $(document), 25 $b = $('body'), 26 baseHref = $('base').attr('href'), 27 // nyroModal Object 28 _nmObj = { 29 filters: [], // List of filters used 30 callbacks: {}, // Sepcific callbacks 31 loadFilter: undefined, // Name of the filter used for loading 32 33 modal: false, // Indicates if it's a modal window or not 34 closeOnEscape: true, // Indicates if the modal should close on Escape key 35 closeOnClick: true, // Indicates if a click on the background should close the modal 36 useKeyHandler: false, // Indicates if the modal has to handle key down event 37 38 showCloseButton: true, // Indicates if the closeButonn should be added 39 closeButton: '<a href="#" class="nyroModalClose nyroModalCloseButton nmReposition" title="close">Close</a>', // Close button HTML 40 41 stack: false, // Indicates if links automatically binded inside the modal should stack or not 42 nonStackable: 'form', // Filter to not stack DOM element 43 44 header: undefined, // header include in every modal 45 footer: undefined, // footer include in every modal 46 47 // Specific confirguation for gallery filter 48 galleryLoop: true, // Indicates if the gallery should loop 49 galleryCounts: true, // Indicates if the gallery counts should be shown 50 ltr: true, // Left to Right by default. Put to false for Hebrew or Right to Left language. Used in gallery filter 51 52 // Specific confirguation for image filter 53 imageRegex: '[^\.]\.(jpg|jpeg|png|tiff|gif|bmp)\s*$', // Regex used to detect image link 54 55 selIndicator: 'nyroModalSel', // Value added when a form or Ajax is sent with a filter content 56 57 swfObjectId: undefined, // Object id for swf object 58 swf: { // Default SWF attributes 59 allowFullScreen: 'true', 60 allowscriptaccess: 'always', 61 wmode: 'transparent' 62 }, 63 64 store: {}, // Storage object for filters. 65 errorMsg: 'An error occured', // Error message 66 elts: { // HTML elements for the modal 67 all: undefined, 68 bg: undefined, 69 load: undefined, 70 cont: undefined, 71 hidden: undefined 72 }, 73 sizes: { // Size information 74 initW: undefined, // Initial width 75 initH: undefined, // Initial height 76 w: undefined, // width 77 h: undefined, // height 78 minW: undefined, // minimum Width 79 minH: undefined, // minimum height 80 wMargin: undefined, // Horizontal margin 81 hMargin: undefined // Vertical margin 82 }, 83 anim: { // Animation names to use 84 def: undefined, // Default animation set to use if sspecific are not defined or doesn't exist 85 showBg: undefined, // Set to use for showBg animation 86 hideBg: undefined, // Set to use for hideBg animation 87 showLoad: undefined, // Set to use for showLoad animation 88 hideLoad: undefined, // Set to use for hideLoad animation 89 showCont: undefined, // Set to use for showCont animation 90 hideCont: undefined, // Set to use for hideCont animation 91 showTrans: undefined, // Set to use for showTrans animation 92 hideTrans: undefined, // Set to use for hideTrans animation 93 resize: undefined // Set to use for resize animation 94 }, 95 96 _open: false, // Indicates if the modal is open 97 _bgReady: false, // Indicates if the background is ready 98 _opened: false, // Indicates if the modal was opened (useful for stacking) 99 _loading: false, // Indicates if the loading is shown 100 _animated: false, // Indicates if the modal is currently animated 101 _transition: false, //Indicates if the modal is in transition 102 _nmOpener: undefined, // nmObj of the modal that opened the current one in non stacking mode 103 _nbContentLoading: 0, // Counter for contentLoading call 104 _scripts: '', // Scripts tags to be included 105 _scriptsShown: '', //Scripts tags to be included once the modal is swhon 106 107 // save the object in data 108 saveObj: function() { 109 this.opener.data('nmObj', this); 110 }, 111 // Open the modal 112 open: function() { 113 if (this._nmOpener) 114 this._nmOpener._close(); 115 this.getInternal()._pushStack(this.opener); 116 this._opened = false;
117 this._bgReady = false; 118 this._open = true; 119 this._initElts(); 120 this._load(); 121 this._nbContentLoading = 0; 122 this._callAnim('showBg', $.proxy(function() { 123 this._bgReady = true; 124 if (this._nmOpener) { 125 // fake closing of the opener nyroModal 126 this._nmOpener._bgReady = false; 127 this._nmOpener._loading = false; 128 this._nmOpener._animated = false; 129 this._nmOpener._opened = false; 130 this._nmOpener._open = false; 131 this._nmOpener.elts.cont = this._nmOpener.elts.hidden = this._nmOpener.elts.load = this._nmOpener.elts.bg = this._nmOpener.elts.all = undefined; 132 this._nmOpener.saveObj(); 133 this._nmOpener = undefined; 134 } 135 this._contentLoading(); 136 }, this)); 137 }, 138 139 // Resize the modal according to sizes.initW and sizes.initH 140 // Will call size function 141 // @param recalc boolean: Indicate if the size should be recalaculated (useful when content has changed) 142 resize: function(recalc) { 143 if (recalc) { 144 this.elts.hidden.append(this.elts.cont.children().first().clone()); 145 this.sizes.initW = this.sizes.w = this.elts.hidden.width(); 146 this.sizes.initH = this.sizes.h = this.elts.hidden.height(); 147 this.elts.hidden.empty(); 148 } else { 149 this.sizes.w = this.sizes.initW; 150 this.sizes.h = this.sizes.initH; 151 } 152 this._unreposition(); 153 this.size(); 154 this._callAnim('resize', $.proxy(function() { 155 this._reposition(); 156 }, this)); 157 }, 158 159 // Update sizes element to not go outsize the viewport. 160 // Will call 'size' callback filter 161 size: function() { 162 var maxHeight = this.getInternal().fullSize.viewH - this.sizes.hMargin, 163 maxWidth = this.getInternal().fullSize.viewW - this.sizes.wMargin; 164 if (this.sizes.minW && this.sizes.minW > this.sizes.w) 165 this.sizes.w = this.sizes.minW; 166 if (this.sizes.minH && this.sizes.minH > this.sizes.h) 167 this.sizes.h = this.sizes.minH; 168 if (this.sizes.h > maxHeight || this.sizes.w > maxWidth) { 169 // We're gonna resize the modal as it will goes outside the view port 170 this.sizes.h = Math.min(this.sizes.h, maxHeight); 171 this.sizes.w = Math.min(this.sizes.w, maxWidth); 172 } 173 this._callFilters('size'); 174 }, 175 176 // Get the nmObject for a new nyroModal 177 getForNewLinks: function(elt) { 178 var ret; 179 if (this.stack && (!elt || this.isStackable(elt))) { 180 ret = $.extend(true, {}, this); 181 ret._nmOpener = undefined; 182 ret.elts.all = undefined; 183 } else { 184 ret = $.extend({}, this); 185 ret._nmOpener = this; 186 } 187 ret.filters = []; 188 ret.opener = undefined; 189 ret._open = false; 190 return ret; 191 }, 192 193 // Indicate if an element can be stackable or not, regarding the nonStackable setting 194 isStackable: function(elt) { 195 return !elt.is(this.nonStackable); 196 }, 197 198 // key handle function. 199 // Will call 'keyHandle' callback filter 200 keyHandle: function(e) { 201 this.keyEvent = e; 202 this._callFilters('keyHandle'); 203 this.keyEvent = undefined; 204 delete(this.keyEvent); 205 }, 206 207 // Get the internal object 208 getInternal: function() { 209 return _internal; 210 }, 211 212 // Internal function for closing a nyroModal 213 // Will call 'close' callback filter 214 _close: function() { 215 this.getInternal()._removeStack(this.opener); 216 this._opened = false; 217 this._open = false; 218 this._callFilters('close'); 219 }, 220 // Public function for closing a nyroModal 221 close: function() { 222 this._close(); 223 this._callFilters('beforeClose'); 224 var self = this; 225 this._unreposition(); 226 self._callAnim('hideCont', function() { 227 self._callAnim('hideLoad', function() { 228 self._callAnim('hideBg', function() { 229 self._callFilters('afterClose'); 230 self.elts.cont.remove(); 231 self.elts.hidden.remove(); 232 self.elts.load.remove(); 233 self.elts.bg.remove(); 234 self.elts.all.remove(); 235 self.elts.cont = self.elts.hidden = self.elts.load = self.elts.bg = self.elts.all = undefined; 236 }); 237 }); 238 }); 239 }, 240 241 // Init HTML elements 242 _initElts: function() { 243 if (!this.stack && this.getInternal().stack.length > 1) 244 this.elts = this.getInternal().stack[this.getInternal().stack.length-2]['nmObj'].elts; 245 if (!this.elts.all || this.elts.all.closest('body').length == 0) 246 this.elts.all = this.elts.bg = this.elts.cont = this.elts.hidden = this.elts.load = undefined; 247 if (!this.elts.all) 248 this.elts.all = $('<div />').appendTo(this.getInternal()._container); 249 if (!this.elts.bg)
250 this.elts.bg = $('<div />').hide().appendTo(this.elts.all); 251 if (!this.elts.cont) 252 this.elts.cont = $('<div />').hide().appendTo(this.elts.all); 253 if (!this.elts.hidden) 254 this.elts.hidden = $('<div />').hide().appendTo(this.elts.all); 255 this.elts.hidden.empty(); 256 if (!this.elts.load) 257 this.elts.load = $('<div />').hide().appendTo(this.elts.all); 258 this._callFilters('initElts'); 259 }, 260 261 // Trigger the error 262 // Will call 'error' callback filter 263 _error: function() { 264 this._callFilters('error'); 265 }, 266 267 // Set the HTML content to show. 268 // - html: HTML content 269 // - selector: selector to filter the content 270 // Will init the size and call the 'size' function. 271 // Will call 'filledContent' callback filter 272 _setCont: function(html, selector) { 273 if (selector) { 274 var tmp = [], 275 i = 0; 276 // Looking for script to store them 277 html = html 278 .replace(/\r\n/gi, 'nyroModalLN') 279 .replace(/<script(.|\s)*?\/script>/gi, function(x) { 280 tmp[i] = x; 281 return '<pre class=nyroModalScript rel="'+(i++)+'"></pre>'; 282 }); 283 var cur = $('<div>'+html+'</div>').find(selector); 284 if (cur.length) { 285 html = cur.html() 286 .replace(/<pre class="?nyroModalScript"? rel="?(.?)"?><\/pre>/gi, function(x, y, z) { return tmp[y]; }) 287 .replace(/nyroModalLN/gi, "\r\n"); 288 } else { 289 // selector not found 290 this._error(); 291 return; 292 } 293 } 294 this.elts.hidden 295 .append(this._filterScripts(html)) 296 .prepend(this.header) 297 .append(this.footer) 298 .wrapInner('<div class="nyroModal'+ucfirst(this.loadFilter)+'" />'); 299 300 // Store the size of the element 301 this.sizes.initW = this.sizes.w = this.elts.hidden.width(); 302 this.sizes.initH = this.sizes.h = this.elts.hidden.height(); 303 var outer = this.getInternal()._getOuter(this.elts.cont); 304 this.sizes.hMargin = outer.h.total; 305 this.sizes.wMargin = outer.w.total; 306 307 this.size(); 308 309 this.loading = false; 310 this._callFilters('filledContent'); 311 this._contentLoading(); 312 }, 313 314 // Filter an html content to remove the script[src] and store them appropriately if needed 315 // - data: Data to filter 316 _filterScripts: function(data) { 317 if (typeof data != 'string') 318 return data; 319 320 this._scripts = []; 321 this._scriptsShown = []; 322 var start = 0, 323 stStart = '<script', 324 stEnd = '</script>', 325 endLn = stEnd.length, 326 pos, 327 pos2, 328 tmp; 329 while ((pos = data.indexOf(stStart, start)) > -1) { 330 pos2 = data.indexOf(stEnd)+endLn; 331 tmp = $(data.substring(pos, pos2)); 332 if (!tmp.attr('src') || tmp.attr('rel') == 'forceLoad') { 333 if (tmp.attr('rev') == 'shown') 334 this._scriptsShown.push(tmp.get(0)); 335 else 336 this._scripts.push(tmp.get(0)); 337 } 338 data = data.substring(0, pos)+data.substr(pos2); 339 start = pos; 340 } 341 return data; 342 }, 343 344 // Check if the nmObject has a specific filter 345 // - filter: Filter name 346 _hasFilter: function(filter) { 347 var ret = false;
348 $.each(this.filters, function(i, f) { 349 ret = ret || f == filter; 350 }); 351 return ret; 352 }, 353 354 // Remove a specific filter 355 // - filter: Filter name 356 _delFilter: function(filter) { 357 this.filters = $.map(this.filters, function(v) { 358 if (v != filter) 359 return v; 360 }); 361 }, 362 363 // Call a function against all active filters 364 // - fct: Function name 365 // return an array of all return of callbacks; keys are filters name 366 _callFilters: function(fct) { 367 this.getInternal()._debug(fct); 368 var ret = [], 369 self = this; 370 $.each(this.filters, function(i, f) { 371 ret[f] = self._callFilter(f, fct); 372 }); 373 if (this.callbacks[fct] && $.isFunction(this.callbacks[fct])) 374 this.callbacks[fct](this); 375 return ret; 376 }, 377 378 // Call a filter function for a specific filter 379 // - f: Filter name 380 // - fct: Function name 381 // return the return of the callback 382 _callFilter: function(f, fct) { 383 if (_filters[f] && _filters[f][fct] && $.isFunction(_filters[f][fct])) 384 return _filters[f][fct](this); 385 return undefined; 386 }, 387 388 // Call animation callback. 389 // Will also call beforeNNN and afterNNN filter callbacks 390 // - fct: Animation function name 391 // - clb: Callback once the animation is done 392 _callAnim: function(fct, clb) { 393 this.getInternal()._debug(fct); 394 this._callFilters('before'+ucfirst(fct)); 395 if (!this._animated) { 396 this._animated = true; 397 if (!$.isFunction(clb)) clb = $.noop; 398 var set = this.anim[fct] || this.anim.def || 'basic'; 399 if (!_animations[set] || !_animations[set][fct] || !$.isFunction(_animations[set][fct])) 400 set = 'basic'; 401 _animations[set][fct](this, $.proxy(function() { 402 this._animated = false; 403 this._callFilters('after'+ucfirst(fct)); 404 clb(); 405 }, this)); 406 } 407 }, 408 409 // Load the content 410 // Will call the 'load' function of the filter specified in the loadFilter parameter 411 _load: function() { 412 this.getInternal()._debug('_load'); 413 if (!this.loading && this.loadFilter) { 414 this.loading = true; 415 this._callFilter(this.loadFilter, 'load'); 416 } 417 }, 418 419 // Show the content or the loading according to the current state of the modal 420 _contentLoading: function() { 421 if (!this._animated && this._bgReady) { 422 if (!this._transition && this.elts.cont.html().length > 0) 423 this._transition = true; 424 this._nbContentLoading++; 425 if (!this.loading) { 426 if (!this._opened) { 427 this._opened = true; 428 if (this._transition) { 429 var fct = $.proxy(function() { 430 this._writeContent(); 431 this._callFilters('beforeShowCont'); 432 this._callAnim('hideTrans', $.proxy(function() { 433 this._transition = false; 434 this._callFilters('afterShowCont'); 435 this.elts.cont.append(this._scriptsShown); 436 this._reposition(); 437 }, this)); 438 }, this); 439 if (this._nbContentLoading == 1) { 440 this._unreposition(); 441 this._callAnim('showTrans', fct); 442 } else { 443 fct(); 444 } 445 } else { 446 this._callAnim('hideLoad', $.proxy(function() { 447 this._writeContent(); 448 this._callAnim('showCont', $.proxy(function() { 449 this.elts.cont.append(this._scriptsShown); 450 this._reposition(); 451 }, this)); 452 }, this)); 453 } 454 } 455 } else if (this._nbContentLoading == 1) { 456 var outer = this.getInternal()._getOuter(this.elts.load); 457 this.elts.load 458 .css({ 459 position: 'fixed', 460 top: (this.getInternal().fullSize.viewH - this.elts.load.height() - outer.h.margin)/2, 461 left: (this.getInternal().fullSize.viewW - this.elts.load.width() - outer.w.margin)/2 462 }); 463 if (this._transition) { 464 this._unreposition(); 465 this._callAnim('showTrans', $.proxy(function() { 466 this._contentLoading(); 467 }, this)); 468 } else { 469 this._callAnim('showLoad', $.proxy(function() { 470 this._contentLoading(); 471 }, this)); 472 } 473 } 474 } 475 }, 476 477 // Write the content in the modal. 478 // Content comes from the hidden div, scripts and eventually close button. 479 _writeContent: function() { 480 this.elts.cont 481 .empty() 482 .append(this.elts.hidden.contents()) 483 .append(this._scripts) 484 .append(this.showCloseButton ? this.closeButton : '') 485 .css({ 486 position: 'fixed', 487 width: this.sizes.w, 488 height: this.sizes.h, 489 top: (this.getInternal().fullSize.viewH - this.sizes.h - this.sizes.hMargin)/2, 490 left: (this.getInternal().fullSize.viewW - this.sizes.w - this.sizes.wMargin)/2
491 }); 492 }, 493 494 // Reposition elements with a class nmReposition 495 _reposition: function() { 496 var elts = this.elts.cont.find('.nmReposition'); 497 if (elts.length) { 498 var space = this.getInternal()._getSpaceReposition(); 499 elts.each(function() { 500 var me = $(this), 501 offset = me.offset(); 502 me.css({ 503 position: 'fixed', 504 top: offset.top - space.top, 505 left: offset.left - space.left 506 }); 507 }); 508 this.elts.cont.after(elts); 509 } 510 this.elts.cont.css('overflow', 'auto'); 511 this._callFilters('afterReposition'); 512 }, 513 514 // Unreposition elements with a class nmReposition 515 // Exaclty the reverse of the _reposition function 516 _unreposition: function() { 517 this.elts.cont.css('overflow', ''); 518 var elts = this.elts.all.find('.nmReposition'); 519 if (elts.length) 520 this.elts.cont.append(elts.removeAttr('style')); 521 this._callFilters('afterUnreposition'); 522 } 523 }, 524 _internal = { 525 firstInit: true, 526 debug: false, 527 stack: [], 528 fullSize: { 529 w: 0, 530 h: 0, 531 wW: 0, 532 wH: 0, 533 viewW: 0, 534 viewH: 0 535 }, 536 nyroModal: function(opts, fullObj) { 537 if (_internal.firstInit) {
538 _internal._container = $('<div />').appendTo($b); 539 $w.smartresize($.proxy(_internal._resize, _internal)); 540 $d.bind('keydown.nyroModal', $.proxy(_internal._keyHandler, _internal)); 541 _internal._calculateFullSize(); 542 _internal.firstInit = false; 543 } 544 return this.nmInit(opts, fullObj).each(function() { 545 _internal._init($(this).data('nmObj')); 546 }); 547 }, 548 nmInit: function(opts, fullObj) { 549 return this.each(function() { 550 var me = $(this); 551 if (fullObj) 552 me.data('nmObj', $.extend(true, {opener: me}, opts)); 553 else 554 me.data('nmObj', 555 me.data('nmObj') 556 ? $.extend(true, me.data('nmObj'), opts) 557 : $.extend(true, {opener: me}, _nmObj, opts)); 558 }); 559 }, 560 nmCall: function() { 561 return this.trigger('nyroModal'); 562 }, 563 564 nmManual: function(url, opts) { 565 $('<a href="'+url+'"></a>').nyroModal(opts).trigger('nyroModal'); 566 }, 567 nmData: function(data, opts) { 568 this.nmManual('#', $.extend({data: data}, opts)); 569 }, 570 nmObj: function(opts) { 571 $.extend(true, _nmObj, opts); 572 }, 573 nmInternal: function(opts) { 574 $.extend(true, _internal, opts); 575 }, 576 nmAnims: function(opts) { 577 $.extend(true, _animations, opts); 578 }, 579 nmFilters: function(opts) { 580 $.extend(true, _filters, opts); 581 }, 582 nmTop: function() { 583 if (_internal.stack.length) 584 return _internal.stack[_internal.stack.length-1]['nmObj']; 585 return undefined; 586 }, 587 588 _debug: function(msg) { 589 if (this.debug && window.console && window.console.log) 590 window.console.log(msg); 591 }, 592 593 _container: undefined, 594 595 _init: function(nm) { 596 nm.filters = []; 597 $.each(_filters, function(f, obj) { 598 if (obj.is && $.isFunction(obj.is) && obj.is(nm)) { 599 nm.filters.push(f); 600 } 601 }); 602 nm._callFilters('initFilters'); 603 nm._callFilters('init'); 604 nm.opener 605 .unbind('nyroModal.nyroModal nmClose.nyroModal nmResize.nyroModal') 606 .bind({ 607 'nyroModal.nyroModal': function(e) { nm.open(); return false;}, 608 'nmClose.nyroModal': function() { nm.close(); return false;}, 609 'nmResize.nyroModal': function() { nm.resize(); return false;} 610 }); 611 }, 612 613 _scrollWidth: (function() { 614 var scrollbarWidth; 615 if ($.browser.msie) { 616 var $textarea1 = $('<textarea cols="10" rows="2"></textarea>') 617 .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo($b), 618 $textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>') 619 .css({ position: 'absolute', top: -1000, left: -1000 }).appendTo($b); 620 scrollbarWidth = $textarea1.width() - $textarea2.width(); 621 $textarea1.add($textarea2).remove(); 622 } else { 623 var $div = $('<div />') 624 .css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 }) 625 .prependTo($b).append('<div />').find('div') 626 .css({ width: '100%', height: 200 }); 627 scrollbarWidth = 100 - $div.width(); 628 $div.parent().remove(); 629 } 630 return scrollbarWidth; 631 })(), 632 633 _selNyroModal: function(obj) { 634 return $(obj).data('nmObj') ? true : false; 635 }, 636 637 _selNyroModalOpen: function(obj) { 638 var me = $(obj); 639 return me.data('nmObj') ? me.data('nmObj')._open : false; 640 }, 641 642 _keyHandler: function(e) { 643 var nmTop = $.nmTop(); 644 if (nmTop && nmTop.useKeyHandler) { 645 return nmTop.keyHandle(e); 646 } 647 }, 648 _pushStack: function(obj) { 649 this.stack = $.map(this.stack, function(elA) { 650 if (elA['nmOpener'] != obj.get(0)) 651 return elA; 652 }); 653 this.stack.push({ 654 nmOpener: obj.get(0), 655 nmObj: $(obj).data('nmObj') 656 }); 657 }, 658 _removeStack: function(obj) { 659 this.stack = $.map(this.stack, function(elA) { 660 if (elA['nmOpener'] != obj.get(0)) 661 return elA; 662 }); 663 }, 664 _resize: function() { 665 var opens = $(':nmOpen').each(function() { 666 $(this).data('nmObj')._unreposition(); 667 }); 668 this._calculateFullSize(); 669 opens.trigger('nmResize'); 670 }, 671 _calculateFullSize: function() { 672 this.fullSize = { 673 w: $d.width(), 674 h: $d.height(), 675 wW: $w.width(), 676 wH: $w.height() 677 }; 678 this.fullSize.viewW = Math.min(this.fullSize.w, this.fullSize.wW); 679 this.fullSize.viewH = Math.min(this.fullSize.h, this.fullSize.wH); 680 }, 681 _getCurCSS: function(elm, name) { 682 var ret = parseInt($.curCSS(elm, name, true)); 683 return isNaN(ret) ? 0 : ret; 684 }, 685 _getOuter: function(elm) { 686 elm = elm.get(0); 687 var ret = { 688 h: { 689 margin: this._getCurCSS(elm, 'marginTop') + this._getCurCSS(elm, 'marginBottom'), 690 border: this._getCurCSS(elm, 'borderTopWidth') + this._getCurCSS(elm, 'borderBottomWidth'), 691 padding: this._getCurCSS(elm, 'paddingTop') + this._getCurCSS(elm, 'paddingBottom') 692 }, 693 w: { 694 margin: this._getCurCSS(elm, 'marginLeft') + this._getCurCSS(elm, 'marginRight'), 695 border: this._getCurCSS(elm, 'borderLeftWidth') + this._getCurCSS(elm, 'borderRightWidth'), 696 padding: this._getCurCSS(elm, 'paddingLeft') + this._getCurCSS(elm, 'paddingRight') 697 } 698 }; 699 700 ret.h.outer = ret.h.margin + ret.h.border; 701 ret.w.outer = ret.w.margin + ret.w.border; 702 703 ret.h.inner = ret.h.padding + ret.h.border; 704 ret.w.inner = ret.w.padding + ret.w.border; 705 706 ret.h.total = ret.h.outer + ret.h.padding; 707 ret.w.total = ret.w.outer + ret.w.padding; 708 709 return ret; 710 }, 711 _getSpaceReposition: function() { 712 var outer = this._getOuter($b), 713 ie7 = $.browser.msie && $.browser.version < 8 && !(screen.height <= $
713w.height()+23); 714 return { 715 top: $w.scrollTop() - (!ie7 ? outer.h.border / 2 : 0), 716 left: $w.scrollLeft() - (!ie7 ? outer.w.border / 2 : 0) 717 }; 718 }, 719 720 _getHash: function(url) { 721 if (typeof url == 'string') { 722 var hashPos = url.indexOf('#'); 723 if (hashPos > -1) 724 return url.substring(hashPos); 725 } 726 return ''; 727 }, 728 _extractUrl: function(url) { 729 var ret = { 730 url: undefined, 731 sel: undefined 732 }; 733 734 if (url) { 735 var hash = this._getHash(url), 736 hashLoc = this._getHash(window.location.href), 737 curLoc = window.location.href.substring(0, window.location.href.length - hashLoc.length), 738 req = url.substring(0, url.length - hash.length); 739 ret.sel = hash; 740 if (req != curLoc && req != baseHref) 741 ret.url = req; 742 } 743 return ret; 744 } 745 }, 746 _animations = { 747 basic: { 748 showBg: function(nm, clb) { 749 nm.elts.bg.css({opacity: 0.7}).show(); 750 clb(); 751 }, 752 hideBg: function(nm, clb) { 753 nm.elts.bg.hide(); 754 clb(); 755 }, 756 showLoad: function(nm, clb) { 757 nm.elts.load.show(); 758 clb(); 759 }, 760 hideLoad: function(nm, clb) { 761 nm.elts.load.hide(); 762 clb(); 763 }, 764 showCont: function(nm, clb) { 765 nm.elts.cont.show(); 766 clb(); 767 }, 768 hideCont: function(nm, clb) { 769 nm.elts.cont.hide(); 770 clb(); 771 }, 772 showTrans: function(nm, clb) { 773 nm.elts.cont.hide(); 774 nm.elts.load.show(); 775 clb(); 776 }, 777 hideTrans: function(nm, clb) { 778 nm.elts.cont.show(); 779 nm.elts.load.hide(); 780 clb(); 781 }, 782 resize: function(nm, clb) { 783 nm.elts.cont.css({ 784 width: nm.sizes.w, 785 height: nm.sizes.h, 786 top: (nm.getInternal().fullSize.viewH - nm.sizes.h - nm.sizes.hMargin)/2, 787 left: (nm.getInternal().fullSize.viewW - nm.sizes.w - nm.sizes.wMargin)/2 788 }); 789 clb(); 790 } 791 } 792 }, 793 _filters = { 794 basic: { 795 is: function(nm) { 796 return true; 797 }, 798 init: function(nm) { 799 if (nm.opener.attr('rev') == 'modal') 800 nm.modal = true; 801 if (nm.modal) 802 nm.closeOnEscape = nm.closeOnClick = nm.showCloseButton = false; 803 if (nm.closeOnEscape) 804 nm.useKeyHandler = true; 805 }, 806 initElts: function(nm) { 807 nm.elts.bg.addClass('nyroModalBg'); 808 if (nm.closeOnClick) 809 nm.elts.bg.unbind('click.nyroModal').bind('click.nyroModal', function(e) { 810 e.preventDefault(); 811 nm.close(); 812 }); 813 nm.elts.cont.addClass('nyroModalCont'); 814 nm.elts.hidden.addClass('nyroModalCont nyroModalHidden'); 815 nm.elts.load.addClass('nyroModalCont nyroModalLoad'); 816 }, 817 error: function(nm) { 818 nm.elts.hidden.addClass('nyroModalError'); 819 nm.elts.cont.addClass('nyroModalError'); 820 nm._setCont(nm.errorMsg); 821 }, 822 beforeShowCont: function(nm) { 823 nm.elts.cont 824 .find('.nyroModal').each(function() { 825 var cur = $(this); 826 cur.nyroModal(nm.getForNewLinks(cur), true); 827 }).end() 828 .find('.nyroModalClose').bind('click.nyroModal', function(e) { 829 e.preventDefault(); 830 nm.close(); 831 }); 832 }, 833 keyHandle: function(nm) { 834 // used for escape key 835 if (nm.keyEvent.keyCode == 27 && nm.closeOnEscape) { 836 nm.keyEvent.preventDefault(); 837 nm.close(); 838 } 839 } 840 }, 841 842 custom: { 843 is: function(nm) { 844 return true; 845 } 846 } 847 }; 848 849 // Add jQuery call fucntions 850 $.fn.extend({ 851 nm: _internal.nyroModal, 852 nyroModal: _internal.nyroModal, 853 nmInit: _internal.nmInit, 854 nmCall: _internal.nmCall 855 }); 856 857 // Add global jQuery functions 858 $.extend({ 859 nmManual: _internal.nmManual, 860 nmData: _internal.nmData, 861 nmObj: _internal.nmObj, 862 nmInternal: _internal.nmInternal, 863 nmAnims: _internal.nmAnims, 864 nmFilters: _internal.nmFilters, 865 nmTop: _internal.nmTop 866 }); 867 868 // Add jQuery selectors 869 $.expr[':'].nyroModal = $.expr[':'].nm = _internal._selNyroModal; 870 $.expr[':'].nmOpen = _internal._selNyroModalOpen; 871}); 872 873// Smartresize plugin 874(function($,sr){ 875 876 // debouncing function from John Hann 877 // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ 878 var debounce = function (func, threshold, execAsap) { 879 var timeout; 880 881 return function debounced () { 882 var obj = this, args = arguments; 883 function delayed () { 884 if (!execAsap) 885 func.apply(obj, args); 886 timeout = null; 887 }; 888 889 if (timeout) 890 clearTimeout(timeout); 891 else if (execAsap) 892 func.apply(obj, args); 893 894 timeout = setTimeout(delayed, threshold || 100); 895 }; 896 }; 897 // smartresize 898 jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); }; 899 900})(jQuery,'smartresize'); 901// ucFirst 902function ucfirst(str) { 903 // http://kevin.vanzonneveld.net 904 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 905 // + bugfixed by: Onno Marsman 906 // + improved by: Brett Zamir (http://brett-zamir.me) 907 // * example 1: ucfirst('kevin van zonneveld'); 908 // * returns 1: 'Kevin van zonneveld' 909 str += ''; 910 var f = str.charAt(0).toUpperCase(); 911 return f + str.substr(1); 912} 913/* 914 * nyroModal v2.0.0 915 * 916 * Fade animations 917 * 918 * Depends: 919 * 920 */ 921jQuery(function($, undefined) { 922 $.nmAnims({ 923 fade: { 924 showBg: function(nm, clb) { 925 nm.elts.bg.fadeTo(250, 0.7, clb); 926 }, 927 hideBg: function(nm, clb) { 928 nm.elts.bg.fadeOut(clb); 929 }, 930 showLoad: function(nm, clb) { 931 nm.elts.load.fadeIn(clb); 932 }, 933 hideLoad: function(nm, clb) { 934 nm.elts.load.fadeOut(clb); 935 }, 936 showCont: function(nm, clb) { 937 nm.elts.cont.fadeIn(clb); 938 }, 939 hideCont: function(nm, clb) { 940 nm.elts.cont.css('overflow', 'hidden').fadeOut(clb); 941 }, 942 showTrans: function(nm, clb) { 943 nm.elts.load 944 .css({ 945 position: nm.elts.cont.css('position'), 946 top: nm.elts.cont.css('top'), 947 left: nm.elts.cont.css('left'), 948 width: nm.elts.cont.css('width'), 949 height: nm.elts.cont.css('height'), 950 marginTop: nm.elts.cont.css('marginTop'), 951 marginLeft: nm.elts.cont.css('marginLeft') 952 }) 953 .fadeIn(function() { 954 nm.elts.cont.hide(); 955 clb(); 956 }); 957 }, 958 hideTrans: function(nm, clb) { 959 nm.elts.cont.css('visibility', 'hidden').show(); 960 nm.elts.load 961 .css('position', nm.elts.cont.css('position')) 962 .animate({ 963 top: nm.elts.cont.css('top'), 964 left: nm.elts.cont.css('left'), 965 width: nm.elts.cont.css('width'), 966 height: nm.elts.cont.css('height'), 967 marginTop: nm.elts.cont.css('marginTop'), 968 marginLeft: nm.elts.cont.css('marginLeft') 969 }, function() { 970 nm.elts.cont.css('visibility', ''); 971 nm.elts.load.fadeOut(clb); 972 }); 973 }, 974 resize: function(nm, clb) { 975 nm.elts.cont.animate({ 976 width: nm.sizes.w, 977 height: nm.sizes.h, 978 top: (nm.getInternal().fullSize.viewH - nm.sizes.h - nm.sizes.hMargin)/2, 979 left: (nm.getInternal().fullSize.viewW - nm.sizes.w - nm.sizes.wMargin)/2
980 }, clb); 981 } 982 } 983 }); 984 // Define fade aniamtions as default 985 $.nmObj({anim: {def: 'fade'}}); 986}); 987/* 988 * nyroModal v2.0.0 989 * 990 * Title filter 991 * 992 * Depends: 993 * 994 * Before: 995 */ 996jQuery(function($, undefined) { 997 $.nmFilters({ 998 title: { 999 is: function(nm) { 1000 return nm.opener.is('[title]'); 1001 }, 1002 beforeShowCont: function(nm) { 1003 var offset = nm.elts.cont.offset(); 1004 nm.store.title = $('<h1 />', { 1005 text: nm.opener.attr('title') 1006 }).addClass('nyroModalTitle nmReposition'); 1007 nm.elts.cont.prepend(nm.store.title); 1008 }, 1009 close: function(nm) { 1010 if (nm.store.title) { 1011 nm.store.title.remove(); 1012 nm.store.title = undefined; 1013 delete(nm.store.title); 1014 } 1015 } 1016 } 1017 }); 1018}); 1019/* 1020 * nyroModal v2.0.0 1021 * 1022 * Gallery filter 1023 * 1024 * Depends: 1025 * - filters.title 1026 * 1027 * Before: filters.title 1028 */ 1029jQuery(function($, undefined) { 1030 $.nmFilters({ 1031 gallery: { 1032 is: function(nm) { 1033 var ret = nm.opener.is('[rel]:not([rel=external], [rel=nofollow])'); 1034 if (ret) { 1035 var rel = nm.opener.attr('rel'), 1036 indexSpace = rel.indexOf(' '), 1037 gal = indexSpace > 0 ? rel.substr(0, indexSpace) : rel, 1038 links = $('[href][rel="'+gal+'"], [href][rel^="'+gal+' "]'); 1039 if (links.length < 2) 1040 ret = false;
1041 if (ret && nm.galleryCounts && !nm._hasFilter('title')) 1042 nm.filters.push('title'); 1043 } 1044 return ret; 1045 }, 1046 init: function(nm) { 1047 nm.useKeyHandler = true; 1048 }, 1049 keyHandle: function(nm) { 1050 // used for arrows key 1051 if (!nm._animated && nm._opened) { 1052 if (nm.keyEvent.keyCode == 39 || nm.keyEvent.keyCode == 40) { 1053 nm.keyEvent.preventDefault(); 1054 nm._callFilters('galleryNext'); 1055 } else if (nm.keyEvent.keyCode == 37 || nm.keyEvent.keyCode == 38) { 1056 nm.keyEvent.preventDefault(); 1057 nm._callFilters('galleryPrev'); 1058 } 1059 } 1060 }, 1061 initElts: function(nm) { 1062 var rel = nm.opener.attr('rel'), 1063 indexSpace = rel.indexOf(' '); 1064 nm.store.gallery = indexSpace > 0 ? rel.substr(0, indexSpace) : rel; 1065 nm.store.galleryLinks = $('[href][rel="'+nm.store.gallery+'"], [href][rel^="'+nm.store.gallery+' "]'); 1066 nm.store.galleryIndex = nm.store.galleryLinks.index(nm.opener); 1067 }, 1068 beforeShowCont: function(nm) { 1069 if (nm.galleryCounts && nm.store.title && nm.store.galleryLinks && nm.store.galleryLinks.length > 1) { 1070 var curTitle = nm.store.title.html(); 1071 nm.store.title.html((curTitle.length ? curTitle+' - ' : '')+(nm.store.galleryIndex+1)+'/'+nm.store.galleryLinks.length); 1072 } 1073 }, 1074 filledContent: function(nm) { 1075 var link = this._getGalleryLink(nm, -1), 1076 append = nm.elts.hidden.find(' > div'); 1077 if (link) { 1078 $('<a />', { 1079 text: 'previous', 1080 href: '#' 1081 }) 1082 .addClass('nyroModalPrev') 1083 .bind('click', function(e) { 1084 e.preventDefault(); 1085 nm._callFilters('galleryPrev'); 1086 }) 1087 .appendTo(append); 1088 } 1089 link = this._getGalleryLink(nm, 1); 1090 if (link) { 1091 $('<a />', { 1092 text: 'next', 1093 href: '#' 1094 }) 1095 .addClass('nyroModalNext') 1096 .bind('click', function(e) { 1097 e.preventDefault(); 1098 nm._callFilters('galleryNext'); 1099 }) 1100 .appendTo(append); 1101 } 1102 }, 1103 close: function(nm) { 1104 nm.store.gallery = undefined; 1105 nm.store.galleryLinks = undefined; 1106 nm.store.galleryIndex = undefined; 1107 delete(nm.store.gallery); 1108 delete(nm.store.galleryLinks); 1109 delete(nm.store.galleryIndex); 1110 if (nm.elts.cont) 1111 nm.elts.cont.find('.nyroModalNext, .nyroModalPrev').remove(); 1112 }, 1113 galleryNext: function(nm) { 1114 this._getGalleryLink(nm, 1).nyroModal(nm.getForNewLinks(), true).click(); 1115 }, 1116 galleryPrev: function(nm) { 1117 this._getGalleryLink(nm, -1).nyroModal(nm.getForNewLinks(), true).click(); 1118 }, 1119 _getGalleryLink: function(nm, dir) { 1120 if (nm.store.gallery) { 1121 if (!nm.ltr) 1122 dir *= -1; 1123 var index = nm.store.galleryIndex + dir; 1124 if (nm.store.galleryLinks && index >= 0 && index < nm.store.galleryLinks.length) 1125 return nm.store.galleryLinks.eq(index); 1126 else if (nm.galleryLoop && nm.store.galleryLinks) 1127 return nm.store.galleryLinks.eq(index<0 ? nm.store.galleryLinks.length-1 : 0); 1128 } 1129 return undefined; 1130 } 1131 } 1132 }); 1133}); 1134/* 1135 * nyroModal v2.0.0 1136 * 1137 * Link filter 1138 * 1139 * Depends: 1140 * 1141 * Before: filters.gallery 1142 */ 1143jQuery(function($, undefined) { 1144 $.nmFilters({ 1145 link: { 1146 is: function(nm) { 1147 var ret = nm.opener.is('[href]'); 1148 if (ret) 1149 nm.store.link = nm.getInternal()._extractUrl(nm.opener.attr('href')); 1150 return ret; 1151 }, 1152 init: function(nm) { 1153 nm.loadFilter = 'link'; 1154 nm.opener.unbind('click.nyroModal').bind('click.nyroModal', function(e) { 1155 e.preventDefault(); 1156 nm.opener.trigger('nyroModal'); 1157 }); 1158 }, 1159 load: function(nm) { 1160 $.ajax({ 1161 url: nm.store.link.url, 1162 data: nm.store.link.sel ? [{name: nm.selIndicator, value: nm.store.link.sel.substring(1)}] : undefined, 1163 success: function(data) { 1164 nm._setCont(data, nm.store.link.sel); 1165 }, 1166 error: function() { 1167 nm._error(); 1168 } 1169 }); 1170 } 1171 } 1172 }); 1173}); 1174/* 1175 * nyroModal v2.0.0 1176 * 1177 * Dom filter 1178 * 1179 * Depends: 1180 * - filters.link 1181 * 1182 * Before: filters.link 1183 */ 1184jQuery(function($, undefined) { 1185 $.nmFilters({ 1186 dom: { 1187 is: function(nm) { 1188 return nm._hasFilter('link') && !nm.store.link.url && nm.store.link.sel; 1189 }, 1190 init: function(nm) { 1191 nm.loadFilter = 'dom'; 1192 }, 1193 load: function(nm) { 1194 nm.store.domEl = $(nm.store.link.sel); 1195 if (nm.store.domEl.length) 1196 nm._setCont(nm.store.domEl.contents()); 1197 else 1198 nm._error(); 1199 }, 1200 close: function(nm) { 1201 if (nm.store.domEl && nm.elts.cont) 1202 nm.store.domEl.append(nm.elts.cont.find('.nyroModalDom').contents()); 1203 } 1204 } 1205 }); 1206}); 1207/* 1208 * nyroModal v2.0.0 1209 * 1210 * Data filter 1211 * 1212 * Depends: 1213 * - filters.link 1214 * 1215 * Before: filters.dom 1216 */ 1217jQuery(function($, undefined) { 1218 $.nmFilters({ 1219 data: { 1220 is: function(nm) { 1221 var ret = nm.data ? true : false;
1222 if (ret) { 1223 nm._delFilter('dom'); 1224 } 1225 return ret; 1226 }, 1227 init: function(nm) { 1228 nm.loadFilter = 'data'; 1229 }, 1230 load: function(nm) { 1231 nm._setCont(nm.data); 1232 } 1233 } 1234 }); 1235}); 1236/* 1237 * nyroModal v2.0.0 1238 * 1239 * Form file filter 1240 * 1241 * Depends: 1242 * 1243 * Before: filters.form 1244 */ 1245jQuery(function($, undefined) { 1246 $.nmFilters({ 1247 formFile: { 1248 is: function(nm) { 1249 var ret = nm.opener.is('form[enctype="multipart/form-data"]'); 1250 if (ret) { 1251 nm._delFilter('form'); 1252 if (!nm.store.form) 1253 nm.store.form = nm.getInternal()._extractUrl(nm.opener.attr('action')); 1254 } 1255 return ret; 1256 }, 1257 init: function(nm) { 1258 nm.loadFilter = 'formFile'; 1259 nm.store.formFileLoading = false; 1260 nm.opener.unbind('submit.nyroModal').bind('submit.nyroModal', function(e) { 1261 if (!nm.store.formFileIframe) { 1262 e.preventDefault(); 1263 nm.opener.trigger('nyroModal'); 1264 } else { 1265 nm.store.formFileLoading = true; 1266 } 1267 }); 1268 }, 1269 initElts: function(nm) { 1270 var inputSel; 1271 if (nm.store.form.sel) 1272 inputSel = $('<input />', { 1273 'type': 'hidden', 1274 name: nm.selIndicator, 1275 value: nm.store.form.sel.substring(1) 1276 }).appendTo(nm.opener); 1277 function rmFormFileElts() { 1278 if (inputSel) { 1279 inputSel.remove(); 1280 inputSel = undefined; 1281 delete(inputSel); 1282 } 1283 nm.store.formFileIframe.attr('src', 'about:blank').remove(); 1284 nm.store.formFileIframe = undefined; 1285 delete(nm.store.formFileIframe); 1286 } 1287 nm.store.formFileIframe = $('<iframe name="nyroModalFormFile" src="javascript:\'\';" id="nyromodal-iframe-'+(new Date().getTime())+'"></iframe>') 1288 .hide() 1289 .load(function() { 1290 if (nm.store.formFileLoading) { 1291 nm.store.formFileLoading = false; 1292 var content = nm.store.formFileIframe 1293 .unbind('load error') 1294 .contents().find('body').not('script[src]'); 1295 if (content && content.html() && content.html().length) { 1296 rmFormFileElts(); 1297 nm._setCont(content.html(), nm.store.form.sel); 1298 } else { 1299 // Not totally ready, try it in a few secs 1300 var nbTry = 0; 1301 fct = function() { 1302 nbTry++; 1303 var content = nm.store.formFileIframe 1304 .unbind('load error') 1305 .contents().find('body').not('script[src]'); 1306 if (content && content.html() && content.html().length) { 1307 nm._setCont(content.html(), nm.store.form.sel); 1308 rmFormFileElts(); 1309 } else if (nbTry < 5) { 1310 setTimeout(fct, 25); 1311 } else { 1312 rmFormFileElts(); 1313 nm._error(); 1314 } 1315 }; 1316 setTimeout(fct, 25); 1317 } 1318 } 1319 }) 1320 .error(function() { 1321 rmFormFileElts(); 1322 nm._error(); 1323 }); 1324 nm.elts.all.append(nm.store.formFileIframe); 1325 nm.opener 1326 .attr('target', 'nyroModalFormFile') 1327 .submit(); 1328 }, 1329 close: function(nm) { 1330 nm.store.formFileLoading = false; 1331 if (nm.store.formFileIframe) { 1332 nm.store.formFileIframe.remove(); 1333 nm.store.formFileIframe = undefined; 1334 delete(nm.store.formFileIframe); 1335 } 1336 } 1337 } 1338 }); 1339});
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.