Changeset 750699
- Timestamp:
- 08/03/2013 02:46:03 PM (13 years ago)
- Location:
- jsdelivr-wordpress-cdn-plugin/trunk
- Files:
-
- 3 edited
-
3rdparty/jquery.blockUI.js (modified) (2 diffs)
-
jsdelivr.php (modified) (52 diffs)
-
readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
jsdelivr-wordpress-cdn-plugin/trunk/3rdparty/jquery.blockUI.js
r669227 r750699 1 1 /*! 2 2 * jQuery blockUI plugin 3 * Version 2. 42 (11-MAY-2012)4 * @requires jQuery v1. 2.3or later3 * Version 2.64.0-2013.07.18 4 * @requires jQuery v1.7 or later 5 5 * 6 6 * Examples at: http://malsup.com/jquery/block/ 7 * Copyright (c) 2007-201 0M. Alsup7 * Copyright (c) 2007-2013 M. Alsup 8 8 * Dual licensed under the MIT and GPL licenses: 9 9 * http://www.opensource.org/licenses/mit-license.php … … 12 12 * Thanks to Amir-Hossein Sobhi for some excellent contributions! 13 13 */ 14 (function(){function a(j){if(/1\.(0|1|2)\.(0|1|2)/.test(j.fn.jquery)||/^1.1/.test(j.fn.jquery)){alert("blockUI requires jQuery v1.2.3 or later! You are using v"+j.fn.jquery);return}j.fn._fadeIn=j.fn.fadeIn;var d=function(){};var k=document.documentMode||0;var f=j.browser.msie&&((j.browser.version<8&&!k)||k<8);var g=j.browser.msie&&/MSIE 6.0/.test(navigator.userAgent)&&!k;j.blockUI=function(q){e(window,q)};j.unblockUI=function(q){i(window,q)};j.growlUI=function(u,s,t,q){var r=j('<div class="growlUI"></div>');if(u){r.append("<h1>"+u+"</h1>")}if(s){r.append("<h2>"+s+"</h2>")}if(t==undefined){t=3000}j.blockUI({message:r,fadeIn:700,fadeOut:1000,centerY:false,timeout:t,showOverlay:false,onUnblock:q,css:j.blockUI.defaults.growlCSS})};j.fn.block=function(r){var q=j.extend({},j.blockUI.defaults,r||{});this.each(function(){var s=j(this);if(q.ignoreIfBlocked&&s.data("blockUI.isBlocked")){return}s.unblock({fadeOut:0})});return this.each(function(){if(j.css(this,"position")=="static"){this.style.position="relative"}if(j.browser.msie){this.style.zoom=1}e(this,r)})};j.fn.unblock=function(q){return this.each(function(){i(this,q)})};j.blockUI.version=2.42;j.blockUI.defaults={message:"<h1>Please wait...</h1>",title:null,draggable:true,theme:false,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:0.6,cursor:"wait"},growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:0.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:false,baseZ:1000,centerX:true,centerY:true,allowBodyStretch:true,bindEvents:true,constrainTabKey:true,fadeIn:200,fadeOut:400,timeout:0,showOverlay:true,focusInput:true,applyPlatformOpacityRules:true,onBlock:null,onUnblock:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:false};var c=null;var h=[];function e(u,G){var D,O;var B=(u==window);var x=(G&&G.message!==undefined?G.message:undefined);G=j.extend({},j.blockUI.defaults,G||{});if(G.ignoreIfBlocked&&j(u).data("blockUI.isBlocked")){return}G.overlayCSS=j.extend({},j.blockUI.defaults.overlayCSS,G.overlayCSS||{});D=j.extend({},j.blockUI.defaults.css,G.css||{});O=j.extend({},j.blockUI.defaults.themedCSS,G.themedCSS||{});x=x===undefined?G.message:x;if(B&&c){i(window,{fadeOut:0})}if(x&&typeof x!="string"&&(x.parentNode||x.jquery)){var J=x.jquery?x[0]:x;var Q={};j(u).data("blockUI.history",Q);Q.el=J;Q.parent=J.parentNode;Q.display=J.style.display;Q.position=J.style.position;if(Q.parent){Q.parent.removeChild(J)}}j(u).data("blockUI.onUnblock",G.onUnblock);var C=G.baseZ;var N=(j.browser.msie||G.forceIframe)?j('<iframe class="blockUI" style="z-index:'+(C++)+';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+G.iframeSrc+'"></iframe>'):j('<div class="blockUI" style="display:none"></div>');var M=G.theme?j('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+(C++)+';display:none"></div>'):j('<div class="blockUI blockOverlay" style="z-index:'+(C++)+';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');var L,H;if(G.theme&&B){H='<div class="blockUI '+G.blockMsgClass+' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(C+10)+';display:none;position:fixed"><div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(G.title||" ")+'</div><div class="ui-widget-content ui-dialog-content"></div></div>'}else{if(G.theme){H='<div class="blockUI '+G.blockMsgClass+' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(C+10)+';display:none;position:absolute"><div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(G.title||" ")+'</div><div class="ui-widget-content ui-dialog-content"></div></div>'}else{if(B){H='<div class="blockUI '+G.blockMsgClass+' blockPage" style="z-index:'+(C+10)+';display:none;position:fixed"></div>'}else{H='<div class="blockUI '+G.blockMsgClass+' blockElement" style="z-index:'+(C+10)+';display:none;position:absolute"></div>'}}}L=j(H);if(x){if(G.theme){L.css(O);L.addClass("ui-widget-content")}else{L.css(D)}}if(!G.theme&&(!G.applyPlatformOpacityRules||!(j.browser.mozilla&&/Linux/.test(navigator.platform)))){M.css(G.overlayCSS)}M.css("position",B?"fixed":"absolute");if(j.browser.msie||G.forceIframe){N.css("opacity",0)}var A=[N,M,L],P=B?j("body"):j(u);j.each(A,function(){this.appendTo(P)});if(G.theme&&G.draggable&&j.fn.draggable){L.draggable({handle:".ui-dialog-titlebar",cancel:"li"})}var w=f&&(!j.boxModel||j("object,embed",B?null:u).length>0);if(g||w){if(B&&G.allowBodyStretch&&j.boxModel){j("html,body").css("height","100%")}if((g||!j.boxModel)&&!B){var F=n(u,"borderTopWidth"),K=n(u,"borderLeftWidth");var y=F?"(0 - "+F+")":0;var E=K?"(0 - "+K+")":0}j.each([N,M,L],function(t,T){var z=T[0].style;z.position="absolute";if(t<2){B?z.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:"+G.quirksmodeOffsetHack+') + "px"'):z.setExpression("height",'this.parentNode.offsetHeight + "px"');B?z.setExpression("width",'jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):z.setExpression("width",'this.parentNode.offsetWidth + "px"');if(E){z.setExpression("left",E)}if(y){z.setExpression("top",y)}}else{if(G.centerY){if(B){z.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"')}z.marginTop=0}else{if(!G.centerY&&B){var R=(G.css&&G.css.top)?parseInt(G.css.top):0;var S="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+R+') + "px"';z.setExpression("top",S)}}}})}if(x){if(G.theme){L.find(".ui-widget-content").append(x)}else{L.append(x)}if(x.jquery||x.nodeType){j(x).show()}}if((j.browser.msie||G.forceIframe)&&G.showOverlay){N.show()}if(G.fadeIn){var I=G.onBlock?G.onBlock:d;var r=(G.showOverlay&&!x)?I:d;var q=x?I:d;if(G.showOverlay){M._fadeIn(G.fadeIn,r)}if(x){L._fadeIn(G.fadeIn,q)}}else{if(G.showOverlay){M.show()}if(x){L.show()}if(G.onBlock){G.onBlock()}}m(1,u,G);if(B){c=L[0];h=j(":input:enabled:visible",c);if(G.focusInput){setTimeout(p,20)}}else{b(L[0],G.centerX,G.centerY)}if(G.timeout){var v=setTimeout(function(){B?j.unblockUI(G):j(u).unblock(G)},G.timeout);j(u).data("blockUI.timeout",v)}}function i(t,u){var s=(t==window);var r=j(t);var v=r.data("blockUI.history");var w=r.data("blockUI.timeout");if(w){clearTimeout(w);r.removeData("blockUI.timeout")}u=j.extend({},j.blockUI.defaults,u||{});m(0,t,u);if(u.onUnblock===null){u.onUnblock=r.data("blockUI.onUnblock");r.removeData("blockUI.onUnblock")}var q;if(s){q=j("body").children().filter(".blockUI").add("body > .blockUI")}else{q=j(".blockUI",t)}if(s){c=h=null}if(u.fadeOut){q.fadeOut(u.fadeOut);setTimeout(function(){l(q,v,u,t)},u.fadeOut)}else{l(q,v,u,t)}}function l(q,t,s,r){q.each(function(u,v){if(this.parentNode){this.parentNode.removeChild(this)}});if(t&&t.el){t.el.style.display=t.display;t.el.style.position=t.position;if(t.parent){t.parent.appendChild(t.el)}j(r).removeData("blockUI.history")}if(typeof s.onUnblock=="function"){s.onUnblock(r,s)}}function m(q,u,v){var t=u==window,s=j(u);if(!q&&(t&&!c||!t&&!s.data("blockUI.isBlocked"))){return}s.data("blockUI.isBlocked",q);if(!v.bindEvents||(q&&!v.showOverlay)){return}var r="mousedown mouseup keydown keypress";q?j(document).bind(r,v,o):j(document).unbind(r,o)}function o(u){if(u.keyCode&&u.keyCode==9){if(c&&u.data.constrainTabKey){var s=h;var r=!u.shiftKey&&u.target===s[s.length-1];var q=u.shiftKey&&u.target===s[0];if(r||q){setTimeout(function(){p(q)},10);return false}}}var t=u.data;if(j(u.target).parents("div."+t.blockMsgClass).length>0){return true}return j(u.target).parents().children().filter("div.blockUI").length==0}function p(q){if(!h){return}var r=h[q===true?h.length-1:0];if(r){r.focus()}}function b(w,q,A){var z=w.parentNode,v=w.style;var r=((z.offsetWidth-w.offsetWidth)/2)-n(z,"borderLeftWidth");var u=((z.offsetHeight-w.offsetHeight)/2)-n(z,"borderTopWidth");if(q){v.left=r>0?(r+"px"):"0"}if(A){v.top=u>0?(u+"px"):"0"}}function n(q,r){return parseInt(j.css(q,r))||0}}if(typeof define==="function"&&define.amd&&define.amd.jQuery){define(["jquery"],a)}else{a(jQuery)}})(); 14 15 ;(function() { 16 /*jshint eqeqeq:false curly:false latedef:false */ 17 "use strict"; 18 19 function setup($) { 20 $.fn._fadeIn = $.fn.fadeIn; 21 22 var noOp = $.noop || function() {}; 23 24 // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle 25 // confusing userAgent strings on Vista) 26 var msie = /MSIE/.test(navigator.userAgent); 27 var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); 28 var mode = document.documentMode || 0; 29 var setExpr = $.isFunction( document.createElement('div').style.setExpression ); 30 31 // global $ methods for blocking/unblocking the entire page 32 $.blockUI = function(opts) { install(window, opts); }; 33 $.unblockUI = function(opts) { remove(window, opts); }; 34 35 // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) 36 $.growlUI = function(title, message, timeout, onClose) { 37 var $m = $('<div class="growlUI"></div>'); 38 if (title) $m.append('<h1>'+title+'</h1>'); 39 if (message) $m.append('<h2>'+message+'</h2>'); 40 if (timeout === undefined) timeout = 3000; 41 42 // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications 43 var callBlock = function(opts) { 44 opts = opts || {}; 45 46 $.blockUI({ 47 message: $m, 48 fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, 49 fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, 50 timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, 51 centerY: false, 52 showOverlay: false, 53 onUnblock: onClose, 54 css: $.blockUI.defaults.growlCSS 55 }); 56 }; 57 58 callBlock(); 59 var nonmousedOpacity = $m.css('opacity'); 60 $m.mouseover(function() { 61 callBlock({ 62 fadeIn: 0, 63 timeout: 30000 64 }); 65 66 var displayBlock = $('.blockMsg'); 67 displayBlock.stop(); // cancel fadeout if it has started 68 displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency 69 }).mouseout(function() { 70 $('.blockMsg').fadeOut(1000); 71 }); 72 // End konapun additions 73 }; 74 75 // plugin method for blocking element content 76 $.fn.block = function(opts) { 77 if ( this[0] === window ) { 78 $.blockUI( opts ); 79 return this; 80 } 81 var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); 82 this.each(function() { 83 var $el = $(this); 84 if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) 85 return; 86 $el.unblock({ fadeOut: 0 }); 87 }); 88 89 return this.each(function() { 90 if ($.css(this,'position') == 'static') { 91 this.style.position = 'relative'; 92 $(this).data('blockUI.static', true); 93 } 94 this.style.zoom = 1; // force 'hasLayout' in ie 95 install(this, opts); 96 }); 97 }; 98 99 // plugin method for unblocking element content 100 $.fn.unblock = function(opts) { 101 if ( this[0] === window ) { 102 $.unblockUI( opts ); 103 return this; 104 } 105 return this.each(function() { 106 remove(this, opts); 107 }); 108 }; 109 110 $.blockUI.version = 2.60; // 2nd generation blocking at no extra cost! 111 112 // override these in your code to change the default behavior and style 113 $.blockUI.defaults = { 114 // message displayed when blocking (use null for no message) 115 message: '<h1>Please wait...</h1>', 116 117 title: null, // title string; only used when theme == true 118 draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) 119 120 theme: false, // set to true to use with jQuery UI themes 121 122 // styles for the message when blocking; if you wish to disable 123 // these and use an external stylesheet then do this in your code: 124 // $.blockUI.defaults.css = {}; 125 css: { 126 padding: 0, 127 margin: 0, 128 width: '30%', 129 top: '40%', 130 left: '35%', 131 textAlign: 'center', 132 color: '#000', 133 border: '3px solid #aaa', 134 backgroundColor:'#fff', 135 cursor: 'wait' 136 }, 137 138 // minimal style set used when themes are used 139 themedCSS: { 140 width: '30%', 141 top: '40%', 142 left: '35%' 143 }, 144 145 // styles for the overlay 146 overlayCSS: { 147 backgroundColor: '#000', 148 opacity: 0.6, 149 cursor: 'wait' 150 }, 151 152 // style to replace wait cursor before unblocking to correct issue 153 // of lingering wait cursor 154 cursorReset: 'default', 155 156 // styles applied when using $.growlUI 157 growlCSS: { 158 width: '350px', 159 top: '10px', 160 left: '', 161 right: '10px', 162 border: 'none', 163 padding: '5px', 164 opacity: 0.6, 165 cursor: 'default', 166 color: '#fff', 167 backgroundColor: '#000', 168 '-webkit-border-radius':'10px', 169 '-moz-border-radius': '10px', 170 'border-radius': '10px' 171 }, 172 173 // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w 174 // (hat tip to Jorge H. N. de Vasconcelos) 175 /*jshint scripturl:true */ 176 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', 177 178 // force usage of iframe in non-IE browsers (handy for blocking applets) 179 forceIframe: false, 180 181 // z-index for the blocking overlay 182 baseZ: 1000, 183 184 // set these to true to have the message automatically centered 185 centerX: true, // <-- only effects element blocking (page block controlled via css above) 186 centerY: true, 187 188 // allow body element to be stetched in ie6; this makes blocking look better 189 // on "short" pages. disable if you wish to prevent changes to the body height 190 allowBodyStretch: true, 191 192 // enable if you want key and mouse events to be disabled for content that is blocked 193 bindEvents: true, 194 195 // be default blockUI will supress tab navigation from leaving blocking content 196 // (if bindEvents is true) 197 constrainTabKey: true, 198 199 // fadeIn time in millis; set to 0 to disable fadeIn on block 200 fadeIn: 200, 201 202 // fadeOut time in millis; set to 0 to disable fadeOut on unblock 203 fadeOut: 400, 204 205 // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock 206 timeout: 0, 207 208 // disable if you don't want to show the overlay 209 showOverlay: true, 210 211 // if true, focus will be placed in the first available input field when 212 // page blocking 213 focusInput: true, 214 215 // elements that can receive focus 216 focusableElements: ':input:enabled:visible', 217 218 // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) 219 // no longer needed in 2012 220 // applyPlatformOpacityRules: true, 221 222 // callback method invoked when fadeIn has completed and blocking message is visible 223 onBlock: null, 224 225 // callback method invoked when unblocking has completed; the callback is 226 // passed the element that has been unblocked (which is the window object for page 227 // blocks) and the options that were passed to the unblock call: 228 // onUnblock(element, options) 229 onUnblock: null, 230 231 // callback method invoked when the overlay area is clicked. 232 // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. 233 onOverlayClick: null, 234 235 // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 236 quirksmodeOffsetHack: 4, 237 238 // class name of the message block 239 blockMsgClass: 'blockMsg', 240 241 // if it is already blocked, then ignore it (don't unblock and reblock) 242 ignoreIfBlocked: false 243 }; 244 245 // private data and functions follow... 246 247 var pageBlock = null; 248 var pageBlockEls = []; 249 250 function install(el, opts) { 251 var css, themedCSS; 252 var full = (el == window); 253 var msg = (opts && opts.message !== undefined ? opts.message : undefined); 254 opts = $.extend({}, $.blockUI.defaults, opts || {}); 255 256 if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) 257 return; 258 259 opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); 260 css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); 261 if (opts.onOverlayClick) 262 opts.overlayCSS.cursor = 'pointer'; 263 264 themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); 265 msg = msg === undefined ? opts.message : msg; 266 267 // remove the current block (if there is one) 268 if (full && pageBlock) 269 remove(window, {fadeOut:0}); 270 271 // if an existing element is being used as the blocking content then we capture 272 // its current place in the DOM (and current display style) so we can restore 273 // it when we unblock 274 if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { 275 var node = msg.jquery ? msg[0] : msg; 276 var data = {}; 277 $(el).data('blockUI.history', data); 278 data.el = node; 279 data.parent = node.parentNode; 280 data.display = node.style.display; 281 data.position = node.style.position; 282 if (data.parent) 283 data.parent.removeChild(node); 284 } 285 286 $(el).data('blockUI.onUnblock', opts.onUnblock); 287 var z = opts.baseZ; 288 289 // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; 290 // layer1 is the iframe layer which is used to supress bleed through of underlying content 291 // layer2 is the overlay layer which has opacity and a wait cursor (by default) 292 // layer3 is the message content that is displayed while blocking 293 var lyr1, lyr2, lyr3, s; 294 if (msie || opts.forceIframe) 295 lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>'); 296 else 297 lyr1 = $('<div class="blockUI" style="display:none"></div>'); 298 299 if (opts.theme) 300 lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>'); 301 else 302 lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>'); 303 304 if (opts.theme && full) { 305 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">'; 306 if ( opts.title ) { 307 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>'; 308 } 309 s += '<div class="ui-widget-content ui-dialog-content"></div>'; 310 s += '</div>'; 311 } 312 else if (opts.theme) { 313 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">'; 314 if ( opts.title ) { 315 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>'; 316 } 317 s += '<div class="ui-widget-content ui-dialog-content"></div>'; 318 s += '</div>'; 319 } 320 else if (full) { 321 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>'; 322 } 323 else { 324 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>'; 325 } 326 lyr3 = $(s); 327 328 // if we have a message, style it 329 if (msg) { 330 if (opts.theme) { 331 lyr3.css(themedCSS); 332 lyr3.addClass('ui-widget-content'); 333 } 334 else 335 lyr3.css(css); 336 } 337 338 // style the overlay 339 if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) 340 lyr2.css(opts.overlayCSS); 341 lyr2.css('position', full ? 'fixed' : 'absolute'); 342 343 // make iframe layer transparent in IE 344 if (msie || opts.forceIframe) 345 lyr1.css('opacity',0.0); 346 347 //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); 348 var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); 349 $.each(layers, function() { 350 this.appendTo($par); 351 }); 352 353 if (opts.theme && opts.draggable && $.fn.draggable) { 354 lyr3.draggable({ 355 handle: '.ui-dialog-titlebar', 356 cancel: 'li' 357 }); 358 } 359 360 // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) 361 var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); 362 if (ie6 || expr) { 363 // give body 100% height 364 if (full && opts.allowBodyStretch && $.support.boxModel) 365 $('html,body').css('height','100%'); 366 367 // fix ie6 issue when blocked element has a border width 368 if ((ie6 || !$.support.boxModel) && !full) { 369 var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); 370 var fixT = t ? '(0 - '+t+')' : 0; 371 var fixL = l ? '(0 - '+l+')' : 0; 372 } 373 374 // simulate fixed position 375 $.each(layers, function(i,o) { 376 var s = o[0].style; 377 s.position = 'absolute'; 378 if (i < 2) { 379 if (full) 380 s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); 381 else 382 s.setExpression('height','this.parentNode.offsetHeight + "px"'); 383 if (full) 384 s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); 385 else 386 s.setExpression('width','this.parentNode.offsetWidth + "px"'); 387 if (fixL) s.setExpression('left', fixL); 388 if (fixT) s.setExpression('top', fixT); 389 } 390 else if (opts.centerY) { 391 if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); 392 s.marginTop = 0; 393 } 394 else if (!opts.centerY && full) { 395 var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; 396 var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; 397 s.setExpression('top',expression); 398 } 399 }); 400 } 401 402 // show the message 403 if (msg) { 404 if (opts.theme) 405 lyr3.find('.ui-widget-content').append(msg); 406 else 407 lyr3.append(msg); 408 if (msg.jquery || msg.nodeType) 409 $(msg).show(); 410 } 411 412 if ((msie || opts.forceIframe) && opts.showOverlay) 413 lyr1.show(); // opacity is zero 414 if (opts.fadeIn) { 415 var cb = opts.onBlock ? opts.onBlock : noOp; 416 var cb1 = (opts.showOverlay && !msg) ? cb : noOp; 417 var cb2 = msg ? cb : noOp; 418 if (opts.showOverlay) 419 lyr2._fadeIn(opts.fadeIn, cb1); 420 if (msg) 421 lyr3._fadeIn(opts.fadeIn, cb2); 422 } 423 else { 424 if (opts.showOverlay) 425 lyr2.show(); 426 if (msg) 427 lyr3.show(); 428 if (opts.onBlock) 429 opts.onBlock(); 430 } 431 432 // bind key and mouse events 433 bind(1, el, opts); 434 435 if (full) { 436 pageBlock = lyr3[0]; 437 pageBlockEls = $(opts.focusableElements,pageBlock); 438 if (opts.focusInput) 439 setTimeout(focus, 20); 440 } 441 else 442 center(lyr3[0], opts.centerX, opts.centerY); 443 444 if (opts.timeout) { 445 // auto-unblock 446 var to = setTimeout(function() { 447 if (full) 448 $.unblockUI(opts); 449 else 450 $(el).unblock(opts); 451 }, opts.timeout); 452 $(el).data('blockUI.timeout', to); 453 } 454 } 455 456 // remove the block 457 function remove(el, opts) { 458 var count; 459 var full = (el == window); 460 var $el = $(el); 461 var data = $el.data('blockUI.history'); 462 var to = $el.data('blockUI.timeout'); 463 if (to) { 464 clearTimeout(to); 465 $el.removeData('blockUI.timeout'); 466 } 467 opts = $.extend({}, $.blockUI.defaults, opts || {}); 468 bind(0, el, opts); // unbind events 469 470 if (opts.onUnblock === null) { 471 opts.onUnblock = $el.data('blockUI.onUnblock'); 472 $el.removeData('blockUI.onUnblock'); 473 } 474 475 var els; 476 if (full) // crazy selector to handle odd field errors in ie6/7 477 els = $('body').children().filter('.blockUI').add('body > .blockUI'); 478 else 479 els = $el.find('>.blockUI'); 480 481 // fix cursor issue 482 if ( opts.cursorReset ) { 483 if ( els.length > 1 ) 484 els[1].style.cursor = opts.cursorReset; 485 if ( els.length > 2 ) 486 els[2].style.cursor = opts.cursorReset; 487 } 488 489 if (full) 490 pageBlock = pageBlockEls = null; 491 492 if (opts.fadeOut) { 493 count = els.length; 494 els.stop().fadeOut(opts.fadeOut, function() { 495 if ( --count === 0) 496 reset(els,data,opts,el); 497 }); 498 } 499 else 500 reset(els, data, opts, el); 501 } 502 503 // move blocking element back into the DOM where it started 504 function reset(els,data,opts,el) { 505 var $el = $(el); 506 if ( $el.data('blockUI.isBlocked') ) 507 return; 508 509 els.each(function(i,o) { 510 // remove via DOM calls so we don't lose event handlers 511 if (this.parentNode) 512 this.parentNode.removeChild(this); 513 }); 514 515 if (data && data.el) { 516 data.el.style.display = data.display; 517 data.el.style.position = data.position; 518 if (data.parent) 519 data.parent.appendChild(data.el); 520 $el.removeData('blockUI.history'); 521 } 522 523 if ($el.data('blockUI.static')) { 524 $el.css('position', 'static'); // #22 525 } 526 527 if (typeof opts.onUnblock == 'function') 528 opts.onUnblock(el,opts); 529 530 // fix issue in Safari 6 where block artifacts remain until reflow 531 var body = $(document.body), w = body.width(), cssW = body[0].style.width; 532 body.width(w-1).width(w); 533 body[0].style.width = cssW; 534 } 535 536 // bind/unbind the handler 537 function bind(b, el, opts) { 538 var full = el == window, $el = $(el); 539 540 // don't bother unbinding if there is nothing to unbind 541 if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) 542 return; 543 544 $el.data('blockUI.isBlocked', b); 545 546 // don't bind events when overlay is not in use or if bindEvents is false 547 if (!full || !opts.bindEvents || (b && !opts.showOverlay)) 548 return; 549 550 // bind anchors and inputs for mouse and key events 551 var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; 552 if (b) 553 $(document).bind(events, opts, handler); 554 else 555 $(document).unbind(events, handler); 556 557 // former impl... 558 // var $e = $('a,:input'); 559 // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); 560 } 561 562 // event handler to suppress keyboard/mouse events when blocking 563 function handler(e) { 564 // allow tab navigation (conditionally) 565 if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { 566 if (pageBlock && e.data.constrainTabKey) { 567 var els = pageBlockEls; 568 var fwd = !e.shiftKey && e.target === els[els.length-1]; 569 var back = e.shiftKey && e.target === els[0]; 570 if (fwd || back) { 571 setTimeout(function(){focus(back);},10); 572 return false; 573 } 574 } 575 } 576 var opts = e.data; 577 var target = $(e.target); 578 if (target.hasClass('blockOverlay') && opts.onOverlayClick) 579 opts.onOverlayClick(); 580 581 // allow events within the message content 582 if (target.parents('div.' + opts.blockMsgClass).length > 0) 583 return true; 584 585 // allow events for content that is not being blocked 586 return target.parents().children().filter('div.blockUI').length === 0; 587 } 588 589 function focus(back) { 590 if (!pageBlockEls) 591 return; 592 var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; 593 if (e) 594 e.focus(); 595 } 596 597 function center(el, x, y) { 598 var p = el.parentNode, s = el.style; 599 var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); 600 var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); 601 if (x) s.left = l > 0 ? (l+'px') : '0'; 602 if (y) s.top = t > 0 ? (t+'px') : '0'; 603 } 604 605 function sz(el, p) { 606 return parseInt($.css(el,p),10)||0; 607 } 608 609 } 610 611 612 /*global define:true */ 613 if (typeof define === 'function' && define.amd && define.amd.jQuery) { 614 define(['jquery'], setup); 615 } else { 616 setup(jQuery); 617 } 618 619 })(); -
jsdelivr-wordpress-cdn-plugin/trunk/jsdelivr.php
r669227 r750699 5 5 Description: The official plugin of jsDelivr.com, a free public CDN. An easy way to integrate the service and speed up your website using our super fast CDN. 6 6 Author: jsDelivr 7 Version: 0.2 7 Version: 0.2.1 8 8 Author URI: http://www.jsdelivr.com 9 License: GPLv2 9 License: GPLv2 10 10 */ 11 11 12 // jsdelivr - main class 12 // jsdelivr - main class 13 13 if (!class_exists('jsdelivr')) 14 14 { … … 17 17 $wpdb->jsd_cdnf = $wpdb->prefix.'jsdelivr_cdn_files'; // table with CDN hosted files 18 18 $wpdb->jsd_files = $wpdb->prefix.'jsdelivr_files'; // list of scanned files from pages 19 19 20 20 define('JSDT_UNKNOWN', 0); 21 21 define('JSDT_CSS', 1); 22 22 define('JSDT_IMAGE', 2); 23 23 define('JSDT_JAVASCRIPT', 3); 24 24 25 25 define('JSDM_NONE', 0); 26 26 define('JSDM_MAYBE', 1); 27 27 define('JSDM_FULL', 2); 28 28 29 29 class jsdelivr_Exception extends Exception { } 30 30 31 31 // main class 32 32 class jsdelivr 33 { 34 const ld = 'jsdelivr'; // name of localization domain 35 const version = '0.2 '; // current version33 { 34 const ld = 'jsdelivr'; // name of localization domain 35 const version = '0.2.1'; // current version 36 36 const nonce = 'jsdelivr_nonce'; 37 37 38 38 // turn on/off debug mode 39 39 protected $debug = true; 40 40 41 41 protected $url; // plugin URL 42 42 protected $path; // plugin path 43 43 44 44 protected $enabled; 45 45 46 46 // internal values 47 47 const user_agent = 'jsDelivr WP CDN Plugin'; 48 48 const update_cdn_url = 'http://www.jsdelivr.com/hash.php'; 49 49 const timestamp_url = 'http://www.jsdelivr.com/timestamp.txt'; 50 50 51 51 private $cdn_baseurl = '//cdn.jsdelivr.net'; 52 52 53 53 // libs hosted by Google CDN 54 54 private $gcdn_baseurl = '//ajax.googleapis.com/ajax/libs'; … … 56 56 'jquery' => array( 57 57 'name' => 'jQuery', 58 'versions' => array( 58 'versions' => array( 59 59 // I added only versions up to 1.8.3, because it looks that many scripts are broken with jQuery version 1.9.x 60 60 '1.8.3', '1.8.2', '1.8.1', 61 '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', 62 '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', 61 '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', 62 '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', 63 63 '1.2.6', '1.2.3' 64 64 ), 65 'files' => array('jquery.js', 'jquery.min.js') 66 ) 65 'files' => array('jquery.js', 'jquery.min.js') 66 ) 67 67 ); 68 69 68 69 70 70 // skip URLs with string occurrence from the list below during scan 71 71 private $scan_skip_urls = array( … … 76 76 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'tif', 'xbm' 77 77 ); 78 78 79 79 function __construct() 80 { 80 { 81 81 // checks used protocol and set proper cdn base URL 82 82 /* ! I commented this because what if PHP handler is hidden via proxy server that supports HTTPS protocol, eg: 83 83 1. I have nginx as a router where is defined SSL certificate and requests are routed into apache server at port XY without SSL 84 84 2. again I have nginx, but I didn't use parameter "fastcgi_param" to pass HTTPS variable into PHP script 85 85 86 86 It should work correctly in way //example.com/some_file.js, so browser will choose correct scheme 87 87 */ … … 90 90 $this->cdn_baseurl = $protocol.':'.$this->cdn_baseurl; 91 91 */ 92 93 92 93 94 94 $this->enabled = get_option('jsdelivr_enabled', false); 95 95 96 96 if (is_admin()) 97 97 { 98 98 // load translation on plugins_loaded 99 99 add_action('plugins_loaded', array(&$this, 'plugins_loaded')); 100 100 101 101 $this->url = WP_PLUGIN_URL.'/'.dirname(plugin_basename(__FILE__)); 102 102 $this->path = WP_PLUGIN_DIR.'/'.dirname(plugin_basename(__FILE__)); 103 104 add_action('admin_menu', array(&$this, 'admin_menu')); 103 104 add_action('admin_menu', array(&$this, 'admin_menu')); 105 105 add_action('wp_ajax_jsdelivr_action', array(&$this, 'action')); 106 106 107 107 if ($this->debug) 108 add_action('wp_ajax_jsdelivr_action_debug', array(&$this, 'action_debug')); 109 110 108 add_action('wp_ajax_jsdelivr_action_debug', array(&$this, 'action_debug')); 109 110 111 111 // wp_cron action 112 112 add_action('jsdelivr_check_update', array(&$this, 'check_update_cdn')); 113 113 114 114 // show notice when update is available 115 115 if (!isset($_GET['cdn_update']) && get_option('jsdelivr_last_cdn_update', false) && … … 120 120 add_action('admin_notices', array(&$this, 'update_notice')); 121 121 } 122 122 123 123 // activation, deactivation and uninstall hooks 124 124 register_activation_hook(__FILE__, array(&$this, 'activation')); … … 130 130 add_action('init', array(&$this, 'init_onthefly'), 0); 131 131 } 132 132 133 133 // deactivation 134 134 function deactivation() 135 135 { 136 wp_clear_scheduled_hook('jsdelivr_check_update'); 137 } 138 136 wp_clear_scheduled_hook('jsdelivr_check_update'); 137 } 138 139 139 // install/activation 140 140 function activation() 141 { 141 { 142 142 global $wpdb; 143 143 … … 159 159 author varchar(255) COLLATE utf8_bin NOT NULL, 160 160 PRIMARY KEY (id) 161 );"; 162 161 );"; 162 163 163 $sql3 = "CREATE TABLE {$wpdb->jsd_files} ( 164 164 id bigint(20) unsigned NOT NULL AUTO_INCREMENT, … … 180 180 PRIMARY KEY (id) 181 181 );"; 182 182 183 183 require_once(ABSPATH.'wp-admin/includes/upgrade.php'); 184 dbDelta(array($sql1, $sql2, $sql3)); 185 184 dbDelta(array($sql1, $sql2, $sql3)); 185 186 186 if (!wp_next_scheduled('jsdelivr_check_update')) 187 187 wp_schedule_event(time(), 'daily', 'jsdelivr_check_update'); … … 192 192 { 193 193 global $wpdb; 194 194 195 195 $wpdb->query("DROP TABLE {$wpdb->jsd_cdnf}"); 196 196 $wpdb->query("DROP TABLE {$wpdb->jsd_cdnp}"); 197 197 $wpdb->query("DROP TABLE {$wpdb->jsd_files}"); 198 198 199 199 delete_option('jsdelivr_update_cdn_timestamp'); 200 200 delete_option('jsdelivr_last_cdn_update'); … … 203 203 delete_option('jsdelivr_update_notice_dismiss'); 204 204 } 205 205 206 206 // update notice at top of admin area 207 207 function update_notice() … … 209 209 require_once $this->path.'/backend/update_notice.php'; 210 210 } 211 211 212 212 // on plugins_loaded 213 213 function plugins_loaded() … … 215 215 // load text domain 216 216 load_plugin_textdomain(self::ld, false, $this->path.'/languages/'); 217 } 218 219 // add menu in Settings 217 } 218 219 // add menu in Settings 220 220 function admin_menu() 221 221 { 222 222 $hook = add_options_page(__('jsDelivr CDN', self::ld), __('jsDelivr CDN', self::ld), 'manage_options', 'jsdelivr', array(&$this, 'options_page')); 223 223 add_filter('plugin_action_links_'.plugin_basename(__FILE__), array(&$this, 'filter_plugin_actions'), 10, 2); 224 224 225 225 // add help tab 226 226 if (function_exists('get_current_screen')) … … 238 238 */ 239 239 } 240 241 add_action("admin_print_styles-$hook", array(&$this, 'add_admin_css')); 242 add_action("admin_print_scripts-$hook", array(&$this, 'add_admin_js')); 243 } 244 240 241 add_action("admin_print_styles-$hook", array(&$this, 'add_admin_css')); 242 add_action("admin_print_scripts-$hook", array(&$this, 'add_admin_js')); 243 } 244 245 245 // it's called when page is loaded 246 246 function admin_load() … … 248 248 // add help tab 249 249 $screen = get_current_screen(); 250 250 251 251 if (!method_exists($screen, 'add_help_tab')) 252 252 return; 253 253 254 254 // overview tab 255 255 /* 256 $screen->add_help_tab(array( 256 $screen->add_help_tab(array( 257 257 'id' => 'jsdelivr_overview', 258 258 'title' => __('Overview', self::ld), 259 'callback' => array(&$this, 'help_overview') 259 'callback' => array(&$this, 'help_overview') 260 260 )); 261 261 */ 262 263 // debug tab for developers 262 263 // debug tab for developers 264 264 if ($this->debug) 265 265 { 266 $screen->add_help_tab(array( 266 $screen->add_help_tab(array( 267 267 'id' => 'jsdelivr_debug', 268 268 'title' => __('Debug', self::ld), 269 'callback' => array(&$this, 'help_debug') 270 )); 271 } 272 } 273 269 'callback' => array(&$this, 'help_debug') 270 )); 271 } 272 } 273 274 274 //function help_overview() { require_once $this->path.'/backend/overview.php'; } 275 275 function help_debug() { require_once $this->path.'/backend/debug.php'; } 276 277 276 277 278 278 function add_admin_css() 279 279 { 280 280 wp_enqueue_style('thickbox'); 281 wp_enqueue_style('jsdelivr_styles', $this->url.'/backend/styles.css', array(), self::version, 'all'); 282 } 283 281 wp_enqueue_style('jsdelivr_styles', $this->url.'/backend/styles.css', array(), self::version, 'all'); 282 } 283 284 284 function add_admin_js() 285 285 { 286 286 wp_enqueue_script('jquery'); 287 287 wp_enqueue_script('thickbox'); 288 wp_enqueue_script('jquery.blockUI', $this->url.'/3rdparty/jquery.blockUI.js', array('jquery'), '2.42'); 289 wp_enqueue_script('jsdelivr', $this->url.'/backend/jsdelivr.js', array('jquery'), self::version, false); 288 wp_enqueue_script('jquery.blockUI', $this->url.'/3rdparty/jquery.blockUI.js', array('jquery'), '2.42'); 289 wp_enqueue_script('jsdelivr', $this->url.'/backend/jsdelivr.js', array('jquery'), self::version, false); 290 290 wp_localize_script('jsdelivr', 'jsdelivr_data', 291 291 array( … … 299 299 'error_update_cdn' => __('Error occured during update process.', self::ld) 300 300 ) 301 )); 302 } 303 301 )); 302 } 303 304 304 // menu Settings on Plugin page 305 305 function filter_plugin_actions($l, $file) 306 306 { 307 307 $settings_link = '<a href="options-general.php?page=jsdelivr">'.__('Settings').'</a>'; 308 array_unshift($l, $settings_link); 309 return $l; 310 } 311 308 array_unshift($l, $settings_link); 309 return $l; 310 } 311 312 312 // debug actions, available only if debug mode is activated 313 313 function action_debug() 314 314 { 315 315 $action = isset($_GET['jsd_action'])?$_GET['jsd_action']:false; 316 316 317 317 switch($action) 318 318 { … … 320 320 $this->check_update_cdn(); 321 321 break; 322 322 323 323 case 'reset': 324 324 global $wpdb; 325 325 $wpdb->query("TRUNCATE TABLE {$wpdb->jsd_cdnf}"); 326 326 $wpdb->query("TRUNCATE TABLE {$wpdb->jsd_cdnp}"); 327 $wpdb->query("TRUNCATE TABLE {$wpdb->jsd_files}"); 327 $wpdb->query("TRUNCATE TABLE {$wpdb->jsd_files}"); 328 328 delete_option('jsdelivr_update_cdn_timestamp'); 329 329 delete_option('jsdelivr_last_cdn_update'); 330 330 delete_option('jsdelivr_last_scan'); 331 331 delete_option('jsdelivr_enabled'); 332 delete_option('jsdelivr_update_notice_dismiss'); 332 delete_option('jsdelivr_update_notice_dismiss'); 333 333 break; 334 334 } 335 335 336 336 wp_redirect(admin_url('options-general.php?page=jsdelivr')); 337 337 exit; 338 338 } 339 339 340 340 // handle AJAX actions 341 341 function action() 342 342 { 343 343 if (!isset($_POST['jsd_action'])) return; 344 344 345 345 header("Content-Type: application/json"); 346 346 347 347 $message = false; 348 348 $r = false; 349 349 350 350 switch($_POST['jsd_action']) 351 351 { 352 case 'scan': 352 case 'scan': 353 353 try 354 354 { … … 359 359 $message = $e->getMessage(); 360 360 } 361 361 362 362 if ($r) 363 echo json_encode(array('status' => 1)); 363 echo json_encode(array('status' => 1)); 364 364 else 365 365 echo json_encode(array('status' => 2, 'message' => $message)); 366 366 367 367 break; 368 368 369 369 case 'update_cdn': 370 370 try … … 376 376 $message = $e->getMessage(); 377 377 } 378 378 379 379 if ($r) 380 echo json_encode(array('status' => 1)); 380 echo json_encode(array('status' => 1)); 381 381 else 382 echo json_encode(array('status' => 2, 'message' => $message)); 382 echo json_encode(array('status' => 2, 'message' => $message)); 383 383 break; 384 384 385 385 case 'dismiss_update_notice': 386 386 update_option('jsdelivr_update_notice_dismiss', true); 387 break; 388 } 389 387 break; 388 } 389 390 390 exit(); 391 391 } 392 392 393 393 // options page 394 394 function options_page() 395 395 { 396 global $wpdb; 396 global $wpdb; 397 397 $action_url = admin_url('options-general.php?page=jsdelivr'); 398 398 399 399 require_once $this->path.'/backend/top.php'; 400 400 401 401 // save options 402 402 if (isset($_POST['save_options']) && $_POST['save_options']) … … 406 406 die(__('Whoops! There was a problem with the data you posted. Please go back and try again.', self::ld)); 407 407 } 408 408 409 409 $ids = isset($_POST['ids'])?$_POST['ids']:array(); 410 410 $js_load = isset($_POST['js_load'])?$_POST['js_load']:array(); … … 412 412 $priority = isset($_POST['priority'])?$_POST['priority']:array(); 413 413 $enabled = isset($_POST['enabled'])?$_POST['enabled']:array(); 414 414 415 415 while(list(, $id) = @each($ids)) 416 416 { 417 417 $wpdb->query($wpdb->prepare(" 418 418 UPDATE {$wpdb->jsd_files} 419 SET enabled = %d, 420 footer = %d, 421 defer = %d, 422 async = %d, 419 SET enabled = %d, 420 footer = %d, 421 defer = %d, 422 async = %d, 423 423 priority = %d 424 424 WHERE id = %d 425 ", 425 ", 426 426 isset($enabled[$id])?1:0, 427 427 isset($move_footer[$id])?$move_footer[$id]:0, 428 428 isset($js_load[$id])?($js_load[$id]==2?1:0):0, 429 isset($js_load[$id])?($js_load[$id]==1?1:0):0, 430 isset($priority[$id])?$priority[$id]:0, 429 isset($js_load[$id])?($js_load[$id]==1?1:0):0, 430 isset($priority[$id])?$priority[$id]:0, 431 431 $id 432 432 )); 433 433 } 434 434 435 435 $this->enabled = isset($_POST['jsd_enabled'])?$_POST['jsd_enabled']:false; 436 436 update_option('jsdelivr_enabled', $this->enabled); 437 437 438 438 $this->generate_replace_data(); 439 439 440 440 // cache flush 441 441 $this->cache_flush(); 442 443 echo '<div class="updated"><p>'.__('Settings were sucessfully saved.', self::ld).'</p></div>'; 442 443 echo '<div class="updated"><p>'.__('Settings were sucessfully saved.', self::ld).'</p></div>'; 444 444 } 445 445 446 446 // get info about last cdn update/scan 447 447 $last_cdn_update = get_option('jsdelivr_last_cdn_update', false); 448 $last_scan = get_option('jsdelivr_last_scan', false); 449 448 $last_scan = get_option('jsdelivr_last_scan', false); 449 450 450 $files = $wpdb->get_results(" 451 451 SELECT files.id AS file_id, … … 469 469 cdn_packages.description AS cdn_description, 470 470 cdn_packages.homepage AS cdn_homepage, 471 cdn_packages.author AS cdn_author 471 cdn_packages.author AS cdn_author 472 472 FROM {$wpdb->jsd_files} AS files 473 473 LEFT JOIN {$wpdb->jsd_cdnf} AS cdn_files ON cdn_files.id = files.cdn_id … … 476 476 (files.match_status = 0 AND files.type = ".JSDT_JAVASCRIPT.") 477 477 ORDER BY files.match_status DESC, files.type DESC, cdn_packages.id ASC", ARRAY_A); 478 478 479 479 require_once $this->path.'/backend/options.php'; 480 480 } 481 481 482 482 // on the fly - buffer callback 483 483 function callback_onthefly($buffer) 484 { 484 { 485 485 $data_from = get_option('jsdelivr_data_from', false); 486 486 $data_to = get_option('jsdelivr_data_to', false); 487 487 488 488 if ($data_from && $data_to) 489 489 return str_replace($data_from, $data_to, $buffer); … … 491 491 return $buffer; 492 492 } 493 493 494 494 // on the fly - init function 495 495 function init_onthefly() 496 496 { 497 497 ob_start(array(&$this, 'callback_onthefly')); 498 } 499 498 } 499 500 500 // loads content of website at URL address 501 501 protected function get_content($url) … … 503 503 $handled = false; 504 504 $data = false; 505 505 506 506 if (function_exists('curl_init')) // CURL method 507 507 { … … 513 513 CURLOPT_USERAGENT => self::user_agent, 514 514 CURLOPT_HEADER => true, 515 CURLOPT_RETURNTRANSFER => true 515 CURLOPT_RETURNTRANSFER => true 516 516 )); 517 518 $data = curl_exec($ch); 517 518 $data = curl_exec($ch); 519 519 $delimiter = strpos($data, "\r\n\r\n"); 520 520 $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); … … 522 522 // handle redirect 523 523 if ($http_code == 301 || $http_code == 302) 524 { 524 { 525 525 $header = substr($data, 0, $delimiter); 526 526 $matches = array(); … … 528 528 $url = @parse_url(trim(array_pop($matches))); 529 529 if ($url) 530 { 531 $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); 530 { 531 $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); 532 532 if (!$url['scheme']) $url['scheme'] = $last_url['scheme']; 533 533 if (!$url['host']) $url['host'] = $last_url['host']; 534 if (!$url['path']) $url['path'] = $last_url['path']; 534 if (!$url['path']) $url['path'] = $last_url['path']; 535 535 $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (isset($url['query']) && $url['query']?'?'.$url['query']:''); 536 536 $data = $this->get_content($new_url); … … 539 539 else 540 540 $data = substr($data, $delimiter + 4, strlen($data) - $delimiter - 4); 541 541 542 542 $handled = true; 543 543 curl_close($ch); … … 551 551 { 552 552 $data = file_get_contents($url); 553 553 554 554 if ($data === false) 555 555 throw new jsdelivr_Exception(__('Cannot get content from remove server via function file_get_contents. Please check configuration of your server or install CURL.', self::ld)); 556 557 $handled = true; 556 557 $handled = true; 558 558 } 559 559 else // still we can try fsockopen 560 560 { 561 561 // get supported transports 562 $transports = stream_get_transports(); 562 $transports = stream_get_transports(); 563 563 if (in_array('tcp', $transports) && in_array('ssl', $transports)) 564 564 { 565 565 $url = parse_url($url); 566 566 $ssl = stripos($url['scheme'], 'https') !== false; 567 567 568 568 $f = fsockopen(($ssl?'ssl':'tcp').'://'.$url['host'], $ssl?443:80, $errno, $errstr); 569 569 if ($f) … … 574 574 $s.= "Connection: Close\r\n\r\n"; 575 575 fwrite($f, $s); 576 576 577 577 $output = ''; 578 578 while(!feof($f) && $line = fgets($f)) … … 580 580 581 581 fclose($f); 582 583 // check if it's redirect 582 583 // check if it's redirect 584 584 if (preg_match('/HTTP\/.{3} (301|302)/', $output)) 585 585 { … … 593 593 $data = substr($output, $delimiter + 4, strlen($output) - $delimiter - 4); 594 594 } 595 595 596 596 $handled = true; 597 } 598 } 599 } 600 } 601 597 } 598 } 599 } 600 } 601 602 602 if (!$handled) 603 603 throw new jsdelivr_Exception(__('Cannot get content from remote server. Please enable CURL or allow_url_fopen with appropriate wrappers or tcp/ssl transports on your server.', self::ld)); 604 605 return $data; 606 } 607 608 // check update CDN timestamp 604 605 return $data; 606 } 607 608 // check update CDN timestamp 609 609 function check_update_cdn() 610 610 { 611 611 $timestamp = trim($this->get_content(self::timestamp_url)); 612 612 613 613 if (!$timestamp) 614 614 return false; 615 615 616 616 if ($timestamp == get_option('jsdelivr_last_cdn_update', false) || 617 617 $timestamp == get_option('jsdelivr_update_cdn_timestamp', false)) … … 619 619 return false; 620 620 } 621 621 622 622 update_option('jsdelivr_update_cdn_timestamp', $timestamp); 623 623 update_option('jsdelivr_update_notice_dismiss', false); 624 return $timestamp; 625 } 626 624 return $timestamp; 625 } 626 627 627 // update data from CDN server 628 protected function update_cdn() 628 protected function update_cdn() 629 629 { 630 630 global $wpdb; 631 631 632 if (!$data = $this->get_content(self::update_cdn_url)) 632 if (!$data = $this->get_content(self::update_cdn_url)) 633 633 return false; 634 634 635 635 // truncate tables 636 $wpdb->query("TRUNCATE TABLE ".$wpdb->jsd_cdnp); 637 $wpdb->query("TRUNCATE TABLE ".$wpdb->jsd_cdnf); 638 636 $wpdb->query("TRUNCATE TABLE ".$wpdb->jsd_cdnp); 637 $wpdb->query("TRUNCATE TABLE ".$wpdb->jsd_cdnf); 638 639 639 $packages = json_decode($data, true); 640 640 … … 648 648 description = %s, 649 649 homepage = %s, 650 author = %s 650 author = %s 651 651 ", $package['name'], $package['zip'], $package['version'], $package['description'], 652 652 $package['homepage'], $package['author'])); 653 653 654 654 $insert_id = $wpdb->insert_id; 655 655 656 656 $sql_values = array(); 657 657 while(list($file_id, $file_name) = @each($package['files'])) 658 658 $sql_values[] = "($insert_id, '".$wpdb->escape($file_name)."', '".$wpdb->escape($package['hashes'][$file_id])."')"; 659 659 660 660 if (count($sql_values) > 0) 661 { 661 { 662 662 $sql = "INSERT INTO {$wpdb->jsd_cdnf} (`package_id`, `file`, `hash`) VALUES ".@implode(',', $sql_values); 663 663 $wpdb->query($sql); 664 } 665 } 666 664 } 665 } 666 667 667 if (!$timestamp = get_option('jsdelivr_update_cdn_timestamp', false)) 668 668 $timestamp = $this->check_update_cdn(); 669 669 670 670 update_option('jsdelivr_last_cdn_update', $timestamp); 671 671 672 672 $this->generate_replace_data(); 673 673 674 674 return true; 675 675 } 676 677 676 677 678 678 // preg_quote all values in array 679 679 function preg_quote_array($array) … … 681 681 foreach($array as $k => $v) 682 682 $array[$k] = preg_quote($v); 683 683 684 684 return $array; 685 685 } 686 686 687 687 // creates list of scripts and CSS links 688 688 protected function parse_html($data) … … 691 691 $ignore_list = '/'.@implode('|', self::preg_quote_array($this->scan_skip_urls)).'/i'; 692 692 $exts = $this->supported_image_exts; 693 693 694 694 if (preg_match_all('/(<link.[^>]*href\s*=\s*[\'"](.[^"\']+\.css)(\?ver=(.[^\'"]+?)|)[\'"].*?'.'>)|(<script.[^>]*src\s*=\s*[\'|"](.[^\?"\']+)(\?ver=(.[^\'"]+)|)[\'|"].*?<\/script>)|(<img.[^>]*src\s*=\s*[\'|"](.[^\'"]+\.('.implode('|', $exts).'))[\'"].*?'.'>)/is', $data, $o)) 695 { 695 { 696 696 $main_url = get_site_url().'/'; 697 $list = array(); 697 $list = array(); 698 698 while(list($k, $v) = @each($o[0])) 699 { 699 { 700 700 $url = trim($o[2][$k]?$o[2][$k]:($o[6][$k]?$o[6][$k]:($o[10][$k]?$o[10][$k]:''))); 701 701 702 702 // skip names listed in the ignore list 703 703 if (preg_match($ignore_list, $url)) continue; 704 704 705 705 $version = trim($o[4][$k]?$o[4][$k]:($o[8][$k]?$o[8][$k]:'')); 706 706 $file = str_replace($main_url, ABSPATH, $url); 707 708 $key = md5($url.$version); 707 708 $key = md5($url.$version); 709 709 if (isset($list[$key])) continue; 710 711 $hash = @md5_file($file); 712 710 711 $hash = @md5_file($file); 712 713 713 $list[$key] = array( 714 714 'type' => $o[1][$k]?JSDT_CSS:($o[5][$k]?JSDT_JAVASCRIPT:($o[10][$k]?JSDT_IMAGE:JSDT_UNKNOWN)), // 0- unknown, 1- css, 2- image,3- javascript … … 717 717 'file' => $file, 718 718 'rel_filename' => str_replace($main_url, '', $url), 719 'hash' => $hash?$hash:false, 719 'hash' => $hash?$hash:false, 720 720 'version' => $version 721 ); 722 } 723 return $list; 721 ); 722 } 723 return $list; 724 724 } 725 725 return array(); 726 726 } 727 727 728 728 // match for google hosted file 729 729 protected function match_gcdn($file, $version) … … 735 735 { 736 736 if (in_array($version, $data['versions'])) 737 $match = JSDM_FULL; 737 $match = JSDM_FULL; 738 738 else 739 739 $match = JSDM_MAYBE; 740 740 741 741 return array( 742 742 'name' => $name, 743 'match' => $match 743 'match' => $match 744 744 ); 745 745 } 746 746 } 747 return false; 748 } 749 747 return false; 748 } 749 750 750 // flush cache of 3rd party plugins 751 751 protected function cache_flush() … … 754 754 if (function_exists('w3tc_pgcache_flush')) 755 755 w3tc_pgcache_flush(); 756 756 757 757 // WP Super Cache 758 758 if (function_exists('wp_cache_clear_cache')) 759 759 wp_cache_clear_cache(); 760 761 } 762 760 761 } 762 763 763 // scan page and save script/css files into DB 764 764 protected function scan() 765 { 766 global $wpdb; 765 { 766 global $wpdb; 767 767 update_option('jsdelivr_enabled', false); 768 768 769 769 // get old settings 770 770 $r = $wpdb->get_results(" … … 772 772 FROM {$wpdb->jsd_files} 773 773 ", ARRAY_A); 774 774 775 775 $old_settings = array(); 776 776 while(list(, $l) = @each($r)) 777 777 $old_settings[$l['hash']] = $l; 778 779 778 779 780 780 // truncate table with files 781 781 $wpdb->query("TRUNCATE TABLE ".$wpdb->jsd_files); 782 782 783 783 $pages = array(); 784 $pages[] = get_bloginfo('home').'/'; // it can scan more URLs, but this is for testing 784 $pages[] = get_bloginfo('home').'/'; // it can scan more URLs, but this is for testing 785 785 786 786 // cache flush 787 787 $this->cache_flush(); 788 788 789 789 $html = ''; 790 790 while(list(, $page) = @each($pages)) 791 791 if ($c = $this->get_content($page)) 792 $html.= $c; 793 794 792 $html.= $c; 793 794 795 795 $list = $this->parse_html($html); 796 796 797 797 // prepare query and insert into DB 798 798 $sql_values = array(); … … 802 802 $version = $wpdb->escape($item['version']); 803 803 $hash = $wpdb->escape($item['hash']); 804 804 805 805 $cdn_id = 0; 806 806 $gcdn = ''; 807 807 808 808 if ($match = $this->match_gcdn($file_a, $item['version'])) 809 809 { 810 810 $gcdn = $match['name']; 811 $match_r = $match['match']; 811 $match_r = $match['match']; 812 812 } 813 813 else 814 814 { 815 // matching by CDN database 815 // matching by CDN database 816 816 $match = $wpdb->get_row(" 817 817 SELECT … … 822 822 '".$version."' != '' AND 823 823 cdn_packages.id = cdn_files.package_id 824 LIMIT 1 824 LIMIT 1 825 825 ) AS match_full, 826 826 (SELECT cdn_files.id 827 827 FROM {$wpdb->jsd_cdnf} AS cdn_files 828 828 WHERE (cdn_files.file LIKE '%/%".$file."' OR cdn_files.file = '".$file."') 829 LIMIT 1 829 LIMIT 1 830 830 ) AS match_filename, 831 831 (SELECT cdn_files.id 832 832 FROM {$wpdb->jsd_cdnf} AS cdn_files 833 833 WHERE cdn_files.hash = '".$hash."' 834 LIMIT 1 834 LIMIT 1 835 835 ) AS match_md5 836 836 ", ARRAY_A); 837 837 838 838 if (($match['match_md5']) || ($match['match_full'] && $item['type'] != JSDT_IMAGE)) // full match 839 839 { … … 843 843 else 844 844 if ($match['match_filename'] && ($item['type'] != JSDT_IMAGE)) // filenames are same, we are not sure if versions are correct 845 { 845 { 846 846 $cdn_id = $match['match_filename']; 847 847 $match_r = JSDM_MAYBE; … … 852 852 } 853 853 } 854 854 855 855 if ($old = $old_settings[$item['hash']]) 856 856 { … … 865 865 $enabled = $footer = $defer = $async = $priority = 0; 866 866 } 867 867 868 868 $sql_values[] = "(".$item['type'].", 869 869 '".$file."', … … 873 873 '".$wpdb->escape($item['url'])."', 874 874 '".$wpdb->escape($item['html'])."', 875 ".(int)$cdn_id.", '".$wpdb->escape($gcdn)."', ".(int)$match_r.", $enabled, $footer, $defer, $async, $priority)"; 876 } 877 875 ".(int)$cdn_id.", '".$wpdb->escape($gcdn)."', ".(int)$match_r.", $enabled, $footer, $defer, $async, $priority)"; 876 } 877 878 878 if (count($sql_values) > 0) 879 879 { 880 $sql = "INSERT INTO {$wpdb->jsd_files} 881 (`type`, `filename`, `full_filename`, `version`, `hash`, `url`, `html`, `cdn_id`, `gcdn`, `match_status`, `enabled`, `footer`, `defer`, `async`, `priority`) 880 $sql = "INSERT INTO {$wpdb->jsd_files} 881 (`type`, `filename`, `full_filename`, `version`, `hash`, `url`, `html`, `cdn_id`, `gcdn`, `match_status`, `enabled`, `footer`, `defer`, `async`, `priority`) 882 882 VALUES ".@implode(',', $sql_values); 883 883 884 $wpdb->query($sql); 885 } 884 $wpdb->query($sql); 885 } 886 886 887 887 update_option('jsdelivr_last_scan', time()); 888 888 update_option('jsdelivr_enabled', $this->enabled); 889 889 890 890 $this->generate_replace_data(); 891 891 892 892 // cache flush 893 893 $this->cache_flush(); 894 894 895 895 return true; 896 896 } 897 898 897 898 899 899 // get CDN enabled files 900 900 protected function get_enabled_files($only_with_options = false) 901 901 { 902 902 global $wpdb; 903 903 904 904 $w = ''; 905 905 if ($only_with_options) … … 907 907 $w = "AND (files.async = 1 OR files.defer = 1 OR files.footer > 1)"; 908 908 } 909 909 910 910 $r = $wpdb->get_results(" 911 911 SELECT files.type AS file_type, 912 912 files.filename AS file_filename, 913 files.url AS file_url, 913 files.url AS file_url, 914 914 files.full_filename AS file_full, 915 915 files.version AS file_version, … … 921 921 CONCAT('/', cdn_packages.name, '/', cdn_packages.version, '/', cdn_files.file) AS cdn_url_part 922 922 FROM {$wpdb->jsd_files} AS files 923 LEFT JOIN {$wpdb->jsd_cdnf} AS cdn_files ON cdn_files.id = files.cdn_id 924 LEFT JOIN {$wpdb->jsd_cdnp} AS cdn_packages ON cdn_packages.id = cdn_files.package_id 923 LEFT JOIN {$wpdb->jsd_cdnf} AS cdn_files ON cdn_files.id = files.cdn_id 924 LEFT JOIN {$wpdb->jsd_cdnp} AS cdn_packages ON cdn_packages.id = cdn_files.package_id 925 925 WHERE files.enabled = 1 AND 926 926 (files.cdn_id > 0 OR files.gcdn != '') 927 $w 927 $w 928 928 ORDER BY files.priority ASC 929 929 ", ARRAY_A); 930 return $r; 931 } 932 930 return $r; 931 } 932 933 933 // generate replace data for on-the-fly method 934 934 protected function generate_replace_data() 935 935 { 936 936 // get list of CDN enabled files from database 937 $r = $this->get_enabled_files(); 938 937 $r = $this->get_enabled_files(); 938 939 939 $header_from = array(); 940 940 $header_to = array(); … … 955 955 $options = " defer='defer'"; 956 956 } 957 957 958 958 if ($l['file_gcdn'] && isset($this->gcdn[$l['file_gcdn']])) 959 959 { … … 963 963 else 964 964 { 965 $url = $this->cdn_baseurl.$l['cdn_url_part']; 965 $url = $this->cdn_baseurl.$l['cdn_url_part']; 966 966 } 967 967 968 968 $script = "<script type='text/javascript'".$options." src='".$url."'></script>"; 969 969 970 970 if ($l['file_footer']) 971 971 { … … 991 991 $header_to[] = @implode(PHP_EOL, $footer).PHP_EOL.'</body>'; 992 992 } 993 993 994 994 update_option('jsdelivr_data_from', $header_from); 995 995 update_option('jsdelivr_data_to', $header_to); 996 997 return true; 998 } 999 996 997 return true; 998 } 999 1000 1000 protected function strip($t) 1001 1001 { 1002 1002 return htmlentities(stripslashes($t), ENT_COMPAT, 'UTF-8'); 1003 } 1003 } 1004 1004 } 1005 1005 1006 1006 new jsdelivr(); 1007 1007 } -
jsdelivr-wordpress-cdn-plugin/trunk/readme.txt
r669230 r750699 1 1 === jsDelivr - Wordpress CDN Plugin === 2 Contributors: jimaek,martinsuly 2 Contributors: jimaek,martinsuly 3 3 Donate link: http://www.jsdelivr.com 4 4 Tags: cdn,speed,jsdelivr,optimize,delivery,network,javascript,async,defer,performance, 5 5 Requires at least: 3.0 6 Tested up to: 3. 4.17 Stable tag: 0.2 6 Tested up to: 3.6 7 Stable tag: 0.2.1 8 8 9 9 The official plugin of jsDelivr.com, a free public CDN. An easy way to integrate the service and speed up your website using our super fast CDN. … … 62 62 Zero has the highest priority. So for example you can give to jQuery the priority 0 then to a plugin priority 1 and if the plugins has javascript addons then 2,3,4,5... 63 63 64 This ensures that there will be no problems with undeclared functions etc. 64 This ensures that there will be no problems with undeclared functions etc. 65 65 If you leave the priority as is then the files will be moved to footer with the same order they were originally declared. 66 66 … … 80 80 == Changelog == 81 81 82 = 0.2.1 = 83 * fixed issue caused by jQuery.blockUI plugin (updated to the newest version) 84 82 85 = 0.2 = 83 86 * Some misc. changes
Note: See TracChangeset
for help on using the changeset viewer.