2011-07-26 16:25:04 +01:00
|
|
|
var phpbb = {};
|
2012-06-21 19:16:05 +01:00
|
|
|
phpbb.alertTime = 100;
|
2011-07-26 16:25:04 +01:00
|
|
|
|
2011-08-24 11:44:28 +01:00
|
|
|
(function($) { // Avoid conflicts with other libraries
|
2011-07-26 11:46:49 +01:00
|
|
|
|
2012-02-08 19:03:30 +01:00
|
|
|
"use strict";
|
|
|
|
|
2011-09-28 18:34:25 +01:00
|
|
|
// define a couple constants for keydown functions.
|
2012-02-08 18:40:08 +01:00
|
|
|
var keymap = {
|
2014-06-13 12:08:03 +01:00
|
|
|
TAB: 9,
|
2012-02-08 18:40:08 +01:00
|
|
|
ENTER: 13,
|
|
|
|
ESC: 27
|
|
|
|
};
|
2011-09-24 17:41:58 +01:00
|
|
|
|
2011-11-18 17:31:10 +00:00
|
|
|
var dark = $('#darkenwrapper');
|
2013-11-03 10:49:28 -08:00
|
|
|
var loadingIndicator = $('#loading_indicator');
|
2013-01-02 16:44:05 +01:00
|
|
|
var phpbbAlertTimer = null;
|
2011-07-25 20:42:29 +01:00
|
|
|
|
2014-05-16 15:27:06 -07:00
|
|
|
phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');
|
2011-07-25 20:42:29 +01:00
|
|
|
|
|
|
|
/**
|
2012-06-21 19:16:05 +01:00
|
|
|
* Display a loading screen
|
2011-08-24 11:44:28 +01:00
|
|
|
*
|
2013-11-03 10:49:28 -08:00
|
|
|
* @returns object Returns loadingIndicator.
|
2011-07-25 20:42:29 +01:00
|
|
|
*/
|
2013-11-03 10:49:28 -08:00
|
|
|
phpbb.loadingIndicator = function() {
|
|
|
|
if (!loadingIndicator.is(':visible')) {
|
|
|
|
loadingIndicator.fadeIn(phpbb.alertTime);
|
2013-10-15 21:37:53 -07:00
|
|
|
// Wait fifteen seconds and display an error if nothing has been returned by then.
|
2013-10-30 19:43:31 -07:00
|
|
|
phpbb.clearLoadingTimeout();
|
2013-10-15 21:37:53 -07:00
|
|
|
phpbbAlertTimer = setTimeout(function() {
|
2013-11-03 10:49:28 -08:00
|
|
|
if (loadingIndicator.is(':visible')) {
|
2013-10-15 21:37:53 -07:00
|
|
|
phpbb.alert($('#phpbb_alert').attr('data-l-err'), $('#phpbb_alert').attr('data-l-timeout-processing-req'));
|
|
|
|
}
|
|
|
|
}, 15000);
|
2011-07-25 20:42:29 +01:00
|
|
|
}
|
2011-08-19 17:39:35 +01:00
|
|
|
|
2013-11-03 10:49:28 -08:00
|
|
|
return loadingIndicator;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-07-25 20:42:29 +01:00
|
|
|
|
2012-12-19 16:41:25 +01:00
|
|
|
/**
|
|
|
|
* Clear loading alert timeout
|
|
|
|
*/
|
|
|
|
phpbb.clearLoadingTimeout = function() {
|
2013-01-04 22:46:12 +01:00
|
|
|
if (phpbbAlertTimer !== null) {
|
2012-12-19 16:41:25 +01:00
|
|
|
clearTimeout(phpbbAlertTimer);
|
2013-01-02 16:44:05 +01:00
|
|
|
phpbbAlertTimer = null;
|
2012-12-19 16:41:25 +01:00
|
|
|
}
|
2013-01-04 22:46:12 +01:00
|
|
|
};
|
2012-12-19 16:41:25 +01:00
|
|
|
|
2011-07-14 13:33:42 +01:00
|
|
|
/**
|
2011-07-14 17:49:17 +01:00
|
|
|
* Display a simple alert similar to JSs native alert().
|
2011-07-14 13:33:42 +01:00
|
|
|
*
|
2011-10-22 16:09:38 +01:00
|
|
|
* You can only call one alert or confirm box at any one time.
|
|
|
|
*
|
|
|
|
* @param string title Title of the message, eg "Information" (HTML).
|
|
|
|
* @param string msg Message to display (HTML).
|
2011-07-26 12:13:09 +01:00
|
|
|
* @param bool fadedark Remove the dark background when done? Defaults
|
2013-03-26 13:13:33 +01:00
|
|
|
* to yes.
|
2011-07-14 14:41:24 +01:00
|
|
|
*
|
2011-08-24 11:44:28 +01:00
|
|
|
* @returns object Returns the div created.
|
2011-07-14 13:33:42 +01:00
|
|
|
*/
|
2011-07-25 20:42:29 +01:00
|
|
|
phpbb.alert = function(title, msg, fadedark) {
|
2011-09-25 18:12:34 +01:00
|
|
|
var div = $('#phpbb_alert');
|
2011-10-15 16:21:40 +01:00
|
|
|
div.find('.alert_title').html(title);
|
|
|
|
div.find('.alert_text').html(msg);
|
2011-07-14 13:33:42 +01:00
|
|
|
|
2013-10-15 21:37:53 -07:00
|
|
|
if (!dark.is(':visible')) {
|
|
|
|
dark.fadeIn(phpbb.alertTime);
|
|
|
|
}
|
|
|
|
|
2011-09-24 16:42:22 +01:00
|
|
|
div.bind('click', function(e) {
|
2011-07-25 20:42:29 +01:00
|
|
|
e.stopPropagation();
|
|
|
|
});
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.one('click', function(e) {
|
2012-02-08 19:02:16 +01:00
|
|
|
var fade;
|
|
|
|
|
2011-10-22 17:07:00 +01:00
|
|
|
div.find('.alert_close').unbind('click');
|
2012-02-08 19:02:16 +01:00
|
|
|
fade = (typeof fadedark !== 'undefined' && !fadedark) ? div : dark;
|
2012-06-21 19:16:05 +01:00
|
|
|
fade.fadeOut(phpbb.alertTime, function() {
|
2011-09-25 16:02:26 +01:00
|
|
|
div.hide();
|
2011-07-26 12:13:09 +01:00
|
|
|
});
|
2012-02-08 18:58:23 +01:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2011-07-14 13:33:42 +01:00
|
|
|
});
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2014-05-13 17:49:54 -07:00
|
|
|
$(document).keydown(function(e) {
|
|
|
|
if ((e.keyCode === keymap.ENTER || e.keyCode === keymap.ESC) && dark.is(':visible')) {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.trigger('click');
|
2012-02-08 18:58:23 +01:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2011-08-18 19:02:18 +01:00
|
|
|
}
|
|
|
|
});
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2012-02-08 19:38:21 +01:00
|
|
|
div.find('.alert_close').one('click', function(e) {
|
2011-09-25 16:49:43 +01:00
|
|
|
dark.trigger('click');
|
2012-02-08 19:38:21 +01:00
|
|
|
|
|
|
|
e.preventDefault();
|
2011-09-25 16:49:43 +01:00
|
|
|
});
|
2011-07-14 13:33:42 +01:00
|
|
|
|
2013-11-03 10:49:28 -08:00
|
|
|
if (loadingIndicator.is(':visible')) {
|
|
|
|
loadingIndicator.fadeOut(phpbb.alertTime, function() {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2012-06-21 19:16:05 +01:00
|
|
|
div.fadeIn(phpbb.alertTime);
|
2011-07-25 20:42:29 +01:00
|
|
|
});
|
2012-06-21 19:16:05 +01:00
|
|
|
} else if (dark.is(':visible')) {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2012-06-21 19:16:05 +01:00
|
|
|
div.fadeIn(phpbb.alertTime);
|
|
|
|
} else {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2011-07-25 20:42:29 +01:00
|
|
|
div.show();
|
2012-06-21 19:16:05 +01:00
|
|
|
dark.fadeIn(phpbb.alertTime);
|
2011-07-25 20:42:29 +01:00
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-07-14 14:41:24 +01:00
|
|
|
return div;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-07-14 13:33:42 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Display a simple yes / no box to the user.
|
|
|
|
*
|
2011-10-22 16:09:38 +01:00
|
|
|
* You can only call one alert or confirm box at any one time.
|
|
|
|
*
|
2011-10-15 18:05:58 +01:00
|
|
|
* @param string msg Message to display (HTML).
|
2011-07-26 12:13:09 +01:00
|
|
|
* @param function callback Callback. Bool param, whether the user pressed
|
2013-01-12 19:08:34 +01:00
|
|
|
* yes or no (or whatever their language is).
|
2011-07-26 12:13:09 +01:00
|
|
|
* @param bool fadedark Remove the dark background when done? Defaults
|
2013-01-12 19:08:34 +01:00
|
|
|
* to yes.
|
2011-07-14 14:41:24 +01:00
|
|
|
*
|
2011-08-24 11:44:28 +01:00
|
|
|
* @returns object Returns the div created.
|
2011-07-14 13:33:42 +01:00
|
|
|
*/
|
2011-07-25 20:42:29 +01:00
|
|
|
phpbb.confirm = function(msg, callback, fadedark) {
|
2011-09-25 18:12:34 +01:00
|
|
|
var div = $('#phpbb_confirm');
|
2011-10-15 16:21:40 +01:00
|
|
|
div.find('.alert_text').html(msg);
|
2011-09-25 18:12:34 +01:00
|
|
|
|
2013-10-15 21:37:53 -07:00
|
|
|
if (!dark.is(':visible')) {
|
|
|
|
dark.fadeIn(phpbb.alertTime);
|
|
|
|
}
|
|
|
|
|
2011-09-25 18:12:34 +01:00
|
|
|
div.bind('click', function(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
});
|
2012-02-08 18:42:21 +01:00
|
|
|
|
2013-01-04 22:46:12 +01:00
|
|
|
var clickHandler = function(e) {
|
2013-05-08 00:08:35 +02:00
|
|
|
var res = this.name === 'confirm';
|
2011-07-26 12:13:09 +01:00
|
|
|
var fade = (typeof fadedark !== 'undefined' && !fadedark && res) ? div : dark;
|
2012-06-21 19:16:05 +01:00
|
|
|
fade.fadeOut(phpbb.alertTime, function() {
|
2011-09-25 16:02:26 +01:00
|
|
|
div.hide();
|
2011-07-26 12:13:09 +01:00
|
|
|
});
|
2013-01-04 22:46:12 +01:00
|
|
|
div.find('input[type="button"]').unbind('click', clickHandler);
|
2011-07-26 12:13:09 +01:00
|
|
|
callback(res);
|
2012-02-08 18:58:23 +01:00
|
|
|
|
|
|
|
if (e) {
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
2011-11-17 17:09:09 +00:00
|
|
|
};
|
2013-01-04 22:46:12 +01:00
|
|
|
div.find('input[type="button"]').one('click', clickHandler);
|
2011-09-25 16:49:43 +01:00
|
|
|
|
|
|
|
dark.one('click', function(e) {
|
2011-10-22 17:07:00 +01:00
|
|
|
div.find('.alert_close').unbind('click');
|
2012-06-21 19:16:05 +01:00
|
|
|
dark.fadeOut(phpbb.alertTime, function() {
|
2011-09-25 16:49:43 +01:00
|
|
|
div.hide();
|
|
|
|
});
|
|
|
|
callback(false);
|
2012-02-08 18:58:23 +01:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2011-09-25 16:49:43 +01:00
|
|
|
});
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-08-18 19:02:18 +01:00
|
|
|
$(document).bind('keydown', function(e) {
|
2012-02-08 18:40:08 +01:00
|
|
|
if (e.keyCode === keymap.ENTER) {
|
2013-05-08 00:08:35 +02:00
|
|
|
$('input[name="confirm"]').trigger('click');
|
2012-02-08 18:58:23 +01:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2012-02-08 18:40:08 +01:00
|
|
|
} else if (e.keyCode === keymap.ESC) {
|
2013-05-08 00:08:35 +02:00
|
|
|
$('input[name="cancel"]').trigger('click');
|
2012-02-08 18:58:23 +01:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2011-08-18 19:02:18 +01:00
|
|
|
}
|
|
|
|
});
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2012-02-08 19:38:21 +01:00
|
|
|
div.find('.alert_close').one('click', function(e) {
|
2011-10-22 17:07:00 +01:00
|
|
|
var fade = (typeof fadedark !== 'undefined' && fadedark) ? div : dark;
|
2012-06-21 19:16:05 +01:00
|
|
|
fade.fadeOut(phpbb.alertTime, function() {
|
2011-10-22 17:07:00 +01:00
|
|
|
div.hide();
|
|
|
|
});
|
|
|
|
callback(false);
|
2012-02-08 19:38:21 +01:00
|
|
|
|
|
|
|
e.preventDefault();
|
2011-09-25 16:49:43 +01:00
|
|
|
});
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2013-11-03 10:49:28 -08:00
|
|
|
if (loadingIndicator.is(':visible')) {
|
|
|
|
loadingIndicator.fadeOut(phpbb.alertTime, function() {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2012-06-21 19:16:05 +01:00
|
|
|
div.fadeIn(phpbb.alertTime);
|
2011-07-25 20:42:29 +01:00
|
|
|
});
|
2012-06-21 19:16:05 +01:00
|
|
|
} else if (dark.is(':visible')) {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2012-06-21 19:16:05 +01:00
|
|
|
div.fadeIn(phpbb.alertTime);
|
|
|
|
} else {
|
2011-09-24 16:42:22 +01:00
|
|
|
dark.append(div);
|
2011-07-25 20:42:29 +01:00
|
|
|
div.show();
|
2012-06-21 19:16:05 +01:00
|
|
|
dark.fadeIn(phpbb.alertTime);
|
2011-07-25 20:42:29 +01:00
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-07-14 14:41:24 +01:00
|
|
|
return div;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-07-14 13:33:42 +01:00
|
|
|
|
2011-08-24 11:31:17 +01:00
|
|
|
/**
|
|
|
|
* Turn a querystring into an array.
|
|
|
|
*
|
|
|
|
* @argument string string The querystring to parse.
|
2011-10-22 16:50:33 +01:00
|
|
|
* @returns object The object created.
|
2011-08-24 11:31:17 +01:00
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.parseQuerystring = function(string) {
|
2011-10-22 16:13:27 +01:00
|
|
|
var params = {}, i, split;
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-08-24 11:31:17 +01:00
|
|
|
string = string.split('&');
|
2012-06-21 19:16:05 +01:00
|
|
|
for (i = 0; i < string.length; i++) {
|
2011-10-22 16:12:08 +01:00
|
|
|
split = string[i].split('=');
|
2011-10-22 16:13:27 +01:00
|
|
|
params[split[0]] = decodeURIComponent(split[1]);
|
2011-08-24 11:31:17 +01:00
|
|
|
}
|
2011-10-22 16:13:27 +01:00
|
|
|
return params;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-08-24 11:31:17 +01:00
|
|
|
|
2011-07-14 14:41:24 +01:00
|
|
|
|
2011-07-14 14:57:45 +01:00
|
|
|
/**
|
|
|
|
* Makes a link use AJAX instead of loading an entire page.
|
2011-07-14 17:49:17 +01:00
|
|
|
*
|
2011-10-15 17:29:34 +01:00
|
|
|
* This function will work for links (both standard links and links which
|
|
|
|
* invoke confirm_box) and forms. It will be called automatically for links
|
|
|
|
* and forms with the data-ajax attribute set, and will call the necessary
|
|
|
|
* callback.
|
|
|
|
*
|
|
|
|
* For more info, view the following page on the phpBB wiki:
|
|
|
|
* http://wiki.phpbb.com/JavaScript_Function.phpbb.ajaxify
|
|
|
|
*
|
2012-02-08 19:46:36 +01:00
|
|
|
* @param object options Options.
|
2011-07-14 17:49:17 +01:00
|
|
|
* @param bool/function refresh If we are sent back a refresh, should it be
|
2013-01-12 19:08:34 +01:00
|
|
|
* acted upon? This can either be true / false / a function.
|
2011-10-15 17:29:34 +01:00
|
|
|
* @param function callback Callback to call on completion of event. Has
|
2013-01-12 19:08:34 +01:00
|
|
|
* three parameters: the element that the event was evoked from, the JSON
|
|
|
|
* that was returned and (if it is a form) the form action.
|
2011-07-14 14:57:45 +01:00
|
|
|
*/
|
2012-02-08 19:56:25 +01:00
|
|
|
phpbb.ajaxify = function(options) {
|
|
|
|
var elements = $(options.selector),
|
|
|
|
refresh = options.refresh,
|
|
|
|
callback = options.callback,
|
2012-04-11 23:29:47 +02:00
|
|
|
overlay = (typeof options.overlay !== 'undefined') ? options.overlay : true,
|
2012-06-21 19:16:05 +01:00
|
|
|
isForm = elements.is('form'),
|
2014-04-08 03:54:56 -07:00
|
|
|
isText = elements.is('input[type="text"], textarea'),
|
|
|
|
eventName;
|
|
|
|
|
|
|
|
if (isForm) {
|
|
|
|
eventName = 'submit';
|
|
|
|
} else if (isText) {
|
|
|
|
eventName = 'keyup';
|
|
|
|
} else {
|
|
|
|
eventName = 'click';
|
|
|
|
}
|
2012-02-08 19:56:25 +01:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
elements.bind(eventName, function(event) {
|
2012-02-19 16:35:21 +00:00
|
|
|
var action, method, data, submit, that = this, $this = $(this);
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
if ($this.find('input[type="submit"][data-clicked]').attr('data-ajax') === 'false') {
|
2012-02-08 18:58:23 +01:00
|
|
|
return;
|
2011-07-25 10:59:19 +01:00
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2013-05-20 21:35:51 +03:00
|
|
|
/**
|
|
|
|
* Handler for AJAX errors
|
|
|
|
*/
|
|
|
|
function errorHandler(jqXHR, textStatus, errorThrown) {
|
2013-05-20 22:12:20 +03:00
|
|
|
if (console && console.log) {
|
|
|
|
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
|
|
|
|
}
|
2013-01-10 10:59:20 +01:00
|
|
|
phpbb.clearLoadingTimeout();
|
2013-05-20 21:35:51 +03:00
|
|
|
var errorText = false;
|
|
|
|
if (typeof errorThrown === 'string' && errorThrown.length > 0) {
|
|
|
|
errorText = errorThrown;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
errorText = dark.attr('data-ajax-error-text-' + textStatus);
|
|
|
|
if (typeof errorText !== 'string' || !errorText.length)
|
|
|
|
errorText = dark.attr('data-ajax-error-text');
|
|
|
|
}
|
|
|
|
phpbb.alert(dark.attr('data-ajax-error-title'), errorText);
|
2013-01-10 10:59:20 +01:00
|
|
|
}
|
|
|
|
|
2011-10-15 17:29:34 +01:00
|
|
|
/**
|
|
|
|
* This is a private function used to handle the callbacks, refreshes
|
2011-10-22 16:40:37 +01:00
|
|
|
* and alert. It calls the callback, refreshes the page if necessary, and
|
|
|
|
* displays an alert to the user and removes it after an amount of time.
|
|
|
|
*
|
|
|
|
* It cannot be called from outside this function, and is purely here to
|
|
|
|
* avoid repetition of code.
|
|
|
|
*
|
|
|
|
* @param object res The object sent back by the server.
|
2011-10-15 17:29:34 +01:00
|
|
|
*/
|
2012-06-21 19:16:05 +01:00
|
|
|
function returnHandler(res) {
|
2012-02-08 19:02:16 +01:00
|
|
|
var alert;
|
|
|
|
|
2012-12-19 16:41:25 +01:00
|
|
|
phpbb.clearLoadingTimeout();
|
|
|
|
|
2011-11-30 16:58:17 +00:00
|
|
|
// Is a confirmation required?
|
2012-06-21 19:16:05 +01:00
|
|
|
if (typeof res.S_CONFIRM_ACTION === 'undefined') {
|
2011-11-30 16:58:17 +00:00
|
|
|
// If a confirmation is not required, display an alert and call the
|
|
|
|
// callbacks.
|
2012-06-21 19:16:05 +01:00
|
|
|
if (typeof res.MESSAGE_TITLE !== 'undefined') {
|
2012-02-08 19:02:16 +01:00
|
|
|
alert = phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);
|
2012-06-21 19:16:05 +01:00
|
|
|
} else {
|
|
|
|
dark.fadeOut(phpbb.alertTime);
|
2011-08-24 16:39:25 +01:00
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
if (typeof phpbb.ajaxCallbacks[callback] === 'function') {
|
|
|
|
phpbb.ajaxCallbacks[callback].call(that, res);
|
2011-07-17 14:57:13 +01:00
|
|
|
}
|
2011-08-24 22:29:52 +01:00
|
|
|
|
2011-11-30 16:58:17 +00:00
|
|
|
// If the server says to refresh the page, check whether the page should
|
|
|
|
// be refreshed and refresh page after specified time if required.
|
2012-06-21 19:16:05 +01:00
|
|
|
if (res.REFRESH_DATA) {
|
|
|
|
if (typeof refresh === 'function') {
|
2011-08-24 22:29:52 +01:00
|
|
|
refresh = refresh(res.REFRESH_DATA.url);
|
2012-06-21 19:16:05 +01:00
|
|
|
} else if (typeof refresh !== 'boolean') {
|
2011-08-24 22:29:52 +01:00
|
|
|
refresh = false;
|
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2013-10-30 19:43:31 -07:00
|
|
|
phpbbAlertTimer = setTimeout(function() {
|
2012-06-21 19:16:05 +01:00
|
|
|
if (refresh) {
|
2011-08-24 22:29:52 +01:00
|
|
|
window.location = res.REFRESH_DATA.url;
|
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-11-30 16:58:17 +00:00
|
|
|
// Hide the alert even if we refresh the page, in case the user
|
|
|
|
// presses the back button.
|
2012-06-21 19:16:05 +01:00
|
|
|
dark.fadeOut(phpbb.alertTime, function() {
|
2014-05-22 01:27:23 +08:00
|
|
|
if (typeof alert !== 'undefined') {
|
|
|
|
alert.hide();
|
|
|
|
}
|
2011-08-24 22:29:52 +01:00
|
|
|
});
|
2011-11-30 16:58:17 +00:00
|
|
|
}, res.REFRESH_DATA.time * 1000); // Server specifies time in seconds
|
2011-08-24 22:29:52 +01:00
|
|
|
}
|
2012-06-21 19:16:05 +01:00
|
|
|
} else {
|
2013-01-15 13:10:25 +01:00
|
|
|
// If confirmation is required, display a dialog to the user.
|
2012-12-18 13:31:38 +01:00
|
|
|
phpbb.confirm(res.MESSAGE_BODY, function(del) {
|
2012-06-21 19:16:05 +01:00
|
|
|
if (del) {
|
2013-11-03 10:49:28 -08:00
|
|
|
phpbb.loadingIndicator();
|
2011-08-24 22:29:52 +01:00
|
|
|
data = $('<form>' + res.S_HIDDEN_FIELDS + '</form>').serialize();
|
2012-02-15 20:58:00 +01:00
|
|
|
$.ajax({
|
|
|
|
url: res.S_CONFIRM_ACTION,
|
|
|
|
type: 'POST',
|
2013-11-08 06:13:55 -08:00
|
|
|
data: data + '&confirm=' + res.YES_VALUE + '&' + $('#phpbb_confirm form').serialize(),
|
2012-06-21 19:16:05 +01:00
|
|
|
success: returnHandler,
|
|
|
|
error: errorHandler
|
2012-02-15 20:58:00 +01:00
|
|
|
});
|
2011-07-17 15:27:58 +01:00
|
|
|
}
|
2011-07-25 20:42:29 +01:00
|
|
|
}, false);
|
2011-07-17 15:27:58 +01:00
|
|
|
}
|
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2011-11-30 16:58:17 +00:00
|
|
|
// If the element is a form, POST must be used and some extra data must
|
|
|
|
// be taken from the form.
|
2012-06-21 19:16:05 +01:00
|
|
|
var runFilter = (typeof options.filter === 'function');
|
2014-04-08 03:54:56 -07:00
|
|
|
var data = {};
|
2012-02-15 19:32:53 +01:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
if (isForm) {
|
2012-02-15 19:32:53 +01:00
|
|
|
action = $this.attr('action').replace('&', '&');
|
|
|
|
data = $this.serializeArray();
|
2012-02-15 19:38:55 +01:00
|
|
|
method = $this.attr('method') || 'GET';
|
2012-02-19 16:30:22 +00:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
if ($this.find('input[type="submit"][data-clicked]')) {
|
2012-02-19 16:35:21 +00:00
|
|
|
submit = $this.find('input[type="submit"][data-clicked]');
|
2012-02-19 16:30:22 +00:00
|
|
|
data.push({
|
|
|
|
name: submit.attr('name'),
|
|
|
|
value: submit.val()
|
|
|
|
});
|
|
|
|
}
|
2014-04-08 03:54:56 -07:00
|
|
|
} else if (isText) {
|
|
|
|
var name = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : this['name'];
|
|
|
|
action = $this.attr('data-url').replace('&', '&');
|
|
|
|
data[name] = this.value;
|
|
|
|
method = 'POST';
|
2012-06-21 19:16:05 +01:00
|
|
|
} else {
|
2012-02-15 19:32:53 +01:00
|
|
|
action = this.href;
|
|
|
|
data = null;
|
|
|
|
method = 'GET';
|
|
|
|
}
|
|
|
|
|
2014-04-08 03:54:56 -07:00
|
|
|
var sendRequest = function() {
|
|
|
|
if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
|
|
|
|
phpbb.loadingIndicator();
|
|
|
|
}
|
|
|
|
|
|
|
|
var request = $.ajax({
|
|
|
|
url: action,
|
|
|
|
type: method,
|
|
|
|
data: data,
|
|
|
|
success: returnHandler,
|
|
|
|
error: errorHandler
|
|
|
|
});
|
|
|
|
request.always(function() {
|
|
|
|
loadingIndicator.fadeOut(phpbb.alertTime);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2012-02-15 19:38:55 +01:00
|
|
|
// If filter function returns false, cancel the AJAX functionality,
|
2012-02-15 19:32:53 +01:00
|
|
|
// and return true (meaning that the HTTP request will be sent normally).
|
2014-04-08 03:54:56 -07:00
|
|
|
if (runFilter && !options.filter.call(this, data, event, sendRequest)) {
|
2012-02-19 16:35:21 +00:00
|
|
|
return;
|
2011-07-17 15:27:58 +01:00
|
|
|
}
|
2011-09-27 19:32:06 +01:00
|
|
|
|
2014-04-08 03:54:56 -07:00
|
|
|
sendRequest();
|
2012-02-19 16:35:21 +00:00
|
|
|
event.preventDefault();
|
2011-07-17 14:57:13 +01:00
|
|
|
});
|
2012-02-15 19:32:53 +01:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
if (isForm) {
|
2012-02-19 16:30:22 +00:00
|
|
|
elements.find('input:submit').click(function () {
|
|
|
|
var $this = $(this);
|
|
|
|
|
|
|
|
$this.siblings('[data-clicked]').removeAttr('data-clicked');
|
|
|
|
$this.attr('data-clicked', 'true');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:58:37 +01:00
|
|
|
return this;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-07-17 14:57:13 +01:00
|
|
|
|
2014-04-08 03:54:56 -07:00
|
|
|
phpbb.search = {cache: {data: []}, tpl: [], container: []};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cached search data.
|
|
|
|
*
|
|
|
|
* @param string id Search ID.
|
|
|
|
* @return bool|object. Cached data object. Returns false if no data exists.
|
|
|
|
*/
|
|
|
|
phpbb.search.cache.get = function(id) {
|
|
|
|
if (this.data[id]) {
|
|
|
|
return this.data[id];
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set search cache data value.
|
|
|
|
*
|
|
|
|
* @param string id Search ID.
|
|
|
|
* @param string key Data key.
|
|
|
|
* @param string value Data value.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.cache.set = function(id, key, value) {
|
|
|
|
if (!this.data[id]) {
|
|
|
|
this.data[id] = {results: []};
|
|
|
|
}
|
|
|
|
this.data[id][key] = value;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cache search result.
|
|
|
|
*
|
|
|
|
* @param string id Search ID.
|
|
|
|
* @param string keyword Keyword.
|
|
|
|
* @param array results Search results.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.cache.setResults = function(id, keyword, value) {
|
|
|
|
this.data[id]['results'][keyword] = value;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Trim spaces from keyword and lower its case.
|
|
|
|
*
|
|
|
|
* @param string keyword Search keyword to clean.
|
|
|
|
* @return string Cleaned string.
|
|
|
|
*/
|
|
|
|
phpbb.search.cleanKeyword = function(keyword) {
|
|
|
|
return $.trim(keyword).toLowerCase();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get clean version of search keyword. If textarea supports several keywords
|
|
|
|
* (one per line), it fetches the current keyword based on the caret position.
|
|
|
|
*
|
|
|
|
* @param jQuery el Search input|textarea.
|
|
|
|
* @param string keyword Input|textarea value.
|
|
|
|
* @param bool multiline Whether textarea supports multiple search keywords.
|
|
|
|
*
|
|
|
|
* @return string Clean string.
|
|
|
|
*/
|
|
|
|
phpbb.search.getKeyword = function(el, keyword, multiline) {
|
|
|
|
if (multiline) {
|
|
|
|
var line = phpbb.search.getKeywordLine(el);
|
|
|
|
keyword = keyword.split("\n").splice(line, 1);
|
|
|
|
}
|
|
|
|
return phpbb.search.cleanKeyword(keyword);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the textarea line number on which the keyword resides - for textareas
|
|
|
|
* that support multiple keywords (one per line).
|
|
|
|
*
|
|
|
|
* @param jQuery el Search textarea.
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
phpbb.search.getKeywordLine = function (el) {
|
|
|
|
return el.val().substr(0, el.get(0).selectionStart).split("\n").length - 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the value on the input|textarea. If textarea supports multiple
|
|
|
|
* keywords, only the active keyword is replaced.
|
|
|
|
*
|
|
|
|
* @param jQuery el Search input|textarea.
|
|
|
|
* @param string value Value to set.
|
|
|
|
* @param bool multiline Whether textarea supports multiple search keywords.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.setValue = function(el, value, multiline) {
|
|
|
|
if (multiline) {
|
|
|
|
var line = phpbb.search.getKeywordLine(el),
|
|
|
|
lines = el.val().split("\n");
|
|
|
|
lines[line] = value;
|
|
|
|
value = lines.join("\n");
|
|
|
|
}
|
|
|
|
el.val(value);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the onclick event to set the value on the input|textarea to the selected search result.
|
|
|
|
*
|
|
|
|
* @param jQuery el Search input|textarea.
|
|
|
|
* @param object value Result object.
|
|
|
|
* @param object container jQuery object for the search container.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.setValueOnClick = function(el, value, row, container) {
|
|
|
|
row.click(function() {
|
|
|
|
phpbb.search.setValue(el, value.result, el.attr('data-multiline'));
|
|
|
|
container.hide();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs before the AJAX search request is sent and determines whether
|
|
|
|
* there is a need to contact the server. If there are cached results
|
|
|
|
* already, those are displayed instead. Executes the AJAX request function
|
|
|
|
* itself due to the need to use a timeout to limit the number of requests.
|
|
|
|
*
|
|
|
|
* @param array data Data to be sent to the server.
|
|
|
|
* @param object event Onkeyup event object.
|
|
|
|
* @param function sendRequest Function to execute AJAX request.
|
|
|
|
*
|
|
|
|
* @return bool Returns false.
|
|
|
|
*/
|
|
|
|
phpbb.search.filter = function(data, event, sendRequest) {
|
|
|
|
var el = $(this),
|
|
|
|
dataName = (el.attr('data-name') !== undefined) ? el.attr('data-name') : el.attr('name'),
|
|
|
|
minLength = parseInt(el.attr('data-min-length')),
|
|
|
|
searchID = el.attr('data-results'),
|
|
|
|
keyword = phpbb.search.getKeyword(el, data[dataName], el.attr('data-multiline')),
|
|
|
|
cache = phpbb.search.cache.get(searchID),
|
|
|
|
proceed = true;
|
|
|
|
data[dataName] = keyword;
|
|
|
|
|
|
|
|
if (cache['timeout']) {
|
|
|
|
clearTimeout(cache['timeout']);
|
|
|
|
}
|
|
|
|
|
|
|
|
var timeout = setTimeout(function() {
|
|
|
|
// Check min length and existence of cache.
|
|
|
|
if (minLength > keyword.length) {
|
|
|
|
proceed = false;
|
|
|
|
} else if (cache['last_search']) {
|
|
|
|
// Has the keyword actually changed?
|
|
|
|
if (cache['last_search'] === keyword) {
|
|
|
|
proceed = false;
|
|
|
|
} else {
|
|
|
|
// Do we already have results for this?
|
|
|
|
if (cache['results'][keyword]) {
|
|
|
|
var response = {keyword: keyword, results: cache['results'][keyword]};
|
|
|
|
phpbb.search.handleResponse(response, el, true);
|
|
|
|
proceed = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the previous search didn't yield results and the string only had characters added to it,
|
|
|
|
// then we won't bother sending a request.
|
|
|
|
if (keyword.indexOf(cache['last_search']) === 0 && cache['results'][cache['last_search']].length === 0) {
|
|
|
|
phpbb.search.cache.set(searchID, 'last_search', keyword);
|
|
|
|
phpbb.search.cache.setResults(searchID, keyword, []);
|
|
|
|
proceed = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (proceed) {
|
|
|
|
sendRequest.call(this);
|
|
|
|
}
|
|
|
|
}, 350);
|
|
|
|
phpbb.search.cache.set(searchID, 'timeout', timeout);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle search result response.
|
|
|
|
*
|
|
|
|
* @param object res Data received from server.
|
|
|
|
* @param jQuery el Search input|textarea.
|
|
|
|
* @param bool fromCache Whether the results are from the cache.
|
|
|
|
* @param function callback Optional callback to run when assigning each search result.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.handleResponse = function(res, el, fromCache, callback) {
|
|
|
|
if (typeof res !== 'object') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var searchID = el.attr('data-results'),
|
|
|
|
container = $(searchID);
|
|
|
|
|
|
|
|
if (this.cache.get(searchID)['callback']) {
|
|
|
|
callback = this.cache.get(searchID)['callback'];
|
|
|
|
} else if (typeof callback === 'function') {
|
|
|
|
this.cache.set(searchID, 'callback', callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fromCache) {
|
|
|
|
this.cache.setResults(searchID, res.keyword, res.results);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.cache.set(searchID, 'last_search', res.keyword);
|
|
|
|
this.showResults(res.results, el, container, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show search results.
|
|
|
|
*
|
|
|
|
* @param array results Search results.
|
|
|
|
* @param jQuery el Search input|textarea.
|
|
|
|
* @param jQuery container Search results container element.
|
|
|
|
* @param function callback Optional callback to run when assigning each search result.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.showResults = function(results, el, container, callback) {
|
|
|
|
var resultContainer = $('.search-results', container);
|
|
|
|
this.clearResults(resultContainer);
|
|
|
|
|
|
|
|
if (!results.length) {
|
|
|
|
container.hide();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var searchID = container.attr('id'),
|
|
|
|
tpl,
|
|
|
|
row;
|
|
|
|
|
|
|
|
if (!this.tpl[searchID]) {
|
|
|
|
tpl = $('.search-result-tpl', container);
|
|
|
|
this.tpl[searchID] = tpl.clone().removeClass('search-result-tpl');
|
|
|
|
tpl.remove();
|
|
|
|
}
|
|
|
|
tpl = this.tpl[searchID];
|
|
|
|
|
|
|
|
$.each(results, function(i, item) {
|
|
|
|
row = tpl.clone();
|
2014-04-08 05:33:24 -07:00
|
|
|
row.find('.search-result').html(item.display);
|
2014-04-08 03:54:56 -07:00
|
|
|
|
2014-04-08 05:33:24 -07:00
|
|
|
if (typeof callback === 'function') {
|
2014-04-08 03:54:56 -07:00
|
|
|
callback.call(this, el, item, row, container);
|
2014-04-08 05:33:24 -07:00
|
|
|
}
|
2014-04-08 03:54:56 -07:00
|
|
|
row.appendTo(resultContainer).show();
|
|
|
|
});
|
|
|
|
container.show();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear search results.
|
|
|
|
*
|
|
|
|
* @param jQuery container Search results container.
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.search.clearResults = function(container) {
|
|
|
|
container.children(':not(.search-result-tpl)').remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
$('#phpbb').click(function(e) {
|
|
|
|
var target = $(e.target);
|
|
|
|
|
|
|
|
if (!target.is('.live-search') && !target.parents().is('.live-search')) {
|
|
|
|
$('.live-search').hide();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-05-06 13:34:12 -07:00
|
|
|
phpbb.history = {};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether a method in the native history object is supported.
|
|
|
|
*
|
|
|
|
* @param string fn Method name.
|
|
|
|
* @return bool Returns true if the method is supported.
|
|
|
|
*/
|
|
|
|
phpbb.history.isSupported = function(fn) {
|
|
|
|
if (typeof history === 'undefined' || typeof history[fn] === 'undefined') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for the pushState and replaceState methods of the
|
|
|
|
* native history object.
|
|
|
|
*
|
|
|
|
* @param string mode Mode. Either push or replace.
|
|
|
|
* @param string url New URL.
|
|
|
|
* @param string title Optional page title.
|
|
|
|
* @patam object obj Optional state object.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.history.alterUrl = function(mode, url, title, obj) {
|
|
|
|
var fn = mode + 'State';
|
|
|
|
|
|
|
|
if (!url || !phpbb.history.isSupported(fn)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!title) {
|
|
|
|
title = document.title;
|
|
|
|
}
|
|
|
|
if (!obj) {
|
|
|
|
obj = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
history[fn](obj, title, url);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for the native history.replaceState method.
|
|
|
|
*
|
|
|
|
* @param string url New URL.
|
|
|
|
* @param string title Optional page title.
|
|
|
|
* @patam object obj Optional state object.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.history.replaceUrl = function(url, title, obj) {
|
|
|
|
phpbb.history.alterUrl('replace', url, title, obj);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for the native history.pushState method.
|
|
|
|
*
|
|
|
|
* @param string url New URL.
|
|
|
|
* @param string title Optional page title.
|
|
|
|
* @patam object obj Optional state object.
|
|
|
|
*
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.history.pushUrl = function(url, title, obj) {
|
|
|
|
phpbb.history.alterUrl('push', url, title, obj);
|
|
|
|
};
|
|
|
|
|
2012-06-19 18:57:20 +02:00
|
|
|
/**
|
|
|
|
* Hide the optgroups that are not the selected timezone
|
|
|
|
*
|
2013-01-04 22:46:12 +01:00
|
|
|
* @param bool keepSelection Shall we keep the value selected, or shall the user be forced to repick one.
|
2012-06-19 18:57:20 +02:00
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.timezoneSwitchDate = function(keepSelection) {
|
2013-02-27 23:12:34 +01:00
|
|
|
if ($('#timezone_copy').length === 0) {
|
2012-07-23 18:13:22 +02:00
|
|
|
// We make a backup of the original dropdown, so we can remove optgroups
|
|
|
|
// instead of setting display to none, because IE and chrome will not
|
|
|
|
// hide options inside of optgroups and selects via css
|
|
|
|
$('#timezone').clone().attr('id', 'timezone_copy').css('display', 'none').attr('name', 'tz_copy').insertAfter('#timezone');
|
|
|
|
} else {
|
|
|
|
// Copy the content of our backup, so we can remove all unneeded options
|
|
|
|
$('#timezone').replaceWith($('#timezone_copy').clone().attr('id', 'timezone').css('display', 'block').attr('name', 'tz'));
|
|
|
|
}
|
|
|
|
|
2013-02-27 23:12:34 +01:00
|
|
|
if ($('#tz_date').val() !== '') {
|
2012-07-23 18:13:22 +02:00
|
|
|
$('#timezone > optgroup').remove(":not([label='" + $('#tz_date').val() + "'])");
|
|
|
|
}
|
2012-06-19 18:57:20 +02:00
|
|
|
|
2013-02-27 23:12:34 +01:00
|
|
|
if ($('#tz_date').val() === $('#tz_select_date_suggest').attr('data-suggested-tz')) {
|
2012-07-19 10:34:21 +02:00
|
|
|
$('#tz_select_date_suggest').css('display', 'none');
|
|
|
|
} else {
|
|
|
|
$('#tz_select_date_suggest').css('display', 'inline');
|
|
|
|
}
|
|
|
|
|
2013-02-27 23:12:34 +01:00
|
|
|
if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() === 1) {
|
2012-06-19 18:57:20 +02:00
|
|
|
// If there is only one timezone for the selected date, we just select that automatically.
|
2014-04-01 17:58:56 -07:00
|
|
|
$("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").prop('selected', true);
|
2013-01-04 22:46:12 +01:00
|
|
|
keepSelection = true;
|
2012-06-19 18:57:20 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 22:46:12 +01:00
|
|
|
if (typeof keepSelection !== 'undefined' && !keepSelection) {
|
2013-01-02 22:05:14 +01:00
|
|
|
var timezoneOptions = $('#timezone > optgroup option');
|
|
|
|
if (timezoneOptions.filter(':selected').length <= 0) {
|
2014-04-01 17:58:56 -07:00
|
|
|
timezoneOptions.filter(':first').prop('selected', true);
|
2013-01-02 22:05:14 +01:00
|
|
|
}
|
2012-06-19 18:57:20 +02:00
|
|
|
}
|
2013-01-04 22:46:12 +01:00
|
|
|
};
|
2012-06-19 18:57:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Display the date/time select
|
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.timezoneEnableDateSelection = function() {
|
2012-06-19 18:57:20 +02:00
|
|
|
$('#tz_select_date').css('display', 'block');
|
2013-01-04 22:46:12 +01:00
|
|
|
};
|
2012-06-19 18:57:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Preselect a date/time or suggest one, if it is not picked.
|
|
|
|
*
|
2013-01-04 22:46:12 +01:00
|
|
|
* @param bool forceSelector Shall we select the suggestion?
|
2012-06-19 18:57:20 +02:00
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.timezonePreselectSelect = function(forceSelector) {
|
2012-06-19 18:57:20 +02:00
|
|
|
|
|
|
|
// The offset returned here is in minutes and negated.
|
|
|
|
// http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp
|
|
|
|
var offset = (new Date()).getTimezoneOffset();
|
2013-01-10 10:59:20 +01:00
|
|
|
var sign = '-';
|
2012-06-19 18:57:20 +02:00
|
|
|
|
|
|
|
if (offset < 0) {
|
2013-01-10 10:59:20 +01:00
|
|
|
sign = '+';
|
2012-06-19 18:57:20 +02:00
|
|
|
offset = -offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
var minutes = offset % 60;
|
|
|
|
var hours = (offset - minutes) / 60;
|
|
|
|
|
|
|
|
if (hours < 10) {
|
|
|
|
hours = '0' + hours.toString();
|
|
|
|
} else {
|
|
|
|
hours = hours.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (minutes < 10) {
|
|
|
|
minutes = '0' + minutes.toString();
|
|
|
|
} else {
|
|
|
|
minutes = minutes.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
var prefix = 'GMT' + sign + hours + ':' + minutes;
|
2013-01-04 22:46:12 +01:00
|
|
|
var prefixLength = prefix.length;
|
|
|
|
var selectorOptions = $('#tz_date > option');
|
2013-01-10 10:59:20 +01:00
|
|
|
var i;
|
2012-06-19 18:57:20 +02:00
|
|
|
|
2013-01-10 10:59:20 +01:00
|
|
|
for (i = 0; i < selectorOptions.length; ++i) {
|
2013-01-04 22:46:12 +01:00
|
|
|
var option = selectorOptions[i];
|
2012-06-19 18:57:20 +02:00
|
|
|
|
2013-02-27 23:12:34 +01:00
|
|
|
if (option.value.substring(0, prefixLength) === prefix) {
|
|
|
|
if ($('#tz_date').val() !== option.value && !forceSelector) {
|
2012-06-19 18:57:20 +02:00
|
|
|
// We do not select the option for the user, but notify him,
|
|
|
|
// that we would suggest a different setting.
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.timezoneSwitchDate(true);
|
2012-07-24 17:09:26 +02:00
|
|
|
$('#tz_select_date_suggest').css('display', 'inline');
|
2012-06-19 18:57:20 +02:00
|
|
|
} else {
|
|
|
|
option.selected = true;
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.timezoneSwitchDate(!forceSelector);
|
2012-06-19 18:57:20 +02:00
|
|
|
$('#tz_select_date_suggest').css('display', 'none');
|
|
|
|
}
|
2012-07-24 17:09:26 +02:00
|
|
|
|
|
|
|
$('#tz_select_date_suggest').attr('title', $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML));
|
|
|
|
$('#tz_select_date_suggest').attr('value', $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML.substring(0, 9)));
|
|
|
|
$('#tz_select_date_suggest').attr('data-suggested-tz', option.innerHTML);
|
|
|
|
|
|
|
|
// Found the suggestion, there cannot be more, so return from here.
|
|
|
|
return;
|
2012-06-19 18:57:20 +02:00
|
|
|
}
|
|
|
|
}
|
2013-01-04 22:46:12 +01:00
|
|
|
};
|
2012-06-19 18:57:20 +02:00
|
|
|
|
2012-06-21 19:16:05 +01:00
|
|
|
phpbb.ajaxCallbacks = {};
|
2011-10-15 17:29:34 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds an AJAX callback to be used by phpbb.ajaxify.
|
|
|
|
*
|
|
|
|
* See the phpbb.ajaxify comments for information on stuff like parameters.
|
|
|
|
*
|
|
|
|
* @param string id The name of the callback.
|
|
|
|
* @param function callback The callback to be called.
|
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.addAjaxCallback = function(id, callback) {
|
2012-06-21 19:16:05 +01:00
|
|
|
if (typeof callback === 'function') {
|
|
|
|
phpbb.ajaxCallbacks[id] = callback;
|
2011-07-23 18:58:37 +01:00
|
|
|
}
|
|
|
|
return this;
|
2012-06-21 19:16:05 +01:00
|
|
|
};
|
2011-07-14 14:57:45 +01:00
|
|
|
|
2014-04-08 03:54:56 -07:00
|
|
|
/**
|
|
|
|
* This callback handles live member searches.
|
|
|
|
*/
|
|
|
|
phpbb.addAjaxCallback('member_search', function(res) {
|
2014-04-08 05:33:24 -07:00
|
|
|
phpbb.search.handleResponse(res, $(this), false, phpbb.getFunctionByName('phpbb.search.setValueOnClick'));
|
2014-04-08 03:54:56 -07:00
|
|
|
});
|
2011-07-14 17:49:17 +01:00
|
|
|
|
2011-10-22 16:16:15 +01:00
|
|
|
/**
|
|
|
|
* This callback alternates text - it replaces the current text with the text in
|
|
|
|
* the alt-text data attribute, and replaces the text in the attribute with the
|
|
|
|
* current text so that the process can be repeated.
|
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.addAjaxCallback('alt_text', function() {
|
2014-04-10 23:43:37 +05:30
|
|
|
var el,
|
|
|
|
updateAll = $(this).data('update-all'),
|
2012-06-21 19:16:05 +01:00
|
|
|
altText;
|
2012-02-08 19:38:21 +01:00
|
|
|
|
2014-04-10 23:43:37 +05:30
|
|
|
if (updateAll !== undefined && updateAll.length) {
|
|
|
|
el = $(updateAll);
|
|
|
|
} else {
|
|
|
|
el = $(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
el.each(function() {
|
|
|
|
var el = $(this);
|
|
|
|
altText = el.attr('data-alt-text');
|
|
|
|
el.attr('data-alt-text', el.text());
|
|
|
|
el.attr('title', $.trim(altText));
|
|
|
|
el.text(altText);
|
|
|
|
});
|
2011-09-25 16:02:26 +01:00
|
|
|
});
|
|
|
|
|
2012-04-18 17:03:24 +02:00
|
|
|
/**
|
|
|
|
* This callback is based on the alt_text callback.
|
|
|
|
*
|
|
|
|
* It replaces the current text with the text in the alt-text data attribute,
|
|
|
|
* and replaces the text in the attribute with the current text so that the
|
|
|
|
* process can be repeated.
|
2012-07-05 00:30:02 +02:00
|
|
|
* Additionally it replaces the class of the link's parent
|
|
|
|
* and changes the link itself.
|
2012-04-18 17:03:24 +02:00
|
|
|
*/
|
2013-01-04 22:46:12 +01:00
|
|
|
phpbb.addAjaxCallback('toggle_link', function() {
|
2014-04-10 23:43:37 +05:30
|
|
|
var el,
|
|
|
|
updateAll = $(this).data('update-all') ,
|
2013-01-04 22:46:12 +01:00
|
|
|
toggleText,
|
|
|
|
toggleUrl,
|
|
|
|
toggleClass;
|
2012-07-05 00:30:02 +02:00
|
|
|
|
2014-04-10 23:43:37 +05:30
|
|
|
if (updateAll !== undefined && updateAll.length) {
|
|
|
|
el = $(updateAll);
|
|
|
|
} else {
|
|
|
|
el = $(this);
|
|
|
|
}
|
2012-07-05 00:30:02 +02:00
|
|
|
|
2014-04-10 23:43:37 +05:30
|
|
|
el.each(function() {
|
|
|
|
var el = $(this);
|
2012-07-05 00:30:02 +02:00
|
|
|
|
2014-04-10 23:43:37 +05:30
|
|
|
// Toggle link text
|
|
|
|
toggleText = el.attr('data-toggle-text');
|
|
|
|
el.attr('data-toggle-text', el.text());
|
|
|
|
el.attr('title', $.trim(toggleText));
|
|
|
|
el.text(toggleText);
|
2012-07-05 00:30:02 +02:00
|
|
|
|
2014-04-10 23:43:37 +05:30
|
|
|
// Toggle link url
|
|
|
|
toggleUrl = el.attr('data-toggle-url');
|
|
|
|
el.attr('data-toggle-url', el.attr('href'));
|
|
|
|
el.attr('href', toggleUrl);
|
|
|
|
|
|
|
|
// Toggle class of link parent
|
|
|
|
toggleClass = el.attr('data-toggle-class');
|
|
|
|
el.attr('data-toggle-class', el.parent().attr('class'));
|
|
|
|
el.parent().attr('class', toggleClass);
|
|
|
|
});
|
2012-04-18 17:03:24 +02:00
|
|
|
});
|
2011-07-26 11:46:49 +01:00
|
|
|
|
2013-04-09 18:38:59 +03:00
|
|
|
/**
|
|
|
|
* Automatically resize textarea
|
|
|
|
*
|
2013-04-30 11:27:43 +03:00
|
|
|
* This function automatically resizes textarea elements when user
|
2013-04-09 18:38:59 +03:00
|
|
|
* types text.
|
|
|
|
*
|
2013-04-30 11:27:43 +03:00
|
|
|
* @param {jQuery} items jQuery object(s) to resize
|
|
|
|
* @param {object} options Optional parameter that adjusts default
|
2013-04-09 18:38:59 +03:00
|
|
|
* configuration. See configuration variable
|
2013-04-30 11:27:43 +03:00
|
|
|
*
|
|
|
|
* Optional parameters:
|
|
|
|
* minWindowHeight {number} Minimum browser window height when textareas are resized. Default = 500
|
|
|
|
* minHeight {number} Minimum height of textarea. Default = 200
|
|
|
|
* maxHeight {number} Maximum height of textarea. Default = 500
|
|
|
|
* heightDiff {number} Minimum difference between window and textarea height. Default = 200
|
|
|
|
* resizeCallback {function} Function to call after resizing textarea
|
|
|
|
* resetCallback {function} Function to call when resize has been canceled
|
|
|
|
|
|
|
|
* Callback function format: function(item) {}
|
|
|
|
* this points to DOM object
|
|
|
|
* item is a jQuery object, same as this
|
2013-04-09 18:38:59 +03:00
|
|
|
*/
|
2013-04-30 11:27:43 +03:00
|
|
|
phpbb.resizeTextArea = function(items, options) {
|
2013-04-09 18:38:59 +03:00
|
|
|
// Configuration
|
|
|
|
var configuration = {
|
2013-04-30 11:27:43 +03:00
|
|
|
minWindowHeight: 500,
|
|
|
|
minHeight: 200,
|
|
|
|
maxHeight: 500,
|
|
|
|
heightDiff: 200,
|
|
|
|
resizeCallback: function(item) { },
|
|
|
|
resetCallback: function(item) { }
|
|
|
|
};
|
2013-04-09 18:38:59 +03:00
|
|
|
|
2014-05-16 15:27:06 -07:00
|
|
|
if (phpbb.isTouch) return;
|
2013-10-31 10:29:46 +02:00
|
|
|
|
|
|
|
if (arguments.length > 1) {
|
2013-04-30 11:27:43 +03:00
|
|
|
configuration = $.extend(configuration, options);
|
2013-04-09 18:38:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function resetAutoResize(item)
|
|
|
|
{
|
|
|
|
var $item = $(item);
|
2013-10-18 23:43:32 +03:00
|
|
|
if ($item.hasClass('auto-resized')) {
|
2013-04-10 09:08:25 +03:00
|
|
|
$(item).css({height: '', resize: ''}).removeClass('auto-resized');
|
2013-04-09 18:38:59 +03:00
|
|
|
configuration.resetCallback.call(item, $item);
|
|
|
|
}
|
2013-04-30 11:27:43 +03:00
|
|
|
}
|
2013-04-09 18:38:59 +03:00
|
|
|
|
|
|
|
function autoResize(item)
|
|
|
|
{
|
|
|
|
function setHeight(height)
|
|
|
|
{
|
2013-10-18 23:43:32 +03:00
|
|
|
height += parseInt($item.css('height')) - $item.height();
|
2013-04-10 09:08:25 +03:00
|
|
|
$item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized');
|
2013-04-09 18:38:59 +03:00
|
|
|
configuration.resizeCallback.call(item, $item);
|
|
|
|
}
|
|
|
|
|
|
|
|
var windowHeight = $(window).height();
|
|
|
|
|
2013-10-18 23:43:32 +03:00
|
|
|
if (windowHeight < configuration.minWindowHeight) {
|
2013-04-09 18:38:59 +03:00
|
|
|
resetAutoResize(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var maxHeight = Math.min(Math.max(windowHeight - configuration.heightDiff, configuration.minHeight), configuration.maxHeight),
|
|
|
|
$item = $(item),
|
|
|
|
height = parseInt($item.height()),
|
|
|
|
scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0;
|
|
|
|
|
2013-10-18 23:43:32 +03:00
|
|
|
if (height < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (height > maxHeight) {
|
2013-04-09 18:38:59 +03:00
|
|
|
setHeight(maxHeight);
|
|
|
|
}
|
2013-10-18 23:43:32 +03:00
|
|
|
else if (scrollHeight > (height + 5)) {
|
2013-04-09 18:38:59 +03:00
|
|
|
setHeight(Math.min(maxHeight, scrollHeight));
|
|
|
|
}
|
2013-04-30 11:27:43 +03:00
|
|
|
}
|
2013-04-09 18:38:59 +03:00
|
|
|
|
|
|
|
items.bind('focus change keyup', function() {
|
|
|
|
$(this).each(function() {
|
|
|
|
autoResize(this);
|
|
|
|
});
|
2013-04-10 09:08:25 +03:00
|
|
|
}).change();
|
2013-04-09 18:38:59 +03:00
|
|
|
|
|
|
|
$(window).resize(function() {
|
|
|
|
items.each(function() {
|
2013-10-18 23:43:32 +03:00
|
|
|
if ($(this).hasClass('auto-resized')) {
|
2013-04-09 18:38:59 +03:00
|
|
|
autoResize(this);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-05-22 20:52:15 +03:00
|
|
|
/**
|
|
|
|
* Check if cursor in textarea is currently inside a bbcode tag
|
|
|
|
*
|
|
|
|
* @param {object} textarea Textarea DOM object
|
|
|
|
* @param {Array} startTags List of start tags to look for
|
|
|
|
* For example, Array('[code]', '[code=')
|
|
|
|
* @param {Array} endTags List of end tags to look for
|
|
|
|
* For example, Array('[/code]')
|
|
|
|
*
|
|
|
|
* @return {boolean} True if cursor is in bbcode tag
|
|
|
|
*/
|
|
|
|
phpbb.inBBCodeTag = function(textarea, startTags, endTags) {
|
|
|
|
var start = textarea.selectionStart,
|
|
|
|
lastEnd = -1,
|
|
|
|
lastStart = -1,
|
|
|
|
i, index, value;
|
|
|
|
|
|
|
|
if (typeof start !== 'number') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = textarea.value.toLowerCase();
|
|
|
|
|
|
|
|
for (i = 0; i < startTags.length; i++) {
|
|
|
|
var tagLength = startTags[i].length;
|
|
|
|
if (start >= tagLength) {
|
|
|
|
index = value.lastIndexOf(startTags[i], start - tagLength);
|
|
|
|
lastStart = Math.max(lastStart, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lastStart == -1) return false;
|
|
|
|
|
|
|
|
if (start > 0) {
|
|
|
|
for (i = 0; i < endTags.length; i++) {
|
|
|
|
index = value.lastIndexOf(endTags[i], start - 1);
|
|
|
|
lastEnd = Math.max(lastEnd, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (lastEnd < lastStart);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-20 20:29:37 +03:00
|
|
|
/**
|
|
|
|
* Adjust textarea to manage code bbcode
|
|
|
|
*
|
|
|
|
* This function allows to use tab characters when typing code
|
|
|
|
* and keeps indentation of previous line of code when adding new
|
|
|
|
* line while typing code.
|
|
|
|
*
|
|
|
|
* Editor's functionality is changed only when cursor is between
|
|
|
|
* [code] and [/code] bbcode tags.
|
|
|
|
*
|
|
|
|
* @param {object} textarea Textarea DOM object to apply editor to
|
|
|
|
*/
|
|
|
|
phpbb.applyCodeEditor = function(textarea) {
|
|
|
|
// list of allowed start and end bbcode code tags, in lower case
|
|
|
|
var startTags = ['[code]', '[code='],
|
|
|
|
startTagsEnd = ']',
|
|
|
|
endTags = ['[/code]'];
|
|
|
|
|
2013-05-20 20:33:51 +03:00
|
|
|
if (!textarea || typeof textarea.selectionStart !== 'number') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-05-20 20:29:37 +03:00
|
|
|
if ($(textarea).data('code-editor') === true) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
function inTag() {
|
2013-05-22 20:52:15 +03:00
|
|
|
return phpbb.inBBCodeTag(textarea, startTags, endTags);
|
2013-05-20 20:29:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get line of text before cursor
|
|
|
|
*
|
|
|
|
* @param {boolean} stripCodeStart If true, only part of line
|
|
|
|
* after [code] tag will be returned.
|
|
|
|
*
|
|
|
|
* @return {string} Line of text
|
|
|
|
*/
|
|
|
|
function getLastLine(stripCodeStart) {
|
|
|
|
var start = textarea.selectionStart,
|
|
|
|
value = textarea.value,
|
|
|
|
index = value.lastIndexOf("\n", start - 1);
|
|
|
|
|
|
|
|
value = value.substring(index + 1, start);
|
|
|
|
|
|
|
|
if (stripCodeStart) {
|
|
|
|
for (var i = 0; i < startTags.length; i++) {
|
|
|
|
index = value.lastIndexOf(startTags[i]);
|
|
|
|
if (index >= 0) {
|
|
|
|
var tagLength = startTags[i].length;
|
|
|
|
|
|
|
|
value = value.substring(index + tagLength);
|
|
|
|
if (startTags[i].lastIndexOf(startTagsEnd) != tagLength) {
|
|
|
|
index = value.indexOf(startTagsEnd);
|
|
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
value = value.substr(index + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Append text at cursor position
|
|
|
|
*
|
|
|
|
* @param {string} Text Text to append
|
|
|
|
*/
|
|
|
|
function appendText(text) {
|
|
|
|
var start = textarea.selectionStart,
|
|
|
|
end = textarea.selectionEnd,
|
|
|
|
value = textarea.value;
|
|
|
|
|
|
|
|
textarea.value = value.substr(0, start) + text + value.substr(end);
|
|
|
|
textarea.selectionStart = textarea.selectionEnd = start + text.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
$(textarea).data('code-editor', true).on('keydown', function(event) {
|
|
|
|
var key = event.keyCode || event.which;
|
|
|
|
|
|
|
|
// intercept tabs
|
2014-06-13 12:10:38 +01:00
|
|
|
if (key == keymap.TAB &&
|
|
|
|
!event.ctrlKey &&
|
|
|
|
!event.shiftKey &&
|
|
|
|
!event.altKey &&
|
2014-06-07 17:08:05 +01:00
|
|
|
!event.metaKey) {
|
2013-05-20 20:29:37 +03:00
|
|
|
if (inTag()) {
|
|
|
|
appendText("\t");
|
|
|
|
event.preventDefault();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// intercept new line characters
|
2014-06-13 12:10:38 +01:00
|
|
|
if (key == keymap.ENTER) {
|
2013-05-20 20:29:37 +03:00
|
|
|
if (inTag()) {
|
|
|
|
var lastLine = getLastLine(true),
|
|
|
|
code = '' + /^\s*/g.exec(lastLine);
|
|
|
|
|
|
|
|
if (code.length > 0) {
|
|
|
|
appendText("\n" + code);
|
|
|
|
event.preventDefault();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-10-26 16:35:59 +03:00
|
|
|
/**
|
|
|
|
* List of classes that toggle dropdown menu,
|
|
|
|
* list of classes that contain visible dropdown menu
|
|
|
|
*
|
|
|
|
* Add your own classes to strings with comma (probably you
|
|
|
|
* will never need to do that)
|
|
|
|
*/
|
|
|
|
phpbb.dropdownHandles = '.dropdown-container.dropdown-visible .dropdown-toggle';
|
|
|
|
phpbb.dropdownVisibleContainers = '.dropdown-container.dropdown-visible';
|
|
|
|
|
2013-10-26 16:29:37 +03:00
|
|
|
/**
|
|
|
|
* Dropdown toggle event handler
|
|
|
|
* This handler is used by phpBB.registerDropdown() and other functions
|
|
|
|
*/
|
|
|
|
phpbb.toggleDropdown = function() {
|
|
|
|
var $this = $(this),
|
|
|
|
options = $this.data('dropdown-options'),
|
|
|
|
parent = options.parent,
|
|
|
|
visible = parent.hasClass('dropdown-visible');
|
|
|
|
|
|
|
|
if (!visible) {
|
|
|
|
// Hide other dropdown menus
|
2013-10-26 16:35:59 +03:00
|
|
|
$(phpbb.dropdownHandles).each(phpbb.toggleDropdown);
|
2013-10-26 16:29:37 +03:00
|
|
|
|
|
|
|
// Figure out direction of dropdown
|
|
|
|
var direction = options.direction,
|
|
|
|
verticalDirection = options.verticalDirection,
|
|
|
|
offset = $this.offset();
|
|
|
|
|
|
|
|
if (direction == 'auto') {
|
|
|
|
if (($(window).width() - $this.outerWidth(true)) / 2 > offset.left) {
|
|
|
|
direction = 'right';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
direction = 'left';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parent.toggleClass(options.leftClass, direction == 'left').toggleClass(options.rightClass, direction == 'right');
|
|
|
|
|
|
|
|
if (verticalDirection == 'auto') {
|
|
|
|
var height = $(window).height(),
|
|
|
|
top = offset.top - $(window).scrollTop();
|
|
|
|
|
|
|
|
if (top < height * 0.7) {
|
|
|
|
verticalDirection = 'down';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
verticalDirection = 'up';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parent.toggleClass(options.upClass, verticalDirection == 'up').toggleClass(options.downClass, verticalDirection == 'down');
|
|
|
|
}
|
|
|
|
|
|
|
|
options.dropdown.toggle();
|
|
|
|
parent.toggleClass(options.visibleClass, !visible).toggleClass('dropdown-visible', !visible);
|
|
|
|
|
|
|
|
// Check dimensions when showing dropdown
|
|
|
|
// !visible because variable shows state of dropdown before it was toggled
|
|
|
|
if (!visible) {
|
2014-04-10 05:18:57 -07:00
|
|
|
var windowWidth = $(window).width();
|
|
|
|
|
2013-10-26 16:29:37 +03:00
|
|
|
options.dropdown.find('.dropdown-contents').each(function() {
|
2014-04-10 05:18:57 -07:00
|
|
|
var $this = $(this);
|
2013-10-26 16:29:37 +03:00
|
|
|
|
|
|
|
$this.css({
|
|
|
|
marginLeft: 0,
|
|
|
|
left: 0,
|
|
|
|
maxWidth: (windowWidth - 4) + 'px'
|
|
|
|
});
|
|
|
|
|
|
|
|
var offset = $this.offset().left,
|
|
|
|
width = $this.outerWidth(true);
|
|
|
|
|
|
|
|
if (offset < 2) {
|
|
|
|
$this.css('left', (2 - offset) + 'px');
|
|
|
|
}
|
|
|
|
else if ((offset + width + 2) > windowWidth) {
|
|
|
|
$this.css('margin-left', (windowWidth - offset - width - 2) + 'px');
|
|
|
|
}
|
|
|
|
});
|
2014-04-10 05:18:57 -07:00
|
|
|
var freeSpace = parent.offset().left - 4;
|
|
|
|
|
|
|
|
if (direction == 'left') {
|
|
|
|
options.dropdown.css('margin-left', '-' + freeSpace + 'px');
|
|
|
|
} else {
|
|
|
|
options.dropdown.css('margin-right', '-' + (windowWidth + freeSpace) + 'px');
|
|
|
|
}
|
2013-10-26 16:29:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Prevent event propagation
|
|
|
|
if (arguments.length > 0) {
|
|
|
|
try {
|
|
|
|
var e = arguments[0];
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
|
|
|
catch (error) { }
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2013-11-08 11:32:42 -08:00
|
|
|
/**
|
|
|
|
* Toggle dropdown submenu
|
|
|
|
*/
|
|
|
|
phpbb.toggleSubmenu = function(e) {
|
|
|
|
$(this).siblings('.dropdown-submenu').toggle();
|
|
|
|
e.preventDefault();
|
|
|
|
}
|
|
|
|
|
2013-10-26 16:29:37 +03:00
|
|
|
/**
|
|
|
|
* Register dropdown menu
|
|
|
|
* Shows/hides dropdown, decides which side to open to
|
|
|
|
*
|
|
|
|
* @param {jQuery} toggle Link that toggles dropdown.
|
|
|
|
* @param {jQuery} dropdown Dropdown menu.
|
|
|
|
* @param {Object} options List of options. Optional.
|
|
|
|
*/
|
|
|
|
phpbb.registerDropdown = function(toggle, dropdown, options)
|
|
|
|
{
|
|
|
|
var ops = {
|
|
|
|
parent: toggle.parent(), // Parent item to add classes to
|
|
|
|
direction: 'auto', // Direction of dropdown menu. Possible values: auto, left, right
|
|
|
|
verticalDirection: 'auto', // Vertical direction. Possible values: auto, up, down
|
|
|
|
visibleClass: 'visible', // Class to add to parent item when dropdown is visible
|
|
|
|
leftClass: 'dropdown-left', // Class to add to parent item when dropdown opens to left side
|
|
|
|
rightClass: 'dropdown-right', // Class to add to parent item when dropdown opens to right side
|
|
|
|
upClass: 'dropdown-up', // Class to add to parent item when dropdown opens above menu item
|
|
|
|
downClass: 'dropdown-down' // Class to add to parent item when dropdown opens below menu item
|
|
|
|
};
|
|
|
|
if (options) {
|
|
|
|
ops = $.extend(ops, options);
|
|
|
|
}
|
|
|
|
ops.dropdown = dropdown;
|
|
|
|
|
|
|
|
ops.parent.addClass('dropdown-container');
|
|
|
|
toggle.addClass('dropdown-toggle');
|
|
|
|
|
|
|
|
toggle.data('dropdown-options', ops);
|
|
|
|
|
|
|
|
toggle.click(phpbb.toggleDropdown);
|
2013-11-08 11:32:42 -08:00
|
|
|
$('.dropdown-toggle-submenu', ops.parent).click(phpbb.toggleSubmenu);
|
2013-10-26 16:29:37 +03:00
|
|
|
};
|
|
|
|
|
2013-11-12 23:57:27 -08:00
|
|
|
/**
|
2013-11-13 00:14:35 -08:00
|
|
|
* Get the HTML for a color palette table.
|
|
|
|
*
|
|
|
|
* @param string dir Palette direction - either v or h
|
|
|
|
* @param int width Palette cell width.
|
|
|
|
* @param int height Palette cell height.
|
2013-11-12 23:57:27 -08:00
|
|
|
*/
|
|
|
|
phpbb.colorPalette = function(dir, width, height) {
|
|
|
|
var r = 0,
|
|
|
|
g = 0,
|
|
|
|
b = 0,
|
|
|
|
numberList = new Array(6),
|
|
|
|
color = '',
|
|
|
|
html = '';
|
|
|
|
|
|
|
|
numberList[0] = '00';
|
|
|
|
numberList[1] = '40';
|
|
|
|
numberList[2] = '80';
|
|
|
|
numberList[3] = 'BF';
|
|
|
|
numberList[4] = 'FF';
|
|
|
|
|
2014-02-16 13:25:01 -08:00
|
|
|
var table_class = (dir == 'h') ? 'horizontal-palette' : 'vertical-palette';
|
|
|
|
html += '<table class="not-responsive colour-palette ' + table_class + '" style="width: auto;">';
|
2013-11-12 23:57:27 -08:00
|
|
|
|
|
|
|
for (r = 0; r < 5; r++) {
|
|
|
|
if (dir == 'h') {
|
|
|
|
html += '<tr>';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (g = 0; g < 5; g++) {
|
|
|
|
if (dir == 'v') {
|
|
|
|
html += '<tr>';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (b = 0; b < 5; b++) {
|
|
|
|
color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]);
|
|
|
|
html += '<td style="background-color: #' + color + '; width: ' + width + 'px; height: ' + height + 'px;">';
|
2013-11-13 00:14:35 -08:00
|
|
|
html += '<a href="#" data-color="' + color + '" style="display: block; width: ' + width + 'px; height: ' + height + 'px; " alt="#' + color + '" title="#' + color + '"></a>';
|
2013-11-12 23:57:27 -08:00
|
|
|
html += '</td>';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dir == 'v') {
|
|
|
|
html += '</tr>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dir == 'h') {
|
|
|
|
html += '</tr>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
html += '</table>';
|
|
|
|
return html;
|
|
|
|
}
|
|
|
|
|
2013-11-13 00:14:35 -08:00
|
|
|
/**
|
|
|
|
* Register a color palette.
|
|
|
|
*
|
|
|
|
* @param object el jQuery object for the palette container.
|
|
|
|
*/
|
|
|
|
phpbb.registerPalette = function(el) {
|
|
|
|
var orientation = el.attr('data-orientation'),
|
|
|
|
height = el.attr('data-height'),
|
|
|
|
width = el.attr('data-width'),
|
|
|
|
target = el.attr('data-target'),
|
|
|
|
bbcode = el.attr('data-bbcode');
|
|
|
|
|
|
|
|
// Insert the palette HTML into the container.
|
|
|
|
el.html(phpbb.colorPalette(orientation, width, height));
|
|
|
|
|
|
|
|
// Add toggle control.
|
|
|
|
$('#color_palette_toggle').click(function(e) {
|
|
|
|
el.toggle();
|
|
|
|
e.preventDefault();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Attach event handler when a palette cell is clicked.
|
|
|
|
$(el).on('click', 'a', function(e) {
|
|
|
|
var color = $(this).attr('data-color');
|
|
|
|
|
|
|
|
if (bbcode) {
|
|
|
|
bbfontstyle('[color=#' + color + ']', '[/color]');
|
|
|
|
} else {
|
|
|
|
$(target).val(color);
|
|
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-04-07 21:27:48 +02:00
|
|
|
/**
|
|
|
|
* Set display of page element
|
|
|
|
*
|
|
|
|
* @param string id The ID of the element to change
|
|
|
|
* @param int action Set to 0 if element display should be toggled, -1 for
|
|
|
|
* hiding the element, and 1 for showing it.
|
|
|
|
* @param string type Display type that should be used, e.g. inline, block or
|
|
|
|
* other CSS "display" types
|
|
|
|
*/
|
2014-04-07 21:42:30 +02:00
|
|
|
phpbb.toggleDisplay = function(id, action, type) {
|
2014-04-07 21:27:48 +02:00
|
|
|
if (!type) {
|
|
|
|
type = 'block';
|
|
|
|
}
|
|
|
|
|
2014-04-11 11:31:22 +02:00
|
|
|
var display = $('#' + id).css('display');
|
2014-04-07 21:27:48 +02:00
|
|
|
if (!action) {
|
|
|
|
action = (display === '' || display === type) ? -1 : 1;
|
|
|
|
}
|
2014-04-11 11:31:22 +02:00
|
|
|
$('#' + id).css('display', ((action === 1) ? type : 'none'));
|
2014-04-07 21:27:48 +02:00
|
|
|
}
|
|
|
|
|
2014-05-06 17:50:22 -07:00
|
|
|
/**
|
|
|
|
* Toggle additional settings based on the selected
|
|
|
|
* option of select element.
|
|
|
|
*
|
|
|
|
* @param jQuery el jQuery select element object.
|
|
|
|
* @return undefined
|
|
|
|
*/
|
|
|
|
phpbb.toggleSelectSettings = function(el) {
|
|
|
|
el.children().each(function() {
|
|
|
|
var option = $(this),
|
|
|
|
setting = $(option.data('toggle-setting'));
|
|
|
|
setting.toggle(option.is(':selected'));
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-04-08 03:54:56 -07:00
|
|
|
/**
|
|
|
|
* Get function from name.
|
|
|
|
* Based on http://stackoverflow.com/a/359910
|
|
|
|
*
|
|
|
|
* @param string functionName Function to get.
|
|
|
|
* @return function
|
|
|
|
*/
|
|
|
|
phpbb.getFunctionByName = function (functionName) {
|
|
|
|
var namespaces = functionName.split('.'),
|
|
|
|
func = namespaces.pop(),
|
|
|
|
context = window;
|
|
|
|
|
|
|
|
for (var i = 0; i < namespaces.length; i++) {
|
|
|
|
context = context[namespaces[i]];
|
|
|
|
}
|
|
|
|
return context[func];
|
|
|
|
};
|
|
|
|
|
2013-05-20 20:29:37 +03:00
|
|
|
/**
|
2014-05-29 18:07:27 -07:00
|
|
|
* Register page dropdowns.
|
2013-05-20 20:29:37 +03:00
|
|
|
*/
|
2014-05-29 18:07:27 -07:00
|
|
|
phpbb.registerPageDropdowns = function() {
|
|
|
|
$('body').find('.dropdown-container').each(function() {
|
|
|
|
var $this = $(this),
|
|
|
|
trigger = $this.find('.dropdown-trigger:first'),
|
|
|
|
contents = $this.find('.dropdown'),
|
|
|
|
options = {
|
|
|
|
direction: 'auto',
|
|
|
|
verticalDirection: 'auto'
|
|
|
|
},
|
|
|
|
data;
|
|
|
|
|
|
|
|
if (!trigger.length) {
|
|
|
|
data = $this.attr('data-dropdown-trigger');
|
|
|
|
trigger = data ? $this.children(data) : $this.children('a:first');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!contents.length) {
|
|
|
|
data = $this.attr('data-dropdown-contents');
|
|
|
|
contents = data ? $this.children(data) : $this.children('div:first');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!trigger.length || !contents.length) return;
|
|
|
|
|
|
|
|
if ($this.hasClass('dropdown-up')) options.verticalDirection = 'up';
|
|
|
|
if ($this.hasClass('dropdown-down')) options.verticalDirection = 'down';
|
|
|
|
if ($this.hasClass('dropdown-left')) options.direction = 'left';
|
|
|
|
if ($this.hasClass('dropdown-right')) options.direction = 'right';
|
|
|
|
|
|
|
|
phpbb.registerDropdown(trigger, contents, options);
|
2013-05-20 20:29:37 +03:00
|
|
|
});
|
2013-10-26 16:35:59 +03:00
|
|
|
|
|
|
|
// Hide active dropdowns when click event happens outside
|
|
|
|
$('body').click(function(e) {
|
|
|
|
var parents = $(e.target).parents();
|
|
|
|
if (!parents.is(phpbb.dropdownVisibleContainers)) {
|
|
|
|
$(phpbb.dropdownHandles).each(phpbb.toggleDropdown);
|
|
|
|
}
|
|
|
|
});
|
2014-05-29 18:07:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply code editor to all textarea elements with data-bbcode attribute
|
|
|
|
*/
|
|
|
|
$(document).ready(function() {
|
|
|
|
$('textarea[data-bbcode]').each(function() {
|
|
|
|
phpbb.applyCodeEditor(this);
|
|
|
|
});
|
|
|
|
|
|
|
|
phpbb.registerPageDropdowns();
|
2013-11-12 23:57:27 -08:00
|
|
|
|
|
|
|
$('#color_palette_placeholder').each(function() {
|
2013-11-13 00:14:35 -08:00
|
|
|
phpbb.registerPalette($(this));
|
2013-11-12 23:57:27 -08:00
|
|
|
});
|
2014-05-05 15:08:18 -07:00
|
|
|
|
2014-05-06 13:34:12 -07:00
|
|
|
// Update browser history URL to point to specific post in viewtopic.php
|
|
|
|
// when using view=unread#unread link.
|
|
|
|
phpbb.history.replaceUrl($('#unread[data-url]').data('url'));
|
2014-05-06 17:50:22 -07:00
|
|
|
|
|
|
|
// Hide settings that are not selected via select element.
|
2014-05-09 13:49:41 -07:00
|
|
|
$('select[data-togglable-settings]').each(function() {
|
2014-05-06 17:50:22 -07:00
|
|
|
var select = $(this);
|
|
|
|
|
|
|
|
select.change(function() {
|
|
|
|
phpbb.toggleSelectSettings(select);
|
|
|
|
});
|
|
|
|
phpbb.toggleSelectSettings(select);
|
|
|
|
});
|
2013-05-20 20:29:37 +03:00
|
|
|
});
|
2013-04-09 18:38:59 +03:00
|
|
|
|
2011-09-27 19:32:06 +01:00
|
|
|
})(jQuery); // Avoid conflicts with other libraries
|