These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | var smf_formSubmitted = false; |
||
2 | var lastKeepAliveCheck = new Date().getTime(); |
||
3 | var smf_editorArray = new Array(); |
||
4 | |||
5 | // Some very basic browser detection - from Mozilla's sniffer page. |
||
6 | var ua = navigator.userAgent.toLowerCase(); |
||
7 | |||
8 | var is_opera = ua.indexOf('opera') != -1; |
||
9 | var is_ff = (ua.indexOf('firefox') != -1 || ua.indexOf('iceweasel') != -1 || ua.indexOf('icecat') != -1 || ua.indexOf('shiretoko') != -1 || ua.indexOf('minefield') != -1) && !is_opera; |
||
10 | var is_gecko = ua.indexOf('gecko') != -1 && !is_opera; |
||
11 | |||
12 | var is_chrome = ua.indexOf('chrome') != -1; |
||
13 | var is_safari = ua.indexOf('applewebkit') != -1 && !is_chrome; |
||
14 | var is_webkit = ua.indexOf('applewebkit') != -1; |
||
15 | |||
16 | var is_ie = ua.indexOf('msie') != -1 && !is_opera; |
||
17 | // Stupid Microsoft... |
||
18 | var is_ie11 = ua.indexOf('trident') != -1 && ua.indexOf('gecko') != -1; |
||
19 | var is_iphone = ua.indexOf('iphone') != -1 || ua.indexOf('ipod') != -1; |
||
20 | var is_android = ua.indexOf('android') != -1; |
||
21 | |||
22 | var ajax_indicator_ele = null; |
||
23 | |||
24 | // Some older versions of Mozilla don't have this, for some reason. |
||
25 | if (!('forms' in document)) |
||
26 | document.forms = document.getElementsByTagName('form'); |
||
27 | |||
28 | // Versions of ie < 9 do not have this built in |
||
29 | if (!('getElementsByClassName' in document)) |
||
30 | { |
||
31 | document.getElementsByClassName = function(className) |
||
32 | { |
||
33 | return $('".' + className + '"'); |
||
34 | } |
||
35 | } |
||
36 | |||
37 | // Get a response from the server. |
||
38 | function getServerResponse(sUrl, funcCallback, sType, sDataType) |
||
39 | { |
||
40 | var oCaller = this; |
||
41 | var oMyDoc = $.ajax({ |
||
42 | type: sType, |
||
43 | url: sUrl, |
||
44 | cache: false, |
||
45 | dataType: sDataType, |
||
46 | success: function(response) { |
||
47 | if (typeof(funcCallback) != 'undefined') |
||
48 | { |
||
49 | funcCallback.call(oCaller, response); |
||
50 | } |
||
51 | }, |
||
52 | }); |
||
53 | |||
54 | return oMyDoc; |
||
55 | } |
||
56 | |||
57 | // Load an XML document. |
||
58 | function getXMLDocument(sUrl, funcCallback) |
||
59 | { |
||
60 | var oCaller = this; |
||
61 | var oMyDoc = $.ajax({ |
||
62 | type: 'GET', |
||
63 | url: sUrl, |
||
64 | cache: false, |
||
65 | dataType: 'xml', |
||
66 | success: function(responseXML) { |
||
67 | if (typeof(funcCallback) != 'undefined') |
||
68 | { |
||
69 | funcCallback.call(oCaller, responseXML); |
||
70 | } |
||
71 | }, |
||
72 | }); |
||
73 | |||
74 | return oMyDoc; |
||
75 | } |
||
76 | |||
77 | // Send a post form to the server. |
||
78 | function sendXMLDocument(sUrl, sContent, funcCallback) |
||
79 | { |
||
80 | var oCaller = this; |
||
81 | var oSendDoc = $.ajax({ |
||
82 | type: 'POST', |
||
83 | url: sUrl, |
||
84 | data: sContent, |
||
85 | beforeSend: function(xhr) { |
||
86 | xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
||
87 | }, |
||
88 | dataType: 'xml', |
||
89 | success: function(responseXML) { |
||
90 | if (typeof(funcCallback) != 'undefined') |
||
91 | { |
||
92 | funcCallback.call(oCaller, responseXML); |
||
93 | } |
||
94 | }, |
||
95 | }); |
||
96 | |||
97 | return true; |
||
98 | } |
||
99 | |||
100 | // A property we'll be needing for php_to8bit. |
||
101 | String.prototype.oCharsetConversion = { |
||
102 | from: '', |
||
103 | to: '' |
||
104 | }; |
||
105 | |||
106 | // Convert a string to an 8 bit representation (like in PHP). |
||
107 | String.prototype.php_to8bit = function () |
||
108 | { |
||
109 | if (smf_charset == 'UTF-8') |
||
110 | { |
||
111 | var n, sReturn = ''; |
||
112 | |||
113 | for (var i = 0, iTextLen = this.length; i < iTextLen; i++) |
||
114 | { |
||
115 | n = this.charCodeAt(i); |
||
116 | if (n < 128) |
||
117 | sReturn += String.fromCharCode(n); |
||
118 | else if (n < 2048) |
||
119 | sReturn += String.fromCharCode(192 | n >> 6) + String.fromCharCode(128 | n & 63); |
||
120 | else if (n < 65536) |
||
121 | sReturn += String.fromCharCode(224 | n >> 12) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63); |
||
122 | else |
||
123 | sReturn += String.fromCharCode(240 | n >> 18) + String.fromCharCode(128 | n >> 12 & 63) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63); |
||
124 | } |
||
125 | |||
126 | return sReturn; |
||
127 | } |
||
128 | |||
129 | else if (this.oCharsetConversion.from.length == 0) |
||
130 | { |
||
131 | switch (smf_charset) |
||
132 | { |
||
133 | case 'ISO-8859-1': |
||
134 | this.oCharsetConversion = { |
||
135 | from: '\xa0-\xff', |
||
136 | to: '\xa0-\xff' |
||
137 | }; |
||
138 | break; |
||
139 | |||
140 | case 'ISO-8859-2': |
||
141 | this.oCharsetConversion = { |
||
142 | from: '\xa0\u0104\u02d8\u0141\xa4\u013d\u015a\xa7\xa8\u0160\u015e\u0164\u0179\xad\u017d\u017b\xb0\u0105\u02db\u0142\xb4\u013e\u015b\u02c7\xb8\u0161\u015f\u0165\u017a\u02dd\u017e\u017c\u0154\xc1\xc2\u0102\xc4\u0139\u0106\xc7\u010c\xc9\u0118\xcb\u011a\xcd\xce\u010e\u0110\u0143\u0147\xd3\xd4\u0150\xd6\xd7\u0158\u016e\xda\u0170\xdc\xdd\u0162\xdf\u0155\xe1\xe2\u0103\xe4\u013a\u0107\xe7\u010d\xe9\u0119\xeb\u011b\xed\xee\u010f\u0111\u0144\u0148\xf3\xf4\u0151\xf6\xf7\u0159\u016f\xfa\u0171\xfc\xfd\u0163\u02d9', |
||
143 | to: '\xa0-\xff' |
||
144 | }; |
||
145 | break; |
||
146 | |||
147 | case 'ISO-8859-5': |
||
148 | this.oCharsetConversion = { |
||
149 | from: '\xa0\u0401-\u040c\xad\u040e-\u044f\u2116\u0451-\u045c\xa7\u045e\u045f', |
||
150 | to: '\xa0-\xff' |
||
151 | }; |
||
152 | break; |
||
153 | |||
154 | case 'ISO-8859-9': |
||
155 | this.oCharsetConversion = { |
||
156 | from: '\xa0-\xcf\u011e\xd1-\xdc\u0130\u015e\xdf-\xef\u011f\xf1-\xfc\u0131\u015f\xff', |
||
157 | to: '\xa0-\xff' |
||
158 | }; |
||
159 | break; |
||
160 | |||
161 | case 'ISO-8859-15': |
||
162 | this.oCharsetConversion = { |
||
163 | from: '\xa0-\xa3\u20ac\xa5\u0160\xa7\u0161\xa9-\xb3\u017d\xb5-\xb7\u017e\xb9-\xbb\u0152\u0153\u0178\xbf-\xff', |
||
164 | to: '\xa0-\xff' |
||
165 | }; |
||
166 | break; |
||
167 | |||
168 | case 'tis-620': |
||
169 | this.oCharsetConversion = { |
||
170 | from: '\u20ac\u2026\u2018\u2019\u201c\u201d\u2022\u2013\u2014\xa0\u0e01-\u0e3a\u0e3f-\u0e5b', |
||
171 | to: '\x80\x85\x91-\x97\xa0-\xda\xdf-\xfb' |
||
172 | }; |
||
173 | break; |
||
174 | |||
175 | case 'windows-1251': |
||
176 | this.oCharsetConversion = { |
||
177 | from: '\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u2122\u0459\u203a\u045a\u045c\u045b\u045f\xa0\u040e\u045e\u0408\xa4\u0490\xa6\xa7\u0401\xa9\u0404\xab-\xae\u0407\xb0\xb1\u0406\u0456\u0491\xb5-\xb7\u0451\u2116\u0454\xbb\u0458\u0405\u0455\u0457\u0410-\u044f', |
||
178 | to: '\x80-\x97\x99-\xff' |
||
179 | }; |
||
180 | break; |
||
181 | |||
182 | case 'windows-1253': |
||
183 | this.oCharsetConversion = { |
||
184 | from: '\u20ac\u201a\u0192\u201e\u2026\u2020\u2021\u2030\u2039\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u2122\u203a\xa0\u0385\u0386\xa3-\xa9\xab-\xae\u2015\xb0-\xb3\u0384\xb5-\xb7\u0388-\u038a\xbb\u038c\xbd\u038e-\u03a1\u03a3-\u03ce', |
||
185 | to: '\x80\x82-\x87\x89\x8b\x91-\x97\x99\x9b\xa0-\xa9\xab-\xd1\xd3-\xfe' |
||
186 | }; |
||
187 | break; |
||
188 | |||
189 | case 'windows-1255': |
||
190 | this.oCharsetConversion = { |
||
191 | from: '\u20ac\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u2039\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u203a\xa0-\xa3\u20aa\xa5-\xa9\xd7\xab-\xb9\xf7\xbb-\xbf\u05b0-\u05b9\u05bb-\u05c3\u05f0-\u05f4\u05d0-\u05ea\u200e\u200f', |
||
192 | to: '\x80\x82-\x89\x8b\x91-\x99\x9b\xa0-\xc9\xcb-\xd8\xe0-\xfa\xfd\xfe' |
||
193 | }; |
||
194 | break; |
||
195 | |||
196 | case 'windows-1256': |
||
197 | this.oCharsetConversion = { |
||
198 | from: '\u20ac\u067e\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06af\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u06a9\u2122\u0691\u203a\u0153\u200c\u200d\u06ba\xa0\u060c\xa2-\xa9\u06be\xab-\xb9\u061b\xbb-\xbe\u061f\u06c1\u0621-\u0636\xd7\u0637-\u063a\u0640-\u0643\xe0\u0644\xe2\u0645-\u0648\xe7-\xeb\u0649\u064a\xee\xef\u064b-\u064e\xf4\u064f\u0650\xf7\u0651\xf9\u0652\xfb\xfc\u200e\u200f\u06d2', |
||
199 | to: '\x80-\xff' |
||
200 | }; |
||
201 | break; |
||
202 | |||
203 | default: |
||
204 | this.oCharsetConversion = { |
||
205 | from: '', |
||
206 | to: '' |
||
207 | }; |
||
208 | break; |
||
209 | } |
||
210 | var funcExpandString = function (sSearch) { |
||
211 | var sInsert = ''; |
||
212 | for (var i = sSearch.charCodeAt(0), n = sSearch.charCodeAt(2); i <= n; i++) |
||
213 | sInsert += String.fromCharCode(i); |
||
214 | return sInsert; |
||
215 | }; |
||
216 | this.oCharsetConversion.from = this.oCharsetConversion.from.replace(/.\-./g, funcExpandString); |
||
217 | this.oCharsetConversion.to = this.oCharsetConversion.to.replace(/.\-./g, funcExpandString); |
||
218 | } |
||
219 | |||
220 | var sReturn = '', iOffsetFrom = 0; |
||
221 | for (var i = 0, n = this.length; i < n; i++) |
||
222 | { |
||
223 | iOffsetFrom = this.oCharsetConversion.from.indexOf(this.charAt(i)); |
||
224 | sReturn += iOffsetFrom > -1 ? this.oCharsetConversion.to.charAt(iOffsetFrom) : (this.charCodeAt(i) > 127 ? '&#' + this.charCodeAt(i) + ';' : this.charAt(i)); |
||
225 | } |
||
226 | |||
227 | return sReturn |
||
228 | } |
||
229 | |||
230 | // Character-level replacement function. |
||
231 | String.prototype.php_strtr = function (sFrom, sTo) |
||
232 | { |
||
233 | return this.replace(new RegExp('[' + sFrom + ']', 'g'), function (sMatch) { |
||
234 | return sTo.charAt(sFrom.indexOf(sMatch)); |
||
235 | }); |
||
236 | } |
||
237 | |||
238 | // Simulate PHP's strtolower (in SOME cases PHP uses ISO-8859-1 case folding). |
||
239 | String.prototype.php_strtolower = function () |
||
240 | { |
||
241 | return typeof(smf_iso_case_folding) == 'boolean' && smf_iso_case_folding == true ? this.php_strtr( |
||
242 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ\x8a\x8c\x8e\x9f\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde', |
||
243 | 'abcdefghijklmnopqrstuvwxyz\x9a\x9c\x9e\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe' |
||
244 | ) : this.php_strtr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); |
||
245 | } |
||
246 | |||
247 | String.prototype.php_urlencode = function() |
||
248 | { |
||
249 | return escape(this).replace(/\+/g, '%2b').replace('*', '%2a').replace('/', '%2f').replace('@', '%40'); |
||
250 | } |
||
251 | |||
252 | String.prototype.php_htmlspecialchars = function() |
||
253 | { |
||
254 | return this.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); |
||
255 | } |
||
256 | |||
257 | String.prototype.php_unhtmlspecialchars = function() |
||
258 | { |
||
259 | return this.replace(/"/g, '"').replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&'); |
||
260 | } |
||
261 | |||
262 | String.prototype.php_addslashes = function() |
||
263 | { |
||
264 | return this.replace(/\\/g, '\\\\').replace(/'/g, '\\\''); |
||
265 | } |
||
266 | |||
267 | String.prototype._replaceEntities = function(sInput, sDummy, sNum) |
||
268 | { |
||
269 | return String.fromCharCode(parseInt(sNum)); |
||
270 | } |
||
271 | |||
272 | String.prototype.removeEntities = function() |
||
273 | { |
||
274 | return this.replace(/&(amp;)?#(\d+);/g, this._replaceEntities); |
||
275 | } |
||
276 | |||
277 | String.prototype.easyReplace = function (oReplacements) |
||
278 | { |
||
279 | var sResult = this; |
||
280 | for (var sSearch in oReplacements) |
||
281 | sResult = sResult.replace(new RegExp('%' + sSearch + '%', 'g'), oReplacements[sSearch]); |
||
282 | |||
283 | return sResult; |
||
284 | } |
||
285 | |||
286 | // Open a new window |
||
287 | function reqWin(desktopURL, alternateWidth, alternateHeight, noScrollbars) |
||
288 | { |
||
289 | if ((alternateWidth && self.screen.availWidth * 0.8 < alternateWidth) || (alternateHeight && self.screen.availHeight * 0.8 < alternateHeight)) |
||
290 | { |
||
291 | noScrollbars = false; |
||
292 | alternateWidth = Math.min(alternateWidth, self.screen.availWidth * 0.8); |
||
293 | alternateHeight = Math.min(alternateHeight, self.screen.availHeight * 0.8); |
||
294 | } |
||
295 | else |
||
296 | noScrollbars = typeof(noScrollbars) == 'boolean' && noScrollbars == true; |
||
297 | |||
298 | window.open(desktopURL, 'requested_popup', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=' + (noScrollbars ? 'no' : 'yes') + ',width=' + (alternateWidth ? alternateWidth : 480) + ',height=' + (alternateHeight ? alternateHeight : 220) + ',resizable=no'); |
||
299 | |||
300 | // Return false so the click won't follow the link ;). |
||
301 | return false; |
||
302 | } |
||
303 | |||
304 | // Open a overlay div |
||
305 | function reqOverlayDiv(desktopURL, sHeader, sIcon) |
||
306 | { |
||
307 | // Set up our div details |
||
308 | var sAjax_indicator = '<div class="centertext"><img src="' + smf_images_url + '/loading_sm.gif"></div>'; |
||
309 | var sIcon = smf_images_url + '/' + (typeof(sIcon) == 'string' ? sIcon : 'helptopics.png'); |
||
310 | var sHeader = typeof(sHeader) == 'string' ? sHeader : help_popup_heading_text; |
||
311 | |||
312 | // Create the div that we are going to load |
||
313 | var oContainer = new smc_Popup({heading: sHeader, content: sAjax_indicator, icon: sIcon}); |
||
314 | var oPopup_body = $('#' + oContainer.popup_id).find('.popup_content'); |
||
315 | |||
316 | // Load the help page content (we just want the text to show) |
||
317 | $.ajax({ |
||
318 | url: desktopURL, |
||
319 | type: "GET", |
||
320 | dataType: "html", |
||
321 | beforeSend: function () { |
||
322 | }, |
||
323 | success: function (data, textStatus, xhr) { |
||
324 | var help_content = $('<div id="temp_help">').html(data).find('a[href$="self.close();"]').hide().prev('br').hide().parent().html(); |
||
325 | oPopup_body.html(help_content); |
||
326 | }, |
||
327 | error: function (xhr, textStatus, errorThrown) { |
||
328 | oPopup_body.html(textStatus); |
||
329 | }, |
||
330 | statusCode: { |
||
331 | 500: function() { |
||
332 | if (sHeader == 'Login') |
||
333 | oPopup_body.html(banned_text); |
||
334 | else |
||
335 | oPopup_body.html('500 Internal Server Error'); |
||
336 | } |
||
337 | } |
||
338 | }); |
||
339 | return false; |
||
340 | } |
||
341 | |||
342 | // Create the popup menus for the top level/user menu area. |
||
343 | function smc_PopupMenu(oOptions) |
||
344 | { |
||
345 | this.opt = (typeof oOptions == 'object') ? oOptions : {}; |
||
346 | this.opt.menus = {}; |
||
347 | } |
||
348 | |||
349 | smc_PopupMenu.prototype.add = function (sItem, sUrl) |
||
350 | { |
||
351 | var $menu = $('#' + sItem + '_menu'), $item = $('#' + sItem + '_menu_top'); |
||
352 | if ($item.length == 0) |
||
353 | return; |
||
354 | |||
355 | this.opt.menus[sItem] = {open: false, loaded: false, sUrl: sUrl, itemObj: $item, menuObj: $menu }; |
||
356 | |||
357 | $item.click({obj: this}, function (e) { |
||
358 | e.preventDefault(); |
||
359 | |||
360 | e.data.obj.toggle(sItem); |
||
361 | }); |
||
362 | } |
||
363 | |||
364 | smc_PopupMenu.prototype.toggle = function (sItem) |
||
365 | { |
||
366 | if (!!this.opt.menus[sItem].open) |
||
367 | this.close(sItem); |
||
368 | else |
||
369 | this.open(sItem); |
||
370 | } |
||
371 | |||
372 | smc_PopupMenu.prototype.open = function (sItem) |
||
373 | { |
||
374 | this.closeAll(); |
||
375 | |||
376 | if (!this.opt.menus[sItem].loaded) |
||
377 | { |
||
378 | this.opt.menus[sItem].menuObj.html('<div class="loading">' + (typeof(ajax_notification_text) != null ? ajax_notification_text : '') + '</div>'); |
||
379 | this.opt.menus[sItem].menuObj.load(this.opt.menus[sItem].sUrl, function() { |
||
380 | if ($(this).hasClass('scrollable')) |
||
381 | $(this).customScrollbar({ |
||
382 | skin: "default-skin", |
||
383 | hScroll: false, |
||
384 | updateOnWindowResize: true |
||
385 | }); |
||
386 | }); |
||
387 | this.opt.menus[sItem].loaded = true; |
||
388 | } |
||
389 | |||
390 | this.opt.menus[sItem].menuObj.addClass('visible'); |
||
391 | this.opt.menus[sItem].itemObj.addClass('open'); |
||
392 | this.opt.menus[sItem].open = true; |
||
393 | |||
394 | // Now set up closing the menu if we click off. |
||
395 | $(document).on('click.menu', {obj: this}, function(e) { |
||
396 | if ($(e.target).closest(e.data.obj.opt.menus[sItem].menuObj.parent()).length) |
||
397 | return; |
||
398 | e.data.obj.closeAll(); |
||
399 | $(document).off('click.menu'); |
||
400 | }); |
||
401 | } |
||
402 | |||
403 | smc_PopupMenu.prototype.close = function (sItem) |
||
404 | { |
||
405 | this.opt.menus[sItem].menuObj.removeClass('visible'); |
||
406 | this.opt.menus[sItem].itemObj.removeClass('open'); |
||
407 | this.opt.menus[sItem].open = false; |
||
408 | $(document).off('click.menu'); |
||
409 | } |
||
410 | |||
411 | smc_PopupMenu.prototype.closeAll = function () |
||
412 | { |
||
413 | for (var prop in this.opt.menus) |
||
414 | if (!!this.opt.menus[prop].open) |
||
415 | this.close(prop); |
||
416 | } |
||
417 | |||
418 | // *** smc_Popup class. |
||
419 | function smc_Popup(oOptions) |
||
420 | { |
||
421 | this.opt = oOptions; |
||
422 | this.popup_id = this.opt.custom_id ? this.opt.custom_id : 'smf_popup'; |
||
423 | this.show(); |
||
424 | } |
||
425 | |||
426 | smc_Popup.prototype.show = function () |
||
427 | { |
||
428 | popup_class = 'popup_window ' + (this.opt.custom_class ? this.opt.custom_class : 'description'); |
||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
429 | if (this.opt.icon_class) |
||
430 | icon = '<span class="' + this.opt.icon_class + '"></span> '; |
||
0 ignored issues
–
show
|
|||
431 | else |
||
432 | icon = this.opt.icon ? '<img src="' + this.opt.icon + '" class="icon" alt=""> ' : ''; |
||
433 | |||
434 | // Create the div that will be shown |
||
435 | $('body').append('<div id="' + this.popup_id + '" class="popup_container"><div class="' + popup_class + '"><div class="catbg popup_heading"><a href="javascript:void(0);" class="generic_icons hide_popup"></a>' + icon + this.opt.heading + '</div><div class="popup_content">' + this.opt.content + '</div></div></div>'); |
||
436 | |||
437 | // Show it |
||
438 | this.popup_body = $('#' + this.popup_id).children('.popup_window'); |
||
439 | this.popup_body.parent().fadeIn(300); |
||
440 | |||
441 | // Trigger hide on escape or mouse click |
||
442 | var popup_instance = this; |
||
443 | $(document).mouseup(function (e) { |
||
444 | if ($('#' + popup_instance.popup_id).has(e.target).length === 0) |
||
445 | popup_instance.hide(); |
||
446 | }).keyup(function(e){ |
||
447 | if (e.keyCode == 27) |
||
448 | popup_instance.hide(); |
||
449 | }); |
||
450 | $('#' + this.popup_id).find('.hide_popup').click(function (){ return popup_instance.hide(); }); |
||
451 | |||
452 | return false; |
||
453 | } |
||
454 | |||
455 | smc_Popup.prototype.hide = function () |
||
456 | { |
||
457 | $('#' + this.popup_id).fadeOut(300, function(){ $(this).remove(); }); |
||
458 | |||
459 | return false; |
||
460 | } |
||
461 | |||
462 | // Remember the current position. |
||
463 | function storeCaret(oTextHandle) |
||
464 | { |
||
465 | // Only bother if it will be useful. |
||
466 | if ('createTextRange' in oTextHandle) |
||
467 | oTextHandle.caretPos = document.selection.createRange().duplicate(); |
||
468 | } |
||
469 | |||
470 | // Replaces the currently selected text with the passed text. |
||
471 | function replaceText(text, oTextHandle) |
||
472 | { |
||
473 | // Attempt to create a text range (IE). |
||
474 | if ('caretPos' in oTextHandle && 'createTextRange' in oTextHandle) |
||
475 | { |
||
476 | var caretPos = oTextHandle.caretPos; |
||
477 | |||
478 | caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? text + ' ' : text; |
||
479 | caretPos.select(); |
||
480 | } |
||
481 | // Mozilla text range replace. |
||
482 | else if ('selectionStart' in oTextHandle) |
||
483 | { |
||
484 | var begin = oTextHandle.value.substr(0, oTextHandle.selectionStart); |
||
485 | var end = oTextHandle.value.substr(oTextHandle.selectionEnd); |
||
486 | var scrollPos = oTextHandle.scrollTop; |
||
487 | |||
488 | oTextHandle.value = begin + text + end; |
||
489 | |||
490 | if (oTextHandle.setSelectionRange) |
||
491 | { |
||
492 | oTextHandle.focus(); |
||
493 | var goForward = is_opera ? text.match(/\n/g).length : 0; |
||
494 | oTextHandle.setSelectionRange(begin.length + text.length + goForward, begin.length + text.length + goForward); |
||
495 | } |
||
496 | oTextHandle.scrollTop = scrollPos; |
||
497 | } |
||
498 | // Just put it on the end. |
||
499 | else |
||
500 | { |
||
501 | oTextHandle.value += text; |
||
502 | oTextHandle.focus(oTextHandle.value.length - 1); |
||
503 | } |
||
504 | } |
||
505 | |||
506 | // Surrounds the selected text with text1 and text2. |
||
507 | function surroundText(text1, text2, oTextHandle) |
||
508 | { |
||
509 | // Can a text range be created? |
||
510 | if ('caretPos' in oTextHandle && 'createTextRange' in oTextHandle) |
||
511 | { |
||
512 | var caretPos = oTextHandle.caretPos, temp_length = caretPos.text.length; |
||
513 | |||
514 | caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? text1 + caretPos.text + text2 + ' ' : text1 + caretPos.text + text2; |
||
515 | |||
516 | if (temp_length == 0) |
||
517 | { |
||
518 | caretPos.moveStart('character', -text2.length); |
||
519 | caretPos.moveEnd('character', -text2.length); |
||
520 | caretPos.select(); |
||
521 | } |
||
522 | else |
||
523 | oTextHandle.focus(caretPos); |
||
524 | } |
||
525 | // Mozilla text range wrap. |
||
526 | else if ('selectionStart' in oTextHandle) |
||
527 | { |
||
528 | var begin = oTextHandle.value.substr(0, oTextHandle.selectionStart); |
||
529 | var selection = oTextHandle.value.substr(oTextHandle.selectionStart, oTextHandle.selectionEnd - oTextHandle.selectionStart); |
||
530 | var end = oTextHandle.value.substr(oTextHandle.selectionEnd); |
||
531 | var newCursorPos = oTextHandle.selectionStart; |
||
532 | var scrollPos = oTextHandle.scrollTop; |
||
533 | |||
534 | oTextHandle.value = begin + text1 + selection + text2 + end; |
||
535 | |||
536 | if (oTextHandle.setSelectionRange) |
||
537 | { |
||
538 | var goForward = is_opera ? text1.match(/\n/g).length : 0, goForwardAll = is_opera ? (text1 + text2).match(/\n/g).length : 0; |
||
539 | if (selection.length == 0) |
||
540 | oTextHandle.setSelectionRange(newCursorPos + text1.length + goForward, newCursorPos + text1.length + goForward); |
||
541 | else |
||
542 | oTextHandle.setSelectionRange(newCursorPos, newCursorPos + text1.length + selection.length + text2.length + goForwardAll); |
||
543 | oTextHandle.focus(); |
||
544 | } |
||
545 | oTextHandle.scrollTop = scrollPos; |
||
546 | } |
||
547 | // Just put them on the end, then. |
||
548 | else |
||
549 | { |
||
550 | oTextHandle.value += text1 + text2; |
||
551 | oTextHandle.focus(oTextHandle.value.length - 1); |
||
552 | } |
||
553 | } |
||
554 | |||
555 | // Checks if the passed input's value is nothing. |
||
556 | function isEmptyText(theField) |
||
557 | { |
||
558 | // Copy the value so changes can be made.. |
||
559 | if (typeof(theField) == 'string') |
||
560 | var theValue = theField; |
||
561 | else |
||
562 | var theValue = theField.value; |
||
563 | |||
564 | // Strip whitespace off the left side. |
||
565 | while (theValue.length > 0 && (theValue.charAt(0) == ' ' || theValue.charAt(0) == '\t')) |
||
566 | theValue = theValue.substring(1, theValue.length); |
||
567 | // Strip whitespace off the right side. |
||
568 | while (theValue.length > 0 && (theValue.charAt(theValue.length - 1) == ' ' || theValue.charAt(theValue.length - 1) == '\t')) |
||
569 | theValue = theValue.substring(0, theValue.length - 1); |
||
570 | |||
571 | if (theValue == '') |
||
572 | return true; |
||
573 | else |
||
574 | return false; |
||
575 | } |
||
576 | |||
577 | // Only allow form submission ONCE. |
||
578 | function submitonce(theform) |
||
579 | { |
||
580 | smf_formSubmitted = true; |
||
581 | |||
582 | // If there are any editors warn them submit is coming! |
||
583 | for (var i = 0; i < smf_editorArray.length; i++) |
||
584 | smf_editorArray[i].doSubmit(); |
||
585 | } |
||
586 | function submitThisOnce(oControl) |
||
587 | { |
||
588 | // oControl might also be a form. |
||
589 | var oForm = 'form' in oControl ? oControl.form : oControl; |
||
590 | |||
591 | var aTextareas = oForm.getElementsByTagName('textarea'); |
||
592 | for (var i = 0, n = aTextareas.length; i < n; i++) |
||
593 | aTextareas[i].readOnly = true; |
||
594 | |||
595 | return !smf_formSubmitted; |
||
596 | } |
||
597 | |||
598 | // Deprecated, as innerHTML is supported everywhere. |
||
599 | function setInnerHTML(oElement, sToValue) |
||
600 | { |
||
601 | oElement.innerHTML = sToValue; |
||
602 | } |
||
603 | |||
604 | function getInnerHTML(oElement) |
||
605 | { |
||
606 | return oElement.innerHTML; |
||
607 | } |
||
608 | |||
609 | // Set the "outer" HTML of an element. |
||
610 | function setOuterHTML(oElement, sToValue) |
||
611 | { |
||
612 | if ('outerHTML' in oElement) |
||
613 | oElement.outerHTML = sToValue; |
||
614 | else |
||
615 | { |
||
616 | var range = document.createRange(); |
||
617 | range.setStartBefore(oElement); |
||
618 | oElement.parentNode.replaceChild(range.createContextualFragment(sToValue), oElement); |
||
619 | } |
||
620 | } |
||
621 | |||
622 | // Checks for variable in theArray. |
||
623 | function in_array(variable, theArray) |
||
624 | { |
||
625 | for (var i in theArray) |
||
626 | if (theArray[i] == variable) |
||
627 | return true; |
||
628 | |||
629 | return false; |
||
630 | } |
||
631 | |||
632 | // Checks for variable in theArray. |
||
633 | function array_search(variable, theArray) |
||
634 | { |
||
635 | for (var i in theArray) |
||
636 | if (theArray[i] == variable) |
||
637 | return i; |
||
638 | |||
639 | return null; |
||
640 | } |
||
641 | |||
642 | // Find a specific radio button in its group and select it. |
||
643 | function selectRadioByName(oRadioGroup, sName) |
||
644 | { |
||
645 | if (!('length' in oRadioGroup)) |
||
646 | return oRadioGroup.checked = true; |
||
647 | |||
648 | for (var i = 0, n = oRadioGroup.length; i < n; i++) |
||
649 | if (oRadioGroup[i].value == sName) |
||
650 | return oRadioGroup[i].checked = true; |
||
651 | |||
652 | return false; |
||
653 | } |
||
654 | |||
655 | function selectAllRadio(oInvertCheckbox, oForm, sMask, sValue, bIgnoreDisabled) |
||
656 | { |
||
657 | for (var i = 0; i < oForm.length; i++) |
||
658 | if (oForm[i].name != undefined && oForm[i].name.substr(0, sMask.length) == sMask && oForm[i].value == sValue && (!oForm[i].disabled || (typeof(bIgnoreDisabled) == 'boolean' && bIgnoreDisabled))) |
||
659 | oForm[i].checked = true; |
||
660 | } |
||
661 | |||
662 | // Invert all checkboxes at once by clicking a single checkbox. |
||
663 | function invertAll(oInvertCheckbox, oForm, sMask, bIgnoreDisabled) |
||
664 | { |
||
665 | for (var i = 0; i < oForm.length; i++) |
||
666 | { |
||
667 | if (!('name' in oForm[i]) || (typeof(sMask) == 'string' && oForm[i].name.substr(0, sMask.length) != sMask && oForm[i].id.substr(0, sMask.length) != sMask)) |
||
668 | continue; |
||
669 | |||
670 | if (!oForm[i].disabled || (typeof(bIgnoreDisabled) == 'boolean' && bIgnoreDisabled)) |
||
671 | oForm[i].checked = oInvertCheckbox.checked; |
||
672 | } |
||
673 | } |
||
674 | |||
675 | // Keep the session alive - always! |
||
676 | var lastKeepAliveCheck = new Date().getTime(); |
||
677 | function smf_sessionKeepAlive() |
||
678 | { |
||
679 | var curTime = new Date().getTime(); |
||
680 | |||
681 | // Prevent a Firefox bug from hammering the server. |
||
682 | if (smf_scripturl && curTime - lastKeepAliveCheck > 900000) |
||
683 | { |
||
684 | var tempImage = new Image(); |
||
685 | tempImage.src = smf_prepareScriptUrl(smf_scripturl) + 'action=keepalive;time=' + curTime; |
||
686 | lastKeepAliveCheck = curTime; |
||
687 | } |
||
688 | |||
689 | window.setTimeout('smf_sessionKeepAlive();', 1200000); |
||
690 | } |
||
691 | window.setTimeout('smf_sessionKeepAlive();', 1200000); |
||
692 | |||
693 | // Set a theme option through javascript. |
||
694 | function smf_setThemeOption(theme_var, theme_value, theme_id, theme_cur_session_id, theme_cur_session_var, theme_additional_vars) |
||
695 | { |
||
696 | // Compatibility. |
||
697 | if (theme_cur_session_id == null) |
||
698 | theme_cur_session_id = smf_session_id; |
||
699 | if (typeof(theme_cur_session_var) == 'undefined') |
||
700 | theme_cur_session_var = 'sesc'; |
||
701 | |||
702 | if (theme_additional_vars == null) |
||
703 | theme_additional_vars = ''; |
||
704 | |||
705 | var tempImage = new Image(); |
||
706 | tempImage.src = smf_prepareScriptUrl(smf_scripturl) + 'action=jsoption;var=' + theme_var + ';val=' + theme_value + ';' + theme_cur_session_var + '=' + theme_cur_session_id + theme_additional_vars + (theme_id == null ? '' : '&th=' + theme_id) + ';time=' + (new Date().getTime()); |
||
707 | } |
||
708 | |||
709 | // Shows the page numbers by clicking the dots (in compact view). |
||
710 | function expandPages(spanNode, baseLink, firstPage, lastPage, perPage) |
||
711 | { |
||
712 | var replacement = '', i, oldLastPage = 0; |
||
713 | var perPageLimit = 50; |
||
714 | |||
715 | // Prevent too many pages to be loaded at once. |
||
716 | if ((lastPage - firstPage) / perPage > perPageLimit) |
||
717 | { |
||
718 | oldLastPage = lastPage; |
||
719 | lastPage = firstPage + perPageLimit * perPage; |
||
720 | } |
||
721 | |||
722 | // Calculate the new pages. |
||
723 | for (i = firstPage; i < lastPage; i += perPage) |
||
724 | replacement += baseLink.replace(/%1\$d/, i).replace(/%2\$s/, 1 + i / perPage).replace(/%%/g, '%'); |
||
725 | |||
726 | // Add the new page links. |
||
727 | $(spanNode).before(replacement); |
||
728 | |||
729 | if (oldLastPage) |
||
730 | // Access the raw DOM element so the native onclick event can be overridden. |
||
731 | spanNode.onclick = function () |
||
732 | { |
||
733 | expandPages(spanNode, baseLink, lastPage, oldLastPage, perPage); |
||
734 | }; |
||
735 | else |
||
736 | $(spanNode).remove(); |
||
737 | } |
||
738 | |||
739 | function smc_preCacheImage(sSrc) |
||
740 | { |
||
741 | if (!('smc_aCachedImages' in window)) |
||
742 | window.smc_aCachedImages = []; |
||
743 | |||
744 | if (!in_array(sSrc, window.smc_aCachedImages)) |
||
745 | { |
||
746 | var oImage = new Image(); |
||
747 | oImage.src = sSrc; |
||
748 | } |
||
749 | } |
||
750 | |||
751 | |||
752 | // *** smc_Cookie class. |
||
753 | function smc_Cookie(oOptions) |
||
754 | { |
||
755 | this.opt = oOptions; |
||
756 | this.oCookies = {}; |
||
757 | this.init(); |
||
758 | } |
||
759 | |||
760 | smc_Cookie.prototype.init = function() |
||
761 | { |
||
762 | if ('cookie' in document && document.cookie != '') |
||
763 | { |
||
764 | var aCookieList = document.cookie.split(';'); |
||
765 | for (var i = 0, n = aCookieList.length; i < n; i++) |
||
766 | { |
||
767 | var aNameValuePair = aCookieList[i].split('='); |
||
768 | this.oCookies[aNameValuePair[0].replace(/^\s+|\s+$/g, '')] = decodeURIComponent(aNameValuePair[1]); |
||
769 | } |
||
770 | } |
||
771 | } |
||
772 | |||
773 | smc_Cookie.prototype.get = function(sKey) |
||
774 | { |
||
775 | return sKey in this.oCookies ? this.oCookies[sKey] : null; |
||
776 | } |
||
777 | |||
778 | smc_Cookie.prototype.set = function(sKey, sValue) |
||
779 | { |
||
780 | document.cookie = sKey + '=' + encodeURIComponent(sValue); |
||
781 | } |
||
782 | |||
783 | |||
784 | // *** smc_Toggle class. |
||
785 | function smc_Toggle(oOptions) |
||
786 | { |
||
787 | this.opt = oOptions; |
||
788 | this.bCollapsed = false; |
||
789 | this.oCookie = null; |
||
790 | this.init(); |
||
791 | } |
||
792 | |||
793 | smc_Toggle.prototype.init = function () |
||
794 | { |
||
795 | // The master switch can disable this toggle fully. |
||
796 | if ('bToggleEnabled' in this.opt && !this.opt.bToggleEnabled) |
||
797 | return; |
||
798 | |||
799 | // If cookies are enabled and they were set, override the initial state. |
||
800 | if ('oCookieOptions' in this.opt && this.opt.oCookieOptions.bUseCookie) |
||
801 | { |
||
802 | // Initialize the cookie handler. |
||
803 | this.oCookie = new smc_Cookie({}); |
||
804 | |||
805 | // Check if the cookie is set. |
||
806 | var cookieValue = this.oCookie.get(this.opt.oCookieOptions.sCookieName) |
||
807 | if (cookieValue != null) |
||
808 | this.opt.bCurrentlyCollapsed = cookieValue == '1'; |
||
809 | } |
||
810 | |||
811 | // Initialize the images to be clickable. |
||
812 | if ('aSwapImages' in this.opt) |
||
813 | { |
||
814 | for (var i = 0, n = this.opt.aSwapImages.length; i < n; i++) |
||
815 | { |
||
816 | this.opt.aSwapImages[i].isCSS = (typeof this.opt.aSwapImages[i].srcCollapsed == 'undefined'); |
||
817 | if (this.opt.aSwapImages[i].isCSS) |
||
818 | { |
||
819 | if (!this.opt.aSwapImages[i].cssCollapsed) |
||
820 | this.opt.aSwapImages[i].cssCollapsed = 'toggle_down'; |
||
821 | if (!this.opt.aSwapImages[i].cssExpanded) |
||
822 | this.opt.aSwapImages[i].cssExpanded = 'toggle_up'; |
||
823 | } |
||
824 | else |
||
825 | { |
||
826 | // Preload the collapsed image. |
||
827 | smc_preCacheImage(this.opt.aSwapImages[i].srcCollapsed); |
||
828 | } |
||
829 | |||
830 | // Display the image in case it was hidden. |
||
831 | $('#' + this.opt.aSwapImages[i].sId).show(); |
||
832 | var oImage = document.getElementById(this.opt.aSwapImages[i].sId); |
||
833 | if (typeof(oImage) == 'object' && oImage != null) |
||
834 | { |
||
835 | oImage.instanceRef = this; |
||
836 | oImage.onclick = function () { |
||
837 | this.instanceRef.toggle(); |
||
838 | this.blur(); |
||
839 | } |
||
840 | oImage.style.cursor = 'pointer'; |
||
841 | } |
||
842 | } |
||
843 | } |
||
844 | |||
845 | // Initialize links. |
||
846 | if ('aSwapLinks' in this.opt) |
||
847 | { |
||
848 | for (var i = 0, n = this.opt.aSwapLinks.length; i < n; i++) |
||
849 | { |
||
850 | var oLink = document.getElementById(this.opt.aSwapLinks[i].sId); |
||
851 | if (typeof(oLink) == 'object' && oLink != null) |
||
852 | { |
||
853 | // Display the link in case it was hidden. |
||
854 | if (oLink.style.display == 'none') |
||
855 | oLink.style.display = ''; |
||
856 | |||
857 | oLink.instanceRef = this; |
||
858 | oLink.onclick = function () { |
||
859 | this.instanceRef.toggle(); |
||
860 | this.blur(); |
||
861 | return false; |
||
862 | } |
||
863 | } |
||
864 | } |
||
865 | } |
||
866 | |||
867 | // If the init state is set to be collapsed, collapse it. |
||
868 | if (this.opt.bCurrentlyCollapsed) |
||
869 | this.changeState(true, true); |
||
870 | } |
||
871 | |||
872 | // Collapse or expand the section. |
||
873 | smc_Toggle.prototype.changeState = function(bCollapse, bInit) |
||
874 | { |
||
875 | // Default bInit to false. |
||
876 | bInit = typeof(bInit) == 'undefined' ? false : true; |
||
877 | |||
878 | // Handle custom function hook before collapse. |
||
879 | if (!bInit && bCollapse && 'funcOnBeforeCollapse' in this.opt) |
||
880 | { |
||
881 | this.tmpMethod = this.opt.funcOnBeforeCollapse; |
||
882 | this.tmpMethod(); |
||
883 | delete this.tmpMethod; |
||
884 | } |
||
885 | |||
886 | // Handle custom function hook before expand. |
||
887 | else if (!bInit && !bCollapse && 'funcOnBeforeExpand' in this.opt) |
||
888 | { |
||
889 | this.tmpMethod = this.opt.funcOnBeforeExpand; |
||
890 | this.tmpMethod(); |
||
891 | delete this.tmpMethod; |
||
892 | } |
||
893 | |||
894 | // Loop through all the images that need to be toggled. |
||
895 | if ('aSwapImages' in this.opt) |
||
896 | { |
||
897 | for (var i = 0, n = this.opt.aSwapImages.length; i < n; i++) |
||
898 | { |
||
899 | if (this.opt.aSwapImages[i].isCSS) |
||
900 | { |
||
901 | $('#' + this.opt.aSwapImages[i].sId).toggleClass(this.opt.aSwapImages[i].cssCollapsed, bCollapse).toggleClass(this.opt.aSwapImages[i].cssExpanded, !bCollapse).attr('title', bCollapse ? this.opt.aSwapImages[i].altCollapsed : this.opt.aSwapImages[i].altExpanded); |
||
902 | } |
||
903 | else |
||
904 | { |
||
905 | var oImage = document.getElementById(this.opt.aSwapImages[i].sId); |
||
906 | if (typeof(oImage) == 'object' && oImage != null) |
||
907 | { |
||
908 | // Only (re)load the image if it's changed. |
||
909 | var sTargetSource = bCollapse ? this.opt.aSwapImages[i].srcCollapsed : this.opt.aSwapImages[i].srcExpanded; |
||
910 | if (oImage.src != sTargetSource) |
||
911 | oImage.src = sTargetSource; |
||
912 | |||
913 | oImage.alt = oImage.title = bCollapse ? this.opt.aSwapImages[i].altCollapsed : this.opt.aSwapImages[i].altExpanded; |
||
914 | } |
||
915 | } |
||
916 | } |
||
917 | } |
||
918 | |||
919 | // Loop through all the links that need to be toggled. |
||
920 | if ('aSwapLinks' in this.opt) |
||
921 | { |
||
922 | for (var i = 0, n = this.opt.aSwapLinks.length; i < n; i++) |
||
923 | { |
||
924 | var oLink = document.getElementById(this.opt.aSwapLinks[i].sId); |
||
925 | if (typeof(oLink) == 'object' && oLink != null) |
||
926 | setInnerHTML(oLink, bCollapse ? this.opt.aSwapLinks[i].msgCollapsed : this.opt.aSwapLinks[i].msgExpanded); |
||
927 | } |
||
928 | } |
||
929 | |||
930 | // Now go through all the sections to be collapsed. |
||
931 | for (var i = 0, n = this.opt.aSwappableContainers.length; i < n; i++) |
||
932 | { |
||
933 | if (this.opt.aSwappableContainers[i] == null) |
||
934 | continue; |
||
935 | |||
936 | var oContainer = document.getElementById(this.opt.aSwappableContainers[i]); |
||
937 | if (typeof(oContainer) == 'object' && oContainer != null) |
||
938 | { |
||
939 | if (!!this.opt.bNoAnimate || bInit) |
||
940 | { |
||
941 | $(oContainer).toggle(!bCollapse); |
||
942 | } |
||
943 | else |
||
944 | { |
||
945 | if (bCollapse) |
||
946 | { |
||
947 | if (this.opt.aHeader != null && this.opt.aHeader.hasClass('cat_bar')) |
||
948 | $(this.opt.aHeader).addClass('collapsed'); |
||
949 | $(oContainer).slideUp(); |
||
950 | } |
||
951 | else |
||
952 | { |
||
953 | if (this.opt.aHeader != null && this.opt.aHeader.hasClass('cat_bar')) |
||
954 | $(this.opt.aHeader).removeClass('collapsed'); |
||
955 | $(oContainer).slideDown(); |
||
956 | } |
||
957 | } |
||
958 | } |
||
959 | } |
||
960 | |||
961 | // Update the new state. |
||
962 | this.bCollapsed = bCollapse; |
||
963 | |||
964 | // Update the cookie, if desired. |
||
965 | if ('oCookieOptions' in this.opt && this.opt.oCookieOptions.bUseCookie) |
||
966 | this.oCookie.set(this.opt.oCookieOptions.sCookieName, this.bCollapsed | 0); |
||
967 | |||
968 | if (!bInit && 'oThemeOptions' in this.opt && this.opt.oThemeOptions.bUseThemeSettings) |
||
969 | smf_setThemeOption(this.opt.oThemeOptions.sOptionName, this.bCollapsed | 0, 'sThemeId' in this.opt.oThemeOptions ? this.opt.oThemeOptions.sThemeId : null, smf_session_id, smf_session_var, 'sAdditionalVars' in this.opt.oThemeOptions ? this.opt.oThemeOptions.sAdditionalVars : null); |
||
970 | } |
||
971 | |||
972 | smc_Toggle.prototype.toggle = function() |
||
973 | { |
||
974 | // Change the state by reversing the current state. |
||
975 | this.changeState(!this.bCollapsed); |
||
976 | } |
||
977 | |||
978 | |||
979 | function ajax_indicator(turn_on) |
||
980 | { |
||
981 | if (ajax_indicator_ele == null) |
||
982 | { |
||
983 | ajax_indicator_ele = document.getElementById('ajax_in_progress'); |
||
984 | |||
985 | if (ajax_indicator_ele == null && typeof(ajax_notification_text) != null) |
||
986 | { |
||
987 | create_ajax_indicator_ele(); |
||
988 | } |
||
989 | } |
||
990 | |||
991 | if (ajax_indicator_ele != null) |
||
992 | { |
||
993 | ajax_indicator_ele.style.display = turn_on ? 'block' : 'none'; |
||
994 | } |
||
995 | } |
||
996 | |||
997 | function create_ajax_indicator_ele() |
||
998 | { |
||
999 | // Create the div for the indicator. |
||
1000 | ajax_indicator_ele = document.createElement('div'); |
||
1001 | |||
1002 | // Set the id so it'll load the style properly. |
||
1003 | ajax_indicator_ele.id = 'ajax_in_progress'; |
||
1004 | |||
1005 | // Set the text. (Note: You MUST append here and not overwrite.) |
||
1006 | ajax_indicator_ele.innerHTML += ajax_notification_text; |
||
1007 | |||
1008 | // Finally attach the element to the body. |
||
1009 | document.body.appendChild(ajax_indicator_ele); |
||
1010 | } |
||
1011 | |||
1012 | function createEventListener(oTarget) |
||
1013 | { |
||
1014 | if (!('addEventListener' in oTarget)) |
||
1015 | { |
||
1016 | if (oTarget.attachEvent) |
||
1017 | { |
||
1018 | oTarget.addEventListener = function (sEvent, funcHandler, bCapture) { |
||
1019 | oTarget.attachEvent('on' + sEvent, funcHandler); |
||
1020 | } |
||
1021 | oTarget.removeEventListener = function (sEvent, funcHandler, bCapture) { |
||
1022 | oTarget.detachEvent('on' + sEvent, funcHandler); |
||
1023 | } |
||
1024 | } |
||
1025 | else |
||
1026 | { |
||
1027 | oTarget.addEventListener = function (sEvent, funcHandler, bCapture) { |
||
1028 | oTarget['on' + sEvent] = funcHandler; |
||
1029 | } |
||
1030 | oTarget.removeEventListener = function (sEvent, funcHandler, bCapture) { |
||
1031 | oTarget['on' + sEvent] = null; |
||
1032 | } |
||
1033 | } |
||
1034 | } |
||
1035 | } |
||
1036 | |||
1037 | // This function will retrieve the contents needed for the jump to boxes. |
||
1038 | function grabJumpToContent(elem) |
||
1039 | { |
||
1040 | var oXMLDoc = getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + 'action=xmlhttp;sa=jumpto;xml'); |
||
1041 | var aBoardsAndCategories = []; |
||
1042 | |||
1043 | ajax_indicator(true); |
||
1044 | |||
1045 | oXMLDoc.done(function(data, textStatus, jqXHR){ |
||
1046 | |||
1047 | var items = $(data).find('item'); |
||
1048 | items.each(function(i) { |
||
1049 | aBoardsAndCategories[i] = { |
||
1050 | id: parseInt($(this).attr('id')), |
||
1051 | isCategory: $(this).attr('type') == 'category', |
||
1052 | name: this.firstChild.nodeValue.removeEntities(), |
||
1053 | is_current: false, |
||
1054 | childLevel: parseInt($(this).attr('childlevel')) |
||
1055 | } |
||
1056 | }); |
||
1057 | |||
1058 | ajax_indicator(false); |
||
1059 | |||
1060 | for (var i = 0, n = aJumpTo.length; i < n; i++) |
||
1061 | { |
||
1062 | aJumpTo[i].fillSelect(aBoardsAndCategories); |
||
1063 | } |
||
1064 | }); |
||
1065 | } |
||
1066 | |||
1067 | // This'll contain all JumpTo objects on the page. |
||
1068 | var aJumpTo = new Array(); |
||
1069 | |||
1070 | // *** JumpTo class. |
||
1071 | function JumpTo(oJumpToOptions) |
||
1072 | { |
||
1073 | this.opt = oJumpToOptions; |
||
1074 | this.dropdownList = null; |
||
1075 | this.showSelect(); |
||
1076 | |||
1077 | // Register a change event after the select has been created. |
||
1078 | $('#' + this.opt.sContainerId).one('mouseenter', function() { |
||
1079 | grabJumpToContent(this); |
||
1080 | }); |
||
1081 | } |
||
1082 | |||
1083 | // Show the initial select box (onload). Method of the JumpTo class. |
||
1084 | JumpTo.prototype.showSelect = function () |
||
1085 | { |
||
1086 | var sChildLevelPrefix = ''; |
||
1087 | for (var i = this.opt.iCurBoardChildLevel; i > 0; i--) |
||
1088 | sChildLevelPrefix += this.opt.sBoardChildLevelIndicator; |
||
1089 | setInnerHTML(document.getElementById(this.opt.sContainerId), this.opt.sJumpToTemplate.replace(/%select_id%/, this.opt.sContainerId + '_select').replace(/%dropdown_list%/, '<select ' + (this.opt.bDisabled == true ? 'disabled ' : '') + (this.opt.sClassName != undefined ? 'class="' + this.opt.sClassName + '" ' : '') + 'name="' + (this.opt.sCustomName != undefined ? this.opt.sCustomName : this.opt.sContainerId + '_select') + '" id="' + this.opt.sContainerId + '_select"><option value="' + (this.opt.bNoRedirect != undefined && this.opt.bNoRedirect == true ? this.opt.iCurBoardId : '?board=' + this.opt.iCurBoardId + '.0') + '">' + sChildLevelPrefix + this.opt.sBoardPrefix + this.opt.sCurBoardName.removeEntities() + '</option></select> ' + (this.opt.sGoButtonLabel != undefined ? '<input type="button" class="button" value="' + this.opt.sGoButtonLabel + '" onclick="window.location.href = \'' + smf_prepareScriptUrl(smf_scripturl) + 'board=' + this.opt.iCurBoardId + '.0\';">' : ''))); |
||
1090 | this.dropdownList = document.getElementById(this.opt.sContainerId + '_select'); |
||
1091 | } |
||
1092 | |||
1093 | // Fill the jump to box with entries. Method of the JumpTo class. |
||
1094 | JumpTo.prototype.fillSelect = function (aBoardsAndCategories) |
||
1095 | { |
||
1096 | var iIndexPointer = 0; |
||
1097 | |||
1098 | // Create an option that'll be above and below the category. |
||
1099 | var oDashOption = document.createElement('option'); |
||
1100 | oDashOption.appendChild(document.createTextNode(this.opt.sCatSeparator)); |
||
1101 | oDashOption.disabled = 'disabled'; |
||
1102 | oDashOption.value = ''; |
||
1103 | |||
1104 | if ('onbeforeactivate' in document) |
||
1105 | this.dropdownList.onbeforeactivate = null; |
||
1106 | else |
||
1107 | this.dropdownList.onfocus = null; |
||
1108 | |||
1109 | if (this.opt.bNoRedirect) |
||
1110 | this.dropdownList.options[0].disabled = 'disabled'; |
||
1111 | |||
1112 | // Create a document fragment that'll allowing inserting big parts at once. |
||
1113 | var oListFragment = document.createDocumentFragment(); |
||
1114 | |||
1115 | // Loop through all items to be added. |
||
1116 | for (var i = 0, n = aBoardsAndCategories.length; i < n; i++) |
||
1117 | { |
||
1118 | var j, sChildLevelPrefix, oOption; |
||
1119 | |||
1120 | // If we've reached the currently selected board add all items so far. |
||
1121 | if (!aBoardsAndCategories[i].isCategory && aBoardsAndCategories[i].id == this.opt.iCurBoardId) |
||
1122 | { |
||
1123 | this.dropdownList.insertBefore(oListFragment, this.dropdownList.options[0]); |
||
1124 | oListFragment = document.createDocumentFragment(); |
||
1125 | continue; |
||
1126 | } |
||
1127 | |||
1128 | if (aBoardsAndCategories[i].isCategory) |
||
1129 | oListFragment.appendChild(oDashOption.cloneNode(true)); |
||
1130 | else |
||
1131 | for (j = aBoardsAndCategories[i].childLevel, sChildLevelPrefix = ''; j > 0; j--) |
||
1132 | sChildLevelPrefix += this.opt.sBoardChildLevelIndicator; |
||
1133 | |||
1134 | oOption = document.createElement('option'); |
||
1135 | oOption.appendChild(document.createTextNode((aBoardsAndCategories[i].isCategory ? this.opt.sCatPrefix : sChildLevelPrefix + this.opt.sBoardPrefix) + aBoardsAndCategories[i].name)); |
||
0 ignored issues
–
show
|
|||
1136 | if (!this.opt.bNoRedirect) |
||
1137 | oOption.value = aBoardsAndCategories[i].isCategory ? '#c' + aBoardsAndCategories[i].id : '?board=' + aBoardsAndCategories[i].id + '.0'; |
||
1138 | else |
||
1139 | { |
||
1140 | if (aBoardsAndCategories[i].isCategory) |
||
1141 | oOption.disabled = 'disabled'; |
||
1142 | else |
||
1143 | oOption.value = aBoardsAndCategories[i].id; |
||
1144 | } |
||
1145 | oListFragment.appendChild(oOption); |
||
1146 | |||
1147 | if (aBoardsAndCategories[i].isCategory) |
||
1148 | oListFragment.appendChild(oDashOption.cloneNode(true)); |
||
1149 | } |
||
1150 | |||
1151 | // Add the remaining items after the currently selected item. |
||
1152 | this.dropdownList.appendChild(oListFragment); |
||
1153 | |||
1154 | // Add an onchange action |
||
1155 | if (!this.opt.bNoRedirect) |
||
1156 | this.dropdownList.onchange = function() { |
||
1157 | if (this.selectedIndex > 0 && this.options[this.selectedIndex].value) |
||
1158 | window.location.href = smf_scripturl + this.options[this.selectedIndex].value.substr(smf_scripturl.indexOf('?') == -1 || this.options[this.selectedIndex].value.substr(0, 1) != '?' ? 0 : 1); |
||
1159 | } |
||
1160 | } |
||
1161 | |||
1162 | // A global array containing all IconList objects. |
||
1163 | var aIconLists = new Array(); |
||
1164 | |||
1165 | // *** IconList object. |
||
1166 | function IconList(oOptions) |
||
1167 | { |
||
1168 | if (!window.XMLHttpRequest) |
||
1169 | return; |
||
1170 | |||
1171 | this.opt = oOptions; |
||
1172 | this.bListLoaded = false; |
||
1173 | this.oContainerDiv = null; |
||
1174 | this.funcMousedownHandler = null; |
||
1175 | this.funcParent = this; |
||
1176 | this.iCurMessageId = 0; |
||
1177 | this.iCurTimeout = 0; |
||
1178 | |||
1179 | // Add backwards compatibility with old themes. |
||
1180 | if (!('sSessionVar' in this.opt)) |
||
1181 | this.opt.sSessionVar = 'sesc'; |
||
1182 | |||
1183 | this.initIcons(); |
||
1184 | } |
||
1185 | |||
1186 | // Replace all message icons by icons with hoverable and clickable div's. |
||
1187 | IconList.prototype.initIcons = function () |
||
1188 | { |
||
1189 | for (var i = document.images.length - 1, iPrefixLength = this.opt.sIconIdPrefix.length; i >= 0; i--) |
||
1190 | if (document.images[i].id.substr(0, iPrefixLength) == this.opt.sIconIdPrefix) |
||
1191 | setOuterHTML(document.images[i], '<div title="' + this.opt.sLabelIconList + '" onclick="' + this.opt.sBackReference + '.openPopup(this, ' + document.images[i].id.substr(iPrefixLength) + ')" onmouseover="' + this.opt.sBackReference + '.onBoxHover(this, true)" onmouseout="' + this.opt.sBackReference + '.onBoxHover(this, false)" style="background: ' + this.opt.sBoxBackground + '; cursor: pointer; padding: 3px; text-align: center;"><img src="' + document.images[i].src + '" alt="' + document.images[i].alt + '" id="' + document.images[i].id + '"></div>'); |
||
1192 | } |
||
1193 | |||
1194 | // Event for the mouse hovering over the original icon. |
||
1195 | IconList.prototype.onBoxHover = function (oDiv, bMouseOver) |
||
1196 | { |
||
1197 | oDiv.style.border = bMouseOver ? this.opt.iBoxBorderWidthHover + 'px solid ' + this.opt.sBoxBorderColorHover : ''; |
||
1198 | oDiv.style.background = bMouseOver ? this.opt.sBoxBackgroundHover : this.opt.sBoxBackground; |
||
1199 | oDiv.style.padding = bMouseOver ? (3 - this.opt.iBoxBorderWidthHover) + 'px' : '3px' |
||
1200 | } |
||
1201 | |||
1202 | // Show the list of icons after the user clicked the original icon. |
||
1203 | IconList.prototype.openPopup = function (oDiv, iMessageId) |
||
1204 | { |
||
1205 | this.iCurMessageId = iMessageId; |
||
1206 | |||
1207 | if (!this.bListLoaded && this.oContainerDiv == null) |
||
1208 | { |
||
1209 | // Create a container div. |
||
1210 | this.oContainerDiv = document.createElement('div'); |
||
1211 | this.oContainerDiv.id = 'iconList'; |
||
1212 | this.oContainerDiv.style.display = 'none'; |
||
1213 | this.oContainerDiv.style.cursor = 'pointer'; |
||
1214 | this.oContainerDiv.style.position = 'absolute'; |
||
1215 | this.oContainerDiv.style.background = this.opt.sContainerBackground; |
||
1216 | this.oContainerDiv.style.border = this.opt.sContainerBorder; |
||
1217 | this.oContainerDiv.style.padding = '6px 0px'; |
||
1218 | document.body.appendChild(this.oContainerDiv); |
||
1219 | |||
1220 | // Start to fetch its contents. |
||
1221 | ajax_indicator(true); |
||
1222 | sendXMLDocument.call(this, smf_prepareScriptUrl(smf_scripturl) + 'action=xmlhttp;sa=messageicons;board=' + this.opt.iBoardId + ';xml', '', this.onIconsReceived); |
||
1223 | |||
1224 | createEventListener(document.body); |
||
1225 | } |
||
1226 | |||
1227 | // Set the position of the container. |
||
1228 | var aPos = smf_itemPos(oDiv); |
||
1229 | |||
1230 | this.oContainerDiv.style.top = (aPos[1] + oDiv.offsetHeight) + 'px'; |
||
1231 | this.oContainerDiv.style.left = (aPos[0] - 1) + 'px'; |
||
1232 | this.oClickedIcon = oDiv; |
||
1233 | |||
1234 | if (this.bListLoaded) |
||
1235 | this.oContainerDiv.style.display = 'block'; |
||
1236 | |||
1237 | document.body.addEventListener('mousedown', this.onWindowMouseDown, false); |
||
1238 | } |
||
1239 | |||
1240 | // Setup the list of icons once it is received through xmlHTTP. |
||
1241 | IconList.prototype.onIconsReceived = function (oXMLDoc) |
||
1242 | { |
||
1243 | var icons = oXMLDoc.getElementsByTagName('smf')[0].getElementsByTagName('icon'); |
||
1244 | var sItems = ''; |
||
1245 | |||
1246 | for (var i = 0, n = icons.length; i < n; i++) |
||
1247 | sItems += '<span onmouseover="' + this.opt.sBackReference + '.onItemHover(this, true)" onmouseout="' + this.opt.sBackReference + '.onItemHover(this, false);" onmousedown="' + this.opt.sBackReference + '.onItemMouseDown(this, \'' + icons[i].getAttribute('value') + '\');" style="padding: 2px 3px; line-height: 20px; border: ' + this.opt.sItemBorder + '; background: ' + this.opt.sItemBackground + '"><img src="' + icons[i].getAttribute('url') + '" alt="' + icons[i].getAttribute('name') + '" title="' + icons[i].firstChild.nodeValue + '" style="vertical-align: middle"></span>'; |
||
1248 | |||
1249 | setInnerHTML(this.oContainerDiv, sItems); |
||
1250 | this.oContainerDiv.style.display = 'block'; |
||
1251 | this.bListLoaded = true; |
||
1252 | |||
1253 | if (is_ie) |
||
1254 | this.oContainerDiv.style.width = this.oContainerDiv.clientWidth + 'px'; |
||
1255 | |||
1256 | ajax_indicator(false); |
||
1257 | } |
||
1258 | |||
1259 | // Event handler for hovering over the icons. |
||
1260 | IconList.prototype.onItemHover = function (oDiv, bMouseOver) |
||
1261 | { |
||
1262 | oDiv.style.background = bMouseOver ? this.opt.sItemBackgroundHover : this.opt.sItemBackground; |
||
1263 | oDiv.style.border = bMouseOver ? this.opt.sItemBorderHover : this.opt.sItemBorder; |
||
1264 | if (this.iCurTimeout != 0) |
||
1265 | window.clearTimeout(this.iCurTimeout); |
||
1266 | if (bMouseOver) |
||
1267 | this.onBoxHover(this.oClickedIcon, true); |
||
1268 | else |
||
1269 | this.iCurTimeout = window.setTimeout(this.opt.sBackReference + '.collapseList();', 500); |
||
1270 | } |
||
1271 | |||
1272 | // Event handler for clicking on one of the icons. |
||
1273 | IconList.prototype.onItemMouseDown = function (oDiv, sNewIcon) |
||
1274 | { |
||
1275 | if (this.iCurMessageId != 0) |
||
1276 | { |
||
1277 | ajax_indicator(true); |
||
1278 | this.tmpMethod = getXMLDocument; |
||
1279 | var oXMLDoc = this.tmpMethod(smf_prepareScriptUrl(smf_scripturl) + 'action=jsmodify;topic=' + this.opt.iTopicId + ';msg=' + this.iCurMessageId + ';' + smf_session_var + '=' + smf_session_id + ';icon=' + sNewIcon + ';xml'), |
||
1280 | oThis = this; |
||
1281 | delete this.tmpMethod; |
||
1282 | ajax_indicator(false); |
||
1283 | |||
1284 | oXMLDoc.done(function(data, textStatus, jqXHR){ |
||
1285 | oMessage = $(data).find('message') |
||
0 ignored issues
–
show
|
|||
1286 | curMessageId = oMessage.attr('id').replace( /^\D+/g, ''); |
||
0 ignored issues
–
show
|
|||
1287 | |||
1288 | if (oMessage.find('error').length == 0) |
||
1289 | { |
||
1290 | if (oThis.opt.bShowModify && oMessage.find('modified').length != 0) |
||
1291 | $('#modified_' + curMessageId).html(oMessage.find('modified').text()); |
||
1292 | |||
1293 | oThis.oClickedIcon.getElementsByTagName('img')[0].src = oDiv.getElementsByTagName('img')[0].src; |
||
1294 | } |
||
1295 | }); |
||
1296 | } |
||
1297 | } |
||
1298 | |||
1299 | // Event handler for clicking outside the list (will make the list disappear). |
||
1300 | IconList.prototype.onWindowMouseDown = function () |
||
1301 | { |
||
1302 | for (var i = aIconLists.length - 1; i >= 0; i--) |
||
1303 | { |
||
1304 | aIconLists[i].funcParent.tmpMethod = aIconLists[i].collapseList; |
||
1305 | aIconLists[i].funcParent.tmpMethod(); |
||
1306 | delete aIconLists[i].funcParent.tmpMethod; |
||
1307 | } |
||
1308 | } |
||
1309 | |||
1310 | // Collapse the list of icons. |
||
1311 | IconList.prototype.collapseList = function() |
||
1312 | { |
||
1313 | this.onBoxHover(this.oClickedIcon, false); |
||
1314 | this.oContainerDiv.style.display = 'none'; |
||
1315 | this.iCurMessageId = 0; |
||
1316 | document.body.removeEventListener('mousedown', this.onWindowMouseDown, false); |
||
1317 | } |
||
1318 | |||
1319 | // Handy shortcuts for getting the mouse position on the screen - only used for IE at the moment. |
||
1320 | function smf_mousePose(oEvent) |
||
1321 | { |
||
1322 | var x = 0; |
||
1323 | var y = 0; |
||
1324 | |||
1325 | if (oEvent.pageX) |
||
1326 | { |
||
1327 | y = oEvent.pageY; |
||
1328 | x = oEvent.pageX; |
||
1329 | } |
||
1330 | else if (oEvent.clientX) |
||
1331 | { |
||
1332 | x = oEvent.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); |
||
1333 | y = oEvent.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); |
||
1334 | } |
||
1335 | |||
1336 | return [x, y]; |
||
1337 | } |
||
1338 | |||
1339 | // Short function for finding the actual position of an item. |
||
1340 | function smf_itemPos(itemHandle) |
||
1341 | { |
||
1342 | var itemX = 0; |
||
1343 | var itemY = 0; |
||
1344 | |||
1345 | if ('offsetParent' in itemHandle) |
||
1346 | { |
||
1347 | itemX = itemHandle.offsetLeft; |
||
1348 | itemY = itemHandle.offsetTop; |
||
1349 | while (itemHandle.offsetParent && typeof(itemHandle.offsetParent) == 'object') |
||
1350 | { |
||
1351 | itemHandle = itemHandle.offsetParent; |
||
1352 | itemX += itemHandle.offsetLeft; |
||
1353 | itemY += itemHandle.offsetTop; |
||
1354 | } |
||
1355 | } |
||
1356 | else if ('x' in itemHandle) |
||
1357 | { |
||
1358 | itemX = itemHandle.x; |
||
1359 | itemY = itemHandle.y; |
||
1360 | } |
||
1361 | |||
1362 | return [itemX, itemY]; |
||
1363 | } |
||
1364 | |||
1365 | // This function takes the script URL and prepares it to allow the query string to be appended to it. |
||
1366 | function smf_prepareScriptUrl(sUrl) |
||
1367 | { |
||
1368 | return sUrl.indexOf('?') == -1 ? sUrl + '?' : sUrl + (sUrl.charAt(sUrl.length - 1) == '?' || sUrl.charAt(sUrl.length - 1) == '&' || sUrl.charAt(sUrl.length - 1) == ';' ? '' : ';'); |
||
1369 | } |
||
1370 | |||
1371 | var aOnloadEvents = new Array(); |
||
1372 | function addLoadEvent(fNewOnload) |
||
1373 | { |
||
1374 | // If there's no event set, just set this one |
||
1375 | if (typeof(fNewOnload) == 'function' && (!('onload' in window) || typeof(window.onload) != 'function')) |
||
1376 | window.onload = fNewOnload; |
||
1377 | |||
1378 | // If there's just one event, setup the array. |
||
1379 | else if (aOnloadEvents.length == 0) |
||
1380 | { |
||
1381 | aOnloadEvents[0] = window.onload; |
||
1382 | aOnloadEvents[1] = fNewOnload; |
||
1383 | window.onload = function() { |
||
1384 | for (var i = 0, n = aOnloadEvents.length; i < n; i++) |
||
1385 | { |
||
1386 | if (typeof(aOnloadEvents[i]) == 'function') |
||
1387 | aOnloadEvents[i](); |
||
1388 | else if (typeof(aOnloadEvents[i]) == 'string') |
||
1389 | eval(aOnloadEvents[i]); |
||
0 ignored issues
–
show
|
|||
1390 | } |
||
1391 | } |
||
1392 | } |
||
1393 | |||
1394 | // This isn't the first event function, add it to the list. |
||
1395 | else |
||
1396 | aOnloadEvents[aOnloadEvents.length] = fNewOnload; |
||
1397 | } |
||
1398 | |||
1399 | // Get the text in a code tag. |
||
1400 | function smfSelectText(oCurElement, bActOnElement) |
||
1401 | { |
||
1402 | // The place we're looking for is one div up, and next door - if it's auto detect. |
||
1403 | if (typeof(bActOnElement) == 'boolean' && bActOnElement) |
||
1404 | var oCodeArea = document.getElementById(oCurElement); |
||
1405 | else |
||
1406 | var oCodeArea = oCurElement.parentNode.nextSibling; |
||
1407 | |||
1408 | if (typeof(oCodeArea) != 'object' || oCodeArea == null) |
||
1409 | return false; |
||
1410 | |||
1411 | // Start off with my favourite, internet explorer. |
||
1412 | if ('createTextRange' in document.body) |
||
1413 | { |
||
1414 | var oCurRange = document.body.createTextRange(); |
||
1415 | oCurRange.moveToElementText(oCodeArea); |
||
1416 | oCurRange.select(); |
||
1417 | } |
||
1418 | // Firefox at el. |
||
1419 | else if (window.getSelection) |
||
1420 | { |
||
1421 | var oCurSelection = window.getSelection(); |
||
1422 | // Safari is special! |
||
1423 | if (oCurSelection.setBaseAndExtent) |
||
1424 | { |
||
1425 | var oLastChild = oCodeArea.lastChild; |
||
1426 | oCurSelection.setBaseAndExtent(oCodeArea, 0, oLastChild, 'innerText' in oLastChild ? oLastChild.innerText.length : oLastChild.textContent.length); |
||
1427 | } |
||
1428 | else |
||
1429 | { |
||
1430 | var curRange = document.createRange(); |
||
1431 | curRange.selectNodeContents(oCodeArea); |
||
1432 | |||
1433 | oCurSelection.removeAllRanges(); |
||
1434 | oCurSelection.addRange(curRange); |
||
1435 | } |
||
1436 | } |
||
1437 | |||
1438 | return false; |
||
1439 | } |
||
1440 | |||
1441 | // A function used to clean the attachments on post page |
||
1442 | function cleanFileInput(idElement) |
||
1443 | { |
||
1444 | // Simpler solutions work in Opera, IE, Safari and Chrome. |
||
1445 | if (is_opera || is_ie || is_safari || is_chrome) |
||
1446 | { |
||
1447 | document.getElementById(idElement).outerHTML = document.getElementById(idElement).outerHTML; |
||
1448 | } |
||
1449 | // What else can we do? By the way, this doesn't work in Chrome and Mac's Safari. |
||
1450 | else |
||
1451 | { |
||
1452 | document.getElementById(idElement).type = 'input'; |
||
1453 | document.getElementById(idElement).type = 'file'; |
||
1454 | } |
||
1455 | } |
||
1456 | |||
1457 | function applyWindowClasses(oList) |
||
1458 | { |
||
1459 | var bAlternate = false; |
||
1460 | oListItems = oList.getElementsByTagName("LI"); |
||
0 ignored issues
–
show
|
|||
1461 | for (i = 0; i < oListItems.length; i++) |
||
0 ignored issues
–
show
|
|||
1462 | { |
||
1463 | // Skip dummies. |
||
1464 | if (oListItems[i].id == "") |
||
1465 | continue; |
||
1466 | oListItems[i].className = "windowbg" + (bAlternate ? "2" : ""); |
||
1467 | bAlternate = !bAlternate; |
||
1468 | } |
||
1469 | } |
||
1470 | |||
1471 | function reActivate() |
||
1472 | { |
||
1473 | document.forms.postmodify.message.readOnly = false; |
||
1474 | } |
||
1475 | |||
1476 | // The actual message icon selector. |
||
1477 | function showimage() |
||
1478 | { |
||
1479 | document.images.icons.src = icon_urls[document.forms.postmodify.icon.options[document.forms.postmodify.icon.selectedIndex].value]; |
||
1480 | } |
||
1481 | |||
1482 | function pollOptions() |
||
1483 | { |
||
1484 | var expire_time = document.getElementById('poll_expire'); |
||
1485 | |||
1486 | if (isEmptyText(expire_time) || expire_time.value == 0) |
||
1487 | { |
||
1488 | document.forms.postmodify.poll_hide[2].disabled = true; |
||
1489 | if (document.forms.postmodify.poll_hide[2].checked) |
||
1490 | document.forms.postmodify.poll_hide[1].checked = true; |
||
1491 | } |
||
1492 | else |
||
1493 | document.forms.postmodify.poll_hide[2].disabled = false; |
||
1494 | } |
||
1495 | |||
1496 | function generateDays(offset) |
||
1497 | { |
||
1498 | // Work around JavaScript's lack of support for default values... |
||
1499 | offset = typeof(offset) != 'undefined' ? offset : ''; |
||
1500 | |||
1501 | var days = 0, selected = 0; |
||
1502 | var dayElement = document.getElementById("day" + offset), yearElement = document.getElementById("year" + offset), monthElement = document.getElementById("month" + offset); |
||
1503 | |||
1504 | var monthLength = [ |
||
1505 | 31, 28, 31, 30, |
||
1506 | 31, 30, 31, 31, |
||
1507 | 30, 31, 30, 31 |
||
1508 | ]; |
||
1509 | if (yearElement.options[yearElement.selectedIndex].value % 4 == 0) |
||
1510 | monthLength[1] = 29; |
||
1511 | |||
1512 | selected = dayElement.selectedIndex; |
||
1513 | while (dayElement.options.length) |
||
1514 | dayElement.options[0] = null; |
||
1515 | |||
1516 | days = monthLength[monthElement.value - 1]; |
||
1517 | |||
1518 | for (i = 1; i <= days; i++) |
||
0 ignored issues
–
show
|
|||
1519 | dayElement.options[dayElement.length] = new Option(i, i); |
||
1520 | |||
1521 | if (selected < days) |
||
1522 | dayElement.selectedIndex = selected; |
||
1523 | } |
||
1524 | |||
1525 | function toggleLinked(form) |
||
1526 | { |
||
1527 | form.board.disabled = !form.link_to_board.checked; |
||
1528 | } |
||
1529 | |||
1530 | function initSearch() |
||
1531 | { |
||
1532 | if (document.forms.searchform.search.value.indexOf("%u") != -1) |
||
1533 | document.forms.searchform.search.value = unescape(document.forms.searchform.search.value); |
||
1534 | } |
||
1535 | |||
1536 | function selectBoards(ids, aFormID) |
||
1537 | { |
||
1538 | var toggle = true; |
||
1539 | var aForm = document.getElementById(aFormID); |
||
1540 | |||
1541 | for (i = 0; i < ids.length; i++) |
||
0 ignored issues
–
show
|
|||
1542 | toggle = toggle & aForm["brd" + ids[i]].checked; |
||
1543 | |||
1544 | for (i = 0; i < ids.length; i++) |
||
1545 | aForm["brd" + ids[i]].checked = !toggle; |
||
1546 | } |
||
1547 | |||
1548 | function updateRuleDef(optNum) |
||
1549 | { |
||
1550 | if (document.getElementById("ruletype" + optNum).value == "gid") |
||
1551 | { |
||
1552 | document.getElementById("defdiv" + optNum).style.display = "none"; |
||
1553 | document.getElementById("defseldiv" + optNum).style.display = ""; |
||
1554 | } |
||
1555 | else if (document.getElementById("ruletype" + optNum).value == "bud" || document.getElementById("ruletype" + optNum).value == "") |
||
1556 | { |
||
1557 | document.getElementById("defdiv" + optNum).style.display = "none"; |
||
1558 | document.getElementById("defseldiv" + optNum).style.display = "none"; |
||
1559 | } |
||
1560 | else |
||
1561 | { |
||
1562 | document.getElementById("defdiv" + optNum).style.display = ""; |
||
1563 | document.getElementById("defseldiv" + optNum).style.display = "none"; |
||
1564 | } |
||
1565 | } |
||
1566 | |||
1567 | function updateActionDef(optNum) |
||
1568 | { |
||
1569 | if (document.getElementById("acttype" + optNum).value == "lab") |
||
1570 | { |
||
1571 | document.getElementById("labdiv" + optNum).style.display = ""; |
||
1572 | } |
||
1573 | else |
||
1574 | { |
||
1575 | document.getElementById("labdiv" + optNum).style.display = "none"; |
||
1576 | } |
||
1577 | } |
||
1578 | |||
1579 | function smc_resize(selector) |
||
1580 | { |
||
1581 | var allElements = []; |
||
1582 | |||
1583 | $(selector).each(function(){ |
||
1584 | $thisElement = $(this); |
||
0 ignored issues
–
show
|
|||
1585 | |||
1586 | // Get rid of the width and height attributes. |
||
1587 | $thisElement.removeAttr('width').removeAttr('height'); |
||
1588 | |||
1589 | // Get the default vars. |
||
1590 | $thisElement.basedElement = $thisElement.parent(); |
||
1591 | $thisElement.defaultWidth = $thisElement.width(); |
||
1592 | $thisElement.defaultHeight = $thisElement.height(); |
||
1593 | $thisElement.aspectRatio = $thisElement.defaultHeight / $thisElement.defaultWidth; |
||
1594 | |||
1595 | allElements.push($thisElement); |
||
1596 | }); |
||
1597 | |||
1598 | $(window).resize(function(){ |
||
1599 | $(allElements).each(function(){ |
||
1600 | _innerElement = this; |
||
0 ignored issues
–
show
|
|||
1601 | |||
1602 | // Get the new width and height. |
||
1603 | var newWidth = _innerElement.basedElement.width(); |
||
1604 | var newHeight = (newWidth * _innerElement.aspectRatio) <= _innerElement.defaultHeight ? (newWidth * _innerElement.aspectRatio) : _innerElement.defaultHeight; |
||
1605 | |||
1606 | // If the new width is lower than the "default width" then apply some resizing. No? then go back to our default sizes |
||
1607 | var applyResize = (newWidth <= _innerElement.defaultWidth), |
||
1608 | applyWidth = !applyResize ? _innerElement.defaultWidth : newWidth, |
||
1609 | applyHeight = !applyResize ? _innerElement.defaultHeight : newHeight; |
||
1610 | |||
1611 | // Gotta check the applied width and height is actually something! |
||
1612 | if (applyWidth <= 0 && applyHeight <= 0) { |
||
1613 | applyWidth = _innerElement.defaultWidth; |
||
1614 | applyHeight = _innerElement.defaultHeight; |
||
1615 | } |
||
1616 | |||
1617 | // Finally resize the element! |
||
1618 | _innerElement.width(applyWidth).height(applyHeight); |
||
1619 | }); |
||
1620 | |||
1621 | // Kick off one resize to fix all elements on page load. |
||
1622 | }).resize(); |
||
1623 | } |
||
1624 | |||
1625 | $(function() { |
||
1626 | $('.buttonlist > .dropmenu').each(function(index, item) { |
||
1627 | $(item).prev().click(function(e) { |
||
1628 | e.stopPropagation(); |
||
1629 | e.preventDefault(); |
||
1630 | |||
1631 | if ($(item).is(':visible')) { |
||
1632 | $(item).css('display', 'none'); |
||
1633 | |||
1634 | return true; |
||
1635 | } |
||
1636 | |||
1637 | $(item).css('display', 'block'); |
||
1638 | $(item).css('top', $(this).offset().top + $(this).height()); |
||
1639 | $(item).css('left', Math.max($(this).offset().left - $(item).width() + $(this).outerWidth(), 0)); |
||
1640 | $(item).height($(item).find('div:first').height()); |
||
1641 | }); |
||
1642 | $(document).click(function() { |
||
1643 | $(item).css('display', 'none'); |
||
1644 | }); |
||
1645 | }); |
||
1646 | |||
1647 | // Generic confirmation message. |
||
1648 | $(document).on('click', '.you_sure', function() { |
||
1649 | var custom_message = $(this).attr('data-confirm'); |
||
1650 | |||
1651 | return confirm(custom_message ? custom_message.replace(/-n-/g, "\n") : smf_you_sure); |
||
1652 | }); |
||
1653 | |||
1654 | // Generic event for smfSelectText() |
||
1655 | $('.smf_select_text').on('click', function(e) { |
||
1656 | e.preventDefault(); |
||
1657 | |||
1658 | // Do you want to target yourself? |
||
1659 | var actOnElement = $(this).attr('data-actonelement'); |
||
1660 | |||
1661 | return typeof actOnElement !== "undefined" ? smfSelectText(actOnElement, true) : smfSelectText(this); |
||
1662 | }); |
||
1663 | }); |
||
1664 | |||
1665 | function avatar_fallback(e) { |
||
1666 | var e = window.e || e; |
||
1667 | var default_avatar = '/avatars/default.png'; |
||
1668 | var default_url = document.URL.substr(0,smf_scripturl.lastIndexOf('/')) + default_avatar; |
||
1669 | |||
1670 | if (e.target.tagName !== 'IMG' || !e.target.classList.contains('avatar') || e.target.src === default_url ) |
||
1671 | return; |
||
1672 | |||
1673 | e.target.src = default_url; |
||
1674 | return true; |
||
1675 | } |
||
1676 | |||
1677 | if (document.addEventListener) |
||
1678 | document.addEventListener("error", avatar_fallback, true); |
||
1679 | else |
||
1680 | document.attachEvent("error", avatar_fallback); |
||
1681 |