/**\r
* Class and function collection for WCF\r
- *\r
+ * \r
* @author Alexander Ebert\r
* @copyright 2001-2011 WoltLab GmbH\r
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>\r
wcfEscapeID: function(id) {\r
return id.replace(/(:|\.)/g, '\\$1');\r
},\r
-\r
+ \r
/**\r
* Returns true if given ID exists within DOM.\r
- *\r
+ * \r
* @param string id\r
* @return boolean\r
*/\r
$.fn.extend({\r
/**\r
* Returns tag name of current jQuery element.\r
- *\r
+ * \r
* @returns string\r
*/\r
getTagName: function() {\r
return this.get(0).tagName.toLowerCase();\r
},\r
-\r
+ \r
/**\r
* Returns the dimensions for current element.\r
- *\r
+ * \r
* @see http://api.jquery.com/hidden-selector/\r
* @param string type\r
* @return object\r
getDimensions: function(type) {\r
var dimensions = css = {};\r
var wasHidden = false;\r
-\r
+ \r
// show element to retrieve dimensions and restore them later\r
if (this.is(':hidden')) {\r
css = {\r
display: this.css('display'),\r
visibility: this.css('visibility')\r
};\r
-\r
+ \r
wasHidden = true;\r
-\r
+ \r
this.css({\r
display: 'block',\r
visibility: 'hidden'\r
});\r
}\r
-\r
+ \r
switch (type) {\r
case 'inner':\r
dimensions = {\r
width: this.innerWidth()\r
};\r
break;\r
-\r
+ \r
case 'outer':\r
dimensions = {\r
height: this.outerHeight(),\r
width: this.outerWidth()\r
};\r
break;\r
-\r
+ \r
default:\r
dimensions = {\r
height: this.height(),\r
};\r
break;\r
}\r
-\r
+ \r
// restore previous settings\r
if (wasHidden) {\r
this.css(css);\r
}\r
-\r
+ \r
return dimensions;\r
},\r
-\r
+ \r
/**\r
* Returns the offsets for current element, defaults to position\r
* relative to document.\r
- *\r
+ * \r
* @see http://api.jquery.com/hidden-selector/\r
* @param string type\r
* @return object\r
getOffsets: function(type) {\r
var offsets = css = {};\r
var wasHidden = false;\r
-\r
+ \r
// show element to retrieve dimensions and restore them later\r
if (this.is(':hidden')) {\r
css = {\r
display: this.css('display'),\r
visibility: this.css('visibility')\r
};\r
-\r
+ \r
wasHidden = true;\r
-\r
+ \r
this.css({\r
display: 'block',\r
visibility: 'hidden'\r
});\r
}\r
-\r
+ \r
switch (type) {\r
case 'offset':\r
offsets = this.offset();\r
break;\r
-\r
+ \r
case 'position':\r
default:\r
offsets = this.position();\r
break;\r
}\r
-\r
+ \r
// restore previous settings\r
if (wasHidden) {\r
this.css(css);\r
}\r
-\r
+ \r
return offsets;\r
},\r
-\r
+ \r
/**\r
* Changes element's position to 'absolute' or 'fixed' while maintaining it's\r
* current position relative to viewport. Optionally removes element from\r
* current DOM-node and moving it into body-element (useful for drag & drop)\r
- *\r
+ * \r
* @param boolean rebase\r
* @return object\r
*/\r
if (position != 'absolute' && position != 'fixed') {\r
position = 'absolute';\r
}\r
-\r
+ \r
var $currentPosition = this.getOffsets('position');\r
this.css({\r
position: position,\r
margin: 0,\r
top: $currentPosition.top\r
});\r
-\r
+ \r
if (rebase) {\r
this.remove().appentTo('body');\r
}\r
-\r
+ \r
return this;\r
},\r
-\r
+ \r
/**\r
* Disables a form element.\r
- *\r
+ * \r
* @return jQuery\r
*/\r
disable: function() {\r
return this.attr('disabled', 'disabled');\r
},\r
-\r
+ \r
/**\r
* Enables a form element.\r
- *\r
+ * \r
* @return jQuery\r
*/\r
enable: function() {\r
return this.removeAttr('disabled');\r
},\r
-\r
+ \r
/**\r
* Applies a grow-effect by resizing element while moving the\r
* element appropriately\r
- *\r
+ * \r
* @param object data\r
* @param object options\r
* @return jQuery\r
var $tempElementID = WCF.getRandomID();\r
$('body').append('<div id="' + $tempElementID + '" class="wcfDimensions">' + data.content + '</div>');\r
var $tempElement = $('#' + $tempElementID);\r
-\r
+ \r
// get content dimensions\r
var $dimensions = $tempElement.getDimensions();\r
-\r
+ \r
// remove temporarily element\r
$tempElement.empty().remove();\r
-\r
+ \r
// move parent element, used if applying effect on dialogs\r
if (!data.parent) {\r
data.parent = this;\r
}\r
-\r
+ \r
// calculate values for grow-effect\r
var $borderHeight = parseInt(data.parent.css('borderTopWidth')) + parseInt(data.parent.css('borderBottomWidth'));\r
var $borderWidth = parseInt(data.parent.css('borderLeftWidth')) + parseInt(data.parent.css('borderRightWidth'));\r
-\r
+ \r
var $windowDimensions = $(window).getDimensions();\r
var $leftOffset = Math.round(($windowDimensions.width - ($dimensions.width + $borderWidth)) / 2);\r
var $topOffset = Math.round(($windowDimensions.height - ($dimensions.height + $borderHeight)) / 2);\r
-\r
+ \r
data.parent.makePositioned('fixed', false);\r
data.parent.animate({\r
left: $leftOffset + 'px',\r
top: $topOffset + 'px'\r
}, options);\r
-\r
+ \r
return this.animate({\r
height: $dimensions.height,\r
width: $dimensions.width\r
}, options);\r
},\r
-\r
+ \r
/**\r
* Shows an element by sliding and fading it into viewport.\r
- *\r
+ * \r
* @param string direction\r
* @param object callback\r
* @returns jQuery\r
*/\r
wcfDropIn: function(direction, callback) {\r
if (!direction) direction = 'up';\r
-\r
+ \r
return this.show(WCF.getEffect(this.getTagName(), 'drop'), { direction: direction }, 600, callback);\r
},\r
-\r
+ \r
/**\r
* Hides an element by sliding and fading it out the viewport.\r
- *\r
+ * \r
* @param string direction\r
* @param object callback\r
* @returns jQuery\r
*/\r
wcfDropOut: function(direction, callback) {\r
if (!direction) direction = 'down';\r
-\r
+ \r
return this.hide(WCF.getEffect(this.getTagName(), 'drop'), { direction: direction }, 600, callback);\r
},\r
-\r
+ \r
/**\r
* Shows an element by blinding it up.\r
- *\r
+ * \r
* @param string direction\r
* @param object callback\r
* @returns jQuery\r
*/\r
wcfBlindIn: function(direction, callback) {\r
if (!direction) direction = 'vertical';\r
-\r
+ \r
return this.show(WCF.getEffect(this.getTagName(), 'blind'), { direction: direction }, 200, callback);\r
},\r
-\r
+ \r
/**\r
* Hides an element by blinding it down.\r
- *\r
+ * \r
* @param string direction\r
* @param object callback\r
* @returns jQuery\r
*/\r
wcfBlindOut: function(direction, callback) {\r
if (!direction) direction = 'vertical';\r
-\r
+ \r
return this.hide(WCF.getEffect(this.getTagName(), 'blind'), { direction: direction }, 200, callback);\r
},\r
-\r
+ \r
/**\r
* Highlights an element.\r
- *\r
+ * \r
* @param object options\r
* @param object callback\r
* @returns jQuery\r
* @var integer\r
*/\r
_idCounter: 0,\r
-\r
+ \r
/**\r
* Shows a modal dialog with a built-in AJAX-loader.\r
- *\r
+ * \r
* @param string dialogID\r
* @param boolean resetDialog\r
*/\r
if (!dialogID) {\r
dialogID = this.getRandomID();\r
}\r
-\r
+ \r
if (!$.wcfIsset(dialogID)) {\r
$('body').append($('<div id="' + dialogID + '"></div>'));\r
}\r
-\r
+ \r
var dialog = $('#' + $.wcfEscapeID(dialogID));\r
-\r
+ \r
if (resetDialog) {\r
dialog.empty();\r
}\r
-\r
+ \r
dialog.addClass('overlayLoading');\r
-\r
+ \r
var dialogOptions = arguments[2] || {};\r
dialog.wcfAJAXDialog(dialogOptions);\r
},\r
-\r
+ \r
/**\r
* Shows a modal dialog.\r
* @param string dialogID\r
// we cannot work with a non-existant dialog, if you wish to\r
// load content via AJAX, see showAJAXDialog() instead\r
if (!$.wcfIsset(dialogID)) return;\r
-\r
+ \r
var $dialog = $('#' + $.wcfEscapeID(dialogID));\r
-\r
+ \r
var dialogOptions = arguments[2] || {};\r
$dialog.wcfDialog(dialogOptions);\r
},\r
-\r
+ \r
/**\r
* Returns a dynamically created id.\r
- *\r
+ * \r
* @see https://github.com/sstephenson/prototype/blob/master/src/prototype/dom/dom.js#L1789\r
* @return string\r
*/\r
getRandomID: function() {\r
var $elementID = '';\r
-\r
+ \r
do {\r
$elementID = 'wcf' + this._idCounter++;\r
}\r
while ($.wcfIsset($elementID));\r
-\r
+ \r
return $elementID;\r
},\r
-\r
+ \r
/**\r
* Wrapper for $.inArray which returns boolean value instead of\r
* index value, similar to PHP's in_array().\r
- *\r
+ * \r
* @param mixed needle\r
* @param array haystack\r
* @return boolean\r
inArray: function(needle, haystack) {\r
return ($.inArray(needle, haystack) != -1);\r
},\r
-\r
+ \r
/**\r
* Adjusts effect for partially supported elements.\r
- *\r
+ * \r
* @param object object\r
* @param string effect\r
* @return string\r
if (tagName == 'tr') {\r
return 'highlight';\r
}\r
-\r
+ \r
return effect;\r
}\r
});\r
/**\r
* Provides a simple call for periodical executed functions. Based upon\r
* ideas by Prototype's PeriodicalExecuter.\r
- *\r
+ * \r
* @see https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/periodical_executer.js\r
* @param function callback\r
* @param integer delay\r
WCF.PeriodicalExecuter.prototype = {\r
/**\r
* Initializes a periodical executer.\r
- *\r
+ * \r
* @param function callback\r
* @param integer delay\r
*/\r
this.callback = callback;\r
this.delay = delay;\r
this.loop = true;\r
-\r
+ \r
this.intervalID = setInterval($.proxy(this._execute, this), this.delay);\r
},\r
-\r
+ \r
/**\r
* Executes callback.\r
*/\r
_execute: function() {\r
this.callback(this);\r
-\r
+ \r
if (!this.loop) {\r
clearInterval(this.intervalID);\r
}\r
},\r
-\r
+ \r
/**\r
* Terminates loop.\r
*/\r
\r
/**\r
* Basic implementation for AJAX-based proxyies\r
- *\r
+ * \r
* @param object options\r
*/\r
WCF.Action.Proxy = function(options) { this.init(options); };\r
WCF.Action.Proxy.prototype = {\r
/**\r
* Initializes AJAXProxy.\r
- *\r
+ * \r
* @param object options\r
*/\r
init: function(options) {\r
type: 'POST',\r
url: 'index.php?action=AJAXProxy&t=' + SECURITY_TOKEN + SID_ARG_2ND\r
}, options);\r
-\r
+ \r
this.confirmationDialog = null;\r
this.loading = null;\r
-\r
+ \r
// send request immediately after initialization\r
if (this.options.autoSend) {\r
this.sendRequest();\r
}\r
},\r
-\r
+ \r
/**\r
* Sends an AJAX request.\r
*/\r
sendRequest: function() {\r
this._init();\r
-\r
+ \r
$.ajax({\r
data: this.options.data,\r
dataType: 'json',\r
error: $.proxy(this._failure, this)\r
});\r
},\r
-\r
+ \r
/**\r
* Fires before request is send, displays global loading status.\r
*/\r
if ($.isFunction(this.options.init)) {\r
this.options.init();\r
}\r
-\r
+ \r
$('<div id="actionProxyLoading" style="display: none;">Loading …</div>').appendTo($('body'));\r
this.loading = $('#actionProxyLoading');\r
this.loading.wcfDropIn();\r
},\r
-\r
+ \r
/**\r
* Handles AJAX errors.\r
- *\r
+ * \r
* @param object jqXHR\r
* @param string textStatus\r
* @param string errorThrown\r
_failure: function(jqXHR, textStatus, errorThrown) {\r
try {\r
var data = $.parseJSON(jqXHR.responseText);\r
-\r
+ \r
// call child method if applicable\r
if ($.isFunction(this.options.failure)) {\r
this.options.failure(jqXHR, textStatus, errorThrown, data);\r
}\r
-\r
+ \r
var $randomID = WCF.getRandomID();\r
$('<div id="' + $randomID + '" title="HTTP/1.0 ' + jqXHR.status + ' ' + errorThrown + '"><p>Der Server antwortete: ' + data.message + '.</p></div>').wcfDialog();\r
}\r
var $randomID = WCF.getRandomID();\r
$('<div id="' + $randomID + '" title="HTTP/1.0 ' + jqXHR.status + ' ' + errorThrown + '"><p>Der Server antwortete: ' + jqXHR.responseText + '.</p></div>').wcfDialog();\r
}\r
-\r
+ \r
this._after();\r
},\r
-\r
+ \r
/**\r
* Handles successful AJAX requests.\r
- *\r
+ * \r
* @param object data\r
* @param string textStatus\r
* @param object jqXHR\r
if ($.isFunction(this.options.success)) {\r
this.options.success(data, textStatus, jqXHR);\r
}\r
-\r
+ \r
this._after();\r
},\r
-\r
+ \r
/**\r
* Fires after an AJAX request, hides global loading status.\r
*/\r
if ($.isFunction(this.options.after)) {\r
this.options.after();\r
}\r
-\r
+ \r
this.loading.wcfDropOut('up');\r
},\r
-\r
+ \r
/**\r
* Sets options, MUST be used to set parameters before sending request\r
* if calling from child classes.\r
- *\r
+ * \r
* @param string optionName\r
* @param mixed optionData\r
*/\r
\r
/**\r
* Basic implementation for simple proxy access using bound elements.\r
- *\r
+ * \r
* @param object options\r
* @param object callbacks\r
*/\r
WCF.Action.SimpleProxy.prototype = {\r
/**\r
* Initializes SimpleProxy.\r
- *\r
+ * \r
* @param object options\r
* @param object callbacks\r
*/\r
elements: null,\r
eventName: 'click'\r
}, options);\r
-\r
+ \r
/**\r
* proxy-specific options\r
*/\r
init: null,\r
success: null\r
}, callbacks);\r
-\r
+ \r
if (!this.options.elements) return;\r
-\r
+ \r
// initialize proxy\r
this.proxy = new WCF.Action.Proxy(this.callbacks);\r
-\r
+ \r
// bind event listener\r
this.options.elements.each($.proxy(function(index, element) {\r
$(element).bind(this.options.eventName, $.proxy(this._handleEvent, this));\r
}, this));\r
},\r
-\r
+ \r
/**\r
* Handles event actions.\r
- *\r
+ * \r
* @param object event\r
*/\r
_handleEvent: function(event) {\r
className: this.options.className,\r
objectIDs: [ $(event.target).data('objectID') ]\r
});\r
-\r
+ \r
this.proxy.sendRequest();\r
}\r
};\r
\r
/**\r
* Basic implementation for AJAXProxy-based deletion.\r
- *\r
+ * \r
* @param string className\r
* @param jQuery containerList\r
*/\r
WCF.Action.Delete.prototype = {\r
/**\r
* Initializes 'delete'-Proxy.\r
- *\r
+ * \r
* @param string className\r
* @param jQuery containerList\r
*/\r
if (!containerList.length) return;\r
this.containerList = containerList;\r
this.className = className;\r
-\r
+ \r
// initialize proxy\r
var options = {\r
success: $.proxy(this._success, this)\r
};\r
this.proxy = new WCF.Action.Proxy(options);\r
-\r
+ \r
// bind event listener\r
this.containerList.each($.proxy(function(index, container) {\r
$(container).find('.deleteButton').bind('click', $.proxy(this._click, this));\r
}, this));\r
},\r
-\r
+ \r
/**\r
* Sends AJAX request.\r
- *\r
+ * \r
* @param object event\r
*/\r
_click: function(event) {\r
var $target = $(event.target);\r
-\r
+ \r
if ($target.data('confirmMessage')) {\r
if (confirm($target.data('confirmMessage'))) {\r
this._sendRequest($target);\r
else {\r
this._sendRequest($target);\r
}\r
-\r
+ \r
},\r
-\r
+ \r
_sendRequest: function(object) {\r
this.proxy.setOption('data', {\r
actionName: 'delete',\r
className: this.className,\r
objectIDs: [ $(object).data('objectID') ]\r
});\r
-\r
+ \r
this.proxy.sendRequest();\r
},\r
-\r
+ \r
/**\r
* Deletes items from containers.\r
- *\r
+ * \r
* @param object data\r
* @param string textStatus\r
* @param object jqXHR\r
\r
/**\r
* Basic implementation for AJAXProxy-based toggle actions.\r
- *\r
+ * \r
* @param string className\r
* @param jQuery containerList\r
*/\r
WCF.Action.Toggle.prototype = {\r
/**\r
* Initializes 'toggle'-Proxy\r
- *\r
+ * \r
* @param string className\r
* @param jQuery containerList\r
*/\r
if (!containerList.length) return;\r
this.containerList = containerList;\r
this.className = className;\r
-\r
+ \r
// initialize proxy\r
var options = {\r
success: $.proxy(this._success, this)\r
};\r
this.proxy = new WCF.Action.Proxy(options);\r
-\r
+ \r
// bind event listener\r
this.containerList.each($.proxy(function(index, container) {\r
$(container).find('.toggleButton').bind('click', $.proxy(this._click, this));\r
}, this));\r
},\r
-\r
+ \r
/**\r
* Sends AJAX request.\r
- *\r
+ * \r
* @param object event\r
*/\r
_click: function(event) {\r
className: this.className,\r
objectIDs: [ $(event.target).data('objectID') ]\r
});\r
-\r
+ \r
this.proxy.sendRequest();\r
},\r
-\r
+ \r
/**\r
* Toggles status icons.\r
- *\r
+ * \r
* @param object data\r
* @param string textStatus\r
* @param object jqXHR\r
var $toggleButton = $(container).find('.toggleButton');\r
if (WCF.inArray($toggleButton.data('objectID'), data.objectIDs)) {\r
$(container).wcfHighlight();\r
-\r
+ \r
// toggle icon source\r
$toggleButton.attr('src', function() {\r
if (this.src.match(/enabled(S|M|L)\.png$/)) {\r
WCF.Date.Util = {\r
/**\r
* Returns UTC timestamp, if date is not given, current time will be used.\r
- *\r
+ * \r
* @param Date date\r
* @return integer\r
*/\r
gmdate: function(date) {\r
var $date = (date) ? date : new Date();\r
-\r
+ \r
return Math.round(Date.UTC(\r
$date.getUTCFullYear(),\r
$date.getUTCMonth(),\r
$date.getUTCSeconds()\r
) / 1000);\r
},\r
-\r
+ \r
/**\r
* Returns a Date object with precise offset (including timezone and local timezone).\r
* Parameter timestamp must be in miliseconds!\r
- *\r
+ * \r
* @param integer timestamp\r
* @param integer offset\r
* @return Date\r
getTimezoneDate: function(timestamp, offset) {\r
var $date = new Date(timestamp);\r
var $localOffset = $date.getTimezoneOffset() * -1 * 60000;\r
-\r
+ \r
return new Date((timestamp - $localOffset - offset));\r
}\r
};\r
// initialize variables\r
this.elements = $('time.datetime');\r
this.timestamp = 0;\r
-\r
+ \r
// calculate relative datetime on init\r
this._refresh();\r
-\r
+ \r
// re-calculate relative datetime every minute\r
new WCF.PeriodicalExecuter($.proxy(this._refresh, this), 60000);\r
},\r
-\r
+ \r
/**\r
* Refreshes relative datetime for each element.\r
*/\r
var $date = new Date();\r
this.timestamp = ($date.getTime() - $date.getMilliseconds()) / 1000;\r
// TESTING ONLY!\r
-\r
+ \r
this.elements.each($.proxy(this._refreshElement, this));\r
},\r
-\r
+ \r
/**\r
* Refreshes relative datetime for current element.\r
- *\r
+ * \r
* @param integer index\r
* @param object element\r
*/\r
if (!$(element).attr('title')) {\r
$(element).attr('title', $(element).text());\r
}\r
-\r
+ \r
var $timestamp = $(element).data('timestamp');\r
var $date = $(element).data('date');\r
var $time = $(element).data('time');\r
var $offset = $(element).data('offset');\r
-\r
+ \r
// timestamp is less than 60 minutes ago (display 1 hour ago rather than 60 minutes ago)\r
if (this.timestamp < ($timestamp + 3540)) {\r
var $minutes = Math.round((this.timestamp - $timestamp) / 60);\r
else if (this.timestamp < ($timestamp + 604800)) {\r
var $days = Math.round((this.timestamp - $timestamp) / 86400);\r
var $string = eval(WCF.Language.get('wcf.global.date.relative.pastDays'));\r
-\r
+ \r
// get day of week\r
var $dateObj = WCF.Date.Util.getTimezoneDate(($timestamp * 1000), $offset);\r
var $dow = $dateObj.getDay();\r
-\r
+ \r
$(element).text($string.replace(/\%day\%/, WCF.Language.get('__days')[$dow]).replace(/\%time\%/, $time));\r
}\r
// timestamp is between ~700 million years BC and last week\r
\r
/**\r
* Hash-like dictionary. Based upon idead from Prototype's hash\r
- *\r
+ * \r
* @see https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/hash.js\r
*/\r
WCF.Dictionary = function() { this.init(); };\r
init: function() {\r
this.variables = { };\r
},\r
-\r
+ \r
/**\r
* Adds an entry.\r
- *\r
+ * \r
* @param string key\r
* @param mixed value\r
*/\r
add: function(key, value) {\r
this.variables[key] = value;\r
},\r
-\r
+ \r
/**\r
* Adds a traditional object to current dataset.\r
- *\r
+ * \r
* @param object object\r
*/\r
addObject: function(object) {\r
this.add($key, object[$key]);\r
}\r
},\r
-\r
+ \r
/**\r
* Adds a dictionary to current dataset.\r
- *\r
+ * \r
* @param object dictionary\r
*/\r
addDictionary: function(dictionary) {\r
this.add(pair.key, pair.value);\r
}, this));\r
},\r
-\r
+ \r
/**\r
* Retrieves the value of an entry or returns null if key is not found.\r
- *\r
+ * \r
* @param string key\r
* @returns mixed\r
*/\r
if (this.isset(key)) {\r
return this.variables[key];\r
}\r
-\r
+ \r
return null;\r
},\r
-\r
+ \r
/**\r
* Returns true if given key is a valid entry.\r
- *\r
+ * \r
* @param string key\r
*/\r
isset: function(key) {\r
return this.variables.hasOwnProperty(key);\r
},\r
-\r
+ \r
/**\r
* Removes an entry.\r
- *\r
+ * \r
* @param string key\r
*/\r
remove: function(key) {\r
delete this.variables[key];\r
},\r
-\r
+ \r
/**\r
* Iterates through dictionary.\r
- *\r
+ * \r
* Usage:\r
* var $hash = new WCF.Dictionary();\r
* $hash.add('foo', 'bar');\r
* // alerts: foo = bar\r
* alert(pair.key + ' = ' + pair.value);\r
* });\r
- *\r
+ * \r
* @param function callback\r
*/\r
each: function(callback) {\r
if (!$.isFunction(callback)) {\r
return;\r
}\r
-\r
+ \r
for (var $key in this.variables) {\r
var $value = this.variables[$key];\r
var $pair = {\r
key: $key,\r
value: $value\r
};\r
-\r
+ \r
callback($pair);\r
}\r
}\r
\r
/**\r
* Global language storage.\r
- *\r
+ * \r
* @see WCF.Dictionary\r
*/\r
WCF.Language = {\r
_variables: new WCF.Dictionary(),\r
-\r
+ \r
/**\r
* @see WCF.Dictionary.addObject()\r
*/\r
add: function(key, value) {\r
this._variables.add(key, value);\r
},\r
-\r
+ \r
/**\r
* @see WCF.Dictionary.addObject()\r
*/\r
addObject: function(object) {\r
this._variables.addObject(object);\r
},\r
-\r
+ \r
/**\r
* Retrieves a variable.\r
- *\r
+ * \r
* @param string key\r
* @return mixed\r
*/\r
WCF.String = {\r
/**\r
* Makes a string's first character uppercase\r
- *\r
+ * \r
* @param string string\r
* @return string\r
*/\r
var $randomID = WCF.getRandomID();\r
$(tabMenu).attr('id', $randomID);\r
}\r
-\r
+ \r
// init jQuery UI TabMenu\r
$(tabMenu).wcfTabs({\r
select: function(event, ui) {\r
var $panel = $(ui.panel);\r
var $container = $panel.closest('.tabMenuContainer');\r
-\r
+ \r
// store currently selected item\r
if ($container.data('store')) {\r
if ($.wcfIsset($container.data('store'))) {\r
}\r
}\r
});\r
-\r
+ \r
// display active item on init\r
if ($(tabMenu).data('active')) {\r
$(tabMenu).find('.tabMenuContent').each(function(index, tabMenuItem) {\r
\r
/**\r
* Toggles options.\r
- *\r
+ * \r
* @param string element\r
* @param array showItems\r
* @param array hideItems\r
WCF.ToggleOptions.prototype = {\r
/**\r
* target item\r
- *\r
+ * \r
* @var jQuery\r
*/\r
_element: null,\r
-\r
+ \r
/**\r
* list of items to be shown\r
- *\r
+ * \r
* @var array\r
*/\r
_showItems: [],\r
-\r
+ \r
/**\r
* list of items to be hidden\r
- *\r
+ * \r
* @var array\r
*/\r
_hideItems: [],\r
-\r
+ \r
/**\r
* Initializes option toggle.\r
- *\r
+ * \r
* @param string element\r
* @param array showItems\r
* @param array hideItems\r
this._element = $('#' + element);\r
this._showItems = showItems;\r
this._hideItems = hideItems;\r
-\r
+ \r
// bind event\r
this._element.click($.proxy(this._toggle, this));\r
-\r
+ \r
// execute toggle on init\r
this._toggle();\r
},\r
-\r
+ \r
/**\r
* Toggles items.\r
*/\r
_toggle: function() {\r
if (!this._element.attr('checked')) return;\r
-\r
+ \r
for (var $i = 0, $length = this._showItems.length; $i < $length; $i++) {\r
var $item = this._showItems[$i];\r
-\r
+ \r
$('#' + $item).show();\r
}\r
-\r
+ \r
for (var $i = 0, $length = this._hideItems.length; $i < $length; $i++) {\r
var $item = this._hideItems[$i];\r
-\r
+ \r
$('#' + $item).hide();\r
}\r
}\r
-}\r
+};\r
\r
/**\r
* Basic implementation for WCF dialogs.\r
this.options.minHeight = 0;\r
this.options.modal = true;\r
this.options.width = 'auto';\r
-\r
+ \r
$.ui.dialog.prototype._init.apply(this, arguments);\r
}\r
});\r
$.widget('ui.wcfAJAXDialog', $.ui.dialog, {\r
/**\r
* Indicates wether callback was already executed\r
- *\r
+ * \r
* @var boolean\r
*/\r
_callbackExecuted: false,\r
-\r
+ \r
/**\r
* Initializes AJAX-request to fetch content.\r
*/\r
if (this.options.ajax) {\r
this._loadContent();\r
}\r
-\r
+ \r
// force dialog to be placed centered\r
this.options.position = {\r
my: 'center center',\r
at: 'center center'\r
};\r
-\r
+ \r
// dialog should display a spinner-like image, thus immediately fire up dialog\r
this.options.autoOpen = true;\r
this.options.width = 'auto';\r
this.options.minHeight = 80;\r
-\r
+ \r
// disable ability to move dialog\r
this.options.resizable = false;\r
this.options.draggable = false;\r
-\r
+ \r
this.options.modal = true;\r
this.options.hide = {\r
effect: 'drop',\r
direction: 'down'\r
};\r
-\r
+ \r
this.options.close = function(event, ui) {\r
// loading ajax content seems to block properly closing\r
$(this).parent('.ui-dialog').empty().remove();\r
};\r
-\r
+ \r
if (this.options.preventClose) {\r
this.options.closeOnEscape = false;\r
}\r
-\r
+ \r
$.ui.dialog.prototype._init.apply(this, arguments);\r
-\r
+ \r
// remove complete node instead of removing node-by-node\r
if (this.options.hideTitle && this.options.preventClose) {\r
this.element.parent('.ui-dialog').find('div.ui-dialog-titlebar').empty().remove();\r
// remove title element\r
$('#ui-dialog-title-' + this.element.attr('id')).empty().remove();\r
}\r
-\r
+ \r
if (this.options.preventClose) {\r
// remove close-button\r
this.element.parent('.ui-dialog').find('a.ui-dialog-titlebar-close').empty().remove();\r
}\r
}\r
},\r
-\r
+ \r
/**\r
* Loads content via AJAX.\r
- *\r
+ * \r
* @todo Enforce JSON\r
*/\r
_loadContent: function() {\r
var $type = 'GET';\r
if (this.options.ajax.type) {\r
$type = this.options.ajax.type;\r
-\r
+ \r
if (this.options.ajax.type != 'GET' && this.options.ajax.type != 'POST') {\r
$type = 'GET';\r
}\r
}\r
-\r
+ \r
var $data = this.options.ajax.data || {};\r
-\r
+ \r
$.ajax({\r
url: this.options.ajax.url,\r
context: this,\r
}\r
});\r
},\r
-\r
+ \r
/**\r
* Inserts content.\r
- *\r
+ * \r
* @param string data\r
*/\r
_createDialog: function(data) {\r
data.ignoreTemplate = true;\r
this.element.data('responseData', data);\r
-\r
+ \r
this.element.wcfGrow({\r
content: data.template,\r
parent: this.element.parent('.ui-dialog')\r
this.element.css({\r
height: 'auto'\r
});\r
-\r
+ \r
// prevent double execution due to two complete-calls (two times animate)\r
if (this._callbackExecuted) {\r
return;\r
}\r
-\r
+ \r
this._callbackExecuted = true;\r
-\r
+ \r
this.element.removeClass('overlayLoading');\r
this.element.html(this.element.data('responseData').template);\r
-\r
+ \r
if (this.options.ajax.success) {\r
this.options.ajax.success();\r
}\r
}, this)\r
});\r
},\r
-\r
+ \r
/**\r
* Redraws dialog, should be executed everytime content is changed.\r
*/\r
redraw: function() {\r
var $dimensions = this.element.getDimensions();\r
-\r
+ \r
if ($dimensions.height > 200) {\r
this.element.wcfGrow({\r
content: this.element.html(),\r
* Workaround for ids containing a dot ".", until jQuery UI devs learn\r
* to properly escape ids ... (it took 18 months until they finally\r
* fixed it!)\r
- *\r
+ * \r
* @see http://bugs.jqueryui.com/ticket/4681\r
*/\r
$.widget('ui.wcfTabs', $.ui.tabs, {\r
_init: function() {\r
$.ui.dialog.prototype._init.apply(this, arguments);\r
},\r
-\r
+ \r
_sanitizeSelector: function(hash) {\r
return hash.replace(/([:\.])/g, '\\$1');\r
}\r
/**\r
* Encapsulate eval() within an own function to prevent problems\r
* with optimizing and minifiny JS.\r
- *\r
+ * \r
* @param mixed expression\r
* @returns mixed\r
*/\r