1;(function ($, window) { 2 "use strict"; 3 4 var $window = $(window), 5 $body, 6 $responders = null, 7 nativeSupport = ("backgroundSize" in document.documentElement.style), 8 guid = 0, 9 youTubeReady = false, 10 youTubeQueue = [], 11 UA = (window.navigator.userAgent||window.navigator.vendor||window.opera), 12 isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(UA), 13 isSafari = (UA.toLowerCase().indexOf('safari') >= 0) && (UA.toLowerCase().indexOf('chrome') < 0), 14 transitionEvent, 15 transitionSupported, 16 respondTimer; 17 18 /** 19 * @options 20 * @param autoPlay [boolean] <true> "Autoplay video" 21 * @param embedRatio [number] <1.777777> "Video / embed ratio (16/9)" 22 * @param hoverPlay [boolean] <false> "Play video on hover" 23 * @param loop [boolean] <true> "Loop video" 24 * @param mute [boolean] <true> "Mute video" 25 * @param onLoad [function] <$.noop> "On load callback" 26 * @param onReady [function] <$.noop> "On ready callback" 27 * @param source [string | object] <null> "Source image (string or object) or video (object) or YouTube (object)" 28 */ 29 var options = { 30 autoPlay: true, 31 embedRatio: 1.777777, 32 hoverPlay: false, 33 loop: true, 34 mute: true, 35 onLoad: $.noop, 36 onReady: $.noop, 37 source: null 38 }; 39 40 /** 41 * @events 42 * @event wallpaper.loaded "Source media loaded" 43 */ 44 45 var pub = { 46 47 /** 48 * @method 49 * @name defaults 50 * @description Sets default plugin options 51 * @param opts [object] <{}> "Options object" 52 * @example $.wallpaper("defaults", opts); 53 */ 54 defaults: function(opts) { 55 options = $.extend(options, opts || {}); 56 return $(this); 57 }, 58 59 /** 60 * @method 61 * @name destroy 62 * @description Removes instance of plugin 63 * @example $(".target").wallpaper("destroy"); 64 */ 65 destroy: function() { 66 var $targets = $(this).each(function() { 67 var data = $(this).data("wallpaper"); 68 69 if (data) { 70 data.$container.remove(); 71 data.$target.removeClass("wallpaper") 72 .off(".boxer") 73 .data("wallpaper", null); 74 } 75 }); 76 77 if (typeof $body !== "undefined" && typeof $window !== "undefined" && $(".wallpaper").length < 1) { 78 $body.removeClass("wallpaper-inititalized"); 79 $window.off(".wallpaper"); 80 } 81 82 return $targets; 83 }, 84 85 /** 86 * @method 87 * @name load 88 * @description Loads source media 89 * @param source [string | object] "Source image (string) or video (object) or YouTube (object); { source: { poster: <"">, video: <"" or {}> } }" 90 * @example $(".target").wallpaper("load", "path/to/image.jpg"); 91 */ 92 load: function(source) { 93 return $(this).each(function() { 94 var data = $(this).data("wallpaper"); 95 96 if (data) { 97 _loadMedia(source, data); 98 } 99 }); 100 }, 101 102 /** 103 * @method 104 * @name pause 105 * @description Pauses target video 106 * @example $(".target").wallpaper("stop"); 107 */ 108 pause: function() { 109 return $(this).each(function() { 110 var data = $(this).data("wallpaper"); 111 112 if (data) { 113 if (data.isYouTube && data.playerReady) { 114 data.player.pauseVideo(); 115 } else { 116 var $video = data.$container.find("video"); 117 118 if ($video.length) { 119 $video[0].pause(); 120 } 121 } 122 } 123 }); 124 }, 125 126 /** 127 * @method 128 * @name play 129 * @description Plays target video 130 * @example $(".target").wallpaper("play"); 131 */ 132 play: function() { 133 return $(this).each(function() { 134 var data = $(this).data("wallpaper"); 135 136 if (data) { 137 if (data.isYouTube && data.playerReady) { 138 data.player.playVideo(); 139 } else { 140 var $video = data.$container.find("video"); 141 142 if ($video.length) { 143 $video[0].play(); 144 } 145 } 146 } 147 }); 148 }, 149 150 /** 151 * @method private 152 * @name stop 153 * @description Deprecated; Aliased to "pause" 154 * @example $(".target").wallpaper("stop"); 155 */ 156 stop: function() { 157 pub.pause.apply(this); 158 }, 159 160 /** 161 * @method 162 * @name unload 163 * @description Unloads current media 164 * @example $(".target").wallpaper("unload"); 165 */ 166 unload: function() { 167 return $(this).each(function() { 168 var data = $(this).data("wallpaper"); 169 170 if (data) { 171 _unloadMedia(data); 172 } 173 }); 174 } 175 }; 176 177 /** 178 * @method private 179 * @name _init 180 * @description Initializes plugin instances 181 * @param opts [object] "Initialization options" 182 */ 183 function _init(opts) { 184 var data = $.extend({}, options, opts); 185 186 $body = $("body"); 187 transitionEvent = _getTransitionEvent(); 188 transitionSupported = (transitionEvent !== false); 189 190 // no transitions :( 191 if (!transitionSupported) { 192 transitionEvent = "transitionend.wallpaper"; 193 } 194 195 // Apply to each 196 var $targets = $(this); 197 for (var i = 0, count = $targets.length; i < count; i++) { 198 _build.apply($targets.eq(i), [ $.extend({}, data) ]); 199 } 200 201 // Global events 202 if (!$body.hasClass("wallpaper-inititalized")) { 203 $body.addClass("wallpaper-inititalized"); 204 $window.on("resize.wallpaper", data, _onResizeAll); 205 } 206 207 // Maintain chainability 208 return $targets; 209 } 210 211 /** 212 * @method private 213 * @name _build 214 * @description Builds each instance 215 * @param data [object] "Instance data" 216 */ 217 function _build(data) { 218 var $target = $(this); 219 if (!$target.hasClass("wallpaper")) { 220 $.extend(data, $target.data("wallpaper-options")); 221 222 $target.addClass("wallpaper") 223 .append('<div class="wallpaper-container"></div>'); 224 225 data.guid = "wallpaper-" + (guid++); 226 data.youTubeGuid = 0; 227 data.$target = $target; 228 data.$container = data.$target.find(".wallpaper-container"); 229 230 // Bind data & events 231 data.$target.data("wallpaper", data) 232 .on("resize.wallpaper", data, _onResize); 233 234 var source = data.source; 235 data.source = null; 236 237 _loadMedia(source, data, true); 238 239 data.onReady.call(); 240 } 241 } 242
243 /** 244 * @method private 245 * @name _loadMedia 246 * @description Determines how to handle source media 247 * @param source [string | object] "Source image (string) or video (object)" 248 * @param data [object] "Instance data" 249 * @param firstLoad [boolean] "Flag for first load" 250 */ 251 function _loadMedia(source, data, firstLoad) { 252 // Check if the source is new 253 if (source !== data.source) { 254 data.source = source; 255 data.isYouTube = false; 256 257 // Check YouTube 258 if (typeof source === "object" && typeof source.video === "string") { 259 // var parts = source.match( /^.*(?:youtu.be\/|v\/|e\/|u\/\w+\/|embed\/|v=)([^#\&\?]*).*/ ); 260 var parts = source.video.match( /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i ); 261 if (parts && parts.length >= 1) { 262 data.isYouTube = true; 263 data.videoId = parts[1]; 264 } 265 } 266 267 if (data.isYouTube) { 268 // youtube video 269 data.playing = false; 270 data.playerReady = false; 271 data.posterLoaded = false; 272 273 _loadYouTube(source, data, firstLoad); 274 } else if (typeof source === "object" && !source.hasOwnProperty("fallback")) { 275 // html5 video 276 _loadVideo(source, data, firstLoad); 277 } else { 278 // regular old image 279 if (data.responsiveSource) { 280 for (var i in data.responsiveSource) { 281 if (data.responsiveSource.hasOwnProperty(i)) { 282 data.responsiveSource[i].mq.removeListener(_onRespond); 283 } 284 } 285 } 286 287 data.responsive = false; 288 data.responsiveSource = null; 289 290 // Responsive image handling 291 if (typeof source === "object") { 292 var sources = [], 293 newSource; 294 295 for (var j in source) { 296 if (source.hasOwnProperty(j)) { 297 var media = (j === "fallback") ? "(min-width: 0px)" : j; 298 299 if (media) { 300 var _mq = window.matchMedia(media.replace(Infinity, "100000px")); 301 _mq.addListener(_onRespond); 302 sources.push({ 303 mq: _mq, 304 source: source[j] 305 }); 306 307 if (_mq.matches) { 308 newSource = source[j]; 309 } 310 } 311 } 312 } 313 314 data.responsive = true; 315 data.responsiveSource = sources; 316 source = newSource; 317 } 318 319 // single or responsive set 320 _loadImage(source, data, false, firstLoad); 321 } 322 } else { 323 data.$target.trigger("wallpaper.loaded"); 324 data.onLoad.call(data.$target); 325 } 326 } 327 328 /** 329 * @method private 330 * @name _loadImage 331 * @description Loads source image 332 * @param source [string] "Source image" 333 * @param data [object] "Instance data", 334 * @param poster [boolean] "Flag for video poster" 335 */ 336 function _loadImage(source, data, poster, firstLoad) {
337 var $imgContainer = $('<div class="wallpaper-media wallpaper-image' + ((firstLoad !== true) ? ' animated' : '') + '"><img /></div>'), 338 $img = $imgContainer.find("img"), 339 newSource = source; 340 341 // Load image 342 $img.one("load.wallpaper", function() { 343 if (nativeSupport) { 344 $imgContainer.addClass("native") 345 .css({ backgroundImage: "url('" + newSource + "')" }); 346 } 347 348 // Append 349 $imgContainer.on(transitionEvent, function(e) { 350 _killEvent(e); 351 352 if ($(e.target).is($imgContainer)) { 353 $imgContainer.off(transitionEvent); 354 355 if (!poster) { 356 _cleanMedia(data); 357 } 358 } 359 }); 360 361 setTimeout( function() { 362 $imgContainer.css({ opacity: 1 }); 363 364 if (data.responsive && firstLoad) { 365 _cleanMedia(data); 366 } 367 }, 0); 368 369 // Resize 370 _onResize({ data: data }); 371 372 if (!poster || firstLoad) { 373 data.$target.trigger("wallpaper.loaded"); 374 data.onLoad.call(data.$target); 375 } 376 377 // caches responsive images 378 $responders = $(".wallpaper-responsive"); 379 }).attr("src", newSource); 380 381 if (data.responsive) { 382 $imgContainer.addClass("wallpaper-responsive"); 383 } 384 385 data.$container.append($imgContainer); 386 387 // Check if image is cached 388 if ($img[0].complete || $img[0].readyState === 4) { 389 $img.trigger("load.wallpaper"); 390 } 391 } 392 393 /** 394 * @method private 395 * @name _loadVideo 396 * @description Loads source video 397 * @param source [object] "Source video" 398 * @param data [object] "Instance data" 399 */ 400 function _loadVideo(source, data, firstLoad) { 401 if (data.source.poster) { 402 _loadImage(data.source.poster, data, true, true); 403 404 firstLoad = false; 405 } 406 407 if (!isMobile) { 408 var html = '<div class="wallpaper-media wallpaper-video' + ((firstLoad !== true) ? ' animated' : '') +'">'; 409 html += '<video'; 410 if (data.loop) { 411 html += ' loop'; 412 } 413 if (data.mute) { 414 html += ' muted'; 415 } 416 html += '>'; 417 if (data.source.webm) { 418 html += '<source src="' + data.source.webm + '" type="video/webm" />'; 419 } 420 if (data.source.mp4) { 421 html += '<source src="' + data.source.mp4 + '" type="video/mp4" />'; 422 } 423 if (data.source.ogg) { 424 html += '<source src="' + data.source.ogg + '" type="video/ogg" />'; 425 } 426 html += '</video>'; 427 html += '</div>'; 428 429 var $videoContainer = $(html), 430 $video = $videoContainer.find("video"); 431 432 $video.one("loadedmetadata.wallpaper", function(e) { 433 $videoContainer.on(transitionEvent, function(e) { 434 _killEvent(e); 435 436 if ($(e.target).is($videoContainer)) { 437 $videoContainer.off(transitionEvent); 438 439 _cleanMedia(data); 440 } 441 }); 442 443 setTimeout( function() { $videoContainer.css({ opacity: 1 }); }, 0); 444 445 // Resize 446 _onResize({ data: data }); 447 448 data.$target.trigger("wallpaper.loaded"); 449 data.onLoad.call(data.$target); 450 451 // Events 452 if (data.hoverPlay) { 453 data.$target.on("mouseover.boxer", pub.play) 454 .on("mouseout.boxer", pub.pause); 455 } else if (data.autoPlay) { 456 this.play(); 457 } 458 }); 459 460 data.$container.append($videoContainer); 461 } 462 } 463 464 /** 465 * @method private 466 * @name _loadYouTube 467 * @description Loads YouTube video 468 * @param source [string] "YouTube URL" 469 * @param data [object] "Instance data" 470 */ 471 function _loadYouTube(source, data, firstLoad) { 472 if (!data.videoId) { 473 var parts = source.match( /^.*(?:youtu.be\/|v\/|e\/|u\/\w+\/|embed\/|v=)([^#\&\?]*).*/ ); 474 data.videoId = parts[1]; 475 } 476 477 if (!data.posterLoaded) { 478 if (!data.source.poster) { 479 // data.source.poster = "http://img.youtube.com/vi/" + data.videoId + "/maxresdefault.jpg"; 480 data.source.poster = "http://img.youtube.com/vi/" + data.videoId + "/0.jpg"; 481 } 482 483 data.posterLoaded = true; 484 _loadImage(data.source.poster, data, true, firstLoad); 485 486 firstLoad = false; 487 } 488 489 if (!isMobile) { 490 if (!$("script[src*='youtube.com/iframe_api']").length) { 491 // $("head").append('<script src="' + window.location.protocol + '//www.youtube.com/iframe_api"></script>'); 492 $("head").append('<script src="//www.youtube.com/iframe_api"></script>'); 493 } 494 495 if (!youTubeReady) { 496 youTubeQueue.push({ 497 source: source, 498 data: data 499 }); 500 } else { 501 var guid = data.guid + "_" + (data.youTubeGuid++), 502 html = ''; 503 504 html += '<div class="wallpaper-media wallpaper-embed' + ((firstLoad !== true) ? ' animated' : '') + '">'; 505 html += '<div id="' + guid + '"></div>'; 506 html += '</div>'; 507 508 var $embedContainer = $(html); 509 data.$container.append($embedContainer); 510 511 if (data.player) { 512 data.oldPlayer = data.player; 513 data.player = null; 514 } 515 516 data.player = new window.YT.Player(guid, { 517 videoId: data.videoId, 518 playerVars: { 519 controls: 0, 520 rel: 0, 521 showinfo: 0, 522 wmode: "transparent", 523 enablejsapi: 1, 524 version: 3, 525 playerapiid: guid, 526 loop: (data.loop) ? 1 : 0, 527 autoplay: 1, 528 origin: window.location.protocol + "//" + window.location.host 529 }, 530 events: { 531 onReady: function (e) { 532 /* console.log("onReady", e); */ 533 534 data.playerReady = true; 535 /* data.player.setPlaybackQuality("highres"); */ 536 537 if (data.mute) { 538 data.player.mute(); 539 } 540 541 if (data.hoverPlay) { 542 data.$target.on("mouseover.boxer", pub.play) 543 .on("mouseout.boxer", pub.pause); 544 } else if (data.autoPlay) { 545 // make sure the video plays 546 data.player.playVideo(); 547 } 548 }, 549 onStateChange: function (e) { 550 /* console.log("onStateChange", e); */ 551 552 if (!data.playing && e.data === window.YT.PlayerState.PLAYING) { 553 data.playing = true; 554 555 if (data.hoverPlay || !data.autoPlay) { 556 data.player.pauseVideo(); 557 } 558 559 data.$target.trigger("wallpaper.loaded"); 560 data.onLoad.call(data.$target); 561 562 $embedContainer.on(transitionEvent, function(e) { 563 _killEvent(e); 564 565 if ($(e.target).is($embedContainer)) { 566 $embedContainer.off(transitionEvent); 567 568 _cleanMedia(data); 569 } 570 }); 571 572 $embedContainer.css({ opacity: 1 }); 573 } else if (data.loop && data.playing && e.data === window.YT.PlayerState.ENDED) { 574 // fix looping option 575 data.player.playVideo(); 576 } 577 578 /* if (!isSafari) { */ 579 // Fix for Safari's overly secure security settings... 580 data.$target.find(".wallpaper-embed").addClass("ready"); 581 /* } */ 582 }, 583 onPlaybackQualityChange: function(e) { 584 /* console.log("onPlaybackQualityChange", e); */ 585 }, 586 onPlaybackRateChange: function(e) { 587 /* console.log("onPlaybackRateChange", e); */ 588 }, 589 onError: function(e) { 590 /* console.log("onError", e); */ 591 }, 592 onApiChange: function(e) { 593 /* console.log("onApiChange", e); */ 594 } 595 } 596 }); 597 598 // Resize 599 _onResize({ data: data }); 600 } 601 } 602 } 603
604 /** 605 * @method private 606 * @name _cleanMedia 607 * @description Cleans up old media 608 * @param data [object] "Instance data" 609 */ 610 function _cleanMedia(data) { 611 var $mediaContainer = data.$container.find(".wallpaper-media"); 612 613 if ($mediaContainer.length >= 1) { 614 $mediaContainer.not(":last").remove(); 615 data.oldPlayer = null; 616 } 617 618 $responders = $(".wallpaper-responsive"); 619 } 620 621 /** 622 * @method private 623 * @name _uploadMedia 624 * @description Unloads current media 625 * @param data [object] "Instance data" 626 */ 627 function _unloadMedia(data) { 628 var $mediaContainer = data.$container.find(".wallpaper-media"); 629 630 if ($mediaContainer.length >= 1) { 631 $mediaContainer.on(transitionEvent, function(e) { 632 _killEvent(e); 633 634 if ($(e.target).is($mediaContainer)) { 635 $(this).remove(); 636 637 delete data.source; 638 } 639 }).css({ opacity: 0 }); 640 } 641 } 642 643 /** 644 * @method private 645 * @name _onResize 646 * @description Resize target instance 647 * @param e [object] "Event data" 648 */ 649 function _onResize(e) { 650 _killEvent(e); 651 652 var data = e.data; 653 654 // Target all media 655 var $mediaContainers = data.$container.find(".wallpaper-media"); 656 657 for (var i = 0, count = $mediaContainers.length; i < count; i++) { 658 var $mediaContainer = $mediaContainers.eq(i), 659 type = (data.isYouTube) ? "iframe" : ($mediaContainer.find("video").length ? "video" : "img"), 660 $media = $mediaContainer.find(type); 661 662 // If media found and scaling is not natively support 663 if ($media.length && !(type === "img" && data.nativeSupport)) { 664 var frameWidth = data.$target.outerWidth(), 665 frameHeight = data.$target.outerHeight(), 666 frameRatio = frameWidth / frameHeight, 667 naturalSize = _naturalSize(data, $media); 668 669 data.width = naturalSize.naturalWidth; 670 data.height = naturalSize.naturalHeight; 671 data.left = 0; 672 data.top = 0; 673 674 var mediaRatio = (data.isYouTube) ? data.embedRatio : (data.width / data.height); 675 676 // First check the height 677 data.height = frameHeight; 678 data.width = data.height * mediaRatio; 679 680 // Next check the width 681 if (data.width < frameWidth) { 682 data.width = frameWidth; 683 data.height = data.width / mediaRatio; 684 } 685 686 // Position the media 687 data.left = -(data.width - frameWidth) / 2; 688 data.top = -(data.height - frameHeight) / 2; 689 690 $mediaContainer.css({ 691 height: data.height, 692 width: data.width, 693 left: data.left, 694 top: data.top 695 }); 696 } 697 } 698 } 699 700 /** 701 * @method private 702 * @name _onResizeAll 703 * @description Resizes all target instances 704 */ 705 function _onResizeAll() { 706 $(".wallpaper").each(function() { 707 var data = $(this).data("wallpaper"); 708 _onResize({ data: data }); 709 }); 710 } 711 712 /** 713 * @method private 714 * @name _onRespond 715 * @description Handle media query changes 716 */ 717 function _onRespond() { 718 respondTimer = _startTimer(respondTimer, 5, _doRespond); 719 } 720 721 /** 722 * @method private 723 * @name _doRespond 724 * @description Handle media query changes 725 */ 726 function _doRespond() { 727 _clearTimer(respondTimer); 728 729 $responders.each(function() { 730 var $target = $(this), 731 $image = $target.find("img"), 732 data = $target.parents(".wallpaper").data("wallpaper"), 733 sources = data.responsiveSource, 734 index = 0; 735 736 for (var i = 0, count = sources.length; i < count; i++) { 737 if (sources.hasOwnProperty(i)) { 738 var match = sources[i].mq; 739 740 if (match && match.matches) { 741 index = i; 742 } 743 } 744 } 745 746 _loadImage(sources[index].source, data, false, true); 747 748 $target.trigger("change.wallpaper"); 749 }); 750 } 751 752 /** 753 * @method private 754 * @name _startTimer 755 * @description Starts an internal timer 756 * @param timer [int] "Timer ID" 757 * @param time [int] "Time until execution" 758 * @param callback [int] "Function to execute" 759 * @param interval [boolean] "Flag for recurring interval" 760 */ 761 function _startTimer(timer, time, func, interval) { 762 _clearTimer(timer, interval); 763 return setTimeout(func, time); 764 } 765 766 /** 767 * @method private 768 * @name _clearTimer 769 * @description Clears an internal timer 770 * @param timer [int] "Timer ID" 771 */ 772 function _clearTimer(timer) { 773 if (timer !== null) { 774 clearInterval(timer); 775 timer = null; 776 } 777 } 778
779 /** 780 * @method private 781 * @name _naturalSize 782 * @description Determines natural size of target media 783 * @param data [object] "Instance data" 784 * @param $media [jQuery object] "Source media object" 785 * @return [object | boolean] "Object containing natural height and width values or false" 786 */ 787 function _naturalSize(data, $media) { 788 if (data.isYouTube) { 789 return { 790 naturalHeight: 500, 791 naturalWidth: 500 / data.embedRatio 792 }; 793 } else if ($media.is("img")) { 794 var node = $media[0]; 795 796 if (typeof node.naturalHeight !== "undefined") { 797 return { 798 naturalHeight: node.naturalHeight, 799 naturalWidth: node.naturalWidth 800 }; 801 } else { 802 var img = new Image(); 803 img.src = node.src; 804 return { 805 naturalHeight: img.height, 806 naturalWidth: img.width 807 }; 808 } 809 } else { 810 return { 811 naturalHeight: $media[0].videoHeight, 812 naturalWidth: $media[0].videoWidth 813 }; 814 } 815 return false; 816 } 817 818 /** 819 * @method private 820 * @name _killEvent 821 * @description Prevents default and stops propagation on event 822 * @param e [object] "Event data" 823 */ 824 function _killEvent(e) { 825 if (e.preventDefault) { 826 e.stopPropagation(); 827 e.preventDefault(); 828 } 829 } 830 831 /** 832 * @method private 833 * @name _getTransitionEvent 834 * @description Retuns a properly prefixed transitionend event 835 * @return [string] "Properly prefixed event" 836 */ 837 function _getTransitionEvent() { 838 var transitions = { 839 'WebkitTransition': 'webkitTransitionEnd', 840 'MozTransition': 'transitionend', 841 'OTransition': 'oTransitionEnd', 842 'transition': 'transitionend' 843 }, 844 test = document.createElement('div'); 845 846 for (var type in transitions) { 847 if (transitions.hasOwnProperty(type) && type in test.style) { 848 return transitions[type] + ".wallpaper"; 849 } 850 } 851 852 return false; 853 } 854 855 /** 856 * @method global 857 * @name window.onYouTubeIframeAPIReady 858 * @description Attaches YouTube players to active instances 859 */ 860 window.onYouTubeIframeAPIReady = function() { 861 youTubeReady = true; 862 863 for (var i in youTubeQueue) { 864 if (youTubeQueue.hasOwnProperty(i)) { 865 _loadYouTube(youTubeQueue[i].source, youTubeQueue[i].data); 866 } 867 } 868 869 youTubeQueue = []; 870 }; 871 872 $.fn.wallpaper = function(method) { 873 if (pub[method]) { 874 return pub[method].apply(this, Array.prototype.slice.call(arguments, 1)); 875 } else if (typeof method === 'object' || !method) { 876 return _init.apply(this, arguments); 877 } 878 return this; 879 }; 880 881 $.wallpaper = function(method) { 882 if (method === "defaults") { 883 pub.defaults.apply(this, Array.prototype.slice.call(arguments, 1)); 884 } 885 }; 886})(jQuery, window);
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.