|
1
|
|
|
/** |
|
2
|
|
|
* SMFtooltip, Basic JQuery function to provide styled tooltips |
|
3
|
|
|
* |
|
4
|
|
|
* - will use the hoverintent plugin if available |
|
5
|
|
|
* - shows the tooltip in a div with the class defined in tooltipClass |
|
6
|
|
|
* - moves all selector titles to a hidden div and removes the title attribute to |
|
7
|
|
|
* prevent any default browser actions |
|
8
|
|
|
* - attempts to keep the tooltip on screen |
|
9
|
|
|
* |
|
10
|
|
|
* Simple Machines Forum (SMF) |
|
11
|
|
|
* |
|
12
|
|
|
* @package SMF |
|
13
|
|
|
* @author Simple Machines http://www.simplemachines.org |
|
14
|
|
|
* @copyright 2017 Simple Machines and individual contributors |
|
15
|
|
|
* @license http://www.simplemachines.org/about/smf/license.php BSD |
|
16
|
|
|
* |
|
17
|
|
|
* @version 2.1 Beta 3 |
|
18
|
|
|
* |
|
19
|
|
|
*/ |
|
20
|
|
|
|
|
21
|
|
|
(function($) { |
|
22
|
|
|
$.fn.SMFtooltip = function(oInstanceSettings) { |
|
23
|
|
|
$.fn.SMFtooltip.oDefaultsSettings = { |
|
24
|
|
|
followMouse: 1, |
|
25
|
|
|
hoverIntent: {sensitivity: 10, interval: 300, timeout: 50}, |
|
26
|
|
|
positionTop: 12, |
|
27
|
|
|
positionLeft: 12, |
|
28
|
|
|
tooltipID: 'smf_tooltip', // ID used on the outer div |
|
29
|
|
|
tooltipTextID: 'smf_tooltipText', // as above but on the inner div holding the text |
|
30
|
|
|
tooltipClass: 'tooltip', // The class applied to the outer div (that displays on hover), use this in your css |
|
31
|
|
|
tooltipSwapClass: 'smf_swaptip', // a class only used internally, change only if you have a conflict |
|
32
|
|
|
tooltipContent: 'html' // display captured title text as html or text |
|
33
|
|
|
}; |
|
34
|
|
|
|
|
35
|
|
|
// account for any user options |
|
36
|
|
|
var oSettings = $.extend({}, $.fn.SMFtooltip.oDefaultsSettings , oInstanceSettings || {}); |
|
37
|
|
|
|
|
38
|
|
|
// move passed selector titles to a hidden span, then remove the selector title to prevent any default browser actions |
|
39
|
|
|
$(this).each(function() |
|
40
|
|
|
{ |
|
41
|
|
|
var sTitle = $('<span class="' + oSettings.tooltipSwapClass + '">' + htmlspecialchars(this.title) + '</span>').hide(); |
|
42
|
|
|
$(this).append(sTitle).attr('title', ''); |
|
43
|
|
|
}); |
|
44
|
|
|
|
|
45
|
|
|
// determine where we are going to place the tooltip, while trying to keep it on screen |
|
46
|
|
|
var positionTooltip = function(event) |
|
47
|
|
|
{ |
|
48
|
|
|
var iPosx = 0; |
|
49
|
|
|
var iPosy = 0; |
|
50
|
|
|
|
|
51
|
|
|
if (!event) |
|
52
|
|
|
var event = window.event; |
|
53
|
|
|
|
|
54
|
|
|
if (event.pageX || event.pageY) |
|
55
|
|
|
{ |
|
56
|
|
|
iPosx = event.pageX; |
|
57
|
|
|
iPosy = event.pageY; |
|
58
|
|
|
} |
|
59
|
|
|
else if (event.clientX || event.clientY) |
|
60
|
|
|
{ |
|
61
|
|
|
iPosx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; |
|
62
|
|
|
iPosy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
// Position of the tooltip top left corner and its size |
|
66
|
|
|
var oPosition = { |
|
67
|
|
|
x: iPosx + oSettings.positionLeft, |
|
68
|
|
|
y: iPosy + oSettings.positionTop, |
|
69
|
|
|
w: $('#' + oSettings.tooltipID).width(), |
|
70
|
|
|
h: $('#' + oSettings.tooltipID).height() |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
// Display limits and window scroll postion |
|
74
|
|
|
var oLimits = { |
|
75
|
|
|
x: $(window).scrollLeft(), |
|
76
|
|
|
y: $(window).scrollTop(), |
|
77
|
|
|
w: $(window).width() - 24, |
|
78
|
|
|
h: $(window).height() - 24 |
|
79
|
|
|
}; |
|
80
|
|
|
|
|
81
|
|
|
// don't go off screen with our tooltop |
|
82
|
|
|
if ((oPosition.y + oPosition.h > oLimits.y + oLimits.h) && (oPosition.x + oPosition.w > oLimits.x + oLimits.w)) |
|
83
|
|
|
{ |
|
84
|
|
|
oPosition.x = (oPosition.x - oPosition.w) - 45; |
|
85
|
|
|
oPosition.y = (oPosition.y - oPosition.h) - 45; |
|
86
|
|
|
} |
|
87
|
|
|
else if ((oPosition.x + oPosition.w) > (oLimits.x + oLimits.w)) |
|
88
|
|
|
{ |
|
89
|
|
|
oPosition.x = oPosition.x - (((oPosition.x + oPosition.w) - (oLimits.x + oLimits.w)) + 24); |
|
90
|
|
|
} |
|
91
|
|
|
else if (oPosition.y + oPosition.h > oLimits.y + oLimits.h) |
|
92
|
|
|
{ |
|
93
|
|
|
oPosition.y = oPosition.y - (((oPosition.y + oPosition.h) - (oLimits.y + oLimits.h)) + 24); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
// finally set the position we determined |
|
97
|
|
|
$('#' + oSettings.tooltipID).css({'left': oPosition.x + 'px', 'top': oPosition.y + 'px'}); |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
// used to show a tooltip |
|
101
|
|
|
var showTooltip = function(){ |
|
102
|
|
|
$('#' + oSettings.tooltipID + ' #' + oSettings.tooltipTextID).show(); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
// used to hide a tooltip |
|
106
|
|
|
var hideTooltip = function(valueOfThis){ |
|
|
|
|
|
|
107
|
|
|
$('#' + oSettings.tooltipID).fadeOut('slow').trigger("unload").remove(); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
// used to keep html encoded |
|
111
|
|
|
function htmlspecialchars(string) |
|
112
|
|
|
{ |
|
113
|
|
|
return $('<span>').text(string).html(); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
// for all of the elements that match the selector on the page, lets set up some actions |
|
117
|
|
|
return this.each(function(index) |
|
|
|
|
|
|
118
|
|
|
{ |
|
119
|
|
|
// if we find hoverIntent use it |
|
120
|
|
|
if ($.fn.hoverIntent) |
|
121
|
|
|
{ |
|
122
|
|
|
$(this).hoverIntent({ |
|
123
|
|
|
sensitivity: oSettings.hoverIntent.sensitivity, |
|
124
|
|
|
interval: oSettings.hoverIntent.interval, |
|
125
|
|
|
over: smf_tooltip_on, |
|
126
|
|
|
timeout: oSettings.hoverIntent.timeout, |
|
127
|
|
|
out: smf_tooltip_off |
|
128
|
|
|
}); |
|
129
|
|
|
} |
|
130
|
|
|
else |
|
131
|
|
|
{ |
|
132
|
|
|
// plain old hover it is |
|
133
|
|
|
$(this).hover(smf_tooltip_on, smf_tooltip_off); |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
// create the on tip action |
|
137
|
|
|
function smf_tooltip_on(event) |
|
138
|
|
|
{ |
|
139
|
|
|
// If we have text in the hidden span element we created on page load |
|
140
|
|
|
if ($(this).children('.' + oSettings.tooltipSwapClass).text()) |
|
141
|
|
|
{ |
|
142
|
|
|
// create a ID'ed div with our style class that holds the tooltip info, hidden for now |
|
143
|
|
|
$('body').append('<div id="' + oSettings.tooltipID + '" class="' + oSettings.tooltipClass + '"><div id="' + oSettings.tooltipTextID + '" style="display:none;"></div></div>'); |
|
144
|
|
|
|
|
145
|
|
|
// load information in to our newly created div |
|
146
|
|
|
var tt = $('#' + oSettings.tooltipID); |
|
147
|
|
|
var ttContent = $('#' + oSettings.tooltipID + ' #' + oSettings.tooltipTextID); |
|
148
|
|
|
|
|
149
|
|
|
if (oSettings.tooltipContent == 'html') |
|
150
|
|
|
ttContent.html($(this).children('.' + oSettings.tooltipSwapClass).html()); |
|
151
|
|
|
else |
|
152
|
|
|
ttContent.text($(this).children('.' + oSettings.tooltipSwapClass).text()); |
|
153
|
|
|
|
|
154
|
|
|
oSettings.tooltipContent |
|
|
|
|
|
|
155
|
|
|
|
|
156
|
|
|
// show then position or it may postion off screen |
|
157
|
|
|
tt.show(); |
|
158
|
|
|
showTooltip(); |
|
159
|
|
|
positionTooltip(event); |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
return false; |
|
163
|
|
|
}; |
|
164
|
|
|
|
|
165
|
|
|
// create the Bye bye tip |
|
166
|
|
|
function smf_tooltip_off(event) |
|
|
|
|
|
|
167
|
|
|
{ |
|
168
|
|
|
hideTooltip(this); |
|
169
|
|
|
return false; |
|
170
|
|
|
}; |
|
171
|
|
|
|
|
172
|
|
|
// create the tip move with the cursor |
|
173
|
|
|
if (oSettings.followMouse) |
|
174
|
|
|
{ |
|
175
|
|
|
$(this).on("mousemove", function(event){ |
|
176
|
|
|
positionTooltip(event); |
|
177
|
|
|
return false; |
|
178
|
|
|
}); |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
// clear the tip on a click |
|
182
|
|
|
$(this).on("click", function(event){ |
|
|
|
|
|
|
183
|
|
|
hideTooltip(this); |
|
184
|
|
|
return true; |
|
185
|
|
|
}); |
|
186
|
|
|
|
|
187
|
|
|
}); |
|
188
|
|
|
}; |
|
189
|
|
|
|
|
190
|
|
|
// A simple plugin for deleting an element from the DOM. |
|
191
|
|
|
$.fn.fadeOutAndRemove = function(speed){ |
|
192
|
|
|
$(this).fadeOut(speed,function(){ |
|
193
|
|
|
$(this).remove(); |
|
194
|
|
|
}); |
|
195
|
|
|
}; |
|
196
|
|
|
|
|
197
|
|
|
// Range to percent. |
|
198
|
|
|
$.fn.rangeToPercent = function(number, min, max){ |
|
199
|
|
|
return ((number - min) / (max - min)); |
|
200
|
|
|
}; |
|
201
|
|
|
|
|
202
|
|
|
// Percent to range. |
|
203
|
|
|
$.fn.percentToRange = function(percent, min, max){ |
|
204
|
|
|
return((max - min) * percent + min); |
|
205
|
|
|
}; |
|
206
|
|
|
|
|
207
|
|
|
})(jQuery); |
|
208
|
|
|
|
|
209
|
|
|
/** |
|
210
|
|
|
* AnimaDrag |
|
211
|
|
|
* Animated jQuery Drag and Drop Plugin |
|
212
|
|
|
* Version 0.5.1 beta |
|
213
|
|
|
* Author Abel Mohler |
|
214
|
|
|
* Released with the MIT License: http://www.opensource.org/licenses/mit-license.php |
|
215
|
|
|
*/ |
|
216
|
|
|
(function($){ |
|
217
|
|
|
$.fn.animaDrag = function(o, callback) { |
|
218
|
|
|
var defaults = { |
|
219
|
|
|
speed: 400, |
|
220
|
|
|
interval: 300, |
|
221
|
|
|
easing: null, |
|
222
|
|
|
cursor: 'move', |
|
223
|
|
|
boundary: document.body, |
|
224
|
|
|
grip: null, |
|
225
|
|
|
overlay: true, |
|
226
|
|
|
after: function(e) {}, |
|
|
|
|
|
|
227
|
|
|
during: function(e) {}, |
|
|
|
|
|
|
228
|
|
|
before: function(e) {}, |
|
|
|
|
|
|
229
|
|
|
afterEachAnimation: function(e) {} |
|
|
|
|
|
|
230
|
|
|
} |
|
231
|
|
|
if(typeof callback == 'function') { |
|
232
|
|
|
defaults.after = callback; |
|
233
|
|
|
} |
|
234
|
|
|
o = $.extend(defaults, o || {}); |
|
235
|
|
|
return this.each(function() { |
|
236
|
|
|
var id, startX, startY, draggableStartX, draggableStartY, dragging = false, Ev, draggable = this, |
|
237
|
|
|
grip = ($(this).find(o.grip).length > 0) ? $(this).find(o.grip) : $(this); |
|
238
|
|
|
if(o.boundary) { |
|
239
|
|
|
var limitTop = $(o.boundary).offset().top, limitLeft = $(o.boundary).offset().left, |
|
240
|
|
|
limitBottom = limitTop + $(o.boundary).innerHeight(), limitRight = limitLeft + $(o.boundary).innerWidth(); |
|
241
|
|
|
} |
|
242
|
|
|
grip.mousedown(function(e) { |
|
243
|
|
|
o.before.call(draggable, e); |
|
244
|
|
|
|
|
245
|
|
|
var lastX, lastY; |
|
246
|
|
|
dragging = true; |
|
247
|
|
|
|
|
248
|
|
|
Ev = e; |
|
249
|
|
|
|
|
250
|
|
|
startX = lastX = e.pageX; |
|
251
|
|
|
startY = lastY = e.pageY; |
|
252
|
|
|
draggableStartX = $(draggable).offset().left; |
|
253
|
|
|
draggableStartY = $(draggable).offset().top; |
|
254
|
|
|
|
|
255
|
|
|
$(draggable).css({ |
|
256
|
|
|
position: 'absolute', |
|
257
|
|
|
left: draggableStartX + 'px', |
|
258
|
|
|
top: draggableStartY + 'px', |
|
259
|
|
|
cursor: o.cursor, |
|
260
|
|
|
zIndex: '1010' |
|
261
|
|
|
}).addClass('anima-drag').appendTo(document.body); |
|
262
|
|
|
if(o.overlay && $('#anima-drag-overlay').length == 0) { |
|
263
|
|
|
$('<div id="anima-drag-overlay"></div>').css({ |
|
264
|
|
|
position: 'absolute', |
|
265
|
|
|
top: '0', |
|
266
|
|
|
left: '0', |
|
267
|
|
|
zIndex: '1000', |
|
268
|
|
|
width: $(document.body).outerWidth() + 'px', |
|
269
|
|
|
height: $(document.body).outerHeight() + 'px' |
|
270
|
|
|
}).appendTo(document.body); |
|
271
|
|
|
} |
|
272
|
|
|
else if(o.overlay) { |
|
273
|
|
|
$('#anima-drag-overlay').show(); |
|
274
|
|
|
} |
|
275
|
|
|
id = setInterval(function() { |
|
276
|
|
|
if(lastX != Ev.pageX || lastY != Ev.pageY) { |
|
277
|
|
|
var positionX = draggableStartX - (startX - Ev.pageX), positionY = draggableStartY - (startY - Ev.pageY); |
|
278
|
|
|
if(positionX < limitLeft && o.boundary) { |
|
|
|
|
|
|
279
|
|
|
positionX = limitLeft; |
|
280
|
|
|
} |
|
281
|
|
|
else if(positionX + $(draggable).innerWidth() > limitRight && o.boundary) { |
|
|
|
|
|
|
282
|
|
|
positionX = limitRight - $(draggable).outerWidth(); |
|
283
|
|
|
} |
|
284
|
|
|
if(positionY < limitTop && o.boundary) { |
|
|
|
|
|
|
285
|
|
|
positionY = limitTop; |
|
286
|
|
|
} |
|
287
|
|
|
else if(positionY + $(draggable).innerHeight() > limitBottom && o.boundary) { |
|
|
|
|
|
|
288
|
|
|
positionY = limitBottom - $(draggable).outerHeight(); |
|
289
|
|
|
} |
|
290
|
|
|
$(draggable).stop().animate({ |
|
291
|
|
|
left: positionX + 'px', |
|
292
|
|
|
top: positionY + 'px' |
|
293
|
|
|
}, o.speed, o.easing, function(){o.afterEachAnimation.call(draggable, Ev)}); |
|
294
|
|
|
} |
|
295
|
|
|
lastX = Ev.pageX; |
|
296
|
|
|
lastY = Ev.pageY; |
|
297
|
|
|
}, o.interval); |
|
298
|
|
|
($.browser.safari || e.preventDefault()); |
|
299
|
|
|
}); |
|
300
|
|
|
$(document).mousemove(function(e) { |
|
301
|
|
|
if(dragging) { |
|
302
|
|
|
Ev = e; |
|
303
|
|
|
o.during.call(draggable, e); |
|
304
|
|
|
} |
|
305
|
|
|
}); |
|
306
|
|
|
$(document).mouseup(function(e) { |
|
307
|
|
|
if(dragging) { |
|
308
|
|
|
$(draggable).css({ |
|
309
|
|
|
cursor: '', |
|
310
|
|
|
zIndex: '990' |
|
311
|
|
|
}).removeClass('anima-drag'); |
|
312
|
|
|
$('#anima-drag-overlay').hide().appendTo(document.body); |
|
313
|
|
|
clearInterval(id); |
|
314
|
|
|
o.after.call(draggable, e); |
|
315
|
|
|
dragging = false; |
|
316
|
|
|
} |
|
317
|
|
|
}); |
|
318
|
|
|
}); |
|
319
|
|
|
} |
|
320
|
|
|
})(jQuery); |
|
321
|
|
|
|
|
322
|
|
|
/* |
|
323
|
|
|
* jQuery Superfish Menu Plugin - v1.7.7 |
|
324
|
|
|
* Copyright (c) 2015 |
|
325
|
|
|
* |
|
326
|
|
|
* Dual licensed under the MIT and GPL licenses: |
|
327
|
|
|
* http://www.opensource.org/licenses/mit-license.php |
|
328
|
|
|
* http://www.gnu.org/licenses/gpl.html |
|
329
|
|
|
*/ |
|
330
|
|
|
|
|
331
|
|
|
;(function ($, w) { |
|
332
|
|
|
"use strict"; |
|
333
|
|
|
|
|
334
|
|
|
var methods = (function () { |
|
335
|
|
|
// private properties and methods go here |
|
336
|
|
|
var c = { |
|
337
|
|
|
bcClass: 'sf-breadcrumb', |
|
338
|
|
|
menuClass: 'sf-js-enabled', |
|
339
|
|
|
anchorClass: 'sf-with-ul', |
|
340
|
|
|
menuArrowClass: 'sf-arrows' |
|
341
|
|
|
}, |
|
342
|
|
|
ios = (function () { |
|
343
|
|
|
var ios = /^(?![\w\W]*Windows Phone)[\w\W]*(iPhone|iPad|iPod)/i.test(navigator.userAgent); |
|
344
|
|
|
if (ios) { |
|
345
|
|
|
// tap anywhere on iOS to unfocus a submenu |
|
346
|
|
|
$('html').css('cursor', 'pointer').on('click', $.noop); |
|
347
|
|
|
} |
|
348
|
|
|
return ios; |
|
349
|
|
|
})(), |
|
350
|
|
|
wp7 = (function () { |
|
351
|
|
|
var style = document.documentElement.style; |
|
352
|
|
|
return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent)); |
|
353
|
|
|
})(), |
|
354
|
|
|
unprefixedPointerEvents = (function () { |
|
355
|
|
|
return (!!w.PointerEvent); |
|
356
|
|
|
})(), |
|
357
|
|
|
toggleMenuClasses = function ($menu, o) { |
|
358
|
|
|
var classes = c.menuClass; |
|
359
|
|
|
if (o.cssArrows) { |
|
360
|
|
|
classes += ' ' + c.menuArrowClass; |
|
361
|
|
|
} |
|
362
|
|
|
$menu.toggleClass(classes); |
|
363
|
|
|
}, |
|
364
|
|
|
setPathToCurrent = function ($menu, o) { |
|
365
|
|
|
return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels) |
|
366
|
|
|
.addClass(o.hoverClass + ' ' + c.bcClass) |
|
367
|
|
|
.filter(function () { |
|
368
|
|
|
return ($(this).children(o.popUpSelector).hide().show().length); |
|
369
|
|
|
}).removeClass(o.pathClass); |
|
370
|
|
|
}, |
|
371
|
|
|
toggleAnchorClass = function ($li) { |
|
372
|
|
|
$li.children('a').toggleClass(c.anchorClass); |
|
373
|
|
|
}, |
|
374
|
|
|
toggleTouchAction = function ($menu) { |
|
375
|
|
|
var msTouchAction = $menu.css('ms-touch-action'); |
|
376
|
|
|
var touchAction = $menu.css('touch-action'); |
|
377
|
|
|
touchAction = touchAction || msTouchAction; |
|
378
|
|
|
touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y'; |
|
379
|
|
|
$menu.css({ |
|
380
|
|
|
'ms-touch-action': touchAction, |
|
381
|
|
|
'touch-action': touchAction |
|
382
|
|
|
}); |
|
383
|
|
|
}, |
|
384
|
|
|
applyHandlers = function ($menu, o) { |
|
385
|
|
|
var targets = 'li:has(' + o.popUpSelector + ')'; |
|
386
|
|
|
if ($.fn.hoverIntent && !o.disableHI) { |
|
387
|
|
|
$menu.hoverIntent(over, out, targets); |
|
388
|
|
|
} |
|
389
|
|
|
else { |
|
390
|
|
|
$menu |
|
391
|
|
|
.on('mouseenter.superfish', targets, over) |
|
392
|
|
|
.on('mouseleave.superfish', targets, out); |
|
393
|
|
|
} |
|
394
|
|
|
var touchevent = 'MSPointerDown.superfish'; |
|
395
|
|
|
if (unprefixedPointerEvents) { |
|
396
|
|
|
touchevent = 'pointerdown.superfish'; |
|
397
|
|
|
} |
|
398
|
|
|
if (!ios) { |
|
399
|
|
|
touchevent += ' touchend.superfish'; |
|
400
|
|
|
} |
|
401
|
|
|
if (wp7) { |
|
402
|
|
|
touchevent += ' mousedown.superfish'; |
|
403
|
|
|
} |
|
404
|
|
|
$menu |
|
405
|
|
|
.on('focusin.superfish', 'li', over) |
|
406
|
|
|
.on('focusout.superfish', 'li', out) |
|
407
|
|
|
.on(touchevent, 'a', o, touchHandler); |
|
408
|
|
|
}, |
|
409
|
|
|
touchHandler = function (e) { |
|
410
|
|
|
var $this = $(this), |
|
411
|
|
|
o = getOptions($this), |
|
412
|
|
|
$ul = $this.siblings(e.data.popUpSelector); |
|
413
|
|
|
|
|
414
|
|
|
if (o.onHandleTouch.call($ul) === false) { |
|
415
|
|
|
return this; |
|
416
|
|
|
} |
|
417
|
|
|
|
|
418
|
|
|
if ($ul.length > 0 && $ul.is(':hidden')) { |
|
|
|
|
|
|
419
|
|
|
$this.one('click.superfish', false); |
|
420
|
|
|
if (e.type === 'MSPointerDown' || e.type === 'pointerdown') { |
|
421
|
|
|
$this.trigger('focus'); |
|
|
|
|
|
|
422
|
|
|
} else { |
|
423
|
|
|
$.proxy(over, $this.parent('li'))(); |
|
|
|
|
|
|
424
|
|
|
} |
|
425
|
|
|
} |
|
426
|
|
|
}, |
|
427
|
|
|
over = function () { |
|
428
|
|
|
var $this = $(this), |
|
429
|
|
|
o = getOptions($this); |
|
430
|
|
|
clearTimeout(o.sfTimer); |
|
431
|
|
|
$this.siblings().superfish('hide').end().superfish('show'); |
|
432
|
|
|
}, |
|
433
|
|
|
out = function () { |
|
434
|
|
|
var $this = $(this), |
|
435
|
|
|
o = getOptions($this); |
|
436
|
|
|
if (ios) { |
|
437
|
|
|
$.proxy(close, $this, o)(); |
|
438
|
|
|
} |
|
439
|
|
|
else { |
|
440
|
|
|
clearTimeout(o.sfTimer); |
|
441
|
|
|
o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay); |
|
442
|
|
|
} |
|
443
|
|
|
}, |
|
444
|
|
|
close = function (o) { |
|
445
|
|
|
o.retainPath = ($.inArray(this[0], o.$path) > -1); |
|
446
|
|
|
this.superfish('hide'); |
|
447
|
|
|
|
|
448
|
|
|
if (!this.parents('.' + o.hoverClass).length) { |
|
449
|
|
|
o.onIdle.call(getMenu(this)); |
|
450
|
|
|
if (o.$path.length) { |
|
451
|
|
|
$.proxy(over, o.$path)(); |
|
452
|
|
|
} |
|
453
|
|
|
} |
|
454
|
|
|
}, |
|
455
|
|
|
getMenu = function ($el) { |
|
456
|
|
|
return $el.closest('.' + c.menuClass); |
|
457
|
|
|
}, |
|
458
|
|
|
getOptions = function ($el) { |
|
459
|
|
|
return getMenu($el).data('sf-options'); |
|
460
|
|
|
}; |
|
461
|
|
|
|
|
462
|
|
|
return { |
|
463
|
|
|
// public methods |
|
464
|
|
|
hide: function (instant) { |
|
465
|
|
|
if (this.length) { |
|
466
|
|
|
var $this = this, |
|
467
|
|
|
o = getOptions($this); |
|
468
|
|
|
if (!o) { |
|
469
|
|
|
return this; |
|
470
|
|
|
} |
|
471
|
|
|
var not = (o.retainPath === true) ? o.$path : '', |
|
472
|
|
|
$ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector), |
|
473
|
|
|
speed = o.speedOut; |
|
474
|
|
|
|
|
475
|
|
|
if (instant) { |
|
476
|
|
|
$ul.show(); |
|
477
|
|
|
speed = 0; |
|
478
|
|
|
} |
|
479
|
|
|
o.retainPath = false; |
|
480
|
|
|
|
|
481
|
|
|
if (o.onBeforeHide.call($ul) === false) { |
|
482
|
|
|
return this; |
|
483
|
|
|
} |
|
484
|
|
|
|
|
485
|
|
|
$ul.stop(true, true).animate(o.animationOut, speed, function () { |
|
486
|
|
|
var $this = $(this); |
|
487
|
|
|
o.onHide.call($this); |
|
488
|
|
|
}); |
|
489
|
|
|
} |
|
490
|
|
|
return this; |
|
491
|
|
|
}, |
|
492
|
|
|
show: function () { |
|
493
|
|
|
var o = getOptions(this); |
|
494
|
|
|
if (!o) { |
|
495
|
|
|
return this; |
|
496
|
|
|
} |
|
497
|
|
|
var $this = this.addClass(o.hoverClass), |
|
498
|
|
|
$ul = $this.children(o.popUpSelector); |
|
499
|
|
|
|
|
500
|
|
|
if (o.onBeforeShow.call($ul) === false) { |
|
501
|
|
|
return this; |
|
502
|
|
|
} |
|
503
|
|
|
|
|
504
|
|
|
$ul.stop(true, true).animate(o.animation, o.speed, function () { |
|
505
|
|
|
o.onShow.call($ul); |
|
506
|
|
|
}); |
|
507
|
|
|
return this; |
|
508
|
|
|
}, |
|
509
|
|
|
destroy: function () { |
|
510
|
|
|
return this.each(function () { |
|
511
|
|
|
var $this = $(this), |
|
512
|
|
|
o = $this.data('sf-options'), |
|
513
|
|
|
$hasPopUp; |
|
514
|
|
|
if (!o) { |
|
515
|
|
|
return false; |
|
516
|
|
|
} |
|
517
|
|
|
$hasPopUp = $this.find(o.popUpSelector).parent('li'); |
|
518
|
|
|
clearTimeout(o.sfTimer); |
|
519
|
|
|
toggleMenuClasses($this, o); |
|
520
|
|
|
toggleAnchorClass($hasPopUp); |
|
521
|
|
|
toggleTouchAction($this); |
|
522
|
|
|
// remove event handlers |
|
523
|
|
|
$this.off('.superfish').off('.hoverIntent'); |
|
524
|
|
|
// clear animation's inline display style |
|
525
|
|
|
$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) { |
|
526
|
|
|
return style.replace(/display[^;]+;?/g, ''); |
|
527
|
|
|
}); |
|
528
|
|
|
// reset 'current' path classes |
|
529
|
|
|
o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass); |
|
530
|
|
|
$this.find('.' + o.hoverClass).removeClass(o.hoverClass); |
|
531
|
|
|
o.onDestroy.call($this); |
|
532
|
|
|
$this.removeData('sf-options'); |
|
|
|
|
|
|
533
|
|
|
}); |
|
534
|
|
|
}, |
|
535
|
|
|
init: function (op) { |
|
536
|
|
|
return this.each(function () { |
|
537
|
|
|
var $this = $(this); |
|
538
|
|
|
if ($this.data('sf-options')) { |
|
539
|
|
|
return false; |
|
540
|
|
|
} |
|
541
|
|
|
var o = $.extend({}, $.fn.superfish.defaults, op), |
|
542
|
|
|
$hasPopUp = $this.find(o.popUpSelector).parent('li'); |
|
543
|
|
|
o.$path = setPathToCurrent($this, o); |
|
544
|
|
|
|
|
545
|
|
|
$this.data('sf-options', o); |
|
546
|
|
|
|
|
547
|
|
|
toggleMenuClasses($this, o); |
|
548
|
|
|
toggleAnchorClass($hasPopUp); |
|
549
|
|
|
toggleTouchAction($this); |
|
550
|
|
|
applyHandlers($this, o); |
|
551
|
|
|
|
|
552
|
|
|
$hasPopUp.not('.' + c.bcClass).superfish('hide', true); |
|
553
|
|
|
|
|
554
|
|
|
o.onInit.call(this); |
|
|
|
|
|
|
555
|
|
|
}); |
|
556
|
|
|
} |
|
557
|
|
|
}; |
|
558
|
|
|
})(); |
|
559
|
|
|
|
|
560
|
|
|
$.fn.superfish = function (method, args) { |
|
|
|
|
|
|
561
|
|
|
if (methods[method]) { |
|
562
|
|
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); |
|
563
|
|
|
} |
|
564
|
|
|
else if (typeof method === 'object' || ! method) { |
|
565
|
|
|
return methods.init.apply(this, arguments); |
|
566
|
|
|
} |
|
567
|
|
|
else { |
|
568
|
|
|
return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish'); |
|
569
|
|
|
} |
|
570
|
|
|
}; |
|
571
|
|
|
|
|
572
|
|
|
$.fn.superfish.defaults = { |
|
573
|
|
|
popUpSelector: 'ul,.sf-mega', // within menu context |
|
574
|
|
|
hoverClass: 'sfHover', |
|
575
|
|
|
pathClass: 'overrideThisToUse', |
|
576
|
|
|
pathLevels: 1, |
|
577
|
|
|
delay: 800, |
|
578
|
|
|
animation: {opacity: 'show'}, |
|
579
|
|
|
animationOut: {opacity: 'hide'}, |
|
580
|
|
|
speed: 'normal', |
|
581
|
|
|
speedOut: 'fast', |
|
582
|
|
|
cssArrows: true, |
|
583
|
|
|
disableHI: false, |
|
584
|
|
|
onInit: $.noop, |
|
585
|
|
|
onBeforeShow: $.noop, |
|
586
|
|
|
onShow: $.noop, |
|
587
|
|
|
onBeforeHide: $.noop, |
|
588
|
|
|
onHide: $.noop, |
|
589
|
|
|
onIdle: $.noop, |
|
590
|
|
|
onDestroy: $.noop, |
|
591
|
|
|
onHandleTouch: $.noop |
|
592
|
|
|
}; |
|
593
|
|
|
|
|
594
|
|
|
})(jQuery, window); |
|
595
|
|
|
|
|
596
|
|
|
/** |
|
597
|
|
|
* hoverIntent is similar to jQuery's built-in "hover" method except that |
|
598
|
|
|
* instead of firing the handlerIn function immediately, hoverIntent checks |
|
599
|
|
|
* to see if the user's mouse has slowed down (beneath the sensitivity |
|
600
|
|
|
* threshold) before firing the event. The handlerOut function is only |
|
601
|
|
|
* called after a matching handlerIn. |
|
602
|
|
|
* |
|
603
|
|
|
* hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+ |
|
604
|
|
|
* http://cherne.net/brian/resources/jquery.hoverIntent.html |
|
605
|
|
|
* |
|
606
|
|
|
* You may use hoverIntent under the terms of the MIT license. Basically that |
|
607
|
|
|
* means you are free to use hoverIntent as long as this header is left intact. |
|
608
|
|
|
* Copyright 2007, 2013 Brian Cherne |
|
609
|
|
|
* |
|
610
|
|
|
* // basic usage ... just like .hover() |
|
611
|
|
|
* .hoverIntent( handlerIn, handlerOut ) |
|
612
|
|
|
* .hoverIntent( handlerInOut ) |
|
613
|
|
|
* |
|
614
|
|
|
* // basic usage ... with event delegation! |
|
615
|
|
|
* .hoverIntent( handlerIn, handlerOut, selector ) |
|
616
|
|
|
* .hoverIntent( handlerInOut, selector ) |
|
617
|
|
|
* |
|
618
|
|
|
* // using a basic configuration object |
|
619
|
|
|
* .hoverIntent( config ) |
|
620
|
|
|
* |
|
621
|
|
|
* @param handlerIn function OR configuration object |
|
|
|
|
|
|
622
|
|
|
* @param handlerOut function OR selector for delegation OR undefined |
|
|
|
|
|
|
623
|
|
|
* @param selector selector OR undefined |
|
|
|
|
|
|
624
|
|
|
* @author Brian Cherne <brian(at)cherne(dot)net> |
|
625
|
|
|
**/ |
|
626
|
|
|
(function($) { |
|
627
|
|
|
$.fn.hoverIntent = function(handlerIn,handlerOut,selector) { |
|
628
|
|
|
|
|
629
|
|
|
// default configuration values |
|
630
|
|
|
var cfg = { |
|
631
|
|
|
interval: 100, |
|
632
|
|
|
sensitivity: 7, |
|
633
|
|
|
timeout: 0 |
|
634
|
|
|
}; |
|
635
|
|
|
|
|
636
|
|
|
if ( typeof handlerIn === "object" ) { |
|
637
|
|
|
cfg = $.extend(cfg, handlerIn ); |
|
638
|
|
|
} else if ($.isFunction(handlerOut)) { |
|
639
|
|
|
cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } ); |
|
640
|
|
|
} else { |
|
641
|
|
|
cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } ); |
|
642
|
|
|
} |
|
643
|
|
|
|
|
644
|
|
|
// instantiate variables |
|
645
|
|
|
// cX, cY = current X and Y position of mouse, updated by mousemove event |
|
646
|
|
|
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval |
|
647
|
|
|
var cX, cY, pX, pY; |
|
648
|
|
|
|
|
649
|
|
|
// A private function for getting mouse position |
|
650
|
|
|
var track = function(ev) { |
|
651
|
|
|
cX = ev.pageX; |
|
652
|
|
|
cY = ev.pageY; |
|
653
|
|
|
}; |
|
654
|
|
|
|
|
655
|
|
|
// A private function for comparing current and previous mouse position |
|
656
|
|
|
var compare = function(ev,ob) { |
|
657
|
|
|
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); |
|
658
|
|
|
// compare mouse positions to see if they've crossed the threshold |
|
659
|
|
|
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { |
|
660
|
|
|
$(ob).off("mousemove.hoverIntent",track); |
|
661
|
|
|
// set hoverIntent state to true (so mouseOut can be called) |
|
662
|
|
|
ob.hoverIntent_s = 1; |
|
663
|
|
|
return cfg.over.apply(ob,[ev]); |
|
664
|
|
|
} else { |
|
665
|
|
|
// set previous coordinates for next time |
|
666
|
|
|
pX = cX; pY = cY; |
|
667
|
|
|
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) |
|
668
|
|
|
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); |
|
|
|
|
|
|
669
|
|
|
} |
|
670
|
|
|
}; |
|
671
|
|
|
|
|
672
|
|
|
// A private function for delaying the mouseOut function |
|
673
|
|
|
var delay = function(ev,ob) { |
|
674
|
|
|
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); |
|
675
|
|
|
ob.hoverIntent_s = 0; |
|
676
|
|
|
return cfg.out.apply(ob,[ev]); |
|
677
|
|
|
}; |
|
678
|
|
|
|
|
679
|
|
|
// A private function for handling mouse 'hovering' |
|
680
|
|
|
var handleHover = function(e) { |
|
681
|
|
|
// copy objects to be passed into t (required for event object to be passed in IE) |
|
682
|
|
|
var ev = jQuery.extend({},e); |
|
683
|
|
|
var ob = this; |
|
684
|
|
|
|
|
685
|
|
|
// cancel hoverIntent timer if it exists |
|
686
|
|
|
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } |
|
687
|
|
|
|
|
688
|
|
|
// if e.type == "mouseenter" |
|
689
|
|
|
if (e.type == "mouseenter") { |
|
690
|
|
|
// set "previous" X and Y position based on initial entry point |
|
691
|
|
|
pX = ev.pageX; pY = ev.pageY; |
|
692
|
|
|
// update "current" X and Y position based on mousemove |
|
693
|
|
|
$(ob).on("mousemove.hoverIntent",track); |
|
694
|
|
|
// start polling interval (self-calling timeout) to compare mouse coordinates over time |
|
695
|
|
|
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} |
|
696
|
|
|
|
|
697
|
|
|
// else e.type == "mouseleave" |
|
698
|
|
|
} else { |
|
699
|
|
|
// unbind expensive mousemove event |
|
700
|
|
|
$(ob).off("mousemove.hoverIntent",track); |
|
701
|
|
|
// if hoverIntent state is true, then call the mouseOut function after the specified delay |
|
702
|
|
|
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} |
|
703
|
|
|
} |
|
704
|
|
|
}; |
|
705
|
|
|
|
|
706
|
|
|
// listen for mouseenter and mouseleave |
|
707
|
|
|
return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector); |
|
708
|
|
|
}; |
|
709
|
|
|
})(jQuery); |
|
710
|
|
|
|
|
711
|
|
|
/* Takes every category header available and adds a collapse option */ |
|
712
|
|
|
$(function() { |
|
713
|
|
|
if (smf_member_id > 0) |
|
714
|
|
|
$('div.boardindex_table div.cat_bar').each(function(index, el) |
|
715
|
|
|
{ |
|
716
|
|
|
var catid = el.id.replace('category_', ''); |
|
717
|
|
|
new smc_Toggle({ |
|
|
|
|
|
|
718
|
|
|
bToggleEnabled: true, |
|
719
|
|
|
bCurrentlyCollapsed: $('#category_' + catid + '_upshrink').data('collapsed'), |
|
720
|
|
|
aSwappableContainers: [ |
|
721
|
|
|
'category_' + catid + '_boards' |
|
722
|
|
|
], |
|
723
|
|
|
aSwapImages: [ |
|
724
|
|
|
{ |
|
725
|
|
|
sId: 'category_' + catid + '_upshrink', |
|
726
|
|
|
msgExpanded: '', |
|
727
|
|
|
msgCollapsed: '' |
|
728
|
|
|
} |
|
729
|
|
|
], |
|
730
|
|
|
oThemeOptions: { |
|
731
|
|
|
bUseThemeSettings: true, |
|
732
|
|
|
sOptionName: 'collapse_category_' + catid, |
|
733
|
|
|
sSessionVar: smf_session_var, |
|
734
|
|
|
sSessionId: smf_session_id |
|
735
|
|
|
} |
|
736
|
|
|
}); |
|
737
|
|
|
}); |
|
738
|
|
|
}); |
|
739
|
|
|
|
|
740
|
|
|
/* Mobile Pop */ |
|
741
|
|
|
$(function() { |
|
742
|
|
|
$( '.mobile_act' ).click(function() { |
|
743
|
|
|
$( '#mobile_action' ).show(); |
|
744
|
|
|
}); |
|
745
|
|
|
$( '.hide_popup' ).click(function() { |
|
746
|
|
|
$( '#mobile_action' ).hide(); |
|
747
|
|
|
}); |
|
748
|
|
|
$( '.mobile_mod' ).click(function() { |
|
749
|
|
|
$( '#mobile_moderation' ).show(); |
|
750
|
|
|
}); |
|
751
|
|
|
$( '.hide_popup' ).click(function() { |
|
752
|
|
|
$( '#mobile_moderation' ).hide(); |
|
753
|
|
|
}); |
|
754
|
|
|
$( '.mobile_user_menu' ).click(function() { |
|
755
|
|
|
$( '#mobile_user_menu' ).show(); |
|
756
|
|
|
}); |
|
757
|
|
|
$( '.hide_popup' ).click(function() { |
|
758
|
|
|
$( '#mobile_user_menu' ).hide(); |
|
759
|
|
|
}); |
|
760
|
|
|
}); |
|
761
|
|
|
|
This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.