Admin Menu Editor - Version 1.8.6

Version Description

  • Fixed a PHP warning being thrown when the WPMU_PLUGIN_DIR constant is not a valid path or the full path cannot be determined.
  • Fixed a rare PHP warning "parameter 1 to be array, null given in menu-editor-core.php on line 4254" that was most likely caused by an unidentified plugin conflict.
  • Fixed a rare warning about a class being redefined.
  • Updated a number of internal dependencies.
  • Tested with WP 5.0.
Download this release

Release Info

Developer whiteshadow
Plugin Icon 128x128 Admin Menu Editor
Version 1.8.6
Comparing to
See all releases

Code changes from version 1.8.5 to 1.8.6

css/jquery.qtip.css CHANGED
@@ -1,26 +1,16 @@
1
- /*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-09-10
2
- * http://craigsworks.com/projects/qtip2/
3
- * Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */
4
-
5
- /* Fluid class for determining actual width in IE */
6
- #qtip-rcontainer{
7
- position: absolute;
8
- left: -28000px;
9
- top: -28000px;
10
- display: block;
11
- visibility: hidden;
12
- }
13
-
14
- /* Fluid class for determining actual width in IE */
15
- #qtip-rcontainer .ui-tooltip{
16
- display: block !important;
17
- visibility: hidden !important;
18
- position: static !important;
19
- float: left !important;
20
- }
21
-
22
- /* Core qTip styles */
23
- .ui-tooltip, .qtip{
24
position: absolute;
25
left: -28000px;
26
top: -28000px;
@@ -28,12 +18,17 @@
28
29
max-width: 280px;
30
min-width: 50px;
31
-
32
font-size: 10.5px;
33
line-height: 12px;
34
}
35
36
- .ui-tooltip-content{
37
position: relative;
38
padding: 5px 9px;
39
overflow: hidden;
@@ -42,9 +37,8 @@
42
word-wrap: break-word;
43
}
44
45
- .ui-tooltip-titlebar{
46
position: relative;
47
- min-height: 14px;
48
padding: 5px 35px 5px 10px;
49
overflow: hidden;
50
@@ -52,42 +46,46 @@
52
font-weight: bold;
53
}
54
55
- .ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0 !important; }
56
57
- /* Default close button class */
58
- .ui-tooltip-titlebar .ui-state-default{
59
- position: absolute;
60
- right: 4px;
61
- top: 50%;
62
- margin-top: -9px;
63
64
- cursor: pointer;
65
- outline: medium none;
66
67
- border-width: 1px;
68
- border-style: solid;
69
}
70
-
71
- * html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */
72
73
- .ui-tooltip-titlebar .ui-icon,
74
- .ui-tooltip-icon .ui-icon{
75
display: block;
76
text-indent: -1000em;
77
direction: ltr;
78
}
79
80
- .ui-tooltip-icon, .ui-tooltip-icon .ui-icon{
81
-moz-border-radius: 3px;
82
-webkit-border-radius: 3px;
83
border-radius: 3px;
84
text-decoration: none;
85
}
86
87
- .ui-tooltip-icon .ui-icon{
88
width: 18px;
89
height: 14px;
90
91
text-align: center;
92
text-indent: 0;
93
font: normal bold 10px/13px Tahoma,sans-serif;
@@ -96,171 +94,173 @@
96
background: transparent none no-repeat -100em -100em;
97
}
98
99
-
100
/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
101
- .ui-tooltip-focus{}
102
103
/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
104
- .ui-tooltip-hover{}
105
106
/* Default tooltip style */
107
- .ui-tooltip-default{
108
- border-width: 1px;
109
- border-style: solid;
110
- border-color: #F1D031;
111
112
background-color: #FFFFA3;
113
color: #555;
114
}
115
116
- .ui-tooltip-default .ui-tooltip-titlebar{
117
background-color: #FFEF93;
118
}
119
120
- .ui-tooltip-default .ui-tooltip-icon{
121
border-color: #CCC;
122
background: #F1F1F1;
123
color: #777;
124
}
125
-
126
- .ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{
127
border-color: #AAA;
128
color: #111;
129
}
130
131
132
/*! Light tooltip style */
133
- .ui-tooltip-light{
134
background-color: white;
135
border-color: #E2E2E2;
136
color: #454545;
137
}
138
139
- .ui-tooltip-light .ui-tooltip-titlebar{
140
background-color: #f1f1f1;
141
}
142
143
144
/*! Dark tooltip style */
145
- .ui-tooltip-dark{
146
background-color: #505050;
147
border-color: #303030;
148
color: #f3f3f3;
149
}
150
151
- .ui-tooltip-dark .ui-tooltip-titlebar{
152
background-color: #404040;
153
}
154
155
- .ui-tooltip-dark .ui-tooltip-icon{
156
border-color: #444;
157
}
158
159
- .ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{
160
border-color: #303030;
161
}
162
163
164
/*! Cream tooltip style */
165
- .ui-tooltip-cream{
166
background-color: #FBF7AA;
167
border-color: #F9E98E;
168
color: #A27D35;
169
}
170
171
- .ui-tooltip-cream .ui-tooltip-titlebar{
172
background-color: #F0DE7D;
173
}
174
175
- .ui-tooltip-cream .ui-state-default .ui-tooltip-icon{
176
background-position: -82px 0;
177
}
178
179
180
/*! Red tooltip style */
181
- .ui-tooltip-red{
182
background-color: #F78B83;
183
border-color: #D95252;
184
color: #912323;
185
}
186
187
- .ui-tooltip-red .ui-tooltip-titlebar{
188
background-color: #F06D65;
189
}
190
191
- .ui-tooltip-red .ui-state-default .ui-tooltip-icon{
192
background-position: -102px 0;
193
}
194
195
- .ui-tooltip-red .ui-tooltip-icon{
196
border-color: #D95252;
197
}
198
199
- .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{
200
border-color: #D95252;
201
}
202
203
204
/*! Green tooltip style */
205
- .ui-tooltip-green{
206
background-color: #CAED9E;
207
border-color: #90D93F;
208
color: #3F6219;
209
}
210
211
- .ui-tooltip-green .ui-tooltip-titlebar{
212
background-color: #B0DE78;
213
}
214
215
- .ui-tooltip-green .ui-state-default .ui-tooltip-icon{
216
background-position: -42px 0;
217
}
218
219
220
/*! Blue tooltip style */
221
- .ui-tooltip-blue{
222
background-color: #E5F6FE;
223
border-color: #ADD9ED;
224
color: #5E99BD;
225
}
226
227
- .ui-tooltip-blue .ui-tooltip-titlebar{
228
background-color: #D0E9F5;
229
}
230
231
- .ui-tooltip-blue .ui-state-default .ui-tooltip-icon{
232
background-position: -2px 0;
233
}
234
235
236
- /* Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
237
- .ui-tooltip-shadow{
238
-webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
239
-moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
240
box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
241
}
242
243
/* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
244
- .ui-tooltip-rounded,
245
- .ui-tooltip-tipsy,
246
- .ui-tooltip-bootstrap{
247
-moz-border-radius: 5px;
248
-webkit-border-radius: 5px;
249
border-radius: 5px;
250
}
251
252
/* Youtube tooltip style */
253
- .ui-tooltip-youtube{
254
-moz-border-radius: 2px;
255
-webkit-border-radius: 2px;
256
border-radius: 2px;
257
-
258
-webkit-box-shadow: 0 0 3px #333;
259
-moz-box-shadow: 0 0 3px #333;
260
box-shadow: 0 0 3px #333;
261
262
color: white;
263
- border-width: 0;
264
265
background: #4A4A4A;
266
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));
@@ -270,30 +270,30 @@
270
background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);
271
}
272
273
- .ui-tooltip-youtube .ui-tooltip-titlebar{
274
background-color: #4A4A4A;
275
background-color: rgba(0,0,0,0);
276
}
277
-
278
- .ui-tooltip-youtube .ui-tooltip-content{
279
padding: .75em;
280
font: 12px arial,sans-serif;
281
-
282
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);
283
-ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);";
284
}
285
286
- .ui-tooltip-youtube .ui-tooltip-icon{
287
border-color: #222;
288
}
289
290
- .ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{
291
border-color: #303030;
292
}
293
294
295
/* jQuery TOOLS Tooltip style */
296
- .ui-tooltip-jtools{
297
background: #232323;
298
background: rgba(0, 0, 0, 0.7);
299
background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
@@ -315,34 +315,34 @@
315
}
316
317
/* IE Specific */
318
- .ui-tooltip-jtools .ui-tooltip-titlebar{
319
background-color: transparent;
320
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
321
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
322
}
323
- .ui-tooltip-jtools .ui-tooltip-content{
324
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
325
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
326
}
327
328
- .ui-tooltip-jtools .ui-tooltip-titlebar,
329
- .ui-tooltip-jtools .ui-tooltip-content{
330
background: transparent;
331
color: white;
332
border: 0 dashed transparent;
333
}
334
335
- .ui-tooltip-jtools .ui-tooltip-icon{
336
border-color: #555;
337
}
338
339
- .ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{
340
border-color: #333;
341
}
342
343
344
/* Cluetip style */
345
- .ui-tooltip-cluetip{
346
-webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
347
-moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
348
box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
@@ -352,24 +352,24 @@
352
border: 0 dashed transparent;
353
}
354
355
- .ui-tooltip-cluetip .ui-tooltip-titlebar{
356
background-color: #87876A;
357
color: white;
358
border: 0 dashed transparent;
359
}
360
-
361
- .ui-tooltip-cluetip .ui-tooltip-icon{
362
border-color: #808064;
363
}
364
-
365
- .ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{
366
border-color: #696952;
367
color: #696952;
368
}
369
370
371
/* Tipsy style */
372
- .ui-tooltip-tipsy{
373
background: black;
374
background: rgba(0, 0, 0, .87);
375
@@ -383,27 +383,27 @@
383
text-shadow: 0 1px black;
384
}
385
386
- .ui-tooltip-tipsy .ui-tooltip-titlebar{
387
- padding: 6px 35px 0 10;
388
background-color: transparent;
389
}
390
391
- .ui-tooltip-tipsy .ui-tooltip-content{
392
- padding: 6px 10;
393
}
394
-
395
- .ui-tooltip-tipsy .ui-tooltip-icon{
396
border-color: #222;
397
text-shadow: none;
398
}
399
400
- .ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{
401
border-color: #303030;
402
}
403
404
405
/* Tipped style */
406
- .ui-tooltip-tipped{
407
border: 3px solid #959FA9;
408
409
-moz-border-radius: 3px;
@@ -417,7 +417,7 @@
417
font-family: serif;
418
}
419
420
- .ui-tooltip-tipped .ui-tooltip-titlebar{
421
border-bottom-width: 0;
422
423
color: white;
@@ -431,12 +431,12 @@
431
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
432
}
433
434
- .ui-tooltip-tipped .ui-tooltip-icon{
435
border: 2px solid #285589;
436
background: #285589;
437
}
438
439
- .ui-tooltip-tipped .ui-tooltip-icon .ui-icon{
440
background-color: #FBFBFB;
441
color: #555;
442
}
@@ -448,53 +448,87 @@
448
* Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.
449
* Does not work with IE 7.
450
*/
451
- .ui-tooltip-bootstrap{
452
- font-size: 13px;
453
- line-height: 18px;
454
-
455
color: #333333;
456
- background-color: #ffffff;
457
-
458
459
border: 1px solid #ccc;
460
border: 1px solid rgba(0, 0, 0, 0.2);
461
-
462
- *border-right-width: 2px;
463
- *border-bottom-width: 2px;
464
-
465
- -webkit-border-radius: 5px;
466
- -moz-border-radius: 5px;
467
- border-radius: 5px;
468
-
469
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
470
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
471
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
472
-
473
-webkit-background-clip: padding-box;
474
-moz-background-clip: padding;
475
background-clip: padding-box;
476
}
477
478
- .ui-tooltip-bootstrap .ui-tooltip-titlebar{
479
- font-size: 18px;
480
- line-height: 22px;
481
-
482
- border-bottom: 1px solid #ccc;
483
- background-color: transparent;
484
- }
485
-
486
- .ui-tooltip-bootstrap .ui-tooltip-titlebar .ui-state-default{
487
- right: 9px; top: 49%;
488
border-style: none;
489
}
490
491
- .ui-tooltip-bootstrap .ui-tooltip-icon{
492
- background: white;
493
}
494
495
- .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon{
496
width: auto;
497
height: auto;
498
float: right;
499
font-size: 20px;
500
font-weight: bold;
@@ -505,7 +539,8 @@
505
filter: alpha(opacity=20);
506
}
507
508
- .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon:hover{
509
color: #000000;
510
text-decoration: none;
511
cursor: pointer;
@@ -515,44 +550,49 @@
515
516
517
/* IE9 fix - removes all filters */
518
- .ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,
519
- .ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{
520
filter: none;
521
-ms-filter: none;
522
}
523
524
525
- /* Tips plugin */
526
- .ui-tooltip .ui-tooltip-tip{
527
margin: 0 auto;
528
overflow: hidden;
529
z-index: 10;
530
}
531
532
- .ui-tooltip .ui-tooltip-tip,
533
- .ui-tooltip .ui-tooltip-tip .qtip-vml{
534
position: absolute;
535
-
536
- line-height: 0.1px !important;
537
- font-size: 0.1px !important;
538
- color: #123456;
539
540
background: transparent;
541
border: 0 dashed transparent;
542
}
543
-
544
- .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; }
545
546
- .ui-tooltip .ui-tooltip-tip .qtip-vml{
547
behavior: url(#default#VML);
548
display: inline-block;
549
visibility: visible;
550
}
551
- /* Modal plugin */
552
#qtip-overlay{
553
position: fixed;
554
- left: -10000em;
555
- top: -10000em;
556
}
557
558
/* Applied to modals with show.modal.blur set to true */
@@ -571,3 +611,7 @@
571
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
572
}
573
1
+ /*
2
+ * qTip2 - Pretty powerful tooltips - v3.0.3
3
+ * http://qtip2.com
4
+ *
5
+ * Copyright (c) 2016
6
+ * Released under the MIT licenses
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: Wed May 11 2016 10:31 GMT+0100+0100
10
+ * Plugins: tips modal viewport svg imagemap ie6
11
+ * Styles: core basic css3
12
+ */
13
+ .qtip{
14
position: absolute;
15
left: -28000px;
16
top: -28000px;
18
19
max-width: 280px;
20
min-width: 50px;
21
+
22
font-size: 10.5px;
23
line-height: 12px;
24
+
25
+ direction: ltr;
26
+
27
+ box-shadow: none;
28
+ padding: 0;
29
}
30
31
+ .qtip-content{
32
position: relative;
33
padding: 5px 9px;
34
overflow: hidden;
37
word-wrap: break-word;
38
}
39
40
+ .qtip-titlebar{
41
position: relative;
42
padding: 5px 35px 5px 10px;
43
overflow: hidden;
44
46
font-weight: bold;
47
}
48
49
+ .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; }
50
51
+ /* Default close button class */
52
+ .qtip-close{
53
+ position: absolute;
54
+ right: -9px; top: -9px;
55
+ z-index: 11; /* Overlap .qtip-tip */
56
57
+ cursor: pointer;
58
+ outline: medium none;
59
+
60
+ border: 1px solid transparent;
61
+ }
62
63
+ .qtip-titlebar .qtip-close{
64
+ right: 4px; top: 50%;
65
+ margin-top: -9px;
66
}
67
68
+ * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */
69
+
70
+ .qtip-titlebar .ui-icon,
71
+ .qtip-icon .ui-icon{
72
display: block;
73
text-indent: -1000em;
74
direction: ltr;
75
}
76
77
+ .qtip-icon, .qtip-icon .ui-icon{
78
-moz-border-radius: 3px;
79
-webkit-border-radius: 3px;
80
border-radius: 3px;
81
text-decoration: none;
82
}
83
84
+ .qtip-icon .ui-icon{
85
width: 18px;
86
height: 14px;
87
88
+ line-height: 14px;
89
text-align: center;
90
text-indent: 0;
91
font: normal bold 10px/13px Tahoma,sans-serif;
94
background: transparent none no-repeat -100em -100em;
95
}
96
97
/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
98
+ .qtip-focus{}
99
100
/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
101
+ .qtip-hover{}
102
103
/* Default tooltip style */
104
+ .qtip-default{
105
+ border: 1px solid #F1D031;
106
107
background-color: #FFFFA3;
108
color: #555;
109
}
110
111
+ .qtip-default .qtip-titlebar{
112
background-color: #FFEF93;
113
}
114
115
+ .qtip-default .qtip-icon{
116
border-color: #CCC;
117
background: #F1F1F1;
118
color: #777;
119
}
120
+
121
+ .qtip-default .qtip-titlebar .qtip-close{
122
border-color: #AAA;
123
color: #111;
124
}
125
126
127
/*! Light tooltip style */
128
+ .qtip-light{
129
background-color: white;
130
border-color: #E2E2E2;
131
color: #454545;
132
}
133
134
+ .qtip-light .qtip-titlebar{
135
background-color: #f1f1f1;
136
}
137
138
139
/*! Dark tooltip style */
140
+ .qtip-dark{
141
background-color: #505050;
142
border-color: #303030;
143
color: #f3f3f3;
144
}
145
146
+ .qtip-dark .qtip-titlebar{
147
background-color: #404040;
148
}
149
150
+ .qtip-dark .qtip-icon{
151
border-color: #444;
152
}
153
154
+ .qtip-dark .qtip-titlebar .ui-state-hover{
155
border-color: #303030;
156
}
157
158
159
/*! Cream tooltip style */
160
+ .qtip-cream{
161
background-color: #FBF7AA;
162
border-color: #F9E98E;
163
color: #A27D35;
164
}
165
166
+ .qtip-cream .qtip-titlebar{
167
background-color: #F0DE7D;
168
}
169
170
+ .qtip-cream .qtip-close .qtip-icon{
171
background-position: -82px 0;
172
}
173
174
175
/*! Red tooltip style */
176
+ .qtip-red{
177
background-color: #F78B83;
178
border-color: #D95252;
179
color: #912323;
180
}
181
182
+ .qtip-red .qtip-titlebar{
183
background-color: #F06D65;
184
}
185
186
+ .qtip-red .qtip-close .qtip-icon{
187
background-position: -102px 0;
188
}
189
190
+ .qtip-red .qtip-icon{
191
border-color: #D95252;
192
}
193
194
+ .qtip-red .qtip-titlebar .ui-state-hover{
195
border-color: #D95252;
196
}
197
198
199
/*! Green tooltip style */
200
+ .qtip-green{
201
background-color: #CAED9E;
202
border-color: #90D93F;
203
color: #3F6219;
204
}
205
206
+ .qtip-green .qtip-titlebar{
207
background-color: #B0DE78;
208
}
209
210
+ .qtip-green .qtip-close .qtip-icon{
211
background-position: -42px 0;
212
}
213
214
215
/*! Blue tooltip style */
216
+ .qtip-blue{
217
background-color: #E5F6FE;
218
border-color: #ADD9ED;
219
color: #5E99BD;
220
}
221
222
+ .qtip-blue .qtip-titlebar{
223
background-color: #D0E9F5;
224
}
225
226
+ .qtip-blue .qtip-close .qtip-icon{
227
background-position: -2px 0;
228
}
229
230
231
+ .qtip-shadow{
232
-webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
233
-moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
234
box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
235
}
236
237
/* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
238
+ .qtip-rounded,
239
+ .qtip-tipsy,
240
+ .qtip-bootstrap{
241
-moz-border-radius: 5px;
242
-webkit-border-radius: 5px;
243
border-radius: 5px;
244
}
245
246
+ .qtip-rounded .qtip-titlebar{
247
+ -moz-border-radius: 4px 4px 0 0;
248
+ -webkit-border-radius: 4px 4px 0 0;
249
+ border-radius: 4px 4px 0 0;
250
+ }
251
+
252
/* Youtube tooltip style */
253
+ .qtip-youtube{
254
-moz-border-radius: 2px;
255
-webkit-border-radius: 2px;
256
border-radius: 2px;
257
+
258
-webkit-box-shadow: 0 0 3px #333;
259
-moz-box-shadow: 0 0 3px #333;
260
box-shadow: 0 0 3px #333;
261
262
color: white;
263
+ border: 0 solid transparent;
264
265
background: #4A4A4A;
266
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));
270
background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);
271
}
272
273
+ .qtip-youtube .qtip-titlebar{
274
background-color: #4A4A4A;
275
background-color: rgba(0,0,0,0);
276
}
277
+
278
+ .qtip-youtube .qtip-content{
279
padding: .75em;
280
font: 12px arial,sans-serif;
281
+
282
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);
283
-ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);";
284
}
285
286
+ .qtip-youtube .qtip-icon{
287
border-color: #222;
288
}
289
290
+ .qtip-youtube .qtip-titlebar .ui-state-hover{
291
border-color: #303030;
292
}
293
294
295
/* jQuery TOOLS Tooltip style */
296
+ .qtip-jtools{
297
background: #232323;
298
background: rgba(0, 0, 0, 0.7);
299
background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
315
}
316
317
/* IE Specific */
318
+ .qtip-jtools .qtip-titlebar{
319
background-color: transparent;
320
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
321
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
322
}
323
+ .qtip-jtools .qtip-content{
324
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
325
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
326
}
327
328
+ .qtip-jtools .qtip-titlebar,
329
+ .qtip-jtools .qtip-content{
330
background: transparent;
331
color: white;
332
border: 0 dashed transparent;
333
}
334
335
+ .qtip-jtools .qtip-icon{
336
border-color: #555;
337
}
338
339
+ .qtip-jtools .qtip-titlebar .ui-state-hover{
340
border-color: #333;
341
}
342
343
344
/* Cluetip style */
345
+ .qtip-cluetip{
346
-webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
347
-moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
348
box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
352
border: 0 dashed transparent;
353
}
354
355
+ .qtip-cluetip .qtip-titlebar{
356
background-color: #87876A;
357
color: white;
358
border: 0 dashed transparent;
359
}
360
+
361
+ .qtip-cluetip .qtip-icon{
362
border-color: #808064;
363
}
364
+
365
+ .qtip-cluetip .qtip-titlebar .ui-state-hover{
366
border-color: #696952;
367
color: #696952;
368
}
369
370
371
/* Tipsy style */
372
+ .qtip-tipsy{
373
background: black;
374
background: rgba(0, 0, 0, .87);
375
383
text-shadow: 0 1px black;
384
}
385
386
+ .qtip-tipsy .qtip-titlebar{
387
+ padding: 6px 35px 0 10px;
388
background-color: transparent;
389
}
390
391
+ .qtip-tipsy .qtip-content{
392
+ padding: 6px 10px;
393
}
394
+
395
+ .qtip-tipsy .qtip-icon{
396
border-color: #222;
397
text-shadow: none;
398
}
399
400
+ .qtip-tipsy .qtip-titlebar .ui-state-hover{
401
border-color: #303030;
402
}
403
404
405
/* Tipped style */
406
+ .qtip-tipped{
407
border: 3px solid #959FA9;
408
409
-moz-border-radius: 3px;
417
font-family: serif;
418
}
419
420
+ .qtip-tipped .qtip-titlebar{
421
border-bottom-width: 0;
422
423
color: white;
431
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
432
}
433
434
+ .qtip-tipped .qtip-icon{
435
border: 2px solid #285589;
436
background: #285589;
437
}
438
439
+ .qtip-tipped .qtip-icon .ui-icon{
440
background-color: #FBFBFB;
441
color: #555;
442
}
448
* Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.
449
* Does not work with IE 7.
450
*/
451
+ .qtip-bootstrap{
452
+ /** Taken from Bootstrap body */
453
+ font-size: 14px;
454
+ line-height: 20px;
455
color: #333333;
456
457
+ /** Taken from Bootstrap .popover */
458
+ padding: 1px;
459
+ background-color: #ffffff;
460
border: 1px solid #ccc;
461
border: 1px solid rgba(0, 0, 0, 0.2);
462
+ -webkit-border-radius: 6px;
463
+ -moz-border-radius: 6px;
464
+ border-radius: 6px;
465
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
466
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
467
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
468
-webkit-background-clip: padding-box;
469
-moz-background-clip: padding;
470
background-clip: padding-box;
471
}
472
473
+ .qtip-bootstrap .qtip-titlebar{
474
+ /** Taken from Bootstrap .popover-title */
475
+ padding: 8px 14px;
476
+ margin: 0;
477
+ font-size: 14px;
478
+ font-weight: normal;
479
+ line-height: 18px;
480
+ background-color: #f7f7f7;
481
+ border-bottom: 1px solid #ebebeb;
482
+ -webkit-border-radius: 5px 5px 0 0;
483
+ -moz-border-radius: 5px 5px 0 0;
484
+ border-radius: 5px 5px 0 0;
485
+ }
486
+
487
+ .qtip-bootstrap .qtip-titlebar .qtip-close{
488
+ /**
489
+ * Overrides qTip2:
490
+ * .qtip-titlebar .qtip-close{
491
+ * [...]
492
+ * right: 4px;
493
+ * top: 50%;
494
+ * [...]
495
+ * border-style: solid;
496
+ * }
497
+ */
498
+ right: 11px;
499
+ top: 45%;
500
border-style: none;
501
}
502
503
+ .qtip-bootstrap .qtip-content{
504
+ /** Taken from Bootstrap .popover-content */
505
+ padding: 9px 14px;
506
+ }
507
+
508
+ .qtip-bootstrap .qtip-icon{
509
+ /**
510
+ * Overrides qTip2:
511
+ * .qtip-default .qtip-icon {
512
+ * border-color: #CCC;
513
+ * background: #F1F1F1;
514
+ * color: #777;
515
+ * }
516
+ */
517
+ background: transparent;
518
}
519
520
+ .qtip-bootstrap .qtip-icon .ui-icon{
521
+ /**
522
+ * Overrides qTip2:
523
+ * .qtip-icon .ui-icon{
524
+ * width: 18px;
525
+ * height: 14px;
526
+ * }
527
+ */
528
width: auto;
529
height: auto;
530
+
531
+ /* Taken from Bootstrap .close */
532
float: right;
533
font-size: 20px;
534
font-weight: bold;
539
filter: alpha(opacity=20);
540
}
541
542
+ .qtip-bootstrap .qtip-icon .ui-icon:hover{
543
+ /* Taken from Bootstrap .close:hover */
544
color: #000000;
545
text-decoration: none;
546
cursor: pointer;
550
551
552
/* IE9 fix - removes all filters */
553
+ .qtip:not(.ie9haxors) div.qtip-content,
554
+ .qtip:not(.ie9haxors) div.qtip-titlebar{
555
filter: none;
556
-ms-filter: none;
557
}
558
559
560
+ .qtip .qtip-tip{
561
margin: 0 auto;
562
overflow: hidden;
563
z-index: 10;
564
+
565
}
566
567
+ /* Opera bug #357 - Incorrect tip position
568
+ https://github.com/Craga89/qTip2/issues/367 */
569
+ x:-o-prefocus, .qtip .qtip-tip{
570
+ visibility: hidden;
571
+ }
572
+
573
+ .qtip .qtip-tip,
574
+ .qtip .qtip-tip .qtip-vml,
575
+ .qtip .qtip-tip canvas{
576
position: absolute;
577
578
+ color: #123456;
579
background: transparent;
580
border: 0 dashed transparent;
581
}
582
583
+ .qtip .qtip-tip canvas{ top: 0; left: 0; }
584
+
585
+ .qtip .qtip-tip .qtip-vml{
586
behavior: url(#default#VML);
587
display: inline-block;
588
visibility: visible;
589
}
590
+
591
+
592
#qtip-overlay{
593
position: fixed;
594
+ left: 0; top: 0;
595
+ width: 100%; height: 100%;
596
}
597
598
/* Applied to modals with show.modal.blur set to true */
611
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
612
}
613
614
+
615
+ .qtipmodal-ie6fix{
616
+ position: absolute !important;
617
+ }
css/jquery.qtip.min.css CHANGED
@@ -1 +1 @@
1
- /*! qTip2 v2.0.0 | http://craigsworks.com/projects/qtip2/ | Licensed MIT, GPL */#qtip-rcontainer{position:absolute;left:-28000px;top:-28000px;display:block;visibility:hidden}#qtip-rcontainer .ui-tooltip{display:block!important;visibility:hidden!important;position:static!important;float:left!important}.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px}.ui-tooltip-content{position:relative;padding:5px 9px;overflow:hidden;text-align:left;word-wrap:break-word}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border-width:0 0 1px;font-weight:700}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important}.ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid}* html .ui-tooltip-titlebar .ui-state-default{top:16px}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em;direction:ltr}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em}.ui-tooltip-focus{}.ui-tooltip-hover{}.ui-tooltip-default{border-width:1px;border-style:solid;border-color:#F1D031;background-color:#FFFFA3;color:#555}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#FFEF93}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111}/*! Light tooltip style */.ui-tooltip-light{background-color:#fff;border-color:#E2E2E2;color:#454545}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1}/*! Dark tooltip style */.ui-tooltip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}/*! Cream tooltip style */.ui-tooltip-cream{background-color:#FBF7AA;border-color:#F9E98E;color:#A27D35}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#F0DE7D}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0}/*! Red tooltip style */.ui-tooltip-red{background-color:#F78B83;border-color:#D95252;color:#912323}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#F06D65}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0}.ui-tooltip-red .ui-tooltip-icon{border-color:#D95252}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#D95252}/*! Green tooltip style */.ui-tooltip-green{background-color:#CAED9E;border-color:#90D93F;color:#3F6219}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#B0DE78}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0}/*! Blue tooltip style */.ui-tooltip-blue{background-color:#E5F6FE;border-color:#ADD9ED;color:#5E99BD}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#D0E9F5}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0}.ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.ui-tooltip-rounded,.ui-tooltip-tipsy,.ui-tooltip-bootstrap{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.ui-tooltip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border-width:0;background:#4A4A4A;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0, #4A4A4A),color-stop(100%,black));background-image:-webkit-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-moz-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-ms-linear-gradient(top, #4A4A4A 0,black 100%);background-image:-o-linear-gradient(top, #4A4A4A 0,black 100%)}.ui-tooltip-youtube .ui-tooltip-titlebar{background-color:#4A4A4A;background-color:rgba(0,0,0,0)}.ui-tooltip-youtube .ui-tooltip-content{padding:.75em;font:12px arial,sans-serif;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);-ms-filter:"progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);"}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from( #717171),to( #232323));background-image:-moz-linear-gradient(top, #717171, #232323);background-image:-webkit-linear-gradient(top, #717171, #232323);background-image:-ms-linear-gradient(top, #717171, #232323);background-image:-o-linear-gradient(top, #717171, #232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.ui-tooltip-jtools .ui-tooltip-titlebar{background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A)"}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323)"}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:#fff;border:0 dashed transparent}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#D9D9C2;color:#111;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876A;color:#fff;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.ui-tooltip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px black}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10;background-color:transparent}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-tipped{border:3px solid #959FA9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#F9F9F9;color:#454545;font-weight:400;font-family:serif}.ui-tooltip-tipped .ui-tooltip-titlebar{border-bottom-width:0;color:#fff;background:#3A79B8;background-image:-webkit-gradient(linear,left top,left bottom,from( #3A79B8),to( #2E629D));background-image:-webkit-linear-gradient(top, #3A79B8, #2E629D);background-image:-moz-linear-gradient(top, #3A79B8, #2E629D);background-image:-ms-linear-gradient(top, #3A79B8, #2E629D);background-image:-o-linear-gradient(top, #3A79B8, #2E629D);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D)"}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#FBFBFB;color:#555}.ui-tooltip-bootstrap{font-size:13px;line-height:18px;color:#333;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.ui-tooltip-bootstrap .ui-tooltip-titlebar{font-size:18px;line-height:22px;border-bottom:1px solid #ccc;background-color:transparent}.ui-tooltip-bootstrap .ui-tooltip-titlebar .ui-state-default{right:9px;top:49%;border-style:none}.ui-tooltip-bootstrap .ui-tooltip-icon{background:#fff}.ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;z-index:10}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip .qtip-vml{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0}.ui-tooltip .ui-tooltip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed;left:-10000em;top:-10000em}#qtip-overlay.blurs{cursor:pointer}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#000;opacity:.7;filter:alpha(opacity=70);-ms-filter:"alpha(Opacity=70)"}
1
+ #qtip-overlay.blurs,.qtip-close{cursor:pointer}.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;direction:ltr;box-shadow:none;padding:0}.qtip-content,.qtip-titlebar{position:relative;overflow:hidden}.qtip-content{padding:5px 9px;text-align:left;word-wrap:break-word}.qtip-titlebar{padding:5px 35px 5px 10px;border-width:0 0 1px;font-weight:700}.qtip-titlebar+.qtip-content{border-top-width:0!important}.qtip-close{position:absolute;right:-9px;top:-9px;z-index:11;outline:0;border:1px solid transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-icon .ui-icon,.qtip-titlebar .ui-icon{display:block;text-indent:-1000em;direction:ltr}.qtip-icon,.qtip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.qtip-icon .ui-icon{width:18px;height:14px;line-height:14px;text-align:center;text-indent:0;font:normal 700 10px/13px Tahoma,sans-serif;color:inherit;background:-100em -100em no-repeat}.qtip-default{border:1px solid #F1D031;background-color:#FFFFA3;color:#555}.qtip-default .qtip-titlebar{background-color:#FFEF93}.qtip-default .qtip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.qtip-default .qtip-titlebar .qtip-close{border-color:#AAA;color:#111}.qtip-light{background-color:#fff;border-color:#E2E2E2;color:#454545}.qtip-light .qtip-titlebar{background-color:#f1f1f1}.qtip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.qtip-dark .qtip-titlebar{background-color:#404040}.qtip-dark .qtip-icon{border-color:#444}.qtip-dark .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-cream{background-color:#FBF7AA;border-color:#F9E98E;color:#A27D35}.qtip-red,.qtip-red .qtip-icon,.qtip-red .qtip-titlebar .ui-state-hover{border-color:#D95252}.qtip-cream .qtip-titlebar{background-color:#F0DE7D}.qtip-cream .qtip-close .qtip-icon{background-position:-82px 0}.qtip-red{background-color:#F78B83;color:#912323}.qtip-red .qtip-titlebar{background-color:#F06D65}.qtip-red .qtip-close .qtip-icon{background-position:-102px 0}.qtip-green{background-color:#CAED9E;border-color:#90D93F;color:#3F6219}.qtip-green .qtip-titlebar{background-color:#B0DE78}.qtip-green .qtip-close .qtip-icon{background-position:-42px 0}.qtip-blue{background-color:#E5F6FE;border-color:#ADD9ED;color:#5E99BD}.qtip-blue .qtip-titlebar{background-color:#D0E9F5}.qtip-blue .qtip-close .qtip-icon{background-position:-2px 0}.qtip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.qtip-bootstrap,.qtip-rounded,.qtip-tipsy{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.qtip-rounded .qtip-titlebar{-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.qtip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border:0 solid transparent;background:#4A4A4A;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,#000));background-image:-webkit-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-moz-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-ms-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-o-linear-gradient(top,#4A4A4A 0,#000 100%)}.qtip-youtube .qtip-titlebar{background-color:#4A4A4A;background-color:rgba(0,0,0,0)}.qtip-youtube .qtip-content{padding:.75em;font:12px arial,sans-serif;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);-ms-filter:"progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"}.qtip-youtube .qtip-icon{border-color:#222}.qtip-youtube .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-linear-gradient(top,#717171,#232323);background-image:-ms-linear-gradient(top,#717171,#232323);background-image:-o-linear-gradient(top,#717171,#232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.qtip-jtools .qtip-titlebar{background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"}.qtip-jtools .qtip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"}.qtip-jtools .qtip-content,.qtip-jtools .qtip-titlebar{background:0 0;color:#fff;border:0 dashed transparent}.qtip-jtools .qtip-icon{border-color:#555}.qtip-jtools .qtip-titlebar .ui-state-hover{border-color:#333}.qtip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#D9D9C2;color:#111;border:0 dashed transparent}.qtip-cluetip .qtip-titlebar{background-color:#87876A;color:#fff;border:0 dashed transparent}.qtip-cluetip .qtip-icon{border-color:#808064}.qtip-cluetip .qtip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.qtip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px #000}.qtip-tipsy .qtip-titlebar{padding:6px 35px 0 10px;background-color:transparent}.qtip-tipsy .qtip-content{padding:6px 10px}.qtip-tipsy .qtip-icon{border-color:#222;text-shadow:none}.qtip-tipsy .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-tipped{border:3px solid #959FA9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#F9F9F9;color:#454545;font-weight:400;font-family:serif}.qtip-tipped .qtip-titlebar{border-bottom-width:0;color:#fff;background:#3A79B8;background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));background-image:-webkit-linear-gradient(top,#3A79B8,#2E629D);background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-ms-linear-gradient(top,#3A79B8,#2E629D);background-image:-o-linear-gradient(top,#3A79B8,#2E629D);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"}.qtip-tipped .qtip-icon{border:2px solid #285589;background:#285589}.qtip-tipped .qtip-icon .ui-icon{background-color:#FBFBFB;color:#555}.qtip-bootstrap{font-size:14px;line-height:20px;color:#333;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.qtip-bootstrap .qtip-titlebar{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.qtip-bootstrap .qtip-titlebar .qtip-close{right:11px;top:45%;border-style:none}.qtip-bootstrap .qtip-content{padding:9px 14px}.qtip-bootstrap .qtip-icon{background:0 0}.qtip-bootstrap .qtip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}#qtip-overlay,#qtip-overlay div{left:0;top:0;width:100%;height:100%}.qtip-bootstrap .qtip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}.qtip:not(.ie9haxors) div.qtip-content,.qtip:not(.ie9haxors) div.qtip-titlebar{filter:none;-ms-filter:none}.qtip .qtip-tip{margin:0 auto;overflow:hidden;z-index:10}.qtip .qtip-tip,x:-o-prefocus{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:0 0;border:0 dashed transparent}.qtip .qtip-tip canvas{top:0;left:0}.qtip .qtip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed}#qtip-overlay div{position:absolute;background-color:#000;opacity:.7;filter:alpha(opacity=70);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"}.qtipmodal-ie6fix{position:absolute!important}
css/menu-editor.css CHANGED
@@ -854,6 +854,8 @@ a#ws-ame-delete-color-preset:hover {
854
position: fixed;
855
left: 0;
856
top: 0;
857
opacity: 0.70;
858
-moz-opacity: 0.70;
859
filter: alpha(opacity=70);
854
position: fixed;
855
left: 0;
856
top: 0;
857
+ right: 0;
858
+ bottom: 0;
859
opacity: 0.70;
860
-moz-opacity: 0.70;
861
filter: alpha(opacity=70);
css/menu-editor.scss CHANGED
@@ -1160,6 +1160,8 @@ $colorFieldRightMargin: 5px;
1160
position: fixed;
1161
left: 0;
1162
top: 0;
1163
opacity: 0.70;
1164
-moz-opacity: 0.70;
1165
filter: alpha(opacity=70);
1160
position: fixed;
1161
left: 0;
1162
top: 0;
1163
+ right: 0;
1164
+ bottom: 0;
1165
opacity: 0.70;
1166
-moz-opacity: 0.70;
1167
filter: alpha(opacity=70);
includes/basic-dependencies.php ADDED
@@ -0,0 +1,19 @@
1
+ <?php
2
+ if ( !defined('AME_ROOT_DIR') ) {
3
+ define('AME_ROOT_DIR', dirname(dirname(__FILE__)));
4
+ }
5
+
6
+ $thisDirectory = dirname(__FILE__);
7
+ require_once $thisDirectory . '/shadow_plugin_framework.php';
8
+ require_once $thisDirectory . '/role-utils.php';
9
+ require_once $thisDirectory . '/ame-utils.php';
10
+ require_once $thisDirectory . '/menu-item.php';
11
+ require_once $thisDirectory . '/menu.php';
12
+ require_once $thisDirectory . '/auto-versioning.php';
13
+ require_once $thisDirectory . '/../ajax-wrapper/AjaxWrapper.php';
14
+ require_once $thisDirectory . '/module.php';
15
+ require_once $thisDirectory . '/persistent-module.php';
16
+
17
+ if ( !class_exists('WPMenuEditor', false) ) {
18
+ require_once $thisDirectory . '/menu-editor-core.php';
19
+ }
includes/menu-editor-core.php CHANGED
@@ -1,24 +1,5 @@
1
<?php
2
3
- //Can't have two different versions of the plugin active at the same time. It would be incredibly buggy.
4
- if (class_exists('WPMenuEditor')){
5
- trigger_error(
6
- 'Another version of Admin Menu Editor is already active. Please deactivate it before activating this one.',
7
- E_USER_ERROR
8
- );
9
- }
10
-
11
- $thisDirectory = dirname(__FILE__);
12
- require $thisDirectory . '/shadow_plugin_framework.php';
13
- require $thisDirectory . '/role-utils.php';
14
- require $thisDirectory . '/ame-utils.php';
15
- require $thisDirectory . '/menu-item.php';
16
- require $thisDirectory . '/menu.php';
17
- require $thisDirectory . '/auto-versioning.php';
18
- require $thisDirectory . '/../ajax-wrapper/AjaxWrapper.php';
19
- require $thisDirectory . '/module.php';
20
- require $thisDirectory . '/persistent-module.php';
21
-
22
class WPMenuEditor extends MenuEd_ShadowPluginFramework {
23
const WPML_CONTEXT = 'admin-menu-editor menu texts';
24
@@ -115,6 +96,11 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
115
*/
116
private $current_tab = '';
117
118
/**
119
* @var array List of capabilities that are used in the default admin menu. Used to detect meta capabilities.
120
*/
@@ -198,7 +184,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
198
self::$admin_heading_tag = version_compare($GLOBALS['wp_version'], '4.3', '<') ? 'h2' : 'h1';
199
200
$this->settings_link = (is_network_admin() ? 'settings.php' : 'options-general.php') . '?page=menu_editor';
201
-
202
$this->magic_hooks = true;
203
//Run our hooks last (almost). Priority is less than PHP_INT_MAX mostly for defensive programming purposes.
204
//Old PHP versions have known bugs related to large array keys, and WP might have undiscovered edge cases.
@@ -255,7 +241,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
255
'admin.php?page=WPCW_showPage_UserProgess' => true,
256
'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
257
);
258
-
259
//AJAXify screen options
260
add_action('wp_ajax_ws_ame_save_screen_options', array($this,'ajax_save_screen_options'));
261
@@ -320,7 +306,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
320
add_action('admin_menu_editor-display_footer', array($this, 'display_settings_page_footer'));
321
322
}
323
-
324
function init_finish() {
325
parent::init_finish();
326
$should_save_options = false;
@@ -375,7 +361,8 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
375
/** @noinspection PhpIncludeInspection */
376
include ($module['path']);
377
if ( !empty($module['className']) ) {
378
- new $module['className']($this);
379
}
380
}
381
@@ -390,9 +377,16 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
390
$this->tabs['settings'] = 'Settings';
391
}
392
393
/**
394
* Import settings from a different version of the plugin.
395
- *
396
* @return bool True if settings were imported successfully, False otherwise
397
*/
398
function import_settings(){
@@ -431,9 +425,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
431
if ( $reset_requested && $this->current_user_can_edit_menu() ){
432
$this->set_custom_menu(null);
433
}
434
-
435
//The menu editor is only visible to users with the manage_options privilege.
436
- //Or, if the plugin is installed in mu-plugins, only to the site administrator(s).
437
if ( $this->current_user_can_edit_menu() ){
438
$this->log_security_note('Current user can edit the admin menu.');
439
@@ -450,9 +444,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
450
$page = add_submenu_page(
451
$parent_slug,
452
apply_filters('admin_menu_editor-self_page_title', 'Menu Editor') . $tab_title,
453
- apply_filters('admin_menu_editor-self_menu_title', 'Menu Editor'),
454
apply_filters('admin_menu_editor-capability', 'manage_options'),
455
- 'menu_editor',
456
array($this, 'page_menu_editor')
457
);
458
//Output our JS & CSS on that page only
@@ -1216,6 +1210,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1216
*
1217
* @param array|null $custom_menu
1218
* @param string|null $config_id Supported values: 'network-admin', 'global' or 'site'
1219
*/
1220
function set_custom_menu($custom_menu, $config_id = null) {
1221
if ( $config_id === null ) {
@@ -1343,7 +1338,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1343
1344
/**
1345
* Determine if the current user may use the menu editor.
1346
- *
1347
* @return bool
1348
*/
1349
public function current_user_can_edit_menu(){
@@ -1393,15 +1388,15 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1393
$this->save_options();
1394
}
1395
}
1396
-
1397
/**
1398
* Apply the custom page title, if any.
1399
*
1400
* This is a callback for the "admin_title" filter. It will change the browser window/tab
1401
* title (i.e. <title>), but not the title displayed on the admin page itself.
1402
- *
1403
* @param string $admin_title The current admin title (full).
1404
- * @param string $title The current page title.
1405
* @return string New admin title.
1406
*/
1407
function hook_admin_title($admin_title, $title){
@@ -1745,7 +1740,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1745
1746
/**
1747
* Generate WP-compatible $menu and $submenu arrays from a custom menu tree.
1748
- *
1749
* Side-effects: This function executes several filters that may modify global state.
1750
* Specifically, IFrame-handling callbacks in 'extras.php' will add add new hooks
1751
* and other menu-related structures.
@@ -1764,7 +1759,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1764
$new_menu = array();
1765
$new_submenu = array();
1766
$this->title_lookups = array();
1767
-
1768
//Prepare the top menu
1769
$first_nonseparator_found = false;
1770
foreach ($tree as $topmenu){
@@ -1782,7 +1777,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
1782
if ( empty($topmenu['separator']) ) {
1783
$this->title_lookups[$topmenu['file']] = !empty($topmenu['page_title']) ? $topmenu['page_title'] : $topmenu['menu_title'];
1784
}
1785
-
1786
//Prepare the submenu of this menu
1787
$new_items = array();
1788
if( !empty($topmenu['items']) ){
@@ -2199,7 +2194,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2199
$item['access_level'] = $capability;
2200
return $item;
2201
}
2202
-
2203
/**
2204
* Output the menu editor page
2205
*
@@ -2865,15 +2860,15 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2865
/**
2866
* Create a virtual 'super_admin' capability that only super admins have.
2867
* This function accomplishes that by by filtering 'user_has_cap' calls.
2868
- *
2869
* @param array $allcaps All capabilities belonging to the current user, cap => true/false.
2870
* @param array $required_caps The required capabilities.
2871
* @param array $args The capability passed to current_user_can, the current user's ID, and other args.
2872
* @return array Filtered version of $allcaps
2873
*/
2874
function hook_user_has_cap($allcaps, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
2875
- //Be careful not to overwrite a super_admin cap added by other plugins
2876
- //For example, Advanced Access Manager also adds this capability.
2877
if ( is_array($allcaps) && !isset($allcaps['super_admin']) ){
2878
$user_id = intval($args[1]);
2879
if ( $user_id != 0 ) {
@@ -2885,19 +2880,19 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2885
2886
/**
2887
* AJAX callback for saving screen options (whether to show or to hide advanced menu options).
2888
- *
2889
- * Handles the 'ws_ame_save_screen_options' action. The new option value
2890
* is read from $_POST['hide_advanced_settings'].
2891
- *
2892
* @return void
2893
*/
2894
function ajax_save_screen_options(){
2895
if (!$this->current_user_can_edit_menu() || !check_ajax_referer('ws_ame_save_screen_options', false, false)){
2896
die( $this->json_encode( array(
2897
- 'error' => "You're not allowed to do that!"
2898
)));
2899
}
2900
-
2901
$this->options['hide_advanced_settings'] = !empty($this->post['hide_advanced_settings']);
2902
$this->options['show_extra_icons'] = !empty($this->post['show_extra_icons']);
2903
$this->save_options();
@@ -3362,7 +3357,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
3362
3363
//Only display the notice on the Menu Editor (Pro) page.
3364
$display_notice = $display_notice && isset($this->get['page']) && ($this->get['page'] == 'menu_editor');
3365
-
3366
//Let the user override this completely (useful for client sites).
3367
if ( $display_notice && file_exists(dirname($this->plugin_file) . '/never-display-surveys.txt') ) {
3368
$display_notice = false;
@@ -3497,6 +3492,18 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
3497
$this->save_options();
3498
}
3499
3500
/**
3501
* Log a security-related message.
3502
*
@@ -4236,27 +4243,36 @@ class ameMenuTemplateBuilder {
4236
$this->templates = array();
4237
$this->blacklist = $blacklist;
4238
4239
- //At this point, the menu might not be sorted yet, especially if other plugins have made changes to it.
4240
- //We need to know the relative order of menus to insert new items in the right place.
4241
- ksort($menu, SORT_NUMERIC);
4242
4243
- foreach($menu as $pos => $item){
4244
- $this->addItem($item, $pos);
4245
}
4246
4247
- foreach($submenu as $parent => $items){
4248
- //Skip sub-menus attached to non-existent parents. This should theoretically never happen,
4249
- //but a buggy plugin can cause such a situation.
4250
- if ( !isset($this->parentNames[$parent]) ) {
4251
- continue;
4252
- }
4253
4254
- ksort($items, SORT_NUMERIC);
4255
- $this->previousItemId = '';
4256
- $this->wasPreviousItemSeparated = false;
4257
4258
- foreach($items as $pos => $item) {
4259
- $this->addItem($item, $pos, $parent);
4260
}
4261
}
4262
1
<?php
2
3
class WPMenuEditor extends MenuEd_ShadowPluginFramework {
4
const WPML_CONTEXT = 'admin-menu-editor menu texts';
5
96
*/
97
private $current_tab = '';
98
99
+ /**
100
+ * @var ameModule[] List of modules that were loaded for the current request.
101
+ */
102
+ private $loaded_modules = array();
103
+
104
/**
105
* @var array List of capabilities that are used in the default admin menu. Used to detect meta capabilities.
106
*/
184
self::$admin_heading_tag = version_compare($GLOBALS['wp_version'], '4.3', '<') ? 'h2' : 'h1';
185
186
$this->settings_link = (is_network_admin() ? 'settings.php' : 'options-general.php') . '?page=menu_editor';
187
+
188
$this->magic_hooks = true;
189
//Run our hooks last (almost). Priority is less than PHP_INT_MAX mostly for defensive programming purposes.
190
//Old PHP versions have known bugs related to large array keys, and WP might have undiscovered edge cases.
241
'admin.php?page=WPCW_showPage_UserProgess' => true,
242
'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
243
);
244
+
245
//AJAXify screen options
246
add_action('wp_ajax_ws_ame_save_screen_options', array($this,'ajax_save_screen_options'));
247
306
add_action('admin_menu_editor-display_footer', array($this, 'display_settings_page_footer'));
307
308
}
309
+
310
function init_finish() {
311
parent::init_finish();
312
$should_save_options = false;
361
/** @noinspection PhpIncludeInspection */
362
include ($module['path']);
363
if ( !empty($module['className']) ) {
364
+ $instance = new $module['className']($this);
365
+ $this->loaded_modules[] = $instance;
366
}
367
}
368
377
$this->tabs['settings'] = 'Settings';
378
}
379
380
+ /**
381
+ * @return ameModule[]
382
+ */
383
+ public function get_loaded_modules() {
384
+ return $this->loaded_modules;
385
+ }
386
+
387
/**
388
* Import settings from a different version of the plugin.
389
+ *
390
* @return bool True if settings were imported successfully, False otherwise
391
*/
392
function import_settings(){
425
if ( $reset_requested && $this->current_user_can_edit_menu() ){
426
$this->set_custom_menu(null);
427
}
428
+
429
//The menu editor is only visible to users with the manage_options privilege.
430
+ //Or, if the plugin is installed in mu-plugins, only to the site administrator(s).
431
if ( $this->current_user_can_edit_menu() ){
432
$this->log_security_note('Current user can edit the admin menu.');
433
444
$page = add_submenu_page(
445
$parent_slug,
446
apply_filters('admin_menu_editor-self_page_title', 'Menu Editor') . $tab_title,
447
+ apply_filters('admin_menu_editor-self_menu_title', 'Menu Editor'),
448
apply_filters('admin_menu_editor-capability', 'manage_options'),
449
+ 'menu_editor',
450
array($this, 'page_menu_editor')
451
);
452
//Output our JS & CSS on that page only
1210
*
1211
* @param array|null $custom_menu
1212
* @param string|null $config_id Supported values: 'network-admin', 'global' or 'site'
1213
+ * @throws InvalidMenuException
1214
*/
1215
function set_custom_menu($custom_menu, $config_id = null) {
1216
if ( $config_id === null ) {
1338
1339
/**
1340
* Determine if the current user may use the menu editor.
1341
+ *
1342
* @return bool
1343
*/
1344
public function current_user_can_edit_menu(){
1388
$this->save_options();
1389
}
1390
}
1391
+
1392
/**
1393
* Apply the custom page title, if any.
1394
*
1395
* This is a callback for the "admin_title" filter. It will change the browser window/tab
1396
* title (i.e. <title>), but not the title displayed on the admin page itself.
1397
+ *
1398
* @param string $admin_title The current admin title (full).
1399
+ * @param string $title The current page title.
1400
* @return string New admin title.
1401
*/
1402
function hook_admin_title($admin_title, $title){
1740
1741
/**
1742
* Generate WP-compatible $menu and $submenu arrays from a custom menu tree.
1743
+ *
1744
* Side-effects: This function executes several filters that may modify global state.
1745
* Specifically, IFrame-handling callbacks in 'extras.php' will add add new hooks
1746
* and other menu-related structures.
1759
$new_menu = array();
1760
$new_submenu = array();
1761
$this->title_lookups = array();
1762
+
1763
//Prepare the top menu
1764
$first_nonseparator_found = false;
1765
foreach ($tree as $topmenu){
1777
if ( empty($topmenu['separator']) ) {
1778
$this->title_lookups[$topmenu['file']] = !empty($topmenu['page_title']) ? $topmenu['page_title'] : $topmenu['menu_title'];
1779
}
1780
+
1781
//Prepare the submenu of this menu
1782
$new_items = array();
1783
if( !empty($topmenu['items']) ){
2194
$item['access_level'] = $capability;
2195
return $item;
2196
}
2197
+
2198
/**
2199
* Output the menu editor page
2200
*
2860
/**
2861
* Create a virtual 'super_admin' capability that only super admins have.
2862
* This function accomplishes that by by filtering 'user_has_cap' calls.
2863
+ *
2864
* @param array $allcaps All capabilities belonging to the current user, cap => true/false.
2865
* @param array $required_caps The required capabilities.
2866
* @param array $args The capability passed to current_user_can, the current user's ID, and other args.
2867
* @return array Filtered version of $allcaps
2868
*/
2869
function hook_user_has_cap($allcaps, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
2870
+ //Be careful not to overwrite a super_admin cap added by other plugins
2871
+ //For example, Advanced Access Manager also adds this capability.
2872
if ( is_array($allcaps) && !isset($allcaps['super_admin']) ){
2873
$user_id = intval($args[1]);
2874
if ( $user_id != 0 ) {
2880
2881
/**
2882
* AJAX callback for saving screen options (whether to show or to hide advanced menu options).
2883
+ *
2884
+ * Handles the 'ws_ame_save_screen_options' action. The new option value
2885
* is read from $_POST['hide_advanced_settings'].
2886
+ *
2887
* @return void
2888
*/
2889
function ajax_save_screen_options(){
2890
if (!$this->current_user_can_edit_menu() || !check_ajax_referer('ws_ame_save_screen_options', false, false)){
2891
die( $this->json_encode( array(
2892
+ 'error' => "You're not allowed to do that!"
2893
)));
2894
}
2895
+
2896
$this->options['hide_advanced_settings'] = !empty($this->post['hide_advanced_settings']);
2897
$this->options['show_extra_icons'] = !empty($this->post['show_extra_icons']);
2898
$this->save_options();
3357
3358
//Only display the notice on the Menu Editor (Pro) page.
3359
$display_notice = $display_notice && isset($this->get['page']) && ($this->get['page'] == 'menu_editor');
3360
+
3361
//Let the user override this completely (useful for client sites).
3362
if ( $display_notice && file_exists(dirname($this->plugin_file) . '/never-display-surveys.txt') ) {
3363
$display_notice = false;
3492
$this->save_options();
3493
}
3494
3495
+ /**
3496
+ * Update multiple plugin configuration values. Saves immediately.
3497
+ *
3498
+ * @param array $options An dictionary of key => value pairs.
3499
+ */
3500
+ public function set_many_plugin_options($options) {
3501
+ foreach($options as $key => $value) {
3502
+ $this->options[$key] = $value;
3503
+ }
3504
+ $this->save_options();
3505
+ }
3506
+
3507
/**
3508
* Log a security-related message.
3509
*
4243
$this->templates = array();
4244
$this->blacklist = $blacklist;
4245
4246
+ if ( !empty($menu) ) {
4247
+ //At this point, the menu might not be sorted yet, especially if other plugins have made changes to it.
4248
+ //We need to know the relative order of menus to insert new items in the right place.
4249
+ ksort($menu, SORT_NUMERIC);
4250
4251
+ foreach($menu as $pos => $item){
4252
+ $this->addItem($item, $pos);
4253
+ }
4254
}
4255
4256
+ if ( !empty($submenu) ) {
4257
+ foreach($submenu as $parent => $items){
4258
+ //Skip NULL's and empty arrays.
4259
+ if ( empty($items) ) {
4260
+ continue;
4261
+ }
4262
4263
+ //Skip sub-menus attached to non-existent parents. This should theoretically never happen,
4264
+ //but a buggy plugin can cause such a situation.
4265
+ if ( !isset($this->parentNames[$parent]) ) {
4266
+ continue;
4267
+ }
4268
4269
+ ksort($items, SORT_NUMERIC);
4270
+ $this->previousItemId = '';
4271
+ $this->wasPreviousItemSeparated = false;
4272
+
4273
+ foreach($items as $pos => $item) {
4274
+ $this->addItem($item, $pos, $parent);
4275
+ }
4276
}
4277
}
4278
includes/menu.php CHANGED
@@ -49,6 +49,12 @@ abstract class ameMenu {
49
if ( ($compared === 0) && isset($arr['format']['is_normalized']) ) {
50
$is_normalized = $arr['format']['is_normalized'];
51
}
52
} else {
53
return self::load_menu_40($arr);
54
}
@@ -169,6 +175,7 @@ abstract class ameMenu {
169
* @static
170
* @param array $arr
171
* @return array
172
*/
173
private static function load_menu_40($arr) {
174
//This is *very* basic and might need to be improved.
@@ -176,7 +183,7 @@ abstract class ameMenu {
176
return self::load_array($menu, true);
177
}
178
179
- private static function add_format_header($menu) {
180
if ( !isset($menu['format']) || !is_array($menu['format']) ) {
181
$menu['format'] = array();
182
}
49
if ( ($compared === 0) && isset($arr['format']['is_normalized']) ) {
50
$is_normalized = $arr['format']['is_normalized'];
51
}
52
+ } else if ( isset($arr['format'], $arr['format']['name']) ) {
53
+ //This is not an admin menu configuration. It's something else with a "format" header.
54
+ throw new InvalidMenuException(sprintf(
55
+ 'Unknown menu configuration format: "%s".',
56
+ esc_html($arr['format']['name'])
57
+ ));
58
} else {
59
return self::load_menu_40($arr);
60
}
175
* @static
176
* @param array $arr
177
* @return array
178
+ * @throws InvalidMenuException
179
*/
180
private static function load_menu_40($arr) {
181
//This is *very* basic and might need to be improved.
183
return self::load_array($menu, true);
184
}
185
186
+ public static function add_format_header($menu) {
187
if ( !isset($menu['format']) || !is_array($menu['format']) ) {
188
$menu['format'] = array();
189
}
includes/module.php CHANGED
@@ -18,6 +18,8 @@ abstract class ameModule {
18
$this->menuEditor = $menuEditor;
19
20
if ( class_exists('ReflectionClass', false) ) {
21
$reflector = new ReflectionClass(get_class($this));
22
$this->moduleDir = dirname($reflector->getFileName());
23
$this->moduleId = basename($this->moduleDir);
@@ -147,4 +149,12 @@ abstract class ameModule {
147
WPMenuEditor::atomic_update_site_option($name, $value);
148
}
149
}
150
}
18
$this->menuEditor = $menuEditor;
19
20
if ( class_exists('ReflectionClass', false) ) {
21
+ //This should never throw an exception since the current class must exist for this constructor to be run.
22
+ /** @noinspection PhpUnhandledExceptionInspection */
23
$reflector = new ReflectionClass(get_class($this));
24
$this->moduleDir = dirname($reflector->getFileName());
25
$this->moduleId = basename($this->moduleDir);
149
WPMenuEditor::atomic_update_site_option($name, $value);
150
}
151
}
152
+
153
+ public function getModuleId() {
154
+ return $this->moduleId;
155
+ }
156
+
157
+ public function getTabTitle() {
158
+ return $this->tabTitle;
159
+ }
160
}
includes/persistent-module.php CHANGED
@@ -47,6 +47,11 @@ abstract class amePersistentModule extends ameModule {
47
$this->setScopedOption($this->optionName, $settings);
48
}
49
50
protected function getTemplateVariables($templateName) {
51
$variables = parent::getTemplateVariables($templateName);
52
if ( $templateName === $this->moduleId ) {
47
$this->setScopedOption($this->optionName, $settings);
48
}
49
50
+ public function mergeSettingsWith($newSettings) {
51
+ $this->settings = array_merge($this->loadSettings(), $newSettings);
52
+ return $this->settings;
53
+ }
54
+
55
protected function getTemplateVariables($templateName) {
56
$variables = parent::getTemplateVariables($templateName);
57
if ( $templateName === $this->moduleId ) {
includes/reflection-callable.php CHANGED
@@ -16,6 +16,7 @@ class AmeReflectionCallable {
16
* AmeReflectionCallable constructor.
17
*
18
* @param callable $callback
19
*/
20
public function __construct($callback) {
21
$this->callback = $callback;
@@ -25,6 +26,7 @@ class AmeReflectionCallable {
25
/**
26
* @param callable $callback
27
* @return ReflectionFunctionAbstract
28
*/
29
private function getReflectionFunction($callback) {
30
//Closure or a simple function name.
16
* AmeReflectionCallable constructor.
17
*
18
* @param callable $callback
19
+ * @throws ReflectionException
20
*/
21
public function __construct($callback) {
22
$this->callback = $callback;
26
/**
27
* @param callable $callback
28
* @return ReflectionFunctionAbstract
29
+ * @throws ReflectionException
30
*/
31
private function getReflectionFunction($callback) {
32
//Closure or a simple function name.
includes/role-utils.php CHANGED
@@ -1,11 +1,12 @@
1
<?php
2
class ameRoleUtils {
3
/**
4
- * Retrieve a list of all known, non-meta capabilities of all roles.
5
- *
6
- * @return array Associative array with capability names as keys
7
- */
8
- public static function get_all_capabilities(){
9
//Cache the results.
10
static $capabilities = null;
11
if ( isset($capabilities) ) {
@@ -23,15 +24,17 @@ class ameRoleUtils {
23
}
24
25
//Add multisite-specific capabilities (not listed in any roles in WP 3.0)
26
- $multisite_caps = array(
27
- 'manage_sites' => 1,
28
- 'manage_network' => 1,
29
- 'manage_network_users' => 1,
30
- 'manage_network_themes' => 1,
31
- 'manage_network_options' => 1,
32
- 'manage_network_plugins' => 1,
33
- );
34
- $capabilities = array_merge($capabilities, $multisite_caps);
35
36
return $capabilities;
37
}
1
<?php
2
class ameRoleUtils {
3
/**
4
+ * Retrieve a list of all known, non-meta capabilities of all roles.
5
+ *
6
+ * @param bool $include_multisite_caps
7
+ * @return array Associative array with capability names as keys
8
+ */
9
+ public static function get_all_capabilities($include_multisite_caps = true){
10
//Cache the results.
11
static $capabilities = null;
12
if ( isset($capabilities) ) {
24
}
25
26
//Add multisite-specific capabilities (not listed in any roles in WP 3.0)
27
+ if ($include_multisite_caps) {
28
+ $multisite_caps = array(
29
+ 'manage_sites' => 1,
30
+ 'manage_network' => 1,
31
+ 'manage_network_users' => 1,
32
+ 'manage_network_themes' => 1,
33
+ 'manage_network_options' => 1,
34
+ 'manage_network_plugins' => 1,
35
+ );
36
+ $capabilities = array_merge($capabilities, $multisite_caps);
37
+ }
38
39
return $capabilities;
40
}
includes/shadow_plugin_framework.php CHANGED
@@ -306,13 +306,23 @@ class MenuEd_ShadowPluginFramework {
306
* @return bool
307
*/
308
function is_in_wpmu_plugin_dir( $filename = '' ){
309
- if ( !defined('WPMU_PLUGIN_DIR') ) return false;
310
311
if ( empty($filename) ){
312
$filename = $this->plugin_file;
313
}
314
-
315
- return (strpos( realpath($filename), realpath(WPMU_PLUGIN_DIR) ) !== false);
316
}
317
318
/**
306
* @return bool
307
*/
308
function is_in_wpmu_plugin_dir( $filename = '' ){
309
+ if ( !defined('WPMU_PLUGIN_DIR') ) {
310
+ return false;
311
+ }
312
313
if ( empty($filename) ){
314
$filename = $this->plugin_file;
315
}
316
+
317
+ $muPluginDir = realpath(WPMU_PLUGIN_DIR);
318
+ $filename = realpath($filename);
319
+
320
+ //If realpath() fails, just normalize the syntax instead.
321
+ if ( empty($muPluginDir) || empty($filename) ) {
322
+ $muPluginDir = wp_normalize_path($muPluginDir);
323
+ $filename = wp_normalize_path($filename);
324
+ }
325
+ return (strpos( $filename, $muPluginDir ) !== false);
326
}
327
328
/**
js/actor-manager.js CHANGED
@@ -1,9 +1,12 @@
1
/// <reference path="lodash-3.10.d.ts" />
2
/// <reference path="common.d.ts" />
3
var __extends = (this && this.__extends) || (function () {
4
- var extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7
return function (d, b) {
8
extendStatics(d, b);
9
function __() { this.constructor = d; }
@@ -58,6 +61,12 @@ var AmeBaseActor = /** @class */ (function () {
58
AmeBaseActor.prototype.toString = function () {
59
return this.displayName + ' [' + this.id + ']';
60
};
61
return AmeBaseActor;
62
}());
63
var AmeRole = /** @class */ (function (_super) {
@@ -162,6 +171,7 @@ var AmeActorManager = /** @class */ (function () {
162
this.tagMetaCaps[tagMetaCaps[i]] = true;
163
}
164
}
165
AmeActorManager.prototype.actorCanAccess = function (actorId, grantAccess, defaultCapability) {
166
if (defaultCapability === void 0) { defaultCapability = null; }
167
if (grantAccess.hasOwnProperty(actorId)) {
@@ -480,6 +490,9 @@ var AmeActorManager = /** @class */ (function () {
480
AmeActorManager.prototype.getSuggestedCapabilities = function () {
481
return this.suggestedCapabilities;
482
};
483
AmeActorManager._ = wsAmeLodash;
484
return AmeActorManager;
485
}());
1
/// <reference path="lodash-3.10.d.ts" />
2
/// <reference path="common.d.ts" />
3
var __extends = (this && this.__extends) || (function () {
4
+ var extendStatics = function (d, b) {
5
+ extendStatics = Object.setPrototypeOf ||
6
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
7
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
8
+ return extendStatics(d, b);
9
+ }
10
return function (d, b) {
11
extendStatics(d, b);
12
function __() { this.constructor = d; }
61
AmeBaseActor.prototype.toString = function () {
62
return this.displayName + ' [' + this.id + ']';
63
};
64
+ AmeBaseActor.prototype.getId = function () {
65
+ return this.id;
66
+ };
67
+ AmeBaseActor.prototype.getDisplayName = function () {
68
+ return this.displayName;
69
+ };
70
return AmeBaseActor;
71
}());
72
var AmeRole = /** @class */ (function (_super) {
171
this.tagMetaCaps[tagMetaCaps[i]] = true;
172
}
173
}
174
+ // noinspection JSUnusedGlobalSymbols
175
AmeActorManager.prototype.actorCanAccess = function (actorId, grantAccess, defaultCapability) {
176
if (defaultCapability === void 0) { defaultCapability = null; }
177
if (grantAccess.hasOwnProperty(actorId)) {
490
AmeActorManager.prototype.getSuggestedCapabilities = function () {
491
return this.suggestedCapabilities;
492
};
493
+ AmeActorManager.prototype.createUserFromProperties = function (properties) {
494
+ return AmeUser.createFromProperties(properties);
495
+ };
496
AmeActorManager._ = wsAmeLodash;
497
return AmeActorManager;
498
}());
js/actor-manager.ts CHANGED
@@ -12,7 +12,17 @@ interface CapabilityMap {
12
[capabilityName: string] : boolean;
13
}
14
15
- abstract class AmeBaseActor {
16
public id: string;
17
public displayName: string = '[Error: No displayName set]';
18
public capabilities: CapabilityMap;
@@ -20,7 +30,7 @@ abstract class AmeBaseActor {
20
21
groupActors: string[] = [];
22
23
- constructor(id: string, displayName: string, capabilities: CapabilityMap, metaCapabilities: CapabilityMap = {}) {
24
this.id = id;
25
this.displayName = displayName;
26
this.capabilities = capabilities;
@@ -68,6 +78,14 @@ abstract class AmeBaseActor {
68
toString(): string {
69
return this.displayName + ' [' + this.id + ']';
70
}
71
}
72
73
class AmeRole extends AmeBaseActor {
@@ -100,7 +118,7 @@ interface AmeUserPropertyMap {
100
avatar_html?: string;
101
}
102
103
- class AmeUser extends AmeBaseActor {
104
userLogin: string;
105
userId: number = 0;
106
roles: string[];
@@ -175,7 +193,7 @@ interface AmeCapabilitySuggestion {
175
capability: string;
176
}
177
178
- class AmeActorManager {
179
private static _ = wsAmeLodash;
180
181
private roles: {[roleId: string] : AmeRole} = {};
@@ -183,7 +201,7 @@ class AmeActorManager {
183
private grantedCapabilities: AmeGrantedCapabilityMap = {};
184
185
public readonly isMultisite: boolean = false;
186
- private superAdmin: AmeSuperAdmin;
187
private exclusiveSuperAdminCapabilities = {};
188
189
private tagMetaCaps = {};
@@ -233,6 +251,7 @@ class AmeActorManager {
233
}
234
}
235
236
actorCanAccess(
237
actorId: string,
238
grantAccess: {[actorId: string] : boolean},
@@ -619,6 +638,23 @@ class AmeActorManager {
619
public getSuggestedCapabilities(): AmeCapabilitySuggestion[] {
620
return this.suggestedCapabilities;
621
}
622
}
623
624
if (typeof wsAmeActorData !== 'undefined') {
12
[capabilityName: string] : boolean;
13
}
14
15
+ interface IAmeActor {
16
+ getId(): string;
17
+ getDisplayName(): string;
18
+ }
19
+
20
+ interface IAmeUser extends IAmeActor {
21
+ userLogin: string;
22
+ isSuperAdmin: boolean;
23
+ }
24
+
25
+ abstract class AmeBaseActor implements IAmeActor {
26
public id: string;
27
public displayName: string = '[Error: No displayName set]';
28
public capabilities: CapabilityMap;
30
31
groupActors: string[] = [];
32
33
+ protected constructor(id: string, displayName: string, capabilities: CapabilityMap, metaCapabilities: CapabilityMap = {}) {
34
this.id = id;
35
this.displayName = displayName;
36
this.capabilities = capabilities;
78
toString(): string {
79
return this.displayName + ' [' + this.id + ']';
80
}
81
+
82
+ getId(): string {
83
+ return this.id;
84
+ }
85
+
86
+ getDisplayName(): string {
87
+ return this.displayName;
88
+ }
89
}
90
91
class AmeRole extends AmeBaseActor {
118
avatar_html?: string;
119
}
120
121
+ class AmeUser extends AmeBaseActor implements IAmeUser {
122
userLogin: string;
123
userId: number = 0;
124
roles: string[];
193
capability: string;
194
}
195
196
+ class AmeActorManager implements AmeActorManagerInterface {
197
private static _ = wsAmeLodash;
198
199
private roles: {[roleId: string] : AmeRole} = {};
201
private grantedCapabilities: AmeGrantedCapabilityMap = {};
202
203
public readonly isMultisite: boolean = false;
204
+ private readonly superAdmin: AmeSuperAdmin;
205
private exclusiveSuperAdminCapabilities = {};
206
207
private tagMetaCaps = {};
251
}
252
}
253
254
+ // noinspection JSUnusedGlobalSymbols
255
actorCanAccess(
256
actorId: string,
257
grantAccess: {[actorId: string] : boolean},
638
public getSuggestedCapabilities(): AmeCapabilitySuggestion[] {
639
return this.suggestedCapabilities;
640
}
641
+
642
+ createUserFromProperties(properties: AmeUserPropertyMap): IAmeUser {
643
+ return AmeUser.createFromProperties(properties);
644
+ }
645
+ }
646
+
647
+ interface AmeActorManagerInterface {
648
+ getUsers(): AmeDictionary<IAmeUser>;
649
+ getUser(login: string): IAmeUser;
650
+ addUsers(newUsers: IAmeUser[]);
651
+ createUserFromProperties(properties: AmeUserPropertyMap): IAmeUser;
652
+
653
+ getRoles(): AmeDictionary<IAmeActor>;
654
+ getSuperAdmin(): IAmeActor;
655
+
656
+ getActor(actorId): IAmeActor;
657
+ actorExists(actorId: string): boolean;
658
}
659
660
if (typeof wsAmeActorData !== 'undefined') {
js/jquery.qtip.js CHANGED
@@ -1,8 +1,15 @@
1
- /*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-09-10
2
- * http://craigsworks.com/projects/qtip2/
3
- * Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */
4
-
5
- /*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */
6
/*global window: false, jQuery: false, console: false, define: false */
7
8
/* Cache window, document, undefined */
@@ -19,2659 +26,2612 @@
19
}
20
}
21
(function($) {
22
- /* This currently causes issues with Safari 6, so for it's disabled */
23
- //"use strict"; // (Dis)able ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
24
-
25
- // Munge the primitives - Paul Irish tip
26
- var TRUE = true,
27
- FALSE = false,
28
- NULL = null,
29
-
30
- // Side names and other stuff
31
- X = 'x', Y = 'y',
32
- WIDTH = 'width',
33
- HEIGHT = 'height',
34
- TOP = 'top',
35
- LEFT = 'left',
36
- BOTTOM = 'bottom',
37
- RIGHT = 'right',
38
- CENTER = 'center',
39
- FLIP = 'flip',
40
- FLIPINVERT = 'flipinvert',
41
- SHIFT = 'shift',
42
-
43
- // Shortcut vars
44
- QTIP, PLUGINS, MOUSE,
45
- usedIDs = {},
46
- uitooltip = 'ui-tooltip',
47
- widget = 'ui-widget',
48
- disabled = 'ui-state-disabled',
49
- selector = 'div.qtip.'+uitooltip,
50
- defaultClass = uitooltip + '-default',
51
- focusClass = uitooltip + '-focus',
52
- hoverClass = uitooltip + '-hover',
53
- replaceSuffix = '_replacedByqTip',
54
- oldtitle = 'oldtitle',
55
- trackingBound,
56
- redrawContainer;
57
-
58
/*
59
- * redraw() container for width/height calculations
60
- */
61
- redrawContainer = $('<div/>', { id: 'qtip-rcontainer' });
62
- $(function() { redrawContainer.appendTo(document.body); });
63
-
64
-
65
-
66
- // Option object sanitizer
67
- function sanitizeOptions(opts)
68
- {
69
- var invalid = function(a) { return a === NULL || 'object' !== typeof a; },
70
- invalidContent = function(c) { return !$.isFunction(c) && ((!c && !c.attr) || c.length < 1 || ('object' === typeof c && !c.jquery)); };
71
-
72
- if(!opts || 'object' !== typeof opts) { return FALSE; }
73
-
74
- if(invalid(opts.metadata)) {
75
- opts.metadata = { type: opts.metadata };
76
- }
77
-
78
- if('content' in opts) {
79
- if(invalid(opts.content) || opts.content.jquery) {
80
- opts.content = { text: opts.content };
81
- }
82
-
83
- if(invalidContent(opts.content.text || FALSE)) {
84
- opts.content.text = FALSE;
85
- }
86
-
87
- if('title' in opts.content) {
88
- if(invalid(opts.content.title)) {
89
- opts.content.title = { text: opts.content.title };
90
- }
91
-
92
- if(invalidContent(opts.content.title.text || FALSE)) {
93
- opts.content.title.text = FALSE;
94
- }
95
- }
96
- }
97
-
98
- if('position' in opts && invalid(opts.position)) {
99
- opts.position = { my: opts.position, at: opts.position };
100
- }
101
-
102
- if('show' in opts && invalid(opts.show)) {
103
- opts.show = opts.show.jquery ? { target: opts.show } : { event: opts.show };
104
- }
105
-
106
- if('hide' in opts && invalid(opts.hide)) {
107
- opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide };
108
- }
109
-
110
- if('style' in opts && invalid(opts.style)) {
111
- opts.style = { classes: opts.style };
112
- }
113
-
114
- // Sanitize plugin options
115
- $.each(PLUGINS, function() {
116
- if(this.sanitize) { this.sanitize(opts); }
117
- });
118
-
119
- return opts;
120
- }
121
-
122
- /*
123
- * Core plugin implementation
124
- */
125
- function QTip(target, options, id, attr)
126
- {
127
- // Declare this reference
128
- var self = this,
129
- docBody = document.body,
130
- tooltipID = uitooltip + '-' + id,
131
- isPositioning = 0,
132
- isDrawing = 0,
133
- tooltip = $(),
134
- namespace = '.qtip-' + id,
135
- elements, cache;
136
-
137
- // Setup class attributes
138
- self.id = id;
139
- self.rendered = FALSE;
140
- self.destroyed = FALSE;
141
- self.elements = elements = { target: target };
142
- self.timers = { img: {} };
143
- self.options = options;
144
- self.checks = {};
145
- self.plugins = {};
146
- self.cache = cache = {
147
- event: {},
148
- target: $(),
149
- disabled: FALSE,
150
- attr: attr,
151
- onTarget: FALSE,
152
- lastClass: ''
153
- };
154
-
155
- /*
156
- * Private core functions
157
- */
158
- function convertNotation(notation)
159
- {
160
- var i = 0, obj, option = options,
161
-
162
- // Split notation into array
163
- levels = notation.split('.');
164
-
165
- // Loop through
166
- while( option = option[ levels[i++] ] ) {
167
- if(i < levels.length) { obj = option; }
168
- }
169
-
170
- return [obj || options, levels.pop()];
171
- }
172
-
173
- function triggerEvent(type, args, event) {
174
- var callback = $.Event('tooltip'+type);
175
- callback.originalEvent = (event ? $.extend({}, event) : NULL) || cache.event || NULL;
176
- tooltip.trigger(callback, [self].concat(args || []));
177
-
178
- return !callback.isDefaultPrevented();
179
- }
180
-
181
- function setWidget()
182
- {
183
- var on = options.style.widget;
184
-
185
- tooltip.toggleClass('ui-helper-reset '+widget, on).toggleClass(defaultClass, options.style.def && !on);
186
-
187
- if(elements.content) {
188
- elements.content.toggleClass(widget+'-content', on);
189
- }
190
-
191
- if(elements.titlebar) {
192
- elements.titlebar.toggleClass(widget+'-header', on);
193
- }
194
- if(elements.button) {
195
- elements.button.toggleClass(uitooltip+'-icon', !on);
196
- }
197
- }
198
-
199
- function removeTitle(reposition)
200
- {
201
- if(elements.title) {
202
- elements.titlebar.remove();
203
- elements.titlebar = elements.title = elements.button = NULL;
204
-
205
- // Reposition if enabled
206
- if(reposition !== FALSE) { self.reposition(); }
207
- }
208
- }
209
-
210
- function createButton()
211
- {
212
- var button = options.content.title.button,
213
- isString = typeof button === 'string',
214
- close = isString ? button : 'Close tooltip';
215
-
216
- if(elements.button) { elements.button.remove(); }
217
-
218
- // Use custom button if one was supplied by user, else use default
219
- if(button.jquery) {
220
- elements.button = button;
221
- }
222
- else {
223
- elements.button = $('<a />', {
224
- 'class': 'ui-state-default ui-tooltip-close ' + (options.style.widget ? '' : uitooltip+'-icon'),
225
- 'title': close,
226
- 'aria-label': close
227
- })
228
- .prepend(
229
- $('<span />', {
230
- 'class': 'ui-icon ui-icon-close',
231
- 'html': '&times;'
232
- })
233
- );
234
- }
235
-
236
- // Create button and setup attributes
237
- elements.button.appendTo(elements.titlebar)
238
- .attr('role', 'button')
239
- .click(function(event) {
240
- if(!tooltip.hasClass(disabled)) { self.hide(event); }
241
- return FALSE;
242
- });
243
-
244
- // Redraw the tooltip when we're done
245
- self.redraw();
246
- }
247
-
248
- function createTitle()
249
- {
250
- var id = tooltipID+'-title';
251
-
252
- // Destroy previous title element, if present
253
- if(elements.titlebar) { removeTitle(); }
254
-
255
- // Create title bar and title elements
256
- elements.titlebar = $('<div />', {
257
- 'class': uitooltip + '-titlebar ' + (options.style.widget ? 'ui-widget-header' : '')
258
- })
259
- .append(
260
- elements.title = $('<div />', {
261
- 'id': id,
262
- 'class': uitooltip + '-title',
263
- 'aria-atomic': TRUE
264
- })
265
- )
266
- .insertBefore(elements.content)
267
-
268
- // Button-specific events
269
- .delegate('.ui-tooltip-close', 'mousedown keydown mouseup keyup mouseout', function(event) {
270
- $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
271
- })
272
- .delegate('.ui-tooltip-close', 'mouseover mouseout', function(event){
273
- $(this).toggleClass('ui-state-hover', event.type === 'mouseover');
274
- });
275
-
276
- // Create button if enabled
277
- if(options.content.title.button) { createButton(); }
278
-
279
- // Redraw the tooltip dimensions if it's rendered
280
- else if(self.rendered){ self.redraw(); }
281
- }
282
-
283
- function updateButton(button)
284
- {
285
- var elem = elements.button,
286
- title = elements.title;
287
-
288
- // Make sure tooltip is rendered and if not, return
289
- if(!self.rendered) { return FALSE; }
290
-
291
- if(!button) {
292
- elem.remove();
293
- }
294
- else {
295
- if(!title) {
296
- createTitle();
297
- }
298
- createButton();
299
- }
300
- }
301
-
302
- function updateTitle(content, reposition)
303
- {
304
- var elem = elements.title;
305
-
306
- // Make sure tooltip is rendered and if not, return
307
- if(!self.rendered || !content) { return FALSE; }
308
-
309
- // Use function to parse content
310
- if($.isFunction(content)) {
311
- content = content.call(target, cache.event, self);
312
- }
313
-
314
- // Remove title if callback returns false or null/undefined (but not '')
315
- if(content === FALSE || (!content && content !== '')) { return removeTitle(FALSE); }
316
-
317
- // Append new content if its a DOM array and show it if hidden
318
- else if(content.jquery && content.length > 0) {
319
- elem.empty().append(content.css({ display: 'block' }));
320
- }
321
-
322
- // Content is a regular string, insert the new content
323
- else { elem.html(content); }
324
-
325
- // Redraw and reposition
326
- self.redraw();
327
- if(reposition !== FALSE && self.rendered && tooltip[0].offsetWidth > 0) {
328
- self.reposition(cache.event);
329
- }
330
- }
331
-
332
- function updateContent(content, reposition)
333
- {
334
- var elem = elements.content;
335
-
336
- // Make sure tooltip is rendered and content is defined. If not return
337
- if(!self.rendered || !content) { return FALSE; }
338
-
339
- // Use function to parse content
340
- if($.isFunction(content)) {
341
- content = content.call(target, cache.event, self) || '';
342
- }
343
-
344
- // Append new content if its a DOM array and show it if hidden
345
- if(content.jquery && content.length > 0) {
346
- elem.empty().append(content.css({ display: 'block' }));
347
- }
348
-
349
- // Content is a regular string, insert the new content
350
- else { elem.html(content); }
351
-
352
- // Image detection
353
- function detectImages(next) {
354
- var images, srcs = {};
355
-
356
- function imageLoad(image) {
357
- // Clear src from object and any timers and events associated with the image
358
- if(image) {
359
- delete srcs[image.src];
360
- clearTimeout(self.timers.img[image.src]);
361
- $(image).unbind(namespace);
362
- }
363
-
364
- // If queue is empty after image removal, update tooltip and continue the queue
365
- if($.isEmptyObject(srcs)) {
366
- self.redraw();
367
- if(reposition !== FALSE) {
368
- self.reposition(cache.event);
369
- }
370
-
371
- next();
372
- }
373
- }
374
-
375
- // Find all content images without dimensions, and if no images were found, continue
376
- if((images = elem.find('img[src]:not([height]):not([width])')).length === 0) { return imageLoad(); }
377
-
378
- // Apply timer to each image to poll for dimensions
379
- images.each(function(i, elem) {
380
- // Skip if the src is already present
381
- if(srcs[elem.src] !== undefined) { return; }
382
-
383
- // Keep track of how many times we poll for image dimensions.
384
- // If it doesn't return in a reasonable amount of time, it's better
385
- // to display the tooltip, rather than hold up the queue.
386
- var iterations = 0, maxIterations = 3;
387
-
388
- (function timer(){
389
- // When the dimensions are found, remove the image from the queue
390
- if(elem.height || elem.width || (iterations > maxIterations)) { return imageLoad(elem); }
391
-
392
- // Increase iterations and restart timer
393
- iterations += 1;
394
- self.timers.img[elem.src] = setTimeout(timer, 700);
395
- }());
396
-
397
- // Also apply regular load/error event handlers
398
- $(elem).bind('error'+namespace+' load'+namespace, function(){ imageLoad(this); });
399
-
400
- // Store the src and element in our object
401
- srcs[elem.src] = elem;
402
- });
403
- }
404
-
405
- /*
406
- * If we're still rendering... insert into 'fx' queue our image dimension
407
- * checker which will halt the showing of the tooltip until image dimensions
408
- * can be detected properly.
409
- */
410
- if(self.rendered < 0) { tooltip.queue('fx', detectImages); }
411
-
412
- // We're fully rendered, so reset isDrawing flag and proceed without queue delay
413
- else { isDrawing = 0; detectImages($.noop); }
414
-
415
- return self;
416
- }
417
-
418
- function assignEvents()
419
- {
420
- var posOptions = options.position,
421
- targets = {
422
- show: options.show.target,
423
- hide: options.hide.target,
424
- viewport: $(posOptions.viewport),
425
- document: $(document),
426
- body: $(document.body),
427
- window: $(window)
428
- },
429
- events = {
430
- show: $.trim('' + options.show.event).split(' '),
431
- hide: $.trim('' + options.hide.event).split(' ')
432
- },
433
- IE6 = $.browser.msie && parseInt($.browser.version, 10) === 6;
434
-
435
- // Define show event method
436
- function showMethod(event)
437
- {
438
- if(tooltip.hasClass(disabled)) { return FALSE; }
439
-
440
- // Clear hide timers
441
- clearTimeout(self.timers.show);
442
- clearTimeout(self.timers.hide);
443
-
444
- // Start show timer
445
- var callback = function(){ self.toggle(TRUE, event); };
446
- if(options.show.delay > 0) {
447
- self.timers.show = setTimeout(callback, options.show.delay);
448
- }
449
- else{ callback(); }
450
- }
451
-
452
- // Define hide method
453
- function hideMethod(event)
454
- {
455
- if(tooltip.hasClass(disabled) || isPositioning || isDrawing) { return FALSE; }
456
-
457
- // Check if new target was actually the tooltip element
458
- var relatedTarget = $(event.relatedTarget || event.target),
459
- ontoTooltip = relatedTarget.closest(selector)[0] === tooltip[0],
460
- ontoTarget = relatedTarget[0] === targets.show[0];
461
-
462
- // Clear timers and stop animation queue
463
- clearTimeout(self.timers.show);
464
- clearTimeout(self.timers.hide);
465
-
466
- // Prevent hiding if tooltip is fixed and event target is the tooltip. Or if mouse positioning is enabled and cursor momentarily overlaps
467
- if((posOptions.target === 'mouse' && ontoTooltip) || (options.hide.fixed && ((/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)))) {
468
- try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} return;
469
- }
470
-
471
- // If tooltip has displayed, start hide timer
472
- if(options.hide.delay > 0) {
473
- self.timers.hide = setTimeout(function(){ self.hide(event); }, options.hide.delay);
474
- }
475
- else{ self.hide(event); }
476
- }
477
-
478
- // Define inactive method
479
- function inactiveMethod(event)
480
- {
481
- if(tooltip.hasClass(disabled)) { return FALSE; }
482
-
483
- // Clear timer
484
- clearTimeout(self.timers.inactive);
485
- self.timers.inactive = setTimeout(function(){ self.hide(event); }, options.hide.inactive);
486
- }
487
-
488
- function repositionMethod(event) {
489
- if(self.rendered && tooltip[0].offsetWidth > 0) { self.reposition(event); }
490
- }
491
-
492
- // On mouseenter/mouseleave...
493
- tooltip.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
494
- var state = event.type === 'mouseenter';
495
-
496
- // Focus the tooltip on mouseenter (z-index stacking)
497
- if(state) { self.focus(event); }
498
-
499
- // Add hover class
500
- tooltip.toggleClass(hoverClass, state);
501
- });
502
-
503
- // If using mouseout/mouseleave as a hide event...
504
- if(/mouse(out|leave)/i.test(options.hide.event)) {
505
- // Hide tooltips when leaving current window/frame (but not select/option elements)
506
- if(options.hide.leave === 'window') {
507
- targets.window.bind('mouseout'+namespace+' blur'+namespace, function(event) {
508
- if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { self.hide(event); }
509
- });
510
- }
511
- }
512
-
513
- // Enable hide.fixed
514
- if(options.hide.fixed) {
515
- // Add tooltip as a hide target
516
- targets.hide = targets.hide.add(tooltip);
517
-
518
- // Clear hide timer on tooltip hover to prevent it from closing
519
- tooltip.bind('mouseover'+namespace, function() {
520
- if(!tooltip.hasClass(disabled)) { clearTimeout(self.timers.hide); }
521
- });
522
- }
523
-
524
- /*
525
- * Make sure hoverIntent functions properly by using mouseleave to clear show timer if
526
- * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
527
- */
528
- else if(/mouse(over|enter)/i.test(options.show.event)) {
529
- targets.hide.bind('mouseleave'+namespace, function(event) {
530
- clearTimeout(self.timers.show);
531
- });
532
- }
533
-
534
- // Hide tooltip on document mousedown if unfocus events are enabled
535
- if(('' + options.hide.event).indexOf('unfocus') > -1) {
536
- posOptions.container.closest('html').bind('mousedown'+namespace, function(event) {
537
- var elem = $(event.target),
538
- enabled = self.rendered && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0,
539
- isAncestor = elem.parents(selector).filter(tooltip[0]).length > 0;
540
-
541
- if(elem[0] !== target[0] && elem[0] !== tooltip[0] && !isAncestor &&
542
- !target.has(elem[0]).length && !elem.attr('disabled')
543
- ) {
544
- self.hide(event);
545
- }
546
- });
547
- }
548
-
549
- // Check if the tooltip hides when inactive
550
- if('number' === typeof options.hide.inactive) {
551
- // Bind inactive method to target as a custom event
552
- targets.show.bind('qtip-'+id+'-inactive', inactiveMethod);
553
-
554
- // Define events which reset the 'inactive' event handler
555
- $.each(QTIP.inactiveEvents, function(index, type){
556
- targets.hide.add(elements.tooltip).bind(type+namespace+'-inactive', inactiveMethod);
557
- });
558
- }
559
-
560
- // Apply hide events
561
- $.each(events.hide, function(index, type) {
562
- var showIndex = $.inArray(type, events.show),
563
- targetHide = $(targets.hide);
564
-
565
- // Both events and targets are identical, apply events using a toggle
566
- if((showIndex > -1 && targetHide.add(targets.show).length === targetHide.length) || type === 'unfocus')
567
- {
568
- targets.show.bind(type+namespace, function(event) {
569
- if(tooltip[0].offsetWidth > 0) { hideMethod(event); }
570
- else { showMethod(event); }
571
- });
572
-
573
- // Don't bind the event again
574
- delete events.show[ showIndex ];
575
- }
576
-
577
- // Events are not identical, bind normally
578
- else { targets.hide.bind(type+namespace, hideMethod); }
579
- });
580
-
581
- // Apply show events
582
- $.each(events.show, function(index, type) {
583
- targets.show.bind(type+namespace, showMethod);
584
- });
585
-
586
- // Check if the tooltip hides when mouse is moved a certain distance
587
- if('number' === typeof options.hide.distance) {
588
- // Bind mousemove to target to detect distance difference
589
- targets.show.add(tooltip).bind('mousemove'+namespace, function(event) {
590
- var origin = cache.origin || {},
591
- limit = options.hide.distance,
592
- abs = Math.abs;
593
-
594
- // Check if the movement has gone beyond the limit, and hide it if so
595
- if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
596
- self.hide(event);
597
- }
598
- });
599
- }
600
-
601
- // Mouse positioning events
602
- if(posOptions.target === 'mouse') {
603
- // Cache mousemove coords on show targets
604
- targets.show.bind('mousemove'+namespace, function(event) {
605
- MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
606
- });
607
-
608
- // If mouse adjustment is on...
609
- if(posOptions.adjust.mouse) {
610
- // Apply a mouseleave event so we don't get problems with overlapping
611
- if(options.hide.event) {
612
- // Hide when we leave the tooltip and not onto the show target
613
- tooltip.bind('mouseleave'+namespace, function(event) {
614
- if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); }
615
- });
616
-
617
- // Track if we're on the target or not
618
- elements.target.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
619
- cache.onTarget = event.type === 'mouseenter';
620
- });
621
- }
622
-
623
- // Update tooltip position on mousemove
624
- targets.document.bind('mousemove'+namespace, function(event) {
625
- // Update the tooltip position only if the tooltip is visible and adjustment is enabled
626
- if(self.rendered && cache.onTarget && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0) {
627
- self.reposition(event || MOUSE);
628
- }
629
- });
630
- }
631
- }
632
-
633
- // Adjust positions of the tooltip on window resize if enabled
634
- if(posOptions.adjust.resize || targets.viewport.length) {
635
- ($.event.special.resize ? targets.viewport : targets.window).bind('resize'+namespace, repositionMethod);
636
- }
637
-
638
- // Adjust tooltip position on scroll if screen adjustment is enabled
639
- if(targets.viewport.length || (IE6 && tooltip.css('position') === 'fixed')) {
640
- targets.viewport.bind('scroll'+namespace, repositionMethod);
641
- }
642
- }
643
-
644
- function unassignEvents()
645
- {
646
- var targets = [
647
- options.show.target[0],
648
- options.hide.target[0],
649
- self.rendered && elements.tooltip[0],
650
- options.position.container[0],
651
- options.position.viewport[0],
652
- options.position.container.closest('html')[0], // unfocus
653
- window,
654
- document
655
- ];
656
-
657
- // Check if tooltip is rendered
658
- if(self.rendered) {
659
- $([]).pushStack( $.grep(targets, function(i){ return typeof i === 'object'; }) ).unbind(namespace);
660
- }
661
-
662
- // Tooltip isn't yet rendered, remove render event
663
- else { options.show.target.unbind(namespace+'-create'); }
664
- }
665
-
666
- // Setup builtin .set() option checks
667
- self.checks.builtin = {
668
- // Core checks
669
- '^id#x27;: function(obj, o, v) {
670
- var id = v === TRUE ? QTIP.nextid : v,
671
- tooltipID = uitooltip + '-' + id;
672
-
673
- if(id !== FALSE && id.length > 0 && !$('#'+tooltipID).length) {
674
- tooltip[0].id = tooltipID;
675
- elements.content[0].id = tooltipID + '-content';
676
- elements.title[0].id = tooltipID + '-title';
677
- }
678
- },
679
-
680
- // Content checks
681
- '^content.text#x27;: function(obj, o, v){ updateContent(v); },
682
- '^content.title.text#x27;: function(obj, o, v) {
683
- // Remove title if content is null
684
- if(!v) { return removeTitle(); }
685
-
686
- // If title isn't already created, create it now and update
687
- if(!elements.title && v) { createTitle(); }
688
- updateTitle(v);
689
- },
690
- '^content.title.button#x27;: function(obj, o, v){ updateButton(v); },
691
-
692
- // Position checks
693
- '^position.(my|at)#x27;: function(obj, o, v){
694
- // Parse new corner value into Corner objecct
695
- if('string' === typeof v) {
696
- obj[o] = new PLUGINS.Corner(v);
697
- }
698
- },
699
- '^position.container#x27;: function(obj, o, v){
700
- if(self.rendered) { tooltip.appendTo(v); }
701
- },
702
-
703
- // Show checks
704
- '^show.ready#x27;: function() {
705
- if(!self.rendered) { self.render(1); }
706
- else { self.toggle(TRUE); }
707
- },
708
-
709
- // Style checks
710
- '^style.classes#x27;: function(obj, o, v) {
711
- tooltip.attr('class', uitooltip + ' qtip ' + v);
712
- },
713
- '^style.widget|content.title': setWidget,
714
-
715
- // Events check
716
- '^events.(render|show|move|hide|focus|blur)#x27;: function(obj, o, v) {
717
- tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
718
- },
719
-
720
- // Properties which require event reassignment
721
- '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
722
- var posOptions = options.position;
723
-
724
- // Set tracking flag
725
- tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
726
-
727
- // Reassign events
728
- unassignEvents(); assignEvents();
729
- }
730
- };
731
-
732
- /*
733
- * Public API methods
734
- */
735
- $.extend(self, {
736
- render: function(show)
737
- {
738
- if(self.rendered) { return self; } // If tooltip has already been rendered, exit
739
-
740
- var text = options.content.text,
741
- title = options.content.title.text,
742
- posOptions = options.position;
743
-
744
- // Add ARIA attributes to target
745
- $.attr(target[0], 'aria-describedby', tooltipID);
746
-
747
- // Create tooltip element
748
- tooltip = elements.tooltip = $('<div/>', {
749
- 'id': tooltipID,
750
- 'class': uitooltip + ' qtip ' + defaultClass + ' ' + options.style.classes + ' '+ uitooltip + '-pos-' + options.position.my.abbrev(),
751
- 'width': options.style.width || '',
752
- 'height': options.style.height || '',
753
- 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
754
-
755
- /* ARIA specific attributes */
756
- 'role': 'alert',
757
- 'aria-live': 'polite',
758
- 'aria-atomic': FALSE,
759
- 'aria-describedby': tooltipID + '-content',
760
- 'aria-hidden': TRUE
761
- })
762
- .toggleClass(disabled, cache.disabled)
763
- .data('qtip', self)
764
- .appendTo(options.position.container)
765
- .append(
766
- // Create content element
767
- elements.content = $('<div />', {
768
- 'class': uitooltip + '-content',
769
- 'id': tooltipID + '-content',
770
- 'aria-atomic': TRUE
771
- })
772
- );
773
-
774
- // Set rendered flag and prevent redundant redraw/reposition calls for now
775
- self.rendered = -1;
776
- isDrawing = 1; isPositioning = 1;
777
-
778
- // Create title...
779
- if(title) {
780
- createTitle();
781
-
782
- // Update title only if its not a callback (called in toggle if so)
783
- if(!$.isFunction(title)) { updateTitle(title, FALSE); }
784
- }
785
-
786
- // Set proper rendered flag and update content if not a callback function (called in toggle)
787
- if(!$.isFunction(text)) { updateContent(text, FALSE); }
788
- self.rendered = TRUE;
789
-
790
- // Setup widget classes
791
- setWidget();
792
-
793
- // Assign passed event callbacks (before plugins!)
794
- $.each(options.events, function(name, callback) {
795
- if($.isFunction(callback)) {
796
- tooltip.bind(name === 'toggle' ? 'tooltipshow tooltiphide' : 'tooltip'+name, callback);
797
- }
798
- });
799
-
800
- // Initialize 'render' plugins
801
- $.each(PLUGINS, function() {
802
- if(this.initialize === 'render') { this(self); }
803
- });
804
-
805
- // Assign events
806
- assignEvents();
807
-
808
- /* Queue this part of the render process in our fx queue so we can
809
- * load images before the tooltip renders fully.
810