* @return {AjaxRequest}
*/
api: function(callbackObject, data) {
+ return this.apiProxy(callbackObject, data);
+ },
+
+ /**
+ * Shorthand function to perform a request against the WCF-API with overrides
+ * for success and failure callbacks.
+ *
+ * @param {object} callbackObject callback object
+ * @param {object<string, *>=} data request data
+ * @param {function=} success success callback
+ * @param {function=} failure failure callback
+ * @return {AjaxRequest}
+ */
+ apiProxy: function(callbackObject, data, success, failure) {
var request = _requests.get(callbackObject);
if (request !== undefined) {
data = data || {};
+ if (typeof success === 'function') request.setOption('success', success);
+ if (typeof failure === 'function') request.setOption('failure', failure);
+
request.setData(data || {});
request.sendRequest();
if (!options.url) options.url = 'index.php/AJAXProxy/?t=' + SECURITY_TOKEN;
request = new AjaxRequest(options);
+
+ if (typeof success === 'function') request.setOption('success', success);
+ if (typeof failure === 'function') request.setOption('failure', failure);
+
request.sendRequest();
_requests.set(callbackObject, request);
}
if (this._options.callbackObject !== null) {
- this._options.failure = (typeof this._options.callbackObject._ajaxFailure === 'function') ? this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject) : null;
- this._options.finalize = (typeof this._options.callbackObject._ajaxFinalize === 'function') ? this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject) : null;
- this._options.success = (typeof this._options.callbackObject._ajaxSuccess === 'function') ? this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject) : null;
+ if (typeof this._options.callbackObject._ajaxFailure === 'function') this._options.failure = this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject);
+ if (typeof this._options.callbackObject._ajaxFinalize === 'function') this._options.finalize = this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject);
+ if (typeof this._options.callbackObject._ajaxSuccess === 'function') this._options.success = this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject);
}
if (_didInit === false) {
this._xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
var self = this;
+
+ var options = Core.clone(this._options);
this._xhr.onload = function() {
if (this.readyState === XMLHttpRequest.DONE) {
if (this.status >= 200 && this.status < 300 || this.status === 304) {
- self._success(this);
+ self._success(this, options);
}
else {
- self._failure(this);
+ self._failure(this, options);
}
}
};
this._xhr.onerror = function() {
- self._failure(this);
+ self._failure(this, options);
};
if (this._options.type === 'POST') {
/**
* Handles a successful request.
*
- * @param {XMLHttpRequest} xhr request object
+ * @param {XMLHttpRequest} xhr request object
+ * @param {object<string, *>} options request options
*/
- _success: function(xhr) {
- if (!this._options.silent) {
+ _success: function(xhr, options) {
+ if (!options.silent) {
AjaxStatus.hide();
}
- if (typeof this._options.success === 'function') {
+ if (typeof options.success === 'function') {
var data = null;
if (xhr.getResponseHeader('Content-Type') === 'application/json') {
try {
}
}
- this._options.success(data, xhr.responseText, xhr);
+ options.success(data, xhr.responseText, xhr);
}
- this._finalize();
+ this._finalize(options);
},
/**
* Handles failed requests, this can be both a successful request with
* a non-success status code or an entirely failed request.
*
- * @param {XMLHttpRequest} xhr request object
+ * @param {XMLHttpRequest} xhr request object
+ * @param {object<string, *>} options request options
*/
- _failure: function (xhr) {
+ _failure: function (xhr, options) {
if (_ignoreAllErrors) {
return;
}
- if (!this._options.silent) {
+ if (!options.silent) {
AjaxStatus.hide();
}
catch (e) {}
var showError = true;
- if (typeof this._options.failure === 'function') {
- showError = this._options.failure(data, xhr);
+ if (typeof options.failure === 'function') {
+ showError = options.failure(data, xhr);
}
- if (this._options.ignoreError !== true && showError !== false) {
+ if (options.ignoreError !== true && showError !== false) {
var details = '';
var message = '';
});
}
- this._finalize();
+ this._finalize(options);
},
/**
* Finalizes a request.
+ *
+ * @param {object<string, *>} options request options
*/
- _finalize: function() {
- if (typeof this._options.finalize === 'function') {
- this._options.finalize(this._xhr);
+ _finalize: function(options) {
+ if (typeof options.finalize === 'function') {
+ options.finalize(this._xhr);
}
this._previousXhr = null;
window.clearTimeout(_timeoutShow);
}
+ console.debug("Removing 'active'!");
+ window.dt = _overlay;
_overlay.classList.remove('active');
}
+
+ console.debug(_activeRequests);
}
};
className: 'userLink',
identifier: 'com.woltlab.wcf.user',
loadCallback: function(objectId, popover) {
- Ajax.api({
- data: {
- actionName: 'getUserProfile',
- className: 'wcf\\data\\user\\UserProfileAction',
- objectIDs: [ objectId ]
- },
- success: (function(data) {
- popover.setContent('com.woltlab.wcf.user', objectId, data.returnValues.template);
- }).bind(this),
- failure: (function(data) {
- popover.setContent('com.woltlab.wcf.user', objectId, data.returnValues.template);
- }).bind(this)
- });
+ var callback = function(data) {
+ popover.setContent('com.woltlab.wcf.user', objectId, data.returnValues.template);
+ };
+
+ popover.ajaxApi({
+ actionName: 'getUserProfile',
+ className: 'wcf\\data\\user\\UserProfileAction',
+ objectIDs: [ objectId ]
+ }, callback, callback);
}
});
}
_click: function(event) {
var button = event.currentTarget;
- Ajax.api({
+ Ajax.apiOnce({
data: {
actionName: 'dismiss',
className: 'wcf\\data\\notice\\NoticeAction',
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLab/WCF/Controller/Popover
*/
-define(['Dictionary', 'Environment', 'DOM/ChangeListener', 'DOM/Util', 'UI/Alignment'], function(Dictionary, Environment, DOMChangeListener, DOMUtil, UIAlignment) {
+define(['Ajax', 'Dictionary', 'Environment', 'DOM/ChangeListener', 'DOM/Util', 'UI/Alignment'], function(Ajax, Dictionary, Environment, DOMChangeListener, DOMUtil, UIAlignment) {
"use strict";
var _activeId = null;
vertical: 'top',
verticalOffset: 3
});
+ },
+
+ _ajaxSetup: function() {
+ // does nothing
+ return {};
+ },
+
+ /**
+ * Sends an AJAX requests to the server, simple wrapper to reuse the request object.
+ *
+ * @param {object<string, *>} data request data
+ * @param {function<object>} success success callback
+ * @param {function<object>=} failure error callback
+ */
+ ajaxApi: function(data, success, failure) {
+ if (typeof success !== 'function') {
+ throw new TypeError("Expected a valid callback for parameter 'success'.");
+ }
+
+ Ajax.apiProxy(this, data, success, failure);
}
};
event.preventDefault();
if (UIDialog.getDialog('styleChanger') === undefined) {
- Ajax.api({
+ Ajax.apiOnce({
data: {
actionName: 'getStyleChooser',
className: 'wcf\\data\\style\\StyleAction'
_click: function(event) {
event.preventDefault();
- Ajax.api({
+ Ajax.apiOnce({
data: {
actionName: 'changeStyle',
className: 'wcf\\data\\style\\StyleAction',
define([], function() {
"use strict";
+ var _clone = function(variable) {
+ if (typeof variable === 'object' && variable !== null) {
+ return _cloneObject(variable);
+ }
+
+ return variable;
+ };
+
+ var _cloneArray = function(oldArray) {
+ var i = oldArray.length;
+ var newArray = new Array(i);
+
+ while (i--) {
+ newArray[i] = oldArray[i];
+ }
+
+ return newArray;
+ };
+
+ var _cloneObject = function(obj) {
+ if (!obj) {
+ return null;
+ }
+
+ if (Array.isArray(obj)) {
+ return _cloneArray(obj);
+ }
+
+ var newObj = {};
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') {
+ newObj[key] = _clone(obj[key]);
+ }
+ }
+
+ return newObj;
+ };
+
/**
* @constructor
*/
function Core() {};
Core.prototype = {
+ /**
+ * Deep clones an object.
+ *
+ * @param {object} obj source object
+ * @return {object} cloned object
+ */
+ clone: function(obj) {
+ return _clone(obj);
+ },
+
/**
* Converts WCF 2.0-style URLs into the default URL layout.
*
box-sizing: border-box;
color: #fff;
left: 50%;
+ opacity: 0;
padding: 7px;
position: fixed;
text-align: center;
top: 200px;
+ visibility: hidden;
z-index: 401;
transform: translateX(-50%);
.boxShadow(0, 1px, rgba(0, 0, 0, .5), 7px);
.linearGradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, 0), rgba(0, 0, 0, .7));
+ transition: visibility 0s linear .1s, opacity .1s linear;
+
+ &.active {
+ opacity: 1;
+ visibility: visible;
+
+ transition-delay: 0s;
+ }
+
> .icon {
color: #fff;
}