WPide - Version 2.6

Version Description

  • 2022-04-26
  • Plugin acquired by XplodedThemes
  • A brand new and completely revamped version of WPide is coming soon, Stay tuned!
Download this release

Release Info

Developer xplodedthemes
Plugin Icon 128x128 WPide
Version 2.6
Comparing to
See all releases

Code changes from version 2.5 to 2.6

css/wpide.css CHANGED
@@ -543,6 +543,7 @@ div.ImageColorPickerWrapper {
543
  }
544
 
545
  #wpfooter {
 
546
  }
547
  #wpbody-content {
548
  padding-bottom: 0;
543
  }
544
 
545
  #wpfooter {
546
+ position:relative;
547
  }
548
  #wpbody-content {
549
  padding-bottom: 0;
index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- //Silence is golden.
1
+ <?php
2
+ //Silence is golden.
js/jquery.dd.js CHANGED
@@ -1,1044 +1,1044 @@
1
- // MSDropDown - jquery.dd.js
2
- // author: Marghoob Suleman - Search me on google
3
- // Date: 12th Aug, 2009, {18 Dec, 2010 (2.36)}
4
- // Version: 2.37 {date: 17 June, 2011}
5
- // Revision: 33
6
- // web: www.giftlelo.com | www.marghoobsuleman.com
7
- /*
8
- // msDropDown is free jQuery Plugin: you can redistribute it and/or modify
9
- // it under the terms of the either the MIT License or the Gnu General Public License (GPL) Version 2
10
- */
11
- ;(function($) {
12
-
13
- var msOldDiv = "";
14
- var dd = function(element, options)
15
- {
16
- var sElement = element;
17
- var $this = this; //parent this
18
- var options = $.extend({
19
- height:120,
20
- visibleRows:7,
21
- rowHeight:23,
22
- showIcon:true,
23
- zIndex:9999,
24
- mainCSS:'dd',
25
- useSprite:false,
26
- animStyle:'slideDown',
27
- onInit:'',
28
- style:''
29
- }, options);
30
- this.ddProp = new Object();//storing propeties;
31
- var oldSelectedValue = "";
32
- var actionSettings ={};
33
- actionSettings.insideWindow = true;
34
- actionSettings.keyboardAction = false;
35
- actionSettings.currentKey = null;
36
- var ddList = false;
37
- var config = {postElementHolder:'_msddHolder', postID:'_msdd', postTitleID:'_title',postTitleTextID:'_titletext',postChildID:'_child',postAID:'_msa',postOPTAID:'_msopta',postInputID:'_msinput', postArrowID:'_arrow', postInputhidden:'_inp'};
38
- var styles = {dd:options.mainCSS, ddTitle:'ddTitle', arrow:'arrow', ddChild:'ddChild', ddTitleText:'ddTitleText', disabled:.30, ddOutOfVision:'ddOutOfVision', borderTop:'borderTop', noBorderTop:'noBorderTop', selected:'selected'};
39
- var attributes = {actions:"focus,blur,change,click,dblclick,mousedown,mouseup,mouseover,mousemove,mouseout,keypress,keydown,keyup", prop:"size,multiple,disabled,tabindex"};
40
- this.onActions = new Object();
41
- var elementid = $(sElement).prop("id");
42
- if(typeof(elementid)=="undefined" || elementid.length<=0) {
43
- //assign and id;
44
- elementid = "msdrpdd"+$.msDropDown.counter++;//I guess it makes unique for the page.
45
- $(sElement).attr("id", elementid);
46
- };
47
- var inlineCSS = $(sElement).prop("style");
48
- options.style += (inlineCSS==undefined) ? "" : inlineCSS;
49
- var allOptions = $(sElement).children();
50
- ddList = ($(sElement).prop("size")>1 || $(sElement).prop("multiple")==true) ? true : false;
51
- if(ddList) {options.visibleRows = $(sElement).prop("size");};
52
- var a_array = {};//stores id, html & value etc
53
- var currentP = 0;
54
- var isFilter = false;
55
- var oldHeight;
56
- var cacheElement = {};
57
-
58
- var getElement = function(ele) {
59
- if(typeof(cacheElement[ele])=="undefined") {
60
- cacheElement[ele] = document.getElementById(ele);
61
- }
62
- return cacheElement[ele];
63
- };
64
- var getPostID = function (id) {
65
- return elementid+config[id];
66
- };
67
- var getOptionsProperties = function (option) {
68
- var currentOption = option;
69
- var styles = $(currentOption).prop("style");
70
- return styles;
71
- };
72
- var matchIndex = function (index) {
73
- var selectedIndex = $("#"+elementid+" option:selected");
74
- if(selectedIndex.length>1) {
75
- for(var i=0;i<selectedIndex.length;i++) {
76
- if(index == selectedIndex[i].index) {
77
- return true;
78
- };
79
- };
80
- } else if(selectedIndex.length==1) {
81
- if(selectedIndex[0].index==index) {
82
- return true;
83
- };
84
- };
85
- return false;
86
- };
87
- var createA = function(currentOptOption, current, currentopt, tp) {
88
- var aTag = "";
89
- //var aidfix = getPostID("postAID");
90
- var aidoptfix = (tp=="opt") ? getPostID("postOPTAID") : getPostID("postAID");
91
- var aid = (tp=="opt") ? aidoptfix+"_"+(current)+"_"+(currentopt) : aidoptfix+"_"+(current);
92
- var arrow = "";
93
- var clsName = "";
94
- if(options.useSprite!=false) {
95
- clsName = ' '+options.useSprite+' '+currentOptOption.className;
96
-
97
- } else {
98
- arrow = $(currentOptOption).prop("title");
99
- arrow = (arrow.length==0) ? "" : '<img src="'+arrow+'" align="absmiddle" /> ';
100
- };
101
- var sText = $(currentOptOption).text();
102
- var sValue = $(currentOptOption).val();
103
- var sEnabledClass = ($(currentOptOption).prop("disabled")==true) ? "disabled" : "enabled";
104
- a_array[aid] = {html:arrow + sText, value:sValue, text:sText, index:currentOptOption.index, id:aid};
105
- var innerStyle = getOptionsProperties(currentOptOption);
106
- if(matchIndex(currentOptOption.index)==true) {
107
- aTag += '<a href="javascript:void(0);" class="'+styles.selected+' '+sEnabledClass+clsName+'"';
108
- } else {
109
- aTag += '<a href="javascript:void(0);" class="'+sEnabledClass+clsName+'"';
110
- };
111
- if(innerStyle!==false && innerStyle!==undefined) {
112
- aTag += " style='"+innerStyle+"'";
113
- };
114
- aTag += ' id="'+aid+'">';
115
- aTag += arrow + '<span class="'+styles.ddTitleText+'">' +sText+'</span></a>';
116
- return aTag;
117
- };
118
- var in_array = function(t) {
119
- var sText = t.toLowerCase();
120
- if(sText.length==0) return -1;
121
- var a = "";
122
- for(var i in a_array) {
123
- var a_text = a_array[i].text.toLowerCase();
124
- if(a_text.substr(0, sText.length) == sText) {
125
- a += "#"+a_array[i].id+ ", ";
126
- };
127
- };
128
- return (a=="") ? -1 : a;
129
- };
130
- var createATags = function () {
131
- var childnodes = allOptions;
132
- if(childnodes.length==0) return "";
133
- var aTag = "";
134
- var aidfix = getPostID("postAID");
135
- var aidoptfix = getPostID("postOPTAID");
136
- childnodes.each(function(current){
137
- var currentOption = childnodes[current];
138
- //OPTGROUP
139
- if(currentOption.nodeName == "OPTGROUP") {
140
- aTag += "<div class='opta'>";
141
- aTag += "<span style='font-weight:bold;font-style:italic; clear:both;'>"+$(currentOption).prop("label")+"</span>";
142
- var optChild = $(currentOption).children();
143
- optChild.each(function(currentopt){
144
- var currentOptOption = optChild[currentopt];
145
- aTag += createA(currentOptOption, current, currentopt, "opt");
146
- });
147
- aTag += "</div>";
148
-
149
- } else {
150
- aTag += createA(currentOption, current, "", "");
151
- };
152
- });
153
- return aTag;
154
- };
155
- var createChildDiv = function () {
156
- var id = getPostID("postID");
157
- var childid = getPostID("postChildID");
158
- var sStyle = options.style;
159
- sDiv = "";
160
- sDiv += '<div id="'+childid+'" class="'+styles.ddChild+'"';
161
- if(!ddList) {
162
- sDiv += (sStyle!="") ? ' style="'+sStyle+'"' : '';
163
- } else {
164
- sDiv += (sStyle!="") ? ' style="border-top:1px solid #c3c3c3;display:block;position:relative;'+sStyle+'"' : '';
165
- };
166
- sDiv += '>';
167
- return sDiv;
168
- };
169
-
170
- var createTitleDiv = function () {
171
- var titleid = getPostID("postTitleID");
172
- var arrowid = getPostID("postArrowID");
173
- var titletextid = getPostID("postTitleTextID");
174
- var inputhidden = getPostID("postInputhidden");
175
- var sText = "";
176
- var arrow = "";
177
- if(getElement(elementid).options.length>0) {
178
- sText = $("#"+elementid+" option:selected").text();
179
- arrow = $("#"+elementid+" option:selected").prop("title");
180
- };
181
- arrow = (arrow.length==0 || arrow==undefined || options.showIcon==false || options.useSprite!=false) ? "" : '<img src="'+arrow+'" align="absmiddle" /> ';
182
- var sDiv = '<div id="'+titleid+'" class="'+styles.ddTitle+'"';
183
- sDiv += '>';
184
- sDiv += '<span id="'+arrowid+'" class="'+styles.arrow+'"></span><span class="'+styles.ddTitleText+'" id="'+titletextid+'">'+arrow + '<span class="'+styles.ddTitleText+'">'+sText+'</span></span></div>';
185
- return sDiv;
186
- };
187
- var applyEventsOnA = function() {
188
- var childid = getPostID("postChildID");
189
- $("#"+childid+ " a.enabled").unbind("click"); //remove old one
190
- $("#"+childid+ " a.enabled").bind("click", function(event) {
191
- event.preventDefault();
192
- manageSelection(this);
193
- setValue();
194
- if(!ddList) {
195
- $("#"+childid).unbind("mouseover");
196
- setInsideWindow(false);
197
- var sText = (options.showIcon==false) ? $(this).text() : $(this).html();
198
- setTitleText(sText);
199
- //$this.data("dd").close();
200
- $this.close();
201
- };
202
- //actionSettings.oldIndex = a_array[$($this).prop("id")].index;
203
- });
204
- };
205
- var createDropDown = function () {
206
- var changeInsertionPoint = false;
207
- var id = getPostID("postID");
208
- var titleid = getPostID("postTitleID");
209
- var titletextid = getPostID("postTitleTextID");
210
- var childid = getPostID("postChildID");
211
- var arrowid = getPostID("postArrowID");
212
- var iWidth = $("#"+elementid).width();
213
- iWidth = iWidth+2;//it always give -2 width; i dont know why
214
- var sStyle = options.style;
215
- if($("#"+id).length>0) {
216
- $("#"+id).remove();
217
- changeInsertionPoint = true;
218
- };
219
- var sDiv = '<div id="'+id+'" class="'+styles.dd+'"';
220
- sDiv += (sStyle!="") ? ' style="'+sStyle+'"' : '';
221
- sDiv += '>';
222
- //create title bar
223
- sDiv += createTitleDiv();
224
- //create child
225
- sDiv += createChildDiv();
226
- sDiv += createATags();
227
- sDiv += "</div>";
228
- sDiv += "</div>";
229
- if(changeInsertionPoint==true) {
230
- var sid =getPostID("postElementHolder");
231
- $("#"+sid).after(sDiv);
232
- } else {
233
- $("#"+elementid).after(sDiv);
234
- };
235
- if(ddList) {
236
- var titleid = getPostID("postTitleID");
237
- $("#"+titleid).hide();
238
- };
239
-
240
- $("#"+id).css("width", iWidth+"px");
241
- $("#"+childid).css("width", (iWidth-2)+"px");
242
- if(allOptions.length>options.visibleRows) {
243
- var margin = parseInt($("#"+childid+" a:first").css("padding-bottom")) + parseInt($("#"+childid+" a:first").css("padding-top"));
244
- var iHeight = ((options.rowHeight)*options.visibleRows) - margin;
245
- $("#"+childid).css("height", iHeight+"px");
246
- } else if(ddList) {
247
- var iHeight = $("#"+elementid).height();
248
- $("#"+childid).css("height", iHeight+"px");
249
- };
250
- //set out of vision
251
- if(changeInsertionPoint==false) {
252
- setOutOfVision();
253
- addRefreshMethods(elementid);
254
- };
255
- if($("#"+elementid).prop("disabled")==true) {
256
- $("#"+id).css("opacity", styles.disabled);
257
- };
258
- applyEvents();
259
- //add events
260
- //arrow hightlight
261
- $("#"+titleid).bind("mouseover", function(event) {
262
- hightlightArrow(1);
263
- });
264
- $("#"+titleid).bind("mouseout", function(event) {
265
- hightlightArrow(0);
266
- });
267
- //open close events
268
- applyEventsOnA();
269
- $("#"+childid+ " a.disabled").css("opacity", styles.disabled);
270
- //alert("ddList "+ddList)
271
- if(ddList) {
272
- $("#"+childid).bind("mouseover", function(event) {if(!actionSettings.keyboardAction) {
273
- actionSettings.keyboardAction = true;
274
- $(document).bind("keydown", function(event) {
275
- var keyCode = event.keyCode;
276
- actionSettings.currentKey = keyCode;
277
- if(keyCode==39 || keyCode==40) {
278
- //move to next
279
- event.preventDefault(); event.stopPropagation();
280
- next();
281
- setValue();
282
- };
283
- if(keyCode==37 || keyCode==38) {
284
- event.preventDefault(); event.stopPropagation();
285
- //move to previous
286
- previous();
287
- setValue();
288
- };
289
- });
290
-
291
- }});
292
- };
293
- $("#"+childid).bind("mouseout", function(event) {setInsideWindow(false);$(document).unbind("keydown");actionSettings.keyboardAction = false;actionSettings.currentKey=null;});
294
- $("#"+titleid).bind("click", function(event) {
295
- setInsideWindow(false);
296
- if($("#"+childid+":visible").length==1) {
297
- $("#"+childid).unbind("mouseover");
298
- } else {
299
- $("#"+childid).bind("mouseover", function(event) {setInsideWindow(true);});
300
- //alert("open "+elementid + $this);
301
- //$this.data("dd").openMe();
302
- $this.open();
303
- };
304
- });
305
- $("#"+titleid).bind("mouseout", function(evt) {
306
- setInsideWindow(false);
307
- });
308
- if(options.showIcon && options.useSprite!=false) {
309
- setTitleImageSprite();
310
- };
311
- };
312
- var getByIndex = function (index) {
313
- for(var i in a_array) {
314
- if(a_array[i].index==index) {
315
- return a_array[i];
316
- };
317
- };
318
- return -1;
319
- };
320
- var manageSelection = function (obj) {
321
- var childid = getPostID("postChildID");
322
- if($("#"+childid+ " a."+styles.selected).length==1) { //check if there is any selected
323
- oldSelectedValue = $("#"+childid+ " a."+styles.selected).text(); //i should have value here. but sometime value is missing
324
- //alert("oldSelectedValue "+oldSelectedValue);
325
- };
326
- if(!ddList) {
327
- $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
328
- };
329
- var selectedA = $("#"+childid + " a."+styles.selected).prop("id");
330
- if(selectedA!=undefined) {
331
- var oldIndex = (actionSettings.oldIndex==undefined || actionSettings.oldIndex==null) ? a_array[selectedA].index : actionSettings.oldIndex;
332
- };
333
- if(obj && !ddList) {
334
- $(obj).addClass(styles.selected);
335
- };
336
- if(ddList) {
337
- var keyCode = actionSettings.currentKey;
338
- if($("#"+elementid).prop("multiple")==true) {
339
- if(keyCode == 17) {
340
- //control
341
- actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
342
- $(obj).toggleClass(styles.selected);
343
- //multiple
344
- } else if(keyCode==16) {
345
- $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
346
- $(obj).addClass(styles.selected);
347
- //shift
348
- var currentSelected = $(obj).prop("id");
349
- var currentIndex = a_array[currentSelected].index;
350
- for(var i=Math.min(oldIndex, currentIndex);i<=Math.max(oldIndex, currentIndex);i++) {
351
- $("#"+getByIndex(i).id).addClass(styles.selected);
352
- };
353
- } else {
354
- $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
355
- $(obj).addClass(styles.selected);
356
- actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
357
- };
358
- } else {
359
- $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
360
- $(obj).addClass(styles.selected);
361
- actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
362
- };
363
- //isSingle
364
- };
365
- };
366
- var addRefreshMethods = function (id) {
367
- //deprecated
368
- var objid = id;
369
- getElement(objid).refresh = function(e) {
370
- $("#"+objid).msDropDown(options);
371
- };
372
- };
373
- var setInsideWindow = function (val) {
374
- actionSettings.insideWindow = val;
375
- };
376
- var getInsideWindow = function () {
377
- return actionSettings.insideWindow;
378
- //will work on this
379
- /*
380
- var childid = getPostID("postChildID");
381
- return ($("#"+childid + ":visible").length == 0) ? false : true;
382
- */
383
- };
384
- var applyEvents = function () {
385
- var mainid = getPostID("postID");
386
- var actions_array = attributes.actions.split(",");
387
- for(var iCount=0;iCount<actions_array.length;iCount++) {
388
- var action = actions_array[iCount];
389
- //var actionFound = $("#"+elementid).prop(action);
390
- var actionFound = has_handler(action);
391
- if(actionFound==true) {
392
- switch(action) {
393
- case "focus":
394
- $("#"+mainid).bind("mouseenter", function(event) {
395
- getElement(elementid).focus();
396
- //$("#"+elementid).focus();
397
- });
398
- break;
399
- case "click":
400
- $("#"+mainid).bind("click", function(event) {
401
- //getElement(elementid).onclick();
402
- $("#"+elementid).trigger("click");
403
- });
404
- break;
405
- case "dblclick":
406
- $("#"+mainid).bind("dblclick", function(event) {
407
- //getElement(elementid).ondblclick();
408
- $("#"+elementid).trigger("dblclick");
409
- });
410
- break;
411
- case "mousedown":
412
- $("#"+mainid).bind("mousedown", function(event) {
413
- //getElement(elementid).onmousedown();
414
- $("#"+elementid).trigger("mousedown");
415
- });
416
- break;
417
- case "mouseup":
418
- //has in close mthod
419
- $("#"+mainid).bind("mouseup", function(event) {
420
- //getElement(elementid).onmouseup();
421
- $("#"+elementid).trigger("mouseup");
422
- //setValue();
423
- });
424
- break;
425
- case "mouseover":
426
- $("#"+mainid).bind("mouseover", function(event) {
427
- //getElement(elementid).onmouseover();
428
- $("#"+elementid).trigger("mouseover");
429
- });
430
- break;
431
- case "mousemove":
432
- $("#"+mainid).bind("mousemove", function(event) {
433
- //getElement(elementid).onmousemove();
434
- $("#"+elementid).trigger("mousemove");
435
- });
436
- break;
437
- case "mouseout":
438
- $("#"+mainid).bind("mouseout", function(event) {
439
- //getElement(elementid).onmouseout();
440
- $("#"+elementid).trigger("mouseout");
441
- });
442
- break;
443
- };
444
- };
445
- };
446
-
447
- };
448
- var setOutOfVision = function () {
449
- var sId = getPostID("postElementHolder");
450
- $("#"+elementid).after("<div class='"+styles.ddOutOfVision+"' style='height:0px;overflow:hidden;position:absolute;' id='"+sId+"'></div>");
451
- $("#"+elementid).appendTo($("#"+sId));
452
- };
453
- var setTitleText = function (sText) {
454
- var titletextid = getPostID("postTitleTextID");
455
- $("#"+titletextid).html(sText);
456
- };
457
- var navigateA = function(w) {
458
- var where = w;
459
- var childid = getPostID("postChildID");
460
- var visibleA = $("#"+childid + " a:visible");
461
- var totalA = visibleA.length;
462
- var currentP = $("#"+childid +" a:visible").index($("#"+childid +" a.selected:visible"));
463
- var nextA;
464
- switch(where) {
465
- case "next":
466
- if(currentP < totalA-1) {
467
- currentP++;
468
- nextA = visibleA[currentP];
469
- };
470
- break;
471
- case "previous":
472
- if(currentP < totalA && currentP>0) {
473
- currentP--;
474
- nextA = visibleA[currentP];
475
- };
476
- break;
477
- };
478
- if(typeof(nextA)=="undefined") {
479
- return false;
480
- };
481
- $("#"+childid + " a."+styles.selected).removeClass(styles.selected);
482
- $(nextA).addClass(styles.selected);
483
- var selectedA = nextA.id;
484
- if(!ddList) {
485
- var sText = (options.showIcon==false) ? a_array[selectedA].text : $("#"+selectedA).html();
486
- setTitleText(sText);
487
- setTitleImageSprite(a_array[selectedA].index);
488
- };
489
- if(where=="next") {
490
- if(parseInt(($("#"+selectedA).position().top+$("#"+selectedA).height()))>=parseInt($("#"+childid).height())) {
491
- $("#"+childid).scrollTop(($("#"+childid).scrollTop())+$("#"+selectedA).height()+$("#"+selectedA).height());
492
- };
493
- } else {
494
- if(parseInt(($("#"+selectedA).position().top+$("#"+selectedA).height())) <=0) {
495
- $("#"+childid).scrollTop(($("#"+childid).scrollTop()-$("#"+childid).height())-$("#"+selectedA).height());
496
- };
497
- };
498
- };
499
-
500
- var setTitleImageSprite = function(i) {
501
- if(options.useSprite!=false) {
502
- var titletextid = getPostID("postTitleTextID");
503
- var index = (typeof(i)=="undefined") ? getElement(elementid).selectedIndex : i;
504
- var sClassName = getElement(elementid).options[index].className;
505
- if(sClassName.length>0) {
506
- var childid = getPostID("postChildID");
507
- var id = $("#"+childid + " a."+sClassName).prop("id");
508
- var backgroundImg = $("#"+id).css("background-image");
509
- var backgroundPosition = $("#"+id).css("background-position");
510
- var paddingLeft = $("#"+id).css("padding-left");
511
- if(backgroundImg!=undefined) {
512
- $("#"+titletextid).find("."+styles.ddTitleText).attr('style', "background:"+backgroundImg);
513
- };
514
- if(backgroundPosition!=undefined) {
515
- $("#"+titletextid).find("."+styles.ddTitleText).css('background-position', backgroundPosition);
516
- };
517
- if(paddingLeft!=undefined) {
518
- $("#"+titletextid).find("."+styles.ddTitleText).css('padding-left', paddingLeft);
519
- };
520
- $("#"+titletextid).find("."+styles.ddTitleText).css('background-repeat', 'no-repeat');
521
- $("#"+titletextid).find("."+styles.ddTitleText).css('padding-bottom', '2px');
522
- };
523
- };
524
- };
525
- var setValue = function () {
526
- //alert("setValue "+elementid);
527
- var childid = getPostID("postChildID");
528
- var allSelected = $("#"+childid + " a."+styles.selected);
529
- if(allSelected.length==1) {
530
- var sText = $("#"+childid + " a."+styles.selected).text();
531
- var selectedA = $("#"+childid + " a."+styles.selected).prop("id");
532
- if(selectedA!=undefined) {
533
- var sValue = a_array[selectedA].value;
534
- getElement(elementid).selectedIndex = a_array[selectedA].index;
535
- };
536
- //set image on title if using sprite
537
-
538
- if(options.showIcon && options.useSprite!=false)
539
- setTitleImageSprite();
540
- } else if(allSelected.length>1) {
541
- //var alls = $("#"+elementid +" > option:selected").removeprop("selected");
542
- for(var i=0;i<allSelected.length;i++) {
543
- var selectedA = $(allSelected[i]).prop("id");
544
- var index = a_array[selectedA].index;
545
- getElement(elementid).options[index].selected = "selected";
546
- };
547
- };
548
- //alert(getElement(elementid).selectedIndex);
549
- var sIndex = getElement(elementid).selectedIndex;
550
- $this.ddProp["selectedIndex"]= sIndex;
551
- //alert("selectedIndex "+ $this.ddProp["selectedIndex"] + " sIndex "+sIndex);
552
- };
553
- var has_handler = function (name) {
554
- // True if a handler has been added in the html.
555
- if ($("#"+elementid).prop("on" + name) != undefined) {
556
- return true;
557
- };
558
- // True if a handler has been added using jQuery.
559
- var evs = $("#"+elementid).data("events");
560
- if (evs && evs[name]) {
561
- return true;
562
- };
563
- return false;
564
- };
565
- var checkMethodAndApply = function () {
566
- var childid = getPostID("postChildID");
567
- if(has_handler('change')==true) {
568
- //alert(1);
569
- var currentSelectedValue = a_array[$("#"+childid +" a.selected").prop("id")].text;
570
- if($.trim(oldSelectedValue) !== $.trim(currentSelectedValue) && oldSelectedValue!==""){
571
- $("#"+elementid).trigger("change");
572
- };
573
- };
574
- if(has_handler('mouseup')==true) {
575
- $("#"+elementid).trigger("mouseup");
576
- };
577
- if(has_handler('blur')==true) {
578
- $(document).bind("mouseup", function(evt) {
579
- $("#"+elementid).focus();
580
- $("#"+elementid)[0].blur();
581
- setValue();
582
- $(document).unbind("mouseup");
583
- });
584
- };
585
- };
586
- var hightlightArrow = function(ison) {
587
- var arrowid = getPostID("postArrowID");
588
- if(ison==1)
589
- $("#"+arrowid).css({backgroundPosition:'0 100%'});
590
- else
591
- $("#"+arrowid).css({backgroundPosition:'0 0'});
592
- };
593
- var setOriginalProperties = function() {
594
- //properties = {};
595
- //alert($this.data("dd"));
596
- for(var i in getElement(elementid)) {
597
- if(typeof(getElement(elementid)[i])!='function' && getElement(elementid)[i]!==undefined && getElement(elementid)[i]!==null) {
598
- $this.set(i, getElement(elementid)[i], true);//true = setting local properties
599
- };
600
- };
601
- };
602
- var setValueByIndex = function(prop, val) {
603
- if(getByIndex(val) != -1) {
604
- getElement(elementid)[prop] = val;
605
- var childid = getPostID("postChildID");
606
- $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
607
- $("#"+getByIndex(val).id).addClass(styles.selected);
608
- var sText = getByIndex(getElement(elementid).selectedIndex).html;
609
- setTitleText(sText);
610
- };
611
- };
612
- var addRemoveFromIndex = function(i, action) {
613
- if(action=='d') {
614
- for(var key in a_array) {
615
- if(a_array[key].index == i) {
616
- delete a_array[key];
617
- break;
618
- };
619
- };
620
- };
621
- //update index
622
- var count = 0;
623
- for(var key in a_array) {
624
- a_array[key].index = count;
625
- count++;
626
- };
627
- };
628
- var shouldOpenOpposite = function() {
629
- var childid = getPostID("postChildID");
630
- var main = getPostID("postID");
631
- var pos = $("#"+main).position();
632
- var mH = $("#"+main).height();
633
- var wH = $(window).height();
634
- var st = $(window).scrollTop();
635
- var cH = $("#"+childid).height();
636
- var css = {zIndex:options.zIndex, top:(pos.top+mH)+"px", display:"none"};
637
- var ani = options.animStyle;
638
- var opp = false;
639
- var borderTop = styles.noBorderTop;
640
- $("#"+childid).removeClass(styles.noBorderTop);
641
- $("#"+childid).removeClass(styles.borderTop);
642
- if( (wH+st) < Math.floor(cH+mH+pos.top) ) {
643
- var tp = pos.top-cH;
644
- if((pos.top-cH)<0) {
645
- tp = 10;
646
- };
647
- css = {zIndex:options.zIndex, top:tp+"px", display:"none"};
648
- ani = "show";
649
- opp = true;
650
- borderTop = styles.borderTop;
651
- };
652
- return {opp:opp, ani:ani, css:css, border:borderTop};
653
- };
654
- var fireOpenEvent = function() {
655
- if($this.onActions["onOpen"]!=null) {
656
- eval($this.onActions["onOpen"])($this);
657
- };
658
- };
659
- var fireCloseEvent = function() {
660
- checkMethodAndApply();
661
- if($this.onActions["onClose"]!=null) {
662
- eval($this.onActions["onClose"])($this);
663
- };
664
- };
665
- /************* public methods *********************/
666
-
667
- this.next = function () {
668
- navigateA("next");
669
- };
670
- this.previous = function () {
671
- navigateA("previous");
672
- };
673
-
674
- this.open = function() {
675
- if(($this.get("disabled", true) == true) || ($this.get("options", true).length==0)) return;
676
- var childid = getPostID("postChildID");
677
- if(msOldDiv!="" && childid!=msOldDiv) {
678
- $("#"+msOldDiv).slideUp("fast");
679
- $("#"+msOldDiv).css({zIndex:'0'});
680
- };
681
-
682
- $(".dd").css("display", "block");
683
-
684
- if($("#"+childid).css("display")=="none") {
685
- oldSelectedValue = a_array[$("#"+childid +" a.selected").prop("id")].text;
686
- //keyboard action
687
- var sText ="";
688
- oldHeight = $("#"+childid).height();
689
- $("#"+childid +" a").show();
690
- $(document).bind("keydown", function(event) {
691
- var keyCode = event.keyCode;
692
- //alert("keyCode "+keyCode);
693
-
694
- if(keyCode==8) {
695
- event.preventDefault(); event.stopPropagation();
696
- //remove char
697
- sText = (sText.length==0) ? "" : sText.substr(0, sText.length-1);
698
- };
699
- switch(keyCode) {
700
- case 39:
701
- case 40:
702
- //move to next
703
- event.preventDefault(); event.stopPropagation();
704
- next();
705
- break;
706
- case 37:
707
- case 38:
708
- //move to previous
709
- event.preventDefault(); event.stopPropagation();
710
- previous();
711
- break;
712
- case 27:
713
- case 13:
714
- $this.close();
715
- setValue();
716
- break;
717
- default:
718
- if(keyCode>46) {
719
- sText += String.fromCharCode(keyCode);
720
- };
721
- var ind = in_array(sText);
722
- if(ind != -1) {
723
- $("#"+childid).css({height:'auto'});
724
- $("#"+childid +" a").hide();
725
- $(ind).show();
726
- var wf = shouldOpenOpposite();
727
- $("#"+childid).css(wf.css);
728
- $("#"+childid).css({display:'block'});
729
- } else {
730
- $("#"+childid +" a").show();
731
- $("#"+childid).css({height:oldHeight+'px'});
732
- };
733
- break;
734
- };
735
- if(has_handler("keydown")==true) {
736
- getElement(elementid).onkeydown();
737
- };
738
- });
739
-
740
- $(document).bind("keyup", function(event) {
741
- if($("#"+elementid).prop("onkeyup")!=undefined) {
742
- //$("#"+elementid).keyup();
743
- getElement(elementid).onkeyup();
744
- };
745
- });
746
- //end keyboard action
747
-
748
- //close onmouseup
749
- $(document).bind("mouseup", function(evt){
750
- if(getInsideWindow()==false) {
751
- //alert("evt.target: "+evt.target);
752
- //$this.data("dd").close();
753
- $this.close();
754
- };
755
- });
756
-
757
- //check open
758
- var wf = shouldOpenOpposite();
759
- $("#"+childid).css(wf.css);
760
- if(wf.opp==true) {
761
- $("#"+childid).css({display:'block'});
762
- $("#"+childid).addClass(wf.border);
763
- fireOpenEvent();
764
- } else {
765
- $("#"+childid)[wf.ani]("fast", function() {
766
- $("#"+childid).addClass(wf.border);
767
- fireOpenEvent();
768
- });
769
- };
770
- if(childid != msOldDiv) {
771
- msOldDiv = childid;
772
- };
773
- };
774
- };
775
- this.close = function() {
776
- var childid = getPostID("postChildID");
777
- var top = $("#"+getPostID("postTitleID")).position().top;
778
- var wf = shouldOpenOpposite();
779
- //var oldHeight = $("#"+childid).height();
780
- isFilter = false;
781
- if(wf.opp==true) {
782
- $("#"+childid).animate({
783
- height:0,
784
- top: top,
785
- }, function() {
786
- $("#"+childid).css({height:oldHeight+'px', display:'none'});
787
- fireCloseEvent();
788
- });
789
- }
790
- else {
791
- $("#"+childid).slideUp("fast", function(event) {
792
- fireCloseEvent();
793
- $("#"+childid).css({zIndex:'0'});
794
- $("#"+childid).css({height:oldHeight+'px'});
795
- });
796
- };
797
- setTitleImageSprite();
798
- $(document).unbind("keydown");
799
- $(document).unbind("keyup");
800
- $(document).unbind("mouseup");
801
-
802
- $(".dd").css("display", "none");
803
-
804
- };
805
- this.selectedIndex = function(i) {
806
- if(typeof(i)=="undefined") {
807
- return $this.get("selectedIndex");
808
- } else {
809
- $this.set("selectedIndex", i);
810
- };
811
- };
812
- this.debug = function(is) {
813
- if(typeof(is)=="undefined" || is==true) {
814
- $("."+styles.ddOutOfVision).removeAttr("style");
815
- } else {
816
- $("."+styles.ddOutOfVision).attr("style", "height:0px;overflow:hidden;position:absolute");
817
- };
818
- };
819
- //update properties
820
- this.set = function(prop, val, isLocal) {
821
- //alert("- set " + prop + " : "+val);
822
- if(prop==undefined || val==undefined) throw {message:"set to what?"};
823
- $this.ddProp[prop] = val;
824
- if(isLocal!=true) {
825
- switch(prop) {
826
- case "selectedIndex":
827
- setValueByIndex(prop, val);
828
- break;
829
- case "disabled":
830
- $this.disabled(val, true);
831
- break;
832
- case "multiple":
833
- getElement(elementid)[prop] = val;
834
- ddList = ($(sElement).prop("size")>0 || $(sElement).prop("multiple")==true) ? true : false;
835
- if(ddList) {
836
- //do something
837
- var iHeight = $("#"+elementid).height();
838
- var childid = getPostID("postChildID");
839
- $("#"+childid).css("height", iHeight+"px");
840
- //hide titlebar
841
- var titleid = getPostID("postTitleID");
842
- $("#"+titleid).hide();
843
- var childid = getPostID("postChildID");
844
- $("#"+childid).css({display:'block',position:'relative'});
845
- applyEventsOnA();
846
- };
847
- break;
848
- case "size":
849
- getElement(elementid)[prop] = val;
850
- if(val==0) {
851
- getElement(elementid).multiple = false;
852
- };
853
- ddList = ($(sElement).prop("size")>0 || $(sElement).prop("multiple")==true) ? true : false;
854
- if(val==0) {
855
- //show titlebar
856
- var titleid = getPostID("postTitleID");
857
- $("#"+titleid).show();
858
- var childid = getPostID("postChildID");
859
- $("#"+childid).css({display:'none',position:'absolute'});
860
- var sText = "";
861
- if(getElement(elementid).selectedIndex>=0) {
862
- var aObj = getByIndex(getElement(elementid).selectedIndex);
863
- sText = aObj.html;
864
- manageSelection($("#"+aObj.id));
865
- };
866
- setTitleText(sText);
867
- } else {
868
- //hide titlebar
869
- var titleid = getPostID("postTitleID");
870
- $("#"+titleid).hide();
871
- var childid = getPostID("postChildID");
872
- $("#"+childid).css({display:'block',position:'relative'});
873
- };
874
- break;
875
- default:
876
- try{
877
- //check if this is not a readonly properties
878
- getElement(elementid)[prop] = val;
879
- } catch(e) {
880
- //silent
881
- };
882
- break;
883
- };
884
- };
885
- //alert("get " + prop + " : "+$this.ddProp[prop]);
886
- //$this.set("selectedIndex", 0);
887
- };
888
- this.get = function(prop, forceRefresh) {
889
- if(prop==undefined && forceRefresh==undefined) {
890
- //alert("c1 : " +$this.ddProp);
891
- return $this.ddProp;
892
- };
893
- if(prop!=undefined && forceRefresh==undefined) {
894
- //alert("c2 : " +$this.ddProp[prop]);
895
- return ($this.ddProp[prop]!=undefined) ? $this.ddProp[prop] : null;
896
- };
897
- if(prop!=undefined && forceRefresh!=undefined) {
898
- //alert("c3 : " +getElement(elementid)[prop]);
899
- return getElement(elementid)[prop];
900
- };
901
- };
902
- this.visible = function(val) {
903
- var id = getPostID("postID");
904
- if(val==true) {
905
- $("#"+id).show();
906
- } else if(val==false) {
907
- $("#"+id).hide();
908
- } else {
909
- return $("#"+id).css("display");
910
- };
911
- };
912
- this.add = function(opt, index) {
913
- var objOpt = opt;
914
- var sText = objOpt.text;
915
- var sValue = (objOpt.value==undefined || objOpt.value==null) ? sText : objOpt.value;
916
- var img = (objOpt["title"]==undefined || objOpt["title"]==null) ? '' : objOpt["title"];
917
- var i = (index==undefined || index==null) ? getElement(elementid).options.length : index;
918
- getElement(elementid).options[i] = new Option(sText, sValue);
919
- if(img!='') getElement(elementid).options[i]["title"] = img;
920
- //check if exist
921
- var ifA = getByIndex(i);
922
- if(ifA != -1) {
923
- //replace
924
- var aTag = createA(getElement(elementid).options[i], i, "", "");
925
- $("#"+ifA.id).html(aTag);
926
- //a_array[key]
927
- } else {
928
- var aTag = createA(getElement(elementid).options[i], i, "", "");
929
- //add
930
- var childid = getPostID("postChildID");
931
- $("#"+childid).append(aTag);
932
- applyEventsOnA();
933
- };
934
- };
935
- this.remove = function(i) {
936
- getElement(elementid).remove(i);
937
- if((getByIndex(i))!= -1) { $("#"+getByIndex(i).id).remove();addRemoveFromIndex(i, 'd');};
938
- //alert("a" +a);
939
- if(getElement(elementid).length==0) {
940
- setTitleText("");
941
- } else {
942
- var sText = getByIndex(getElement(elementid).selectedIndex).html;
943
- setTitleText(sText);
944
- };
945
- $this.set("selectedIndex", getElement(elementid).selectedIndex);
946
- };
947
- this.disabled = function(dis, isLocal) {
948
- getElement(elementid).disabled = dis;
949
- //alert(getElement(elementid).disabled);
950
- var id = getPostID("postID");
951
- if(dis==true) {
952
- $("#"+id).css("opacity", styles.disabled);
953
- $this.close();
954
- } else if(dis==false) {
955
- $("#"+id).css("opacity", 1);
956
- };
957
- if(isLocal!=true) {
958
- $this.set("disabled", dis);
959
- };
960
- };
961
- //return form element
962
- this.form = function() {
963
- return (getElement(elementid).form == undefined) ? null : getElement(elementid).form;
964
- };
965
- this.item = function() {
966
- //index, subindex - use arguments.length
967
- if(arguments.length==1) {
968
- return getElement(elementid).item(arguments[0]);
969
- } else if(arguments.length==2) {
970
- return getElement(elementid).item(arguments[0], arguments[1]);
971
- } else {
972
- throw {message:"An index is required!"};
973
- };
974
- };
975
- this.namedItem = function(nm) {
976
- return getElement(elementid).namedItem(nm);
977
- };
978
- this.multiple = function(is) {
979
- if(typeof(is)=="undefined") {
980
- return $this.get("multiple");
981
- } else {
982
- $this.set("multiple", is);
983
- };
984
-
985
- };
986
- this.size = function(sz) {
987
- if(typeof(sz)=="undefined") {
988
- return $this.get("size");
989
- } else {
990
- $this.set("size", sz);
991
- };
992
- };
993
- this.addMyEvent = function(nm, fn) {
994
- $this.onActions[nm] = fn;
995
- };
996
- this.fireEvent = function(nm) {
997
- eval($this.onActions[nm])($this);
998
- };
999
- //end
1000
- var updateCommonVars = function() {
1001
- $this.set("version", $.msDropDown.version);
1002
- $this.set("author", $.msDropDown.author);
1003
- };
1004
- var init = function() {
1005
- //create wrapper
1006
- createDropDown();
1007
- //update propties
1008
- //alert("init");
1009
- setOriginalProperties();
1010
- updateCommonVars();
1011
- if(options.onInit!='') {
1012
- eval(options.onInit)($this);
1013
- };
1014
- };
1015
- init();
1016
- };
1017
- //static
1018
- $.msDropDown = {
1019
- version: 2.37,
1020
- author: "Marghoob Suleman",
1021
- counter:20,
1022
- create: function(id, opt) {
1023
- return $(id).msDropDown(opt).data("dd");
1024
- }
1025
- };
1026
- $.fn.extend({
1027
- msDropDown: function(options)
1028
- {
1029
- return this.each(function()
1030
- {
1031
- //if ($(this).data('dd')) return; // need to comment when using refresh method - will remove in next version
1032
- var mydropdown = new dd(this, options);
1033
- $(this).data('dd', mydropdown);
1034
- });
1035
- }
1036
- });
1037
- //fixed for prop
1038
- if(typeof($.fn.prop)=='undefined') {
1039
- $.fn.prop = function(w) {
1040
- return $(this).attr(w);
1041
- };
1042
- };
1043
-
1044
  })(jQuery);
1
+ // MSDropDown - jquery.dd.js
2
+ // author: Marghoob Suleman - Search me on google
3
+ // Date: 12th Aug, 2009, {18 Dec, 2010 (2.36)}
4
+ // Version: 2.37 {date: 17 June, 2011}
5
+ // Revision: 33
6
+ // web: www.giftlelo.com | www.marghoobsuleman.com
7
+ /*
8
+ // msDropDown is free jQuery Plugin: you can redistribute it and/or modify
9
+ // it under the terms of the either the MIT License or the Gnu General Public License (GPL) Version 2
10
+ */
11
+ ;(function($) {
12
+
13
+ var msOldDiv = "";
14
+ var dd = function(element, options)
15
+ {
16
+ var sElement = element;
17
+ var $this = this; //parent this
18
+ var options = $.extend({
19
+ height:120,
20
+ visibleRows:7,
21
+ rowHeight:23,
22
+ showIcon:true,
23
+ zIndex:9999,
24
+ mainCSS:'dd',
25
+ useSprite:false,
26
+ animStyle:'slideDown',
27
+ onInit:'',
28
+ style:''
29
+ }, options);
30
+ this.ddProp = new Object();//storing propeties;
31
+ var oldSelectedValue = "";
32
+ var actionSettings ={};
33
+ actionSettings.insideWindow = true;
34
+ actionSettings.keyboardAction = false;
35
+ actionSettings.currentKey = null;
36
+ var ddList = false;
37
+ var config = {postElementHolder:'_msddHolder', postID:'_msdd', postTitleID:'_title',postTitleTextID:'_titletext',postChildID:'_child',postAID:'_msa',postOPTAID:'_msopta',postInputID:'_msinput', postArrowID:'_arrow', postInputhidden:'_inp'};
38
+ var styles = {dd:options.mainCSS, ddTitle:'ddTitle', arrow:'arrow', ddChild:'ddChild', ddTitleText:'ddTitleText', disabled:.30, ddOutOfVision:'ddOutOfVision', borderTop:'borderTop', noBorderTop:'noBorderTop', selected:'selected'};
39
+ var attributes = {actions:"focus,blur,change,click,dblclick,mousedown,mouseup,mouseover,mousemove,mouseout,keypress,keydown,keyup", prop:"size,multiple,disabled,tabindex"};
40
+ this.onActions = new Object();
41
+ var elementid = $(sElement).prop("id");
42
+ if(typeof(elementid)=="undefined" || elementid.length<=0) {
43
+ //assign and id;
44
+ elementid = "msdrpdd"+$.msDropDown.counter++;//I guess it makes unique for the page.
45
+ $(sElement).attr("id", elementid);
46
+ };
47
+ var inlineCSS = $(sElement).prop("style");
48
+ options.style += (inlineCSS==undefined) ? "" : inlineCSS;
49
+ var allOptions = $(sElement).children();
50
+ ddList = ($(sElement).prop("size")>1 || $(sElement).prop("multiple")==true) ? true : false;
51
+ if(ddList) {options.visibleRows = $(sElement).prop("size");};
52
+ var a_array = {};//stores id, html & value etc
53
+ var currentP = 0;
54
+ var isFilter = false;
55
+ var oldHeight;
56
+ var cacheElement = {};
57
+
58
+ var getElement = function(ele) {
59
+ if(typeof(cacheElement[ele])=="undefined") {
60
+ cacheElement[ele] = document.getElementById(ele);
61
+ }
62
+ return cacheElement[ele];
63
+ };
64
+ var getPostID = function (id) {
65
+ return elementid+config[id];
66
+ };
67
+ var getOptionsProperties = function (option) {
68
+ var currentOption = option;
69
+ var styles = $(currentOption).prop("style");
70
+ return styles;
71
+ };
72
+ var matchIndex = function (index) {
73
+ var selectedIndex = $("#"+elementid+" option:selected");
74
+ if(selectedIndex.length>1) {
75
+ for(var i=0;i<selectedIndex.length;i++) {
76
+ if(index == selectedIndex[i].index) {
77
+ return true;
78
+ };
79
+ };
80
+ } else if(selectedIndex.length==1) {
81
+ if(selectedIndex[0].index==index) {
82
+ return true;
83
+ };
84
+ };
85
+ return false;
86
+ };
87
+ var createA = function(currentOptOption, current, currentopt, tp) {
88
+ var aTag = "";
89
+ //var aidfix = getPostID("postAID");
90
+ var aidoptfix = (tp=="opt") ? getPostID("postOPTAID") : getPostID("postAID");
91
+ var aid = (tp=="opt") ? aidoptfix+"_"+(current)+"_"+(currentopt) : aidoptfix+"_"+(current);
92
+ var arrow = "";
93
+ var clsName = "";
94
+ if(options.useSprite!=false) {
95
+ clsName = ' '+options.useSprite+' '+currentOptOption.className;
96
+
97
+ } else {
98
+ arrow = $(currentOptOption).prop("title");
99
+ arrow = (arrow.length==0) ? "" : '<img src="'+arrow+'" align="absmiddle" /> ';
100
+ };
101
+ var sText = $(currentOptOption).text();
102
+ var sValue = $(currentOptOption).val();
103
+ var sEnabledClass = ($(currentOptOption).prop("disabled")==true) ? "disabled" : "enabled";
104
+ a_array[aid] = {html:arrow + sText, value:sValue, text:sText, index:currentOptOption.index, id:aid};
105
+ var innerStyle = getOptionsProperties(currentOptOption);
106
+ if(matchIndex(currentOptOption.index)==true) {
107
+ aTag += '<a href="javascript:void(0);" class="'+styles.selected+' '+sEnabledClass+clsName+'"';
108
+ } else {
109
+ aTag += '<a href="javascript:void(0);" class="'+sEnabledClass+clsName+'"';
110
+ };
111
+ if(innerStyle!==false && innerStyle!==undefined) {
112
+ aTag += " style='"+innerStyle+"'";
113
+ };
114
+ aTag += ' id="'+aid+'">';
115
+ aTag += arrow + '<span class="'+styles.ddTitleText+'">' +sText+'</span></a>';
116
+ return aTag;
117
+ };
118
+ var in_array = function(t) {
119
+ var sText = t.toLowerCase();
120
+ if(sText.length==0) return -1;
121
+ var a = "";
122
+ for(var i in a_array) {
123
+ var a_text = a_array[i].text.toLowerCase();
124
+ if(a_text.substr(0, sText.length) == sText) {
125
+ a += "#"+a_array[i].id+ ", ";
126
+ };
127
+ };
128
+ return (a=="") ? -1 : a;
129
+ };
130
+ var createATags = function () {
131
+ var childnodes = allOptions;
132
+ if(childnodes.length==0) return "";
133
+ var aTag = "";
134
+ var aidfix = getPostID("postAID");
135
+ var aidoptfix = getPostID("postOPTAID");
136
+ childnodes.each(function(current){
137
+ var currentOption = childnodes[current];
138
+ //OPTGROUP
139
+ if(currentOption.nodeName == "OPTGROUP") {
140
+ aTag += "<div class='opta'>";
141
+ aTag += "<span style='font-weight:bold;font-style:italic; clear:both;'>"+$(currentOption).prop("label")+"</span>";
142
+ var optChild = $(currentOption).children();
143
+ optChild.each(function(currentopt){
144
+ var currentOptOption = optChild[currentopt];
145
+ aTag += createA(currentOptOption, current, currentopt, "opt");
146
+ });
147
+ aTag += "</div>";
148
+
149
+ } else {
150
+ aTag += createA(currentOption, current, "", "");
151
+ };
152
+ });
153
+ return aTag;
154
+ };
155
+ var createChildDiv = function () {
156
+ var id = getPostID("postID");
157
+ var childid = getPostID("postChildID");
158
+ var sStyle = options.style;
159
+ sDiv = "";
160
+ sDiv += '<div id="'+childid+'" class="'+styles.ddChild+'"';
161
+ if(!ddList) {
162
+ sDiv += (sStyle!="") ? ' style="'+sStyle+'"' : '';
163
+ } else {
164
+ sDiv += (sStyle!="") ? ' style="border-top:1px solid #c3c3c3;display:block;position:relative;'+sStyle+'"' : '';
165
+ };
166
+ sDiv += '>';
167
+ return sDiv;
168
+ };
169
+
170
+ var createTitleDiv = function () {
171
+ var titleid = getPostID("postTitleID");
172
+ var arrowid = getPostID("postArrowID");
173
+ var titletextid = getPostID("postTitleTextID");
174
+ var inputhidden = getPostID("postInputhidden");
175
+ var sText = "";
176
+ var arrow = "";
177
+ if(getElement(elementid).options.length>0) {
178
+ sText = $("#"+elementid+" option:selected").text();
179
+ arrow = $("#"+elementid+" option:selected").prop("title");
180
+ };
181
+ arrow = (arrow.length==0 || arrow==undefined || options.showIcon==false || options.useSprite!=false) ? "" : '<img src="'+arrow+'" align="absmiddle" /> ';
182
+ var sDiv = '<div id="'+titleid+'" class="'+styles.ddTitle+'"';
183
+ sDiv += '>';
184
+ sDiv += '<span id="'+arrowid+'" class="'+styles.arrow+'"></span><span class="'+styles.ddTitleText+'" id="'+titletextid+'">'+arrow + '<span class="'+styles.ddTitleText+'">'+sText+'</span></span></div>';
185
+ return sDiv;
186
+ };
187
+ var applyEventsOnA = function() {
188
+ var childid = getPostID("postChildID");
189
+ $("#"+childid+ " a.enabled").unbind("click"); //remove old one
190
+ $("#"+childid+ " a.enabled").bind("click", function(event) {
191
+ event.preventDefault();
192
+ manageSelection(this);
193
+ setValue();
194
+ if(!ddList) {
195
+ $("#"+childid).unbind("mouseover");
196
+ setInsideWindow(false);
197
+ var sText = (options.showIcon==false) ? $(this).text() : $(this).html();
198
+ setTitleText(sText);
199
+ //$this.data("dd").close();
200
+ $this.close();
201
+ };
202
+ //actionSettings.oldIndex = a_array[$($this).prop("id")].index;
203
+ });
204
+ };
205
+ var createDropDown = function () {
206
+ var changeInsertionPoint = false;
207
+ var id = getPostID("postID");
208
+ var titleid = getPostID("postTitleID");
209
+ var titletextid = getPostID("postTitleTextID");
210
+ var childid = getPostID("postChildID");
211
+ var arrowid = getPostID("postArrowID");
212
+ var iWidth = $("#"+elementid).width();
213
+ iWidth = iWidth+2;//it always give -2 width; i dont know why
214
+ var sStyle = options.style;
215
+ if($("#"+id).length>0) {
216
+ $("#"+id).remove();
217
+ changeInsertionPoint = true;
218
+ };
219
+ var sDiv = '<div id="'+id+'" class="'+styles.dd+'"';
220
+ sDiv += (sStyle!="") ? ' style="'+sStyle+'"' : '';
221
+ sDiv += '>';
222
+ //create title bar
223
+ sDiv += createTitleDiv();
224
+ //create child
225
+ sDiv += createChildDiv();
226
+ sDiv += createATags();
227
+ sDiv += "</div>";
228
+ sDiv += "</div>";
229
+ if(changeInsertionPoint==true) {
230
+ var sid =getPostID("postElementHolder");
231
+ $("#"+sid).after(sDiv);
232
+ } else {
233
+ $("#"+elementid).after(sDiv);
234
+ };
235
+ if(ddList) {
236
+ var titleid = getPostID("postTitleID");
237
+ $("#"+titleid).hide();
238
+ };
239
+
240
+ $("#"+id).css("width", iWidth+"px");
241
+ $("#"+childid).css("width", (iWidth-2)+"px");
242
+ if(allOptions.length>options.visibleRows) {
243
+ var margin = parseInt($("#"+childid+" a:first").css("padding-bottom")) + parseInt($("#"+childid+" a:first").css("padding-top"));
244
+ var iHeight = ((options.rowHeight)*options.visibleRows) - margin;
245
+ $("#"+childid).css("height", iHeight+"px");
246
+ } else if(ddList) {
247
+ var iHeight = $("#"+elementid).height();
248
+ $("#"+childid).css("height", iHeight+"px");
249
+ };
250
+ //set out of vision
251
+ if(changeInsertionPoint==false) {
252
+ setOutOfVision();
253
+ addRefreshMethods(elementid);
254
+ };
255
+ if($("#"+elementid).prop("disabled")==true) {
256
+ $("#"+id).css("opacity", styles.disabled);
257
+ };
258
+ applyEvents();
259
+ //add events
260
+ //arrow hightlight
261
+ $("#"+titleid).bind("mouseover", function(event) {
262
+ hightlightArrow(1);
263
+ });
264
+ $("#"+titleid).bind("mouseout", function(event) {
265
+ hightlightArrow(0);
266
+ });
267
+ //open close events
268
+ applyEventsOnA();
269
+ $("#"+childid+ " a.disabled").css("opacity", styles.disabled);
270
+ //alert("ddList "+ddList)
271
+ if(ddList) {
272
+ $("#"+childid).bind("mouseover", function(event) {if(!actionSettings.keyboardAction) {
273
+ actionSettings.keyboardAction = true;
274
+ $(document).bind("keydown", function(event) {
275
+ var keyCode = event.keyCode;
276
+ actionSettings.currentKey = keyCode;
277
+ if(keyCode==39 || keyCode==40) {
278
+ //move to next
279
+ event.preventDefault(); event.stopPropagation();
280
+ next();
281
+ setValue();
282
+ };
283
+ if(keyCode==37 || keyCode==38) {
284
+ event.preventDefault(); event.stopPropagation();
285
+ //move to previous
286
+ previous();
287
+ setValue();
288
+ };
289
+ });
290
+
291
+ }});
292
+ };
293
+ $("#"+childid).bind("mouseout", function(event) {setInsideWindow(false);$(document).unbind("keydown");actionSettings.keyboardAction = false;actionSettings.currentKey=null;});
294
+ $("#"+titleid).bind("click", function(event) {
295
+ setInsideWindow(false);
296
+ if($("#"+childid+":visible").length==1) {
297
+ $("#"+childid).unbind("mouseover");
298
+ } else {
299
+ $("#"+childid).bind("mouseover", function(event) {setInsideWindow(true);});
300
+ //alert("open "+elementid + $this);
301
+ //$this.data("dd").openMe();
302
+ $this.open();
303
+ };
304
+ });
305
+ $("#"+titleid).bind("mouseout", function(evt) {
306
+ setInsideWindow(false);
307
+ });
308
+ if(options.showIcon && options.useSprite!=false) {
309
+ setTitleImageSprite();
310
+ };
311
+ };
312
+ var getByIndex = function (index) {
313
+ for(var i in a_array) {
314
+ if(a_array[i].index==index) {
315
+ return a_array[i];
316
+ };
317
+ };
318
+ return -1;
319
+ };
320
+ var manageSelection = function (obj) {
321
+ var childid = getPostID("postChildID");
322
+ if($("#"+childid+ " a."+styles.selected).length==1) { //check if there is any selected
323
+ oldSelectedValue = $("#"+childid+ " a."+styles.selected).text(); //i should have value here. but sometime value is missing
324
+ //alert("oldSelectedValue "+oldSelectedValue);
325
+ };
326
+ if(!ddList) {
327
+ $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
328
+ };
329
+ var selectedA = $("#"+childid + " a."+styles.selected).prop("id");
330
+ if(selectedA!=undefined) {
331
+ var oldIndex = (actionSettings.oldIndex==undefined || actionSettings.oldIndex==null) ? a_array[selectedA].index : actionSettings.oldIndex;
332
+ };
333
+ if(obj && !ddList) {
334
+ $(obj).addClass(styles.selected);
335
+ };
336
+ if(ddList) {
337
+ var keyCode = actionSettings.currentKey;
338
+ if($("#"+elementid).prop("multiple")==true) {
339
+ if(keyCode == 17) {
340
+ //control
341
+ actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
342
+ $(obj).toggleClass(styles.selected);
343
+ //multiple
344
+ } else if(keyCode==16) {
345
+ $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
346
+ $(obj).addClass(styles.selected);
347
+ //shift
348
+ var currentSelected = $(obj).prop("id");
349
+ var currentIndex = a_array[currentSelected].index;
350
+ for(var i=Math.min(oldIndex, currentIndex);i<=Math.max(oldIndex, currentIndex);i++) {
351
+ $("#"+getByIndex(i).id).addClass(styles.selected);
352
+ };
353
+ } else {
354
+ $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
355
+ $(obj).addClass(styles.selected);
356
+ actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
357
+ };
358
+ } else {
359
+ $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
360
+ $(obj).addClass(styles.selected);
361
+ actionSettings.oldIndex = a_array[$(obj).prop("id")].index;
362
+ };
363
+ //isSingle
364
+ };
365
+ };
366
+ var addRefreshMethods = function (id) {
367
+ //deprecated
368
+ var objid = id;
369
+ getElement(objid).refresh = function(e) {
370
+ $("#"+objid).msDropDown(options);
371
+ };
372
+ };
373
+ var setInsideWindow = function (val) {
374
+ actionSettings.insideWindow = val;
375
+ };
376
+ var getInsideWindow = function () {
377
+ return actionSettings.insideWindow;
378
+ //will work on this
379
+ /*
380
+ var childid = getPostID("postChildID");
381
+ return ($("#"+childid + ":visible").length == 0) ? false : true;
382
+ */
383
+ };
384
+ var applyEvents = function () {
385
+ var mainid = getPostID("postID");
386
+ var actions_array = attributes.actions.split(",");
387
+ for(var iCount=0;iCount<actions_array.length;iCount++) {
388
+ var action = actions_array[iCount];
389
+ //var actionFound = $("#"+elementid).prop(action);
390
+ var actionFound = has_handler(action);
391
+ if(actionFound==true) {
392
+ switch(action) {
393
+ case "focus":
394
+ $("#"+mainid).bind("mouseenter", function(event) {
395
+ getElement(elementid).focus();
396
+ //$("#"+elementid).focus();
397
+ });
398
+ break;
399
+ case "click":
400
+ $("#"+mainid).bind("click", function(event) {
401
+ //getElement(elementid).onclick();
402
+ $("#"+elementid).trigger("click");
403
+ });
404
+ break;
405
+ case "dblclick":
406
+ $("#"+mainid).bind("dblclick", function(event) {
407
+ //getElement(elementid).ondblclick();
408
+ $("#"+elementid).trigger("dblclick");
409
+ });
410
+ break;
411
+ case "mousedown":
412
+ $("#"+mainid).bind("mousedown", function(event) {
413
+ //getElement(elementid).onmousedown();
414
+ $("#"+elementid).trigger("mousedown");
415
+ });
416
+ break;
417
+ case "mouseup":
418
+ //has in close mthod
419
+ $("#"+mainid).bind("mouseup", function(event) {
420
+ //getElement(elementid).onmouseup();
421
+ $("#"+elementid).trigger("mouseup");
422
+ //setValue();
423
+ });
424
+ break;
425
+ case "mouseover":
426
+ $("#"+mainid).bind("mouseover", function(event) {
427
+ //getElement(elementid).onmouseover();
428
+ $("#"+elementid).trigger("mouseover");
429
+ });
430
+ break;
431
+ case "mousemove":
432
+ $("#"+mainid).bind("mousemove", function(event) {
433
+ //getElement(elementid).onmousemove();
434
+ $("#"+elementid).trigger("mousemove");
435
+ });
436
+ break;
437
+ case "mouseout":
438
+ $("#"+mainid).bind("mouseout", function(event) {
439
+ //getElement(elementid).onmouseout();
440
+ $("#"+elementid).trigger("mouseout");
441
+ });
442
+ break;
443
+ };
444
+ };
445
+ };
446
+
447
+ };
448
+ var setOutOfVision = function () {
449
+ var sId = getPostID("postElementHolder");
450
+ $("#"+elementid).after("<div class='"+styles.ddOutOfVision+"' style='height:0px;overflow:hidden;position:absolute;' id='"+sId+"'></div>");
451
+ $("#"+elementid).appendTo($("#"+sId));
452
+ };
453
+ var setTitleText = function (sText) {
454
+ var titletextid = getPostID("postTitleTextID");
455
+ $("#"+titletextid).html(sText);
456
+ };
457
+ var navigateA = function(w) {
458
+ var where = w;
459
+ var childid = getPostID("postChildID");
460
+ var visibleA = $("#"+childid + " a:visible");
461
+ var totalA = visibleA.length;
462
+ var currentP = $("#"+childid +" a:visible").index($("#"+childid +" a.selected:visible"));
463
+ var nextA;
464
+ switch(where) {
465
+ case "next":
466
+ if(currentP < totalA-1) {
467
+ currentP++;
468
+ nextA = visibleA[currentP];
469
+ };
470
+ break;
471
+ case "previous":
472
+ if(currentP < totalA && currentP>0) {
473
+ currentP--;
474
+ nextA = visibleA[currentP];
475
+ };
476
+ break;
477
+ };
478
+ if(typeof(nextA)=="undefined") {
479
+ return false;
480
+ };
481
+ $("#"+childid + " a."+styles.selected).removeClass(styles.selected);
482
+ $(nextA).addClass(styles.selected);
483
+ var selectedA = nextA.id;
484
+ if(!ddList) {
485
+ var sText = (options.showIcon==false) ? a_array[selectedA].text : $("#"+selectedA).html();
486
+ setTitleText(sText);
487
+ setTitleImageSprite(a_array[selectedA].index);
488
+ };
489
+ if(where=="next") {
490
+ if(parseInt(($("#"+selectedA).position().top+$("#"+selectedA).height()))>=parseInt($("#"+childid).height())) {
491
+ $("#"+childid).scrollTop(($("#"+childid).scrollTop())+$("#"+selectedA).height()+$("#"+selectedA).height());
492
+ };
493
+ } else {
494
+ if(parseInt(($("#"+selectedA).position().top+$("#"+selectedA).height())) <=0) {
495
+ $("#"+childid).scrollTop(($("#"+childid).scrollTop()-$("#"+childid).height())-$("#"+selectedA).height());
496
+ };
497
+ };
498
+ };
499
+
500
+ var setTitleImageSprite = function(i) {
501
+ if(options.useSprite!=false) {
502
+ var titletextid = getPostID("postTitleTextID");
503
+ var index = (typeof(i)=="undefined") ? getElement(elementid).selectedIndex : i;
504
+ var sClassName = getElement(elementid).options[index].className;
505
+ if(sClassName.length>0) {
506
+ var childid = getPostID("postChildID");
507
+ var id = $("#"+childid + " a."+sClassName).prop("id");
508
+ var backgroundImg = $("#"+id).css("background-image");
509
+ var backgroundPosition = $("#"+id).css("background-position");
510
+ var paddingLeft = $("#"+id).css("padding-left");
511
+ if(backgroundImg!=undefined) {
512
+ $("#"+titletextid).find("."+styles.ddTitleText).attr('style', "background:"+backgroundImg);
513
+ };
514
+ if(backgroundPosition!=undefined) {
515
+ $("#"+titletextid).find("."+styles.ddTitleText).css('background-position', backgroundPosition);
516
+ };
517
+ if(paddingLeft!=undefined) {
518
+ $("#"+titletextid).find("."+styles.ddTitleText).css('padding-left', paddingLeft);
519
+ };
520
+ $("#"+titletextid).find("."+styles.ddTitleText).css('background-repeat', 'no-repeat');
521
+ $("#"+titletextid).find("."+styles.ddTitleText).css('padding-bottom', '2px');
522
+ };
523
+ };
524
+ };
525
+ var setValue = function () {
526
+ //alert("setValue "+elementid);
527
+ var childid = getPostID("postChildID");
528
+ var allSelected = $("#"+childid + " a."+styles.selected);
529
+ if(allSelected.length==1) {
530
+ var sText = $("#"+childid + " a."+styles.selected).text();
531
+ var selectedA = $("#"+childid + " a."+styles.selected).prop("id");
532
+ if(selectedA!=undefined) {
533
+ var sValue = a_array[selectedA].value;
534
+ getElement(elementid).selectedIndex = a_array[selectedA].index;
535
+ };
536
+ //set image on title if using sprite
537
+
538
+ if(options.showIcon && options.useSprite!=false)
539
+ setTitleImageSprite();
540
+ } else if(allSelected.length>1) {
541
+ //var alls = $("#"+elementid +" > option:selected").removeprop("selected");
542
+ for(var i=0;i<allSelected.length;i++) {
543
+ var selectedA = $(allSelected[i]).prop("id");
544
+ var index = a_array[selectedA].index;
545
+ getElement(elementid).options[index].selected = "selected";
546
+ };
547
+ };
548
+ //alert(getElement(elementid).selectedIndex);
549
+ var sIndex = getElement(elementid).selectedIndex;
550
+ $this.ddProp["selectedIndex"]= sIndex;
551
+ //alert("selectedIndex "+ $this.ddProp["selectedIndex"] + " sIndex "+sIndex);
552
+ };
553
+ var has_handler = function (name) {
554
+ // True if a handler has been added in the html.
555
+ if ($("#"+elementid).prop("on" + name) != undefined) {
556
+ return true;
557
+ };
558
+ // True if a handler has been added using jQuery.
559
+ var evs = $("#"+elementid).data("events");
560
+ if (evs && evs[name]) {
561
+ return true;
562
+ };
563
+ return false;
564
+ };
565
+ var checkMethodAndApply = function () {
566
+ var childid = getPostID("postChildID");
567
+ if(has_handler('change')==true) {
568
+ //alert(1);
569
+ var currentSelectedValue = a_array[$("#"+childid +" a.selected").prop("id")].text;
570
+ if($.trim(oldSelectedValue) !== $.trim(currentSelectedValue) && oldSelectedValue!==""){
571
+ $("#"+elementid).trigger("change");
572
+ };
573
+ };
574
+ if(has_handler('mouseup')==true) {
575
+ $("#"+elementid).trigger("mouseup");
576
+ };
577
+ if(has_handler('blur')==true) {
578
+ $(document).bind("mouseup", function(evt) {
579
+ $("#"+elementid).focus();
580
+ $("#"+elementid)[0].blur();
581
+ setValue();
582
+ $(document).unbind("mouseup");
583
+ });
584
+ };
585
+ };
586
+ var hightlightArrow = function(ison) {
587
+ var arrowid = getPostID("postArrowID");
588
+ if(ison==1)
589
+ $("#"+arrowid).css({backgroundPosition:'0 100%'});
590
+ else
591
+ $("#"+arrowid).css({backgroundPosition:'0 0'});
592
+ };
593
+ var setOriginalProperties = function() {
594
+ //properties = {};
595
+ //alert($this.data("dd"));
596
+ for(var i in getElement(elementid)) {
597
+ if(typeof(getElement(elementid)[i])!='function' && getElement(elementid)[i]!==undefined && getElement(elementid)[i]!==null) {
598
+ $this.set(i, getElement(elementid)[i], true);//true = setting local properties
599
+ };
600
+ };
601
+ };
602
+ var setValueByIndex = function(prop, val) {
603
+ if(getByIndex(val) != -1) {
604
+ getElement(elementid)[prop] = val;
605
+ var childid = getPostID("postChildID");
606
+ $("#"+childid+ " a."+styles.selected).removeClass(styles.selected);
607
+ $("#"+getByIndex(val).id).addClass(styles.selected);
608
+ var sText = getByIndex(getElement(elementid).selectedIndex).html;
609
+ setTitleText(sText);
610
+ };
611
+ };
612
+ var addRemoveFromIndex = function(i, action) {
613
+ if(action=='d') {
614
+ for(var key in a_array) {
615
+ if(a_array[key].index == i) {
616
+ delete a_array[key];
617
+ break;
618
+ };
619
+ };
620
+ };
621
+ //update index
622
+ var count = 0;
623
+ for(var key in a_array) {
624
+ a_array[key].index = count;
625
+ count++;
626
+ };
627
+ };
628
+ var shouldOpenOpposite = function() {
629
+ var childid = getPostID("postChildID");
630
+ var main = getPostID("postID");
631
+ var pos = $("#"+main).position();
632
+ var mH = $("#"+main).height();
633
+ var wH = $(window).height();
634
+ var st = $(window).scrollTop();
635
+ var cH = $("#"+childid).height();
636
+ var css = {zIndex:options.zIndex, top:(pos.top+mH)+"px", display:"none"};
637
+ var ani = options.animStyle;
638
+ var opp = false;
639
+ var borderTop = styles.noBorderTop;
640
+ $("#"+childid).removeClass(styles.noBorderTop);
641
+ $("#"+childid).removeClass(styles.borderTop);
642
+ if( (wH+st) < Math.floor(cH+mH+pos.top) ) {
643
+ var tp = pos.top-cH;
644
+ if((pos.top-cH)<0) {
645
+ tp = 10;
646
+ };
647
+ css = {zIndex:options.zIndex, top:tp+"px", display:"none"};
648
+ ani = "show";
649
+ opp = true;
650
+ borderTop = styles.borderTop;
651
+ };
652
+ return {opp:opp, ani:ani, css:css, border:borderTop};
653
+ };
654
+ var fireOpenEvent = function() {
655
+ if($this.onActions["onOpen"]!=null) {
656
+ eval($this.onActions["onOpen"])($this);
657
+ };
658
+ };
659
+ var fireCloseEvent = function() {
660
+ checkMethodAndApply();
661
+ if($this.onActions["onClose"]!=null) {
662
+ eval($this.onActions["onClose"])($this);
663
+ };
664
+ };
665
+ /************* public methods *********************/
666
+
667
+ this.next = function () {
668
+ navigateA("next");
669
+ };
670
+ this.previous = function () {
671
+ navigateA("previous");
672
+ };
673
+
674
+ this.open = function() {
675
+ if(($this.get("disabled", true) == true) || ($this.get("options", true).length==0)) return;
676
+ var childid = getPostID("postChildID");
677
+ if(msOldDiv!="" && childid!=msOldDiv) {
678
+ $("#"+msOldDiv).slideUp("fast");
679
+ $("#"+msOldDiv).css({zIndex:'0'});
680
+ };
681
+
682
+ $(".dd").css("display", "block");
683
+
684
+ if($("#"+childid).css("display")=="none") {
685
+ oldSelectedValue = a_array[$("#"+childid +" a.selected").prop("id")].text;
686
+ //keyboard action
687
+ var sText ="";
688
+ oldHeight = $("#"+childid).height();
689
+ $("#"+childid +" a").show();
690
+ $(document).bind("keydown", function(event) {
691
+ var keyCode = event.keyCode;
692
+ //alert("keyCode "+keyCode);
693
+
694
+ if(keyCode==8) {
695
+ event.preventDefault(); event.stopPropagation();
696
+ //remove char
697
+ sText = (sText.length==0) ? "" : sText.substr(0, sText.length-1);
698
+ };
699
+ switch(keyCode) {
700
+ case 39:
701
+ case 40:
702
+ //move to next
703
+ event.preventDefault(); event.stopPropagation();
704
+ next();
705
+ break;
706
+ case 37:
707
+ case 38:
708
+ //move to previous
709
+ event.preventDefault(); event.stopPropagation();
710
+ previous();
711
+ break;
712
+ case 27:
713
+ case 13:
714
+ $this.close();
715
+ setValue();
716
+ break;
717
+ default:
718
+ if(keyCode>46) {
719
+ sText += String.fromCharCode(keyCode);
720
+ };
721
+ var ind = in_array(sText);
722
+ if(ind != -1) {
723
+ $("#"+childid).css({height:'auto'});
724
+ $("#"+childid +" a").hide();
725
+ $(ind).show();
726
+ var wf = shouldOpenOpposite();
727
+ $("#"+childid).css(wf.css);
728
+ $("#"+childid).css({display:'block'});
729
+ } else {
730
+ $("#"+childid +" a").show();
731
+ $("#"+childid).css({height:oldHeight+'px'});
732
+ };
733
+ break;
734
+ };
735
+ if(has_handler("keydown")==true) {
736
+ getElement(elementid).onkeydown();
737
+ };
738
+ });
739
+
740
+ $(document).bind("keyup", function(event) {
741
+ if($("#"+elementid).prop("onkeyup")!=undefined) {
742
+ //$("#"+elementid).keyup();
743
+ getElement(elementid).onkeyup();
744
+ };
745
+ });
746
+ //end keyboard action
747
+
748
+ //close onmouseup
749
+ $(document).bind("mouseup", function(evt){
750
+ if(getInsideWindow()==false) {
751
+ //alert("evt.target: "+evt.target);
752
+ //$this.data("dd").close();
753
+ $this.close();
754
+ };
755
+ });
756
+
757
+ //check open
758
+ var wf = shouldOpenOpposite();
759
+ $("#"+childid).css(wf.css);
760
+ if(wf.opp==true) {
761
+ $("#"+childid).css({display:'block'});
762
+ $("#"+childid).addClass(wf.border);
763
+ fireOpenEvent();
764
+ } else {
765
+ $("#"+childid)[wf.ani]("fast", function() {
766
+ $("#"+childid).addClass(wf.border);
767
+ fireOpenEvent();
768
+ });
769
+ };
770
+ if(childid != msOldDiv) {
771
+ msOldDiv = childid;
772
+ };
773
+ };
774
+ };
775
+ this.close = function() {
776
+ var childid = getPostID("postChildID");
777
+ var top = $("#"+getPostID("postTitleID")).position().top;
778
+ var wf = shouldOpenOpposite();
779
+ //var oldHeight = $("#"+childid).height();
780
+ isFilter = false;
781
+ if(wf.opp==true) {
782
+ $("#"+childid).animate({
783
+ height:0,
784
+ top: top,
785
+ }, function() {
786
+ $("#"+childid).css({height:oldHeight+'px', display:'none'});
787
+ fireCloseEvent();
788
+ });
789
+ }
790
+ else {
791
+ $("#"+childid).slideUp("fast", function(event) {
792
+ fireCloseEvent();
793
+ $("#"+childid).css({zIndex:'0'});
794
+ $("#"+childid).css({height:oldHeight+'px'});
795
+ });
796
+ };
797
+ setTitleImageSprite();
798
+ $(document).unbind("keydown");
799
+ $(document).unbind("keyup");
800
+ $(document).unbind("mouseup");
801
+
802
+ $(".dd").css("display", "none");
803
+
804
+ };
805
+ this.selectedIndex = function(i) {
806
+ if(typeof(i)=="undefined") {
807
+ return $this.get("selectedIndex");
808
+ } else {
809
+ $this.set("selectedIndex", i);
810
+ };
811
+ };
812
+ this.debug = function(is) {
813
+ if(typeof(is)=="undefined" || is==true) {
814
+ $("."+styles.ddOutOfVision).removeAttr("style");
815
+ } else {
816
+ $("."+styles.ddOutOfVision).attr("style", "height:0px;overflow:hidden;position:absolute");
817
+ };
818
+ };
819
+ //update properties
820
+ this.set = function(prop, val, isLocal) {
821
+ //alert("- set " + prop + " : "+val);
822
+ if(prop==undefined || val==undefined) throw {message:"set to what?"};
823
+ $this.ddProp[prop] = val;
824
+ if(isLocal!=true) {
825
+ switch(prop) {
826
+ case "selectedIndex":
827
+ setValueByIndex(prop, val);
828
+ break;
829
+ case "disabled":
830
+ $this.disabled(val, true);
831
+ break;
832
+ case "multiple":
833
+ getElement(elementid)[prop] = val;
834
+ ddList = ($(sElement).prop("size")>0 || $(sElement).prop("multiple")==true) ? true : false;
835
+ if(ddList) {
836
+ //do something
837
+ var iHeight = $("#"+elementid).height();
838
+ var childid = getPostID("postChildID");
839
+ $("#"+childid).css("height", iHeight+"px");
840
+ //hide titlebar
841
+ var titleid = getPostID("postTitleID");
842
+ $("#"+titleid).hide();
843
+ var childid = getPostID("postChildID");
844
+ $("#"+childid).css({display:'block',position:'relative'});
845
+ applyEventsOnA();
846
+ };
847
+ break;
848
+ case "size":
849
+ getElement(elementid)[prop] = val;
850
+ if(val==0) {
851
+ getElement(elementid).multiple = false;
852
+ };
853
+ ddList = ($(sElement).prop("size")>0 || $(sElement).prop("multiple")==true) ? true : false;
854
+ if(val==0) {
855
+ //show titlebar
856
+ var titleid = getPostID("postTitleID");
857
+ $("#"+titleid).show();
858
+ var childid = getPostID("postChildID");
859
+ $("#"+childid).css({display:'none',position:'absolute'});
860
+ var sText = "";
861
+ if(getElement(elementid).selectedIndex>=0) {
862
+ var aObj = getByIndex(getElement(elementid).selectedIndex);
863
+ sText = aObj.html;
864
+ manageSelection($("#"+aObj.id));
865
+ };
866
+ setTitleText(sText);
867
+ } else {
868
+ //hide titlebar
869
+ var titleid = getPostID("postTitleID");
870
+ $("#"+titleid).hide();
871
+ var childid = getPostID("postChildID");
872
+ $("#"+childid).css({display:'block',position:'relative'});
873
+ };
874
+ break;
875
+ default:
876
+ try{
877
+ //check if this is not a readonly properties
878
+ getElement(elementid)[prop] = val;
879
+ } catch(e) {
880
+ //silent
881
+ };
882
+ break;
883
+ };
884
+ };
885
+ //alert("get " + prop + " : "+$this.ddProp[prop]);
886
+ //$this.set("selectedIndex", 0);
887
+ };
888
+ this.get = function(prop, forceRefresh) {
889
+ if(prop==undefined && forceRefresh==undefined) {
890
+ //alert("c1 : " +$this.ddProp);
891
+ return $this.ddProp;
892
+ };
893
+ if(prop!=undefined && forceRefresh==undefined) {
894
+ //alert("c2 : " +$this.ddProp[prop]);
895
+ return ($this.ddProp[prop]!=undefined) ? $this.ddProp[prop] : null;
896
+ };
897
+ if(prop!=undefined && forceRefresh!=undefined) {
898
+ //alert("c3 : " +getElement(elementid)[prop]);
899
+ return getElement(elementid)[prop];
900
+ };
901
+ };
902
+ this.visible = function(val) {
903
+ var id = getPostID("postID");
904
+ if(val==true) {
905
+ $("#"+id).show();
906
+ } else if(val==false) {
907
+ $("#"+id).hide();
908
+ } else {
909
+ return $("#"+id).css("display");
910
+ };
911
+ };
912
+ this.add = function(opt, index) {
913
+ var objOpt = opt;
914
+ var sText = objOpt.text;
915
+ var sValue = (objOpt.value==undefined || objOpt.value==null) ? sText : objOpt.value;
916
+ var img = (objOpt["title"]==undefined || objOpt["title"]==null) ? '' : objOpt["title"];
917
+ var i = (index==undefined || index==null) ? getElement(elementid).options.length : index;
918
+ getElement(elementid).options[i] = new Option(sText, sValue);
919
+ if(img!='') getElement(elementid).options[i]["title"] = img;
920
+ //check if exist
921
+ var ifA = getByIndex(i);
922
+ if(ifA != -1) {
923
+ //replace
924
+ var aTag = createA(getElement(elementid).options[i], i, "", "");
925
+ $("#"+ifA.id).html(aTag);
926
+ //a_array[key]
927
+ } else {
928
+ var aTag = createA(getElement(elementid).options[i], i, "", "");
929
+ //add
930
+ var childid = getPostID("postChildID");
931
+ $("#"+childid).append(aTag);
932
+ applyEventsOnA();
933
+ };
934
+ };
935
+ this.remove = function(i) {
936
+ getElement(elementid).remove(i);
937
+ if((getByIndex(i))!= -1) { $("#"+getByIndex(i).id).remove();addRemoveFromIndex(i, 'd');};
938
+ //alert("a" +a);
939
+ if(getElement(elementid).length==0) {
940
+ setTitleText("");
941
+ } else {
942
+ var sText = getByIndex(getElement(elementid).selectedIndex).html;
943
+ setTitleText(sText);
944
+ };
945
+ $this.set("selectedIndex", getElement(elementid).selectedIndex);
946
+ };
947
+ this.disabled = function(dis, isLocal) {
948
+ getElement(elementid).disabled = dis;
949
+ //alert(getElement(elementid).disabled);
950
+ var id = getPostID("postID");
951
+ if(dis==true) {
952
+ $("#"+id).css("opacity", styles.disabled);
953
+ $this.close();
954
+ } else if(dis==false) {
955
+ $("#"+id).css("opacity", 1);
956
+ };
957
+ if(isLocal!=true) {
958
+ $this.set("disabled", dis);
959
+ };
960
+ };
961
+ //return form element
962
+ this.form = function() {
963
+ return (getElement(elementid).form == undefined) ? null : getElement(elementid).form;
964
+ };
965
+ this.item = function() {
966
+ //index, subindex - use arguments.length
967
+ if(arguments.length==1) {
968
+ return getElement(elementid).item(arguments[0]);
969
+ } else if(arguments.length==2) {
970
+ return getElement(elementid).item(arguments[0], arguments[1]);
971
+ } else {
972
+ throw {message:"An index is required!"};
973
+ };
974
+ };
975
+ this.namedItem = function(nm) {
976
+ return getElement(elementid).namedItem(nm);
977
+ };
978
+ this.multiple = function(is) {
979
+ if(typeof(is)=="undefined") {
980
+ return $this.get("multiple");
981
+ } else {
982
+ $this.set("multiple", is);
983
+ };
984
+
985
+ };
986
+ this.size = function(sz) {
987
+ if(typeof(sz)=="undefined") {
988
+ return $this.get("size");
989
+ } else {
990
+ $this.set("size", sz);
991
+ };
992
+ };
993
+ this.addMyEvent = function(nm, fn) {
994
+ $this.onActions[nm] = fn;
995
+ };
996
+ this.fireEvent = function(nm) {
997
+ eval($this.onActions[nm])($this);
998
+ };
999
+ //end
1000
+ var updateCommonVars = function() {
1001
+ $this.set("version", $.msDropDown.version);
1002
+ $this.set("author", $.msDropDown.author);
1003
+ };
1004
+ var init = function() {
1005
+ //create wrapper
1006
+ createDropDown();
1007
+ //update propties
1008
+ //alert("init");
1009
+ setOriginalProperties();
1010
+ updateCommonVars();
1011
+ if(options.onInit!='') {
1012
+ eval(options.onInit)($this);
1013
+ };
1014
+ };
1015
+ init();
1016
+ };
1017
+ //static
1018
+ $.msDropDown = {
1019
+ version: 2.37,
1020
+ author: "Marghoob Suleman",
1021
+ counter:20,
1022
+ create: function(id, opt) {
1023
+ return $(id).msDropDown(opt).data("dd");
1024
+ }
1025
+ };
1026
+ $.fn.extend({
1027
+ msDropDown: function(options)
1028
+ {
1029
+ return this.each(function()
1030
+ {
1031
+ //if ($(this).data('dd')) return; // need to comment when using refresh method - will remove in next version
1032
+ var mydropdown = new dd(this, options);
1033
+ $(this).data('dd', mydropdown);
1034
+ });
1035
+ }
1036
+ });
1037
+ //fixed for prop
1038
+ if(typeof($.fn.prop)=='undefined') {
1039
+ $.fn.prop = function(w) {
1040
+ return $(this).attr(w);
1041
+ };
1042
+ };
1043
+
1044
  })(jQuery);
js/jquery.dd.js.minified.js CHANGED
@@ -1,11 +1,11 @@
1
- // MSDropDown - jquery.dd.js
2
- // author: Marghoob Suleman - Search me on google
3
- // Date: 12th Aug, 2009, {18 Dec, 2010 (2.36)}
4
- // Version: 2.37 {date: 17 June, 2011}
5
- // Revision: 33
6
- // web: www.giftlelo.com | www.marghoobsuleman.com
7
- /*
8
- // msDropDown is free jQuery Plugin: you can redistribute it and/or modify
9
- // it under the terms of the either the MIT License or the Gnu General Public License (GPL) Version 2
10
- */
11
  ;eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(5($){3 1L="";3 3m=5(p,q){3 r=p;3 s=1a;3 q=$.3n({1d:4c,2q:7,3o:23,1U:6,1M:4d,3p:\'28\',1N:15,3q:\'4e\',2I:\'\',1j:\'\'},q);1a.1V=2r 3r();3 u="";3 v={};v.2J=6;v.2s=15;v.2t=1o;3 x=15;3 y={2K:\'4f\',1O:\'4g\',1H:\'4h\',29:\'4i\',1h:\'4j\',2L:\'4k\',2M:\'4l\',4m:\'4n\',2u:\'4o\',3s:\'4p\'};3 z={28:q.3p,2N:\'2N\',2O:\'2O\',2P:\'2P\',1t:\'1t\',1k:.30,2a:\'2a\',2v:\'2v\',2w:\'2w\',11:\'11\'};3 A={3t:"2x,2Q,2R,1P,2y,2z,1u,1B,2A,1Q,4q,1W,2S",18:"1C,1v,1k,4r"};1a.1R=2r 3r();3 B=$(r).18("1b");4(1w(B)=="14"||B.1c<=0){B="4s"+$.1S.3u++;$(r).2B("1b",B)};3 C=$(r).18("1j");q.1j+=(C==14)?"":C;3 D=$(r).3v();x=($(r).18("1C")>1||$(r).18("1v")==6)?6:15;4(x){q.2q=$(r).18("1C")};3 E={};3 F=0;3 G=15;3 H;3 I={};3 J=5(a){4(1w(I[a])=="14"){I[a]=1p.4t(a)}12 I[a]};3 K=5(a){12 B+y[a]};3 L=5(a){3 b=a;3 c=$(b).18("1j");12 c};3 M=5(a){3 b=$("#"+B+" 2T:11");4(b.1c>1){1D(3 i=0;i<b.1c;i++){4(a==b[i].1i){12 6}}}19 4(b.1c==1){4(b[0].1i==a){12 6}};12 15};3 N=5(a,b,c,d){3 e="";3 f=(d=="2U")?K("2M"):K("2L");3 g=(d=="2U")?f+"2V"+(b)+"2V"+(c):f+"2V"+(b);3 h="";3 i="";4(q.1N!=15){i=\' \'+q.1N+\' \'+a.3w}19{h=$(a).18("1X");h=(h.1c==0)?"":\'<3x 3y="\'+h+\'" 3z="3A" /> \'};3 j=$(a).1q();3 k=$(a).4u();3 l=($(a).18("1k")==6)?"1k":"2W";E[g]={1I:h+j,2b:k,1q:j,1i:a.1i,1b:g};3 m=L(a);4(M(a.1i)==6){e+=\'<a 3B="3C:3D(0);" 1r="\'+z.11+\' \'+l+i+\'"\'}19{e+=\'<a 3B="3C:3D(0);" 1r="\'+l+i+\'"\'};4(m!==15&&m!==14){e+=" 1j=\'"+m+"\'"};e+=\' 1b="\'+g+\'">\';e+=h+\'<1x 1r="\'+z.1t+\'">\'+j+\'</1x></a>\';12 e};3 O=5(t){3 b=t.3E();4(b.1c==0)12-1;3 a="";1D(3 i 2c E){3 c=E[i].1q.3E();4(c.3F(0,b.1c)==b){a+="#"+E[i].1b+", "}};12(a=="")?-1:a};3 P=5(){3 f=D;4(f.1c==0)12"";3 g="";3 h=K("2L");3 i=K("2M");f.2X(5(c){3 d=f[c];4(d.4v=="4w"){g+="<1y 1r=\'4x\'>";g+="<1x 1j=\'3G-4y:4z;3G-1j:4A; 4B:4C;\'>"+$(d).18("4D")+"</1x>";3 e=$(d).3v();e.2X(5(a){3 b=e[a];g+=N(b,c,a,"2U")});g+="</1y>"}19{g+=N(d,c,"","")}});12 g};3 Q=5(){3 a=K("1O");3 b=K("1h");3 c=q.1j;1Y="";1Y+=\'<1y 1b="\'+b+\'" 1r="\'+z.2P+\'"\';4(!x){1Y+=(c!="")?\' 1j="\'+c+\'"\':\'\'}19{1Y+=(c!="")?\' 1j="2C-1m:4E 4F #4G;1s:2d;1n:2Y;\'+c+\'"\':\'\'};1Y+=\'>\';12 1Y};3 R=5(){3 a=K("1H");3 b=K("2u");3 c=K("29");3 d=K("3s");3 e="";3 f="";4(J(B).1E.1c>0){e=$("#"+B+" 2T:11").1q();f=$("#"+B+" 2T:11").18("1X")};f=(f.1c==0||f==14||q.1U==15||q.1N!=15)?"":\'<3x 3y="\'+f+\'" 3z="3A" /> \';3 g=\'<1y 1b="\'+a+\'" 1r="\'+z.2N+\'"\';g+=\'>\';g+=\'<1x 1b="\'+b+\'" 1r="\'+z.2O+\'"></1x><1x 1r="\'+z.1t+\'" 1b="\'+c+\'">\'+f+\'<1x 1r="\'+z.1t+\'">\'+e+\'</1x></1x></1y>\';12 g};3 S=5(){3 c=K("1h");$("#"+c+" a.2W").1J("1P");$("#"+c+" a.2W").1e("1P",5(a){a.1Z();V(1a);21();4(!x){$("#"+c).1J("1B");X(15);3 b=(q.1U==15)?$(1a).1q():$(1a).1I();1T(b);s.2e()}})};3 T=5(){3 d=15;3 e=K("1O");3 f=K("1H");3 g=K("29");3 h=K("1h");3 i=K("2u");3 j=$("#"+B).2Z();j=j+2;3 k=q.1j;4($("#"+e).1c>0){$("#"+e).2D();d=6};3 l=\'<1y 1b="\'+e+\'" 1r="\'+z.28+\'"\';l+=(k!="")?\' 1j="\'+k+\'"\':\'\';l+=\'>\';l+=R();l+=Q();l+=P();l+="</1y>";l+="</1y>";4(d==6){3 m=K("2K");$("#"+m).31(l)}19{$("#"+B).31(l)};4(x){3 f=K("1H");$("#"+f).2f()};$("#"+e).9("2Z",j+"1z");$("#"+h).9("2Z",(j-2)+"1z");4(D.1c>q.2q){3 n=2g($("#"+h+" a:3H").9("2h-3I"))+2g($("#"+h+" a:3H").9("2h-1m"));3 o=((q.3o)*q.2q)-n;$("#"+h).9("1d",o+"1z")}19 4(x){3 o=$("#"+B).1d();$("#"+h).9("1d",o+"1z")};4(d==15){3J();W(B)};4($("#"+B).18("1k")==6){$("#"+e).9("2E",z.1k)};Z();$("#"+f).1e("1B",5(a){32(1)});$("#"+f).1e("1Q",5(a){32(0)});S();$("#"+h+" a.1k").9("2E",z.1k);4(x){$("#"+h).1e("1B",5(c){4(!v.2s){v.2s=6;$(1p).1e("1W",5(a){3 b=a.3K;v.2t=b;4(b==39||b==40){a.1Z();a.2i();33();21()};4(b==37||b==38){a.1Z();a.2i();34();21()}})}})};$("#"+h).1e("1Q",5(a){X(15);$(1p).1J("1W");v.2s=15;v.2t=1o});$("#"+f).1e("1P",5(b){X(15);4($("#"+h+":2j").1c==1){$("#"+h).1J("1B")}19{$("#"+h).1e("1B",5(a){X(6)});s.3L()}});$("#"+f).1e("1Q",5(a){X(15)});4(q.1U&&q.1N!=15){2k()}};3 U=5(a){1D(3 i 2c E){4(E[i].1i==a){12 E[i]}};12-1};3 V=5(a){3 b=K("1h");4($("#"+b+" a."+z.11).1c==1){u=$("#"+b+" a."+z.11).1q()};4(!x){$("#"+b+" a."+z.11).1K(z.11)};3 c=$("#"+b+" a."+z.11).18("1b");4(c!=14){3 d=(v.22==14||v.22==1o)?E[c].1i:v.22};4(a&&!x){$(a).1F(z.11)};4(x){3 e=v.2t;4($("#"+B).18("1v")==6){4(e==17){v.22=E[$(a).18("1b")].1i;$(a).4H(z.11)}19 4(e==16){$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);3 f=$(a).18("1b");3 g=E[f].1i;1D(3 i=35.4I(d,g);i<=35.4J(d,g);i++){$("#"+U(i).1b).1F(z.11)}}19{$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);v.22=E[$(a).18("1b")].1i}}19{$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);v.22=E[$(a).18("1b")].1i}}};3 W=5(a){3 b=a;J(b).4K=5(e){$("#"+b).1S(q)}};3 X=5(a){v.2J=a};3 Y=5(){12 v.2J};3 Z=5(){3 b=K("1O");3 c=A.3t.4L(",");1D(3 d=0;d<c.1c;d++){3 e=c[d];3 f=24(e);4(f==6){2F(e){1f"2x":$("#"+b).1e("4M",5(a){J(B).2x()});1g;1f"1P":$("#"+b).1e("1P",5(a){$("#"+B).1G("1P")});1g;1f"2y":$("#"+b).1e("2y",5(a){$("#"+B).1G("2y")});1g;1f"2z":$("#"+b).1e("2z",5(a){$("#"+B).1G("2z")});1g;1f"1u":$("#"+b).1e("1u",5(a){$("#"+B).1G("1u")});1g;1f"1B":$("#"+b).1e("1B",5(a){$("#"+B).1G("1B")});1g;1f"2A":$("#"+b).1e("2A",5(a){$("#"+B).1G("2A")});1g;1f"1Q":$("#"+b).1e("1Q",5(a){$("#"+B).1G("1Q")});1g}}}};3 3J=5(){3 a=K("2K");$("#"+B).31("<1y 1r=\'"+z.2a+"\' 1j=\'1d:3M;3N:3O;1n:36;\' 1b=\'"+a+"\'></1y>");$("#"+B).4N($("#"+a))};3 1T=5(a){3 b=K("29");$("#"+b).1I(a)};3 3a=5(w){3 a=w;3 b=K("1h");3 c=$("#"+b+" a:2j");3 d=c.1c;3 e=$("#"+b+" a:2j").1i($("#"+b+" a.11:2j"));3 f;2F(a){1f"3b":4(e<d-1){e++;f=c[e]};1g;1f"3P":4(e<d&&e>0){e--;f=c[e]};1g};4(1w(f)=="14"){12 15};$("#"+b+" a."+z.11).1K(z.11);$(f).1F(z.11);3 g=f.1b;4(!x){3 h=(q.1U==15)?E[g].1q:$("#"+g).1I();1T(h);2k(E[g].1i)};4(a=="3b"){4(2g(($("#"+g).1n().1m+$("#"+g).1d()))>=2g($("#"+b).1d())){$("#"+b).2l(($("#"+b).2l())+$("#"+g).1d()+$("#"+g).1d())}}19{4(2g(($("#"+g).1n().1m+$("#"+g).1d()))<=0){$("#"+b).2l(($("#"+b).2l()-$("#"+b).1d())-$("#"+g).1d())}}};3 33=5(){3a("3b")};3 34=5(){3a("3P")};3 2k=5(i){4(q.1N!=15){3 a=K("29");3 b=(1w(i)=="14")?J(B).1l:i;3 c=J(B).1E[b].3w;4(c.1c>0){3 d=K("1h");3 e=$("#"+d+" a."+c).18("1b");3 f=$("#"+e).9("2m-4O");3 g=$("#"+e).9("2m-1n");3 h=$("#"+e).9("2h-3Q");4(f!=14){$("#"+a).2n("."+z.1t).2B(\'1j\',"2m:"+f)};4(g!=14){$("#"+a).2n("."+z.1t).9(\'2m-1n\',g)};4(h!=14){$("#"+a).2n("."+z.1t).9(\'2h-3Q\',h)};$("#"+a).2n("."+z.1t).9(\'2m-3R\',\'4P-3R\');$("#"+a).2n("."+z.1t).9(\'2h-3I\',\'4Q\')}}};3 21=5(){3 a=K("1h");3 b=$("#"+a+" a."+z.11);4(b.1c==1){3 c=$("#"+a+" a."+z.11).1q();3 d=$("#"+a+" a."+z.11).18("1b");4(d!=14){3 e=E[d].2b;J(B).1l=E[d].1i};4(q.1U&&q.1N!=15)2k()}19 4(b.1c>1){1D(3 i=0;i<b.1c;i++){3 d=$(b[i]).18("1b");3 f=E[d].1i;J(B).1E[f].11="11"}};3 g=J(B).1l;s.1V["1l"]=g};3 24=5(a){4($("#"+B).18("4R"+a)!=14){12 6};3 b=$("#"+B).3c("4S");4(b&&b[a]){12 6};12 15};3 3S=5(){3 b=K("1h");4(24(\'2R\')==6){3 c=E[$("#"+b+" a.11").18("1b")].1q;4($.3T(u)!==$.3T(c)&&u!==""){$("#"+B).1G("2R")}};4(24(\'1u\')==6){$("#"+B).1G("1u")};4(24(\'2Q\')==6){$(1p).1e("1u",5(a){$("#"+B).2x();$("#"+B)[0].2Q();21();$(1p).1J("1u")})}};3 32=5(a){3 b=K("2u");4(a==1)$("#"+b).9({3U:\'0 4T%\'});19 $("#"+b).9({3U:\'0 0\'})};3 3V=5(){1D(3 i 2c J(B)){4(1w(J(B)[i])!=\'5\'&&J(B)[i]!==14&&J(B)[i]!==1o){s.1A(i,J(B)[i],6)}}};3 3W=5(a,b){4(U(b)!=-1){J(B)[a]=b;3 c=K("1h");$("#"+c+" a."+z.11).1K(z.11);$("#"+U(b).1b).1F(z.11);3 d=U(J(B).1l).1I;1T(d)}};3 3X=5(i,a){4(a==\'d\'){1D(3 b 2c E){4(E[b].1i==i){4U E[b];1g}}};3 c=0;1D(3 b 2c E){E[b].1i=c;c++}};3 2G=5(){3 a=K("1h");3 b=K("1O");3 c=$("#"+b).1n();3 d=$("#"+b).1d();3 e=$(3Y).1d();3 f=$(3Y).2l();3 g=$("#"+a).1d();3 h={1M:q.1M,1m:(c.1m+d)+"1z",1s:"2o"};3 i=q.3q;3 j=15;3 k=z.2w;$("#"+a).1K(z.2w);$("#"+a).1K(z.2v);4((e+f)<35.4V(g+d+c.1m)){3 l=c.1m-g;4((c.1m-g)<0){l=10};h={1M:q.1M,1m:l+"1z",1s:"2o"};i="25";j=6;k=z.2v};12{3d:j,3Z:i,9:h,2C:k}};3 3e=5(){4(s.1R["41"]!=1o){2H(s.1R["41"])(s)}};3 3f=5(){3S();4(s.1R["42"]!=1o){2H(s.1R["42"])(s)}};1a.3L=5(){4((s.26("1k",6)==6)||(s.26("1E",6).1c==0))12;3 e=K("1h");4(1L!=""&&e!=1L){$("#"+1L).43("3g");$("#"+1L).9({1M:\'0\'})};4($("#"+e).9("1s")=="2o"){u=E[$("#"+e+" a.11").18("1b")].1q;3 f="";H=$("#"+e).1d();$("#"+e+" a").25();$(1p).1e("1W",5(a){3 b=a.3K;4(b==8){a.1Z();a.2i();f=(f.1c==0)?"":f.3F(0,f.1c-1)};2F(b){1f 39:1f 40:a.1Z();a.2i();33();1g;1f 37:1f 38:a.1Z();a.2i();34();1g;1f 27:1f 13:s.2e();21();1g;44:4(b>46){f+=4W.4X(b)};3 c=O(f);4(c!=-1){$("#"+e).9({1d:\'4Y\'});$("#"+e+" a").2f();$(c).25();3 d=2G();$("#"+e).9(d.9);$("#"+e).9({1s:\'2d\'})}19{$("#"+e+" a").25();$("#"+e).9({1d:H+\'1z\'})};1g};4(24("1W")==6){J(B).4Z()}});$(1p).1e("2S",5(a){4($("#"+B).18("45")!=14){J(B).45()}});$(1p).1e("1u",5(a){4(Y()==15){s.2e()}});3 g=2G();$("#"+e).9(g.9);4(g.3d==6){$("#"+e).9({1s:\'2d\'});$("#"+e).1F(g.2C);3e()}19{$("#"+e)[g.3Z]("3g",5(){$("#"+e).1F(g.2C);3e()})};4(e!=1L){1L=e}}};1a.2e=5(){3 b=K("1h");3 c=$("#"+K("1H")).1n().1m;3 d=2G();G=15;4(d.3d==6){$("#"+b).50({1d:0,1m:c,},5(){$("#"+b).9({1d:H+\'1z\',1s:\'2o\'});3f()})}19{$("#"+b).43("3g",5(a){3f();$("#"+b).9({1M:\'0\'});$("#"+b).9({1d:H+\'1z\'})})};2k();$(1p).1J("1W");$(1p).1J("2S");$(1p).1J("1u")};1a.1l=5(i){4(1w(i)=="14"){12 s.26("1l")}19{s.1A("1l",i)}};1a.51=5(a){4(1w(a)=="14"||a==6){$("."+z.2a).52("1j")}19{$("."+z.2a).2B("1j","1d:3M;3N:3O;1n:36")}};1a.1A=5(a,b,c){4(a==14||b==14)47{48:"1A 53 54?"};s.1V[a]=b;4(c!=6){2F(a){1f"1l":3W(a,b);1g;1f"1k":s.1k(b,6);1g;1f"1v":J(B)[a]=b;x=($(r).18("1C")>0||$(r).18("1v")==6)?6:15;4(x){3 d=$("#"+B).1d();3 f=K("1h");$("#"+f).9("1d",d+"1z");3 g=K("1H");$("#"+g).2f();3 f=K("1h");$("#"+f).9({1s:\'2d\',1n:\'2Y\'});S()};1g;1f"1C":J(B)[a]=b;4(b==0){J(B).1v=15};x=($(r).18("1C")>0||$(r).18("1v")==6)?6:15;4(b==0){3 g=K("1H");$("#"+g).25();3 f=K("1h");$("#"+f).9({1s:\'2o\',1n:\'36\'});3 h="";4(J(B).1l>=0){3 i=U(J(B).1l);h=i.1I;V($("#"+i.1b))};1T(h)}19{3 g=K("1H");$("#"+g).2f();3 f=K("1h");$("#"+f).9({1s:\'2d\',1n:\'2Y\'})};1g;44:55{J(B)[a]=b}56(e){};1g}}};1a.26=5(a,b){4(a==14&&b==14){12 s.1V};4(a!=14&&b==14){12(s.1V[a]!=14)?s.1V[a]:1o};4(a!=14&&b!=14){12 J(B)[a]}};1a.2j=5(a){3 b=K("1O");4(a==6){$("#"+b).25()}19 4(a==15){$("#"+b).2f()}19{12 $("#"+b).9("1s")}};1a.57=5(a,b){3 c=a;3 d=c.1q;3 e=(c.2b==14||c.2b==1o)?d:c.2b;3 f=(c["1X"]==14||c["1X"]==1o)?\'\':c["1X"];3 i=(b==14||b==1o)?J(B).1E.1c:b;J(B).1E[i]=2r 58(d,e);4(f!=\'\')J(B).1E[i]["1X"]=f;3 g=U(i);4(g!=-1){3 h=N(J(B).1E[i],i,"","");$("#"+g.1b).1I(h)}19{3 h=N(J(B).1E[i],i,"","");3 j=K("1h");$("#"+j).59(h);S()}};1a.2D=5(i){J(B).2D(i);4((U(i))!=-1){$("#"+U(i).1b).2D();3X(i,\'d\')};4(J(B).1c==0){1T("")}19{3 a=U(J(B).1l).1I;1T(a)};s.1A("1l",J(B).1l)};1a.1k=5(a,b){J(B).1k=a;3 c=K("1O");4(a==6){$("#"+c).9("2E",z.1k);s.2e()}19 4(a==15){$("#"+c).9("2E",1)};4(b!=6){s.1A("1k",a)}};1a.3h=5(){12(J(B).3h==14)?1o:J(B).3h};1a.3i=5(){4(2p.1c==1){12 J(B).3i(2p[0])}19 4(2p.1c==2){12 J(B).3i(2p[0],2p[1])}19{47{48:"5a 1i 5b 5c!"}}};1a.49=5(a){12 J(B).49(a)};1a.1v=5(a){4(1w(a)=="14"){12 s.26("1v")}19{s.1A("1v",a)}};1a.1C=5(a){4(1w(a)=="14"){12 s.26("1C")}19{s.1A("1C",a)}};1a.5d=5(a,b){s.1R[a]=b};1a.5e=5(a){2H(s.1R[a])(s)};3 4a=5(){s.1A("3j",$.1S.3j);s.1A("3k",$.1S.3k)};3 4b=5(){T();3V();4a();4(q.2I!=\'\'){2H(q.2I)(s)}};4b()};$.1S={3j:2.37,3k:"5f 5g",3u:20,5h:5(a,b){12 $(a).1S(b).3c("28")}};$.3l.3n({1S:5(b){12 1a.2X(5(){3 a=2r 3m(1a,b);$(1a).3c(\'28\',a)})}});4(1w($.3l.18)==\'14\'){$.3l.18=5(w){12 $(1a).2B(w)}}})(5i);',62,329,'|||var|if|function|true|||css||||||||||||||||||||||||||||||||||||||||||||||||||||||selected|return||undefined|false|||prop|else|this|id|length|height|bind|case|break|postChildID|index|style|disabled|selectedIndex|top|position|null|document|text|class|display|ddTitleText|mouseup|multiple|typeof|span|div|px|set|mouseover|size|for|options|addClass|trigger|postTitleID|html|unbind|removeClass|bs|zIndex|useSprite|postID|click|mouseout|onActions|msDropDown|bv|showIcon|ddProp|keydown|title|sDiv|preventDefault||bA|oldIndex||bB|show|get||dd|postTitleTextID|ddOutOfVision|value|in|block|close|hide|parseInt|padding|stopPropagation|visible|bz|scrollTop|background|find|none|arguments|visibleRows|new|keyboardAction|currentKey|postArrowID|borderTop|noBorderTop|focus|dblclick|mousedown|mousemove|attr|border|remove|opacity|switch|bH|eval|onInit|insideWindow|postElementHolder|postAID|postOPTAID|ddTitle|arrow|ddChild|blur|change|keyup|option|opt|_|enabled|each|relative|width||after|bD|bx|by|Math|absolute||||bw|next|data|opp|bI|bJ|fast|form|item|version|author|fn|bt|extend|rowHeight|mainCSS|animStyle|Object|postInputhidden|actions|counter|children|className|img|src|align|absmiddle|href|javascript|void|toLowerCase|substr|font|first|bottom|bu|keyCode|open|0px|overflow|hidden|previous|left|repeat|bC|trim|backgroundPosition|bE|bF|bG|window|ani||onOpen|onClose|slideUp|default|onkeyup||throw|message|namedItem|bK|bL|120|9999|slideDown|_msddHolder|_msdd|_title|_titletext|_child|_msa|_msopta|postInputID|_msinput|_arrow|_inp|keypress|tabindex|msdrpdd|getElementById|val|nodeName|OPTGROUP|opta|weight|bold|italic|clear|both|label|1px|solid|c3c3c3|toggleClass|min|max|refresh|split|mouseenter|appendTo|image|no|2px|on|events|100|delete|floor|String|fromCharCode|auto|onkeydown|animate|debug|removeAttr|to|what|try|catch|add|Option|append|An|is|required|addMyEvent|fireEvent|Marghoob|Suleman|create|jQuery'.split('|'),0,{}))
1
+ // MSDropDown - jquery.dd.js
2
+ // author: Marghoob Suleman - Search me on google
3
+ // Date: 12th Aug, 2009, {18 Dec, 2010 (2.36)}
4
+ // Version: 2.37 {date: 17 June, 2011}
5
+ // Revision: 33
6
+ // web: www.giftlelo.com | www.marghoobsuleman.com
7
+ /*
8
+ // msDropDown is free jQuery Plugin: you can redistribute it and/or modify
9
+ // it under the terms of the either the MIT License or the Gnu General Public License (GPL) Version 2
10
+ */
11
  ;eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(5($){3 1L="";3 3m=5(p,q){3 r=p;3 s=1a;3 q=$.3n({1d:4c,2q:7,3o:23,1U:6,1M:4d,3p:\'28\',1N:15,3q:\'4e\',2I:\'\',1j:\'\'},q);1a.1V=2r 3r();3 u="";3 v={};v.2J=6;v.2s=15;v.2t=1o;3 x=15;3 y={2K:\'4f\',1O:\'4g\',1H:\'4h\',29:\'4i\',1h:\'4j\',2L:\'4k\',2M:\'4l\',4m:\'4n\',2u:\'4o\',3s:\'4p\'};3 z={28:q.3p,2N:\'2N\',2O:\'2O\',2P:\'2P\',1t:\'1t\',1k:.30,2a:\'2a\',2v:\'2v\',2w:\'2w\',11:\'11\'};3 A={3t:"2x,2Q,2R,1P,2y,2z,1u,1B,2A,1Q,4q,1W,2S",18:"1C,1v,1k,4r"};1a.1R=2r 3r();3 B=$(r).18("1b");4(1w(B)=="14"||B.1c<=0){B="4s"+$.1S.3u++;$(r).2B("1b",B)};3 C=$(r).18("1j");q.1j+=(C==14)?"":C;3 D=$(r).3v();x=($(r).18("1C")>1||$(r).18("1v")==6)?6:15;4(x){q.2q=$(r).18("1C")};3 E={};3 F=0;3 G=15;3 H;3 I={};3 J=5(a){4(1w(I[a])=="14"){I[a]=1p.4t(a)}12 I[a]};3 K=5(a){12 B+y[a]};3 L=5(a){3 b=a;3 c=$(b).18("1j");12 c};3 M=5(a){3 b=$("#"+B+" 2T:11");4(b.1c>1){1D(3 i=0;i<b.1c;i++){4(a==b[i].1i){12 6}}}19 4(b.1c==1){4(b[0].1i==a){12 6}};12 15};3 N=5(a,b,c,d){3 e="";3 f=(d=="2U")?K("2M"):K("2L");3 g=(d=="2U")?f+"2V"+(b)+"2V"+(c):f+"2V"+(b);3 h="";3 i="";4(q.1N!=15){i=\' \'+q.1N+\' \'+a.3w}19{h=$(a).18("1X");h=(h.1c==0)?"":\'<3x 3y="\'+h+\'" 3z="3A" /> \'};3 j=$(a).1q();3 k=$(a).4u();3 l=($(a).18("1k")==6)?"1k":"2W";E[g]={1I:h+j,2b:k,1q:j,1i:a.1i,1b:g};3 m=L(a);4(M(a.1i)==6){e+=\'<a 3B="3C:3D(0);" 1r="\'+z.11+\' \'+l+i+\'"\'}19{e+=\'<a 3B="3C:3D(0);" 1r="\'+l+i+\'"\'};4(m!==15&&m!==14){e+=" 1j=\'"+m+"\'"};e+=\' 1b="\'+g+\'">\';e+=h+\'<1x 1r="\'+z.1t+\'">\'+j+\'</1x></a>\';12 e};3 O=5(t){3 b=t.3E();4(b.1c==0)12-1;3 a="";1D(3 i 2c E){3 c=E[i].1q.3E();4(c.3F(0,b.1c)==b){a+="#"+E[i].1b+", "}};12(a=="")?-1:a};3 P=5(){3 f=D;4(f.1c==0)12"";3 g="";3 h=K("2L");3 i=K("2M");f.2X(5(c){3 d=f[c];4(d.4v=="4w"){g+="<1y 1r=\'4x\'>";g+="<1x 1j=\'3G-4y:4z;3G-1j:4A; 4B:4C;\'>"+$(d).18("4D")+"</1x>";3 e=$(d).3v();e.2X(5(a){3 b=e[a];g+=N(b,c,a,"2U")});g+="</1y>"}19{g+=N(d,c,"","")}});12 g};3 Q=5(){3 a=K("1O");3 b=K("1h");3 c=q.1j;1Y="";1Y+=\'<1y 1b="\'+b+\'" 1r="\'+z.2P+\'"\';4(!x){1Y+=(c!="")?\' 1j="\'+c+\'"\':\'\'}19{1Y+=(c!="")?\' 1j="2C-1m:4E 4F #4G;1s:2d;1n:2Y;\'+c+\'"\':\'\'};1Y+=\'>\';12 1Y};3 R=5(){3 a=K("1H");3 b=K("2u");3 c=K("29");3 d=K("3s");3 e="";3 f="";4(J(B).1E.1c>0){e=$("#"+B+" 2T:11").1q();f=$("#"+B+" 2T:11").18("1X")};f=(f.1c==0||f==14||q.1U==15||q.1N!=15)?"":\'<3x 3y="\'+f+\'" 3z="3A" /> \';3 g=\'<1y 1b="\'+a+\'" 1r="\'+z.2N+\'"\';g+=\'>\';g+=\'<1x 1b="\'+b+\'" 1r="\'+z.2O+\'"></1x><1x 1r="\'+z.1t+\'" 1b="\'+c+\'">\'+f+\'<1x 1r="\'+z.1t+\'">\'+e+\'</1x></1x></1y>\';12 g};3 S=5(){3 c=K("1h");$("#"+c+" a.2W").1J("1P");$("#"+c+" a.2W").1e("1P",5(a){a.1Z();V(1a);21();4(!x){$("#"+c).1J("1B");X(15);3 b=(q.1U==15)?$(1a).1q():$(1a).1I();1T(b);s.2e()}})};3 T=5(){3 d=15;3 e=K("1O");3 f=K("1H");3 g=K("29");3 h=K("1h");3 i=K("2u");3 j=$("#"+B).2Z();j=j+2;3 k=q.1j;4($("#"+e).1c>0){$("#"+e).2D();d=6};3 l=\'<1y 1b="\'+e+\'" 1r="\'+z.28+\'"\';l+=(k!="")?\' 1j="\'+k+\'"\':\'\';l+=\'>\';l+=R();l+=Q();l+=P();l+="</1y>";l+="</1y>";4(d==6){3 m=K("2K");$("#"+m).31(l)}19{$("#"+B).31(l)};4(x){3 f=K("1H");$("#"+f).2f()};$("#"+e).9("2Z",j+"1z");$("#"+h).9("2Z",(j-2)+"1z");4(D.1c>q.2q){3 n=2g($("#"+h+" a:3H").9("2h-3I"))+2g($("#"+h+" a:3H").9("2h-1m"));3 o=((q.3o)*q.2q)-n;$("#"+h).9("1d",o+"1z")}19 4(x){3 o=$("#"+B).1d();$("#"+h).9("1d",o+"1z")};4(d==15){3J();W(B)};4($("#"+B).18("1k")==6){$("#"+e).9("2E",z.1k)};Z();$("#"+f).1e("1B",5(a){32(1)});$("#"+f).1e("1Q",5(a){32(0)});S();$("#"+h+" a.1k").9("2E",z.1k);4(x){$("#"+h).1e("1B",5(c){4(!v.2s){v.2s=6;$(1p).1e("1W",5(a){3 b=a.3K;v.2t=b;4(b==39||b==40){a.1Z();a.2i();33();21()};4(b==37||b==38){a.1Z();a.2i();34();21()}})}})};$("#"+h).1e("1Q",5(a){X(15);$(1p).1J("1W");v.2s=15;v.2t=1o});$("#"+f).1e("1P",5(b){X(15);4($("#"+h+":2j").1c==1){$("#"+h).1J("1B")}19{$("#"+h).1e("1B",5(a){X(6)});s.3L()}});$("#"+f).1e("1Q",5(a){X(15)});4(q.1U&&q.1N!=15){2k()}};3 U=5(a){1D(3 i 2c E){4(E[i].1i==a){12 E[i]}};12-1};3 V=5(a){3 b=K("1h");4($("#"+b+" a."+z.11).1c==1){u=$("#"+b+" a."+z.11).1q()};4(!x){$("#"+b+" a."+z.11).1K(z.11)};3 c=$("#"+b+" a."+z.11).18("1b");4(c!=14){3 d=(v.22==14||v.22==1o)?E[c].1i:v.22};4(a&&!x){$(a).1F(z.11)};4(x){3 e=v.2t;4($("#"+B).18("1v")==6){4(e==17){v.22=E[$(a).18("1b")].1i;$(a).4H(z.11)}19 4(e==16){$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);3 f=$(a).18("1b");3 g=E[f].1i;1D(3 i=35.4I(d,g);i<=35.4J(d,g);i++){$("#"+U(i).1b).1F(z.11)}}19{$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);v.22=E[$(a).18("1b")].1i}}19{$("#"+b+" a."+z.11).1K(z.11);$(a).1F(z.11);v.22=E[$(a).18("1b")].1i}}};3 W=5(a){3 b=a;J(b).4K=5(e){$("#"+b).1S(q)}};3 X=5(a){v.2J=a};3 Y=5(){12 v.2J};3 Z=5(){3 b=K("1O");3 c=A.3t.4L(",");1D(3 d=0;d<c.1c;d++){3 e=c[d];3 f=24(e);4(f==6){2F(e){1f"2x":$("#"+b).1e("4M",5(a){J(B).2x()});1g;1f"1P":$("#"+b).1e("1P",5(a){$("#"+B).1G("1P")});1g;1f"2y":$("#"+b).1e("2y",5(a){$("#"+B).1G("2y")});1g;1f"2z":$("#"+b).1e("2z",5(a){$("#"+B).1G("2z")});1g;1f"1u":$("#"+b).1e("1u",5(a){$("#"+B).1G("1u")});1g;1f"1B":$("#"+b).1e("1B",5(a){$("#"+B).1G("1B")});1g;1f"2A":$("#"+b).1e("2A",5(a){$("#"+B).1G("2A")});1g;1f"1Q":$("#"+b).1e("1Q",5(a){$("#"+B).1G("1Q")});1g}}}};3 3J=5(){3 a=K("2K");$("#"+B).31("<1y 1r=\'"+z.2a+"\' 1j=\'1d:3M;3N:3O;1n:36;\' 1b=\'"+a+"\'></1y>");$("#"+B).4N($("#"+a))};3 1T=5(a){3 b=K("29");$("#"+b).1I(a)};3 3a=5(w){3 a=w;3 b=K("1h");3 c=$("#"+b+" a:2j");3 d=c.1c;3 e=$("#"+b+" a:2j").1i($("#"+b+" a.11:2j"));3 f;2F(a){1f"3b":4(e<d-1){e++;f=c[e]};1g;1f"3P":4(e<d&&e>0){e--;f=c[e]};1g};4(1w(f)=="14"){12 15};$("#"+b+" a."+z.11).1K(z.11);$(f).1F(z.11);3 g=f.1b;4(!x){3 h=(q.1U==15)?E[g].1q:$("#"+g).1I();1T(h);2k(E[g].1i)};4(a=="3b"){4(2g(($("#"+g).1n().1m+$("#"+g).1d()))>=2g($("#"+b).1d())){$("#"+b).2l(($("#"+b).2l())+$("#"+g).1d()+$("#"+g).1d())}}19{4(2g(($("#"+g).1n().1m+$("#"+g).1d()))<=0){$("#"+b).2l(($("#"+b).2l()-$("#"+b).1d())-$("#"+g).1d())}}};3 33=5(){3a("3b")};3 34=5(){3a("3P")};3 2k=5(i){4(q.1N!=15){3 a=K("29");3 b=(1w(i)=="14")?J(B).1l:i;3 c=J(B).1E[b].3w;4(c.1c>0){3 d=K("1h");3 e=$("#"+d+" a."+c).18("1b");3 f=$("#"+e).9("2m-4O");3 g=$("#"+e).9("2m-1n");3 h=$("#"+e).9("2h-3Q");4(f!=14){$("#"+a).2n("."+z.1t).2B(\'1j\',"2m:"+f)};4(g!=14){$("#"+a).2n("."+z.1t).9(\'2m-1n\',g)};4(h!=14){$("#"+a).2n("."+z.1t).9(\'2h-3Q\',h)};$("#"+a).2n("."+z.1t).9(\'2m-3R\',\'4P-3R\');$("#"+a).2n("."+z.1t).9(\'2h-3I\',\'4Q\')}}};3 21=5(){3 a=K("1h");3 b=$("#"+a+" a."+z.11);4(b.1c==1){3 c=$("#"+a+" a."+z.11).1q();3 d=$("#"+a+" a."+z.11).18("1b");4(d!=14){3 e=E[d].2b;J(B).1l=E[d].1i};4(q.1U&&q.1N!=15)2k()}19 4(b.1c>1){1D(3 i=0;i<b.1c;i++){3 d=$(b[i]).18("1b");3 f=E[d].1i;J(B).1E[f].11="11"}};3 g=J(B).1l;s.1V["1l"]=g};3 24=5(a){4($("#"+B).18("4R"+a)!=14){12 6};3 b=$("#"+B).3c("4S");4(b&&b[a]){12 6};12 15};3 3S=5(){3 b=K("1h");4(24(\'2R\')==6){3 c=E[$("#"+b+" a.11").18("1b")].1q;4($.3T(u)!==$.3T(c)&&u!==""){$("#"+B).1G("2R")}};4(24(\'1u\')==6){$("#"+B).1G("1u")};4(24(\'2Q\')==6){$(1p).1e("1u",5(a){$("#"+B).2x();$("#"+B)[0].2Q();21();$(1p).1J("1u")})}};3 32=5(a){3 b=K("2u");4(a==1)$("#"+b).9({3U:\'0 4T%\'});19 $("#"+b).9({3U:\'0 0\'})};3 3V=5(){1D(3 i 2c J(B)){4(1w(J(B)[i])!=\'5\'&&J(B)[i]!==14&&J(B)[i]!==1o){s.1A(i,J(B)[i],6)}}};3 3W=5(a,b){4(U(b)!=-1){J(B)[a]=b;3 c=K("1h");$("#"+c+" a."+z.11).1K(z.11);$("#"+U(b).1b).1F(z.11);3 d=U(J(B).1l).1I;1T(d)}};3 3X=5(i,a){4(a==\'d\'){1D(3 b 2c E){4(E[b].1i==i){4U E[b];1g}}};3 c=0;1D(3 b 2c E){E[b].1i=c;c++}};3 2G=5(){3 a=K("1h");3 b=K("1O");3 c=$("#"+b).1n();3 d=$("#"+b).1d();3 e=$(3Y).1d();3 f=$(3Y).2l();3 g=$("#"+a).1d();3 h={1M:q.1M,1m:(c.1m+d)+"1z",1s:"2o"};3 i=q.3q;3 j=15;3 k=z.2w;$("#"+a).1K(z.2w);$("#"+a).1K(z.2v);4((e+f)<35.4V(g+d+c.1m)){3 l=c.1m-g;4((c.1m-g)<0){l=10};h={1M:q.1M,1m:l+"1z",1s:"2o"};i="25";j=6;k=z.2v};12{3d:j,3Z:i,9:h,2C:k}};3 3e=5(){4(s.1R["41"]!=1o){2H(s.1R["41"])(s)}};3 3f=5(){3S();4(s.1R["42"]!=1o){2H(s.1R["42"])(s)}};1a.3L=5(){4((s.26("1k",6)==6)||(s.26("1E",6).1c==0))12;3 e=K("1h");4(1L!=""&&e!=1L){$("#"+1L).43("3g");$("#"+1L).9({1M:\'0\'})};4($("#"+e).9("1s")=="2o"){u=E[$("#"+e+" a.11").18("1b")].1q;3 f="";H=$("#"+e).1d();$("#"+e+" a").25();$(1p).1e("1W",5(a){3 b=a.3K;4(b==8){a.1Z();a.2i();f=(f.1c==0)?"":f.3F(0,f.1c-1)};2F(b){1f 39:1f 40:a.1Z();a.2i();33();1g;1f 37:1f 38:a.1Z();a.2i();34();1g;1f 27:1f 13:s.2e();21();1g;44:4(b>46){f+=4W.4X(b)};3 c=O(f);4(c!=-1){$("#"+e).9({1d:\'4Y\'});$("#"+e+" a").2f();$(c).25();3 d=2G();$("#"+e).9(d.9);$("#"+e).9({1s:\'2d\'})}19{$("#"+e+" a").25();$("#"+e).9({1d:H+\'1z\'})};1g};4(24("1W")==6){J(B).4Z()}});$(1p).1e("2S",5(a){4($("#"+B).18("45")!=14){J(B).45()}});$(1p).1e("1u",5(a){4(Y()==15){s.2e()}});3 g=2G();$("#"+e).9(g.9);4(g.3d==6){$("#"+e).9({1s:\'2d\'});$("#"+e).1F(g.2C);3e()}19{$("#"+e)[g.3Z]("3g",5(){$("#"+e).1F(g.2C);3e()})};4(e!=1L){1L=e}}};1a.2e=5(){3 b=K("1h");3 c=$("#"+K("1H")).1n().1m;3 d=2G();G=15;4(d.3d==6){$("#"+b).50({1d:0,1m:c,},5(){$("#"+b).9({1d:H+\'1z\',1s:\'2o\'});3f()})}19{$("#"+b).43("3g",5(a){3f();$("#"+b).9({1M:\'0\'});$("#"+b).9({1d:H+\'1z\'})})};2k();$(1p).1J("1W");$(1p).1J("2S");$(1p).1J("1u")};1a.1l=5(i){4(1w(i)=="14"){12 s.26("1l")}19{s.1A("1l",i)}};1a.51=5(a){4(1w(a)=="14"||a==6){$("."+z.2a).52("1j")}19{$("."+z.2a).2B("1j","1d:3M;3N:3O;1n:36")}};1a.1A=5(a,b,c){4(a==14||b==14)47{48:"1A 53 54?"};s.1V[a]=b;4(c!=6){2F(a){1f"1l":3W(a,b);1g;1f"1k":s.1k(b,6);1g;1f"1v":J(B)[a]=b;x=($(r).18("1C")>0||$(r).18("1v")==6)?6:15;4(x){3 d=$("#"+B).1d();3 f=K("1h");$("#"+f).9("1d",d+"1z");3 g=K("1H");$("#"+g).2f();3 f=K("1h");$("#"+f).9({1s:\'2d\',1n:\'2Y\'});S()};1g;1f"1C":J(B)[a]=b;4(b==0){J(B).1v=15};x=($(r).18("1C")>0||$(r).18("1v")==6)?6:15;4(b==0){3 g=K("1H");$("#"+g).25();3 f=K("1h");$("#"+f).9({1s:\'2o\',1n:\'36\'});3 h="";4(J(B).1l>=0){3 i=U(J(B).1l);h=i.1I;V($("#"+i.1b))};1T(h)}19{3 g=K("1H");$("#"+g).2f();3 f=K("1h");$("#"+f).9({1s:\'2d\',1n:\'2Y\'})};1g;44:55{J(B)[a]=b}56(e){};1g}}};1a.26=5(a,b){4(a==14&&b==14){12 s.1V};4(a!=14&&b==14){12(s.1V[a]!=14)?s.1V[a]:1o};4(a!=14&&b!=14){12 J(B)[a]}};1a.2j=5(a){3 b=K("1O");4(a==6){$("#"+b).25()}19 4(a==15){$("#"+b).2f()}19{12 $("#"+b).9("1s")}};1a.57=5(a,b){3 c=a;3 d=c.1q;3 e=(c.2b==14||c.2b==1o)?d:c.2b;3 f=(c["1X"]==14||c["1X"]==1o)?\'\':c["1X"];3 i=(b==14||b==1o)?J(B).1E.1c:b;J(B).1E[i]=2r 58(d,e);4(f!=\'\')J(B).1E[i]["1X"]=f;3 g=U(i);4(g!=-1){3 h=N(J(B).1E[i],i,"","");$("#"+g.1b).1I(h)}19{3 h=N(J(B).1E[i],i,"","");3 j=K("1h");$("#"+j).59(h);S()}};1a.2D=5(i){J(B).2D(i);4((U(i))!=-1){$("#"+U(i).1b).2D();3X(i,\'d\')};4(J(B).1c==0){1T("")}19{3 a=U(J(B).1l).1I;1T(a)};s.1A("1l",J(B).1l)};1a.1k=5(a,b){J(B).1k=a;3 c=K("1O");4(a==6){$("#"+c).9("2E",z.1k);s.2e()}19 4(a==15){$("#"+c).9("2E",1)};4(b!=6){s.1A("1k",a)}};1a.3h=5(){12(J(B).3h==14)?1o:J(B).3h};1a.3i=5(){4(2p.1c==1){12 J(B).3i(2p[0])}19 4(2p.1c==2){12 J(B).3i(2p[0],2p[1])}19{47{48:"5a 1i 5b 5c!"}}};1a.49=5(a){12 J(B).49(a)};1a.1v=5(a){4(1w(a)=="14"){12 s.26("1v")}19{s.1A("1v",a)}};1a.1C=5(a){4(1w(a)=="14"){12 s.26("1C")}19{s.1A("1C",a)}};1a.5d=5(a,b){s.1R[a]=b};1a.5e=5(a){2H(s.1R[a])(s)};3 4a=5(){s.1A("3j",$.1S.3j);s.1A("3k",$.1S.3k)};3 4b=5(){T();3V();4a();4(q.2I!=\'\'){2H(q.2I)(s)}};4b()};$.1S={3j:2.37,3k:"5f 5g",3u:20,5h:5(a,b){12 $(a).1S(b).3c("28")}};$.3l.3n({1S:5(b){12 1a.2X(5(){3 a=2r 3m(1a,b);$(1a).3c(\'28\',a)})}});4(1w($.3l.18)==\'14\'){$.3l.18=5(w){12 $(1a).2B(w)}}})(5i);',62,329,'|||var|if|function|true|||css||||||||||||||||||||||||||||||||||||||||||||||||||||||selected|return||undefined|false|||prop|else|this|id|length|height|bind|case|break|postChildID|index|style|disabled|selectedIndex|top|position|null|document|text|class|display|ddTitleText|mouseup|multiple|typeof|span|div|px|set|mouseover|size|for|options|addClass|trigger|postTitleID|html|unbind|removeClass|bs|zIndex|useSprite|postID|click|mouseout|onActions|msDropDown|bv|showIcon|ddProp|keydown|title|sDiv|preventDefault||bA|oldIndex||bB|show|get||dd|postTitleTextID|ddOutOfVision|value|in|block|close|hide|parseInt|padding|stopPropagation|visible|bz|scrollTop|background|find|none|arguments|visibleRows|new|keyboardAction|currentKey|postArrowID|borderTop|noBorderTop|focus|dblclick|mousedown|mousemove|attr|border|remove|opacity|switch|bH|eval|onInit|insideWindow|postElementHolder|postAID|postOPTAID|ddTitle|arrow|ddChild|blur|change|keyup|option|opt|_|enabled|each|relative|width||after|bD|bx|by|Math|absolute||||bw|next|data|opp|bI|bJ|fast|form|item|version|author|fn|bt|extend|rowHeight|mainCSS|animStyle|Object|postInputhidden|actions|counter|children|className|img|src|align|absmiddle|href|javascript|void|toLowerCase|substr|font|first|bottom|bu|keyCode|open|0px|overflow|hidden|previous|left|repeat|bC|trim|backgroundPosition|bE|bF|bG|window|ani||onOpen|onClose|slideUp|default|onkeyup||throw|message|namedItem|bK|bL|120|9999|slideDown|_msddHolder|_msdd|_title|_titletext|_child|_msa|_msopta|postInputID|_msinput|_arrow|_inp|keypress|tabindex|msdrpdd|getElementById|val|nodeName|OPTGROUP|opta|weight|bold|italic|clear|both|label|1px|solid|c3c3c3|toggleClass|min|max|refresh|split|mouseenter|appendTo|image|no|2px|on|events|100|delete|floor|String|fromCharCode|auto|onkeydown|animate|debug|removeAttr|to|what|try|catch|add|Option|append|An|is|required|addMyEvent|fireEvent|Marghoob|Suleman|create|jQuery'.split('|'),0,{}))
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === WPide ===
2
- Contributors: WebFactory
3
  Tags: theme editor, plugin editor, code editor, file editor, file manager, wpide, ide
4
  Requires at least: 5.0
5
  Tested up to: 5.9
6
- Stable tag: 2.5
7
  Requires PHP: 5.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -16,8 +16,6 @@ WPide is a WordPress code editor and file editor with automatic backups. You can
16
 
17
  This plugin would not be possible without the <a href="http://ace.ajax.org/">Ajax.org Cloud9 Editor</a> which is the embedded code editor that powers much of the functionality.
18
 
19
- **Moving a site from HTTP to HTTPS? Having problems with SSL? Install our <a href="https://wordpress.org/plugins/wp-force-ssl/">free WP Force SSL plugin</a> and fix all SSL issues.**
20
-
21
  = Current Features: =
22
 
23
  * Syntax highlighting
@@ -85,6 +83,11 @@ Either the image contains no image data (its a new empty file) or the image is n
85
 
86
  == Changelog ==
87
 
 
 
 
 
 
88
  = 2.5 =
89
  * 2020-04-13
90
  * getting the plugin back to life
1
  === WPide ===
2
+ Contributors: XplodedThemes
3
  Tags: theme editor, plugin editor, code editor, file editor, file manager, wpide, ide
4
  Requires at least: 5.0
5
  Tested up to: 5.9
6
+ Stable tag: 2.6
7
  Requires PHP: 5.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
16
 
17
  This plugin would not be possible without the <a href="http://ace.ajax.org/">Ajax.org Cloud9 Editor</a> which is the embedded code editor that powers much of the functionality.
18
 
 
 
19
  = Current Features: =
20
 
21
  * Syntax highlighting
83
 
84
  == Changelog ==
85
 
86
+ = 2.6 =
87
+ * 2022-04-26
88
+ * Plugin acquired by XplodedThemes
89
+ * A brand new and completely revamped version of WPide is coming soon, Stay tuned!
90
+
91
  = 2.5 =
92
  * 2020-04-13
93
  * getting the plugin back to life
wf-flyout/config.php CHANGED
@@ -1,19 +1,16 @@
1
- <?php
2
- $config['plugin_screen'] = 'toplevel_page_wpide';
3
- $config['icon_border'] = '2px solid #7e7e7e';
4
- $config['icon_right'] = '40px';
5
- $config['icon_bottom'] = '30px';
6
- $config['icon_image'] = 'wpide.png';
7
- $config['icon_padding'] = '6px';
8
- $config['icon_size'] = '55px';
9
- $config['menu_accent_color'] = '#ff7920';
10
- $config['custom_css'] = '';
11
-
12
- $config['menu_items'] = array(
13
- array('href' => 'https://wpreset.com/?ref=wff-wpide', 'target' => '_blank', 'label' => 'Problems with your site? Need to start over? Get WP Reset', 'icon' => 'wp-reset.png'),
14
- array('href' => 'https://underconstructionpage.com/?ref=wff-wpide&coupon=welcome', 'target' => '_blank', 'label' => 'Get UnderConstrucionPage PRO with 20% OFF', 'icon' => 'ucp.png', 'class' => ''),
15
- array('href' => 'https://wp301redirects.com/?ref=wff-wpide&coupon=50off', 'label' => 'Fix 2 most common SEO issues on WordPress', 'icon' => '301-logo.png', 'class' => 'wp301-icon'),
16
- array('href' => 'https://wpsticky.com/?ref=wff-wpide', 'target' => '_blank', 'label' => 'Make any element sticky with WP Sticky', 'icon' => 'dashicons-admin-post'),
17
- array('href' => 'https://wordpress.org/support/plugin/wpide/reviews/?filter=5#new-post', 'target' => '_blank', 'label' => 'Rate the Plugin', 'icon' => 'dashicons-thumbs-up'),
18
- array('href' => 'https://wordpress.org/support/plugin/wpide/', 'target' => '_blank', 'label' => 'Get Support', 'icon' => 'dashicons-sos'),
19
- );
1
+ <?php
2
+ $config['plugin_screen'] = 'toplevel_page_wpide';
3
+ $config['icon_border'] = '2px solid #7e7e7e';
4
+ $config['icon_right'] = '40px';
5
+ $config['icon_bottom'] = '30px';
6
+ $config['icon_image'] = 'wpide.png';
7
+ $config['icon_padding'] = '6px';
8
+ $config['icon_size'] = '55px';
9
+ $config['menu_accent_color'] = '#ff7920';
10
+ $config['custom_css'] = '';
11
+
12
+ $config['menu_items'] = array(
13
+ array('href' => 'https://slickmenu.com/?ref=wpide', 'target' => '_blank', 'label' => 'Slick Menu - The Non-Boring Vertical Menu for WordPress', 'icon' => 'slickmenu.png'),
14
+ array('href' => 'https://xplodedthemes.com/?ref=wpide', 'target' => '_blank', 'label' => 'XplodedThemes - Feature-Rich & Sales-Boosting WooCommerce Plugins', 'icon' => 'xt.png', 'class' => ''),
15
+ array('href' => 'https://xplodedthemes.com/support/', 'target' => '_blank', 'label' => 'Get Support', 'icon' => 'dashicons-sos'),
16
+ );
 
 
 
wf-flyout/wf-flyout.css CHANGED
@@ -1,200 +1,200 @@
1
- /**
2
- * Universal fly-out menu for WebFactory plugins
3
- * (c) WebFactory Ltd, 2021
4
- */
5
-
6
- #wf-flyout {
7
- position: fixed;
8
- z-index: 100049;
9
- transition: all 0.3s ease-in-out;
10
- right: 40px;
11
- bottom: 40px;
12
- opacity: 1;
13
- }
14
-
15
- #wff-overlay {
16
- background: #000;
17
- opacity: 0.4;
18
- filter: alpha(opacity=40);
19
- position: fixed;
20
- top: 0;
21
- right: 0;
22
- bottom: 0;
23
- left: 0;
24
- display: none;
25
- z-index: 100049;
26
- }
27
-
28
- #wf-flyout a:focus {
29
- outline: none;
30
- box-shadow: none;
31
- }
32
-
33
- #wf-flyout #wff-button {
34
- display: block;
35
- }
36
-
37
- #wf-flyout #wff-image-wrapper {
38
- border: 3px solid #000000;
39
- border-radius: 50%;
40
- padding: 0;
41
- display: block;
42
- overflow: hidden;
43
- background: #ffffff;
44
- box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
45
- }
46
-
47
- #wf-flyout #wff-button img {
48
- width: 55px;
49
- height: 55px;
50
- display: block;
51
- overflow: hidden;
52
- padding: 2px;
53
- background: #ffffff;
54
- box-sizing: border-box;
55
- }
56
-
57
- #wf-flyout #wff-button:hover #wff-image-wrapper {
58
- box-shadow: 0 3px 30px rgba(0, 0, 0, 0.25);
59
- }
60
-
61
- #wf-flyout:not(.opened) #wff-button:hover .wff-label {
62
- opacity: 1;
63
- margin-right: 0;
64
- }
65
-
66
- #wf-flyout .wff-label {
67
- position: absolute;
68
- display: block;
69
- top: 50%;
70
- right: calc(100% + 25px);
71
- transform: translateY(-50%) scale(1);
72
- -moz-transform: translateY(-50%);
73
- -webkit-transform: translateY(-50%);
74
- color: #fff;
75
- background: #444 0 0 no-repeat padding-box;
76
- font-size: 14px;
77
- white-space: nowrap;
78
- padding: 5px 10px;
79
- height: auto !important;
80
- line-height: initial;
81
- transition: all 0.2s ease-out;
82
- border-radius: 3px;
83
- -moz-border-radius: 3px;
84
- -webkit-border-radius: 3px;
85
- opacity: 0;
86
- margin-right: -50px;
87
- }
88
-
89
- #wf-flyout .wff-icon {
90
- width: 40px;
91
- height: 40px;
92
- vertical-align: middle;
93
- line-height: 60px;
94
- text-align: center;
95
- }
96
-
97
- #wf-flyout .wff-icon img {
98
- max-width: 80%;
99
- filter: brightness(100);
100
- }
101
-
102
- #wf-flyout .wff-label.visible {
103
- opacity: 1;
104
- }
105
-
106
- #wf-flyout .wff-menu-item {
107
- position: absolute;
108
- left: 10px;
109
- width: 40px;
110
- height: 40px;
111
- opacity: 0;
112
- visibility: hidden;
113
- transform: scale(0);
114
- border-radius: 50%;
115
- box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
116
- background: #0071a1;
117
- text-align: center;
118
- vertical-align: middle;
119
- text-decoration: none;
120
- transition-timing-function: ease-in-out;
121
- }
122
-
123
- #wf-flyout .wff-menu-item.accent {
124
- background: #ca4a1f;
125
- }
126
-
127
- #wf-flyout.opened .wff-menu-item {
128
- opacity: 1;
129
- visibility: visible;
130
- transform: scale(1);
131
- }
132
-
133
- #wf-flyout .wff-menu-item:hover {
134
- box-shadow: 0 3px 30px rgba(0, 0, 0, 0.25);
135
- }
136
-
137
- #wf-flyout .wff-menu-item:hover .wff-label {
138
- right: calc(100% + 55px);
139
- }
140
-
141
- #wf-flyout .wff-menu-item .wff-label {
142
- right: calc(100% + 70px);
143
- }
144
-
145
- #wf-flyout .wff-menu-item .dashicons {
146
- line-height: 41px;
147
- font-size: 23px;
148
- color: #fff;
149
- padding: 0px 3px 0px 0;
150
- }
151
-
152
- .wff-menu-item-1 {
153
- bottom: 75px;
154
- transition: transform 0.2s 30ms, background-color 0.2s;
155
- }
156
-
157
- .wff-menu-item-2 {
158
- bottom: 130px;
159
- transition: transform 0.2s 70ms, background-color 0.2s;
160
- }
161
-
162
- .wff-menu-item-3 {
163
- bottom: 185px;
164
- transition: transform 0.2s 110ms, background-color 0.2s;
165
- }
166
-
167
- .wff-menu-item-4 {
168
- bottom: 240px;
169
- transition: transform 0.2s 150ms, background-color 0.2s;
170
- }
171
-
172
- .wff-menu-item-5 {
173
- bottom: 295px;
174
- transition: transform 0.2s 190ms, background-color 0.2s;
175
- }
176
-
177
- .wff-menu-item-6 {
178
- bottom: 350px;
179
- transition: transform 0.2s 230ms, background-color 0.2s;
180
- }
181
-
182
- .wff-menu-item-7 {
183
- bottom: 405px;
184
- transition: transform 0.2s 270ms, background-color 0.2s;
185
- }
186
-
187
- .wff-menu-item-8 {
188
- bottom: 460px;
189
- transition: transform 0.2s 310ms, background-color 0.2s;
190
- }
191
-
192
- .wff-menu-item-9 {
193
- bottom: 515px;
194
- transition: transform 0.2s 350ms, background-color 0.2s;
195
- }
196
-
197
- .wff-menu-item-10 {
198
- bottom: 570px;
199
- transition: transform 0.2s 390ms, background-color 0.2s;
200
- }
1
+ /**
2
+ * Universal fly-out menu for XplodedThemes plugins
3
+ * (c) XplodedThemes, 2021
4
+ */
5
+
6
+ #wf-flyout {
7
+ position: fixed;
8
+ z-index: 100049;
9
+ transition: all 0.3s ease-in-out;
10
+ right: 40px;
11
+ bottom: 40px;
12
+ opacity: 1;
13
+ }
14
+
15
+ #wff-overlay {
16
+ background: #000;
17
+ opacity: 0.4;
18
+ filter: alpha(opacity=40);
19
+ position: fixed;
20
+ top: 0;
21
+ right: 0;
22
+ bottom: 0;
23
+ left: 0;
24
+ display: none;
25
+ z-index: 100049;
26
+ }
27
+
28
+ #wf-flyout a:focus {
29
+ outline: none;
30
+ box-shadow: none;
31
+ }
32
+
33
+ #wf-flyout #wff-button {
34
+ display: block;
35
+ }
36
+
37
+ #wf-flyout #wff-image-wrapper {
38
+ border: 3px solid #000000;
39
+ border-radius: 50%;
40
+ padding: 0;
41
+ display: block;
42
+ overflow: hidden;
43
+ background: #ffffff;
44
+ box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
45
+ }
46
+
47
+ #wf-flyout #wff-button img {
48
+ width: 55px;
49
+ height: 55px;
50
+ display: block;
51
+ overflow: hidden;
52
+ padding: 2px;
53
+ background: #ffffff;
54
+ box-sizing: border-box;
55
+ }
56
+
57
+ #wf-flyout #wff-button:hover #wff-image-wrapper {
58
+ box-shadow: 0 3px 30px rgba(0, 0, 0, 0.25);
59
+ }
60
+
61
+ #wf-flyout:not(.opened) #wff-button:hover .wff-label {
62
+ opacity: 1;
63
+ margin-right: 0;
64
+ }
65
+
66
+ #wf-flyout .wff-label {
67
+ position: absolute;
68
+ display: block;
69
+ top: 50%;
70
+ right: calc(100% + 25px);
71
+ transform: translateY(-50%) scale(1);
72
+ -moz-transform: translateY(-50%);
73
+ -webkit-transform: translateY(-50%);
74
+ color: #fff;
75
+ background: #444 0 0 no-repeat padding-box;
76
+ font-size: 14px;
77
+ white-space: nowrap;
78
+ padding: 5px 10px;
79
+ height: auto !important;
80
+ line-height: initial;
81
+ transition: all 0.2s ease-out;
82
+ border-radius: 3px;
83
+ -moz-border-radius: 3px;
84
+ -webkit-border-radius: 3px;
85
+ opacity: 0;
86
+ margin-right: -50px;
87
+ }
88
+
89
+ #wf-flyout .wff-icon {
90
+ width: 40px;
91
+ height: 40px;
92
+ vertical-align: middle;
93
+ line-height: 60px;
94
+ text-align: center;
95
+ }
96
+
97
+ #wf-flyout .wff-icon img {
98
+ max-width: 80%;
99
+ filter: brightness(100);
100
+ }
101
+
102
+ #wf-flyout .wff-label.visible {
103
+ opacity: 1;
104
+ }
105
+
106
+ #wf-flyout .wff-menu-item {
107
+ position: absolute;
108
+ left: 10px;
109
+ width: 40px;
110
+ height: 40px;
111
+ opacity: 0;
112
+ visibility: hidden;
113
+ transform: scale(0);
114
+ border-radius: 50%;
115
+ box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
116
+ background: #0071a1;
117
+ text-align: center;
118
+ vertical-align: middle;
119
+ text-decoration: none;
120
+ transition-timing-function: ease-in-out;
121
+ }
122
+
123
+ #wf-flyout .wff-menu-item.accent {
124
+ background: #ca4a1f;
125
+ }
126
+
127
+ #wf-flyout.opened .wff-menu-item {
128
+ opacity: 1;
129
+ visibility: visible;
130
+ transform: scale(1);
131
+ }
132
+
133
+ #wf-flyout .wff-menu-item:hover {
134
+ box-shadow: 0 3px 30px rgba(0, 0, 0, 0.25);
135
+ }
136
+
137
+ #wf-flyout .wff-menu-item:hover .wff-label {
138
+ right: calc(100% + 55px);
139
+ }
140
+
141
+ #wf-flyout .wff-menu-item .wff-label {
142
+ right: calc(100% + 70px);
143
+ }
144
+
145
+ #wf-flyout .wff-menu-item .dashicons {
146
+ line-height: 41px;
147
+ font-size: 23px;
148
+ color: #fff;
149
+ padding: 0px 3px 0px 0;
150
+ }
151
+
152
+ .wff-menu-item-1 {
153
+ bottom: 75px;
154
+ transition: transform 0.2s 30ms, background-color 0.2s;
155
+ }
156
+
157
+ .wff-menu-item-2 {
158
+ bottom: 130px;
159
+ transition: transform 0.2s 70ms, background-color 0.2s;
160
+ }
161
+
162
+ .wff-menu-item-3 {
163
+ bottom: 185px;
164
+ transition: transform 0.2s 110ms, background-color 0.2s;
165
+ }
166
+
167
+ .wff-menu-item-4 {
168
+ bottom: 240px;
169
+ transition: transform 0.2s 150ms, background-color 0.2s;
170
+ }
171
+
172
+ .wff-menu-item-5 {
173
+ bottom: 295px;
174
+ transition: transform 0.2s 190ms, background-color 0.2s;
175
+ }
176
+
177
+ .wff-menu-item-6 {
178
+ bottom: 350px;
179
+ transition: transform 0.2s 230ms, background-color 0.2s;
180
+ }
181
+
182
+ .wff-menu-item-7 {
183
+ bottom: 405px;
184
+ transition: transform 0.2s 270ms, background-color 0.2s;
185
+ }
186
+
187
+ .wff-menu-item-8 {
188
+ bottom: 460px;
189
+ transition: transform 0.2s 310ms, background-color 0.2s;
190
+ }
191
+
192
+ .wff-menu-item-9 {
193
+ bottom: 515px;
194
+ transition: transform 0.2s 350ms, background-color 0.2s;
195
+ }
196
+
197
+ .wff-menu-item-10 {
198
+ bottom: 570px;
199
+ transition: transform 0.2s 390ms, background-color 0.2s;
200
+ }
wf-flyout/wf-flyout.js CHANGED
@@ -1,24 +1,24 @@
1
- /**
2
- * Universal fly-out menu for WebFactory plugins
3
- * (c) WebFactory Ltd, 2021
4
- */
5
-
6
- jQuery(document).ready(function ($) {
7
- $('#wff-button').on('click', function (e) {
8
- e.preventDefault();
9
-
10
- $('#wf-flyout').toggleClass('opened');
11
- $('#wff-overlay').toggle();
12
-
13
- return false;
14
- }); // open/close menu
15
-
16
- $('#wff-overlay').on('click', function (e) {
17
- e.preventDefault();
18
-
19
- $(this).hide();
20
- $('#wf-flyout').removeClass('opened');
21
-
22
- return false;
23
- }); // click on overlay - hide menu
24
- }); // jQuery ready
1
+ /**
2
+ * Universal fly-out menu for XplodedThemes plugins
3
+ * (c) XplodedThemes, 2021
4
+ */
5
+
6
+ jQuery(document).ready(function ($) {
7
+ $('#wff-button').on('click', function (e) {
8
+ e.preventDefault();
9
+
10
+ $('#wf-flyout').toggleClass('opened');
11
+ $('#wff-overlay').toggle();
12
+
13
+ return false;
14
+ }); // open/close menu
15
+
16
+ $('#wff-overlay').on('click', function (e) {
17
+ e.preventDefault();
18
+
19
+ $(this).hide();
20
+ $('#wf-flyout').removeClass('opened');
21
+
22
+ return false;
23
+ }); // click on overlay - hide menu
24
+ }); // jQuery ready
wf-flyout/wf-flyout.php CHANGED
@@ -1,167 +1,167 @@
1
- <?php
2
-
3
- /**
4
- * Universal fly-out menu for WebFactory plugins
5
- * (c) WebFactory Ltd, 2021
6
- */
7
-
8
-
9
- if (false == class_exists('wf_flyout')) {
10
- class wf_flyout
11
- {
12
- var $ver = 1.0;
13
- var $plugin_file = '';
14
- var $plugin_slug = '';
15
- var $config = array();
16
-
17
-
18
- function __construct($plugin_file)
19
- {
20
- $this->plugin_file = $plugin_file;
21
- $this->plugin_slug = basename(dirname($plugin_file));
22
- $this->load_config();
23
-
24
- if (!is_admin()) {
25
- return;
26
- } else {
27
- add_action('admin_init', array($this, 'init'));
28
- }
29
- } // __construct
30
-
31
-
32
- function load_config()
33
- {
34
- $config = array();
35
- require_once plugin_dir_path($this->plugin_file) . 'wf-flyout/config.php';
36
-
37
- $defaults = array(
38
- 'plugin_screen' => '',
39
- 'icon_border' => '#0000ff',
40
- 'icon_right' => '40px',
41
- 'icon_bottom' => '40px',
42
- 'icon_image' => '',
43
- 'icon_padding' => '2px',
44
- 'icon_size' => '55px',
45
- 'menu_accent_color' => '#ca4a1f',
46
- 'custom_css' => '',
47
- 'menu_items' => array(),
48
- );
49
-
50
- $config = array_merge($defaults, $config);
51
- if (!is_array($config['plugin_screen'])) {
52
- $config['plugin_screen'] = array($config['plugin_screen']);
53
- }
54
-
55
- $this->config = $config;
56
- } // load_config
57
-
58
-
59
- function is_plugin_screen()
60
- {
61
- $screen = get_current_screen();
62
-
63
- if (in_array($screen->id, $this->config['plugin_screen'])) {
64
- return true;
65
- } else {
66
- return false;
67
- }
68
- } // is_plugin_screen
69
-
70
-
71
- function init()
72
- {
73
- add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
74
- add_action('admin_head', array($this, 'admin_head'));
75
- add_action('admin_footer', array($this, 'admin_footer'));
76
- } // init
77
-
78
-
79
- function admin_enqueue_scripts()
80
- {
81
- if (false === $this->is_plugin_screen()) {
82
- return;
83
- }
84
-
85
- wp_enqueue_style('wf_flyout', plugin_dir_url($this->plugin_file) . 'wf-flyout/wf-flyout.css', array(), $this->ver);
86
- wp_enqueue_script('wf_flyout', plugin_dir_url($this->plugin_file) . 'wf-flyout/wf-flyout.js', array(), $this->ver, true);;
87
- } // admin_enqueue_scripts
88
-
89
-
90
- function admin_head()
91
- {
92
- if (false === $this->is_plugin_screen()) {
93
- return;
94
- }
95
-
96
- $out = '<style type="text/css">';
97
- $out .= '#wf-flyout {
98
- right: ' . $this->config['icon_right'] . ';
99
- bottom: ' . $this->config['icon_bottom'] . ';
100
- }';
101
- $out .= '#wf-flyout #wff-image-wrapper {
102
- border: ' . $this->config['icon_border'] . ';
103
- }';
104
- $out .= '#wf-flyout #wff-button img {
105
- padding: ' . $this->config['icon_padding'] . ';
106
- width: ' . $this->config['icon_size'] . ';
107
- height: ' . $this->config['icon_size'] . ';
108
- }';
109
- $out .= '#wf-flyout .wff-menu-item.accent {
110
- background: ' . $this->config['menu_accent_color'] . ';
111
- }';
112
- $out .= $this->config['custom_css'];
113
- $out .= '</style>';
114
-
115
- echo $out;
116
- } // admin_head
117
-
118
-
119
- function admin_footer()
120
- {
121
- if (false === $this->is_plugin_screen()) {
122
- return;
123
- }
124
-
125
- $out = '';
126
- $icons_url = plugin_dir_url($this->plugin_file) . 'wf-flyout/icons/';
127
- $default_link_item = array('class' => '', 'href' => '#', 'target' => '_blank', 'label' => '', 'icon' => '', 'data' => '');
128
-
129
- $out .= '<div id="wff-overlay"></div>';
130
-
131
- $out .= '<div id="wf-flyout">';
132
-
133
- $out .= '<a href="#" id="wff-button">';
134
- $out .= '<span class="wff-label">Open Quick Links</span>';
135
- $out .= '<span id="wff-image-wrapper">';
136
- $out .= '<img src="' . $icons_url . $this->config['icon_image'] . '" alt="Open Quick Links" title="Open Quick Links">';
137
- $out .= '</span>';
138
- $out .= '</a>';
139
-
140
- $out .= '<div id="wff-menu">';
141
- $i = 0;
142
- foreach (array_reverse($this->config['menu_items']) as $item) {
143
- $i++;
144
- $item = array_merge($default_link_item, $item);
145
-
146
- if (!empty($item['icon']) && substr($item['icon'], 0, 9) != 'dashicons') {
147
- $item['class'] .= ' wff-custom-icon';
148
- $item['class'] = trim($item['class']);
149
- }
150
-
151
- $out .= '<a ' . $item['data'] . ' href="' . $item['href'] . '" class="wff-menu-item wff-menu-item-' . $i . ' ' . $item['class'] . '" target="_blank">';
152
- $out .= '<span class="wff-label visible">' . $item['label'] . '</span>';
153
- if (substr($item['icon'], 0, 9) == 'dashicons') {
154
- $out .= '<span class="dashicons ' . $item['icon'] . '"></span>';
155
- } elseif (!empty($item['icon'])) {
156
- $out .= '<span class="wff-icon"><img src="' . $icons_url . $item['icon'] . '"></span>';
157
- }
158
- $out .= '</a>';
159
- } // foreach
160
- $out .= '</div>'; // #wff-menu
161
-
162
- $out .= '</div>'; // #wf-flyout
163
-
164
- echo $out;
165
- } // admin_footer
166
- } // wf_flyout
167
- } // if class exists
1
+ <?php
2
+
3
+ /**
4
+ * Universal fly-out menu for XplodedThemes plugins
5
+ * (c) XplodedThemes, 2021
6
+ */
7
+
8
+
9
+ if (false == class_exists('wf_flyout')) {
10
+ class wf_flyout
11
+ {
12
+ var $ver = 1.0;
13
+ var $plugin_file = '';
14
+ var $plugin_slug = '';
15
+ var $config = array();
16
+
17
+
18
+ function __construct($plugin_file)
19
+ {
20
+ $this->plugin_file = $plugin_file;
21
+ $this->plugin_slug = basename(dirname($plugin_file));
22
+ $this->load_config();
23
+
24
+ if (!is_admin()) {
25
+ return;
26
+ } else {
27
+ add_action('admin_init', array($this, 'init'));
28
+ }
29
+ } // __construct
30
+
31
+
32
+ function load_config()
33
+ {
34
+ $config = array();
35
+ require_once plugin_dir_path($this->plugin_file) . 'wf-flyout/config.php';
36
+
37
+ $defaults = array(
38
+ 'plugin_screen' => '',
39
+ 'icon_border' => '#0000ff',
40
+ 'icon_right' => '40px',
41
+ 'icon_bottom' => '40px',
42
+ 'icon_image' => '',
43
+ 'icon_padding' => '2px',
44
+ 'icon_size' => '55px',
45
+ 'menu_accent_color' => '#ca4a1f',
46
+ 'custom_css' => '',
47
+ 'menu_items' => array(),
48
+ );
49
+
50
+ $config = array_merge($defaults, $config);
51
+ if (!is_array($config['plugin_screen'])) {
52
+ $config['plugin_screen'] = array($config['plugin_screen']);
53
+ }
54
+
55
+ $this->config = $config;
56
+ } // load_config
57
+
58
+
59
+ function is_plugin_screen()
60
+ {
61
+ $screen = get_current_screen();
62
+
63
+ if (in_array($screen->id, $this->config['plugin_screen'])) {
64
+ return true;
65
+ } else {
66
+ return false;
67
+ }
68
+ } // is_plugin_screen
69
+
70
+
71
+ function init()
72
+ {
73
+ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
74
+ add_action('admin_head', array($this, 'admin_head'));
75
+ add_action('admin_footer', array($this, 'admin_footer'));
76
+ } // init
77
+
78
+
79
+ function admin_enqueue_scripts()
80
+ {
81
+ if (false === $this->is_plugin_screen()) {
82
+ return;
83
+ }
84
+
85
+ wp_enqueue_style('wf_flyout', plugin_dir_url($this->plugin_file) . 'wf-flyout/wf-flyout.css', array(), $this->ver);
86
+ wp_enqueue_script('wf_flyout', plugin_dir_url($this->plugin_file) . 'wf-flyout/wf-flyout.js', array(), $this->ver, true);;
87
+ } // admin_enqueue_scripts
88
+
89
+
90
+ function admin_head()
91
+ {
92
+ if (false === $this->is_plugin_screen()) {
93
+ return;
94
+ }
95
+
96
+ $out = '<style type="text/css">';
97
+ $out .= '#wf-flyout {
98
+ right: ' . $this->config['icon_right'] . ';
99
+ bottom: ' . $this->config['icon_bottom'] . ';
100
+ }';
101
+ $out .= '#wf-flyout #wff-image-wrapper {
102
+ border: ' . $this->config['icon_border'] . ';
103
+ }';
104
+ $out .= '#wf-flyout #wff-button img {
105
+ padding: ' . $this->config['icon_padding'] . ';
106
+ width: ' . $this->config['icon_size'] . ';
107
+ height: ' . $this->config['icon_size'] . ';
108
+ }';
109
+ $out .= '#wf-flyout .wff-menu-item.accent {
110
+ background: ' . $this->config['menu_accent_color'] . ';
111
+ }';
112
+ $out .= $this->config['custom_css'];
113
+ $out .= '</style>';
114
+
115
+ echo $out;
116
+ } // admin_head
117
+
118
+
119
+ function admin_footer()
120
+ {
121
+ if (false === $this->is_plugin_screen()) {
122
+ return;
123
+ }
124
+
125
+ $out = '';
126
+ $icons_url = plugin_dir_url($this->plugin_file) . 'wf-flyout/icons/';
127
+ $default_link_item = array('class' => '', 'href' => '#', 'target' => '_blank', 'label' => '', 'icon' => '', 'data' => '');
128
+
129
+ $out .= '<div id="wff-overlay"></div>';
130
+
131
+ $out .= '<div id="wf-flyout">';
132
+
133
+ $out .= '<a href="#" id="wff-button">';
134
+ $out .= '<span class="wff-label">Open Quick Links</span>';
135
+ $out .= '<span id="wff-image-wrapper">';
136
+ $out .= '<img src="' . $icons_url . $this->config['icon_image'] . '" alt="Open Quick Links" title="Open Quick Links">';
137
+ $out .= '</span>';
138
+ $out .= '</a>';
139
+
140
+ $out .= '<div id="wff-menu">';
141
+ $i = 0;
142
+ foreach (array_reverse($this->config['menu_items']) as $item) {
143
+ $i++;
144
+ $item = array_merge($default_link_item, $item);
145
+
146
+ if (!empty($item['icon']) && substr($item['icon'], 0, 9) != 'dashicons') {
147
+ $item['class'] .= ' wff-custom-icon';
148
+ $item['class'] = trim($item['class']);
149
+ }
150
+
151
+ $out .= '<a ' . $item['data'] . ' href="' . $item['href'] . '" class="wff-menu-item wff-menu-item-' . $i . ' ' . $item['class'] . '" target="_blank">';
152
+ $out .= '<span class="wff-label visible">' . $item['label'] . '</span>';
153
+ if (substr($item['icon'], 0, 9) == 'dashicons') {
154
+ $out .= '<span class="dashicons ' . $item['icon'] . '"></span>';
155
+ } elseif (!empty($item['icon'])) {
156
+ $out .= '<span class="wff-icon"><img src="' . $icons_url . $item['icon'] . '"></span>';
157
+ }
158
+ $out .= '</a>';
159
+ } // foreach
160
+ $out .= '</div>'; // #wff-menu
161
+
162
+ $out .= '</div>'; // #wf-flyout
163
+
164
+ echo $out;
165
+ } // admin_footer
166
+ } // wf_flyout
167
+ } // if class exists
wpide.php CHANGED
@@ -1,1459 +1,1456 @@
1
- <?php
2
- /*
3
- Plugin Name: WPide
4
- Plugin URI: https://wpide.com/
5
- Description: WordPress code editor with auto-completion of both WordPress and PHP functions with reference, syntax highlighting, line numbers, tabbed editing, automatic backup.
6
- Version: 2.5
7
- Author: WebFactory Ltd
8
- Author URI: https://www.webfactoryltd.com/
9
- Requires at least: 5.0
10
- Requires PHP: 5.2
11
- Tested up to: 5.7
12
- Text Domain: wpide
13
-
14
- Copyright 2021 WebFactory Ltd (email: wpide@webfactoryltd.com)
15
- Copyright 2011 - 2021 Simon @ WPsites
16
-
17
- This program is free software; you can redistribute it and/or modify
18
- it under the terms of the GNU General Public License, version 2, as
19
- published by the Free Software Foundation.
20
-
21
- This program is distributed in the hope that it will be useful,
22
- but WITHOUT ANY WARRANTY; without even the implied warranty of
23
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
- GNU General Public License for more details.
25
-
26
- You should have received a copy of the GNU General Public License
27
- along with this program; if not, write to the Free Software
28
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
- */
30
-
31
- if (!defined('ABSPATH')) {
32
- die();
33
- }
34
-
35
- require_once 'wf-flyout/wf-flyout.php';
36
- new wf_flyout(__FILE__);
37
-
38
- if (!class_exists('wpide')) :
39
- class wpide
40
- {
41
-
42
- public $site_url, $plugin_url;
43
- private $menu_hook, $version;
44
-
45
-
46
- function __construct()
47
- {
48
-
49
- $this->get_plugin_version();
50
-
51
- // add WPide to the menu
52
- add_action('admin_menu', array($this, 'add_my_menu_page'));
53
-
54
- // hook for processing incoming image saves
55
- if (is_admin() && isset($_GET['wpide_save_image'])) {
56
-
57
- // force local file method for testing - you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
58
- $this->override_fs_method('direct');
59
-
60
- add_action('admin_init', array($this, 'wpide_save_image'));
61
- }
62
-
63
- add_action('admin_init', array($this, 'setup_hooks'));
64
-
65
- $this->site_url = get_bloginfo('url');
66
- }
67
-
68
-
69
- public function override_fs_method($method = 'direct')
70
- {
71
- if (defined('FS_METHOD')) {
72
- define('WPIDE_FS_METHOD_FORCED_ELSEWHERE', FS_METHOD); //make a note of the forced method
73
- } else {
74
- define('FS_METHOD', $method); //force direct
75
- }
76
- }
77
-
78
- function is_plugin_page()
79
- {
80
- $current_screen = get_current_screen();
81
-
82
- if ($current_screen->id === $this->menu_hook) {
83
- return true;
84
- } else {
85
- return false;
86
- }
87
- }
88
-
89
- // get plugin version from header
90
- function get_plugin_version()
91
- {
92
- $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
93
- $this->version = $plugin_data['version'];
94
-
95
- return $plugin_data['version'];
96
- } // get_plugin_version
97
-
98
-
99
- public function setup_hooks()
100
- {
101
- // force local file method until I've worked out how to implement the other methods
102
- // main problem being password wouldn't/isn't saved between requests
103
- // you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
104
- $this->override_fs_method('direct');
105
-
106
- // Will only enqueue on WPide page
107
- add_action('admin_print_scripts-' . $this->menu_hook, array($this, 'add_admin_js'));
108
- add_action('admin_print_styles-' . $this->menu_hook, array($this, 'add_admin_styles'));
109
-
110
- add_action('admin_print_footer_scripts', array($this, 'print_find_dialog'));
111
-
112
- //setup jqueryFiletree list callback
113
- add_action('wp_ajax_jqueryFileTree', array($this, 'jqueryFileTree_get_list'));
114
- //setup ajax function to get file contents for editing
115
- add_action('wp_ajax_wpide_get_file', array($this, 'wpide_get_file'));
116
- //setup ajax function to save file contents and do automatic backup if needed
117
- add_action('wp_ajax_wpide_save_file', array($this, 'wpide_save_file'));
118
- //setup ajax function to rename file/folder
119
- add_action('wp_ajax_wpide_rename_file', array($this, 'wpide_rename_file'));
120
- //setup ajax function to delete file/folder
121
- add_action('wp_ajax_wpide_delete_file', array($this, 'wpide_delete_file'));
122
- //setup ajax function to handle upload
123
- add_action('wp_ajax_wpide_upload_file', array($this, 'wpide_upload_file'));
124
- //setup ajax function to handle download
125
- add_action('wp_ajax_wpide_download_file', array($this, 'wpide_download_file'));
126
- //setup ajax function to unzip file
127
- add_action('wp_ajax_wpide_unzip_file', array($this, 'wpide_unzip_file'));
128
- //setup ajax function to zip file
129
- add_action('wp_ajax_wpide_zip_file', array($this, 'wpide_zip_file'));
130
- //setup ajax function to create new item (folder, file etc)
131
- add_action('wp_ajax_wpide_create_new', array($this, 'wpide_create_new'));
132
-
133
- //setup ajax function to create new item (folder, file etc)
134
- add_action('wp_ajax_wpide_image_edit_key', array($this, 'wpide_image_edit_key'));
135
-
136
- //setup ajax function for startup to get some debug info, checking permissions etc
137
- add_action('wp_ajax_wpide_startup_check', array($this, 'wpide_startup_check'));
138
-
139
- //add a warning when navigating away from WPide
140
- //it has to go after WordPress scripts otherwise WP clears the binding
141
- // This has been implemented in load-editor.js
142
- // todo:
143
- // add_action('admin_print_footer_scripts', array( $this, 'add_admin_nav_warning' ), 99);
144
-
145
- // Add body class to collapse the wp sidebar nav
146
- add_filter('admin_body_class', array($this, 'hide_wp_sidebar_nav'), 11);
147
-
148
- //hide the update nag
149
- add_action('admin_menu', array($this, 'hide_wp_update_nag'));
150
-
151
- add_filter(
152
- 'plugin_action_links_' . plugin_basename(__FILE__),
153
- array($this, 'plugin_action_links')
154
- );
155
- add_filter('admin_footer_text', array($this, 'admin_footer_text'));
156
- }
157
-
158
-
159
- // add settings link to plugins page
160
- function plugin_action_links($links)
161
- {
162
- $settings_link = '<a href="' . admin_url('admin.php?page=wpide') . '" title="Manage Files">Manage Files</a>';
163
-
164
- array_unshift($links, $settings_link);
165
-
166
- return $links;
167
- } // plugin_action_links
168
-
169
-
170
- // additional powered by text in admin footer; only on WPide page
171
- function admin_footer_text($text)
172
- {
173
- if (!$this->is_plugin_page()) {
174
- return $text;
175
- }
176
-
177
- $text = '<i><a href="https://wpide.com/" title="Visit WPide\'s site for more info" target="_blank">WPide</a> v' . $this->version . ' by <a href="https://www.webfactoryltd.com/" title="Visit our site to get more great plugins" target="_blank">WebFactory Ltd</a>. Please <a target="_blank" href="https://wordpress.org/support/plugin/wpide/reviews/#new-post" title="Rate the plugin">rate the plugin <span>★★★★★</span></a> to help us spread the word. Thank you!</i>';
178
-
179
- return $text;
180
- } // admin_footer_text
181
-
182
-
183
- public function hide_wp_sidebar_nav($classes)
184
- {
185
- global $hook_suffix;
186
-
187
- if (!$this->is_plugin_page()) {
188
- return $classes;
189
- }
190
-
191
- if (apply_filters('wpide_sidebar_folded', $hook_suffix === $this->menu_hook)) {
192
- return str_replace("auto-fold", "", $classes) . ' folded';
193
- }
194
- }
195
-
196
- public function hide_wp_update_nag()
197
- {
198
- if (!$this->is_plugin_page()) {
199
- return;
200
- }
201
-
202
- remove_action('admin_notices', 'update_nag', 3);
203
- }
204
-
205
- public function add_admin_nav_warning()
206
- {
207
- ?>
208
- <script type="text/javascript">
209
- jQuery(document).ready(function($) {
210
- window.onbeforeunload = function() {
211
- return 'You are attempting to navigate away from WPide. Make sure you have saved any changes made to your files otherwise they will be forgotten.';
212
- }
213
- });
214
- </script>
215
- <?php
216
- }
217
-
218
- public function add_admin_js()
219
- {
220
- $plugin_path = plugin_dir_url(__FILE__);
221
- //include file tree
222
- wp_enqueue_script('jquery-file-tree', plugins_url("js/jqueryFileTree.js", __FILE__));
223
- //include ace
224
- wp_enqueue_script('ace', plugins_url("js/ace-1.2.0/ace.js", __FILE__));
225
- //include ace modes for css, javascript & php
226
- wp_enqueue_script('ace-mode-css', $plugin_path . 'js/ace-1.2.0/mode-css.js');
227
- wp_enqueue_script('ace-mode-less', $plugin_path . 'js/ace-1.2.0/mode-less.js');
228
- wp_enqueue_script('ace-mode-javascript', $plugin_path . 'js/ace-1.2.0/mode-javascript.js');
229
- wp_enqueue_script('ace-mode-php', $plugin_path . 'js/ace-1.2.0/mode-php.js');
230
- //include ace theme
231
- wp_enqueue_script('ace-theme', plugins_url("js/ace-1.2.0/theme-dawn.js", __FILE__)); //ambiance looks really nice for high contrast
232
- // wordpress-completion tags
233
- wp_enqueue_script('wpide-wordpress-completion', plugins_url("js/autocomplete/wordpress.js", __FILE__));
234
- // php-completion tags
235
- wp_enqueue_script('wpide-php-completion', plugins_url("js/autocomplete/php.js", __FILE__));
236
- // load editor
237
- wp_enqueue_script('wpide-load-editor', plugins_url("js/load-editor.js", __FILE__));
238
- // load filetree menu
239
- wp_enqueue_script('wpide-load-filetree-menu', plugins_url("js/load-filetree-menu.js", __FILE__));
240
- // load autocomplete dropdown
241
- wp_enqueue_script('wpide-dd', plugins_url("js/jquery.dd.js", __FILE__));
242
-
243
- // load jquery ui
244
- wp_enqueue_script('jquery-ui', plugins_url("js/jquery-ui-1.9.2.custom.min.js", __FILE__), array('jquery'), '1.9.2');
245
-
246
- // load color picker
247
- wp_enqueue_script('ImageColorPicker', plugins_url("js/ImageColorPicker.js", __FILE__), array('jquery'), '0.3');
248
- }
249
-
250
- public function add_admin_styles()
251
- {
252
- //main wpide styles
253
- wp_register_style('wpide_style', plugins_url('css/wpide.css', __FILE__));
254
- wp_enqueue_style('wpide_style');
255
- //filetree styles
256
- wp_register_style('wpide_filetree_style', plugins_url('css/jqueryFileTree.css', __FILE__));
257
- wp_enqueue_style('wpide_filetree_style');
258
- //autocomplete dropdown styles
259
- wp_register_style('wpide_dd_style', plugins_url('css/dd.css', __FILE__));
260
- wp_enqueue_style('wpide_dd_style');
261
-
262
- //jquery ui styles
263
- wp_register_style('wpide_jqueryui_style', plugins_url('css/flick/jquery-ui-1.8.20.custom.css', __FILE__));
264
- wp_enqueue_style('wpide_jqueryui_style');
265
- }
266
-
267
- public function jqueryFileTree_get_list()
268
- {
269
- //check the user has the permissions
270
- check_admin_referer('plugin-name-action_wpidenonce');
271
- if (!current_user_can('edit_themes'))
272
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
273
-
274
- //setup wp_filesystem api
275
- global $wp_filesystem;
276
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
277
- $form_fields = null; // for now, but at some point the login info should be passed in here
278
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
279
- // no credentials yet, just produced a form for the user to fill in
280
- return true; // stop the normal page form from displaying
281
- }
282
-
283
- if (!WP_Filesystem($creds))
284
- return false;
285
-
286
- $_POST['dir'] = urldecode($_POST['dir']);
287
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
288
-
289
- if ($wp_filesystem->exists($root . $_POST['dir'])) {
290
-
291
- $files = $wp_filesystem->dirlist($root . $_POST['dir']);
292
-
293
- echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
294
- if (count($files) > 0) {
295
-
296
- //build separate arrays for folders and files
297
- $dir_array = array();
298
- $file_array = array();
299
- foreach ($files as $file => $file_info) {
300
- if ($file != '.' && $file != '..' && $file_info['type'] == 'd') {
301
- $file_string = strtolower(preg_replace("[._-]", "", $file));
302
- $dir_array[$file_string] = $file_info;
303
- } elseif ($file != '.' && $file != '..' && $file_info['type'] == 'f') {
304
- $file_string = strtolower(preg_replace("[._-]", "", $file));
305
- $file_array[$file_string] = $file_info;
306
- }
307
- }
308
-
309
- //shot those arrays
310
- ksort($dir_array);
311
- ksort($file_array);
312
-
313
- // All dirs
314
- foreach ($dir_array as $file => $file_info) {
315
- echo "<li class=\"directory collapsed\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "/\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
316
- }
317
- // All files
318
- foreach ($file_array as $file => $file_info) {
319
- $ext = preg_replace('/^.*\./', '', $file_info['name']);
320
- echo "<li class=\"file ext_$ext\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
321
- }
322
- }
323
- //output toolbar for creating new file, folder etc
324
- echo "<li class=\"create_new\"><a class='new_directory' title='Create a new directory here.' href=\"#\" rel=\"{type: 'directory', path: '" . htmlentities($_POST['dir']) . "'}\"></a> <a class='new_file' title='Create a new file here.' href=\"#\" rel=\"{type: 'file', path: '" . htmlentities($_POST['dir']) . "'}\"></a><br style='clear:both;' /></li>";
325
- echo "</ul>";
326
- }
327
-
328
- die(); // this is required to return a proper result
329
- }
330
-
331
-
332
- public function wpide_get_file()
333
- {
334
- //check the user has the permissions
335
- check_admin_referer('plugin-name-action_wpidenonce');
336
- if (!current_user_can('edit_themes'))
337
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
338
-
339
- //setup wp_filesystem api
340
- global $wp_filesystem;
341
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
342
- $form_fields = null; // for now, but at some point the login info should be passed in here
343
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
344
- // no credentials yet, just produced a form for the user to fill in
345
- return true; // stop the normal page form from displaying
346
- }
347
- if (!WP_Filesystem($creds))
348
- return false;
349
-
350
-
351
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
352
- $file_name = $root . stripslashes($_POST['filename']);
353
- echo $wp_filesystem->get_contents($file_name);
354
- die(); // this is required to return a proper result
355
- }
356
-
357
- public function wpide_image_edit_key()
358
- {
359
-
360
- //check the user has the permissions
361
- check_admin_referer('plugin-name-action_wpidenonce');
362
- if (!current_user_can('edit_themes')) {
363
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
364
- }
365
-
366
- //create a nonce based on the image path
367
- echo wp_create_nonce('wpide_image_edit' . $_POST['file']);
368
- }
369
-
370
- public function wpide_create_new()
371
- {
372
- //check the user has the permissions
373
- check_admin_referer('plugin-name-action_wpidenonce');
374
- if (!current_user_can('edit_themes')) {
375
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
376
- }
377
-
378
- //setup wp_filesystem api
379
- global $wp_filesystem;
380
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
381
- $form_fields = null; // for now, but at some point the login info should be passed in here
382
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
383
- // no credentials yet, just produced a form for the user to fill in
384
- return true; // stop the normal page form from displaying
385
- }
386
- if (!WP_Filesystem($creds))
387
- return false;
388
-
389
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
390
-
391
- //check all required vars are passed
392
- if (strlen($_POST['path']) > 0 && strlen($_POST['type']) > 0 && strlen($_POST['file']) > 0) {
393
- $filename = $_POST['file'];
394
- $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0));
395
- $filename = preg_replace("#\x{00a0}#siu", ' ', $filename);
396
- $filename = str_replace($special_chars, '', $filename);
397
- $filename = str_replace(array('%20', '+'), '-', $filename);
398
- $filename = preg_replace('/[\r\n\t -]+/', '-', $filename);
399
-
400
- $path = $_POST['path'];
401
-
402
- if ($_POST['type'] == "directory") {
403
- $write_result = $wp_filesystem->mkdir($root . $path . $filename, FS_CHMOD_DIR);
404
-
405
- if ($write_result) {
406
- die("1"); //created
407
- } else {
408
- echo "Problem creating directory" . $root . $path . $filename;
409
- }
410
- } else if ($_POST['type'] == "file") {
411
- //write the file
412
- $write_result = $wp_filesystem->put_contents(
413
- $root . $path . $filename,
414
- '',
415
- FS_CHMOD_FILE // predefined mode settings for WP files
416
- );
417
-
418
- if ($write_result) {
419
- die("1"); //created
420
- } else {
421
- echo "Problem creating file " . $root . $path . $filename;
422
- }
423
- }
424
- //print_r($_POST);
425
- }
426
-
427
- echo "0";
428
- die(); // this is required to return a proper result
429
- }
430
-
431
- public function wpide_save_file()
432
- {
433
- //check the user has the permissions
434
- check_admin_referer('plugin-name-action_wpidenonce');
435
- if (!current_user_can('edit_themes')) {
436
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
437
- }
438
-
439
- $is_php = false;
440
-
441
- /*
442
- * Check file syntax of PHP files by parsing the PHP
443
- * If a site is running low on memory this PHP parser library could well tip memory usage over the edge
444
- * Especially if you are editing a large PHP file.
445
- * Might be worth either making this syntax check optional or it only running if memory is available.
446
- * Symptoms: no response on file save, and errors in your log like "Fatal error: Allowed memory size of 8388608 bytes exhausted…"
447
- */
448
- if (preg_match("#\.php$#i", $_POST['filename'])) {
449
-
450
- $is_php = true;
451
-
452
- require('PHP-Parser/lib/bootstrap.php');
453
- ini_set('xdebug.max_nesting_level', 2000);
454
-
455
- $code = stripslashes($_POST['content']);
456
-
457
- $parser = new PHPParser_Parser(new PHPParser_Lexer);
458
-
459
- try {
460
- $stmts = $parser->parse($code);
461
- } catch (PHPParser_Error $e) {
462
- echo 'Parse Error: ', $e->getMessage();
463
- die();
464
- }
465
- }
466
-
467
- //setup wp_filesystem api
468
- global $wp_filesystem;
469
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
470
- $form_fields = null; // for now, but at some point the login info should be passed in here
471
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
472
- // no credentials yet, just produced a form for the user to fill in
473
- return true; // stop the normal page form from displaying
474
- }
475
- if (!WP_Filesystem($creds))
476
- echo "Cannot initialise the WP file system API";
477
-
478
- //save a copy of the file and create a backup just in case
479
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
480
- $file_name = $root . stripslashes($_POST['filename']);
481
-
482
- //set backup filename
483
- $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
484
- $backup_path_full = plugin_dir_path(__FILE__) . $backup_path;
485
- //create backup directory if not there
486
- $new_file_info = pathinfo($backup_path_full);
487
- if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
488
-
489
- if ($is_php) {
490
- //create the backup file adding some php to the file to enable direct restore
491
- global $current_user;
492
- get_currentuserinfo();
493
- $user_md5 = md5(serialize($current_user));
494
-
495
- $restore_php = '<?php /* start WPide restore code */
496
- if ($_POST["restorewpnonce"] === "' . $user_md5 . $_POST['_wpnonce'] . '"){
497
- if ( file_put_contents ( "' . $file_name . '" , preg_replace("#<\?php /\* start WPide(.*)end WPide restore code \*/ \?>#s", "", file_get_contents("' . $backup_path_full . '") ) ) ){
498
- echo "Your file has been restored, overwritting the recently edited file! \n\n The active editor still contains the broken or unwanted code. If you no longer need that content then close the tab and start fresh with the restored file.";
499
- }
500
- }else{
501
- echo "-1";
502
- }
503
- die();
504
- /* end WPide restore code */ ?>';
505
-
506
- file_put_contents($backup_path_full, $restore_php . file_get_contents($file_name));
507
- } else {
508
- //do normal backup
509
- $wp_filesystem->copy($file_name, $backup_path_full);
510
- }
511
-
512
- //save file
513
- if ($wp_filesystem->put_contents($file_name, stripslashes($_POST['content']))) {
514
-
515
- //lets create an extra long nonce to make it less crackable
516
- global $current_user;
517
- get_currentuserinfo();
518
- $user_md5 = md5(serialize($current_user));
519
-
520
- $result = "\"" . $backup_path . ":::" . $user_md5 . "\"";
521
- }
522
-
523
- die($result); // this is required to return a proper result
524
- }
525
-
526
-
527
- public function wpide_rename_file()
528
- {
529
- global $wp_filesystem;
530
-
531
- //check the user has the permissions
532
- check_admin_referer('plugin-name-action_wpidenonce');
533
- if (!current_user_can('manage_options')) {
534
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
535
- }
536
-
537
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
538
- $form_fields = null; // for now, but at some point the login info should be passed in here
539
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
540
- if (false === $creds) {
541
- // no credentials yet, just produced a form for the user to fill in
542
- return true; // stop the normal page form from displaying
543
- }
544
- if (!WP_Filesystem($creds))
545
- echo "Cannot initialise the WP file system API";
546
-
547
-
548
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
549
- $file_name = $root . stripslashes($_POST['filename']);
550
- $new_name = dirname($file_name) . '/' . stripslashes($_POST['newname']);
551
-
552
- if (!$wp_filesystem->exists($file_name)) {
553
- echo 'The target file doesn\'t exist!';
554
- exit;
555
- }
556
-
557
- if ($wp_filesystem->exists($new_name)) {
558
- echo 'The destination file exists!';
559
- exit;
560
- }
561
-
562
- // Move instead of rename
563
- $renamed = $wp_filesystem->move($file_name, $new_name);
564
-
565
- if (!$renamed) {
566
- echo 'The file could not be renamed!';
567
- }
568
- exit;
569
- }
570
-
571
-
572
- public function wpide_delete_file()
573
- {
574
- global $wp_filesystem;
575
-
576
- //check the user has the permissions
577
- check_admin_referer('plugin-name-action_wpidenonce');
578
- if (!current_user_can('manage_options')) {
579
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
580
- }
581
-
582
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
583
- $form_fields = null; // for now, but at some point the login info should be passed in here
584
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
585
- if (false === $creds) {
586
- // no credentials yet, just produced a form for the user to fill in
587
- return true; // stop the normal page form from displaying
588
- }
589
- if (!WP_Filesystem($creds))
590
- echo "Cannot initialise the WP file system API";
591
-
592
-
593
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
594
- $file_name = $root . stripslashes($_POST['filename']);
595
-
596
- if (!$wp_filesystem->exists($file_name)) {
597
- echo 'The file doesn\'t exist!';
598
- exit;
599
- }
600
-
601
- $deleted = $wp_filesystem->delete($file_name);
602
-
603
- if (!$deleted) {
604
- echo 'The file couldn\'t be deleted.';
605
- }
606
-
607
- exit;
608
- }
609
-
610
- public function wpide_upload_file()
611
- {
612
- global $wp_filesystem;
613
-
614
- //check the user has the permissions
615
- check_admin_referer('plugin-name-action_wpidenonce');
616
- if (!current_user_can('manage_options')) {
617
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
618
- }
619
-
620
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
621
- $form_fields = null; // for now, but at some point the login info should be passed in here
622
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
623
- if (false === $creds) {
624
- // no credentials yet, just produced a form for the user to fill in
625
- return true; // stop the normal page form from displaying
626
- }
627
- if (!WP_Filesystem($creds))
628
- echo "Cannot initialise the WP file system API";
629
-
630
-
631
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
632
- $destination_folder = $root . stripslashes($_POST['destination']);
633
-
634
- foreach ($_FILES as $file) {
635
- if (!is_uploaded_file($file['tmp_name'])) {
636
- continue;
637
- }
638
-
639
- $destination = $destination_folder . $file['name'];
640
-
641
- if ($wp_filesystem->exists($destination)) {
642
- exit($file['name'] . ' already exists!');
643
- }
644
-
645
- if (!$wp_filesystem->move($file['tmp_name'], $destination)) {
646
- exit($file['name'] . ' could not be moved.');
647
- }
648
-
649
- if (!$wp_filesystem->chmod($destination)) {
650
- exit($file['name'] . ' could not be chmod.');
651
- }
652
- }
653
- exit;
654
- }
655
-
656
- public function wpide_download_file()
657
- {
658
- global $wp_filesystem;
659
-
660
- //check the user has the permissions
661
- check_admin_referer('plugin-name-action_wpidenonce');
662
- if (!current_user_can('manage_options')) {
663
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
664
- }
665
-
666
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
667
- $form_fields = null; // for now, but at some point the login info should be passed in here
668
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
669
- if (false === $creds) {
670
- // no credentials yet, just produced a form for the user to fill in
671
- return true; // stop the normal page form from displaying
672
- }
673
- if (!WP_Filesystem($creds))
674
- echo "Cannot initialise the WP file system API";
675
-
676
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
677
- $file_name = $root . stripslashes($_POST['filename']);
678
-
679
- if (!$wp_filesystem->exists($file_name)) {
680
- echo 'The file doesn\'t exist!';
681
- exit;
682
- }
683
-
684
- header('Content-Description: File Transfer');
685
- header('Content-Type: application/octet-stream');
686
- header('Content-Disposition: filename="' . basename($file_name) . '"');
687
- header('Expires: 0');
688
- header('Cache-Control: must-revalidate');
689
- header('Pragma: public');
690
-
691
- echo $wp_filesystem->get_contents($file_name);
692
- exit;
693
- }
694
-
695
- public function wpide_zip_file()
696
- {
697
- global $wp_filesystem;
698
-
699
- //check the user has the permissions
700
- check_admin_referer('plugin-name-action_wpidenonce');
701
- if (!current_user_can('manage_options')) {
702
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
703
- }
704
-
705
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
706
- $file_name = $root . stripslashes($_POST['filename']);
707
-
708
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
709
- $form_fields = null; // for now, but at some point the login info should be passed in here
710
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
711
- if (false === $creds) {
712
- // no credentials yet, just produced a form for the user to fill in
713
- return true; // stop the normal page form from displaying
714
- }
715
- if (!WP_Filesystem($creds))
716
- echo "Cannot initialise the WP file system API";
717
-
718
-
719
- if (!$wp_filesystem->exists($file_name)) {
720
- echo 'Error: target file does not exist!';
721
- exit;
722
- }
723
-
724
- $ext = '.zip';
725
- switch (apply_filters('wpide_compression_method', 'zip')) {
726
- case 'gz':
727
- $ext = '.tar.gz';
728
- break;
729
- case 'tar':
730
- $ext = '.tar';
731
- break;
732
- case 'b2z':
733
- $ext = '.b2z';
734
- break;
735
- case 'zip':
736
- $ext = '.zip';
737
- break;
738
- }
739
-
740
- // Unzip a file to its current directory.
741
- if ($wp_filesystem->is_dir($file_name)) {
742
- $output_path = dirname($file_name) . '/' . basename($file_name) . $ext;
743
- } else {
744
- $output_path = $file_name;
745
- $output_path = strstr($file_name, '.', true) . $ext;
746
- }
747
-
748
- $zipped = self::do_zip_file($file_name, $output_path);
749
-
750
- if (is_wp_error($zipped)) {
751
- printf('%s: %s', $zipped->get_error_code(), $zipped->get_error_message());
752
- exit;
753
- }
754
-
755
- exit;
756
- }
757
-
758
- protected function do_zip_file($file, $to)
759
- {
760
- // Unzip can use a lot of memory, but not this much hopefully
761
- @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
762
-
763
- $method = apply_filters('wpide_compression_method', 'zip');
764
-
765
- switch ($method) {
766
- case 'gz':
767
- case 'tar':
768
- if (class_exists('PharData') && apply_filters('unzip_file_use_phardata', true)) {
769
- exit('yes');
770
- return self::_zip_archive_phardata($file, $to);
771
- } else {
772
- exit('figure it out');
773
- }
774
-
775
- /* if ( $method === 'gz' ) {
776
- $gz = gzopen( $to );
777
- }
778
- */
779
- break;
780
- case 'b2z':
781
- exit('B2Z!');
782
- case 'zip':
783
- default:
784
- if ($method !== 'zip') {
785
- trigger_error(sprintf('"%s" is not a valid compression mechanism.', $method));
786
- }
787
-
788
- if (class_exists('ZipArchive') && apply_filters('unzip_file_use_ziparchive', true)) {
789
- return self::_zip_file_ziparchive($file, $to);
790
- } else {
791
- // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
792
- return self::_zip_file_pclzip($file, $to);
793
- }
794
- break;
795
- }
796
- }
797
-
798
- protected static function _zip_file_ziparchive($file, $to)
799
- {
800
- $z = new ZipArchive;
801
- $opened = $z->open($to, ZipArchive::CREATE);
802
-
803
- if ($opened !== true) {
804
- switch ($opened) {
805
- case ZipArchive::ER_EXISTS:
806
- return new WP_Error(
807
- 'ZipArchive Error',
808
- 'File already exists',
809
- ZipArchive::ER_EXISTS
810
- );
811
- case ZipArchive::ER_INCONS:
812
- return new WP_Error(
813
- 'ZipArchive Error',
814
- 'Archive inconsistent',
815
- ZipArchive::ER_INCONS
816
- );
817
- case ZipArchive::ER_INVAL:
818
- return new WP_Error(
819
- 'ZipArchive Error',
820
- 'Invalid argument',
821
- ZipArchive::ER_INVAL
822
- );
823
- case ZipArchive::ER_MEMORY:
824
- return new WP_Error(
825
- 'ZipArchive Error',
826
- 'Malloc failure',
827
- ZipArchive::ER_MEMORY
828
- );
829
- case ZipArchive::ER_NOENT:
830
- return new WP_Error(
831
- 'ZipArchive Error',
832
- 'No such file.',
833
- ZipArchive::ER_NOENT
834
- );
835
- case ZipArchive::ER_NOZIP:
836
- return new WP_Error(
837
- 'ZipArchive Error',
838
- 'Not a zip archive.',
839
- ZipArchive::ER_NOZIP
840
- );
841
- case ZipArchive::ER_OPEN:
842
- return new WP_Error(
843
- 'ZipArchive Error',
844
- 'Can\'t open file.',
845
- ZipArchive::ER_OPEN
846
- );
847
- case ZipArchive::ER_READ:
848
- return new WP_Error(
849
- 'ZipArchive Error',
850
- 'Read Error',
851
- ZipArchive::ER_READ
852
- );
853
- case ZipArchive::ER_SEEK:
854
- return new WP_Error(
855
- 'ZipArchive Error',
856
- 'Seek Error',
857
- ZipArchive::ER_SEEK
858
- );
859
-
860
- default:
861
- return new WP_Error(
862
- 'ZipArchive Error',
863
- 'Unknown Error',
864
- $opened
865
- );
866
- break;
867
- }
868
- }
869
-
870
- if (is_dir($file)) {
871
- $base = dirname($file);
872
- $file = untrailingslashit($file);
873
-
874
- $z = self::_zip_folder_ziparchive($base, $file, $to, $z);
875
- if (is_wp_error($z))
876
- return $z;
877
- } else {
878
- $z->addFile($file, basename($file));
879
- }
880
-
881
- $z->close();
882
-
883
- return true;
884
- }
885
-
886
- protected static function _zip_folder_ziparchive($zip_base, $folder, $to, $z)
887
- {
888
- $handle = opendir($folder);
889
- while (1) {
890
- $file = readdir($handle);
891
-
892
- if (false === $file)
893
- break;
894
-
895
- if (($file != '.') && ($file != '..')) {
896
- $filePath = "$folder/$file";
897
- $filePathRel = str_replace($zip_base, '', $filePath);
898
-
899
- if ($filePathRel[0] === '/')
900
- $filePathRel = substr($filePathRel, 1);
901
-
902
- if (is_file($filePath)) {
903
- $z->addFile($filePath, $filePathRel);
904
- } elseif (is_dir($filePath)) {
905
- // Add sub-directory.
906
- $z->addEmptyDir($filePathRel);
907
- self::_zip_folder_ziparchive($zip_base, $filePath, $to, $z);
908
- }
909
- }
910
- }
911
- closedir($handle);
912
-
913
- return $z;
914
- }
915
-
916
- protected static function _zip_file_pclzip($file, $to)
917
- {
918
- require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
919
-
920
- $pz = new PclZip($to);
921
- $created = $pz->create($file, PCLZIP_OPT_REMOVE_PATH, dirname($file));
922
-
923
- if (!$created) {
924
- return new WP_Error('PclZip Error', $pz->errorInfo(true));
925
- }
926
-
927
- return true;
928
- }
929
-
930
- protected static function _zip_file_phardata($file, $to)
931
- {
932
- $p = new PharData($to);
933
-
934
- if (is_dir($file)) {
935
- $p->buildFromDirectory($file);
936
- } else {
937
- $p->addFile($file, basename($file));
938
- }
939
-
940
- return true;
941
- }
942
-
943
- public function wpide_unzip_file()
944
- {
945
- global $wp_filesystem;
946
-
947
- //check the user has the permissions
948
- check_admin_referer('plugin-name-action_wpidenonce');
949
- if (!current_user_can('manage_options')) {
950
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
951
- }
952
-
953
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
954
- $file_name = $root . stripslashes($_POST['filename']);
955
-
956
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
957
- $form_fields = null; // for now, but at some point the login info should be passed in here
958
- $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
959
- if (false === $creds) {
960
- // no credentials yet, just produced a form for the user to fill in
961
- return true; // stop the normal page form from displaying
962
- }
963
- if (!WP_Filesystem($creds))
964
- echo "Cannot initialise the WP file system API";
965
-
966
-
967
- if (!$wp_filesystem->exists($file_name)) {
968
- echo 'Error: Extraction path doesn\'t exist!';
969
- exit;
970
- }
971
-
972
- $unzipped = self::do_unzip_file($file_name, dirname($file_name));
973
-
974
- if (is_wp_error($unzipped)) {
975
- printf('%s: %s', $unzipped->get_error_code(), $unzipped->get_error_message());
976
- exit;
977
- }
978
-
979
- exit;
980
- }
981
-
982
- protected function do_unzip_file($from, $to)
983
- {
984
- if (!file_exists($from)) {
985
- return new WP_Error('file-missing', 'Archive missing.');
986
- }
987
-
988
- $fp = fopen($from, 'rb');
989
- $bytes = fread($fp, 2);
990
- fclose($fp);
991
-
992
- switch ($bytes) {
993
- case "\37\213":
994
- // gz
995
- case 'BZ':
996
- return new WP_Error('unimplemented', 'That method is not yet implemented.');
997
- break;
998
- case 'PK':
999
- return unzip_file($from, $to);
1000
- default:
1001
- return new WP_Error('unknown', 'Unknown archive type');
1002
- }
1003
- }
1004
-
1005
- public function wpide_save_image()
1006
- {
1007
- $filennonce = split("::", $_POST["opt"]); //file::nonce
1008
-
1009
- //check the user has a valid nonce
1010
- //we are checking two variations of the nonce, one as-is and another that we have removed a trailing zero from
1011
- //this is to get around some sort of bug where a nonce generated on another page has a trailing zero and a nonce generated/checked here doesn't have the zero
1012
- if (
1013
- !wp_verify_nonce($filennonce[1], 'wpide_image_edit' . $filennonce[0]) &&
1014
- !wp_verify_nonce(rtrim($filennonce[1], "0"), 'wpide_image_edit' . $filennonce[0])
1015
- ) {
1016
- die('Security check'); //die because both checks failed
1017
- }
1018
- //check the user has the permissions
1019
- if (!current_user_can('edit_themes')) {
1020
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1021
- }
1022
-
1023
-
1024
- $_POST['content'] = base64_decode($_POST["data"]); //image content
1025
- $_POST['filename'] = $filennonce[0]; //filename
1026
-
1027
- //setup wp_filesystem api
1028
- global $wp_filesystem;
1029
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1030
- $form_fields = null; // for now, but at some point the login info should be passed in here
1031
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1032
- // no credentials yet, just produced a form for the user to fill in
1033
- return true; // stop the normal page form from displaying
1034
- }
1035
- if (!WP_Filesystem($creds))
1036
- echo "Cannot initialise the WP file system API";
1037
-
1038
- //save a copy of the file and create a backup just in case
1039
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1040
- $file_name = $root . stripslashes($_POST['filename']);
1041
-
1042
- //set backup filename
1043
- $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
1044
- $backup_path = plugin_dir_path(__FILE__) . $backup_path;
1045
-
1046
- //create backup directory if not there
1047
- $new_file_info = pathinfo($backup_path);
1048
- if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
1049
-
1050
- //do backup
1051
- $wp_filesystem->move($file_name, $backup_path);
1052
-
1053
- //save file
1054
- if ($wp_filesystem->put_contents($file_name, $_POST['content'])) {
1055
- $result = "success";
1056
- }
1057
-
1058
- if ($result == "success") {
1059
- wp_die('<p>' . __('<strong>Image saved.</strong> <br />You may <a href="JavaScript:window.close();">close this window / tab</a>.') . '</p>');
1060
- } else {
1061
- wp_die('<p>' . __('<strong>Problem saving image.</strong> <br /><a href="JavaScript:window.close();">Close this window / tab</a> and try editing the image again.') . '</p>');
1062
- }
1063
- //print_r($_POST);
1064
- }
1065
-
1066
-
1067
- public function wpide_startup_check()
1068
- {
1069
- global $wp_filesystem, $wp_version;
1070
-
1071
- echo "\n\n\n\nWPIDE STARTUP CHECKS \n";
1072
- echo "___________________ \n\n";
1073
-
1074
- // WordPress version
1075
- if ($wp_version > 5) {
1076
- echo "WordPress version = " . $wp_version . "\n\n";
1077
- } else {
1078
- echo "WordPress version = " . $wp_version . " (which is too old to run WPide) \n\n";
1079
- }
1080
-
1081
- //check the user has the permissions
1082
- check_admin_referer('plugin-name-action_wpidenonce');
1083
- if (!current_user_can('edit_themes'))
1084
- wp_die('<p>' . __('You do not have sufficient permissions to edit templates for this site. SORRY') . '</p>');
1085
-
1086
- if (defined('WPIDE_FS_METHOD_FORCED_ELSEWHERE')) {
1087
- echo "WordPress filesystem API has been forced to use the " . WPIDE_FS_METHOD_FORCED_ELSEWHERE . " method by another plugin/WordPress. \n\n";
1088
- }
1089
-
1090
- //setup wp_filesystem api
1091
- $wpide_filesystem_before = $wp_filesystem;
1092
-
1093
- $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1094
- $form_fields = null; // for now, but at some point the login info should be passed in here
1095
- ob_start();
1096
- if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1097
- // if we get here, then we don't have credentials yet,
1098
- // but have just produced a form for the user to fill in,
1099
- // so stop processing for now
1100
- //return true; // stop the normal page form from displaying
1101
- }
1102
- ob_end_clean();
1103
- if (!WP_Filesystem($creds)) {
1104
-
1105
- echo "There has been a problem initialising the filesystem API \n\n";
1106
- echo "Filesystem API before this plugin ran: \n\n" . print_r($wpide_filesystem_before, true);
1107
- echo "Filesystem API now: \n\n" . print_r($wp_filesystem, true);
1108
- }
1109
- unset($wpide_filesystem_before);
1110
-
1111
-
1112
- $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1113
- if (isset($wp_filesystem)) {
1114
-
1115
- //Running webservers user and group
1116
- echo "Web server user/group = " . getenv('APACHE_RUN_USER') . ":" . getenv('APACHE_RUN_GROUP') . "\n";
1117
- //wp-content user and group
1118
- echo "wp-content owner/group = " . $wp_filesystem->owner($root) . ":" . $wp_filesystem->group($root) . "\n\n";
1119
-
1120
-
1121
- //check we can list wp-content files
1122
- if ($wp_filesystem->exists($root)) {
1123
-
1124
- $files = $wp_filesystem->dirlist($root);
1125
- if (count($files) > 0) {
1126
- echo "wp-content folder exists and contains " . count($files) . " files \n";
1127
- } else {
1128
- echo "wp-content folder exists but we cannot read it's contents \n";
1129
- }
1130
- }
1131
-
1132
- // $wp_filesystem->owner() $wp_filesystem->group() $wp_filesystem->is_writable() $wp_filesystem->is_readable()
1133
- echo "\nUsing the " . $wp_filesystem->method . " method of the WP filesystem API\n";
1134
-
1135
- //wp-content editable?
1136
- echo "The wp-content folder " . ($wp_filesystem->is_readable($root) == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root) == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1137
-
1138
-
1139
- //plugins folder editable
1140
- echo "The wp-content/plugins folder " . ($wp_filesystem->is_readable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1141
-
1142
-
1143
- //themes folder editable
1144
- echo "The wp-content/themes folder " . ($wp_filesystem->is_readable($root . "/themes") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/themes") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1145
- }
1146
-
1147
- echo "___________________ \n\n\n\n";
1148
-
1149
- echo " If the file tree to the right is empty there is a possibility that your server permissions are not compatible with this plugin. \n The startup information above may shed some light on things. \n Paste that information into the support forum for further assistance.";
1150
-
1151
-
1152
- die();
1153
- }
1154
-
1155
- public function add_my_menu_page()
1156
- {
1157
- $this->menu_hook = add_menu_page('WPide', 'WPide', 'edit_themes', "wpide", array($this, 'my_menu_page'), 'dashicons-editor-code');
1158
- }
1159
-
1160
- public function my_menu_page()
1161
- {
1162
- if (!current_user_can('edit_themes')) {
1163
- wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1164
- }
1165
-
1166
- $app_url = get_bloginfo('url'); //need to make this https if we are currently looking on the site using https (even though https for admin might not be forced it can still cause issues)
1167
- if (is_ssl()) $app_url = str_replace("http:", "https:", $app_url);
1168
-
1169
- ?>
1170
- <script>
1171
- var wpide_app_path = "<?php echo plugin_dir_url(__FILE__); ?>";
1172
- //dont think this is needed any more.. var wpide_file_root_url = "<?php echo apply_filters("wpide_file_root_url", WP_CONTENT_URL); ?>";
1173
- var user_nonce_addition = '';
1174
-
1175
- function the_filetree() {
1176
- jQuery('#wpide_file_browser').fileTree({
1177
- script: ajaxurl
1178
- }, function(parent, file) {
1179
-
1180
- if (jQuery(parent).hasClass("create_new")) { //create new file/folder
1181
- //to create a new item we need to know the name of it so show input
1182
-
1183
- var item = eval('(' + file + ')');
1184
-
1185
- //hide all inputs just incase one is selected
1186
- jQuery(".new_item_inputs").hide();
1187
- //show the input form for this
1188
- jQuery("div.new_" + item.type).show();
1189
- jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").focus();
1190
- jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").attr("rel", file);
1191
-
1192
-
1193
- } else if (jQuery(".wpide_tab[rel='" + file + "']").length > 0) { //focus existing tab
1194
- jQuery(".wpide_tab[sessionrel='" + jQuery(".wpide_tab[rel='" + file + "']").attr("sessionrel") + "']").click(); //focus the already open tab
1195
- } else { //open file
1196
-
1197
- var image_pattern = new RegExp("(\\.jpg$|\\.gif$|\\.png$|\\.bmp$)");
1198
- if (image_pattern.test(file)) {
1199
- //it's an image so open it for editing
1200
-
1201
- //using modal+iframe
1202
- if ("lets not" == "use the modal for now") {
1203
-
1204
- var NewDialog = jQuery('<div id="MenuDialog">\
1205
- <iframe src="http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&target=<?php echo get_bloginfo('url') . "?action=wpide_image_save"; ?>&url=<?php echo get_bloginfo('url') . "/wp-content"; ?>' + file + '&title=Edit image&service=Save back to WPide" width="100%" height="600px"> </iframe>\
1206
- </div>');
1207
- NewDialog.dialog({
1208
- modal: true,
1209
- title: "title",
1210
- show: 'clip',
1211
- hide: 'clip',
1212
- width: '800',
1213
- height: '600'
1214
- });
1215
-
1216
- } else { //open in new tab/window
1217
-
1218
- var data = {
1219
- action: 'wpide_image_edit_key',
1220
- file: file,
1221
- _wpnonce: jQuery('#_wpnonce').val(),
1222
- _wp_http_referer: jQuery('#_wp_http_referer').val()
1223
- };
1224
- var image_data = '';
1225
- jQuery.ajaxSetup({
1226
- async: false
1227
- }); //we need to wait until we get the response before opening the window
1228
- jQuery.post(ajaxurl, data, function(response) {
1229
-
1230
- //with the response (which is a nonce), build the json data to pass to the image editor. The edit key (nonce) is only valid to edit this image
1231
- image_data = file + '::' + response;
1232
-
1233
- });
1234
-
1235
- jQuery.ajaxSetup({
1236
- async: true
1237
- }); //enable async again
1238
-
1239
-
1240
- window.open('http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&url=<?php echo $app_url . "/wp-content"; ?>' + file + '&opt=' + image_data + '&title=Edit image&service=Save back to WPide&target=<?php echo urlencode($app_url . "/wp-admin/admin.php?wpide_save_image=yes"); ?>');
1241
-
1242
- }
1243
-
1244
- } else {
1245
- jQuery(parent).addClass('wait');
1246
-
1247
- wpide_set_file_contents(file, function() {
1248
-
1249
- //once file loaded remove the wait class/indicator
1250
- jQuery(parent).removeClass('wait');
1251
-
1252
- });
1253
-
1254
- jQuery('#filename').val(file);
1255
- }
1256
-
1257
- }
1258
-
1259
- });
1260
- }
1261
-
1262
-
1263
-
1264
- jQuery(document).ready(function($) {
1265
-
1266
- // $("#fancyeditordiv").css("height", ($('body').height()-120) + 'px' );
1267
-
1268
- // Handler for .ready() called.
1269
- the_filetree();
1270
-
1271
- //inialise the color assist
1272
- $("#wpide_color_assist img").ImageColorPicker({
1273
- afterColorSelected: function(event, color) {
1274
- jQuery("#wpide_color_assist_input").val(color);
1275
- }
1276
- });
1277
- $("#wpide_color_assist").hide(); //hide it until it's needed
1278
-
1279
- $("#wpide_color_assist_send").click(function(e) {
1280
- e.preventDefault();
1281
- editor.insert(jQuery("#wpide_color_assist_input").val().replace('#', ''));
1282
-
1283
- $("#wpide_color_assist").hide(); //hide it until it's needed again
1284
- });
1285
-
1286
- $(".close_color_picker a").click(function(e) {
1287
- e.preventDefault();
1288
- $("#wpide_color_assist").hide(); //hide it until it's needed again
1289
- });
1290
-
1291
- $("#wpide_toolbar_buttons").on('click', "a.restore", function(e) {
1292
- e.preventDefault();
1293
- var file_path = jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup");
1294
-
1295
- jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1296
- jQuery("#wpide_message").html('<span><strong>File available for restore</strong><p> ' + file_path + '</p><a class="button red restore now" href="' + wpide_app_path + file_path + '">Restore this file now &#10012;</a><a class="button restore cancel" href="#">Cancel &#10007;</a><br /><em class="note"><strong>note: </strong>You can browse all file backups if you navigate to the backups folder (plugins/WPide/backups/..) using the filetree.</em></span>');
1297
- jQuery("#wpide_message").show();
1298
- });
1299
- $("#wpide_toolbar_buttons").on('click', "a.restore.now", function(e) {
1300
- e.preventDefault();
1301
-
1302
- var data = {
1303
- restorewpnonce: user_nonce_addition + jQuery('#_wpnonce').val()
1304
- };
1305
- jQuery.post(wpide_app_path + jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup"), data, function(response) {
1306
-
1307
- if (response == -1) {
1308
- alert("Problem restoring file.");
1309
- } else {
1310
- alert(response);
1311
- jQuery("#wpide_message").hide();
1312
- }
1313
-
1314
- });
1315
-
1316
- });
1317
- $("#wpide_toolbar_buttons").on('click', "a.cancel", function(e) {
1318
- e.preventDefault();
1319
-
1320
- jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1321
- });
1322
-
1323
- });
1324
- </script>
1325
-
1326
- <div id="poststuff" class="metabox-holder has-right-sidebar">
1327
-
1328
- <div id="side-info-column" class="inner-sidebar">
1329
-
1330
- <div id="wpide_info">
1331
- <div id="wpide_info_content"></div>
1332
- </div>
1333
- <br style="clear:both;" />
1334
- <div id="wpide_color_assist">
1335
- <div class="close_color_picker"><a href="close-color-picker">x</a></div>
1336
- <h3>Colour Assist</h3>
1337
- <img src='<?php echo plugins_url("images/color-wheel.png", __FILE__); ?>' />
1338
- <input type="button" class="button" id="wpide_color_assist_send" value="&lt; Send to editor" />
1339
- <input type="text" id="wpide_color_assist_input" name="wpide_color_assist_input" value="" />
1340
-
1341
- </div>
1342
-
1343
-
1344
-
1345
- <div id="submitdiv" class="postbox ">
1346
- <h3 class="hndle"><span>Files</span></h3>
1347
- <div class="inside">
1348
- <div class="submitbox" id="submitpost">
1349
- <div id="minor-publishing">
1350
- </div>
1351
- <div id="major-publishing-actions">
1352
- <div id="wpide_file_browser"></div>
1353
- <br style="clear:both;" />
1354
- <div class="new_file new_item_inputs">
1355
- <label for="new_folder">File name</label><input class="has_data" name="new_file" type="text" rel="" value="" placeholder="Filename.ext" />
1356
- <a href="#" id="wpide_create_new_file" class="button-primary">CREATE</a>
1357
- </div>
1358
- <div class="new_directory new_item_inputs">
1359
- <label for="new_directory">Directory name</label><input class="has_data" name="new_directory" type="text" rel="" value="" placeholder="Filename.ext" />
1360
- <a href="#" id="wpide_create_new_directory" class="button-primary">CREATE</a>
1361
- </div>
1362
- <div class="clear"></div>
1363
- </div>
1364
- </div>
1365
- </div>
1366
- </div>
1367
-
1368
-
1369
- </div>
1370
-
1371
- <div id="post-body">
1372
- <div id="wpide_toolbar" class="quicktags-toolbar">
1373
- <div id="wpide_toolbar_tabs"> </div>
1374
- <div id="dialog_window_minimized_container"></div>
1375
- </div>
1376
-
1377
- <div id="wpide_toolbar_buttons">
1378
- <div id="wpide_message"></div>
1379
- <a class="button restore" style="display:none;" title="Restore the active tab" href="#">Restore &#10012;</a>
1380
-
1381
- </div>
1382
-
1383
-
1384
- <div id='fancyeditordiv'></div>
1385
-
1386
- <form id="wpide_save_container" action="" method="get">
1387
- <div id="wpide_footer_message"></div>
1388
- <div id="wpide_footer_message_last_saved"></div>
1389
- <div id="wpide_footer_message_unsaved"></div>
1390
-
1391
- <a href="#" id="wpide_save" alt="Keyboard shortcut to save [Ctrl/Cmd + S]" title="Keyboard shortcut to save [Ctrl/Cmd + S]" class="button-primary">SAVE
1392
- FILE</a>
1393
-
1394
- <input type="hidden" id="filename" name="filename" value="" />
1395
- <?php
1396
- if (function_exists('wp_nonce_field'))
1397
- wp_nonce_field('plugin-name-action_wpidenonce');
1398
- ?>
1399
- </form>
1400
-
1401
- </div>
1402
-
1403
- </div>
1404
-
1405
- <?php
1406
- }
1407
-
1408
- public function print_find_dialog()
1409
- {
1410
- if (!$this->is_plugin_page()) {
1411
- return;
1412
- }
1413
- ?>
1414
- <div id="editor_find_dialog" title="Find..." style="padding: 0px; display: none;">
1415
- <?php if (false) : ?>
1416
- <ul>
1417
- <li><a href="#find-inline">Text</a></li>
1418
- <li><a href="#find-func">Function</a></li>
1419
- </ul>
1420
- <?php endif; ?>
1421
- <form id="find-inline" style="position: relative; padding: 4px; margin: 0px; height: 100%; overflow: hidden; width: 400px;">
1422
- <label class="left"> Find<input type="search" name="find" /></label>
1423
- <label class="left"> Replace<input type="search" name="replace" /></label>
1424
- <div class="clear" style="height: 33px;"></div>
1425
-
1426
- <label><input type="checkbox" name="wrap" checked="checked" /> Wrap Around</label>
1427
- <label><input type="checkbox" name="case" /> Case Sensitive</label>
1428
- <label><input type="checkbox" name="whole" /> Match Whole Word</label>
1429
- <label><input type="checkbox" name="regexp" /> Regular Expression</label>
1430
-
1431
- <div class="search_direction">
1432
- Direction:
1433
- <label><input type="radio" name="direction" value="0" /> Up</label>
1434
- <label><input type="radio" name="direction" value="1" checked="checked" /> Down</label>
1435
- </div>
1436
- <div class="right">
1437
- <input type="submit" name="submit" value="Find" class="action_button" />
1438
- <input type="button" name="replace" value="Replace" class="action_button" />
1439
- <input type="button" name="replace_all" value="Replace All" class="action_button" />
1440
- <input type="button" name="cancel" value="Cancel" class="action_button" />
1441
- </div>
1442
- </form>
1443
- <?php if (false) : ?>
1444
- <form id="find-func">
1445
- <label class="left"> Function<input type="search" name="find" /></label>
1446
- <div class="right">
1447
- <input type="submit" name="submit" value="Find Function" class="action_button" />
1448
- </div>
1449
- </form>
1450
- <?php endif; ?>
1451
- </div>
1452
- <div id="editor_goto_dialog" title="Go to..." style="padding: 0px; display: none;"></div>
1453
- <?php
1454
- }
1455
- }
1456
-
1457
- $wpide = new wpide();
1458
-
1459
- endif; // class_exists check
1
+ <?php
2
+ /*
3
+ Plugin Name: WPide
4
+ Plugin URI: https://wpide.com/
5
+ Description: WordPress code editor with auto-completion of both WordPress and PHP functions with reference, syntax highlighting, line numbers, tabbed editing, automatic backup.
6
+ Version: 2.6
7
+ Author: XplodedThemes
8
+ Author URI: https://www.xplodedthemes.com/
9
+ Requires at least: 5.0
10
+ Requires PHP: 5.2
11
+ Tested up to: 5.7
12
+ Text Domain: wpide
13
+
14
+ This program is free software; you can redistribute it and/or modify
15
+ it under the terms of the GNU General Public License, version 2, as
16
+ published by the Free Software Foundation.
17
+
18
+ This program is distributed in the hope that it will be useful,
19
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ GNU General Public License for more details.
22
+
23
+ You should have received a copy of the GNU General Public License
24
+ along with this program; if not, write to the Free Software
25
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
+ */
27
+
28
+ if (!defined('ABSPATH')) {
29
+ die();
30
+ }
31
+
32
+ require_once 'wf-flyout/wf-flyout.php';
33
+ new wf_flyout(__FILE__);
34
+
35
+ if (!class_exists('wpide')) :
36
+ class wpide
37
+ {
38
+
39
+ public $site_url, $plugin_url;
40
+ private $menu_hook, $version;
41
+
42
+
43
+ function __construct()
44
+ {
45
+
46
+ $this->get_plugin_version();
47
+
48
+ // add WPide to the menu
49
+ add_action('admin_menu', array($this, 'add_my_menu_page'));
50
+
51
+ // hook for processing incoming image saves
52
+ if (is_admin() && isset($_GET['wpide_save_image'])) {
53
+
54
+ // force local file method for testing - you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
55
+ $this->override_fs_method('direct');
56
+
57
+ add_action('admin_init', array($this, 'wpide_save_image'));
58
+ }
59
+
60
+ add_action('admin_init', array($this, 'setup_hooks'));
61
+
62
+ $this->site_url = get_bloginfo('url');
63
+ }
64
+
65
+
66
+ public function override_fs_method($method = 'direct')
67
+ {
68
+ if (defined('FS_METHOD')) {
69
+ define('WPIDE_FS_METHOD_FORCED_ELSEWHERE', FS_METHOD); //make a note of the forced method
70
+ } else {
71
+ define('FS_METHOD', $method); //force direct
72
+ }
73
+ }
74
+
75
+ function is_plugin_page()
76
+ {
77
+ $current_screen = get_current_screen();
78
+
79
+ if ($current_screen->id === $this->menu_hook) {
80
+ return true;
81
+ } else {
82
+ return false;
83
+ }
84
+ }
85
+
86
+ // get plugin version from header
87
+ function get_plugin_version()
88
+ {
89
+ $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
90
+ $this->version = $plugin_data['version'];
91
+
92
+ return $plugin_data['version'];
93
+ } // get_plugin_version
94
+
95
+
96
+ public function setup_hooks()
97
+ {
98
+ // force local file method until I've worked out how to implement the other methods
99
+ // main problem being password wouldn't/isn't saved between requests
100
+ // you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
101
+ $this->override_fs_method('direct');
102
+
103
+ // Will only enqueue on WPide page
104
+ add_action('admin_print_scripts-' . $this->menu_hook, array($this, 'add_admin_js'));
105
+ add_action('admin_print_styles-' . $this->menu_hook, array($this, 'add_admin_styles'));
106
+
107
+ add_action('admin_print_footer_scripts', array($this, 'print_find_dialog'));
108
+
109
+ //setup jqueryFiletree list callback
110
+ add_action('wp_ajax_jqueryFileTree', array($this, 'jqueryFileTree_get_list'));
111
+ //setup ajax function to get file contents for editing
112
+ add_action('wp_ajax_wpide_get_file', array($this, 'wpide_get_file'));
113
+ //setup ajax function to save file contents and do automatic backup if needed
114
+ add_action('wp_ajax_wpide_save_file', array($this, 'wpide_save_file'));
115
+ //setup ajax function to rename file/folder
116
+ add_action('wp_ajax_wpide_rename_file', array($this, 'wpide_rename_file'));
117
+ //setup ajax function to delete file/folder
118
+ add_action('wp_ajax_wpide_delete_file', array($this, 'wpide_delete_file'));
119
+ //setup ajax function to handle upload
120
+ add_action('wp_ajax_wpide_upload_file', array($this, 'wpide_upload_file'));
121
+ //setup ajax function to handle download
122
+ add_action('wp_ajax_wpide_download_file', array($this, 'wpide_download_file'));
123
+ //setup ajax function to unzip file
124
+ add_action('wp_ajax_wpide_unzip_file', array($this, 'wpide_unzip_file'));
125
+ //setup ajax function to zip file
126
+ add_action('wp_ajax_wpide_zip_file', array($this, 'wpide_zip_file'));
127
+ //setup ajax function to create new item (folder, file etc)
128
+ add_action('wp_ajax_wpide_create_new', array($this, 'wpide_create_new'));
129
+
130
+ //setup ajax function to create new item (folder, file etc)
131
+ add_action('wp_ajax_wpide_image_edit_key', array($this, 'wpide_image_edit_key'));
132
+
133
+ //setup ajax function for startup to get some debug info, checking permissions etc
134
+ add_action('wp_ajax_wpide_startup_check', array($this, 'wpide_startup_check'));
135
+
136
+ //add a warning when navigating away from WPide
137
+ //it has to go after WordPress scripts otherwise WP clears the binding
138
+ // This has been implemented in load-editor.js
139
+ // todo:
140
+ // add_action('admin_print_footer_scripts', array( $this, 'add_admin_nav_warning' ), 99);
141
+
142
+ // Add body class to collapse the wp sidebar nav
143
+ add_filter('admin_body_class', array($this, 'hide_wp_sidebar_nav'), 11);
144
+
145
+ //hide the update nag
146
+ add_action('admin_menu', array($this, 'hide_wp_update_nag'));
147
+
148
+ add_filter(
149
+ 'plugin_action_links_' . plugin_basename(__FILE__),
150
+ array($this, 'plugin_action_links')
151
+ );
152
+ add_filter('admin_footer_text', array($this, 'admin_footer_text'));
153
+ }
154
+
155
+
156
+ // add settings link to plugins page
157
+ function plugin_action_links($links)
158
+ {
159
+ $settings_link = '<a href="' . admin_url('admin.php?page=wpide') . '" title="Manage Files">Manage Files</a>';
160
+
161
+ array_unshift($links, $settings_link);
162
+
163
+ return $links;
164
+ } // plugin_action_links
165
+
166
+
167
+ // additional powered by text in admin footer; only on WPide page
168
+ function admin_footer_text($text)
169
+ {
170
+ if (!$this->is_plugin_page()) {
171
+ return $text;
172
+ }
173
+
174
+ $text = '<i><a href="https://wpide.com/" title="Visit WPide\'s site for more info" target="_blank">WPide</a> v' . $this->version . ' by <a href="https://www.xplodedthemes.com/" title="Visit our site to get more great plugins" target="_blank">XplodedThemes</a>. Please <a target="_blank" href="https://wordpress.org/support/plugin/wpide/reviews/#new-post" title="Rate the plugin">rate the plugin <span>★★★★★</span></a> to help us spread the word. Thank you!</i>';
175
+
176
+ return $text;
177
+ } // admin_footer_text
178
+
179
+
180
+ public function hide_wp_sidebar_nav($classes)
181
+ {
182
+ global $hook_suffix;
183
+
184
+ if (!$this->is_plugin_page()) {
185
+ return $classes;
186
+ }
187
+
188
+ if (apply_filters('wpide_sidebar_folded', $hook_suffix === $this->menu_hook)) {
189
+ return str_replace("auto-fold", "", $classes) . ' folded';
190
+ }
191
+ }
192
+
193
+ public function hide_wp_update_nag()
194
+ {
195
+ if (!$this->is_plugin_page()) {
196
+ return;
197
+ }
198
+
199
+ remove_action('admin_notices', 'update_nag', 3);
200
+ }
201
+
202
+ public function add_admin_nav_warning()
203
+ {
204
+ ?>
205
+ <script type="text/javascript">
206
+ jQuery(document).ready(function($) {
207
+ window.onbeforeunload = function() {
208
+ return 'You are attempting to navigate away from WPide. Make sure you have saved any changes made to your files otherwise they will be forgotten.';
209
+ }
210
+ });
211
+ </script>
212
+ <?php
213
+ }
214
+
215
+ public function add_admin_js()
216
+ {
217
+ $plugin_path = plugin_dir_url(__FILE__);
218
+ //include file tree
219
+ wp_enqueue_script('jquery-file-tree', plugins_url("js/jqueryFileTree.js", __FILE__));
220
+ //include ace
221
+ wp_enqueue_script('ace', plugins_url("js/ace-1.2.0/ace.js", __FILE__));
222
+ //include ace modes for css, javascript & php
223
+ wp_enqueue_script('ace-mode-css', $plugin_path . 'js/ace-1.2.0/mode-css.js');
224
+ wp_enqueue_script('ace-mode-less', $plugin_path . 'js/ace-1.2.0/mode-less.js');
225
+ wp_enqueue_script('ace-mode-javascript', $plugin_path . 'js/ace-1.2.0/mode-javascript.js');
226
+ wp_enqueue_script('ace-mode-php', $plugin_path . 'js/ace-1.2.0/mode-php.js');
227
+ //include ace theme
228
+ wp_enqueue_script('ace-theme', plugins_url("js/ace-1.2.0/theme-dawn.js", __FILE__)); //ambiance looks really nice for high contrast
229
+ // wordpress-completion tags
230
+ wp_enqueue_script('wpide-wordpress-completion', plugins_url("js/autocomplete/wordpress.js", __FILE__));
231
+ // php-completion tags
232
+ wp_enqueue_script('wpide-php-completion', plugins_url("js/autocomplete/php.js", __FILE__));
233
+ // load editor
234
+ wp_enqueue_script('wpide-load-editor', plugins_url("js/load-editor.js", __FILE__));
235
+ // load filetree menu
236
+ wp_enqueue_script('wpide-load-filetree-menu', plugins_url("js/load-filetree-menu.js", __FILE__));
237
+ // load autocomplete dropdown
238
+ wp_enqueue_script('wpide-dd', plugins_url("js/jquery.dd.js", __FILE__));
239
+
240
+ // load jquery ui
241
+ wp_enqueue_script('jquery-ui', plugins_url("js/jquery-ui-1.9.2.custom.min.js", __FILE__), array('jquery'), '1.9.2');
242
+
243
+ // load color picker
244
+ wp_enqueue_script('ImageColorPicker', plugins_url("js/ImageColorPicker.js", __FILE__), array('jquery'), '0.3');
245
+ }
246
+
247
+ public function add_admin_styles()
248
+ {
249
+ //main wpide styles
250
+ wp_register_style('wpide_style', plugins_url('css/wpide.css', __FILE__));
251
+ wp_enqueue_style('wpide_style');
252
+ //filetree styles
253
+ wp_register_style('wpide_filetree_style', plugins_url('css/jqueryFileTree.css', __FILE__));
254
+ wp_enqueue_style('wpide_filetree_style');
255
+ //autocomplete dropdown styles
256
+ wp_register_style('wpide_dd_style', plugins_url('css/dd.css', __FILE__));
257
+ wp_enqueue_style('wpide_dd_style');
258
+
259
+ //jquery ui styles
260
+ wp_register_style('wpide_jqueryui_style', plugins_url('css/flick/jquery-ui-1.8.20.custom.css', __FILE__));
261
+ wp_enqueue_style('wpide_jqueryui_style');
262
+ }
263
+
264
+ public function jqueryFileTree_get_list()
265
+ {
266
+ //check the user has the permissions
267
+ check_admin_referer('plugin-name-action_wpidenonce');
268
+ if (!current_user_can('edit_themes'))
269
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
270
+
271
+ //setup wp_filesystem api
272
+ global $wp_filesystem;
273
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
274
+ $form_fields = null; // for now, but at some point the login info should be passed in here
275
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
276
+ // no credentials yet, just produced a form for the user to fill in
277
+ return true; // stop the normal page form from displaying
278
+ }
279
+
280
+ if (!WP_Filesystem($creds))
281
+ return false;
282
+
283
+ $_POST['dir'] = urldecode($_POST['dir']);
284
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
285
+
286
+ if ($wp_filesystem->exists($root . $_POST['dir'])) {
287
+
288
+ $files = $wp_filesystem->dirlist($root . $_POST['dir']);
289
+
290
+ echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
291
+ if (count($files) > 0) {
292
+
293
+ //build separate arrays for folders and files
294
+ $dir_array = array();
295
+ $file_array = array();
296
+ foreach ($files as $file => $file_info) {
297
+ if ($file != '.' && $file != '..' && $file_info['type'] == 'd') {
298
+ $file_string = strtolower(preg_replace("[._-]", "", $file));
299
+ $dir_array[$file_string] = $file_info;
300
+ } elseif ($file != '.' && $file != '..' && $file_info['type'] == 'f') {
301
+ $file_string = strtolower(preg_replace("[._-]", "", $file));
302
+ $file_array[$file_string] = $file_info;
303
+ }
304
+ }
305
+
306
+ //shot those arrays
307
+ ksort($dir_array);
308
+ ksort($file_array);
309
+
310
+ // All dirs
311
+ foreach ($dir_array as $file => $file_info) {
312
+ echo "<li class=\"directory collapsed\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "/\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
313
+ }
314
+ // All files
315
+ foreach ($file_array as $file => $file_info) {
316
+ $ext = preg_replace('/^.*\./', '', $file_info['name']);
317
+ echo "<li class=\"file ext_$ext\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
318
+ }
319
+ }
320
+ //output toolbar for creating new file, folder etc
321
+ echo "<li class=\"create_new\"><a class='new_directory' title='Create a new directory here.' href=\"#\" rel=\"{type: 'directory', path: '" . htmlentities($_POST['dir']) . "'}\"></a> <a class='new_file' title='Create a new file here.' href=\"#\" rel=\"{type: 'file', path: '" . htmlentities($_POST['dir']) . "'}\"></a><br style='clear:both;' /></li>";
322
+ echo "</ul>";
323
+ }
324
+
325
+ die(); // this is required to return a proper result
326
+ }
327
+
328
+
329
+ public function wpide_get_file()
330
+ {
331
+ //check the user has the permissions
332
+ check_admin_referer('plugin-name-action_wpidenonce');
333
+ if (!current_user_can('edit_themes'))
334
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
335
+
336
+ //setup wp_filesystem api
337
+ global $wp_filesystem;
338
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
339
+ $form_fields = null; // for now, but at some point the login info should be passed in here
340
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
341
+ // no credentials yet, just produced a form for the user to fill in
342
+ return true; // stop the normal page form from displaying
343
+ }
344
+ if (!WP_Filesystem($creds))
345
+ return false;
346
+
347
+
348
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
349
+ $file_name = $root . stripslashes($_POST['filename']);
350
+ echo $wp_filesystem->get_contents($file_name);
351
+ die(); // this is required to return a proper result
352
+ }
353
+
354
+ public function wpide_image_edit_key()
355
+ {
356
+
357
+ //check the user has the permissions
358
+ check_admin_referer('plugin-name-action_wpidenonce');
359
+ if (!current_user_can('edit_themes')) {
360
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
361
+ }
362
+
363
+ //create a nonce based on the image path
364
+ echo wp_create_nonce('wpide_image_edit' . $_POST['file']);
365
+ }
366
+
367
+ public function wpide_create_new()
368
+ {
369
+ //check the user has the permissions
370
+ check_admin_referer('plugin-name-action_wpidenonce');
371
+ if (!current_user_can('edit_themes')) {
372
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
373
+ }
374
+
375
+ //setup wp_filesystem api
376
+ global $wp_filesystem;
377
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
378
+ $form_fields = null; // for now, but at some point the login info should be passed in here
379
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
380
+ // no credentials yet, just produced a form for the user to fill in
381
+ return true; // stop the normal page form from displaying
382
+ }
383
+ if (!WP_Filesystem($creds))
384
+ return false;
385
+
386
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
387
+
388
+ //check all required vars are passed
389
+ if (strlen($_POST['path']) > 0 && strlen($_POST['type']) > 0 && strlen($_POST['file']) > 0) {
390
+ $filename = $_POST['file'];
391
+ $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0));
392
+ $filename = preg_replace("#\x{00a0}#siu", ' ', $filename);
393
+ $filename = str_replace($special_chars, '', $filename);
394
+ $filename = str_replace(array('%20', '+'), '-', $filename);
395
+ $filename = preg_replace('/[\r\n\t -]+/', '-', $filename);
396
+
397
+ $path = $_POST['path'];
398
+
399
+ if ($_POST['type'] == "directory") {
400
+ $write_result = $wp_filesystem->mkdir($root . $path . $filename, FS_CHMOD_DIR);
401
+
402
+ if ($write_result) {
403
+ die("1"); //created
404
+ } else {
405
+ echo "Problem creating directory" . $root . $path . $filename;
406
+ }
407
+ } else if ($_POST['type'] == "file") {
408
+ //write the file
409
+ $write_result = $wp_filesystem->put_contents(
410
+ $root . $path . $filename,
411
+ '',
412
+ FS_CHMOD_FILE // predefined mode settings for WP files
413
+ );
414
+
415
+ if ($write_result) {
416
+ die("1"); //created
417
+ } else {
418
+ echo "Problem creating file " . $root . $path . $filename;
419
+ }
420
+ }
421
+ //print_r($_POST);
422
+ }
423
+
424
+ echo "0";
425
+ die(); // this is required to return a proper result
426
+ }
427
+
428
+ public function wpide_save_file()
429
+ {
430
+ //check the user has the permissions
431
+ check_admin_referer('plugin-name-action_wpidenonce');
432
+ if (!current_user_can('edit_themes')) {
433
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
434
+ }
435
+
436
+ $is_php = false;
437
+
438
+ /*
439
+ * Check file syntax of PHP files by parsing the PHP
440
+ * If a site is running low on memory this PHP parser library could well tip memory usage over the edge
441
+ * Especially if you are editing a large PHP file.
442
+ * Might be worth either making this syntax check optional or it only running if memory is available.
443
+ * Symptoms: no response on file save, and errors in your log like "Fatal error: Allowed memory size of 8388608 bytes exhausted…"
444
+ */
445
+ if (preg_match("#\.php$#i", $_POST['filename'])) {
446
+
447
+ $is_php = true;
448
+
449
+ require('PHP-Parser/lib/bootstrap.php');
450
+ ini_set('xdebug.max_nesting_level', 2000);
451
+
452
+ $code = stripslashes($_POST['content']);
453
+
454
+ $parser = new PHPParser_Parser(new PHPParser_Lexer);
455
+
456
+ try {
457
+ $stmts = $parser->parse($code);
458
+ } catch (PHPParser_Error $e) {
459
+ echo 'Parse Error: ', $e->getMessage();
460
+ die();
461
+ }
462
+ }
463
+
464
+ //setup wp_filesystem api
465
+ global $wp_filesystem;
466
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
467
+ $form_fields = null; // for now, but at some point the login info should be passed in here
468
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
469
+ // no credentials yet, just produced a form for the user to fill in
470
+ return true; // stop the normal page form from displaying
471
+ }
472
+ if (!WP_Filesystem($creds))
473
+ echo "Cannot initialise the WP file system API";
474
+
475
+ //save a copy of the file and create a backup just in case
476
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
477
+ $file_name = $root . stripslashes($_POST['filename']);
478
+
479
+ //set backup filename
480
+ $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
481
+ $backup_path_full = plugin_dir_path(__FILE__) . $backup_path;
482
+ //create backup directory if not there
483
+ $new_file_info = pathinfo($backup_path_full);
484
+ if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
485
+
486
+ if ($is_php) {
487
+ //create the backup file adding some php to the file to enable direct restore
488
+ global $current_user;
489
+ get_currentuserinfo();
490
+ $user_md5 = md5(serialize($current_user));
491
+
492
+ $restore_php = '<?php /* start WPide restore code */
493
+ if ($_POST["restorewpnonce"] === "' . $user_md5 . $_POST['_wpnonce'] . '"){
494
+ if ( file_put_contents ( "' . $file_name . '" , preg_replace("#<\?php /\* start WPide(.*)end WPide restore code \*/ \?>#s", "", file_get_contents("' . $backup_path_full . '") ) ) ){
495
+ echo "Your file has been restored, overwritting the recently edited file! \n\n The active editor still contains the broken or unwanted code. If you no longer need that content then close the tab and start fresh with the restored file.";
496
+ }
497
+ }else{
498
+ echo "-1";
499
+ }
500
+ die();
501
+ /* end WPide restore code */ ?>';
502
+
503
+ file_put_contents($backup_path_full, $restore_php . file_get_contents($file_name));
504
+ } else {
505
+ //do normal backup
506
+ $wp_filesystem->copy($file_name, $backup_path_full);
507
+ }
508
+
509
+ //save file
510
+ if ($wp_filesystem->put_contents($file_name, stripslashes($_POST['content']))) {
511
+
512
+ //lets create an extra long nonce to make it less crackable
513
+ global $current_user;
514
+ get_currentuserinfo();
515
+ $user_md5 = md5(serialize($current_user));
516
+
517
+ $result = "\"" . $backup_path . ":::" . $user_md5 . "\"";
518
+ }
519
+
520
+ die($result); // this is required to return a proper result
521
+ }
522
+
523
+
524
+ public function wpide_rename_file()
525
+ {
526
+ global $wp_filesystem;
527
+
528
+ //check the user has the permissions
529
+ check_admin_referer('plugin-name-action_wpidenonce');
530
+ if (!current_user_can('manage_options')) {
531
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
532
+ }
533
+
534
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
535
+ $form_fields = null; // for now, but at some point the login info should be passed in here
536
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
537
+ if (false === $creds) {
538
+ // no credentials yet, just produced a form for the user to fill in
539
+ return true; // stop the normal page form from displaying
540
+ }
541
+ if (!WP_Filesystem($creds))
542
+ echo "Cannot initialise the WP file system API";
543
+
544
+
545
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
546
+ $file_name = $root . stripslashes($_POST['filename']);
547
+ $new_name = dirname($file_name) . '/' . stripslashes($_POST['newname']);
548
+
549
+ if (!$wp_filesystem->exists($file_name)) {
550
+ echo 'The target file doesn\'t exist!';
551
+ exit;
552
+ }
553
+
554
+ if ($wp_filesystem->exists($new_name)) {
555
+ echo 'The destination file exists!';
556
+ exit;
557
+ }
558
+
559
+ // Move instead of rename
560
+ $renamed = $wp_filesystem->move($file_name, $new_name);
561
+
562
+ if (!$renamed) {
563
+ echo 'The file could not be renamed!';
564
+ }
565
+ exit;
566
+ }
567
+
568
+
569
+ public function wpide_delete_file()
570
+ {
571
+ global $wp_filesystem;
572
+
573
+ //check the user has the permissions
574
+ check_admin_referer('plugin-name-action_wpidenonce');
575
+ if (!current_user_can('manage_options')) {
576
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
577
+ }
578
+
579
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
580
+ $form_fields = null; // for now, but at some point the login info should be passed in here
581
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
582
+ if (false === $creds) {
583
+ // no credentials yet, just produced a form for the user to fill in
584
+ return true; // stop the normal page form from displaying
585
+ }
586
+ if (!WP_Filesystem($creds))
587
+ echo "Cannot initialise the WP file system API";
588
+
589
+
590
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
591
+ $file_name = $root . stripslashes($_POST['filename']);
592
+
593
+ if (!$wp_filesystem->exists($file_name)) {
594
+ echo 'The file doesn\'t exist!';
595
+ exit;
596
+ }
597
+
598
+ $deleted = $wp_filesystem->delete($file_name);
599
+
600
+ if (!$deleted) {
601
+ echo 'The file couldn\'t be deleted.';
602
+ }
603
+
604
+ exit;
605
+ }
606
+
607
+ public function wpide_upload_file()
608
+ {
609
+ global $wp_filesystem;
610
+
611
+ //check the user has the permissions
612
+ check_admin_referer('plugin-name-action_wpidenonce');
613
+ if (!current_user_can('manage_options')) {
614
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
615
+ }
616
+
617
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
618
+ $form_fields = null; // for now, but at some point the login info should be passed in here
619
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
620
+ if (false === $creds) {
621
+ // no credentials yet, just produced a form for the user to fill in
622
+ return true; // stop the normal page form from displaying
623
+ }
624
+ if (!WP_Filesystem($creds))
625
+ echo "Cannot initialise the WP file system API";
626
+
627
+
628
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
629
+ $destination_folder = $root . stripslashes($_POST['destination']);
630
+
631
+ foreach ($_FILES as $file) {
632
+ if (!is_uploaded_file($file['tmp_name'])) {
633
+ continue;
634
+ }
635
+
636
+ $destination = $destination_folder . $file['name'];
637
+
638
+ if ($wp_filesystem->exists($destination)) {
639
+ exit($file['name'] . ' already exists!');
640
+ }
641
+
642
+ if (!$wp_filesystem->move($file['tmp_name'], $destination)) {
643
+ exit($file['name'] . ' could not be moved.');
644
+ }
645
+
646
+ if (!$wp_filesystem->chmod($destination)) {
647
+ exit($file['name'] . ' could not be chmod.');
648
+ }
649
+ }
650
+ exit;
651
+ }
652
+
653
+ public function wpide_download_file()
654
+ {
655
+ global $wp_filesystem;
656
+
657
+ //check the user has the permissions
658
+ check_admin_referer('plugin-name-action_wpidenonce');
659
+ if (!current_user_can('manage_options')) {
660
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
661
+ }
662
+
663
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
664
+ $form_fields = null; // for now, but at some point the login info should be passed in here
665
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
666
+ if (false === $creds) {
667
+ // no credentials yet, just produced a form for the user to fill in
668
+ return true; // stop the normal page form from displaying
669
+ }
670
+ if (!WP_Filesystem($creds))
671
+ echo "Cannot initialise the WP file system API";
672
+
673
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
674
+ $file_name = $root . stripslashes($_POST['filename']);
675
+
676
+ if (!$wp_filesystem->exists($file_name)) {
677
+ echo 'The file doesn\'t exist!';
678
+ exit;
679
+ }
680
+
681
+ header('Content-Description: File Transfer');
682
+ header('Content-Type: application/octet-stream');
683
+ header('Content-Disposition: filename="' . basename($file_name) . '"');
684
+ header('Expires: 0');
685
+ header('Cache-Control: must-revalidate');
686
+ header('Pragma: public');
687
+
688
+ echo $wp_filesystem->get_contents($file_name);
689
+ exit;
690
+ }
691
+
692
+ public function wpide_zip_file()
693
+ {
694
+ global $wp_filesystem;
695
+
696
+ //check the user has the permissions
697
+ check_admin_referer('plugin-name-action_wpidenonce');
698
+ if (!current_user_can('manage_options')) {
699
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
700
+ }
701
+
702
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
703
+ $file_name = $root . stripslashes($_POST['filename']);
704
+
705
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
706
+ $form_fields = null; // for now, but at some point the login info should be passed in here
707
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
708
+ if (false === $creds) {
709
+ // no credentials yet, just produced a form for the user to fill in
710
+ return true; // stop the normal page form from displaying
711
+ }
712
+ if (!WP_Filesystem($creds))
713
+ echo "Cannot initialise the WP file system API";
714
+
715
+
716
+ if (!$wp_filesystem->exists($file_name)) {
717
+ echo 'Error: target file does not exist!';
718
+ exit;
719
+ }
720
+
721
+ $ext = '.zip';
722
+ switch (apply_filters('wpide_compression_method', 'zip')) {
723
+ case 'gz':
724
+ $ext = '.tar.gz';
725
+ break;
726
+ case 'tar':
727
+ $ext = '.tar';
728
+ break;
729
+ case 'b2z':
730
+ $ext = '.b2z';
731
+ break;
732
+ case 'zip':
733
+ $ext = '.zip';
734
+ break;
735
+ }
736
+
737
+ // Unzip a file to its current directory.
738
+ if ($wp_filesystem->is_dir($file_name)) {
739
+ $output_path = dirname($file_name) . '/' . basename($file_name) . $ext;
740
+ } else {
741
+ $output_path = $file_name;
742
+ $output_path = strstr($file_name, '.', true) . $ext;
743
+ }
744
+
745
+ $zipped = self::do_zip_file($file_name, $output_path);
746
+
747
+ if (is_wp_error($zipped)) {
748
+ printf('%s: %s', $zipped->get_error_code(), $zipped->get_error_message());
749
+ exit;
750
+ }
751
+
752
+ exit;
753
+ }
754
+
755
+ protected function do_zip_file($file, $to)
756
+ {
757
+ // Unzip can use a lot of memory, but not this much hopefully
758
+ @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
759
+
760
+ $method = apply_filters('wpide_compression_method', 'zip');
761
+
762
+ switch ($method) {
763
+ case 'gz':
764
+ case 'tar':
765
+ if (class_exists('PharData') && apply_filters('unzip_file_use_phardata', true)) {
766
+ exit('yes');
767
+ return self::_zip_archive_phardata($file, $to);
768
+ } else {
769
+ exit('figure it out');
770
+ }
771
+
772
+ /* if ( $method === 'gz' ) {
773
+ $gz = gzopen( $to );
774
+ }
775
+ */
776
+ break;
777
+ case 'b2z':
778
+ exit('B2Z!');
779
+ case 'zip':
780
+ default:
781
+ if ($method !== 'zip') {
782
+ trigger_error(sprintf('"%s" is not a valid compression mechanism.', $method));
783
+ }
784
+
785
+ if (class_exists('ZipArchive') && apply_filters('unzip_file_use_ziparchive', true)) {
786
+ return self::_zip_file_ziparchive($file, $to);
787
+ } else {
788
+ // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
789
+ return self::_zip_file_pclzip($file, $to);
790
+ }
791
+ break;
792
+ }
793
+ }
794
+
795
+ protected static function _zip_file_ziparchive($file, $to)
796
+ {
797
+ $z = new ZipArchive;
798
+ $opened = $z->open($to, ZipArchive::CREATE);
799
+
800
+ if ($opened !== true) {
801
+ switch ($opened) {
802
+ case ZipArchive::ER_EXISTS:
803
+ return new WP_Error(
804
+ 'ZipArchive Error',
805
+ 'File already exists',
806
+ ZipArchive::ER_EXISTS
807
+ );
808
+ case ZipArchive::ER_INCONS:
809
+ return new WP_Error(
810
+ 'ZipArchive Error',
811
+ 'Archive inconsistent',
812
+ ZipArchive::ER_INCONS
813
+ );
814
+ case ZipArchive::ER_INVAL:
815
+ return new WP_Error(
816
+ 'ZipArchive Error',
817
+ 'Invalid argument',
818
+ ZipArchive::ER_INVAL
819
+ );
820
+ case ZipArchive::ER_MEMORY:
821
+ return new WP_Error(
822
+ 'ZipArchive Error',
823
+ 'Malloc failure',
824
+ ZipArchive::ER_MEMORY
825
+ );
826
+ case ZipArchive::ER_NOENT:
827
+ return new WP_Error(
828
+ 'ZipArchive Error',
829
+ 'No such file.',
830
+ ZipArchive::ER_NOENT
831
+ );
832
+ case ZipArchive::ER_NOZIP:
833
+ return new WP_Error(
834
+ 'ZipArchive Error',
835
+ 'Not a zip archive.',
836
+ ZipArchive::ER_NOZIP
837
+ );
838
+ case ZipArchive::ER_OPEN:
839
+ return new WP_Error(
840
+ 'ZipArchive Error',
841
+ 'Can\'t open file.',
842
+ ZipArchive::ER_OPEN
843
+ );
844
+ case ZipArchive::ER_READ:
845
+ return new WP_Error(
846
+ 'ZipArchive Error',
847
+ 'Read Error',
848
+ ZipArchive::ER_READ
849
+ );
850
+ case ZipArchive::ER_SEEK:
851
+ return new WP_Error(
852
+ 'ZipArchive Error',
853
+ 'Seek Error',
854
+ ZipArchive::ER_SEEK
855
+ );
856
+
857
+ default:
858
+ return new WP_Error(
859
+ 'ZipArchive Error',
860
+ 'Unknown Error',
861
+ $opened
862
+ );
863
+ break;
864
+ }
865
+ }
866
+
867
+ if (is_dir($file)) {
868
+ $base = dirname($file);
869
+ $file = untrailingslashit($file);
870
+
871
+ $z = self::_zip_folder_ziparchive($base, $file, $to, $z);
872
+ if (is_wp_error($z))
873
+ return $z;
874
+ } else {
875
+ $z->addFile($file, basename($file));
876
+ }
877
+
878
+ $z->close();
879
+
880
+ return true;
881
+ }
882
+
883
+ protected static function _zip_folder_ziparchive($zip_base, $folder, $to, $z)
884
+ {
885
+ $handle = opendir($folder);
886
+ while (1) {
887
+ $file = readdir($handle);
888
+
889
+ if (false === $file)
890
+ break;
891
+
892
+ if (($file != '.') && ($file != '..')) {
893
+ $filePath = "$folder/$file";
894
+ $filePathRel = str_replace($zip_base, '', $filePath);
895
+
896
+ if ($filePathRel[0] === '/')
897
+ $filePathRel = substr($filePathRel, 1);
898
+
899
+ if (is_file($filePath)) {
900
+ $z->addFile($filePath, $filePathRel);
901
+ } elseif (is_dir($filePath)) {
902
+ // Add sub-directory.
903
+ $z->addEmptyDir($filePathRel);
904
+ self::_zip_folder_ziparchive($zip_base, $filePath, $to, $z);
905
+ }
906
+ }
907
+ }
908
+ closedir($handle);
909
+
910
+ return $z;
911
+ }
912
+
913
+ protected static function _zip_file_pclzip($file, $to)
914
+ {
915
+ require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
916
+
917
+ $pz = new PclZip($to);
918
+ $created = $pz->create($file, PCLZIP_OPT_REMOVE_PATH, dirname($file));
919
+
920
+ if (!$created) {
921
+ return new WP_Error('PclZip Error', $pz->errorInfo(true));
922
+ }
923
+
924
+ return true;
925
+ }
926
+
927
+ protected static function _zip_file_phardata($file, $to)
928
+ {
929
+ $p = new PharData($to);
930
+
931
+ if (is_dir($file)) {
932
+ $p->buildFromDirectory($file);
933
+ } else {
934
+ $p->addFile($file, basename($file));
935
+ }
936
+
937
+ return true;
938
+ }
939
+
940
+ public function wpide_unzip_file()
941
+ {
942
+ global $wp_filesystem;
943
+
944
+ //check the user has the permissions
945
+ check_admin_referer('plugin-name-action_wpidenonce');
946
+ if (!current_user_can('manage_options')) {
947
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
948
+ }
949
+
950
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
951
+ $file_name = $root . stripslashes($_POST['filename']);
952
+
953
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
954
+ $form_fields = null; // for now, but at some point the login info should be passed in here
955
+ $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
956
+ if (false === $creds) {
957
+ // no credentials yet, just produced a form for the user to fill in
958
+ return true; // stop the normal page form from displaying
959
+ }
960
+ if (!WP_Filesystem($creds))
961
+ echo "Cannot initialise the WP file system API";
962
+
963
+
964
+ if (!$wp_filesystem->exists($file_name)) {
965
+ echo 'Error: Extraction path doesn\'t exist!';
966
+ exit;
967
+ }
968
+
969
+ $unzipped = self::do_unzip_file($file_name, dirname($file_name));
970
+
971
+ if (is_wp_error($unzipped)) {
972
+ printf('%s: %s', $unzipped->get_error_code(), $unzipped->get_error_message());
973
+ exit;
974
+ }
975
+
976
+ exit;
977
+ }
978
+
979
+ protected function do_unzip_file($from, $to)
980
+ {
981
+ if (!file_exists($from)) {
982
+ return new WP_Error('file-missing', 'Archive missing.');
983
+ }
984
+
985
+ $fp = fopen($from, 'rb');
986
+ $bytes = fread($fp, 2);
987
+ fclose($fp);
988
+
989
+ switch ($bytes) {
990
+ case "\37\213":
991
+ // gz
992
+ case 'BZ':
993
+ return new WP_Error('unimplemented', 'That method is not yet implemented.');
994
+ break;
995
+ case 'PK':
996
+ return unzip_file($from, $to);
997
+ default:
998
+ return new WP_Error('unknown', 'Unknown archive type');
999
+ }
1000
+ }
1001
+
1002
+ public function wpide_save_image()
1003
+ {
1004
+ $filennonce = split("::", $_POST["opt"]); //file::nonce
1005
+
1006
+ //check the user has a valid nonce
1007
+ //we are checking two variations of the nonce, one as-is and another that we have removed a trailing zero from
1008
+ //this is to get around some sort of bug where a nonce generated on another page has a trailing zero and a nonce generated/checked here doesn't have the zero
1009
+ if (
1010
+ !wp_verify_nonce($filennonce[1], 'wpide_image_edit' . $filennonce[0]) &&
1011
+ !wp_verify_nonce(rtrim($filennonce[1], "0"), 'wpide_image_edit' . $filennonce[0])
1012
+ ) {
1013
+ die('Security check'); //die because both checks failed
1014
+ }
1015
+ //check the user has the permissions
1016
+ if (!current_user_can('edit_themes')) {
1017
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1018
+ }
1019
+
1020
+
1021
+ $_POST['content'] = base64_decode($_POST["data"]); //image content
1022
+ $_POST['filename'] = $filennonce[0]; //filename
1023
+
1024
+ //setup wp_filesystem api
1025
+ global $wp_filesystem;
1026
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1027
+ $form_fields = null; // for now, but at some point the login info should be passed in here
1028
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1029
+ // no credentials yet, just produced a form for the user to fill in
1030
+ return true; // stop the normal page form from displaying
1031
+ }
1032
+ if (!WP_Filesystem($creds))
1033
+ echo "Cannot initialise the WP file system API";
1034
+
1035
+ //save a copy of the file and create a backup just in case
1036
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1037
+ $file_name = $root . stripslashes($_POST['filename']);
1038
+
1039
+ //set backup filename
1040
+ $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
1041
+ $backup_path = plugin_dir_path(__FILE__) . $backup_path;
1042
+
1043
+ //create backup directory if not there
1044
+ $new_file_info = pathinfo($backup_path);
1045
+ if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
1046
+
1047
+ //do backup
1048
+ $wp_filesystem->move($file_name, $backup_path);
1049
+
1050
+ //save file
1051
+ if ($wp_filesystem->put_contents($file_name, $_POST['content'])) {
1052
+ $result = "success";
1053
+ }
1054
+
1055
+ if ($result == "success") {
1056
+ wp_die('<p>' . __('<strong>Image saved.</strong> <br />You may <a href="JavaScript:window.close();">close this window / tab</a>.') . '</p>');
1057
+ } else {
1058
+ wp_die('<p>' . __('<strong>Problem saving image.</strong> <br /><a href="JavaScript:window.close();">Close this window / tab</a> and try editing the image again.') . '</p>');
1059
+ }
1060
+ //print_r($_POST);
1061
+ }
1062
+
1063
+
1064
+ public function wpide_startup_check()
1065
+ {
1066
+ global $wp_filesystem, $wp_version;
1067
+
1068
+ echo "\n\n\n\nWPIDE STARTUP CHECKS \n";
1069
+ echo "___________________ \n\n";
1070
+
1071
+ // WordPress version
1072
+ if ($wp_version > 5) {
1073
+ echo "WordPress version = " . $wp_version . "\n\n";
1074
+ } else {
1075
+ echo "WordPress version = " . $wp_version . " (which is too old to run WPide) \n\n";
1076
+ }
1077
+
1078
+ //check the user has the permissions
1079
+ check_admin_referer('plugin-name-action_wpidenonce');
1080
+ if (!current_user_can('edit_themes'))
1081
+ wp_die('<p>' . __('You do not have sufficient permissions to edit templates for this site. SORRY') . '</p>');
1082
+
1083
+ if (defined('WPIDE_FS_METHOD_FORCED_ELSEWHERE')) {
1084
+ echo "WordPress filesystem API has been forced to use the " . WPIDE_FS_METHOD_FORCED_ELSEWHERE . " method by another plugin/WordPress. \n\n";
1085
+ }
1086
+
1087
+ //setup wp_filesystem api
1088
+ $wpide_filesystem_before = $wp_filesystem;
1089
+
1090
+ $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1091
+ $form_fields = null; // for now, but at some point the login info should be passed in here
1092
+ ob_start();
1093
+ if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1094
+ // if we get here, then we don't have credentials yet,
1095
+ // but have just produced a form for the user to fill in,
1096
+ // so stop processing for now
1097
+ //return true; // stop the normal page form from displaying
1098
+ }
1099
+ ob_end_clean();
1100
+ if (!WP_Filesystem($creds)) {
1101
+
1102
+ echo "There has been a problem initialising the filesystem API \n\n";
1103
+ echo "Filesystem API before this plugin ran: \n\n" . print_r($wpide_filesystem_before, true);
1104
+ echo "Filesystem API now: \n\n" . print_r($wp_filesystem, true);
1105
+ }
1106
+ unset($wpide_filesystem_before);
1107
+
1108
+
1109
+ $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1110
+ if (isset($wp_filesystem)) {
1111
+
1112
+ //Running webservers user and group
1113
+ echo "Web server user/group = " . getenv('APACHE_RUN_USER') . ":" . getenv('APACHE_RUN_GROUP') . "\n";
1114
+ //wp-content user and group
1115
+ echo "wp-content owner/group = " . $wp_filesystem->owner($root) . ":" . $wp_filesystem->group($root) . "\n\n";
1116
+
1117
+
1118
+ //check we can list wp-content files
1119
+ if ($wp_filesystem->exists($root)) {
1120
+
1121
+ $files = $wp_filesystem->dirlist($root);
1122
+ if (count($files) > 0) {
1123
+ echo "wp-content folder exists and contains " . count($files) . " files \n";
1124
+ } else {
1125
+ echo "wp-content folder exists but we cannot read it's contents \n";
1126
+ }
1127
+ }
1128
+
1129
+ // $wp_filesystem->owner() $wp_filesystem->group() $wp_filesystem->is_writable() $wp_filesystem->is_readable()
1130
+ echo "\nUsing the " . $wp_filesystem->method . " method of the WP filesystem API\n";
1131
+
1132
+ //wp-content editable?
1133
+ echo "The wp-content folder " . ($wp_filesystem->is_readable($root) == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root) == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1134
+
1135
+
1136
+ //plugins folder editable
1137
+ echo "The wp-content/plugins folder " . ($wp_filesystem->is_readable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1138
+
1139
+
1140
+ //themes folder editable
1141
+ echo "The wp-content/themes folder " . ($wp_filesystem->is_readable($root . "/themes") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/themes") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1142
+ }
1143
+
1144
+ echo "___________________ \n\n\n\n";
1145
+
1146
+ echo " If the file tree to the right is empty there is a possibility that your server permissions are not compatible with this plugin. \n The startup information above may shed some light on things. \n Paste that information into the support forum for further assistance.";
1147
+
1148
+
1149
+ die();
1150
+ }
1151
+
1152
+ public function add_my_menu_page()
1153
+ {
1154
+ $this->menu_hook = add_menu_page('WPide', 'WPide', 'edit_themes', "wpide", array($this, 'my_menu_page'), 'dashicons-editor-code');
1155
+ }
1156
+
1157
+ public function my_menu_page()
1158
+ {
1159
+ if (!current_user_can('edit_themes')) {
1160
+ wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1161
+ }
1162
+
1163
+ $app_url = get_bloginfo('url'); //need to make this https if we are currently looking on the site using https (even though https for admin might not be forced it can still cause issues)
1164
+ if (is_ssl()) $app_url = str_replace("http:", "https:", $app_url);
1165
+
1166
+ ?>
1167
+ <script>
1168
+ var wpide_app_path = "<?php echo plugin_dir_url(__FILE__); ?>";
1169
+ //dont think this is needed any more.. var wpide_file_root_url = "<?php echo apply_filters("wpide_file_root_url", WP_CONTENT_URL); ?>";
1170
+ var user_nonce_addition = '';
1171
+
1172
+ function the_filetree() {
1173
+ jQuery('#wpide_file_browser').fileTree({
1174
+ script: ajaxurl
1175
+ }, function(parent, file) {
1176
+
1177
+ if (jQuery(parent).hasClass("create_new")) { //create new file/folder
1178
+ //to create a new item we need to know the name of it so show input
1179
+
1180
+ var item = eval('(' + file + ')');
1181
+
1182
+ //hide all inputs just incase one is selected
1183
+ jQuery(".new_item_inputs").hide();
1184
+ //show the input form for this
1185
+ jQuery("div.new_" + item.type).show();
1186
+ jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").focus();
1187
+ jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").attr("rel", file);
1188
+
1189
+
1190
+ } else if (jQuery(".wpide_tab[rel='" + file + "']").length > 0) { //focus existing tab
1191
+ jQuery(".wpide_tab[sessionrel='" + jQuery(".wpide_tab[rel='" + file + "']").attr("sessionrel") + "']").click(); //focus the already open tab
1192
+ } else { //open file
1193
+
1194
+ var image_pattern = new RegExp("(\\.jpg$|\\.gif$|\\.png$|\\.bmp$)");
1195
+ if (image_pattern.test(file)) {
1196
+ //it's an image so open it for editing
1197
+
1198
+ //using modal+iframe
1199
+ if ("lets not" == "use the modal for now") {
1200
+
1201
+ var NewDialog = jQuery('<div id="MenuDialog">\
1202
+ <iframe src="http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&target=<?php echo get_bloginfo('url') . "?action=wpide_image_save"; ?>&url=<?php echo get_bloginfo('url') . "/wp-content"; ?>' + file + '&title=Edit image&service=Save back to WPide" width="100%" height="600px"> </iframe>\
1203
+ </div>');
1204
+ NewDialog.dialog({
1205
+ modal: true,
1206
+ title: "title",
1207
+ show: 'clip',
1208
+ hide: 'clip',
1209
+ width: '800',
1210
+ height: '600'
1211
+ });
1212
+
1213
+ } else { //open in new tab/window
1214
+
1215
+ var data = {
1216
+ action: 'wpide_image_edit_key',
1217
+ file: file,
1218
+ _wpnonce: jQuery('#_wpnonce').val(),
1219
+ _wp_http_referer: jQuery('#_wp_http_referer').val()
1220
+ };
1221
+ var image_data = '';
1222
+ jQuery.ajaxSetup({
1223
+ async: false
1224
+ }); //we need to wait until we get the response before opening the window
1225
+ jQuery.post(ajaxurl, data, function(response) {
1226
+
1227
+ //with the response (which is a nonce), build the json data to pass to the image editor. The edit key (nonce) is only valid to edit this image
1228
+ image_data = file + '::' + response;
1229
+
1230
+ });
1231
+
1232
+ jQuery.ajaxSetup({
1233
+ async: true
1234
+ }); //enable async again
1235
+
1236
+
1237
+ window.open('http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&url=<?php echo $app_url . "/wp-content"; ?>' + file + '&opt=' + image_data + '&title=Edit image&service=Save back to WPide&target=<?php echo urlencode($app_url . "/wp-admin/admin.php?wpide_save_image=yes"); ?>');
1238
+
1239
+ }
1240
+
1241
+ } else {
1242
+ jQuery(parent).addClass('wait');
1243
+
1244
+ wpide_set_file_contents(file, function() {
1245
+
1246
+ //once file loaded remove the wait class/indicator
1247
+ jQuery(parent).removeClass('wait');
1248
+
1249
+ });
1250
+
1251
+ jQuery('#filename').val(file);
1252
+ }
1253
+
1254
+ }
1255
+
1256
+ });
1257
+ }
1258
+
1259
+
1260
+
1261
+ jQuery(document).ready(function($) {
1262
+
1263
+ // $("#fancyeditordiv").css("height", ($('body').height()-120) + 'px' );
1264
+
1265
+ // Handler for .ready() called.
1266
+ the_filetree();
1267
+
1268
+ //inialise the color assist
1269
+ $("#wpide_color_assist img").ImageColorPicker({
1270
+ afterColorSelected: function(event, color) {
1271
+ jQuery("#wpide_color_assist_input").val(color);
1272
+ }
1273
+ });
1274
+ $("#wpide_color_assist").hide(); //hide it until it's needed
1275
+
1276
+ $("#wpide_color_assist_send").click(function(e) {
1277
+ e.preventDefault();
1278
+ editor.insert(jQuery("#wpide_color_assist_input").val().replace('#', ''));
1279
+
1280
+ $("#wpide_color_assist").hide(); //hide it until it's needed again
1281
+ });
1282
+
1283
+ $(".close_color_picker a").click(function(e) {
1284
+ e.preventDefault();
1285
+ $("#wpide_color_assist").hide(); //hide it until it's needed again
1286
+ });
1287
+
1288
+ $("#wpide_toolbar_buttons").on('click', "a.restore", function(e) {
1289
+ e.preventDefault();
1290
+ var file_path = jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup");
1291
+
1292
+ jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1293
+ jQuery("#wpide_message").html('<span><strong>File available for restore</strong><p> ' + file_path + '</p><a class="button red restore now" href="' + wpide_app_path + file_path + '">Restore this file now &#10012;</a><a class="button restore cancel" href="#">Cancel &#10007;</a><br /><em class="note"><strong>note: </strong>You can browse all file backups if you navigate to the backups folder (plugins/WPide/backups/..) using the filetree.</em></span>');
1294
+ jQuery("#wpide_message").show();
1295
+ });
1296
+ $("#wpide_toolbar_buttons").on('click', "a.restore.now", function(e) {
1297
+ e.preventDefault();
1298
+
1299
+ var data = {
1300
+ restorewpnonce: user_nonce_addition + jQuery('#_wpnonce').val()
1301
+ };
1302
+ jQuery.post(wpide_app_path + jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup"), data, function(response) {
1303
+
1304
+ if (response == -1) {
1305
+ alert("Problem restoring file.");
1306
+ } else {
1307
+ alert(response);
1308
+ jQuery("#wpide_message").hide();
1309
+ }
1310
+
1311
+ });
1312
+
1313
+ });
1314
+ $("#wpide_toolbar_buttons").on('click', "a.cancel", function(e) {
1315
+ e.preventDefault();
1316
+
1317
+ jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1318
+ });
1319
+
1320
+ });
1321
+ </script>
1322
+
1323
+ <div id="poststuff" class="metabox-holder has-right-sidebar">
1324
+
1325
+ <div id="side-info-column" class="inner-sidebar">
1326
+
1327
+ <div id="wpide_info">
1328
+ <div id="wpide_info_content"></div>
1329
+ </div>
1330
+ <br style="clear:both;" />
1331
+ <div id="wpide_color_assist">
1332
+ <div class="close_color_picker"><a href="close-color-picker">x</a></div>
1333
+ <h3>Colour Assist</h3>
1334
+ <img src='<?php echo plugins_url("images/color-wheel.png", __FILE__); ?>' />
1335
+ <input type="button" class="button" id="wpide_color_assist_send" value="&lt; Send to editor" />
1336
+ <input type="text" id="wpide_color_assist_input" name="wpide_color_assist_input" value="" />
1337
+
1338
+ </div>
1339
+
1340
+
1341
+
1342
+ <div id="submitdiv" class="postbox ">
1343
+ <h3 class="hndle"><span>Files</span></h3>
1344
+ <div class="inside">
1345
+ <div class="submitbox" id="submitpost">
1346
+ <div id="minor-publishing">
1347
+ </div>
1348
+ <div id="major-publishing-actions">
1349
+ <div id="wpide_file_browser"></div>
1350
+ <br style="clear:both;" />
1351
+ <div class="new_file new_item_inputs">
1352
+ <label for="new_folder">File name</label><input class="has_data" name="new_file" type="text" rel="" value="" placeholder="Filename.ext" />
1353
+ <a href="#" id="wpide_create_new_file" class="button-primary">CREATE</a>
1354
+ </div>
1355
+ <div class="new_directory new_item_inputs">
1356
+ <label for="new_directory">Directory name</label><input class="has_data" name="new_directory" type="text" rel="" value="" placeholder="Filename.ext" />
1357
+ <a href="#" id="wpide_create_new_directory" class="button-primary">CREATE</a>
1358
+ </div>
1359
+ <div class="clear"></div>
1360
+ </div>
1361
+ </div>
1362
+ </div>
1363
+ </div>
1364
+
1365
+
1366
+ </div>
1367
+
1368
+ <div id="post-body">
1369
+ <div id="wpide_toolbar" class="quicktags-toolbar">
1370
+ <div id="wpide_toolbar_tabs"> </div>
1371
+ <div id="dialog_window_minimized_container"></div>
1372
+ </div>
1373
+
1374
+ <div id="wpide_toolbar_buttons">
1375
+ <div id="wpide_message"></div>
1376
+ <a class="button restore" style="display:none;" title="Restore the active tab" href="#">Restore &#10012;</a>
1377
+
1378
+ </div>
1379
+
1380
+
1381
+ <div id='fancyeditordiv'></div>
1382
+
1383
+ <form id="wpide_save_container" action="" method="get">
1384
+ <div id="wpide_footer_message"></div>
1385
+ <div id="wpide_footer_message_last_saved"></div>
1386
+ <div id="wpide_footer_message_unsaved"></div>
1387
+
1388
+ <a href="#" id="wpide_save" alt="Keyboard shortcut to save [Ctrl/Cmd + S]" title="Keyboard shortcut to save [Ctrl/Cmd + S]" class="button-primary">SAVE
1389
+ FILE</a>
1390
+
1391
+ <input type="hidden" id="filename" name="filename" value="" />
1392
+ <?php
1393
+ if (function_exists('wp_nonce_field'))
1394
+ wp_nonce_field('plugin-name-action_wpidenonce');
1395
+ ?>
1396
+ </form>
1397
+
1398
+ </div>
1399
+
1400
+ </div>
1401
+
1402
+ <?php
1403
+ }
1404
+
1405
+ public function print_find_dialog()
1406
+ {
1407
+ if (!$this->is_plugin_page()) {
1408
+ return;
1409
+ }
1410
+ ?>
1411
+ <div id="editor_find_dialog" title="Find..." style="padding: 0px; display: none;">
1412
+ <?php if (false) : ?>
1413
+ <ul>
1414
+ <li><a href="#find-inline">Text</a></li>
1415
+ <li><a href="#find-func">Function</a></li>
1416
+ </ul>
1417
+ <?php endif; ?>
1418
+ <form id="find-inline" style="position: relative; padding: 4px; margin: 0px; height: 100%; overflow: hidden; width: 400px;">
1419
+ <label class="left"> Find<input type="search" name="find" /></label>
1420
+ <label class="left"> Replace<input type="search" name="replace" /></label>
1421
+ <div class="clear" style="height: 33px;"></div>
1422
+
1423
+ <label><input type="checkbox" name="wrap" checked="checked" /> Wrap Around</label>
1424
+ <label><input type="checkbox" name="case" /> Case Sensitive</label>
1425
+ <label><input type="checkbox" name="whole" /> Match Whole Word</label>
1426
+ <label><input type="checkbox" name="regexp" /> Regular Expression</label>
1427
+
1428
+ <div class="search_direction">
1429
+ Direction:
1430
+ <label><input type="radio" name="direction" value="0" /> Up</label>
1431
+ <label><input type="radio" name="direction" value="1" checked="checked" /> Down</label>
1432
+ </div>
1433
+ <div class="right">
1434
+ <input type="submit" name="submit" value="Find" class="action_button" />
1435
+ <input type="button" name="replace" value="Replace" class="action_button" />
1436
+ <input type="button" name="replace_all" value="Replace All" class="action_button" />
1437
+ <input type="button" name="cancel" value="Cancel" class="action_button" />
1438
+ </div>
1439
+ </form>
1440
+ <?php if (false) : ?>
1441
+ <form id="find-func">
1442
+ <label class="left"> Function<input type="search" name="find" /></label>
1443
+ <div class="right">
1444
+ <input type="submit" name="submit" value="Find Function" class="action_button" />
1445
+ </div>
1446
+ </form>
1447
+ <?php endif; ?>
1448
+ </div>
1449
+ <div id="editor_goto_dialog" title="Go to..." style="padding: 0px; display: none;"></div>
1450
+ <?php
1451
+ }
1452
+ }
1453
+
1454
+ $wpide = new wpide();
1455
+
1456
+ endif; // class_exists check