var TIME_NOW = {@TIME_NOW};
var LAST_UPDATE_TIME = {@LAST_UPDATE_TIME};
var URL_LEGACY_MODE = false;
+
+ {if ENABLE_DEBUG_MODE}
+ {* This constant is a compiler option, it does not exist in production. *}
+ var COMPILER_TARGET_DEFAULT = {if $__wcf->user->userID}true{else}false{/if};
+ {/if}
</script>
{js application='wcf' lib='polyfill' file='promise' core='true'}
var TIME_NOW = {@TIME_NOW};
var LAST_UPDATE_TIME = {@LAST_UPDATE_TIME};
var URL_LEGACY_MODE = false;
+
+ {if ENABLE_DEBUG_MODE}
+ {* This constant is a compiler option, it does not exist in production. *}
+ var COMPILER_TARGET_DEFAULT = {if $__wcf->user->userID}true{else}false{/if};
+ {/if}
</script>
{js application='wcf' file='require' bundle='WoltLabSuite.Core' core='true'}
*/
WCF.ACL = { };
-/**
- * ACL support for WCF
- *
- * @author Alexander Ebert
- * @copyright 2001-2017 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- */
-WCF.ACL.List = Class.extend({
- /**
- * name of the category the acl options belong to
- * @var string
- */
- _categoryName: '',
-
- /**
- * ACL container
- * @var jQuery
- */
- _container: null,
-
- /**
- * list of ACL container elements
- * @var object
- */
- _containerElements: { },
-
- /**
- * object id
- * @var integer
- */
- _objectID: 0,
-
- /**
- * object type id
- * @var integer
- */
- _objectTypeID: null,
-
- /**
- * list of available ACL options
- * @var object
- */
- _options: { },
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * user search handler
- * @var WCF.Search.User
- */
- _search: null,
-
- /**
- * list of ACL settings
- * @var object
- */
- _values: {
- group: { },
- user: { }
- },
-
- /**
- * Initializes the ACL configuration.
- *
- * @param string containerSelector
- * @param integer objectTypeID
- * @param string categoryName
- * @param integer objectID
- * @param boolean includeUserGroups
- */
- init: function(containerSelector, objectTypeID, categoryName, objectID, includeUserGroups, initialPermissions) {
- this._objectID = objectID || 0;
- this._objectTypeID = objectTypeID;
- this._categoryName = categoryName;
- if (includeUserGroups === undefined) {
- includeUserGroups = true;
- }
- this._values = {
- group: { },
- user: { }
- };
-
- this._proxy = new WCF.Action.Proxy({
- showLoadingOverlay: false,
- success: $.proxy(this._success, this)
- });
-
- // bind hidden container
- this._container = $(containerSelector).hide().addClass('aclContainer');
-
- // insert container elements
- var $elementContainer = this._container.children('dd');
- var $aclList = $('<ul class="aclList containerList" />').appendTo($elementContainer);
- var $searchInput = $('<input type="text" class="long" placeholder="' + WCF.Language.get('wcf.acl.search.' + (!includeUserGroups ? 'user.' : '') + 'description') + '" />').appendTo($elementContainer);
- var $permissionList = $('<ul class="aclPermissionList containerList" />').hide().appendTo($elementContainer);
- elData($permissionList[0], 'grant', WCF.Language.get('wcf.acl.option.grant'));
- elData($permissionList[0], 'deny', WCF.Language.get('wcf.acl.option.deny'));
-
- // set elements
- this._containerElements = {
- aclList: $aclList,
- denyAll: null,
- grantAll: null,
- permissionList: $permissionList,
- searchInput: $searchInput
- };
-
- // prepare search input
- this._search = new WCF.Search.User($searchInput, $.proxy(this.addObject, this), includeUserGroups);
-
- // bind event listener for submit
- var $form = this._container.parents('form:eq(0)');
- $form.submit($.proxy(this.submit, this));
-
- // reset ACL on click
- var $resetButton = $form.find('input[type=reset]:eq(0)');
- if ($resetButton.length) {
- $resetButton.click($.proxy(this._reset, this));
- }
-
- if (initialPermissions) {
- this._success(initialPermissions);
- }
- else {
- this._loadACL();
- }
- },
-
- /**
- * Restores the original ACL state.
- */
- _reset: function() {
- // reset stored values
- this._values = {
- group: { },
- user: { }
- };
-
- // remove entries
- this._containerElements.aclList.empty();
- this._containerElements.searchInput.val('');
-
- // deselect all input elements
- this._containerElements.permissionList.hide().find('input[type=checkbox]').prop('checked', false);
- },
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Loads current ACL configuration.
+ * ACL support for WCF
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
*/
- _loadACL: function() {
- this._proxy.setOption('data', {
- actionName: 'loadAll',
- className: 'wcf\\data\\acl\\option\\ACLOptionAction',
- parameters: {
- categoryName: this._categoryName,
- objectID: this._objectID,
- objectTypeID: this._objectTypeID
+ WCF.ACL.List = Class.extend({
+ /**
+ * name of the category the acl options belong to
+ * @var string
+ */
+ _categoryName: '',
+
+ /**
+ * ACL container
+ * @var jQuery
+ */
+ _container: null,
+
+ /**
+ * list of ACL container elements
+ * @var object
+ */
+ _containerElements: {},
+
+ /**
+ * object id
+ * @var integer
+ */
+ _objectID: 0,
+
+ /**
+ * object type id
+ * @var integer
+ */
+ _objectTypeID: null,
+
+ /**
+ * list of available ACL options
+ * @var object
+ */
+ _options: {},
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * user search handler
+ * @var WCF.Search.User
+ */
+ _search: null,
+
+ /**
+ * list of ACL settings
+ * @var object
+ */
+ _values: {
+ group: {},
+ user: {}
+ },
+
+ /**
+ * Initializes the ACL configuration.
+ *
+ * @param string containerSelector
+ * @param integer objectTypeID
+ * @param string categoryName
+ * @param integer objectID
+ * @param boolean includeUserGroups
+ */
+ init: function (containerSelector, objectTypeID, categoryName, objectID, includeUserGroups, initialPermissions) {
+ this._objectID = objectID || 0;
+ this._objectTypeID = objectTypeID;
+ this._categoryName = categoryName;
+ if (includeUserGroups === undefined) {
+ includeUserGroups = true;
}
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Adds a new object to acl list.
- *
- * @param object data
- */
- addObject: function(data) {
- var $listItem = this._createListItem(data.objectID, data.label, data.type);
-
- // toggle element
- this._savePermissions();
- this._containerElements.aclList.children('li').removeClass('active');
- $listItem.addClass('active');
-
- this._search.addExcludedSearchValue(data.label);
-
- // uncheck all option values
- this._containerElements.permissionList.find('input[type=checkbox]').prop('checked', false);
-
- // clear search input
- this._containerElements.searchInput.val('');
-
- // show permissions
- this._containerElements.permissionList.show();
-
- WCF.DOMNodeInsertedHandler.execute();
- },
-
- /**
- * Creates a list item with the given data and returns it.
- *
- * @param integer objectID
- * @param string label
- * @param string type
- * @return jQuery
- */
- _createListItem: function(objectID, label, type) {
- var $listItem = $('<li><span class="icon icon16 fa-user' + (type === 'group' ? 's' : '') + '" /> <span class="aclLabel">' + label + '</span></li>').appendTo(this._containerElements.aclList);
- $listItem.data('objectID', objectID).data('type', type).data('label', label).click($.proxy(this._click, this));
- $('<span class="icon icon16 fa-times jsTooltip pointer" title="' + WCF.Language.get('wcf.global.button.delete') + '" />').click($.proxy(this._removeItem, this)).appendTo($listItem);
-
- return $listItem;
- },
-
- /**
- * Removes an item from list.
- *
- * @param object event
- */
- _removeItem: function(event) {
- var $listItem = $(event.currentTarget).parent();
- var $type = $listItem.data('type');
- var $objectID = $listItem.data('objectID');
-
- this._search.removeExcludedSearchValue($listItem.data('label'));
- $listItem.remove();
-
- // remove stored data
- if (this._values[$type][$objectID]) {
- delete this._values[$type][$objectID];
- }
-
- // try to select something else
- this._selectFirstEntry();
- },
-
- /**
- * Selects the first available entry.
- */
- _selectFirstEntry: function() {
- var $listItem = this._containerElements.aclList.children('li:eq(0)');
- if ($listItem.length) {
- this._select($listItem, false);
- }
- else {
- this._reset();
- }
- },
-
- /**
- * Parses current ACL configuration.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- if (!$.getLength(data.returnValues.options)) {
- return;
- }
-
- // prepare options
- var $count = 0;
- var $structure = { };
- for (var $optionID in data.returnValues.options) {
- var $option = data.returnValues.options[$optionID];
+ this._values = {
+ group: {},
+ user: {}
+ };
- var $listItem = $('<li><span>' + $option.label + '</span></li>').data('optionID', $optionID).data('optionName', $option.optionName);
- var $grantPermission = $('<input type="checkbox" id="grant' + $optionID + '" />').appendTo($listItem).wrap('<label for="grant' + $optionID + '" class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.grant') + '" />');
- var $denyPermission = $('<input type="checkbox" id="deny' + $optionID + '" />').appendTo($listItem).wrap('<label for="deny' + $optionID + '" class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.deny') + '" />');
+ this._proxy = new WCF.Action.Proxy({
+ showLoadingOverlay: false,
+ success: $.proxy(this._success, this)
+ });
- $grantPermission.data('type', 'grant').data('optionID', $optionID).change($.proxy(this._change, this));
- $denyPermission.data('type', 'deny').data('optionID', $optionID).change($.proxy(this._change, this));
+ // bind hidden container
+ this._container = $(containerSelector).hide().addClass('aclContainer');
- if (!$structure[$option.categoryName]) {
- $structure[$option.categoryName] = [ ];
+ // insert container elements
+ var $elementContainer = this._container.children('dd');
+ var $aclList = $('<ul class="aclList containerList" />').appendTo($elementContainer);
+ var $searchInput = $('<input type="text" class="long" placeholder="' + WCF.Language.get('wcf.acl.search.' + (!includeUserGroups ? 'user.' : '') + 'description') + '" />').appendTo($elementContainer);
+ var $permissionList = $('<ul class="aclPermissionList containerList" />').hide().appendTo($elementContainer);
+ elData($permissionList[0], 'grant', WCF.Language.get('wcf.acl.option.grant'));
+ elData($permissionList[0], 'deny', WCF.Language.get('wcf.acl.option.deny'));
+
+ // set elements
+ this._containerElements = {
+ aclList: $aclList,
+ denyAll: null,
+ grantAll: null,
+ permissionList: $permissionList,
+ searchInput: $searchInput
+ };
+
+ // prepare search input
+ this._search = new WCF.Search.User($searchInput, $.proxy(this.addObject, this), includeUserGroups);
+
+ // bind event listener for submit
+ var $form = this._container.parents('form:eq(0)');
+ $form.submit($.proxy(this.submit, this));
+
+ // reset ACL on click
+ var $resetButton = $form.find('input[type=reset]:eq(0)');
+ if ($resetButton.length) {
+ $resetButton.click($.proxy(this._reset, this));
}
- if ($option.categoryName === '') {
- $listItem.appendTo(this._containerElements.permissionList);
+ if (initialPermissions) {
+ this._success(initialPermissions);
}
else {
- $structure[$option.categoryName].push($listItem);
+ this._loadACL();
}
+ },
+
+ /**
+ * Restores the original ACL state.
+ */
+ _reset: function () {
+ // reset stored values
+ this._values = {
+ group: {},
+ user: {}
+ };
- $count++;
- }
-
- // add a "full access" permission if there are more than one option
- if ($count > 1) {
- var $listItem = $('<li class="aclFullAccess"><span>' + WCF.Language.get('wcf.acl.option.fullAccess') + '</span></li>').prependTo(this._containerElements.permissionList);
- this._containerElements.grantAll = $('<input type="checkbox" id="grantAll_' + this._container.attr('id') + '" />').appendTo($listItem).wrap('<label class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.grant') + '" />');
- this._containerElements.denyAll = $('<input type="checkbox" id="denyAll_' + this._container.attr('id') + '" />').appendTo($listItem).wrap('<label class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.deny') + '" />');
-
- // bind events
- this._containerElements.grantAll.data('type', 'grant').change($.proxy(this._changeAll, this));
- this._containerElements.denyAll.data('type', 'deny').change($.proxy(this._changeAll, this));
- }
-
- if ($.getLength($structure)) {
- for (var $categoryName in $structure) {
- var $listItems = $structure[$categoryName];
+ // remove entries
+ this._containerElements.aclList.empty();
+ this._containerElements.searchInput.val('');
+
+ // deselect all input elements
+ this._containerElements.permissionList.hide().find('input[type=checkbox]').prop('checked', false);
+ },
+
+ /**
+ * Loads current ACL configuration.
+ */
+ _loadACL: function () {
+ this._proxy.setOption('data', {
+ actionName: 'loadAll',
+ className: 'wcf\\data\\acl\\option\\ACLOptionAction',
+ parameters: {
+ categoryName: this._categoryName,
+ objectID: this._objectID,
+ objectTypeID: this._objectTypeID
+ }
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Adds a new object to acl list.
+ *
+ * @param object data
+ */
+ addObject: function (data) {
+ var $listItem = this._createListItem(data.objectID, data.label, data.type);
+
+ // toggle element
+ this._savePermissions();
+ this._containerElements.aclList.children('li').removeClass('active');
+ $listItem.addClass('active');
+
+ this._search.addExcludedSearchValue(data.label);
+
+ // uncheck all option values
+ this._containerElements.permissionList.find('input[type=checkbox]').prop('checked', false);
+
+ // clear search input
+ this._containerElements.searchInput.val('');
+
+ // show permissions
+ this._containerElements.permissionList.show();
+
+ WCF.DOMNodeInsertedHandler.execute();
+ },
+
+ /**
+ * Creates a list item with the given data and returns it.
+ *
+ * @param integer objectID
+ * @param string label
+ * @param string type
+ * @return jQuery
+ */
+ _createListItem: function (objectID, label, type) {
+ var $listItem = $('<li><span class="icon icon16 fa-user' + (type === 'group' ? 's' : '') + '" /> <span class="aclLabel">' + label + '</span></li>').appendTo(this._containerElements.aclList);
+ $listItem.data('objectID', objectID).data('type', type).data('label', label).click($.proxy(this._click, this));
+ $('<span class="icon icon16 fa-times jsTooltip pointer" title="' + WCF.Language.get('wcf.global.button.delete') + '" />').click($.proxy(this._removeItem, this)).appendTo($listItem);
+
+ return $listItem;
+ },
+
+ /**
+ * Removes an item from list.
+ *
+ * @param object event
+ */
+ _removeItem: function (event) {
+ var $listItem = $(event.currentTarget).parent();
+ var $type = $listItem.data('type');
+ var $objectID = $listItem.data('objectID');
+
+ this._search.removeExcludedSearchValue($listItem.data('label'));
+ $listItem.remove();
+
+ // remove stored data
+ if (this._values[$type][$objectID]) {
+ delete this._values[$type][$objectID];
+ }
+
+ // try to select something else
+ this._selectFirstEntry();
+ },
+
+ /**
+ * Selects the first available entry.
+ */
+ _selectFirstEntry: function () {
+ var $listItem = this._containerElements.aclList.children('li:eq(0)');
+ if ($listItem.length) {
+ this._select($listItem, false);
+ }
+ else {
+ this._reset();
+ }
+ },
+
+ /**
+ * Parses current ACL configuration.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ if (!$.getLength(data.returnValues.options)) {
+ return;
+ }
+
+ // prepare options
+ var $count = 0;
+ var $structure = {};
+ for (var $optionID in data.returnValues.options) {
+ var $option = data.returnValues.options[$optionID];
- if (data.returnValues.categories[$categoryName]) {
- $('<li class="aclCategory">' + data.returnValues.categories[$categoryName] + '</li>').appendTo(this._containerElements.permissionList);
+ var $listItem = $('<li><span>' + $option.label + '</span></li>').data('optionID', $optionID).data('optionName', $option.optionName);
+ var $grantPermission = $('<input type="checkbox" id="grant' + $optionID + '" />').appendTo($listItem).wrap('<label for="grant' + $optionID + '" class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.grant') + '" />');
+ var $denyPermission = $('<input type="checkbox" id="deny' + $optionID + '" />').appendTo($listItem).wrap('<label for="deny' + $optionID + '" class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.deny') + '" />');
+
+ $grantPermission.data('type', 'grant').data('optionID', $optionID).change($.proxy(this._change, this));
+ $denyPermission.data('type', 'deny').data('optionID', $optionID).change($.proxy(this._change, this));
+
+ if (!$structure[$option.categoryName]) {
+ $structure[$option.categoryName] = [];
}
- for (var $i = 0, $length = $listItems.length; $i < $length; $i++) {
- $listItems[$i].appendTo(this._containerElements.permissionList);
+ if ($option.categoryName === '') {
+ $listItem.appendTo(this._containerElements.permissionList);
+ }
+ else {
+ $structure[$option.categoryName].push($listItem);
}
+
+ $count++;
}
- }
-
- // set data
- this._parseData(data, 'group');
- this._parseData(data, 'user');
-
- // show container
- this._container.show();
-
- // pre-select an entry
- this._selectFirstEntry();
- },
-
- /**
- * Parses user and group data.
- *
- * @param object data
- * @param string type
- */
- _parseData: function(data, type) {
- if (!$.getLength(data.returnValues[type].option)) {
- return;
- }
-
- // add list items
- for (var $typeID in data.returnValues[type].label) {
- this._createListItem($typeID, data.returnValues[type].label[$typeID], type);
- this._search.addExcludedSearchValue(data.returnValues[type].label[$typeID]);
- }
-
- // add options
- this._values[type] = data.returnValues[type].option;
-
- WCF.DOMNodeInsertedHandler.execute();
- },
-
- /**
- * Prepares permission list for a specific object.
- *
- * @param object event
- */
- _click: function(event) {
- var $listItem = $(event.currentTarget);
- if ($listItem.hasClass('active')) {
- return;
- }
-
- this._select($listItem, true);
- },
-
- /**
- * Selects the given item and marks it as active.
- *
- * @param jQuery listItem
- * @param boolean savePermissions
- */
- _select: function(listItem, savePermissions) {
- // save previous permissions
- if (savePermissions) {
- this._savePermissions();
- }
-
- // switch active item
- this._containerElements.aclList.children('li').removeClass('active');
- listItem.addClass('active');
-
- // apply permissions for current item
- this._setupPermissions(listItem.data('type'), listItem.data('objectID'));
- },
-
- /**
- * Toggles between deny and grant.
- *
- * @param object event
- */
- _change: function(event) {
- var $checkbox = $(event.currentTarget);
- var $optionID = $checkbox.data('optionID');
- var $type = $checkbox.data('type');
-
- if ($checkbox.is(':checked')) {
- if ($type === 'deny') {
- $('#grant' + $optionID).prop('checked', false);
+ // add a "full access" permission if there are more than one option
+ if ($count > 1) {
+ var $listItem = $('<li class="aclFullAccess"><span>' + WCF.Language.get('wcf.acl.option.fullAccess') + '</span></li>').prependTo(this._containerElements.permissionList);
+ this._containerElements.grantAll = $('<input type="checkbox" id="grantAll_' + this._container.attr('id') + '" />').appendTo($listItem).wrap('<label class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.grant') + '" />');
+ this._containerElements.denyAll = $('<input type="checkbox" id="denyAll_' + this._container.attr('id') + '" />').appendTo($listItem).wrap('<label class="jsTooltip" title="' + WCF.Language.get('wcf.acl.option.deny') + '" />');
- if (this._containerElements.grantAll !== null) {
- this._containerElements.grantAll.prop('checked', false);
- }
+ // bind events
+ this._containerElements.grantAll.data('type', 'grant').change($.proxy(this._changeAll, this));
+ this._containerElements.denyAll.data('type', 'deny').change($.proxy(this._changeAll, this));
}
- else {
- $('#deny' + $optionID).prop('checked', false);
-
- if (this._containerElements.denyAll !== null) {
- this._containerElements.denyAll.prop('checked', false);
+
+ if ($.getLength($structure)) {
+ for (var $categoryName in $structure) {
+ var $listItems = $structure[$categoryName];
+
+ if (data.returnValues.categories[$categoryName]) {
+ $('<li class="aclCategory">' + data.returnValues.categories[$categoryName] + '</li>').appendTo(this._containerElements.permissionList);
+ }
+
+ for (var $i = 0, $length = $listItems.length; $i < $length; $i++) {
+ $listItems[$i].appendTo(this._containerElements.permissionList);
+ }
}
}
- }
- else {
- if ($type === 'deny' && this._containerElements.denyAll !== null) {
- this._containerElements.denyAll.prop('checked', false);
- }
- else if ($type === 'grant' && this._containerElements.grantAll !== null) {
- this._containerElements.grantAll.prop('checked', false);
+
+ // set data
+ this._parseData(data, 'group');
+ this._parseData(data, 'user');
+
+ // show container
+ this._container.show();
+
+ // pre-select an entry
+ this._selectFirstEntry();
+ },
+
+ /**
+ * Parses user and group data.
+ *
+ * @param object data
+ * @param string type
+ */
+ _parseData: function (data, type) {
+ if (!$.getLength(data.returnValues[type].option)) {
+ return;
}
- }
-
- var $allChecked = true;
- this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function(index, item) {
- var $item = $(item);
-
- if ($item.data('type') === $type && $item.attr('id') !== $type + 'All_' + this._container.attr('id')) {
- if (!$item.is(':checked')) {
- $allChecked = false;
- return false;
- }
+
+ // add list items
+ for (var $typeID in data.returnValues[type].label) {
+ this._createListItem($typeID, data.returnValues[type].label[$typeID], type);
+
+ this._search.addExcludedSearchValue(data.returnValues[type].label[$typeID]);
}
- }, this));
- if ($type == 'deny') {
- if (this._containerElements.denyAll !== null) {
- if ($allChecked) this._containerElements.denyAll.prop('checked', true);
- else this._containerElements.denyAll.prop('checked', false);
+
+ // add options
+ this._values[type] = data.returnValues[type].option;
+
+ WCF.DOMNodeInsertedHandler.execute();
+ },
+
+ /**
+ * Prepares permission list for a specific object.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $listItem = $(event.currentTarget);
+ if ($listItem.hasClass('active')) {
+ return;
}
- }
- else {
- if (this._containerElements.grantAll !== null) {
- if ($allChecked) this._containerElements.grantAll.prop('checked', true);
- else this._containerElements.grantAll.prop('checked', false);
+
+ this._select($listItem, true);
+ },
+
+ /**
+ * Selects the given item and marks it as active.
+ *
+ * @param jQuery listItem
+ * @param boolean savePermissions
+ */
+ _select: function (listItem, savePermissions) {
+ // save previous permissions
+ if (savePermissions) {
+ this._savePermissions();
}
- }
- },
-
- /**
- * Toggles all options between deny and grant.
- *
- * @param object event
- */
- _changeAll: function(event) {
- var $checkbox = $(event.currentTarget);
- var $type = $checkbox.data('type');
-
- if ($checkbox.is(':checked')) {
- if ($type === 'deny') {
- this._containerElements.grantAll.prop('checked', false);
-
- this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function(index, item) {
- var $item = $(item);
+
+ // switch active item
+ this._containerElements.aclList.children('li').removeClass('active');
+ listItem.addClass('active');
+
+ // apply permissions for current item
+ this._setupPermissions(listItem.data('type'), listItem.data('objectID'));
+ },
+
+ /**
+ * Toggles between deny and grant.
+ *
+ * @param object event
+ */
+ _change: function (event) {
+ var $checkbox = $(event.currentTarget);
+ var $optionID = $checkbox.data('optionID');
+ var $type = $checkbox.data('type');
+
+ if ($checkbox.is(':checked')) {
+ if ($type === 'deny') {
+ $('#grant' + $optionID).prop('checked', false);
- if ($item.data('type') === 'deny' && $item.attr('id') !== 'denyAll_' + this._container.attr('id')) {
- $item.prop('checked', true).trigger('change');
+ if (this._containerElements.grantAll !== null) {
+ this._containerElements.grantAll.prop('checked', false);
}
- }, this));
- }
- else {
- this._containerElements.denyAll.prop('checked', false);
-
- this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function(index, item) {
- var $item = $(item);
+ }
+ else {
+ $('#deny' + $optionID).prop('checked', false);
- if ($item.data('type') === 'grant' && $item.attr('id') !== 'grantAll_' + this._container.attr('id')) {
- $item.prop('checked', true).trigger('change');
+ if (this._containerElements.denyAll !== null) {
+ this._containerElements.denyAll.prop('checked', false);
}
- }, this));
+ }
}
- }
- else {
- if ($type === 'deny') {
- this._containerElements.grantAll.prop('checked', false);
+ else {
+ if ($type === 'deny' && this._containerElements.denyAll !== null) {
+ this._containerElements.denyAll.prop('checked', false);
+ }
+ else if ($type === 'grant' && this._containerElements.grantAll !== null) {
+ this._containerElements.grantAll.prop('checked', false);
+ }
+ }
+
+ var $allChecked = true;
+ this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function (index, item) {
+ var $item = $(item);
- this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function(index, item) {
- var $item = $(item);
-
- if ($item.data('type') === 'deny' && $item.attr('id') !== 'denyAll_' + this._container.attr('id')) {
- $item.prop('checked', false).trigger('change');
+ if ($item.data('type') === $type && $item.attr('id') !== $type + 'All_' + this._container.attr('id')) {
+ if (!$item.is(':checked')) {
+ $allChecked = false;
+ return false;
}
- }, this));
+ }
+ }, this));
+ if ($type == 'deny') {
+ if (this._containerElements.denyAll !== null) {
+ if ($allChecked) this._containerElements.denyAll.prop('checked', true);
+ else this._containerElements.denyAll.prop('checked', false);
+ }
}
else {
- this._containerElements.denyAll.prop('checked', false);
-
- this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function(index, item) {
- var $item = $(item);
-
- if ($item.data('type') === 'grant' && $item.attr('id') !== 'grantAll_' + this._container.attr('id')) {
- $item.prop('checked', false).trigger('change');
- }
- }, this));
+ if (this._containerElements.grantAll !== null) {
+ if ($allChecked) this._containerElements.grantAll.prop('checked', true);
+ else this._containerElements.grantAll.prop('checked', false);
+ }
}
- }
- },
-
- /**
- * Setups permission input for given object.
- *
- * @param string type
- * @param integer objectID
- */
- _setupPermissions: function(type, objectID) {
- // reset all checkboxes to unchecked
- this._containerElements.permissionList.find("input[type='checkbox']").prop('checked', false);
-
- // use stored permissions if applicable
- if (this._values[type] && this._values[type][objectID]) {
- for (var $optionID in this._values[type][objectID]) {
- if (this._values[type][objectID][$optionID] == 1) {
- $('#grant' + $optionID).prop('checked', true).trigger('change');
+ },
+
+ /**
+ * Toggles all options between deny and grant.
+ *
+ * @param object event
+ */
+ _changeAll: function (event) {
+ var $checkbox = $(event.currentTarget);
+ var $type = $checkbox.data('type');
+
+ if ($checkbox.is(':checked')) {
+ if ($type === 'deny') {
+ this._containerElements.grantAll.prop('checked', false);
+
+ this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function (index, item) {
+ var $item = $(item);
+
+ if ($item.data('type') === 'deny' && $item.attr('id') !== 'denyAll_' + this._container.attr('id')) {
+ $item.prop('checked', true).trigger('change');
+ }
+ }, this));
}
else {
- $('#deny' + $optionID).prop('checked', true).trigger('change');
+ this._containerElements.denyAll.prop('checked', false);
+
+ this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function (index, item) {
+ var $item = $(item);
+
+ if ($item.data('type') === 'grant' && $item.attr('id') !== 'grantAll_' + this._container.attr('id')) {
+ $item.prop('checked', true).trigger('change');
+ }
+ }, this));
}
}
- }
-
- // show permissions
- this._containerElements.permissionList.show();
- },
-
- /**
- * Saves currently set permissions.
- */
- _savePermissions: function() {
- // get active object
- var $activeObject = this._containerElements.aclList.find('li.active');
- if (!$activeObject.length) {
- return;
- }
-
- var $objectID = $activeObject.data('objectID');
- var $type = $activeObject.data('type');
-
- // clear old values
- this._values[$type][$objectID] = { };
- this._containerElements.permissionList.find("input[type='checkbox']").each((function(index, checkbox) {
- var $checkbox = $(checkbox);
- if ($checkbox.attr('id') != 'grantAll_' + this._container.attr('id') && $checkbox.attr('id') != 'denyAll_' + this._container.attr('id')) {
- var $optionValue = ($checkbox.data('type') === 'deny') ? 0 : 1;
- var $optionID = $checkbox.data('optionID');
-
- if ($checkbox.is(':checked')) {
- // store value
- this._values[$type][$objectID][$optionID] = $optionValue;
+ else {
+ if ($type === 'deny') {
+ this._containerElements.grantAll.prop('checked', false);
- // reset value afterwards
- $checkbox.prop('checked', false);
+ this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function (index, item) {
+ var $item = $(item);
+
+ if ($item.data('type') === 'deny' && $item.attr('id') !== 'denyAll_' + this._container.attr('id')) {
+ $item.prop('checked', false).trigger('change');
+ }
+ }, this));
}
- else if (this._values[$type] && this._values[$type][$objectID] && this._values[$type][$objectID][$optionID] && this._values[$type][$objectID][$optionID] == $optionValue) {
- delete this._values[$type][$objectID][$optionID];
+ else {
+ this._containerElements.denyAll.prop('checked', false);
+
+ this._containerElements.permissionList.find('input[type=checkbox]').each($.proxy(function (index, item) {
+ var $item = $(item);
+
+ if ($item.data('type') === 'grant' && $item.attr('id') !== 'grantAll_' + this._container.attr('id')) {
+ $item.prop('checked', false).trigger('change');
+ }
+ }, this));
}
}
- }).bind(this));
- },
-
- /**
- * Prepares ACL values on submit.
- *
- * @param object event
- */
- submit: function(event) {
- this._savePermissions();
-
- this._save('group');
- this._save('user');
- },
-
- /**
- * Inserts hidden form elements for each value.
- *
- * @param string $type
- */
- _save: function($type) {
- if ($.getLength(this._values[$type])) {
- var $form = this._container.parents('form:eq(0)');
+ },
+
+ /**
+ * Setups permission input for given object.
+ *
+ * @param string type
+ * @param integer objectID
+ */
+ _setupPermissions: function (type, objectID) {
+ // reset all checkboxes to unchecked
+ this._containerElements.permissionList.find("input[type='checkbox']").prop('checked', false);
- for (var $objectID in this._values[$type]) {
- var $object = this._values[$type][$objectID];
+ // use stored permissions if applicable
+ if (this._values[type] && this._values[type][objectID]) {
+ for (var $optionID in this._values[type][objectID]) {
+ if (this._values[type][objectID][$optionID] == 1) {
+ $('#grant' + $optionID).prop('checked', true).trigger('change');
+ }
+ else {
+ $('#deny' + $optionID).prop('checked', true).trigger('change');
+ }
+ }
+ }
+
+ // show permissions
+ this._containerElements.permissionList.show();
+ },
+
+ /**
+ * Saves currently set permissions.
+ */
+ _savePermissions: function () {
+ // get active object
+ var $activeObject = this._containerElements.aclList.find('li.active');
+ if (!$activeObject.length) {
+ return;
+ }
+
+ var $objectID = $activeObject.data('objectID');
+ var $type = $activeObject.data('type');
+
+ // clear old values
+ this._values[$type][$objectID] = {};
+ this._containerElements.permissionList.find("input[type='checkbox']").each((function (index, checkbox) {
+ var $checkbox = $(checkbox);
+ if ($checkbox.attr('id') != 'grantAll_' + this._container.attr('id') && $checkbox.attr('id') != 'denyAll_' + this._container.attr('id')) {
+ var $optionValue = ($checkbox.data('type') === 'deny') ? 0 : 1;
+ var $optionID = $checkbox.data('optionID');
+
+ if ($checkbox.is(':checked')) {
+ // store value
+ this._values[$type][$objectID][$optionID] = $optionValue;
+
+ // reset value afterwards
+ $checkbox.prop('checked', false);
+ }
+ else if (this._values[$type] && this._values[$type][$objectID] && this._values[$type][$objectID][$optionID] && this._values[$type][$objectID][$optionID] == $optionValue) {
+ delete this._values[$type][$objectID][$optionID];
+ }
+ }
+ }).bind(this));
+ },
+
+ /**
+ * Prepares ACL values on submit.
+ *
+ * @param object event
+ */
+ submit: function (event) {
+ this._savePermissions();
+
+ this._save('group');
+ this._save('user');
+ },
+
+ /**
+ * Inserts hidden form elements for each value.
+ *
+ * @param string $type
+ */
+ _save: function ($type) {
+ if ($.getLength(this._values[$type])) {
+ var $form = this._container.parents('form:eq(0)');
- for (var $optionID in $object) {
- $('<input type="hidden" name="aclValues[' + $type + '][' + $objectID + '][' + $optionID + ']" value="' + $object[$optionID] + '" />').appendTo($form);
+ for (var $objectID in this._values[$type]) {
+ var $object = this._values[$type][$objectID];
+
+ for (var $optionID in $object) {
+ $('<input type="hidden" name="aclValues[' + $type + '][' + $objectID + '][' + $optionID + ']" value="' + $object[$optionID] + '" />').appendTo($form);
+ }
}
}
}
- }
-});
+ });
+}
+else {
+ WCF.ACL.List = Class.extend({
+ _categoryName: "",
+ _container: {},
+ _containerElements: {},
+ _objectID: 0,
+ _objectTypeID: {},
+ _options: {},
+ _proxy: {},
+ _search: {},
+ _values: {},
+ init: function() {},
+ _reset: function() {},
+ _loadACL: function() {},
+ addObject: function() {},
+ _createListItem: function() {},
+ _removeItem: function() {},
+ _selectFirstEntry: function() {},
+ _success: function() {},
+ _parseData: function() {},
+ _click: function() {},
+ _select: function() {},
+ _change: function() {},
+ _changeAll: function() {},
+ _setupPermissions: function() {},
+ _savePermissions: function() {},
+ submit: function() {},
+ _save: function() {}
+ });
+}
*/
WCF.Attachment = {};
-/**
- * Attachment upload function
- *
- * @see WCF.Upload
- */
-WCF.Attachment.Upload = WCF.Upload.extend({
- /**
- * list of upload ids which should be automatically inserted
- * @var array<integer>
- */
- _autoInsert: [ ],
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * reference to 'Insert All' button
- * @var jQuery
+ * Attachment upload function
+ *
+ * @see WCF.Upload
*/
- _insertAllButton: null,
-
- /**
- * object type of the object the uploaded attachments belong to
- * @var string
- */
- _objectType: '',
-
- /**
- * id of the object the uploaded attachments belong to
- * @var string
- */
- _objectID: 0,
-
- /**
- * temporary hash to identify uploaded attachments
- * @var string
- */
- _tmpHash: '',
-
- /**
- * id of the parent object of the object the uploaded attachments belongs to
- * @var string
- */
- _parentObjectID: 0,
-
- /**
- * editor id
- * @var string
- */
- _editorId: '',
-
- /**
- * replace img element on load
- * @var Object
- */
- _replaceOnLoad: {},
-
- /**
- * @see WCF.Upload.init()
- */
- init: function(buttonSelector, fileListSelector, objectType, objectID, tmpHash, parentObjectID, maxUploads, editorId) {
- this._super(buttonSelector, fileListSelector, 'wcf\\data\\attachment\\AttachmentAction', { multiple: true, maxUploads: maxUploads });
+ WCF.Attachment.Upload = WCF.Upload.extend({
+ /**
+ * list of upload ids which should be automatically inserted
+ * @var array<integer>
+ */
+ _autoInsert: [],
- this._autoInsert = [ ];
- this._objectType = objectType;
- this._objectID = parseInt(objectID);
- this._tmpHash = tmpHash;
- this._parentObjectID = parseInt(parentObjectID);
- this._editorId = editorId;
+ /**
+ * reference to 'Insert All' button
+ * @var jQuery
+ */
+ _insertAllButton: null,
- this._buttonSelector.children('p.button').click($.proxy(this._validateLimit, this));
- this._fileListSelector.find('.jsButtonInsertAttachment').click($.proxy(this._insert, this));
- this._fileListSelector.find('.jsButtonAttachmentInsertThumbnail').click($.proxy(this._insert, this));
- this._fileListSelector.find('.jsButtonAttachmentInsertFull').click($.proxy(this._insert, this));
+ /**
+ * object type of the object the uploaded attachments belong to
+ * @var string
+ */
+ _objectType: '',
- WCF.DOMNodeRemovedHandler.addCallback('WCF.Attachment.Upload', $.proxy(this._removeLimitError, this));
- WCF.System.Event.addListener('com.woltlab.wcf.action.delete', 'attachment_' + this._editorId, $.proxy(this._removeLimitError, this));
+ /**
+ * id of the object the uploaded attachments belong to
+ * @var string
+ */
+ _objectID: 0,
- this._makeSortable();
+ /**
+ * temporary hash to identify uploaded attachments
+ * @var string
+ */
+ _tmpHash: '',
- this._insertAllButton = $('<p class="button jsButtonAttachmentInsertAll">' + WCF.Language.get('wcf.attachment.insertAll') + '</p>').hide().appendTo(this._buttonSelector);
- this._insertAllButton.click($.proxy(this._insertAll, this));
+ /**
+ * id of the parent object of the object the uploaded attachments belongs to
+ * @var string
+ */
+ _parentObjectID: 0,
- if (this._fileListSelector.children('li:not(.uploadFailed)').length) {
- this._insertAllButton.show();
- }
+ /**
+ * editor id
+ * @var string
+ */
+ _editorId: '',
- if (this._editorId) {
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'submit_' + this._editorId, this._submitInline.bind(this));
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'reset_' + this._editorId, this._reset.bind(this));
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'dragAndDrop_' + this._editorId, this._editorUpload.bind(this));
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this._editorId, this._editorUpload.bind(this));
+ /**
+ * replace img element on load
+ * @var Object
+ */
+ _replaceOnLoad: {},
+
+ /**
+ * @see WCF.Upload.init()
+ */
+ init: function (buttonSelector, fileListSelector, objectType, objectID, tmpHash, parentObjectID, maxUploads, editorId) {
+ this._super(buttonSelector, fileListSelector, 'wcf\\data\\attachment\\AttachmentAction', {
+ multiple: true,
+ maxUploads: maxUploads
+ });
- var metacodeAttachUuid = WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'metacode_attach_' + this._editorId, (function(data) {
- var images = this._getImageAttachments();
- var attachmentId = data.attributes[0] || 0;
- if (images.hasOwnProperty(attachmentId)) {
- var thumbnail = data.attributes[2];
- thumbnail = (thumbnail === true || thumbnail === 'true');
-
- var image = elCreate('img');
- image.className = 'woltlabAttachment';
- image.src = images[attachmentId][(thumbnail ? 'thumbnailUrl' : 'url')];
- elData(image, 'attachment-id', attachmentId);
-
- var float = data.attributes[1] || 'none';
- if (float === 'left') image.classList.add('messageFloatObjectLeft');
- else if (float === 'right') image.classList.add('messageFloatObjectRight');
-
- var metacode = data.metacode;
- metacode.parentNode.insertBefore(image, metacode);
- elRemove(metacode);
-
- data.cancel = true;
- }
- }).bind(this));
+ this._autoInsert = [];
+ this._objectType = objectType;
+ this._objectID = parseInt(objectID);
+ this._tmpHash = tmpHash;
+ this._parentObjectID = parseInt(parentObjectID);
+ this._editorId = editorId;
+
+ this._buttonSelector.children('p.button').click($.proxy(this._validateLimit, this));
+ this._fileListSelector.find('.jsButtonInsertAttachment').click($.proxy(this._insert, this));
+ this._fileListSelector.find('.jsButtonAttachmentInsertThumbnail').click($.proxy(this._insert, this));
+ this._fileListSelector.find('.jsButtonAttachmentInsertFull').click($.proxy(this._insert, this));
+
+ WCF.DOMNodeRemovedHandler.addCallback('WCF.Attachment.Upload', $.proxy(this._removeLimitError, this));
+ WCF.System.Event.addListener('com.woltlab.wcf.action.delete', 'attachment_' + this._editorId, $.proxy(this._removeLimitError, this));
+
+ this._makeSortable();
+
+ this._insertAllButton = $('<p class="button jsButtonAttachmentInsertAll">' + WCF.Language.get('wcf.attachment.insertAll') + '</p>').hide().appendTo(this._buttonSelector);
+ this._insertAllButton.click($.proxy(this._insertAll, this));
+
+ if (this._fileListSelector.children('li:not(.uploadFailed)').length) {
+ this._insertAllButton.show();
+ }
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'destroy_' + this._editorId, (function () {
- WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'submit_' + this._editorId);
- WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'reset_' + this._editorId);
- WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'insertAttachment_' + this._editorId);
- WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'dragAndDrop_' + this._editorId);
- WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this._editorId);
+ if (this._editorId) {
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'submit_' + this._editorId, this._submitInline.bind(this));
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'reset_' + this._editorId, this._reset.bind(this));
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'dragAndDrop_' + this._editorId, this._editorUpload.bind(this));
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this._editorId, this._editorUpload.bind(this));
- WCF.System.Event.removeListener('com.woltlab.wcf.redactor2', 'metacode_attach_' + this._editorId, metacodeAttachUuid);
- }).bind(this));
- }
- },
-
- /**
- * Handles drag & drop uploads and clipboard paste.
- *
- * @param object data
- */
- _editorUpload: function(data) {
- var $uploadID, replace = null;
-
- // show tab
- this._fileListSelector.closest('.messageTabMenu').messageTabMenu('showTab', 'attachments', true);
-
- if (data.file) {
- $uploadID = this._upload(undefined, data.file);
- }
- else {
- $uploadID = this._upload(undefined, undefined, data.blob);
- replace = data.replace || null;
- }
-
- if (replace === null) {
- this._autoInsert.push($uploadID);
- }
- else {
- this._replaceOnLoad[$uploadID] = replace;
- }
-
- data.uploadID = $uploadID;
- },
-
- /**
- * Sets the attachments representing an image.
- *
- * @return {Object}
- */
- _getImageAttachments: function() {
- var images = {};
-
- this._fileListSelector.children('li').each(function(index, attachment) {
- var $attachment = $(attachment);
- if ($attachment.data('isImage')) {
- images[~~$attachment.data('objectID')] = {
- thumbnailUrl: $attachment.find('.jsButtonAttachmentInsertThumbnail').data('url'),
- url: $attachment.find('.jsButtonAttachmentInsertFull').data('url')
- };
+ var metacodeAttachUuid = WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'metacode_attach_' + this._editorId, (function (data) {
+ var images = this._getImageAttachments();
+ var attachmentId = data.attributes[0] || 0;
+ if (images.hasOwnProperty(attachmentId)) {
+ var thumbnail = data.attributes[2];
+ thumbnail = (thumbnail === true || thumbnail === 'true');
+
+ var image = elCreate('img');
+ image.className = 'woltlabAttachment';
+ image.src = images[attachmentId][(thumbnail ? 'thumbnailUrl' : 'url')];
+ elData(image, 'attachment-id', attachmentId);
+
+ var float = data.attributes[1] || 'none';
+ if (float === 'left') image.classList.add('messageFloatObjectLeft');
+ else if (float === 'right') image.classList.add('messageFloatObjectRight');
+
+ var metacode = data.metacode;
+ metacode.parentNode.insertBefore(image, metacode);
+ elRemove(metacode);
+
+ data.cancel = true;
+ }
+ }).bind(this));
+
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'destroy_' + this._editorId, (function () {
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'submit_' + this._editorId);
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'reset_' + this._editorId);
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'insertAttachment_' + this._editorId);
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'dragAndDrop_' + this._editorId);
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this._editorId);
+
+ WCF.System.Event.removeListener('com.woltlab.wcf.redactor2', 'metacode_attach_' + this._editorId, metacodeAttachUuid);
+ }).bind(this));
}
- });
+ },
- return images;
- },
-
- /**
- * Adds parameters for the inline editor.
- *
- * @param object data
- */
- _submitInline: function(data) {
- if (this._tmpHash) {
- data.tmpHash = this._tmpHash;
- }
- },
-
- /**
- * Resets the attachment container.
- */
- _reset: function() {
- this._fileListSelector.hide().empty();
- this._insertAllButton.hide();
- this._validateLimit();
- },
-
- /**
- * Validates upload limits.
- *
- * @return boolean
- */
- _validateLimit: function() {
- var $innerError = this._buttonSelector.next('small.innerError');
-
- // check maximum uploads
- var $max = this._options.maxUploads - this._fileListSelector.children('li:not(.uploadFailed)').length;
- var $filesLength = (this._fileUpload) ? this._fileUpload.prop('files').length : 0;
- if ($max <= 0 || $max < $filesLength) {
- // reached limit
- var $errorMessage = ($max <= 0) ? WCF.Language.get('wcf.attachment.upload.error.reachedLimit') : WCF.Language.get('wcf.attachment.upload.error.reachedRemainingLimit').replace(/#remaining#/, $max);
- if (!$innerError.length) {
- $innerError = $('<small class="innerError" />').insertAfter(this._buttonSelector);
+ /**
+ * Handles drag & drop uploads and clipboard paste.
+ *
+ * @param object data
+ */
+ _editorUpload: function (data) {
+ var $uploadID, replace = null;
+
+ // show tab
+ this._fileListSelector.closest('.messageTabMenu').messageTabMenu('showTab', 'attachments', true);
+
+ if (data.file) {
+ $uploadID = this._upload(undefined, data.file);
+ }
+ else {
+ $uploadID = this._upload(undefined, undefined, data.blob);
+ replace = data.replace || null;
}
- $innerError.html($errorMessage);
+ if (replace === null) {
+ this._autoInsert.push($uploadID);
+ }
+ else {
+ this._replaceOnLoad[$uploadID] = replace;
+ }
- return false;
- }
-
- // remove previous errors
- $innerError.remove();
-
- return true;
- },
-
- /**
- * Removes the limit error message.
- *
- * @param object data
- */
- _removeLimitError: function(data) {
- var $listItems = this._fileListSelector.children('li');
- if (!$listItems.filter(':not(.uploadFailed)').length) {
- this._insertAllButton.hide();
- }
+ data.uploadID = $uploadID;
+ },
- if (!$listItems.length) {
- this._fileListSelector.hide();
- }
-
- if (this._editorId && data.button) {
- WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'deleteAttachment_' + this._editorId, {
- attachmentId: data.button.data('objectID')
+ /**
+ * Sets the attachments representing an image.
+ *
+ * @return {Object}
+ */
+ _getImageAttachments: function () {
+ var images = {};
+
+ this._fileListSelector.children('li').each(function (index, attachment) {
+ var $attachment = $(attachment);
+ if ($attachment.data('isImage')) {
+ images[~~$attachment.data('objectID')] = {
+ thumbnailUrl: $attachment.find('.jsButtonAttachmentInsertThumbnail').data('url'),
+ url: $attachment.find('.jsButtonAttachmentInsertFull').data('url')
+ };
+ }
});
- }
- },
-
- /**
- * @see WCF.Upload._upload()
- */
- _upload: function(event, file, blob) {
- var $uploadID = undefined;
-
- if (this._validateLimit()) {
- $uploadID = this._super(event, file, blob);
- }
+
+ return images;
+ },
- if (this._fileUpload) {
- // remove and re-create the upload button since the 'files' property
- // of the input field is readonly thus it can't be reset
- this._removeButton();
- this._createButton();
- }
+ /**
+ * Adds parameters for the inline editor.
+ *
+ * @param object data
+ */
+ _submitInline: function (data) {
+ if (this._tmpHash) {
+ data.tmpHash = this._tmpHash;
+ }
+ },
- return $uploadID;
- },
-
- /**
- * @see WCF.Upload._createUploadMatrix()
- */
- _createUploadMatrix: function(files) {
- // remove failed uploads
- this._fileListSelector.children('li.uploadFailed').remove();
+ /**
+ * Resets the attachment container.
+ */
+ _reset: function () {
+ this._fileListSelector.hide().empty();
+ this._insertAllButton.hide();
+ this._validateLimit();
+ },
- return this._super(files);
- },
-
- /**
- * @see WCF.Upload._getParameters()
- */
- _getParameters: function() {
- return {
- objectType: this._objectType,
- objectID: this._objectID,
- tmpHash: this._tmpHash,
- parentObjectID: this._parentObjectID
- };
- },
-
- /**
- * @see WCF.Upload._initFile()
- */
- _initFile: function(file) {
- var $li = $('<li class="box64"><span class="icon icon64 fa-spinner" /><div><div><p>'+file.name+'</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data('filename', file.name);
- this._fileListSelector.append($li);
- this._fileListSelector.show();
+ /**
+ * Validates upload limits.
+ *
+ * @return boolean
+ */
+ _validateLimit: function () {
+ var $innerError = this._buttonSelector.next('small.innerError');
+
+ // check maximum uploads
+ var $max = this._options.maxUploads - this._fileListSelector.children('li:not(.uploadFailed)').length;
+ var $filesLength = (this._fileUpload) ? this._fileUpload.prop('files').length : 0;
+ if ($max <= 0 || $max < $filesLength) {
+ // reached limit
+ var $errorMessage = ($max <= 0) ? WCF.Language.get('wcf.attachment.upload.error.reachedLimit') : WCF.Language.get('wcf.attachment.upload.error.reachedRemainingLimit').replace(/#remaining#/, $max);
+ if (!$innerError.length) {
+ $innerError = $('<small class="innerError" />').insertAfter(this._buttonSelector);
+ }
+
+ $innerError.html($errorMessage);
+
+ return false;
+ }
+
+ // remove previous errors
+ $innerError.remove();
+
+ return true;
+ },
- // validate file size
- if (this._buttonSelector.data('maxSize') < file.size) {
- // remove progress bar
- $li.find('progress').remove();
+ /**
+ * Removes the limit error message.
+ *
+ * @param object data
+ */
+ _removeLimitError: function (data) {
+ var $listItems = this._fileListSelector.children('li');
+ if (!$listItems.filter(':not(.uploadFailed)').length) {
+ this._insertAllButton.hide();
+ }
- // upload icon
- $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
+ if (!$listItems.length) {
+ this._fileListSelector.hide();
+ }
- // error message
- $li.find('div > div').append($('<small class="innerError">' + WCF.Language.get('wcf.attachment.upload.error.tooLarge') + '</small>'));
- $li.addClass('uploadFailed');
- }
+ if (this._editorId && data.button) {
+ WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'deleteAttachment_' + this._editorId, {
+ attachmentId: data.button.data('objectID')
+ });
+ }
+ },
- return $li;
- },
-
- /**
- * @see WCF.Upload._success()
- */
- _success: function(uploadID, data) {
- var attachmentData;
- for (var $i in this._uploadMatrix[uploadID]) {
- if (!this._uploadMatrix[uploadID].hasOwnProperty($i)) {
- continue;
+ /**
+ * @see WCF.Upload._upload()
+ */
+ _upload: function (event, file, blob) {
+ var $uploadID = undefined;
+
+ if (this._validateLimit()) {
+ $uploadID = this._super(event, file, blob);
}
- // get li
- var $li = this._uploadMatrix[uploadID][$i];
+ if (this._fileUpload) {
+ // remove and re-create the upload button since the 'files' property
+ // of the input field is readonly thus it can't be reset
+ this._removeButton();
+ this._createButton();
+ }
- // remove progress bar
- $li.find('progress').remove();
+ return $uploadID;
+ },
+
+ /**
+ * @see WCF.Upload._createUploadMatrix()
+ */
+ _createUploadMatrix: function (files) {
+ // remove failed uploads
+ this._fileListSelector.children('li.uploadFailed').remove();
- // get filename and check result
- var $filename = $li.data('filename');
- var $internalFileID = $li.data('internalFileID');
- if (data.returnValues && data.returnValues.attachments[$internalFileID]) {
- attachmentData = data.returnValues.attachments[$internalFileID];
-
- // show thumbnail
- if (attachmentData.tinyURL) {
- $li.children('.fa-spinner').replaceWith($('<img src="' + attachmentData.tinyURL + '" alt="" class="attachmentTinyThumbnail" />'));
-
- $li.data('height', attachmentData.height);
- $li.data('width', attachmentData.width);
- elData($li[0], 'is-image', attachmentData.isImage);
- }
- // show file icon
- else {
- $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-' + attachmentData.iconName);
- }
+ return this._super(files);
+ },
+
+ /**
+ * @see WCF.Upload._getParameters()
+ */
+ _getParameters: function () {
+ return {
+ objectType: this._objectType,
+ objectID: this._objectID,
+ tmpHash: this._tmpHash,
+ parentObjectID: this._parentObjectID
+ };
+ },
+
+ /**
+ * @see WCF.Upload._initFile()
+ */
+ _initFile: function (file) {
+ var $li = $('<li class="box64"><span class="icon icon64 fa-spinner" /><div><div><p>' + file.name + '</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data('filename', file.name);
+ this._fileListSelector.append($li);
+ this._fileListSelector.show();
+
+ // validate file size
+ if (this._buttonSelector.data('maxSize') < file.size) {
+ // remove progress bar
+ $li.find('progress').remove();
- // update attachment link
- var $link = $('<a href=""></a>');
- $link.text($filename).attr('href', attachmentData.url);
+ // upload icon
+ $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
- if (attachmentData.isImage != 0) {
- $link.addClass('jsImageViewer').attr('title', $filename);
+ // error message
+ $li.find('div > div').append($('<small class="innerError">' + WCF.Language.get('wcf.attachment.upload.error.tooLarge') + '</small>'));
+ $li.addClass('uploadFailed');
+ }
+
+ return $li;
+ },
+
+ /**
+ * @see WCF.Upload._success()
+ */
+ _success: function (uploadID, data) {
+ var attachmentData;
+ for (var $i in this._uploadMatrix[uploadID]) {
+ if (!this._uploadMatrix[uploadID].hasOwnProperty($i)) {
+ continue;
}
- $li.find('p').empty().append($link);
- // update file size
- $li.find('small').append(attachmentData.formattedFilesize);
+ // get li
+ var $li = this._uploadMatrix[uploadID][$i];
- // init buttons
- var $buttonList = $li.find('ul').addClass('buttonGroup');
- var $deleteButton = $('<li><span class="button small jsDeleteButton" data-object-id="'+attachmentData.attachmentID+'" data-confirm-message="'+WCF.Language.get('wcf.attachment.delete.sure')+'" data-event-name="attachment_' + this._editorId + '">' + WCF.Language.get('wcf.global.button.delete') + '</span></li>');
- $buttonList.append($deleteButton);
+ // remove progress bar
+ $li.find('progress').remove();
- $li.data('objectID', attachmentData.attachmentID);
-
- if (this._editorId) {
+ // get filename and check result
+ var $filename = $li.data('filename');
+ var $internalFileID = $li.data('internalFileID');
+ if (data.returnValues && data.returnValues.attachments[$internalFileID]) {
+ attachmentData = data.returnValues.attachments[$internalFileID];
+
+ // show thumbnail
if (attachmentData.tinyURL) {
- if (attachmentData.thumbnailURL) {
- var $insertThumbnail = $('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.thumbnailURL) + '">' + WCF.Language.get('wcf.attachment.insertThumbnail') + '</span></li>').appendTo($buttonList);
- $insertThumbnail.children('span.button').click($.proxy(this._insert, this));
- }
+ $li.children('.fa-spinner').replaceWith($('<img src="' + attachmentData.tinyURL + '" alt="" class="attachmentTinyThumbnail" />'));
- var $insertOriginal = $('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.url) + '">' + WCF.Language.get('wcf.attachment.insertFull') + '</span></li>').appendTo($buttonList);
- $insertOriginal.children('span.button').click($.proxy(this._insert, this));
+ $li.data('height', attachmentData.height);
+ $li.data('width', attachmentData.width);
+ elData($li[0], 'is-image', attachmentData.isImage);
}
+ // show file icon
else {
- var $insertPlain = $('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="' + attachmentData.attachmentID + '">' + WCF.Language.get('wcf.attachment.insert') + '</span></li>');
- $insertPlain.appendTo($buttonList).children('span.button').click($.proxy(this._insert, this));
+ $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-' + attachmentData.iconName);
}
- }
-
- if (this._replaceOnLoad.hasOwnProperty(uploadID)) {
- if (!$li.hasClass('uploadFailed')) {
- var img = this._replaceOnLoad[uploadID];
- if (img && img.parentNode) {
- WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'replaceAttachment_' + this._editorId, {
- attachmentId: attachmentData.attachmentID,
- img: img,
- src: (attachmentData.thumbnailURL) ? attachmentData.thumbnailURL : attachmentData.url
- });
+
+ // update attachment link
+ var $link = $('<a href=""></a>');
+ $link.text($filename).attr('href', attachmentData.url);
+
+ if (attachmentData.isImage != 0) {
+ $link.addClass('jsImageViewer').attr('title', $filename);
+ }
+ $li.find('p').empty().append($link);
+
+ // update file size
+ $li.find('small').append(attachmentData.formattedFilesize);
+
+ // init buttons
+ var $buttonList = $li.find('ul').addClass('buttonGroup');
+ var $deleteButton = $('<li><span class="button small jsDeleteButton" data-object-id="' + attachmentData.attachmentID + '" data-confirm-message="' + WCF.Language.get('wcf.attachment.delete.sure') + '" data-event-name="attachment_' + this._editorId + '">' + WCF.Language.get('wcf.global.button.delete') + '</span></li>');
+ $buttonList.append($deleteButton);
+
+ $li.data('objectID', attachmentData.attachmentID);
+
+ if (this._editorId) {
+ if (attachmentData.tinyURL) {
+ if (attachmentData.thumbnailURL) {
+ var $insertThumbnail = $('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.thumbnailURL) + '">' + WCF.Language.get('wcf.attachment.insertThumbnail') + '</span></li>').appendTo($buttonList);
+ $insertThumbnail.children('span.button').click($.proxy(this._insert, this));
+ }
+
+ var $insertOriginal = $('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.url) + '">' + WCF.Language.get('wcf.attachment.insertFull') + '</span></li>').appendTo($buttonList);
+ $insertOriginal.children('span.button').click($.proxy(this._insert, this));
+ }
+ else {
+ var $insertPlain = $('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="' + attachmentData.attachmentID + '">' + WCF.Language.get('wcf.attachment.insert') + '</span></li>');
+ $insertPlain.appendTo($buttonList).children('span.button').click($.proxy(this._insert, this));
}
}
- this._replaceOnLoad[uploadID] = null;
- }
- }
- else {
- // upload icon
- $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
- var $errorMessage = '';
-
- // error handling
- if (data.returnValues && data.returnValues.errors[$internalFileID]) {
- $errorMessage = data.returnValues.errors[$internalFileID]['errorType'];
+ if (this._replaceOnLoad.hasOwnProperty(uploadID)) {
+ if (!$li.hasClass('uploadFailed')) {
+ var img = this._replaceOnLoad[uploadID];
+ if (img && img.parentNode) {
+ WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'replaceAttachment_' + this._editorId, {
+ attachmentId: attachmentData.attachmentID,
+ img: img,
+ src: (attachmentData.thumbnailURL) ? attachmentData.thumbnailURL : attachmentData.url
+ });
+ }
+ }
+
+ this._replaceOnLoad[uploadID] = null;
+ }
}
else {
- // unknown error
- $errorMessage = 'uploadFailed';
+ // upload icon
+ $li.children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
+ var $errorMessage = '';
+
+ // error handling
+ if (data.returnValues && data.returnValues.errors[$internalFileID]) {
+ $errorMessage = data.returnValues.errors[$internalFileID]['errorType'];
+ }
+ else {
+ // unknown error
+ $errorMessage = 'uploadFailed';
+ }
+
+ $li.find('div > div').append($('<small class="innerError">' + WCF.Language.get('wcf.attachment.upload.error.' + $errorMessage) + '</small>'));
+ $li.addClass('uploadFailed');
}
- $li.find('div > div').append($('<small class="innerError">'+WCF.Language.get('wcf.attachment.upload.error.'+$errorMessage)+'</small>'));
- $li.addClass('uploadFailed');
- }
-
- if (WCF.inArray(uploadID, this._autoInsert)) {
- this._autoInsert.splice(this._autoInsert.indexOf(uploadID), 1);
-
- if (!$li.hasClass('uploadFailed')) {
- var btn = $li.find('.jsButtonAttachmentInsertThumbnail');
- if (!btn.length) btn = $li.find('.jsButtonAttachmentInsertFull');
+ if (WCF.inArray(uploadID, this._autoInsert)) {
+ this._autoInsert.splice(this._autoInsert.indexOf(uploadID), 1);
- btn.trigger('click');
+ if (!$li.hasClass('uploadFailed')) {
+ var btn = $li.find('.jsButtonAttachmentInsertThumbnail');
+ if (!btn.length) btn = $li.find('.jsButtonAttachmentInsertFull');
+
+ btn.trigger('click');
+ }
}
}
- }
-
- this._makeSortable();
+
+ this._makeSortable();
+
+ if (this._fileListSelector.children('li:not(.uploadFailed)').length) {
+ this._insertAllButton.show();
+ }
+ else {
+ this._insertAllButton.hide();
+ }
+
+ WCF.DOMNodeInsertedHandler.execute();
+ },
- if (this._fileListSelector.children('li:not(.uploadFailed)').length) {
- this._insertAllButton.show();
- }
- else {
- this._insertAllButton.hide();
- }
+ /**
+ * Inserts an attachment into WYSIWYG editor contents.
+ *
+ * @param {Event} event
+ */
+ _insert: function (event) {
+ WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertAttachment_' + this._editorId, {
+ attachmentId: elData(event.currentTarget, 'object-id'),
+ url: elData(event.currentTarget, 'url')
+ });
+ },
- WCF.DOMNodeInsertedHandler.execute();
- },
-
- /**
- * Inserts an attachment into WYSIWYG editor contents.
- *
- * @param {Event} event
- */
- _insert: function(event) {
- WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertAttachment_' + this._editorId, {
- attachmentId: elData(event.currentTarget, 'object-id'),
- url: elData(event.currentTarget, 'url')
- });
- },
-
- /**
- * Inserts all attachments at once.
- */
- _insertAll: function() {
- this._fileListSelector.children('li:not(.uploadFailed)').find('.jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain').trigger('click');
- },
-
- /**
- * @see WCF.Upload._error()
- */
- _error: function(data) {
- // mark uploads as failed
- this._fileListSelector.find('li').each(function(index, listItem) {
- var $listItem = $(listItem);
- if ($listItem.children('.fa-spinner').length) {
- // upload icon
- $listItem.addClass('uploadFailed').children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
- $listItem.find('div > div').append($('<small class="innerError">' + (data.responseJSON && data.responseJSON.message ? data.responseJSON.message : WCF.Language.get('wcf.attachment.upload.error.uploadFailed')) + '</small>'));
- }
- });
- },
-
- /**
- * Initializes sorting for uploaded attachments.
- */
- _makeSortable: function() {
- var $attachments = this._fileListSelector.children('li:not(.uploadFailed)');
- if (!$attachments.length) {
- return;
- }
+ /**
+ * Inserts all attachments at once.
+ */
+ _insertAll: function () {
+ this._fileListSelector.children('li:not(.uploadFailed)').find('.jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain').trigger('click');
+ },
- $attachments.addClass('sortableAttachment').children('img').addClass('sortableNode');
+ /**
+ * @see WCF.Upload._error()
+ */
+ _error: function (data) {
+ // mark uploads as failed
+ this._fileListSelector.find('li').each(function (index, listItem) {
+ var $listItem = $(listItem);
+ if ($listItem.children('.fa-spinner').length) {
+ // upload icon
+ $listItem.addClass('uploadFailed').children('.fa-spinner').removeClass('fa-spinner').addClass('fa-ban');
+ $listItem.find('div > div').append($('<small class="innerError">' + (data.responseJSON && data.responseJSON.message ? data.responseJSON.message : WCF.Language.get('wcf.attachment.upload.error.uploadFailed')) + '</small>'));
+ }
+ });
+ },
- if (!this._fileListSelector.hasClass('sortableList')) {
- this._fileListSelector.addClass('sortableList');
+ /**
+ * Initializes sorting for uploaded attachments.
+ */
+ _makeSortable: function () {
+ var $attachments = this._fileListSelector.children('li:not(.uploadFailed)');
+ if (!$attachments.length) {
+ return;
+ }
- require(['Environment'], (function (Environment) {
- if (Environment.platform() === 'desktop') {
- new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(), '', 0, {
- axis: false,
- items: 'li.sortableAttachment',
- toleranceElement: null,
- start: function (event, ui) {
- ui.placeholder[0].style.setProperty('height', ui.helper[0].offsetHeight + 'px', '');
- },
- update: (function() {
- var $attachmentIDs = [ ];
- this._fileListSelector.children('li:not(.uploadFailed)').each(function(index, listItem) {
- $attachmentIDs.push($(listItem).data('objectID'));
- });
-
- if ($attachmentIDs.length) {
- new WCF.Action.Proxy({
- autoSend: true,
- data: {
- actionName: 'updatePosition',
- className: 'wcf\\data\\attachment\\AttachmentAction',
- parameters: {
- attachmentIDs: $attachmentIDs,
- objectID: this._objectID,
- objectType: this._objectType,
- tmpHash: this._tmpHash
- }
- }
+ $attachments.addClass('sortableAttachment').children('img').addClass('sortableNode');
+
+ if (!this._fileListSelector.hasClass('sortableList')) {
+ this._fileListSelector.addClass('sortableList');
+
+ require(['Environment'], (function (Environment) {
+ if (Environment.platform() === 'desktop') {
+ new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(), '', 0, {
+ axis: false,
+ items: 'li.sortableAttachment',
+ toleranceElement: null,
+ start: function (event, ui) {
+ ui.placeholder[0].style.setProperty('height', ui.helper[0].offsetHeight + 'px', '');
+ },
+ update: (function () {
+ var $attachmentIDs = [];
+ this._fileListSelector.children('li:not(.uploadFailed)').each(function (index, listItem) {
+ $attachmentIDs.push($(listItem).data('objectID'));
});
- }
- }).bind(this)
- }, true);
- }
- }).bind(this));
+
+ if ($attachmentIDs.length) {
+ new WCF.Action.Proxy({
+ autoSend: true,
+ data: {
+ actionName: 'updatePosition',
+ className: 'wcf\\data\\attachment\\AttachmentAction',
+ parameters: {
+ attachmentIDs: $attachmentIDs,
+ objectID: this._objectID,
+ objectType: this._objectType,
+ tmpHash: this._tmpHash
+ }
+ }
+ });
+ }
+ }).bind(this)
+ }, true);
+ }
+ }).bind(this));
+ }
}
- }
-});
+ });
+}
+else {
+ WCF.Attachment.Upload = WCF.Upload.extend({
+ _autoInsert: {},
+ _insertAllButton: {},
+ _objectType: "",
+ _objectID: 0,
+ _tmpHash: "",
+ _parentObjectID: 0,
+ _editorId: "",
+ _replaceOnLoad: {},
+ init: function() {},
+ _editorUpload: function() {},
+ _getImageAttachments: function() {},
+ _submitInline: function() {},
+ _reset: function() {},
+ _validateLimit: function() {},
+ _removeLimitError: function() {},
+ _upload: function() {},
+ _createUploadMatrix: function() {},
+ _getParameters: function() {},
+ _initFile: function() {},
+ _success: function() {},
+ _insert: function() {},
+ _insertAll: function() {},
+ _error: function() {},
+ _makeSortable: function() {},
+ _name: "",
+ _buttonSelector: {},
+ _fileListSelector: {},
+ _fileUpload: {},
+ _className: "",
+ _iframe: {},
+ _internalFileID: 0,
+ _options: {},
+ _uploadMatrix: {},
+ _supportsAJAXUpload: true,
+ _overlay: {},
+ _createButton: function() {},
+ _insertButton: function() {},
+ _removeButton: function() {},
+ _progress: function() {},
+ _showOverlay: function() {},
+ _evaluateResponse: function() {},
+ _getFilename: function() {}
+ });
+}
"use strict";
-/**
- * Color picker for WCF
- *
- * @author Alexander Ebert
- * @copyright 2001-2017 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- */
-WCF.ColorPicker = Class.extend({
- /**
- * hue bar element
- * @var jQuery
- */
- _bar: null,
-
- /**
- * bar selector is being moved
- * @var boolean
- */
- _barActive: false,
-
- /**
- * bar selector element
- * @var jQuery
- */
- _barSelector: null,
-
- /**
- * optional submit callback
- * @var Function
- */
- _callbackSubmit: null,
-
- /**
- * dialog overlay
- * @var jQuery
- */
- _dialog: null,
-
- /**
- * initialization state
- * @var boolean
- */
- _didInit: false,
-
- /**
- * active element id
- * @var string
- */
- _elementID: '',
-
- /**
- * saturation and value gradient element
- * @var jQuery
- */
- _gradient: null,
-
- /**
- * gradient selector is being moved
- * @var boolean
- */
- _gradientActive: false,
-
- /**
- * gradient selector element
- * @var jQuery
- */
- _gradientSelector: null,
-
- /**
- * HEX input element
- * @var jQuery
- */
- _hex: null,
-
- /**
- * HSV representation
- * @var object
- */
- _hsv: { },
-
- /**
- * visual new color element
- * @var jQuery
- */
- _newColor: null,
-
- /**
- * visual previous color element
- * @var jQuery
- */
- _oldColor: null,
-
- /**
- * list of RGBa input elements
- * @var object
- */
- _rgba: { },
-
- /**
- * RegExp to parse rgba()
- * @var RegExp
- */
- _rgbaRegExp: null,
-
- /**
- * Initializes the WCF.ColorPicker class.
- *
- * @param string selector
- */
- init: function(selector) {
- this._callbackSubmit = null;
- this._elementID = '';
- this._hsv = { h: 0, s: 100, v: 100 };
- this._position = { };
-
- var $elements = $(selector);
- if (!$elements.length) {
- console.debug("[WCF.ColorPicker] Selector does not match any element, aborting.");
- return;
- }
-
- $elements.click($.proxy(this._open, this));
- },
-
- /**
- * Sets an optional submit callback.
- *
- * @param {Function} callback
- */
- setCallbackSubmit: function(callback) {
- this._callbackSubmit = callback;
- },
-
- /**
- * Opens the color picker overlay.
- *
- * @param object event
- */
- _open: function(event) {
- if (!this._didInit) {
- // init color picker on first usage
- this._initColorPicker();
- this._didInit = true;
- }
-
- // load values from element
- var $element = $(event.currentTarget);
- this._elementID = $element.wcfIdentify();
- this._parseColor($element);
-
- // set 'current' color
- var $rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
- this._oldColor.css({ backgroundColor: 'rgba(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ', ' + (this._rgba.a.val() / 100) + ')' });
-
- this._dialog.wcfDialog({
- 'title': WCF.Language.get('wcf.style.colorPicker')
- });
-
- // set default focus
- window.setTimeout((function () {
- this._hex.focus();
- }).bind(this), 200);
- },
-
- /**
- * Parses the color of an element.
- *
- * @param jQuery element
- */
- _parseColor: function(element) {
- if (element.data('hsv') && element.data('rgb')) {
- // create an explicit copy here, otherwise it would be only a reference
- var $hsv = element.data('hsv');
- for (var $type in $hsv) {
- this._hsv[$type] = $hsv[$type];
- }
- this._updateValues(element.data('rgb'), true, true);
- this._rgba.a.val(parseInt(element.data('alpha')));
- }
- else {
- if (this._rgbaRegExp === null) {
- this._rgbaRegExp = new RegExp("^rgba\\((\\d{1,3}), ?(\\d{1,3}), ?(\\d{1,3}), ?(1|1\\.00?|0|0?\\.[0-9]{1,2})\\)$");
- }
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Color picker for WCF
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+ WCF.ColorPicker = Class.extend({
+ /**
+ * hue bar element
+ * @var jQuery
+ */
+ _bar: null,
+
+ /**
+ * bar selector is being moved
+ * @var boolean
+ */
+ _barActive: false,
+
+ /**
+ * bar selector element
+ * @var jQuery
+ */
+ _barSelector: null,
+
+ /**
+ * optional submit callback
+ * @var Function
+ */
+ _callbackSubmit: null,
+
+ /**
+ * dialog overlay
+ * @var jQuery
+ */
+ _dialog: null,
+
+ /**
+ * initialization state
+ * @var boolean
+ */
+ _didInit: false,
+
+ /**
+ * active element id
+ * @var string
+ */
+ _elementID: '',
+
+ /**
+ * saturation and value gradient element
+ * @var jQuery
+ */
+ _gradient: null,
+
+ /**
+ * gradient selector is being moved
+ * @var boolean
+ */
+ _gradientActive: false,
+
+ /**
+ * gradient selector element
+ * @var jQuery
+ */
+ _gradientSelector: null,
+
+ /**
+ * HEX input element
+ * @var jQuery
+ */
+ _hex: null,
+
+ /**
+ * HSV representation
+ * @var object
+ */
+ _hsv: {},
+
+ /**
+ * visual new color element
+ * @var jQuery
+ */
+ _newColor: null,
+
+ /**
+ * visual previous color element
+ * @var jQuery
+ */
+ _oldColor: null,
+
+ /**
+ * list of RGBa input elements
+ * @var object
+ */
+ _rgba: {},
+
+ /**
+ * RegExp to parse rgba()
+ * @var RegExp
+ */
+ _rgbaRegExp: null,
+
+ /**
+ * Initializes the WCF.ColorPicker class.
+ *
+ * @param string selector
+ */
+ init: function (selector) {
+ this._callbackSubmit = null;
+ this._elementID = '';
+ this._hsv = {h: 0, s: 100, v: 100};
+ this._position = {};
- // parse value
- this._rgbaRegExp.exec(element.data('color'));
- var $alpha = RegExp.$4;
- // convert into x.yz
- if ($alpha.indexOf('.') === 0) {
- $alpha = "0" + $alpha;
+ var $elements = $(selector);
+ if (!$elements.length) {
+ console.debug("[WCF.ColorPicker] Selector does not match any element, aborting.");
+ return;
}
- $alpha *= 100;
- this._updateValues({
- r: RegExp.$1,
- g: RegExp.$2,
- b: RegExp.$3,
- a: Math.round($alpha)
- }, true, true);
- }
- },
-
- /**
- * Initializes the color picker upon first usage.
- */
- _initColorPicker: function() {
- this._dialog = $('<div id="colorPickerContainer" />').hide().appendTo(document.body);
-
- // create gradient
- this._gradient = $('<div id="colorPickerGradient" />').appendTo(this._dialog);
- this._gradientSelector = $('<span id="colorPickerGradientSelector"><span></span></span>').appendTo(this._gradient);
-
- // create bar
- this._bar = $('<div id="colorPickerBar" />').appendTo(this._dialog);
- this._barSelector = $('<span id="colorPickerBarSelector" />').appendTo(this._bar);
-
- // bind event listener
- this._gradient.mousedown($.proxy(this._mouseDownGradient, this));
- this._bar.mousedown($.proxy(this._mouseDownBar, this));
-
- var self = this;
- $(document).mouseup(function(event) {
- if (self._barActive) {
- self._barActive = false;
- self._mouseBar(event);
- }
- else if (self._gradientActive) {
- self._gradientActive = false;
- self._mouseGradient(event);
+ $elements.click($.proxy(this._open, this));
+ },
+
+ /**
+ * Sets an optional submit callback.
+ *
+ * @param {Function} callback
+ */
+ setCallbackSubmit: function (callback) {
+ this._callbackSubmit = callback;
+ },
+
+ /**
+ * Opens the color picker overlay.
+ *
+ * @param object event
+ */
+ _open: function (event) {
+ if (!this._didInit) {
+ // init color picker on first usage
+ this._initColorPicker();
+ this._didInit = true;
}
- }).mousemove(function(event) {
- if (self._barActive) {
- self._mouseBar(event);
- }
- else if (self._gradientActive) {
- self._mouseGradient(event);
+
+ // load values from element
+ var $element = $(event.currentTarget);
+ this._elementID = $element.wcfIdentify();
+ this._parseColor($element);
+
+ // set 'current' color
+ var $rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
+ this._oldColor.css({backgroundColor: 'rgba(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ', ' + (this._rgba.a.val() / 100) + ')'});
+
+ this._dialog.wcfDialog({
+ 'title': WCF.Language.get('wcf.style.colorPicker')
+ });
+
+ // set default focus
+ window.setTimeout((function () {
+ this._hex.focus();
+ }).bind(this), 200);
+ },
+
+ /**
+ * Parses the color of an element.
+ *
+ * @param jQuery element
+ */
+ _parseColor: function (element) {
+ if (element.data('hsv') && element.data('rgb')) {
+ // create an explicit copy here, otherwise it would be only a reference
+ var $hsv = element.data('hsv');
+ for (var $type in $hsv) {
+ this._hsv[$type] = $hsv[$type];
+ }
+ this._updateValues(element.data('rgb'), true, true);
+ this._rgba.a.val(parseInt(element.data('alpha')));
}
- });
-
- this._initColorPickerForm();
- },
-
- /**
- * Initializes the color picker input elements upon first usage.
- */
- _initColorPickerForm: function() {
- var $form = $('<div id="colorPickerForm" />').appendTo(this._dialog);
-
- // new and current color
- $('<small>' + WCF.Language.get('wcf.style.colorPicker.new') + '</small>').appendTo($form);
- var $colors = $('<ul class="colors" />').appendTo($form);
- this._newColor = $('<li class="new"><span /></li>').appendTo($colors).children('span');
- this._oldColor = $('<li class="old"><span /></li>').appendTo($colors).children('span');
- $('<small>' + WCF.Language.get('wcf.style.colorPicker.current') + '</small>').appendTo($form);
-
- // RGBa input
- var $rgba = $('<ul class="rgba" />').appendTo($form);
- this._createInputElement('r', 'R', 0, 255).appendTo($rgba);
- this._createInputElement('g', 'G', 0, 255).appendTo($rgba);
- this._createInputElement('b', 'B', 0, 255).appendTo($rgba);
- this._createInputElement('a', 'a', 0, 100).appendTo($rgba);
-
- // HEX input
- var $hex = $('<ul class="hex"><li><label><span>#</span></label></li></ul>').appendTo($form);
- this._hex = $('<input type="text" maxlength="6" />').appendTo($hex.find('label'));
-
- // bind event listener
- this._rgba.r.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
- this._rgba.g.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
- this._rgba.b.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
- this._rgba.a.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
- this._hex.blur($.proxy(this._blurHex, this)).keyup($.proxy(this._keyUpHex, this));
-
- // submit button
- var $submitForm = $('<div class="formSubmit" />').appendTo(this._dialog);
- $('<button class="buttonPrimary">' + WCF.Language.get('wcf.style.colorPicker.button.apply') + '</button>').appendTo($submitForm).click($.proxy(this._submit, this));
-
- // allow pasting of colors like '#888888'
- var self = this;
- this._hex.on('paste', function() {
- self._hex.attr('maxlength', '7');
-
- setTimeout(function() {
- var $value = self._hex.val();
- if ($value.substring(0, 1) == '#') {
- $value = $value.substr(1);
+ else {
+ if (this._rgbaRegExp === null) {
+ this._rgbaRegExp = new RegExp("^rgba\\((\\d{1,3}), ?(\\d{1,3}), ?(\\d{1,3}), ?(1|1\\.00?|0|0?\\.[0-9]{1,2})\\)$");
}
- if ($value.length > 6) {
- $value = $value.substring(0, 6);
+ // parse value
+ this._rgbaRegExp.exec(element.data('color'));
+ var $alpha = RegExp.$4;
+ // convert into x.yz
+ if ($alpha.indexOf('.') === 0) {
+ $alpha = "0" + $alpha;
}
+ $alpha *= 100;
- self._hex.attr('maxlength', '6').val($value);
- }, 50);
- });
-
- // select text in input boxes on user focus
- $form.find('input').focus(function(){
- this.select();
- });
- },
-
- /**
- * Submits form on enter.
- */
- _keyUpRGBA: function(event) {
- if (event.which == 13) {
- this._blurRgba();
- this._submit();
- }
- },
-
- /**
- * Submits form on enter.
- */
- _keyUpHex: function(event) {
- if (event.which == 13) {
- this._blurHex();
- this._submit();
- }
- },
-
- /**
- * Assigns the new color for active element.
- */
- _submit: function() {
- var $rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
-
- // create an explicit copy here, otherwise it would be only a reference
- var $hsv = { };
- for (var $type in this._hsv) {
- $hsv[$type] = this._hsv[$type];
- }
-
- var $element = $('#' + this._elementID);
- $element.data('hsv', $hsv).css({ backgroundColor: 'rgba(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ', ' + (this._rgba.a.val() / 100) + ')' }).data('alpha', parseInt(this._rgba.a.val()));
- $element.data('rgb', {
- r: this._rgba.r.val(),
- g: this._rgba.g.val(),
- b: this._rgba.b.val()
- });
- $('#' + $element.data('store')).val('rgba(' + this._rgba.r.val() + ', ' + this._rgba.g.val() + ', ' + this._rgba.b.val() + ', ' + (this._rgba.a.val() / 100) + ')').trigger('change');
+ this._updateValues({
+ r: RegExp.$1,
+ g: RegExp.$2,
+ b: RegExp.$3,
+ a: Math.round($alpha)
+ }, true, true);
+ }
+ },
- this._dialog.wcfDialog('close');
+ /**
+ * Initializes the color picker upon first usage.
+ */
+ _initColorPicker: function () {
+ this._dialog = $('<div id="colorPickerContainer" />').hide().appendTo(document.body);
+
+ // create gradient
+ this._gradient = $('<div id="colorPickerGradient" />').appendTo(this._dialog);
+ this._gradientSelector = $('<span id="colorPickerGradientSelector"><span></span></span>').appendTo(this._gradient);
+
+ // create bar
+ this._bar = $('<div id="colorPickerBar" />').appendTo(this._dialog);
+ this._barSelector = $('<span id="colorPickerBarSelector" />').appendTo(this._bar);
+
+ // bind event listener
+ this._gradient.mousedown($.proxy(this._mouseDownGradient, this));
+ this._bar.mousedown($.proxy(this._mouseDownBar, this));
+
+ var self = this;
+ $(document).mouseup(function (event) {
+ if (self._barActive) {
+ self._barActive = false;
+ self._mouseBar(event);
+ }
+ else if (self._gradientActive) {
+ self._gradientActive = false;
+ self._mouseGradient(event);
+ }
+ }).mousemove(function (event) {
+ if (self._barActive) {
+ self._mouseBar(event);
+ }
+ else if (self._gradientActive) {
+ self._mouseGradient(event);
+ }
+ });
+
+ this._initColorPickerForm();
+ },
+
+ /**
+ * Initializes the color picker input elements upon first usage.
+ */
+ _initColorPickerForm: function () {
+ var $form = $('<div id="colorPickerForm" />').appendTo(this._dialog);
+
+ // new and current color
+ $('<small>' + WCF.Language.get('wcf.style.colorPicker.new') + '</small>').appendTo($form);
+ var $colors = $('<ul class="colors" />').appendTo($form);
+ this._newColor = $('<li class="new"><span /></li>').appendTo($colors).children('span');
+ this._oldColor = $('<li class="old"><span /></li>').appendTo($colors).children('span');
+ $('<small>' + WCF.Language.get('wcf.style.colorPicker.current') + '</small>').appendTo($form);
+
+ // RGBa input
+ var $rgba = $('<ul class="rgba" />').appendTo($form);
+ this._createInputElement('r', 'R', 0, 255).appendTo($rgba);
+ this._createInputElement('g', 'G', 0, 255).appendTo($rgba);
+ this._createInputElement('b', 'B', 0, 255).appendTo($rgba);
+ this._createInputElement('a', 'a', 0, 100).appendTo($rgba);
+
+ // HEX input
+ var $hex = $('<ul class="hex"><li><label><span>#</span></label></li></ul>').appendTo($form);
+ this._hex = $('<input type="text" maxlength="6" />').appendTo($hex.find('label'));
+
+ // bind event listener
+ this._rgba.r.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
+ this._rgba.g.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
+ this._rgba.b.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
+ this._rgba.a.blur($.proxy(this._blurRgba, this)).keyup($.proxy(this._keyUpRGBA, this));
+ this._hex.blur($.proxy(this._blurHex, this)).keyup($.proxy(this._keyUpHex, this));
+
+ // submit button
+ var $submitForm = $('<div class="formSubmit" />').appendTo(this._dialog);
+ $('<button class="buttonPrimary">' + WCF.Language.get('wcf.style.colorPicker.button.apply') + '</button>').appendTo($submitForm).click($.proxy(this._submit, this));
+
+ // allow pasting of colors like '#888888'
+ var self = this;
+ this._hex.on('paste', function () {
+ self._hex.attr('maxlength', '7');
+
+ setTimeout(function () {
+ var $value = self._hex.val();
+ if ($value.substring(0, 1) == '#') {
+ $value = $value.substr(1);
+ }
+
+ if ($value.length > 6) {
+ $value = $value.substring(0, 6);
+ }
+
+ self._hex.attr('maxlength', '6').val($value);
+ }, 50);
+ });
+
+ // select text in input boxes on user focus
+ $form.find('input').focus(function () {
+ this.select();
+ });
+ },
+
+ /**
+ * Submits form on enter.
+ */
+ _keyUpRGBA: function (event) {
+ if (event.which == 13) {
+ this._blurRgba();
+ this._submit();
+ }
+ },
+
+ /**
+ * Submits form on enter.
+ */
+ _keyUpHex: function (event) {
+ if (event.which == 13) {
+ this._blurHex();
+ this._submit();
+ }
+ },
- if (typeof this._callbackSubmit === 'function') {
- this._callbackSubmit({
+ /**
+ * Assigns the new color for active element.
+ */
+ _submit: function () {
+ var $rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
+
+ // create an explicit copy here, otherwise it would be only a reference
+ var $hsv = {};
+ for (var $type in this._hsv) {
+ $hsv[$type] = this._hsv[$type];
+ }
+
+ var $element = $('#' + this._elementID);
+ $element.data('hsv', $hsv).css({backgroundColor: 'rgba(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ', ' + (this._rgba.a.val() / 100) + ')'}).data('alpha', parseInt(this._rgba.a.val()));
+ $element.data('rgb', {
r: this._rgba.r.val(),
g: this._rgba.g.val(),
- b: this._rgba.b.val(),
- a: (this._rgba.a.val() / 100)
+ b: this._rgba.b.val()
});
- }
- },
-
- /**
- * Creates an input element.
- *
- * @param string type
- * @param string label
- * @param integer min
- * @param integer max
- * @return jQuery
- */
- _createInputElement: function(type, label, min, max) {
- // create elements
- var $listItem = $('<li class="' + type + '" />');
- var $label = $('<label />').appendTo($listItem);
- $('<span>' + label + '</span>').appendTo($label);
- this._rgba[type] = $('<input type="number" value="0" min="' + min + '" max="' + max + '" step="1" />').appendTo($label);
-
- return $listItem;
- },
-
- /**
- * Handles the mouse down event on the gradient.
- *
- * @param object event
- */
- _mouseDownGradient: function(event) {
- this._gradientActive = true;
- this._mouseGradient(event);
- },
-
- /**
- * Handles updates of gradient selector position.
- *
- * @param object event
- */
- _mouseGradient: function(event) {
- var $position = this._gradient.getOffsets('offset');
-
- var $left = Math.max(Math.min(event.pageX - $position.left, 255), 0);
- var $top = Math.max(Math.min(event.pageY - $position.top, 255), 0);
-
- // calculate saturation and value
- this._hsv.s = Math.max(0, Math.min(1, $left / 255)) * 100;
- this._hsv.v = Math.max(0, Math.min(1, (255 - $top) / 255)) * 100;
-
- // update color
- this._updateValues(null);
- },
-
- /**
- * Handles the mouse down event on the bar.
- *
- * @param object event
- */
- _mouseDownBar: function(event) {
- this._barActive = true;
- this._mouseBar(event);
- },
-
- /**
- * Handles updates of the bar selector position.
- *
- * @param object event
- */
- _mouseBar: function(event) {
- var $position = this._bar.getOffsets('offset');
- var $top = Math.max(Math.min(event.pageY - $position.top, 255), 0);
- this._barSelector.css({ top: $top + 'px' });
-
- // calculate hue
- this._hsv.h = Math.max(0, Math.min(359, Math.round((255 - $top) / 255 * 360)));
-
- // update color
- this._updateValues(null);
- },
-
- /**
- * Handles changes of RGBa input fields.
- */
- _blurRgba: function() {
- for (var $type in this._rgba) {
- var $value = parseInt(this._rgba[$type].val()) || 0;
+ $('#' + $element.data('store')).val('rgba(' + this._rgba.r.val() + ', ' + this._rgba.g.val() + ', ' + this._rgba.b.val() + ', ' + (this._rgba.a.val() / 100) + ')').trigger('change');
+
+ this._dialog.wcfDialog('close');
- // alpha
- if ($type === 'a') {
- this._rgba[$type].val(Math.max(0, Math.min(100, $value)));
+ if (typeof this._callbackSubmit === 'function') {
+ this._callbackSubmit({
+ r: this._rgba.r.val(),
+ g: this._rgba.g.val(),
+ b: this._rgba.b.val(),
+ a: (this._rgba.a.val() / 100)
+ });
}
- else {
- // rgb
- this._rgba[$type].val(Math.max(0, Math.min(255, $value)));
+ },
+
+ /**
+ * Creates an input element.
+ *
+ * @param string type
+ * @param string label
+ * @param integer min
+ * @param integer max
+ * @return jQuery
+ */
+ _createInputElement: function (type, label, min, max) {
+ // create elements
+ var $listItem = $('<li class="' + type + '" />');
+ var $label = $('<label />').appendTo($listItem);
+ $('<span>' + label + '</span>').appendTo($label);
+ this._rgba[type] = $('<input type="number" value="0" min="' + min + '" max="' + max + '" step="1" />').appendTo($label);
+
+ return $listItem;
+ },
+
+ /**
+ * Handles the mouse down event on the gradient.
+ *
+ * @param object event
+ */
+ _mouseDownGradient: function (event) {
+ this._gradientActive = true;
+ this._mouseGradient(event);
+ },
+
+ /**
+ * Handles updates of gradient selector position.
+ *
+ * @param object event
+ */
+ _mouseGradient: function (event) {
+ var $position = this._gradient.getOffsets('offset');
+
+ var $left = Math.max(Math.min(event.pageX - $position.left, 255), 0);
+ var $top = Math.max(Math.min(event.pageY - $position.top, 255), 0);
+
+ // calculate saturation and value
+ this._hsv.s = Math.max(0, Math.min(1, $left / 255)) * 100;
+ this._hsv.v = Math.max(0, Math.min(1, (255 - $top) / 255)) * 100;
+
+ // update color
+ this._updateValues(null);
+ },
+
+ /**
+ * Handles the mouse down event on the bar.
+ *
+ * @param object event
+ */
+ _mouseDownBar: function (event) {
+ this._barActive = true;
+ this._mouseBar(event);
+ },
+
+ /**
+ * Handles updates of the bar selector position.
+ *
+ * @param object event
+ */
+ _mouseBar: function (event) {
+ var $position = this._bar.getOffsets('offset');
+ var $top = Math.max(Math.min(event.pageY - $position.top, 255), 0);
+ this._barSelector.css({top: $top + 'px'});
+
+ // calculate hue
+ this._hsv.h = Math.max(0, Math.min(359, Math.round((255 - $top) / 255 * 360)));
+
+ // update color
+ this._updateValues(null);
+ },
+
+ /**
+ * Handles changes of RGBa input fields.
+ */
+ _blurRgba: function () {
+ for (var $type in this._rgba) {
+ var $value = parseInt(this._rgba[$type].val()) || 0;
+
+ // alpha
+ if ($type === 'a') {
+ this._rgba[$type].val(Math.max(0, Math.min(100, $value)));
+ }
+ else {
+ // rgb
+ this._rgba[$type].val(Math.max(0, Math.min(255, $value)));
+ }
}
- }
-
- this._updateValues({
- r: this._rgba.r.val(),
- g: this._rgba.g.val(),
- b: this._rgba.b.val()
- }, true, true);
- },
-
- /**
- * Handles change of HEX value.
- */
- _blurHex: function() {
- var $value = this.hexToRgb(this._hex.val());
- if ($value !== Number.NaN) {
- this._updateValues($value, true, true);
- }
- },
-
- /**
- * Updates the values of all elements, including color picker and
- * input elements. Argument 'rgb' may be null.
- *
- * @param object rgb
- * @param boolean changeH
- * @param boolean changeSV
- */
- _updateValues: function(rgb, changeH, changeSV) {
- changeH = (changeH === true) ? true : false;
- changeSV = (changeSV === true) ? true : false;
-
- // calculate RGB values from HSV
- if (rgb === null) {
- rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
- if (this._rgba.a.val() == 0) {
- rgb.a = 100;
+ this._updateValues({
+ r: this._rgba.r.val(),
+ g: this._rgba.g.val(),
+ b: this._rgba.b.val()
+ }, true, true);
+ },
+
+ /**
+ * Handles change of HEX value.
+ */
+ _blurHex: function () {
+ var $value = this.hexToRgb(this._hex.val());
+ if ($value !== Number.NaN) {
+ this._updateValues($value, true, true);
+ }
+ },
+
+ /**
+ * Updates the values of all elements, including color picker and
+ * input elements. Argument 'rgb' may be null.
+ *
+ * @param object rgb
+ * @param boolean changeH
+ * @param boolean changeSV
+ */
+ _updateValues: function (rgb, changeH, changeSV) {
+ changeH = (changeH === true) ? true : false;
+ changeSV = (changeSV === true) ? true : false;
+
+ // calculate RGB values from HSV
+ if (rgb === null) {
+ rgb = this.hsvToRgb(this._hsv.h, this._hsv.s, this._hsv.v);
+
+ if (this._rgba.a.val() == 0) {
+ rgb.a = 100;
+ }
}
- }
-
- // add alpha channel
- if (rgb.a === undefined) {
- rgb.a = this._rgba.a.val();
- }
-
- // adjust RGBa input
- for (var $type in rgb) {
- this._rgba[$type].val(rgb[$type]);
- }
-
- // set hex input
- this._hex.val(this.rgbToHex(rgb.r, rgb.g, rgb.b));
-
- // calculate HSV to adjust selectors
- if (changeH || changeSV) {
- var $hsv = this.rgbToHsv(rgb.r, rgb.g, rgb.b);
- // adjust hue
- if (changeH) {
- this._hsv.h = $hsv.h;
+ // add alpha channel
+ if (rgb.a === undefined) {
+ rgb.a = this._rgba.a.val();
}
- // adjust saturation and value
- if (changeSV) {
- this._hsv.s = $hsv.s;
- this._hsv.v = $hsv.v;
+ // adjust RGBa input
+ for (var $type in rgb) {
+ this._rgba[$type].val(rgb[$type]);
}
- }
-
- // adjust bar selector
- var $top = Math.max(0, Math.min(255, 255 - (this._hsv.h / 360) * 255));
- this._barSelector.css({ top: $top + 'px' });
-
- // adjust gradient selector
- var $left = Math.max(0, Math.min(255, (this._hsv.s / 100) * 255));
- var $top = Math.max(0, Math.min(255, 255 - ((this._hsv.v / 100) * 255)));
- this._gradientSelector.css({
- left: ($left - 6) + 'px',
- top: ($top - 6) + 'px'
- });
+
+ // set hex input
+ this._hex.val(this.rgbToHex(rgb.r, rgb.g, rgb.b));
+
+ // calculate HSV to adjust selectors
+ if (changeH || changeSV) {
+ var $hsv = this.rgbToHsv(rgb.r, rgb.g, rgb.b);
- // update 'new' color
- this._newColor.css({ backgroundColor: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (rgb.a / 100) + ')' });
-
- // adjust gradient color
- var $rgb = this.hsvToRgb(this._hsv.h, 100, 100);
- this._gradient.css({ backgroundColor: 'rgb(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ')' });
- },
-
- /**
- * Converts a HSV color into RGB.
- *
- * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV
- *
- * @param integer h
- * @param integer s
- * @param integer v
- * @return object
- */
- hsvToRgb: function(h, s, v) {
- return window.__wcf_bc_colorUtil.hsvToRgb(h, s, v);
- },
-
- /**
- * Converts a RGB color into HSV.
- *
- * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV
- *
- * @param integer r
- * @param integer g
- * @param integer b
- * @return object
- */
- rgbToHsv: function(r, g, b) {
- return window.__wcf_bc_colorUtil.rgbToHsv(r, g, b);
- },
-
- /**
- * Converts HEX into RGB.
- *
- * @param string hex
- * @return object
- */
- hexToRgb: function(hex) {
- return window.__wcf_bc_colorUtil.hexToRgb(hex);
- },
-
- /**
- * Converts a RGB into HEX.
- *
- * @see http://www.linuxtopia.org/online_books/javascript_guides/javascript_faq/rgbtohex.htm
- *
- * @param integer r
- * @param integer g
- * @param integer b
- * @return string
- */
- rgbToHex: function(r, g, b) {
- return window.__wcf_bc_colorUtil.rgbToHex(r, g, b);
- }
-});
-
-(function() {
- if (window.__wcf_bc_colorUtil === undefined) {
- require(['ColorUtil'], function (ColorUtil) {
- // void call to force module evaluation
- });
- }
+ // adjust hue
+ if (changeH) {
+ this._hsv.h = $hsv.h;
+ }
+
+ // adjust saturation and value
+ if (changeSV) {
+ this._hsv.s = $hsv.s;
+ this._hsv.v = $hsv.v;
+ }
+ }
+
+ // adjust bar selector
+ var $top = Math.max(0, Math.min(255, 255 - (this._hsv.h / 360) * 255));
+ this._barSelector.css({top: $top + 'px'});
+
+ // adjust gradient selector
+ var $left = Math.max(0, Math.min(255, (this._hsv.s / 100) * 255));
+ var $top = Math.max(0, Math.min(255, 255 - ((this._hsv.v / 100) * 255)));
+ this._gradientSelector.css({
+ left: ($left - 6) + 'px',
+ top: ($top - 6) + 'px'
+ });
+
+ // update 'new' color
+ this._newColor.css({backgroundColor: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (rgb.a / 100) + ')'});
+
+ // adjust gradient color
+ var $rgb = this.hsvToRgb(this._hsv.h, 100, 100);
+ this._gradient.css({backgroundColor: 'rgb(' + $rgb.r + ', ' + $rgb.g + ', ' + $rgb.b + ')'});
+ },
+
+ /**
+ * Converts a HSV color into RGB.
+ *
+ * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV
+ *
+ * @param integer h
+ * @param integer s
+ * @param integer v
+ * @return object
+ */
+ hsvToRgb: function (h, s, v) {
+ return window.__wcf_bc_colorUtil.hsvToRgb(h, s, v);
+ },
+
+ /**
+ * Converts a RGB color into HSV.
+ *
+ * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV
+ *
+ * @param integer r
+ * @param integer g
+ * @param integer b
+ * @return object
+ */
+ rgbToHsv: function (r, g, b) {
+ return window.__wcf_bc_colorUtil.rgbToHsv(r, g, b);
+ },
+
+ /**
+ * Converts HEX into RGB.
+ *
+ * @param string hex
+ * @return object
+ */
+ hexToRgb: function (hex) {
+ return window.__wcf_bc_colorUtil.hexToRgb(hex);
+ },
+
+ /**
+ * Converts a RGB into HEX.
+ *
+ * @see http://www.linuxtopia.org/online_books/javascript_guides/javascript_faq/rgbtohex.htm
+ *
+ * @param integer r
+ * @param integer g
+ * @param integer b
+ * @return string
+ */
+ rgbToHex: function (r, g, b) {
+ return window.__wcf_bc_colorUtil.rgbToHex(r, g, b);
+ }
+ });
- if (typeof window.__wcf_bc_colorPickerInit === 'function') {
- window.__wcf_bc_colorPickerInit();
- }
-})();
\ No newline at end of file
+ (function () {
+ if (window.__wcf_bc_colorUtil === undefined) {
+ require(['ColorUtil'], function (ColorUtil) {
+ // void call to force module evaluation
+ });
+ }
+
+ if (typeof window.__wcf_bc_colorPickerInit === 'function') {
+ window.__wcf_bc_colorPickerInit();
+ }
+ })();
+}
+else {
+ WCF.ColorPicker = Class.extend({
+ _bar: {},
+ _barActive: false,
+ _barSelector: {},
+ _dialog: {},
+ _didInit: false,
+ _elementID: "",
+ _gradient: {},
+ _gradientActive: false,
+ _gradientSelector: {},
+ _hex: {},
+ _hsv: {},
+ _newColor: {},
+ _oldColor: {},
+ _rgba: {},
+ _rgbaRegExp: {},
+ init: function() {},
+ _open: function() {},
+ _parseColor: function() {},
+ _initColorPicker: function() {},
+ _initColorPickerForm: function() {},
+ _keyUpRGBA: function() {},
+ _keyUpHex: function() {},
+ _submit: function() {},
+ _createInputElement: function() {},
+ _mouseDownGradient: function() {},
+ _mouseGradient: function() {},
+ _mouseDownBar: function() {},
+ _mouseBar: function() {},
+ _blurRgba: function() {},
+ _blurHex: function() {},
+ _updateValues: function() {},
+ hsvToRgb: function (h, s, v) { return window.__wcf_bc_colorUtil.hsvToRgb(h, s, v); },
+ rgbToHsv: function (r, g, b) { return window.__wcf_bc_colorUtil.rgbToHsv(r, g, b); },
+ hexToRgb: function (hex) { return window.__wcf_bc_colorUtil.hexToRgb(hex); },
+ rgbToHex: function (r, g, b) { return window.__wcf_bc_colorUtil.rgbToHex(r, g, b); }
+ });
+}
\ No newline at end of file
*/
WCF.Label = {};
-/**
- * Provides enhancements for ACP label management.
- */
-WCF.Label.ACPList = Class.extend({
- /**
- * input element
- * @var jQuery
- */
- _labelInput: null,
-
- /**
- * list of pre-defined label items
- * @var array<jQuery>
- */
- _labelList: [ ],
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes the ACP label list.
+ * Provides enhancements for ACP label management.
*/
- init: function() {
- this._labelInput = $('#label').keydown($.proxy(this._keyPressed, this)).keyup($.proxy(this._keyPressed, this)).blur($.proxy(this._keyPressed, this));
+ WCF.Label.ACPList = Class.extend({
+ /**
+ * input element
+ * @var jQuery
+ */
+ _labelInput: null,
- if ($.browser.mozilla && $.browser.touch) {
- this._labelInput.on('input', $.proxy(this._keyPressed, this));
- }
+ /**
+ * list of pre-defined label items
+ * @var array<jQuery>
+ */
+ _labelList: [],
- $('#labelList').find('input[type="radio"]').each($.proxy(function(index, input) {
- var $input = $(input);
+ /**
+ * Initializes the ACP label list.
+ */
+ init: function () {
+ this._labelInput = $('#label').keydown($.proxy(this._keyPressed, this)).keyup($.proxy(this._keyPressed, this)).blur($.proxy(this._keyPressed, this));
- // ignore custom values
- if ($input.prop('value') !== 'custom') {
- this._labelList.push($($input.next('span')));
+ if ($.browser.mozilla && $.browser.touch) {
+ this._labelInput.on('input', $.proxy(this._keyPressed, this));
}
- }, this));
- },
-
- /**
- * Renders label name as label or falls back to a default value if label is empty.
- */
- _keyPressed: function() {
- var $text = this._labelInput.prop('value');
- if ($text === '') $text = WCF.Language.get('wcf.acp.label.defaultValue');
+
+ $('#labelList').find('input[type="radio"]').each($.proxy(function (index, input) {
+ var $input = $(input);
+
+ // ignore custom values
+ if ($input.prop('value') !== 'custom') {
+ this._labelList.push($($input.next('span')));
+ }
+ }, this));
+ },
- for (var $i = 0, $length = this._labelList.length; $i < $length; $i++) {
- this._labelList[$i].text($text);
+ /**
+ * Renders label name as label or falls back to a default value if label is empty.
+ */
+ _keyPressed: function () {
+ var $text = this._labelInput.prop('value');
+ if ($text === '') $text = WCF.Language.get('wcf.acp.label.defaultValue');
+
+ for (var $i = 0, $length = this._labelList.length; $i < $length; $i++) {
+ this._labelList[$i].text($text);
+ }
}
- }
-});
-
-/**
- * Provides simple logic to inherit associations within structured lists.
- */
-WCF.Label.ACPList.Connect = Class.extend({
- /**
- * Initializes inheritation for structured lists.
- */
- init: function() {
- var $listItems = $('#connect .structuredList li');
- if (!$listItems.length) return;
-
- $listItems.each($.proxy(function(index, item) {
- $(item).find('input[type="checkbox"]').click($.proxy(this._click, this));
- }, this));
- },
+ });
/**
- * Marks items as checked if they're logically below current item.
- *
- * @param object event
+ * Provides simple logic to inherit associations within structured lists.
*/
- _click: function(event) {
- var $listItem = $(event.currentTarget);
- if ($listItem.is(':checked')) {
- $listItem = $listItem.parents('li');
- var $depth = $listItem.data('depth');
+ WCF.Label.ACPList.Connect = Class.extend({
+ /**
+ * Initializes inheritation for structured lists.
+ */
+ init: function () {
+ var $listItems = $('#connect .structuredList li');
+ if (!$listItems.length) return;
- while (true) {
- $listItem = $listItem.next();
- if (!$listItem.length) {
- // no more siblings
- return true;
- }
+ $listItems.each($.proxy(function (index, item) {
+ $(item).find('input[type="checkbox"]').click($.proxy(this._click, this));
+ }, this));
+ },
+
+ /**
+ * Marks items as checked if they're logically below current item.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $listItem = $(event.currentTarget);
+ if ($listItem.is(':checked')) {
+ $listItem = $listItem.parents('li');
+ var $depth = $listItem.data('depth');
- // element is on the same or higher level (= lower depth)
- if ($listItem.data('depth') <= $depth) {
- return true;
+ while (true) {
+ $listItem = $listItem.next();
+ if (!$listItem.length) {
+ // no more siblings
+ return true;
+ }
+
+ // element is on the same or higher level (= lower depth)
+ if ($listItem.data('depth') <= $depth) {
+ return true;
+ }
+
+ $listItem.find('input[type="checkbox"]').prop('checked', 'checked');
}
-
- $listItem.find('input[type="checkbox"]').prop('checked', 'checked');
}
}
- }
-});
+ });
+}
+else {
+ WCF.Label.ACPList = Class.extend({
+ _labelInput: {},
+ _labelList: {},
+ init: function() {},
+ _keyPressed: function() {}
+ });
+
+ WCF.Label.ACPList.Connect = Class.extend({
+ init: function() {},
+ _click: function() {}
+ });
+}
/**
* Provides a flexible label chooser.
}
});
-/**
- * Handles displaying label groups based on the selected categories.
- */
-WCF.Label.ArticleLabelChooser = WCF.Label.Chooser.extend({
- /**
- * maps the available label group ids to the categories
- * @var object
- */
- _labelGroupsToCategories: null,
-
- /**
- * Initializes a new WCF.Label.ArticleLabelChooser object.
- *
- * @param object labelGroupsToCategories
- * @param object selectedLabelIDs
- * @param string containerSelector
- * @param string submitButtonSelector
- * @param boolean showWithoutSelection
- */
- init: function(labelGroupsToCategories, selectedLabelIDs, containerSelector, submitButtonSelector, showWithoutSelection) {
- this._super(selectedLabelIDs, containerSelector, submitButtonSelector, showWithoutSelection);
- this._labelGroupsToCategories = labelGroupsToCategories;
-
- this._updateLabelGroups();
-
- $('#categoryID').change($.proxy(this._updateLabelGroups, this));
- },
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Updates the visible label groups based on the selected categories.
+ * Handles displaying label groups based on the selected categories.
*/
- _updateLabelGroups: function() {
- // hide all label choosers first
- $('.labelChooser').each(function(index, element) {
- $(element).parents('dl:eq(0)').hide();
- })
+ WCF.Label.ArticleLabelChooser = WCF.Label.Chooser.extend({
+ /**
+ * maps the available label group ids to the categories
+ * @var object
+ */
+ _labelGroupsToCategories: null,
- var visibleGroupIDs = [];
- var categoryID = parseInt($('#categoryID').val());
+ /**
+ * Initializes a new WCF.Label.ArticleLabelChooser object.
+ *
+ * @param object labelGroupsToCategories
+ * @param object selectedLabelIDs
+ * @param string containerSelector
+ * @param string submitButtonSelector
+ * @param boolean showWithoutSelection
+ */
+ init: function (labelGroupsToCategories, selectedLabelIDs, containerSelector, submitButtonSelector, showWithoutSelection) {
+ this._super(selectedLabelIDs, containerSelector, submitButtonSelector, showWithoutSelection);
+ this._labelGroupsToCategories = labelGroupsToCategories;
+
+ this._updateLabelGroups();
+
+ $('#categoryID').change($.proxy(this._updateLabelGroups, this));
+ },
- if (this._labelGroupsToCategories[categoryID]) {
- for (var i = 0, length = this._labelGroupsToCategories[categoryID].length; i < length; i++) {
- $('#labelGroup' + this._labelGroupsToCategories[categoryID][i]).parents('dl:eq(0)').show();
+ /**
+ * Updates the visible label groups based on the selected categories.
+ */
+ _updateLabelGroups: function () {
+ // hide all label choosers first
+ $('.labelChooser').each(function (index, element) {
+ $(element).parents('dl:eq(0)').hide();
+ })
+
+ var visibleGroupIDs = [];
+ var categoryID = parseInt($('#categoryID').val());
+
+ if (this._labelGroupsToCategories[categoryID]) {
+ for (var i = 0, length = this._labelGroupsToCategories[categoryID].length; i < length; i++) {
+ $('#labelGroup' + this._labelGroupsToCategories[categoryID][i]).parents('dl:eq(0)').show();
+ }
}
- }
- },
-
- /**
- * @see WCF.Label.Chooser._submit()
- */
- _submit: function() {
- // delete non-selected groups to avoid sumitting these labels
- for (var groupID in this._groups) {
- if (!this._groups[groupID].is(':visible')) {
- delete this._groups[groupID];
+ },
+
+ /**
+ * @see WCF.Label.Chooser._submit()
+ */
+ _submit: function () {
+ // delete non-selected groups to avoid sumitting these labels
+ for (var groupID in this._groups) {
+ if (!this._groups[groupID].is(':visible')) {
+ delete this._groups[groupID];
+ }
}
+
+ this._super();
}
-
- this._super();
- }
-});
\ No newline at end of file
+ });
+}
+else {
+ WCF.Label.ArticleLabelChooser = WCF.Label.Chooser.extend({
+ _labelGroupsToCategories: {},
+ init: function() {},
+ _updateLabelGroups: function () {},
+ _submit: function() {}
+ });
+}
case $.ui.keyCode.LEFT:
case $.ui.keyCode.RIGHT:
return;
- break;
case $.ui.keyCode.UP:
this._selectPreviousItem();
return;
- break;
case $.ui.keyCode.DOWN:
this._selectNextItem();
return;
- break;
case $.ui.keyCode.ENTER:
return this._selectElement(event);
- break;
}
var $content = this._getSearchString(event);
}
});
-/**
- * Provides the dynamic parts of the edit history interface.
- */
-WCF.Message.EditHistory = Class.extend({
- /**
- * jQuery object containing the radio buttons for the oldID
- * @var object
- */
- _oldIDInputs: null,
-
- /**
- * jQuery object containing the radio buttons for the oldID
- * @var object
- */
- _newIDInputs: null,
-
- /**
- * selector for the version rows
- * @var string
- */
- _containerSelector: '',
-
- /**
- * selector for the revert button
- * @var string
- */
- _buttonSelector: '.jsRevertButton',
-
- /**
- * Initializes the edit history interface.
- *
- * @param object oldIDInputs
- * @param object newIDInputs
- * @param string containerSelector
- * @param string buttonSelector
- * @param {Object} options
- */
- init: function(oldIDInputs, newIDInputs, containerSelector, buttonSelector, options) {
- this._oldIDInputs = oldIDInputs;
- this._newIDInputs = newIDInputs;
- this._containerSelector = containerSelector;
- this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsRevertButton';
- this._options = $.extend({
- isVersionTracker: false,
- versionTrackerObjectType: '',
- versionTrackerObjectId: 0,
- redirectUrl: ''
- }, options);
-
- this.proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- this._initInputs();
- this._initElements();
- },
-
- /**
- * Initializes the radio buttons.
- * Force the "oldID" to be lower than the "newID"
- * 'current' is interpreted as Infinity.
- */
- _initInputs: function() {
- var self = this;
- this._newIDInputs.change(function(event) {
- var newID = parseInt($(this).val());
- if ($(this).val() === 'current') newID = Infinity;
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Provides the dynamic parts of the edit history interface.
+ */
+ WCF.Message.EditHistory = Class.extend({
+ /**
+ * jQuery object containing the radio buttons for the oldID
+ * @var object
+ */
+ _oldIDInputs: null,
+
+ /**
+ * jQuery object containing the radio buttons for the oldID
+ * @var object
+ */
+ _newIDInputs: null,
+
+ /**
+ * selector for the version rows
+ * @var string
+ */
+ _containerSelector: '',
+
+ /**
+ * selector for the revert button
+ * @var string
+ */
+ _buttonSelector: '.jsRevertButton',
+
+ /**
+ * Initializes the edit history interface.
+ *
+ * @param object oldIDInputs
+ * @param object newIDInputs
+ * @param string containerSelector
+ * @param string buttonSelector
+ * @param {Object} options
+ */
+ init: function (oldIDInputs, newIDInputs, containerSelector, buttonSelector, options) {
+ this._oldIDInputs = oldIDInputs;
+ this._newIDInputs = newIDInputs;
+ this._containerSelector = containerSelector;
+ this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsRevertButton';
+ this._options = $.extend({
+ isVersionTracker: false,
+ versionTrackerObjectType: '',
+ versionTrackerObjectId: 0,
+ redirectUrl: ''
+ }, options);
- self._oldIDInputs.each(function(event) {
- var oldID = parseInt($(this).val());
- if ($(this).val() === 'current') oldID = Infinity;
-
- if (oldID >= newID) {
- $(this).disable();
- }
- else {
- $(this).enable();
- }
+ this.proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
});
- });
-
- this._oldIDInputs.change(function(event) {
- var oldID = parseInt($(this).val());
- if ($(this).val() === 'current') oldID = Infinity;
- self._newIDInputs.each(function(event) {
+ this._initInputs();
+ this._initElements();
+ },
+
+ /**
+ * Initializes the radio buttons.
+ * Force the "oldID" to be lower than the "newID"
+ * 'current' is interpreted as Infinity.
+ */
+ _initInputs: function () {
+ var self = this;
+ this._newIDInputs.change(function (event) {
var newID = parseInt($(this).val());
if ($(this).val() === 'current') newID = Infinity;
- if (newID <= oldID) {
- $(this).disable();
- }
- else {
- $(this).enable();
- }
+ self._oldIDInputs.each(function (event) {
+ var oldID = parseInt($(this).val());
+ if ($(this).val() === 'current') oldID = Infinity;
+
+ if (oldID >= newID) {
+ $(this).disable();
+ }
+ else {
+ $(this).enable();
+ }
+ });
});
- });
- this._oldIDInputs.filter(':checked').change();
- this._newIDInputs.filter(':checked').change();
- },
-
- /**
- * Initializes available element containers.
- */
- _initElements: function() {
- var self = this;
- $(this._containerSelector).each(function(index, container) {
- var $container = $(container);
- $container.find(self._buttonSelector).click($.proxy(self._click, self));
- });
- },
-
- /**
- * Sends AJAX request.
- *
- * @param object event
- */
- _click: function(event) {
- var $target = $(event.currentTarget);
- event.preventDefault();
-
- if ($target.data('confirmMessage')) {
- var self = this;
- WCF.System.Confirmation.show($target.data('confirmMessage'), function(action) {
- if (action === 'cancel') return;
+ this._oldIDInputs.change(function (event) {
+ var oldID = parseInt($(this).val());
+ if ($(this).val() === 'current') oldID = Infinity;
- self._sendRequest($target);
- }, undefined, undefined, true);
- }
- else {
- this._sendRequest($target);
- }
- },
-
-
- /**
- * Sends the request
- *
- * @param jQuery object
- */
- _sendRequest: function(object) {
- if (this._options.isVersionTracker) {
- //noinspection JSUnresolvedVariable
- this.proxy.setOption('url', window.WSC_API_URL + 'index.php?ajax-invoke/&t=' + window.SECURITY_TOKEN);
- this.proxy.setOption('data', {
- actionName: 'revert',
- className: 'wcf\\system\\version\\VersionTracker',
- parameters: {
- objectType: this._options.versionTrackerObjectType,
- objectID: this._options.versionTrackerObjectId,
- versionID: $(object).data('objectID')
- }
+ self._newIDInputs.each(function (event) {
+ var newID = parseInt($(this).val());
+ if ($(this).val() === 'current') newID = Infinity;
+
+ if (newID <= oldID) {
+ $(this).disable();
+ }
+ else {
+ $(this).enable();
+ }
+ });
});
- }
- else {
- this.proxy.setOption('data', {
- actionName: 'revert',
- className: 'wcf\\data\\edit\\history\\entry\\EditHistoryEntryAction',
- objectIDs: [$(object).data('objectID')]
+ this._oldIDInputs.filter(':checked').change();
+ this._newIDInputs.filter(':checked').change();
+ },
+
+ /**
+ * Initializes available element containers.
+ */
+ _initElements: function () {
+ var self = this;
+ $(this._containerSelector).each(function (index, container) {
+ var $container = $(container);
+ $container.find(self._buttonSelector).click($.proxy(self._click, self));
});
+ },
+
+ /**
+ * Sends AJAX request.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $target = $(event.currentTarget);
+ event.preventDefault();
+
+ if ($target.data('confirmMessage')) {
+ var self = this;
+
+ WCF.System.Confirmation.show($target.data('confirmMessage'), function (action) {
+ if (action === 'cancel') return;
+
+ self._sendRequest($target);
+ }, undefined, undefined, true);
+ }
+ else {
+ this._sendRequest($target);
+ }
+ },
+
+
+ /**
+ * Sends the request
+ *
+ * @param jQuery object
+ */
+ _sendRequest: function (object) {
+ if (this._options.isVersionTracker) {
+ //noinspection JSUnresolvedVariable
+ this.proxy.setOption('url', window.WSC_API_URL + 'index.php?ajax-invoke/&t=' + window.SECURITY_TOKEN);
+ this.proxy.setOption('data', {
+ actionName: 'revert',
+ className: 'wcf\\system\\version\\VersionTracker',
+ parameters: {
+ objectType: this._options.versionTrackerObjectType,
+ objectID: this._options.versionTrackerObjectId,
+ versionID: $(object).data('objectID')
+ }
+ });
+ }
+ else {
+ this.proxy.setOption('data', {
+ actionName: 'revert',
+ className: 'wcf\\data\\edit\\history\\entry\\EditHistoryEntryAction',
+ objectIDs: [$(object).data('objectID')]
+ });
+ }
+
+ this.proxy.sendRequest();
+ },
+
+ /**
+ * Reloads the page to show the new versions.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param object jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ if (this._options.redirectUrl) {
+ new WCF.System.Notification().show((function () {
+ window.location = this._options.redirectUrl;
+ }).bind(this));
+ }
+ else {
+ window.location.reload(true);
+ }
}
-
- this.proxy.sendRequest();
- },
-
- /**
- * Reloads the page to show the new versions.
- *
- * @param object data
- * @param string textStatus
- * @param object jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- if (this._options.redirectUrl) {
- new WCF.System.Notification().show((function () {
- window.location = this._options.redirectUrl;
- }).bind(this));
- }
- else {
- window.location.reload(true);
- }
- }
-});
+ });
+}
+else {
+ WCF.Message.EditHistory = Class.extend({
+ _oldIDInputs: {},
+ _newIDInputs: {},
+ _containerSelector: "",
+ _buttonSelector: "",
+ init: function() {},
+ _initInputs: function() {},
+ _initElements: function() {},
+ _click: function() {},
+ _sendRequest: function() {},
+ _success: function() {}
+ });
+}
/**
* Prevents multiple submits of the same form by disabling the submit button.
}
});
-/**
- * Provides previews for Redactor message fields.
- *
- * @param string className
- * @param string messageFieldID
- * @param string previewButtonID
- */
-WCF.Message.Preview = Class.extend({
- /**
- * class name
- * @var string
- */
- _className: '',
-
- /**
- * message field id
- * @var string
- */
- _messageFieldID: '',
-
- /**
- * message field
- * @var jQuery
- */
- _messageField: null,
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * preview button
- * @var jQuery
- */
- _previewButton: null,
-
- /**
- * previous button label
- * @var string
- */
- _previewButtonLabel: '',
-
- /**
- * Initializes a new WCF.Message.Preview object.
- *
- * @param string className
- * @param string messageFieldID
- * @param string previewButtonID
- */
- init: function(className, messageFieldID, previewButtonID) {
- this._className = className;
-
- // validate message field
- this._messageFieldID = $.wcfEscapeID(messageFieldID);
- this._textarea = $('#' + this._messageFieldID);
- if (!this._textarea.length) {
- console.debug("[WCF.Message.Preview] Unable to find message field identified by '" + this._messageFieldID + "'");
- return;
- }
-
- // validate preview button
- previewButtonID = $.wcfEscapeID(previewButtonID);
- this._previewButton = $('#' + previewButtonID);
- if (!this._previewButton.length) {
- console.debug("[WCF.Message.Preview] Unable to find preview button identified by '" + previewButtonID + "'");
- return;
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Provides previews for Redactor message fields.
+ *
+ * @param string className
+ * @param string messageFieldID
+ * @param string previewButtonID
+ */
+ WCF.Message.Preview = Class.extend({
+ /**
+ * class name
+ * @var string
+ */
+ _className: '',
+
+ /**
+ * message field id
+ * @var string
+ */
+ _messageFieldID: '',
+
+ /**
+ * message field
+ * @var jQuery
+ */
+ _messageField: null,
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * preview button
+ * @var jQuery
+ */
+ _previewButton: null,
+
+ /**
+ * previous button label
+ * @var string
+ */
+ _previewButtonLabel: '',
+
+ /**
+ * Initializes a new WCF.Message.Preview object.
+ *
+ * @param string className
+ * @param string messageFieldID
+ * @param string previewButtonID
+ */
+ init: function (className, messageFieldID, previewButtonID) {
+ this._className = className;
+
+ // validate message field
+ this._messageFieldID = $.wcfEscapeID(messageFieldID);
+ this._textarea = $('#' + this._messageFieldID);
+ if (!this._textarea.length) {
+ console.debug("[WCF.Message.Preview] Unable to find message field identified by '" + this._messageFieldID + "'");
+ return;
+ }
+
+ // validate preview button
+ previewButtonID = $.wcfEscapeID(previewButtonID);
+ this._previewButton = $('#' + previewButtonID);
+ if (!this._previewButton.length) {
+ console.debug("[WCF.Message.Preview] Unable to find preview button identified by '" + previewButtonID + "'");
+ return;
+ }
+
+ this._previewButton.click($.proxy(this._click, this));
+ this._proxy = new WCF.Action.Proxy({
+ failure: $.proxy(this._failure, this),
+ success: $.proxy(this._success, this)
+ });
+ },
+
+ /**
+ * Reads message field input and triggers an AJAX request.
+ */
+ _click: function (event) {
+ var $message = this._getMessage();
+ if ($message === null) {
+ console.debug("[WCF.Message.Preview] Unable to access Redactor instance of '" + this._messageFieldID + "'");
+ return;
+ }
+
+ this._proxy.setOption('data', {
+ actionName: 'getMessagePreview',
+ className: this._className,
+ parameters: this._getParameters($message)
+ });
+ this._proxy.sendRequest();
+
+ // update button label
+ this._previewButtonLabel = this._previewButton.html();
+ this._previewButton.html(WCF.Language.get('wcf.global.loading')).disable();
+
+ // poke event
+ event.stopPropagation();
+ return false;
+ },
+
+ /**
+ * Returns request parameters.
+ *
+ * @param string message
+ * @return object
+ */
+ _getParameters: function (message) {
+ // collect message form options
+ var $options = {};
+ $('#settings_' + this._messageFieldID).find('input[type=checkbox]').each(function (index, checkbox) {
+ var $checkbox = $(checkbox);
+ if ($checkbox.is(':checked')) {
+ $options[$checkbox.prop('name')] = $checkbox.prop('value');
+ }
+ });
+
+ // build parameters
+ return {
+ data: {
+ message: message
+ },
+ options: $options
+ };
+ },
+
+ /**
+ * Returns parsed message from Redactor or null if editor was not accessible.
+ *
+ * @return string
+ */
+ _getMessage: function () {
+ return this._textarea.redactor('code.get');
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ // restore preview button
+ this._previewButton.html(this._previewButtonLabel).enable();
+
+ // remove error message
+ this._textarea.parent().children('small.innerError').remove();
+
+ // evaluate message
+ this._handleResponse(data);
+ },
+
+ /**
+ * Evaluates response data.
+ *
+ * @param object data
+ */
+ _handleResponse: function (data) {
+ },
+
+ /**
+ * Handles errors during preview requests.
+ *
+ * The return values indicates if the default error overlay is shown.
+ *
+ * @param object data
+ * @return boolean
+ */
+ _failure: function (data) {
+ if (data === null || data.returnValues === undefined || data.returnValues.errorType === undefined) {
+ return true;
+ }
+
+ // restore preview button
+ this._previewButton.html(this._previewButtonLabel).enable();
+
+ var $innerError = this._textarea.parent().children('small.innerError').empty();
+ if (!$innerError.length) {
+ $innerError = $('<small class="innerError" />').appendTo(this._textarea.parent());
+ }
+
+ $innerError.html((data.returnValues.errorType === 'empty' ? WCF.Language.get('wcf.global.form.error.empty') : data.returnValues.errorMessage));
+
+ return false;
}
-
- this._previewButton.click($.proxy(this._click, this));
- this._proxy = new WCF.Action.Proxy({
- failure: $.proxy(this._failure, this),
- success: $.proxy(this._success, this)
- });
- },
+ });
/**
- * Reads message field input and triggers an AJAX request.
+ * Default implementation for message previews.
+ *
+ * @see WCF.Message.Preview
*/
- _click: function(event) {
- var $message = this._getMessage();
- if ($message === null) {
- console.debug("[WCF.Message.Preview] Unable to access Redactor instance of '" + this._messageFieldID + "'");
- return;
- }
-
- this._proxy.setOption('data', {
- actionName: 'getMessagePreview',
- className: this._className,
- parameters: this._getParameters($message)
- });
- this._proxy.sendRequest();
-
- // update button label
- this._previewButtonLabel = this._previewButton.html();
- this._previewButton.html(WCF.Language.get('wcf.global.loading')).disable();
+ WCF.Message.DefaultPreview = WCF.Message.Preview.extend({
+ _dialog: null,
+ _options: {},
- // poke event
- event.stopPropagation();
- return false;
- },
-
- /**
- * Returns request parameters.
- *
- * @param string message
- * @return object
- */
- _getParameters: function(message) {
- // collect message form options
- var $options = { };
- $('#settings_' + this._messageFieldID).find('input[type=checkbox]').each(function(index, checkbox) {
- var $checkbox = $(checkbox);
- if ($checkbox.is(':checked')) {
- $options[$checkbox.prop('name')] = $checkbox.prop('value');
+ /**
+ * @see WCF.Message.Preview.init()
+ */
+ init: function (options) {
+ if (arguments.length > 1 && typeof options === 'string') {
+ throw new Error("Outdated API call, please update your implementation.");
}
- });
-
- // build parameters
- return {
- data: {
- message: message
- },
- options: $options
- };
- },
-
- /**
- * Returns parsed message from Redactor or null if editor was not accessible.
- *
- * @return string
- */
- _getMessage: function() {
- return this._textarea.redactor('code.get');
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- // restore preview button
- this._previewButton.html(this._previewButtonLabel).enable();
-
- // remove error message
- this._textarea.parent().children('small.innerError').remove();
+
+ this._options = $.extend({
+ disallowedBBCodesPermission: 'user.message.disallowedBBCodes',
+ messageFieldID: '',
+ previewButtonID: '',
+ messageObjectType: '',
+ messageObjectID: 0
+ }, options);
+
+ if (!this._options.messageObjectType) {
+ throw new Error("Field 'messageObjectType' cannot be empty.");
+ }
+
+ this._super('wcf\\data\\bbcode\\MessagePreviewAction', this._options.messageFieldID, this._options.previewButtonID);
+ },
+
+ /**
+ * @see WCF.Message.Preview._handleResponse()
+ */
+ _handleResponse: function (data) {
+ require(['WoltLabSuite/Core/Ui/Dialog'], (function (UiDialog) {
+ UiDialog.open(this, '<div class="htmlContent">' + data.returnValues.message + '</div>');
+ }).bind(this));
+ },
- // evaluate message
- this._handleResponse(data);
- },
-
- /**
- * Evaluates response data.
- *
- * @param object data
- */
- _handleResponse: function(data) { },
-
- /**
- * Handles errors during preview requests.
- *
- * The return values indicates if the default error overlay is shown.
- *
- * @param object data
- * @return boolean
- */
- _failure: function(data) {
- if (data === null || data.returnValues === undefined || data.returnValues.errorType === undefined) {
- return true;
+ /**
+ * @see WCF.Message.Preview._getParameters()
+ */
+ _getParameters: function (message) {
+ var $parameters = this._super(message);
+
+ for (var key in this._options) {
+ if (this._options.hasOwnProperty(key) && key !== 'messageFieldID' && key !== 'previewButtonID') {
+ $parameters[key] = this._options[key];
+ }
+ }
+
+ return $parameters;
+ },
+
+ _dialogSetup: function () {
+ return {
+ id: 'messagePreview',
+ options: {
+ title: WCF.Language.get('wcf.global.preview')
+ },
+ source: null
+ }
}
-
- // restore preview button
- this._previewButton.html(this._previewButtonLabel).enable();
-
- var $innerError = this._textarea.parent().children('small.innerError').empty();
- if (!$innerError.length) {
- $innerError = $('<small class="innerError" />').appendTo(this._textarea.parent());
+ });
+
+ /**
+ * Handles multilingualism for messages.
+ *
+ * @param integer languageID
+ * @param object availableLanguages
+ * @param boolean forceSelection
+ */
+ WCF.Message.Multilingualism = Class.extend({
+ /**
+ * list of available languages
+ * @var object
+ */
+ _availableLanguages: {},
+
+ /**
+ * language id
+ * @var integer
+ */
+ _languageID: 0,
+
+ /**
+ * language input element
+ * @var jQuery
+ */
+ _languageInput: null,
+
+ /**
+ * Initializes WCF.Message.Multilingualism
+ *
+ * @param integer languageID
+ * @param object availableLanguages
+ * @param boolean forceSelection
+ */
+ init: function (languageID, availableLanguages, forceSelection) {
+ this._availableLanguages = availableLanguages;
+ this._languageID = languageID || 0;
+
+ this._languageInput = $('#languageID');
+
+ // preselect current language id
+ this._updateLabel();
+
+ // register event listener
+ this._languageInput.find('.dropdownMenu > li').click($.proxy(this._click, this));
+
+ // add element to disable multilingualism
+ if (!forceSelection) {
+ var $dropdownMenu = this._languageInput.find('.dropdownMenu');
+ $('<li class="dropdownDivider" />').appendTo($dropdownMenu);
+ $('<li><span><span class="badge">' + this._availableLanguages[0] + '</span></span></li>').click($.proxy(this._disable, this)).appendTo($dropdownMenu);
+ }
+
+ // bind submit event
+ this._languageInput.parents('form').submit($.proxy(this._submit, this));
+ },
+
+ /**
+ * Handles language selections.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ this._languageID = $(event.currentTarget).data('languageID');
+ this._updateLabel();
+ },
+
+ /**
+ * Disables language selection.
+ */
+ _disable: function () {
+ this._languageID = 0;
+ this._updateLabel();
+ },
+
+ /**
+ * Updates selected language.
+ */
+ _updateLabel: function () {
+ this._languageInput.find('.dropdownToggle > span').text(this._availableLanguages[this._languageID]);
+ },
+
+ /**
+ * Sets language id upon submit.
+ */
+ _submit: function () {
+ this._languageInput.next('input[name=languageID]').prop('value', this._languageID);
+ }
+ });
+
+ /**
+ * Loads smiley categories upon user request.
+ */
+ WCF.Message.SmileyCategories = Class.extend({
+ /**
+ * list of already loaded category ids
+ * @var array<integer>
+ */
+ _cache: [],
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * wysiwyg editor selector
+ * @var string
+ */
+ _wysiwygSelector: '',
+
+ /**
+ * Initializes the smiley loader.
+ *
+ * @param string wysiwygSelector
+ */
+ init: function (wysiwygSelector) {
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+ this._wysiwygSelector = wysiwygSelector;
+
+ $('#smilies-' + this._wysiwygSelector).on('messagetabmenushow', $.proxy(this._click, this));
+ },
+
+ /**
+ * Handles tab menu clicks.
+ *
+ * @param {Event} event
+ * @param {Object} data
+ */
+ _click: function (event, data) {
+ event.preventDefault();
+
+ var $categoryID = parseInt(data.activeTab.tab.data('smileyCategoryID'));
+
+ // ignore global category, will always be pre-loaded
+ if (!$categoryID) {
+ return;
+ }
+
+ // smilies have already been loaded for this tab, ignore
+ if (data.activeTab.container.children('ul.smileyList').length) {
+ return;
+ }
+
+ // cache exists
+ if (this._cache[$categoryID] !== undefined) {
+ data.activeTab.container.html(this._cache[$categoryID]);
+ return;
+ }
+
+ // load content
+ this._proxy.setOption('data', {
+ actionName: 'getSmilies',
+ className: 'wcf\\data\\smiley\\category\\SmileyCategoryAction',
+ objectIDs: [$categoryID]
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ var $categoryID = parseInt(data.returnValues.smileyCategoryID);
+ this._cache[$categoryID] = data.returnValues.template;
+
+ $('#smilies-' + this._wysiwygSelector + '-' + $categoryID).html(data.returnValues.template);
}
-
- $innerError.html((data.returnValues.errorType === 'empty' ? WCF.Language.get('wcf.global.form.error.empty') : data.returnValues.errorMessage));
-
- return false;
- }
-});
-
-/**
- * Default implementation for message previews.
- *
- * @see WCF.Message.Preview
- */
-WCF.Message.DefaultPreview = WCF.Message.Preview.extend({
- _dialog: null,
- _options: {},
+ });
/**
- * @see WCF.Message.Preview.init()
+ * Handles smiley clicks.
+ *
+ * @param string wysiwygSelector
*/
- init: function(options) {
- if (arguments.length > 1 && typeof options === 'string') {
- throw new Error("Outdated API call, please update your implementation.");
- }
+ WCF.Message.Smilies = Class.extend({
+ /**
+ * wysiwyg editor id
+ * @var string
+ */
+ _editorId: '',
- this._options = $.extend({
- disallowedBBCodesPermission: 'user.message.disallowedBBCodes',
- messageFieldID: '',
- previewButtonID: '',
- messageObjectType: '',
- messageObjectID: 0
- }, options);
-
- if (!this._options.messageObjectType) {
- throw new Error("Field 'messageObjectType' cannot be empty.");
+ /**
+ * Initializes the smiley handler.
+ *
+ * @param {string} editorId
+ */
+ init: function (editorId) {
+ this._editorId = editorId;
+
+ $('.messageTabMenu[data-wysiwyg-container-id=' + this._editorId + ']').on('mousedown', '.jsSmiley', this._smileyClick.bind(this));
+ },
+
+ /**
+ * Handles tab smiley clicks.
+ *
+ * @param {Event} event
+ */
+ _smileyClick: function (event) {
+ event.preventDefault();
+
+ require(['EventHandler'], (function (EventHandler) {
+ EventHandler.fire('com.woltlab.wcf.redactor2', 'insertSmiley_' + this._editorId, {
+ img: event.currentTarget.children[0]
+ });
+ }).bind(this));
}
-
- this._super('wcf\\data\\bbcode\\MessagePreviewAction', this._options.messageFieldID, this._options.previewButtonID);
- },
-
- /**
- * @see WCF.Message.Preview._handleResponse()
- */
- _handleResponse: function(data) {
- require(['WoltLabSuite/Core/Ui/Dialog'], (function(UiDialog) {
- UiDialog.open(this, '<div class="htmlContent">' + data.returnValues.message + '</div>');
- }).bind(this));
- },
-
- /**
- * @see WCF.Message.Preview._getParameters()
- */
- _getParameters: function(message) {
- var $parameters = this._super(message);
-
- for (var key in this._options) {
- if (this._options.hasOwnProperty(key) && key !== 'messageFieldID' && key !== 'previewButtonID') {
- $parameters[key] = this._options[key];
+ });
+
+ /**
+ * Provides an inline message editor.
+ *
+ * @deprecated 3.0 - please use `WoltLabSuite/Core/Ui/Message/InlineEditor` instead
+ *
+ * @param integer containerID
+ */
+ WCF.Message.InlineEditor = Class.extend({
+ /**
+ * list of messages
+ * @var object
+ */
+ _container: {},
+
+ /**
+ * container id
+ * @var int
+ */
+ _containerID: 0,
+
+ /**
+ * list of dropdowns
+ * @var object
+ */
+ _dropdowns: {},
+
+ /**
+ * CSS selector for the message container
+ * @var string
+ */
+ _messageContainerSelector: '.jsMessage',
+
+ /**
+ * prefix of the message editor CSS id
+ * @var string
+ */
+ _messageEditorIDPrefix: 'messageEditor',
+
+ /**
+ * Initializes a new WCF.Message.InlineEditor object.
+ *
+ * @param integer containerID
+ * @param boolean supportExtendedForm
+ * @param WCF.Message.Quote.Manager quoteManager
+ */
+ init: function (containerID, supportExtendedForm, quoteManager) {
+ require(['WoltLabSuite/Core/Ui/Message/InlineEditor'], (function (UiMessageInlineEditor) {
+ new UiMessageInlineEditor({
+ className: this._getClassName(),
+ containerId: containerID,
+ editorPrefix: this._messageEditorIDPrefix,
+
+ messageSelector: this._messageContainerSelector,
+
+ callbackDropdownInit: this._callbackDropdownInit.bind(this)
+ });
+ }).bind(this));
+ },
+
+ /**
+ * Loads WYSIWYG editor for selected message.
+ *
+ * @param object event
+ * @param integer containerID
+ * @return boolean
+ */
+ _click: function (event, containerID) {
+ containerID = (event === null) ? ~~containerID : ~~elData(event.currentTarget, 'container-id');
+
+ require(['WoltLabSuite/Core/Ui/Message/InlineEditor'], (function (UiMessageInlineEditor) {
+ UiMessageInlineEditor.legacyEdit(containerID);
+ }).bind(this));
+
+ if (event) {
+ event.preventDefault();
}
- }
-
- return $parameters;
- },
-
- _dialogSetup: function() {
- return {
- id: 'messagePreview',
- options: {
- title: WCF.Language.get('wcf.global.preview')
- },
- source: null
- }
- }
-});
-
-/**
- * Handles multilingualism for messages.
- *
- * @param integer languageID
- * @param object availableLanguages
- * @param boolean forceSelection
- */
-WCF.Message.Multilingualism = Class.extend({
- /**
- * list of available languages
- * @var object
- */
- _availableLanguages: { },
-
- /**
- * language id
- * @var integer
- */
- _languageID: 0,
-
- /**
- * language input element
- * @var jQuery
- */
- _languageInput: null,
-
- /**
- * Initializes WCF.Message.Multilingualism
- *
- * @param integer languageID
- * @param object availableLanguages
- * @param boolean forceSelection
- */
- init: function(languageID, availableLanguages, forceSelection) {
- this._availableLanguages = availableLanguages;
- this._languageID = languageID || 0;
-
- this._languageInput = $('#languageID');
-
- // preselect current language id
- this._updateLabel();
-
- // register event listener
- this._languageInput.find('.dropdownMenu > li').click($.proxy(this._click, this));
-
- // add element to disable multilingualism
- if (!forceSelection) {
- var $dropdownMenu = this._languageInput.find('.dropdownMenu');
- $('<li class="dropdownDivider" />').appendTo($dropdownMenu);
- $('<li><span><span class="badge">' + this._availableLanguages[0] + '</span></span></li>').click($.proxy(this._disable, this)).appendTo($dropdownMenu);
- }
-
- // bind submit event
- this._languageInput.parents('form').submit($.proxy(this._submit, this));
- },
-
- /**
- * Handles language selections.
- *
- * @param object event
- */
- _click: function(event) {
- this._languageID = $(event.currentTarget).data('languageID');
- this._updateLabel();
- },
-
- /**
- * Disables language selection.
- */
- _disable: function() {
- this._languageID = 0;
- this._updateLabel();
- },
-
- /**
- * Updates selected language.
- */
- _updateLabel: function() {
- this._languageInput.find('.dropdownToggle > span').text(this._availableLanguages[this._languageID]);
- },
-
- /**
- * Sets language id upon submit.
- */
- _submit: function() {
- this._languageInput.next('input[name=languageID]').prop('value', this._languageID);
- }
-});
-
-/**
- * Loads smiley categories upon user request.
- */
-WCF.Message.SmileyCategories = Class.extend({
- /**
- * list of already loaded category ids
- * @var array<integer>
- */
- _cache: [ ],
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * wysiwyg editor selector
- * @var string
- */
- _wysiwygSelector: '',
-
- /**
- * Initializes the smiley loader.
- *
- * @param string wysiwygSelector
- */
- init: function(wysiwygSelector) {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
- this._wysiwygSelector = wysiwygSelector;
-
- $('#smilies-' + this._wysiwygSelector).on('messagetabmenushow', $.proxy(this._click, this));
- },
-
- /**
- * Handles tab menu clicks.
- *
- * @param {Event} event
- * @param {Object} data
- */
- _click: function(event, data) {
- event.preventDefault();
-
- var $categoryID = parseInt(data.activeTab.tab.data('smileyCategoryID'));
-
- // ignore global category, will always be pre-loaded
- if (!$categoryID) {
- return;
- }
-
- // smilies have already been loaded for this tab, ignore
- if (data.activeTab.container.children('ul.smileyList').length) {
- return;
- }
-
- // cache exists
- if (this._cache[$categoryID] !== undefined) {
- data.activeTab.container.html(this._cache[$categoryID]);
- return;
- }
-
- // load content
- this._proxy.setOption('data', {
- actionName: 'getSmilies',
- className: 'wcf\\data\\smiley\\category\\SmileyCategoryAction',
- objectIDs: [ $categoryID ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- var $categoryID = parseInt(data.returnValues.smileyCategoryID);
- this._cache[$categoryID] = data.returnValues.template;
-
- $('#smilies-' + this._wysiwygSelector + '-' + $categoryID).html(data.returnValues.template);
- }
-});
-
-/**
- * Handles smiley clicks.
- *
- * @param string wysiwygSelector
- */
-WCF.Message.Smilies = Class.extend({
- /**
- * wysiwyg editor id
- * @var string
- */
- _editorId: '',
-
- /**
- * Initializes the smiley handler.
- *
- * @param {string} editorId
- */
- init: function(editorId) {
- this._editorId = editorId;
-
- $('.messageTabMenu[data-wysiwyg-container-id=' + this._editorId + ']').on('mousedown', '.jsSmiley', this._smileyClick.bind(this));
- },
-
- /**
- * Handles tab smiley clicks.
- *
- * @param {Event} event
- */
- _smileyClick: function(event) {
- event.preventDefault();
-
- require(['EventHandler'], (function(EventHandler) {
- EventHandler.fire('com.woltlab.wcf.redactor2', 'insertSmiley_' + this._editorId, {
- img: event.currentTarget.children[0]
- });
- }).bind(this));
- }
-});
-
-/**
- * Provides an inline message editor.
- *
- * @deprecated 3.0 - please use `WoltLabSuite/Core/Ui/Message/InlineEditor` instead
- *
- * @param integer containerID
- */
-WCF.Message.InlineEditor = Class.extend({
- /**
- * list of messages
- * @var object
- */
- _container: { },
-
- /**
- * container id
- * @var int
- */
- _containerID: 0,
-
- /**
- * list of dropdowns
- * @var object
- */
- _dropdowns: { },
-
- /**
- * CSS selector for the message container
- * @var string
- */
- _messageContainerSelector: '.jsMessage',
-
- /**
- * prefix of the message editor CSS id
- * @var string
- */
- _messageEditorIDPrefix: 'messageEditor',
-
- /**
- * Initializes a new WCF.Message.InlineEditor object.
- *
- * @param integer containerID
- * @param boolean supportExtendedForm
- * @param WCF.Message.Quote.Manager quoteManager
- */
- init: function(containerID, supportExtendedForm, quoteManager) {
- require(['WoltLabSuite/Core/Ui/Message/InlineEditor'], (function(UiMessageInlineEditor) {
- new UiMessageInlineEditor({
- className: this._getClassName(),
- containerId: containerID,
- editorPrefix: this._messageEditorIDPrefix,
-
- messageSelector: this._messageContainerSelector,
-
- callbackDropdownInit: this._callbackDropdownInit.bind(this)
- });
- }).bind(this));
- },
-
- /**
- * Loads WYSIWYG editor for selected message.
- *
- * @param object event
- * @param integer containerID
- * @return boolean
- */
- _click: function(event, containerID) {
- containerID = (event === null) ? ~~containerID : ~~elData(event.currentTarget, 'container-id');
-
- require(['WoltLabSuite/Core/Ui/Message/InlineEditor'], (function(UiMessageInlineEditor) {
- UiMessageInlineEditor.legacyEdit(containerID);
- }).bind(this));
-
- if (event) {
- event.preventDefault();
- }
- },
-
- /**
- * Initializes the inline edit dropdown menu.
- *
- * @param integer containerID
- * @param jQuery dropdownMenu
- */
- _initDropdownMenu: function(containerID, dropdownMenu) { },
-
- _callbackDropdownInit: function(element, dropdownMenu) {
- this._initDropdownMenu($(element).wcfIdentify(), $(dropdownMenu));
-
- return null;
- },
-
- /**
- * Returns message action class name.
- *
- * @return string
- */
- _getClassName: function() {
- return '';
- }
-});
-
-/**
- * Handles submit buttons for forms with an embedded WYSIWYG editor.
- */
-WCF.Message.Submit = {
- /**
- * list of registered buttons
- * @var object
- */
- _buttons: { },
-
- /**
- * Registers submit button for specified wysiwyg container id.
- *
- * @param string wysiwygContainerID
- * @param string selector
- */
- registerButton: function(wysiwygContainerID, selector) {
- if (!WCF.Browser.isChrome()) {
- return;
- }
-
- this._buttons[wysiwygContainerID] = $(selector);
- },
-
- /**
- * Triggers 'click' event for registered buttons.
- */
- execute: function(wysiwygContainerID) {
- if (!this._buttons[wysiwygContainerID]) {
- return;
- }
-
- this._buttons[wysiwygContainerID].trigger('click');
- }
-};
+ },
+
+ /**
+ * Initializes the inline edit dropdown menu.
+ *
+ * @param integer containerID
+ * @param jQuery dropdownMenu
+ */
+ _initDropdownMenu: function (containerID, dropdownMenu) {
+ },
+
+ _callbackDropdownInit: function (element, dropdownMenu) {
+ this._initDropdownMenu($(element).wcfIdentify(), $(dropdownMenu));
+
+ return null;
+ },
+
+ /**
+ * Returns message action class name.
+ *
+ * @return string
+ */
+ _getClassName: function () {
+ return '';
+ }
+ });
+
+ /**
+ * Handles submit buttons for forms with an embedded WYSIWYG editor.
+ */
+ WCF.Message.Submit = {
+ /**
+ * list of registered buttons
+ * @var object
+ */
+ _buttons: {},
+
+ /**
+ * Registers submit button for specified wysiwyg container id.
+ *
+ * @param string wysiwygContainerID
+ * @param string selector
+ */
+ registerButton: function (wysiwygContainerID, selector) {
+ if (!WCF.Browser.isChrome()) {
+ return;
+ }
+
+ this._buttons[wysiwygContainerID] = $(selector);
+ },
+
+ /**
+ * Triggers 'click' event for registered buttons.
+ */
+ execute: function (wysiwygContainerID) {
+ if (!this._buttons[wysiwygContainerID]) {
+ return;
+ }
+
+ this._buttons[wysiwygContainerID].trigger('click');
+ }
+ };
+}
+else {
+ WCF.Message.Preview = Class.extend({
+ _className: "",
+ _messageFieldID: "",
+ _messageField: {},
+ _proxy: {},
+ _previewButton: {},
+ _previewButtonLabel: "",
+ init: function() {},
+ _click: function() {},
+ _getParameters: function() {},
+ _getMessage: function() {},
+ _success: function() {},
+ _handleResponse: function() {},
+ _failure: function() {}
+ });
+
+ WCF.Message.DefaultPreview = WCF.Message.Preview.extend({
+ _dialog: {},
+ _options: {},
+ init: function() {},
+ _handleResponse: function() {},
+ _getParameters: function() {},
+ _dialogSetup: function() {},
+ _className: "",
+ _messageFieldID: "",
+ _messageField: {},
+ _proxy: {},
+ _previewButton: {},
+ _previewButtonLabel: "",
+ _click: function() {},
+ _getMessage: function() {},
+ _success: function() {},
+ _failure: function() {}
+ });
+
+ WCF.Message.Multilingualism = Class.extend({
+ _availableLanguages: {},
+ _languageID: 0,
+ _languageInput: {},
+ init: function() {},
+ _click: function() {},
+ _disable: function() {},
+ _updateLabel: function() {},
+ _submit: function() {}
+ });
+
+ WCF.Message.SmileyCategories = Class.extend({
+ _cache: {},
+ _proxy: {},
+ _wysiwygSelector: "",
+ init: function() {},
+ _click: function() {},
+ _success: function() {}
+ });
+
+ WCF.Message.Smilies = Class.extend({
+ _editorId: "",
+ init: function() {},
+ _smileyClick: function() {}
+ });
+
+ WCF.Message.InlineEditor = Class.extend({
+ _container: {},
+ _containerID: 0,
+ _dropdowns: {},
+ _messageContainerSelector: "",
+ _messageEditorIDPrefix: "",
+ init: function() {},
+ _click: function() {},
+ _initDropdownMenu: function() {},
+ _callbackDropdownInit: function() {},
+ _getClassName: function() {}
+ });
+
+ WCF.Message.Submit = {
+ _buttons: {},
+ registerButton: function() {},
+ execute: function() {}
+ };
+}
/**
* Namespace for message quotes.
*/
WCF.Message.Quote = { };
-/**
- * Handles message quotes.
- */
-WCF.Message.Quote.Handler = Class.extend({
- /**
- * active container id
- * @var string
- */
- _activeContainerID: '',
-
- /**
- * action class name
- * @var string
- */
- _className: '',
-
- /**
- * list of message containers
- * @var object
- */
- _containers: { },
-
- /**
- * container selector
- * @var string
- */
- _containerSelector: '',
-
- /**
- * 'copy quote' overlay
- * @var jQuery
- */
- _copyQuote: null,
-
- /**
- * marked message
- * @var string
- */
- _message: '',
-
- /**
- * message body selector
- * @var string
- */
- _messageBodySelector: '',
-
- /**
- * object id
- * @var {int}
- */
- _objectID: 0,
-
- /**
- * object type name
- * @var string
- */
- _objectType: '',
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * quote manager
- * @var WCF.Message.Quote.Manager
- */
- _quoteManager: null,
-
- /**
- * Initializes the quote handler for given object type.
- *
- * @param {WCF.Message.Quote.Manager} quoteManager
- * @param {string} className
- * @param {string} objectType
- * @param {string} containerSelector
- * @param {string} messageBodySelector
- * @param {string} messageContentSelector
- * @param {boolean} supportDirectInsert
- */
- init: function(quoteManager, className, objectType, containerSelector, messageBodySelector, messageContentSelector, supportDirectInsert) {
- this._className = className;
- if (this._className === '') {
- console.debug("[WCF.Message.QuoteManager] Empty class name given, aborting.");
- return;
- }
-
- this._objectType = objectType;
- if (this._objectType === '') {
- console.debug("[WCF.Message.QuoteManager] Empty object type name given, aborting.");
- return;
- }
-
- this._containerSelector = containerSelector;
- this._message = '';
- this._messageBodySelector = messageBodySelector;
- this._objectID = 0;
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- this._initContainers();
-
- supportDirectInsert = (supportDirectInsert && quoteManager.supportPaste());
- this._initCopyQuote(supportDirectInsert);
-
- $(document).mouseup($.proxy(this._mouseUp, this));
-
- // register with quote manager
- this._quoteManager = quoteManager;
- this._quoteManager.register(this._objectType, this);
-
- // register with DOMNodeInsertedHandler
- WCF.DOMNodeInsertedHandler.addCallback('WCF.Message.Quote.Handler' + objectType.hashCode(), $.proxy(this._initContainers, this));
- },
-
- /**
- * Initializes message containers.
- */
- _initContainers: function() {
- var self = this;
- $(this._containerSelector).each(function(index, container) {
- var $container = $(container);
- var $containerID = $container.wcfIdentify();
-
- if (!self._containers[$containerID]) {
- self._containers[$containerID] = $container;
- if ($container.hasClass('jsInvalidQuoteTarget')) {
- return true;
- }
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Handles message quotes.
+ */
+ WCF.Message.Quote.Handler = Class.extend({
+ /**
+ * active container id
+ * @var string
+ */
+ _activeContainerID: '',
+
+ /**
+ * action class name
+ * @var string
+ */
+ _className: '',
+
+ /**
+ * list of message containers
+ * @var object
+ */
+ _containers: {},
+
+ /**
+ * container selector
+ * @var string
+ */
+ _containerSelector: '',
+
+ /**
+ * 'copy quote' overlay
+ * @var jQuery
+ */
+ _copyQuote: null,
+
+ /**
+ * marked message
+ * @var string
+ */
+ _message: '',
+
+ /**
+ * message body selector
+ * @var string
+ */
+ _messageBodySelector: '',
+
+ /**
+ * object id
+ * @var {int}
+ */
+ _objectID: 0,
+
+ /**
+ * object type name
+ * @var string
+ */
+ _objectType: '',
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * quote manager
+ * @var WCF.Message.Quote.Manager
+ */
+ _quoteManager: null,
+
+ /**
+ * Initializes the quote handler for given object type.
+ *
+ * @param {WCF.Message.Quote.Manager} quoteManager
+ * @param {string} className
+ * @param {string} objectType
+ * @param {string} containerSelector
+ * @param {string} messageBodySelector
+ * @param {string} messageContentSelector
+ * @param {boolean} supportDirectInsert
+ */
+ init: function (quoteManager, className, objectType, containerSelector, messageBodySelector, messageContentSelector, supportDirectInsert) {
+ this._className = className;
+ if (this._className === '') {
+ console.debug("[WCF.Message.QuoteManager] Empty class name given, aborting.");
+ return;
+ }
+
+ this._objectType = objectType;
+ if (this._objectType === '') {
+ console.debug("[WCF.Message.QuoteManager] Empty object type name given, aborting.");
+ return;
+ }
+
+ this._containerSelector = containerSelector;
+ this._message = '';
+ this._messageBodySelector = messageBodySelector;
+ this._objectID = 0;
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ this._initContainers();
+
+ supportDirectInsert = (supportDirectInsert && quoteManager.supportPaste());
+ this._initCopyQuote(supportDirectInsert);
+
+ $(document).mouseup($.proxy(this._mouseUp, this));
+
+ // register with quote manager
+ this._quoteManager = quoteManager;
+ this._quoteManager.register(this._objectType, this);
+
+ // register with DOMNodeInsertedHandler
+ WCF.DOMNodeInsertedHandler.addCallback('WCF.Message.Quote.Handler' + objectType.hashCode(), $.proxy(this._initContainers, this));
+ },
+
+ /**
+ * Initializes message containers.
+ */
+ _initContainers: function () {
+ var self = this;
+ $(this._containerSelector).each(function (index, container) {
+ var $container = $(container);
+ var $containerID = $container.wcfIdentify();
- if (self._messageBodySelector) {
- $container.data('body', $container.find(self._messageBodySelector).data('containerID', $containerID));
+ if (!self._containers[$containerID]) {
+ self._containers[$containerID] = $container;
+ if ($container.hasClass('jsInvalidQuoteTarget')) {
+ return true;
+ }
+
+ if (self._messageBodySelector) {
+ $container.data('body', $container.find(self._messageBodySelector).data('containerID', $containerID));
+ }
+
+ $container.mousedown($.proxy(self._mouseDown, self));
+
+ // bind event to quote whole message
+ self._containers[$containerID].find('.jsQuoteMessage').click($.proxy(self._saveFullQuote, self));
}
+ });
+ },
+
+ /**
+ * Handles mouse down event.
+ *
+ * @param {Event} event
+ */
+ _mouseDown: function (event) {
+ // hide copy quote
+ this._copyQuote.removeClass('active');
+
+ this._activeContainerID = (event.currentTarget.classList.contains('jsInvalidQuoteTarget')) ? '' : event.currentTarget.id;
+ },
+
+ /**
+ * Returns the text of a node and its children.
+ *
+ * @param {Node} node
+ * @return {string}
+ */
+ _getNodeText: function (node) {
+ // work-around for IE, see http://stackoverflow.com/a/5983176
+ var $nodeFilter = function (node) {
+ switch (node.tagName) {
+ case 'BLOCKQUOTE':
+ case 'IMG':
+ case 'SCRIPT':
+ return NodeFilter.FILTER_REJECT;
+
+ default:
+ return NodeFilter.FILTER_ACCEPT;
+ }
+ };
+ $nodeFilter.acceptNode = $nodeFilter;
+
+ var $walker = document.createTreeWalker(
+ node,
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
+ $nodeFilter,
+ true
+ );
+
+ var $text = '', ignoreLinks = [], value;
+ while ($walker.nextNode()) {
+ var $node = $walker.currentNode;
- $container.mousedown($.proxy(self._mouseDown, self));
-
- // bind event to quote whole message
- self._containers[$containerID].find('.jsQuoteMessage').click($.proxy(self._saveFullQuote, self));
- }
- });
- },
-
- /**
- * Handles mouse down event.
- *
- * @param {Event} event
- */
- _mouseDown: function(event) {
- // hide copy quote
- this._copyQuote.removeClass('active');
-
- this._activeContainerID = (event.currentTarget.classList.contains('jsInvalidQuoteTarget')) ? '' : event.currentTarget.id;
- },
-
- /**
- * Returns the text of a node and its children.
- *
- * @param {Node} node
- * @return {string}
- */
- _getNodeText: function(node) {
- // work-around for IE, see http://stackoverflow.com/a/5983176
- var $nodeFilter = function(node) {
- switch (node.tagName) {
- case 'BLOCKQUOTE':
- case 'IMG':
- case 'SCRIPT':
- return NodeFilter.FILTER_REJECT;
- break;
-
- default:
- return NodeFilter.FILTER_ACCEPT;
- break;
- }
- };
- $nodeFilter.acceptNode = $nodeFilter;
-
- var $walker = document.createTreeWalker(
- node,
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
- $nodeFilter,
- true
- );
-
- var $text = '', ignoreLinks = [], value;
- while ($walker.nextNode()) {
- var $node = $walker.currentNode;
-
- if ($node.nodeType === Node.ELEMENT_NODE) {
- switch ($node.tagName) {
- case 'A':
- // \u2026 === …
- value = $node.textContent;
- if (value.indexOf('\u2026') > 0) {
- var tmp = value.split(/\u2026/);
- if (tmp.length === 2) {
- var href = $node.href;
- if (href.indexOf(tmp[0]) === 0 && href.substr(tmp[1].length * -1) === tmp[1]) {
- // truncated url, use original href to preserve link
- $text += href;
- ignoreLinks.push($node);
+ if ($node.nodeType === Node.ELEMENT_NODE) {
+ switch ($node.tagName) {
+ case 'A':
+ // \u2026 === …
+ value = $node.textContent;
+ if (value.indexOf('\u2026') > 0) {
+ var tmp = value.split(/\u2026/);
+ if (tmp.length === 2) {
+ var href = $node.href;
+ if (href.indexOf(tmp[0]) === 0 && href.substr(tmp[1].length * -1) === tmp[1]) {
+ // truncated url, use original href to preserve link
+ $text += href;
+ ignoreLinks.push($node);
+ }
}
}
- }
- break;
+ break;
- case 'BR':
- case 'LI':
- case 'UL':
- $text += "\n";
- break;
-
- case 'TD':
- if (!$.browser.msie) {
+ case 'BR':
+ case 'LI':
+ case 'UL':
$text += "\n";
- }
- break;
-
- case 'P':
- $text += "\n\n";
- break;
+ break;
+
+ case 'TD':
+ if (!$.browser.msie) {
+ $text += "\n";
+ }
+ break;
+
+ case 'P':
+ $text += "\n\n";
+ break;
+ }
}
- }
- else {
- if ($node.parentNode.nodeName === 'A' && ignoreLinks.indexOf($node.parentNode) !== -1) {
- // ignore text content of links that have already been captured
- continue;
+ else {
+ if ($node.parentNode.nodeName === 'A' && ignoreLinks.indexOf($node.parentNode) !== -1) {
+ // ignore text content of links that have already been captured
+ continue;
+ }
+
+ $text += $node.nodeValue.replace(/\n/g, '');
}
- $text += $node.nodeValue.replace(/\n/g, '');
}
- }
-
- return $text;
- },
-
- /**
- * Handles the mouse up event.
- */
- _mouseUp: function() {
- // ignore event
- if (this._activeContainerID === '') {
- this._copyQuote.removeClass('active');
- return;
- }
-
- var selection = window.getSelection();
- if (selection.rangeCount !== 1 || selection.isCollapsed) {
- this._copyQuote.removeClass('active');
- return;
- }
-
- var $container = this._containers[this._activeContainerID];
- var $objectID = $container.data('objectID');
- $container = $container.data('body') || $container;
-
- var anchorNode = selection.anchorNode;
- while (anchorNode) {
- if (anchorNode === $container[0]) {
- break;
+ return $text;
+ },
+
+ /**
+ * Handles the mouse up event.
+ */
+ _mouseUp: function () {
+ // ignore event
+ if (this._activeContainerID === '') {
+ this._copyQuote.removeClass('active');
+ return;
}
- anchorNode = anchorNode.parentNode;
- }
-
- // selection spans unrelated nodes
- if (anchorNode !== $container[0]) {
- this._copyQuote.removeClass('active');
- return;
- }
-
- var $selection = this._getSelectedText();
- var $text = $.trim($selection);
- if ($text == '') {
- this._copyQuote.removeClass('active');
+ var selection = window.getSelection();
+ if (selection.rangeCount !== 1 || selection.isCollapsed) {
+ this._copyQuote.removeClass('active');
+ return;
+ }
- return;
- }
-
- // check if mousedown/mouseup took place inside a blockquote
- var range = selection.getRangeAt(0);
- var startContainer = (range.startContainer.nodeType === Node.TEXT_NODE) ? range.startContainer.parentNode : range.startContainer;
- var endContainer = (range.endContainer.nodeType === Node.TEXT_NODE) ? range.endContainer.parentNode : range.endContainer;
- if (startContainer.closest('blockquote') || endContainer.closest('blockquote')) {
- this._copyQuote.removeClass('active');
+ var $container = this._containers[this._activeContainerID];
+ var $objectID = $container.data('objectID');
+ $container = $container.data('body') || $container;
- return;
- }
-
- // compare selection with message text of given container
- var $messageText = this._getNodeText($container[0]);
-
- // selected text is not part of $messageText or contains text from unrelated nodes
- if (this._normalize($messageText).indexOf(this._normalize($text)) === -1) {
- return;
- }
- this._copyQuote.addClass('active');
-
- var $coordinates = this._getBoundingRectangle($container, window.getSelection());
- var $dimensions = this._copyQuote.getDimensions('outer');
- var $left = ($coordinates.right - $coordinates.left) / 2 - ($dimensions.width / 2) + $coordinates.left;
-
- this._copyQuote.css({
- top: $coordinates.top - $dimensions.height - 7 + 'px',
- left: $left + 'px'
- });
- this._copyQuote.removeClass('active');
-
- // reset containerID
- this._activeContainerID = '';
-
- // show element after a delay, to prevent display if text was unmarked again (clicking into marked text)
- var self = this;
- window.setTimeout(function() {
- var $text = $.trim(self._getSelectedText());
- if ($text != '') {
- self._copyQuote.addClass('active');
- self._message = $text;
- self._objectID = $objectID;
+ var anchorNode = selection.anchorNode;
+ while (anchorNode) {
+ if (anchorNode === $container[0]) {
+ break;
+ }
+
+ anchorNode = anchorNode.parentNode;
}
- }, 10);
- },
-
- /**
- * Normalizes a text for comparison.
- *
- * @param {string} text
- * @return {string}
- */
- _normalize: function(text) {
- return text.replace(/\r?\n|\r/g, "\n").replace(/\s/g, ' ').replace(/\s{2,}/g, ' ');
- },
-
- /**
- * Returns the offsets of the selection's bounding rectangle.
- *
- * @return {Object}
- */
- _getBoundingRectangle: function(container, selection) {
- var $coordinates = null;
-
- if (selection.rangeCount > 0) {
- // the coordinates returned by getBoundingClientRect() are relative to the viewport, not the document!
- var $rect = selection.getRangeAt(0).getBoundingClientRect();
- $coordinates = {
- left: $rect.left,
- right: $rect.right,
- top: $rect.top + $(document).scrollTop()
- };
- }
-
- return $coordinates;
- },
-
- /**
- * Initializes the 'copy quote' element.
- *
- * @param {boolean} supportDirectInsert
- */
- _initCopyQuote: function(supportDirectInsert) {
- this._copyQuote = $('#quoteManagerCopy');
- if (!this._copyQuote.length) {
- this._copyQuote = $('<div id="quoteManagerCopy" class="balloonTooltip interactive"><span class="jsQuoteManagerStore">' + WCF.Language.get('wcf.message.quote.quoteSelected') + '</span></div>').appendTo(document.body);
- var $storeQuote = this._copyQuote.children('span.jsQuoteManagerStore').click($.proxy(this._saveQuote, this));
- if (supportDirectInsert) {
- $('<span class="jsQuoteManagerQuoteAndInsert">' + WCF.Language.get('wcf.message.quote.quoteAndReply') + '</span>').click($.proxy(this._saveAndInsertQuote, this)).insertAfter($storeQuote);
- }
- }
- },
-
- /**
- * Returns the text selection.
- *
- * @return string
- */
- _getSelectedText: function() {
- var $selection = window.getSelection();
- if ($selection.rangeCount) {
- return this._getNodeText($selection.getRangeAt(0).cloneContents());
- }
-
- return '';
- },
-
- /**
- * Saves a full quote.
- *
- * @param {Event} event
- */
- _saveFullQuote: function(event) {
- event.preventDefault();
-
- var $listItem = $(event.currentTarget);
-
- this._proxy.setOption('data', {
- actionName: 'saveFullQuote',
- className: this._className,
- interfaceName: 'wcf\\data\\IMessageQuoteAction',
- objectIDs: [ $listItem.data('objectID') ]
- });
- this._proxy.sendRequest();
-
- // mark element as quoted
- if ($listItem.data('isQuoted')) {
- $listItem.data('isQuoted', false).children('a').removeClass('active');
- }
- else {
- $listItem.data('isQuoted', true).children('a').addClass('active');
- }
-
- // close navigation on mobile
- var $navigationList = $listItem.parents('.buttonGroupNavigation');
- if ($navigationList.hasClass('jsMobileButtonGroupNavigation')) {
- $navigationList.children('.dropdownLabel').trigger('click');
- }
- },
-
- /**
- * Saves a quote.
- *
- * @param {boolean} renderQuote
- */
- _saveQuote: function(renderQuote) {
- this._proxy.setOption('data', {
- actionName: 'saveQuote',
- className: this._className,
- interfaceName: 'wcf\\data\\IMessageQuoteAction',
- objectIDs: [ this._objectID ],
- parameters: {
- message: this._message,
- renderQuote: (renderQuote === true)
+ // selection spans unrelated nodes
+ if (anchorNode !== $container[0]) {
+ this._copyQuote.removeClass('active');
+ return;
}
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Saves a quote and directly inserts it.
- */
- _saveAndInsertQuote: function() {
- this._saveQuote(true);
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param {Object} data
- */
- _success: function(data) {
- if (data.returnValues.count !== undefined) {
- if (data.returnValues.fullQuoteMessageIDs !== undefined) {
- data.returnValues.fullQuoteObjectIDs = data.returnValues.fullQuoteMessageIDs;
+
+ var $selection = this._getSelectedText();
+ var $text = $.trim($selection);
+ if ($text == '') {
+ this._copyQuote.removeClass('active');
+
+ return;
}
- var $fullQuoteObjectIDs = (data.returnValues.fullQuoteObjectIDs !== undefined) ? data.returnValues.fullQuoteObjectIDs : { };
- this._quoteManager.updateCount(data.returnValues.count, $fullQuoteObjectIDs);
- }
-
- switch (data.actionName) {
- case 'saveQuote':
- case 'saveFullQuote':
- if (data.returnValues.renderedQuote) {
- WCF.System.Event.fireEvent('com.woltlab.wcf.message.quote', 'insert', {
- forceInsert: (data.actionName === 'saveQuote'),
- quote: data.returnValues.renderedQuote
- });
- }
- break;
- }
- },
-
- /**
- * Updates the full quote data for all matching objects.
- *
- * @param array<integer> $objectIDs
- */
- updateFullQuoteObjectIDs: function(objectIDs) {
- for (var $containerID in this._containers) {
- this._containers[$containerID].find('.jsQuoteMessage').each(function(index, button) {
- // reset all markings
- var $button = $(button).data('isQuoted', 0);
- $button.children('a').removeClass('active');
+ // check if mousedown/mouseup took place inside a blockquote
+ var range = selection.getRangeAt(0);
+ var startContainer = (range.startContainer.nodeType === Node.TEXT_NODE) ? range.startContainer.parentNode : range.startContainer;
+ var endContainer = (range.endContainer.nodeType === Node.TEXT_NODE) ? range.endContainer.parentNode : range.endContainer;
+ if (startContainer.closest('blockquote') || endContainer.closest('blockquote')) {
+ this._copyQuote.removeClass('active');
- // mark as active
- if (WCF.inArray($button.data('objectID'), objectIDs)) {
- $button.data('isQuoted', 1).children('a').addClass('active');
- }
+ return;
+ }
+
+ // compare selection with message text of given container
+ var $messageText = this._getNodeText($container[0]);
+
+ // selected text is not part of $messageText or contains text from unrelated nodes
+ if (this._normalize($messageText).indexOf(this._normalize($text)) === -1) {
+ return;
+ }
+ this._copyQuote.addClass('active');
+
+ var $coordinates = this._getBoundingRectangle($container, window.getSelection());
+ var $dimensions = this._copyQuote.getDimensions('outer');
+ var $left = ($coordinates.right - $coordinates.left) / 2 - ($dimensions.width / 2) + $coordinates.left;
+
+ this._copyQuote.css({
+ top: $coordinates.top - $dimensions.height - 7 + 'px',
+ left: $left + 'px'
});
- }
- }
-});
-
-/**
- * Manages stored quotes.
- *
- * @param integer count
- */
-WCF.Message.Quote.Manager = Class.extend({
- /**
- * list of form buttons
- * @var {Object}
- */
- _buttons: {},
-
- /**
- * number of stored quotes
- * @var {int}
- */
- _count: 0,
-
- /**
- * dialog overlay
- * @var {jQuery}
- */
- _dialog: null,
-
- /**
- * editor element id
- * @var {string}
- */
- _editorId: '',
-
- /**
- * alternative editor element id
- * @var {string}
- */
- _editorIdAlternative: '',
-
- /**
- * form element
- * @var {jQuery}
- */
- _form: null,
-
- /**
- * list of quote handlers
- * @var {Object}
- */
- _handlers: {},
-
- /**
- * true, if an up-to-date template exists
- * @var {boolean}
- */
- _hasTemplate: false,
-
- /**
- * true, if related quotes should be inserted
- * @var {boolean}
- */
- _insertQuotes: true,
-
- /**
- * action proxy
- * @var {WCF.Action.Proxy}
- */
- _proxy: null,
-
- /**
- * list of quotes to remove upon submit
- * @var {Array}
- */
- _removeOnSubmit: [ ],
-
- /**
- * allow pasting
- * @var {boolean}
- */
- _supportPaste: false,
-
- /**
- * Initializes the quote manager.
- *
- * @param {int} count
- * @param {string} elementID
- * @param {boolean} supportPaste
- * @param {Array} removeOnSubmit
- */
- init: function(count, elementID, supportPaste, removeOnSubmit) {
- this._buttons = {
- insert: null,
- remove: null
- };
- this._count = parseInt(count) || 0;
- this._dialog = null;
- this._editorId = '';
- this._editorIdAlternative = '';
- this._form = null;
- this._handlers = { };
- this._hasTemplate = false;
- this._insertQuotes = true;
- this._removeOnSubmit = [];
- this._supportPaste = false;
-
- if (elementID) {
- var element = $('#' + elementID);
- if (element.length) {
- this._editorId = elementID;
- this._supportPaste = true;
-
- // get surrounding form-tag
- this._form = element.parents('form:eq(0)');
- if (this._form.length) {
- this._form.submit(this._submit.bind(this));
- this._removeOnSubmit = removeOnSubmit || [];
+ this._copyQuote.removeClass('active');
+
+ // reset containerID
+ this._activeContainerID = '';
+
+ // show element after a delay, to prevent display if text was unmarked again (clicking into marked text)
+ var self = this;
+ window.setTimeout(function () {
+ var $text = $.trim(self._getSelectedText());
+ if ($text != '') {
+ self._copyQuote.addClass('active');
+ self._message = $text;
+ self._objectID = $objectID;
}
- else {
- this._form = null;
-
- // allow override
- this._supportPaste = (supportPaste === true);
+ }, 10);
+ },
+
+ /**
+ * Normalizes a text for comparison.
+ *
+ * @param {string} text
+ * @return {string}
+ */
+ _normalize: function (text) {
+ return text.replace(/\r?\n|\r/g, "\n").replace(/\s/g, ' ').replace(/\s{2,}/g, ' ');
+ },
+
+ /**
+ * Returns the offsets of the selection's bounding rectangle.
+ *
+ * @return {Object}
+ */
+ _getBoundingRectangle: function (container, selection) {
+ var $coordinates = null;
+
+ if (selection.rangeCount > 0) {
+ // the coordinates returned by getBoundingClientRect() are relative to the viewport, not the document!
+ var $rect = selection.getRangeAt(0).getBoundingClientRect();
+
+ $coordinates = {
+ left: $rect.left,
+ right: $rect.right,
+ top: $rect.top + $(document).scrollTop()
+ };
+ }
+
+ return $coordinates;
+ },
+
+ /**
+ * Initializes the 'copy quote' element.
+ *
+ * @param {boolean} supportDirectInsert
+ */
+ _initCopyQuote: function (supportDirectInsert) {
+ this._copyQuote = $('#quoteManagerCopy');
+ if (!this._copyQuote.length) {
+ this._copyQuote = $('<div id="quoteManagerCopy" class="balloonTooltip interactive"><span class="jsQuoteManagerStore">' + WCF.Language.get('wcf.message.quote.quoteSelected') + '</span></div>').appendTo(document.body);
+ var $storeQuote = this._copyQuote.children('span.jsQuoteManagerStore').click($.proxy(this._saveQuote, this));
+ if (supportDirectInsert) {
+ $('<span class="jsQuoteManagerQuoteAndInsert">' + WCF.Language.get('wcf.message.quote.quoteAndReply') + '</span>').click($.proxy(this._saveAndInsertQuote, this)).insertAfter($storeQuote);
}
}
- }
-
- this._proxy = new WCF.Action.Proxy({
- showLoadingOverlay: false,
- success: $.proxy(this._success, this),
- url: 'index.php?message-quote/&t=' + SECURITY_TOKEN
- });
-
- this._toggleShowQuotes();
-
- WCF.System.Event.addListener('com.woltlab.wcf.quote', 'reload', this.countQuotes.bind(this));
-
- // event forwarding
- WCF.System.Event.addListener('com.woltlab.wcf.message.quote', 'insert', (function(data) {
- //noinspection JSUnresolvedVariable
- WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertQuote_' + (this._editorIdAlternative ? this._editorIdAlternative : this._editorId), {
- author: data.quote.username,
- content: data.quote.text,
- isText: !data.quote.isFullQuote,
- link: data.quote.link
- });
- }).bind(this));
- },
-
- /**
- * Sets an alternative editor element id on runtime.
- *
- * @param {(string|jQuery)} elementId element id or jQuery element
- */
- setAlternativeEditor: function(elementId) {
- if (typeof elementId === 'object') elementId = elementId[0].id;
- this._editorIdAlternative = elementId;
- },
-
- /**
- * Clears alternative editor element id.
- */
- clearAlternativeEditor: function() {
- this._editorIdAlternative = '';
- },
-
- /**
- * Registers a quote handler.
- *
- * @param {string} objectType
- * @param {WCF.Message.Quote.Handler} handler
- */
- register: function(objectType, handler) {
- this._handlers[objectType] = handler;
- },
-
- /**
- * Updates number of stored quotes.
- *
- * @param {int} count
- * @param {Object} fullQuoteObjectIDs
- */
- updateCount: function(count, fullQuoteObjectIDs) {
- this._count = parseInt(count) || 0;
-
- this._toggleShowQuotes();
-
- // update full quote ids of handlers
- for (var $objectType in this._handlers) {
- if (this._handlers.hasOwnProperty($objectType)) {
- var $objectIDs = fullQuoteObjectIDs[$objectType] || [];
- this._handlers[$objectType].updateFullQuoteObjectIDs($objectIDs);
+ },
+
+ /**
+ * Returns the text selection.
+ *
+ * @return string
+ */
+ _getSelectedText: function () {
+ var $selection = window.getSelection();
+ if ($selection.rangeCount) {
+ return this._getNodeText($selection.getRangeAt(0).cloneContents());
+ }
+
+ return '';
+ },
+
+ /**
+ * Saves a full quote.
+ *
+ * @param {Event} event
+ */
+ _saveFullQuote: function (event) {
+ event.preventDefault();
+
+ var $listItem = $(event.currentTarget);
+
+ this._proxy.setOption('data', {
+ actionName: 'saveFullQuote',
+ className: this._className,
+ interfaceName: 'wcf\\data\\IMessageQuoteAction',
+ objectIDs: [$listItem.data('objectID')]
+ });
+ this._proxy.sendRequest();
+
+ // mark element as quoted
+ if ($listItem.data('isQuoted')) {
+ $listItem.data('isQuoted', false).children('a').removeClass('active');
+ }
+ else {
+ $listItem.data('isQuoted', true).children('a').addClass('active');
}
- }
- },
-
- /**
- * Inserts all associated quotes upon first time using quick reply.
- *
- * @param {string} className
- * @param {int} parentObjectID
- * @param {Object} callback
- */
- insertQuotes: function(className, parentObjectID, callback) {
- if (!this._insertQuotes) {
- this._insertQuotes = true;
- return;
- }
-
- new WCF.Action.Proxy({
- autoSend: true,
- data: {
- actionName: 'getRenderedQuotes',
- className: className,
+ // close navigation on mobile
+ var $navigationList = $listItem.parents('.buttonGroupNavigation');
+ if ($navigationList.hasClass('jsMobileButtonGroupNavigation')) {
+ $navigationList.children('.dropdownLabel').trigger('click');
+ }
+ },
+
+ /**
+ * Saves a quote.
+ *
+ * @param {boolean} renderQuote
+ */
+ _saveQuote: function (renderQuote) {
+ this._proxy.setOption('data', {
+ actionName: 'saveQuote',
+ className: this._className,
interfaceName: 'wcf\\data\\IMessageQuoteAction',
+ objectIDs: [this._objectID],
parameters: {
- parentObjectID: parentObjectID
+ message: this._message,
+ renderQuote: (renderQuote === true)
}
- },
- success: callback
- });
- },
-
- /**
- * Toggles the display of the 'Show quotes' button
- */
- _toggleShowQuotes: function() {
- require(['WoltLabSuite/Core/Ui/Page/Action'], (function(UiPageAction) {
- var buttonName = 'showQuotes';
-
- if (this._count) {
- var button = UiPageAction.get(buttonName);
- if (button === undefined) {
- button = elCreate('a');
- button.addEventListener('mousedown', this._click.bind(this));
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Saves a quote and directly inserts it.
+ */
+ _saveAndInsertQuote: function () {
+ this._saveQuote(true);
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param {Object} data
+ */
+ _success: function (data) {
+ if (data.returnValues.count !== undefined) {
+ if (data.returnValues.fullQuoteMessageIDs !== undefined) {
+ data.returnValues.fullQuoteObjectIDs = data.returnValues.fullQuoteMessageIDs;
+ }
+
+ var $fullQuoteObjectIDs = (data.returnValues.fullQuoteObjectIDs !== undefined) ? data.returnValues.fullQuoteObjectIDs : {};
+ this._quoteManager.updateCount(data.returnValues.count, $fullQuoteObjectIDs);
+ }
+
+ switch (data.actionName) {
+ case 'saveQuote':
+ case 'saveFullQuote':
+ if (data.returnValues.renderedQuote) {
+ WCF.System.Event.fireEvent('com.woltlab.wcf.message.quote', 'insert', {
+ forceInsert: (data.actionName === 'saveQuote'),
+ quote: data.returnValues.renderedQuote
+ });
+ }
+ break;
+ }
+ },
+
+ /**
+ * Updates the full quote data for all matching objects.
+ *
+ * @param array<integer> $objectIDs
+ */
+ updateFullQuoteObjectIDs: function (objectIDs) {
+ for (var $containerID in this._containers) {
+ this._containers[$containerID].find('.jsQuoteMessage').each(function (index, button) {
+ // reset all markings
+ var $button = $(button).data('isQuoted', 0);
+ $button.children('a').removeClass('active');
+
+ // mark as active
+ if (WCF.inArray($button.data('objectID'), objectIDs)) {
+ $button.data('isQuoted', 1).children('a').addClass('active');
+ }
+ });
+ }
+ }
+ });
+
+ /**
+ * Manages stored quotes.
+ *
+ * @param integer count
+ */
+ WCF.Message.Quote.Manager = Class.extend({
+ /**
+ * list of form buttons
+ * @var {Object}
+ */
+ _buttons: {},
+
+ /**
+ * number of stored quotes
+ * @var {int}
+ */
+ _count: 0,
+
+ /**
+ * dialog overlay
+ * @var {jQuery}
+ */
+ _dialog: null,
+
+ /**
+ * editor element id
+ * @var {string}
+ */
+ _editorId: '',
+
+ /**
+ * alternative editor element id
+ * @var {string}
+ */
+ _editorIdAlternative: '',
+
+ /**
+ * form element
+ * @var {jQuery}
+ */
+ _form: null,
+
+ /**
+ * list of quote handlers
+ * @var {Object}
+ */
+ _handlers: {},
+
+ /**
+ * true, if an up-to-date template exists
+ * @var {boolean}
+ */
+ _hasTemplate: false,
+
+ /**
+ * true, if related quotes should be inserted
+ * @var {boolean}
+ */
+ _insertQuotes: true,
+
+ /**
+ * action proxy
+ * @var {WCF.Action.Proxy}
+ */
+ _proxy: null,
+
+ /**
+ * list of quotes to remove upon submit
+ * @var {Array}
+ */
+ _removeOnSubmit: [],
+
+ /**
+ * allow pasting
+ * @var {boolean}
+ */
+ _supportPaste: false,
+
+ /**
+ * Initializes the quote manager.
+ *
+ * @param {int} count
+ * @param {string} elementID
+ * @param {boolean} supportPaste
+ * @param {Array} removeOnSubmit
+ */
+ init: function (count, elementID, supportPaste, removeOnSubmit) {
+ this._buttons = {
+ insert: null,
+ remove: null
+ };
+ this._count = parseInt(count) || 0;
+ this._dialog = null;
+ this._editorId = '';
+ this._editorIdAlternative = '';
+ this._form = null;
+ this._handlers = {};
+ this._hasTemplate = false;
+ this._insertQuotes = true;
+ this._removeOnSubmit = [];
+ this._supportPaste = false;
+
+ if (elementID) {
+ var element = $('#' + elementID);
+ if (element.length) {
+ this._editorId = elementID;
+ this._supportPaste = true;
- UiPageAction.add(buttonName, button);
+ // get surrounding form-tag
+ this._form = element.parents('form:eq(0)');
+ if (this._form.length) {
+ this._form.submit(this._submit.bind(this));
+ this._removeOnSubmit = removeOnSubmit || [];
+ }
+ else {
+ this._form = null;
+
+ // allow override
+ this._supportPaste = (supportPaste === true);
+ }
+ }
+ }
+
+ this._proxy = new WCF.Action.Proxy({
+ showLoadingOverlay: false,
+ success: $.proxy(this._success, this),
+ url: 'index.php?message-quote/&t=' + SECURITY_TOKEN
+ });
+
+ this._toggleShowQuotes();
+
+ WCF.System.Event.addListener('com.woltlab.wcf.quote', 'reload', this.countQuotes.bind(this));
+
+ // event forwarding
+ WCF.System.Event.addListener('com.woltlab.wcf.message.quote', 'insert', (function (data) {
+ //noinspection JSUnresolvedVariable
+ WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertQuote_' + (this._editorIdAlternative ? this._editorIdAlternative : this._editorId), {
+ author: data.quote.username,
+ content: data.quote.text,
+ isText: !data.quote.isFullQuote,
+ link: data.quote.link
+ });
+ }).bind(this));
+ },
+
+ /**
+ * Sets an alternative editor element id on runtime.
+ *
+ * @param {(string|jQuery)} elementId element id or jQuery element
+ */
+ setAlternativeEditor: function (elementId) {
+ if (typeof elementId === 'object') elementId = elementId[0].id;
+ this._editorIdAlternative = elementId;
+ },
+
+ /**
+ * Clears alternative editor element id.
+ */
+ clearAlternativeEditor: function () {
+ this._editorIdAlternative = '';
+ },
+
+ /**
+ * Registers a quote handler.
+ *
+ * @param {string} objectType
+ * @param {WCF.Message.Quote.Handler} handler
+ */
+ register: function (objectType, handler) {
+ this._handlers[objectType] = handler;
+ },
+
+ /**
+ * Updates number of stored quotes.
+ *
+ * @param {int} count
+ * @param {Object} fullQuoteObjectIDs
+ */
+ updateCount: function (count, fullQuoteObjectIDs) {
+ this._count = parseInt(count) || 0;
+
+ this._toggleShowQuotes();
+
+ // update full quote ids of handlers
+ for (var $objectType in this._handlers) {
+ if (this._handlers.hasOwnProperty($objectType)) {
+ var $objectIDs = fullQuoteObjectIDs[$objectType] || [];
+ this._handlers[$objectType].updateFullQuoteObjectIDs($objectIDs);
}
+ }
+ },
+
+ /**
+ * Inserts all associated quotes upon first time using quick reply.
+ *
+ * @param {string} className
+ * @param {int} parentObjectID
+ * @param {Object} callback
+ */
+ insertQuotes: function (className, parentObjectID, callback) {
+ if (!this._insertQuotes) {
+ this._insertQuotes = true;
- button.textContent = WCF.Language.get('wcf.message.quote.showQuotes').replace(/#count#/, this._count);
+ return;
+ }
+
+ new WCF.Action.Proxy({
+ autoSend: true,
+ data: {
+ actionName: 'getRenderedQuotes',
+ className: className,
+ interfaceName: 'wcf\\data\\IMessageQuoteAction',
+ parameters: {
+ parentObjectID: parentObjectID
+ }
+ },
+ success: callback
+ });
+ },
+
+ /**
+ * Toggles the display of the 'Show quotes' button
+ */
+ _toggleShowQuotes: function () {
+ require(['WoltLabSuite/Core/Ui/Page/Action'], (function (UiPageAction) {
+ var buttonName = 'showQuotes';
+
+ if (this._count) {
+ var button = UiPageAction.get(buttonName);
+ if (button === undefined) {
+ button = elCreate('a');
+ button.addEventListener('mousedown', this._click.bind(this));
+
+ UiPageAction.add(buttonName, button);
+ }
+
+ button.textContent = WCF.Language.get('wcf.message.quote.showQuotes').replace(/#count#/, this._count);
+
+ UiPageAction.show(buttonName);
+ }
+ else {
+ UiPageAction.hide(buttonName);
+ }
- UiPageAction.show(buttonName);
+ this._hasTemplate = false;
+ }).bind(this));
+ },
+
+ /**
+ * Handles clicks on 'Show quotes'.
+ */
+ _click: function () {
+ var editor = document.activeElement;
+ if (editor.classList.contains('redactor-layer')) {
+ $('#' + elData(editor, 'element-id')).redactor('selection.save');
+ }
+
+ if (this._hasTemplate) {
+ this._dialog.wcfDialog('open');
}
else {
- UiPageAction.hide(buttonName);
+ this._proxy.showLoadingOverlayOnce();
+
+ this._proxy.setOption('data', {
+ actionName: 'getQuotes',
+ supportPaste: this._supportPaste
+ });
+ this._proxy.sendRequest();
+ }
+ },
+
+ /**
+ * Renders the dialog.
+ *
+ * @param {string} template
+ */
+ renderDialog: function (template) {
+ // create dialog if not exists
+ if (this._dialog === null) {
+ this._dialog = $('#messageQuoteList');
+ if (!this._dialog.length) {
+ this._dialog = $('<div id="messageQuoteList" />').hide().appendTo(document.body);
+ }
}
- this._hasTemplate = false;
- }).bind(this));
- },
-
- /**
- * Handles clicks on 'Show quotes'.
- */
- _click: function() {
- var editor = document.activeElement;
- if (editor.classList.contains('redactor-layer')) {
- $('#' + elData(editor, 'element-id')).redactor('selection.save');
- }
-
- if (this._hasTemplate) {
- this._dialog.wcfDialog('open');
- }
- else {
- this._proxy.showLoadingOverlayOnce();
+ // add template
+ this._dialog.html(template);
- this._proxy.setOption('data', {
- actionName: 'getQuotes',
- supportPaste: this._supportPaste
+ // add 'insert' and 'delete' buttons
+ var $formSubmit = $('<div class="formSubmit" />').appendTo(this._dialog);
+ if (this._supportPaste) this._buttons.insert = $('<button class="buttonPrimary">' + WCF.Language.get('wcf.message.quote.insertAllQuotes') + '</button>').click($.proxy(this._insertSelected, this)).appendTo($formSubmit);
+ this._buttons.remove = $('<button>' + WCF.Language.get('wcf.message.quote.removeAllQuotes') + '</button>').click($.proxy(this._removeSelected, this)).appendTo($formSubmit);
+
+ // show dialog
+ this._dialog.wcfDialog({
+ title: WCF.Language.get('wcf.message.quote.manageQuotes')
});
- this._proxy.sendRequest();
- }
- },
-
- /**
- * Renders the dialog.
- *
- * @param {string} template
- */
- renderDialog: function(template) {
- // create dialog if not exists
- if (this._dialog === null) {
- this._dialog = $('#messageQuoteList');
- if (!this._dialog.length) {
- this._dialog = $('<div id="messageQuoteList" />').hide().appendTo(document.body);
+ this._dialog.wcfDialog('render');
+ this._hasTemplate = true;
+
+ // bind event listener
+ var $insertQuoteButtons = this._dialog.find('.jsInsertQuote');
+ if (this._supportPaste) {
+ $insertQuoteButtons.click($.proxy(this._insertQuote, this));
}
- }
-
- // add template
- this._dialog.html(template);
-
- // add 'insert' and 'delete' buttons
- var $formSubmit = $('<div class="formSubmit" />').appendTo(this._dialog);
- if (this._supportPaste) this._buttons.insert = $('<button class="buttonPrimary">' + WCF.Language.get('wcf.message.quote.insertAllQuotes') + '</button>').click($.proxy(this._insertSelected, this)).appendTo($formSubmit);
- this._buttons.remove = $('<button>' + WCF.Language.get('wcf.message.quote.removeAllQuotes') + '</button>').click($.proxy(this._removeSelected, this)).appendTo($formSubmit);
-
- // show dialog
- this._dialog.wcfDialog({
- title: WCF.Language.get('wcf.message.quote.manageQuotes')
- });
- this._dialog.wcfDialog('render');
- this._hasTemplate = true;
-
- // bind event listener
- var $insertQuoteButtons = this._dialog.find('.jsInsertQuote');
- if (this._supportPaste) {
- $insertQuoteButtons.click($.proxy(this._insertQuote, this));
- }
- else {
- $insertQuoteButtons.hide();
- }
-
- this._dialog.find('input.jsCheckbox').change($.proxy(this._changeButtons, this));
-
- // mark quotes for removal
- if (this._removeOnSubmit.length) {
- var self = this;
- this._dialog.find('input.jsRemoveQuote').each(function(index, input) {
- var $input = $(input).change($.proxy(this._change, this));
-
- // mark for deletion
- if (WCF.inArray($input.parent('li').attr('data-quote-id'), self._removeOnSubmit)) {
- $input.attr('checked', 'checked');
+ else {
+ $insertQuoteButtons.hide();
+ }
+
+ this._dialog.find('input.jsCheckbox').change($.proxy(this._changeButtons, this));
+
+ // mark quotes for removal
+ if (this._removeOnSubmit.length) {
+ var self = this;
+ this._dialog.find('input.jsRemoveQuote').each(function (index, input) {
+ var $input = $(input).change($.proxy(this._change, this));
+
+ // mark for deletion
+ if (WCF.inArray($input.parent('li').attr('data-quote-id'), self._removeOnSubmit)) {
+ $input.attr('checked', 'checked');
+ }
+ });
+ }
+ },
+
+ /**
+ * Updates button labels if a checkbox is checked or unchecked.
+ */
+ _changeButtons: function () {
+ // selection
+ if (this._dialog.find('input.jsCheckbox:checked').length) {
+ if (this._supportPaste) this._buttons.insert.html(WCF.Language.get('wcf.message.quote.insertSelectedQuotes'));
+ this._buttons.remove.html(WCF.Language.get('wcf.message.quote.removeSelectedQuotes'));
+ }
+ else {
+ // no selection, pick all
+ if (this._supportPaste) this._buttons.insert.html(WCF.Language.get('wcf.message.quote.insertAllQuotes'));
+ this._buttons.remove.html(WCF.Language.get('wcf.message.quote.removeAllQuotes'));
+ }
+ },
+
+ /**
+ * Checks for change event on delete-checkboxes.
+ *
+ * @param {Object} event
+ */
+ _change: function (event) {
+ var $input = $(event.currentTarget);
+ var $quoteID = $input.parent('li').attr('data-quote-id');
+
+ if ($input.prop('checked')) {
+ this._removeOnSubmit.push($quoteID);
+ }
+ else {
+ var index = this._removeOnSubmit.indexOf($quoteID);
+ if (index !== -1) {
+ this._removeOnSubmit.splice(index, 1);
}
- });
- }
- },
-
- /**
- * Updates button labels if a checkbox is checked or unchecked.
- */
- _changeButtons: function() {
- // selection
- if (this._dialog.find('input.jsCheckbox:checked').length) {
- if (this._supportPaste) this._buttons.insert.html(WCF.Language.get('wcf.message.quote.insertSelectedQuotes'));
- this._buttons.remove.html(WCF.Language.get('wcf.message.quote.removeSelectedQuotes'));
- }
- else {
- // no selection, pick all
- if (this._supportPaste) this._buttons.insert.html(WCF.Language.get('wcf.message.quote.insertAllQuotes'));
- this._buttons.remove.html(WCF.Language.get('wcf.message.quote.removeAllQuotes'));
- }
- },
-
- /**
- * Checks for change event on delete-checkboxes.
- *
- * @param {Object} event
- */
- _change: function(event) {
- var $input = $(event.currentTarget);
- var $quoteID = $input.parent('li').attr('data-quote-id');
-
- if ($input.prop('checked')) {
- this._removeOnSubmit.push($quoteID);
- }
- else {
- var index = this._removeOnSubmit.indexOf($quoteID);
- if (index !== -1) {
- this._removeOnSubmit.splice(index, 1);
}
- }
- },
-
- /**
- * Inserts the selected quotes.
- */
- _insertSelected: function() {
- if (!this._dialog.find('input.jsCheckbox:checked').length) {
- this._dialog.find('input.jsCheckbox').prop('checked', 'checked');
- }
-
- // insert all quotes
- this._dialog.find('input.jsCheckbox:checked').each($.proxy(function(index, input) {
- this._insertQuote(null, input);
- }, this));
-
- // close dialog
- this._dialog.wcfDialog('close');
- },
-
- /**
- * Inserts a quote.
- *
- * @param {Event} event
- * @param {Object} inputElement
- */
- _insertQuote: function(event, inputElement) {
- var listItem = $(event ? event.currentTarget : inputElement).parents('li:eq(0)');
- var text = listItem.children('.jsFullQuote')[0].textContent.trim();
-
- var message = listItem.parents('.message:eq(0)');
- var author = message.data('username');
- var link = message.data('link');
- var isText = !elDataBool(listItem[0], 'is-full-quote');
-
- WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertQuote_' + (this._editorIdAlternative ? this._editorIdAlternative : this._editorId), {
- author: author,
- content: text,
- isText: isText,
- link: link
- });
-
- // remove quote upon submit or upon request
- this._removeOnSubmit.push(listItem.data('quote-id'));
-
- // close dialog
- if (event !== null) {
+ },
+
+ /**
+ * Inserts the selected quotes.
+ */
+ _insertSelected: function () {
+ if (!this._dialog.find('input.jsCheckbox:checked').length) {
+ this._dialog.find('input.jsCheckbox').prop('checked', 'checked');
+ }
+
+ // insert all quotes
+ this._dialog.find('input.jsCheckbox:checked').each($.proxy(function (index, input) {
+ this._insertQuote(null, input);
+ }, this));
+
+ // close dialog
this._dialog.wcfDialog('close');
- }
- },
-
- /**
- * Removes selected quotes.
- */
- _removeSelected: function() {
- if (!this._dialog.find('input.jsCheckbox:checked').length) {
- this._dialog.find('input.jsCheckbox').prop('checked', 'checked');
- }
-
- var $quoteIDs = [ ];
- this._dialog.find('input.jsCheckbox:checked').each(function(index, input) {
- $quoteIDs.push($(input).parents('li').attr('data-quote-id'));
- });
+ },
+
+ /**
+ * Inserts a quote.
+ *
+ * @param {Event} event
+ * @param {Object} inputElement
+ */
+ _insertQuote: function (event, inputElement) {
+ var listItem = $(event ? event.currentTarget : inputElement).parents('li:eq(0)');
+ var text = listItem.children('.jsFullQuote')[0].textContent.trim();
+
+ var message = listItem.parents('.message:eq(0)');
+ var author = message.data('username');
+ var link = message.data('link');
+ var isText = !elDataBool(listItem[0], 'is-full-quote');
+
+ WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'insertQuote_' + (this._editorIdAlternative ? this._editorIdAlternative : this._editorId), {
+ author: author,
+ content: text,
+ isText: isText,
+ link: link
+ });
+
+ // remove quote upon submit or upon request
+ this._removeOnSubmit.push(listItem.data('quote-id'));
+
+ // close dialog
+ if (event !== null) {
+ this._dialog.wcfDialog('close');
+ }
+ },
+
+ /**
+ * Removes selected quotes.
+ */
+ _removeSelected: function () {
+ if (!this._dialog.find('input.jsCheckbox:checked').length) {
+ this._dialog.find('input.jsCheckbox').prop('checked', 'checked');
+ }
+
+ var $quoteIDs = [];
+ this._dialog.find('input.jsCheckbox:checked').each(function (index, input) {
+ $quoteIDs.push($(input).parents('li').attr('data-quote-id'));
+ });
+
+ if ($quoteIDs.length) {
+ // get object types
+ var $objectTypes = [];
+ for (var $objectType in this._handlers) {
+ if (this._handlers.hasOwnProperty($objectType)) {
+ $objectTypes.push($objectType);
+ }
+ }
+
+ this._proxy.setOption('data', {
+ actionName: 'remove',
+ getFullQuoteObjectIDs: this._handlers.length > 0,
+ objectTypes: $objectTypes,
+ quoteIDs: $quoteIDs
+ });
+ this._proxy.sendRequest();
+
+ this._dialog.wcfDialog('close');
+ }
+ },
+
+ /**
+ * Appends list of quote ids to remove after successful submit.
+ */
+ _submit: function () {
+ if (this._supportPaste && this._removeOnSubmit.length > 0) {
+ var $formSubmit = this._form.find('.formSubmit');
+ for (var i = 0, length = this._removeOnSubmit.length; i < length; i++) {
+ $('<input type="hidden" name="__removeQuoteIDs[]" value="' + this._removeOnSubmit[i] + '" />').appendTo($formSubmit);
+ }
+ }
+ },
+
+ /**
+ * Returns a list of quote ids marked for removal.
+ *
+ * @return {Array}
+ */
+ getQuotesMarkedForRemoval: function () {
+ return this._removeOnSubmit;
+ },
+
+ /**
+ * Marks quote ids for removal.
+ */
+ markQuotesForRemoval: function () {
+ if (this._removeOnSubmit.length) {
+ this._proxy.setOption('data', {
+ actionName: 'markForRemoval',
+ quoteIDs: this._removeOnSubmit
+ });
+ this._proxy.suppressErrors();
+ this._proxy.sendRequest();
+ }
+ },
+
+ /**
+ * Removes all marked quote ids.
+ */
+ removeMarkedQuotes: function () {
+ if (this._removeOnSubmit.length) {
+ this._proxy.setOption('data', {
+ actionName: 'removeMarkedQuotes',
+ getFullQuoteObjectIDs: this._handlers.length > 0
+ });
+ this._proxy.sendRequest();
+ }
+ },
- if ($quoteIDs.length) {
- // get object types
+ /**
+ * Counts stored quotes.
+ */
+ countQuotes: function () {
var $objectTypes = [];
for (var $objectType in this._handlers) {
if (this._handlers.hasOwnProperty($objectType)) {
}
this._proxy.setOption('data', {
- actionName: 'remove',
- getFullQuoteObjectIDs: this._handlers.length > 0,
- objectTypes: $objectTypes,
- quoteIDs: $quoteIDs
- });
- this._proxy.sendRequest();
-
- this._dialog.wcfDialog('close');
- }
- },
-
- /**
- * Appends list of quote ids to remove after successful submit.
- */
- _submit: function() {
- if (this._supportPaste && this._removeOnSubmit.length > 0) {
- var $formSubmit = this._form.find('.formSubmit');
- for (var i = 0, length = this._removeOnSubmit.length; i < length; i++) {
- $('<input type="hidden" name="__removeQuoteIDs[]" value="' + this._removeOnSubmit[i] + '" />').appendTo($formSubmit);
- }
- }
- },
-
- /**
- * Returns a list of quote ids marked for removal.
- *
- * @return {Array}
- */
- getQuotesMarkedForRemoval: function() {
- return this._removeOnSubmit;
- },
-
- /**
- * Marks quote ids for removal.
- */
- markQuotesForRemoval: function() {
- if (this._removeOnSubmit.length) {
- this._proxy.setOption('data', {
- actionName: 'markForRemoval',
- quoteIDs: this._removeOnSubmit
- });
- this._proxy.suppressErrors();
- this._proxy.sendRequest();
- }
- },
-
- /**
- * Removes all marked quote ids.
- */
- removeMarkedQuotes: function() {
- if (this._removeOnSubmit.length) {
- this._proxy.setOption('data', {
- actionName: 'removeMarkedQuotes',
- getFullQuoteObjectIDs: this._handlers.length > 0
+ actionName: 'count',
+ getFullQuoteObjectIDs: ($objectTypes.length > 0),
+ objectTypes: $objectTypes
});
this._proxy.sendRequest();
- }
- },
-
- /**
- * Counts stored quotes.
- */
- countQuotes: function() {
- var $objectTypes = [ ];
- for (var $objectType in this._handlers) {
- if (this._handlers.hasOwnProperty($objectType)) {
- $objectTypes.push($objectType);
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param {Object} data
+ */
+ _success: function (data) {
+ if (data === null) {
+ return;
}
- }
-
- this._proxy.setOption('data', {
- actionName: 'count',
- getFullQuoteObjectIDs: ($objectTypes.length > 0),
- objectTypes: $objectTypes
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param {Object} data
- */
- _success: function(data) {
- if (data === null) {
- return;
- }
-
- if (data.count !== undefined) {
- var $fullQuoteObjectIDs = (data.fullQuoteObjectIDs !== undefined) ? data.fullQuoteObjectIDs : { };
- this.updateCount(data.count, $fullQuoteObjectIDs);
- }
-
- if (data.template !== undefined) {
- if ($.trim(data.template) == '') {
- this.updateCount(0, { });
+
+ if (data.count !== undefined) {
+ var $fullQuoteObjectIDs = (data.fullQuoteObjectIDs !== undefined) ? data.fullQuoteObjectIDs : {};
+ this.updateCount(data.count, $fullQuoteObjectIDs);
}
- else {
- this.renderDialog(data.template);
+
+ if (data.template !== undefined) {
+ if ($.trim(data.template) == '') {
+ this.updateCount(0, {});
+ }
+ else {
+ this.renderDialog(data.template);
+ }
}
- }
- },
-
- /**
- * Returns true if pasting is supported.
- *
- * @return boolean
- */
- supportPaste: function() {
- return this._supportPaste;
- }
-});
+ },
+
+ /**
+ * Returns true if pasting is supported.
+ *
+ * @return boolean
+ */
+ supportPaste: function () {
+ return this._supportPaste;
+ }
+ });
+}
+else {
+ WCF.Message.Quote.Handler = Class.extend({
+ _activeContainerID: "",
+ _className: "",
+ _containers: {},
+ _containerSelector: "",
+ _copyQuote: {},
+ _message: "",
+ _messageBodySelector: "",
+ _objectID: 0,
+ _objectType: "",
+ _proxy: {},
+ _quoteManager: {},
+ init: function() {},
+ _initContainers: function() {},
+ _mouseDown: function() {},
+ _getNodeText: function() {},
+ _mouseUp: function() {},
+ _normalize: function() {},
+ _getBoundingRectangle: function() {},
+ _initCopyQuote: function() {},
+ _getSelectedText: function() {},
+ _saveFullQuote: function() {},
+ _saveQuote: function() {},
+ _saveAndInsertQuote: function() {},
+ _success: function() {},
+ updateFullQuoteObjectIDs: function() {}
+ });
+
+ WCF.Message.Quote.Manager = Class.extend({
+ _buttons: {},
+ _count: 0,
+ _dialog: {},
+ _editorId: "",
+ _editorIdAlternative: "",
+ _form: {},
+ _handlers: {},
+ _hasTemplate: false,
+ _insertQuotes: true,
+ _proxy: {},
+ _removeOnSubmit: {},
+ _supportPaste: false,
+ init: function() {},
+ setAlternativeEditor: function() {},
+ clearAlternativeEditor: function() {},
+ register: function() {},
+ updateCount: function() {},
+ insertQuotes: function() {},
+ _toggleShowQuotes: function() {},
+ _click: function() {},
+ renderDialog: function() {},
+ _changeButtons: function() {},
+ _change: function() {},
+ _insertSelected: function() {},
+ _insertQuote: function() {},
+ _removeSelected: function() {},
+ _submit: function() {},
+ getQuotesMarkedForRemoval: function() {},
+ markQuotesForRemoval: function() {},
+ removeMarkedQuotes: function() {},
+ countQuotes: function() {},
+ _success: function() {},
+ supportPaste: function() {}
+ });
+}
/**
* Namespace for message sharing related classes.
*/
WCF.Moderation = { };
-/**
- * Moderation queue management.
- *
- * @param integer queueID
- * @param string redirectURL
- */
-WCF.Moderation.Management = Class.extend({
- /**
- * button selector
- * @var string
- */
- _buttonSelector: '',
-
- /**
- * action class name
- * @var string
- */
- _className: '',
-
- /**
- * list of templates for confirmation message by action name
- * @var object
- */
- _confirmationTemplate: { },
-
- /**
- * dialog overlay
- * @var jQuery
- */
- _dialog: null,
-
- /**
- * language item pattern
- * @var string
- */
- _languageItem: '',
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * queue id
- * @var integer
- */
- _queueID: 0,
-
- /**
- * redirect URL
- * @var string
- */
- _redirectURL: '',
-
- /**
- * Initializes the moderation report management.
- *
- * @param integer queueID
- * @param string redirectURL
- * @param string languageItem
- */
- init: function(queueID, redirectURL, languageItem) {
- if (!this._buttonSelector) {
- console.debug("[WCF.Moderation.Management] Missing button selector, aborting.");
- return;
- }
- else if (!this._className) {
- console.debug("[WCF.Moderation.Management] Missing class name, aborting.");
- return;
- }
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Moderation queue management.
+ *
+ * @param integer queueID
+ * @param string redirectURL
+ */
+ WCF.Moderation.Management = Class.extend({
+ /**
+ * button selector
+ * @var string
+ */
+ _buttonSelector: '',
- this._dialog = null;
- this._queueID = queueID;
- this._redirectURL = redirectURL;
- this._languageItem = languageItem;
+ /**
+ * action class name
+ * @var string
+ */
+ _className: '',
- this._proxy = new WCF.Action.Proxy({
- failure: $.proxy(this._failure, this),
- success: $.proxy(this._success, this)
- });
+ /**
+ * list of templates for confirmation message by action name
+ * @var object
+ */
+ _confirmationTemplate: {},
- $(this._buttonSelector).click($.proxy(this._click, this));
+ /**
+ * dialog overlay
+ * @var jQuery
+ */
+ _dialog: null,
- $('#moderationAssignUser').click($.proxy(this._clickAssignedUser, this));
- },
-
- /**
- * Handles clicks on the action buttons.
- *
- * @param object event
- */
- _click: function(event) {
- var $actionName = $(event.currentTarget).wcfIdentify();
- var $innerTemplate = '';
- if (this._confirmationTemplate[$actionName]) {
- $innerTemplate = this._confirmationTemplate[$actionName];
- }
+ /**
+ * language item pattern
+ * @var string
+ */
+ _languageItem: '',
- WCF.System.Confirmation.show(WCF.Language.get(this._languageItem.replace(/{actionName}/, $actionName)), $.proxy(function(action, parameters, content) {
- if (action === 'confirm') {
- var $parameters = {
- actionName: $actionName,
- className: this._className,
- objectIDs: [ this._queueID ]
- };
- if (this._confirmationTemplate[$actionName]) {
- $parameters.parameters = { };
- $(content).find('input, textarea').each(function(index, element) {
- var $element = $(element);
- var $value = $element.val();
- if ($element.getTagName() === 'input' && $element.attr('type') === 'checkbox') {
- if (!$element.is(':checked')) {
- $value = null;
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * queue id
+ * @var integer
+ */
+ _queueID: 0,
+
+ /**
+ * redirect URL
+ * @var string
+ */
+ _redirectURL: '',
+
+ /**
+ * Initializes the moderation report management.
+ *
+ * @param integer queueID
+ * @param string redirectURL
+ * @param string languageItem
+ */
+ init: function (queueID, redirectURL, languageItem) {
+ if (!this._buttonSelector) {
+ console.debug("[WCF.Moderation.Management] Missing button selector, aborting.");
+ return;
+ }
+ else if (!this._className) {
+ console.debug("[WCF.Moderation.Management] Missing class name, aborting.");
+ return;
+ }
+
+ this._dialog = null;
+ this._queueID = queueID;
+ this._redirectURL = redirectURL;
+ this._languageItem = languageItem;
+
+ this._proxy = new WCF.Action.Proxy({
+ failure: $.proxy(this._failure, this),
+ success: $.proxy(this._success, this)
+ });
+
+ $(this._buttonSelector).click($.proxy(this._click, this));
+
+ $('#moderationAssignUser').click($.proxy(this._clickAssignedUser, this));
+ },
+
+ /**
+ * Handles clicks on the action buttons.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $actionName = $(event.currentTarget).wcfIdentify();
+ var $innerTemplate = '';
+ if (this._confirmationTemplate[$actionName]) {
+ $innerTemplate = this._confirmationTemplate[$actionName];
+ }
+
+ WCF.System.Confirmation.show(WCF.Language.get(this._languageItem.replace(/{actionName}/, $actionName)), $.proxy(function (action, parameters, content) {
+ if (action === 'confirm') {
+ var $parameters = {
+ actionName: $actionName,
+ className: this._className,
+ objectIDs: [this._queueID]
+ };
+ if (this._confirmationTemplate[$actionName]) {
+ $parameters.parameters = {};
+ $(content).find('input, textarea').each(function (index, element) {
+ var $element = $(element);
+ var $value = $element.val();
+ if ($element.getTagName() === 'input' && $element.attr('type') === 'checkbox') {
+ if (!$element.is(':checked')) {
+ $value = null;
+ }
}
- }
-
- if ($value !== null) {
- $parameters.parameters[$element.attr('name')] = $value;
- }
- });
+
+ if ($value !== null) {
+ $parameters.parameters[$element.attr('name')] = $value;
+ }
+ });
+ }
+
+ this._proxy.setOption('data', $parameters);
+ this._proxy.sendRequest();
+
+ $(this._buttonSelector).disable();
}
+ }, this), {}, $innerTemplate);
+ },
+
+ /**
+ * Handles clicks on the assign user link.
+ */
+ _clickAssignedUser: function () {
+ this._proxy.setOption('data', {
+ actionName: 'getAssignUserForm',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
+ objectIDs: [this._queueID]
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ switch (data.actionName) {
+ case 'getAssignUserForm':
+ if (this._dialog === null) {
+ this._dialog = $('<div />').hide().appendTo(document.body);
+ this._dialog.html(data.returnValues.template).wcfDialog({
+ title: WCF.Language.get('wcf.moderation.assignedUser')
+ });
+ }
+ else {
+ this._dialog.html(data.returnValues.template).wcfDialog('open');
+ }
+
+ this._dialog.find('button[data-type=submit]').click($.proxy(this._assignUser, this));
+ break;
- this._proxy.setOption('data', $parameters);
- this._proxy.sendRequest();
+ case 'assignUser':
+ var $span = $('#moderationAssignedUserContainer > dd > span').empty();
+ if (data.returnValues.userID) {
+ $('<a href="' + data.returnValues.link + '" data-user-id="' + data.returnValues.userID + '" class="userLink">' + WCF.String.escapeHTML(data.returnValues.username) + '</a>').appendTo($span);
+ }
+ else {
+ $span.append(data.returnValues.username);
+ }
+
+ $span.append(' ');
+
+ if (data.returnValues.newStatus) {
+ $('#moderationStatusContainer > dd').text(WCF.Language.get('wcf.moderation.status.' + data.returnValues.newStatus));
+ }
+
+ this._dialog.wcfDialog('close');
+
+ new WCF.System.Notification().show();
+ break;
- $(this._buttonSelector).disable();
- }
- }, this), { }, $innerTemplate);
- },
-
- /**
- * Handles clicks on the assign user link.
- */
- _clickAssignedUser: function() {
- this._proxy.setOption('data', {
- actionName: 'getAssignUserForm',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
- objectIDs: [ this._queueID ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- switch (data.actionName) {
- case 'getAssignUserForm':
- if (this._dialog === null) {
- this._dialog = $('<div />').hide().appendTo(document.body);
- this._dialog.html(data.returnValues.template).wcfDialog({
- title: WCF.Language.get('wcf.moderation.assignedUser')
+ default:
+ var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
+ var self = this;
+ $notification.show(function () {
+ window.location = self._redirectURL;
});
- }
- else {
- this._dialog.html(data.returnValues.template).wcfDialog('open');
- }
-
- this._dialog.find('button[data-type=submit]').click($.proxy(this._assignUser, this));
- break;
-
- case 'assignUser':
- var $span = $('#moderationAssignedUserContainer > dd > span').empty();
- if (data.returnValues.userID) {
- $('<a href="' + data.returnValues.link + '" data-user-id="' + data.returnValues.userID + '" class="userLink">' + WCF.String.escapeHTML(data.returnValues.username) + '</a>').appendTo($span);
- }
- else {
- $span.append(data.returnValues.username);
- }
-
- $span.append(' ');
+ break;
+ }
+ },
+
+ /**
+ * Handles errorneus AJAX requests.
+ *
+ * @param object data
+ * @param jQuery jqXHR
+ * @param string textStatus
+ * @param string errorThrown
+ */
+ _failure: function (data, jqXHR, textStatus, errorThrown) {
+ if (data.returnValues && data.returnValues.fieldName && data.returnValues.fieldName == 'assignedUsername') {
+ this._dialog.find('small.innerError').remove();
- if (data.returnValues.newStatus) {
- $('#moderationStatusContainer > dd').text(WCF.Language.get('wcf.moderation.status.' + data.returnValues.newStatus));
+ var $errorString = '';
+ switch (data.returnValues.errorType) {
+ case 'empty':
+ $errorString = WCF.Language.get('wcf.global.form.error.empty');
+ break;
+
+ case 'notAffected':
+ $errorString = WCF.Language.get('wcf.moderation.assignedUser.error.notAffected');
+ break;
+
+ default:
+ $errorString = WCF.Language.get('wcf.user.username.error.' + data.returnValues.errorType, {username: this._dialog.find('#assignedUsername').val()});
+ break;
}
- this._dialog.wcfDialog('close');
+ $('<small class="innerError">' + $errorString + '</small>').insertAfter(this._dialog.find('#assignedUsername'));
- new WCF.System.Notification().show();
- break;
-
- default:
- var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
- var self = this;
- $notification.show(function() {
- window.location = self._redirectURL;
- });
- break;
- }
- },
-
- /**
- * Handles errorneus AJAX requests.
- *
- * @param object data
- * @param jQuery jqXHR
- * @param string textStatus
- * @param string errorThrown
- */
- _failure: function(data, jqXHR, textStatus, errorThrown) {
- if (data.returnValues && data.returnValues.fieldName && data.returnValues.fieldName == 'assignedUsername') {
- this._dialog.find('small.innerError').remove();
+ return false;
+ }
- var $errorString = '';
- switch (data.returnValues.errorType) {
- case 'empty':
- $errorString = WCF.Language.get('wcf.global.form.error.empty');
- break;
-
- case 'notAffected':
- $errorString = WCF.Language.get('wcf.moderation.assignedUser.error.notAffected');
- break;
-
- default:
- $errorString = WCF.Language.get('wcf.user.username.error.' + data.returnValues.errorType, { username: this._dialog.find('#assignedUsername').val() });
- break;
+ return true;
+ },
+
+ /**
+ * Submits the assign user form.
+ */
+ _assignUser: function () {
+ var $assignedUserID = this._dialog.find('input[name=assignedUserID]:checked').val();
+ var $assignedUsername = '';
+ if ($assignedUserID == -1) {
+ $assignedUsername = $.trim(this._dialog.find('#assignedUsername').val());
}
- $('<small class="innerError">' + $errorString + '</small>').insertAfter(this._dialog.find('#assignedUsername'));
+ if ($assignedUserID == -1 && $assignedUsername.length == 0) {
+ this._dialog.find('small.innerError').remove();
+ $('<small class="innerError">' + WCF.Language.get('wcf.global.form.error.empty') + '</small>').insertAfter(this._dialog.find('#assignedUsername'));
+ return;
+ }
- return false;
- }
-
- return true;
- },
-
- /**
- * Submits the assign user form.
- */
- _assignUser: function() {
- var $assignedUserID = this._dialog.find('input[name=assignedUserID]:checked').val();
- var $assignedUsername = '';
- if ($assignedUserID == -1) {
- $assignedUsername = $.trim(this._dialog.find('#assignedUsername').val());
- }
-
- if ($assignedUserID == -1 && $assignedUsername.length == 0) {
- this._dialog.find('small.innerError').remove();
- $('<small class="innerError">' + WCF.Language.get('wcf.global.form.error.empty') + '</small>').insertAfter(this._dialog.find('#assignedUsername'));
- return;
+ this._proxy.setOption('data', {
+ actionName: 'assignUser',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
+ objectIDs: [this._queueID],
+ parameters: {
+ assignedUserID: $assignedUserID,
+ assignedUsername: $assignedUsername
+ }
+ });
+ this._proxy.sendRequest();
}
-
- this._proxy.setOption('data', {
- actionName: 'assignUser',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
- objectIDs: [ this._queueID ],
- parameters: {
- assignedUserID: $assignedUserID,
- assignedUsername: $assignedUsername
- }
- });
- this._proxy.sendRequest();
- }
-});
+ });
+}
+else {
+ WCF.Moderation.Management = Class.extend({
+ _buttonSelector: "",
+ _className: "",
+ _confirmationTemplate: {},
+ _dialog: {},
+ _languageItem: "",
+ _proxy: {},
+ _queueID: 0,
+ _redirectURL: "",
+ init: function() {},
+ _click: function() {},
+ _clickAssignedUser: function() {},
+ _success: function() {},
+ _failure: function() {},
+ _assignUser: function() {}
+ });
+}
/**
* Namespace for moderation queue related classes.
*/
WCF.Moderation.Queue = { };
-/**
- * Marks one moderation queue entry as read.
- */
-WCF.Moderation.Queue.MarkAsRead = Class.extend({
+if (COMPILER_TARGET_DEFAULT) {
/**
- * action proxy
- * @var WCF.Action.Proxy
+ * Marks one moderation queue entry as read.
*/
- _proxy: null,
-
- /**
- * Initializes the mark as read for queue entries.
- */
- init: function() {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
+ WCF.Moderation.Queue.MarkAsRead = Class.extend({
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
- $(document).on('dblclick', '.moderationList .new .columnAvatar', $.proxy(this._dblclick, this));
- },
-
- /**
- * Handles double clicks on avatar.
- *
- * @param object event
- */
- _dblclick: function(event) {
- this._proxy.setOption('data', {
- actionName: 'markAsRead',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
- objectIDs: [ $(event.currentTarget).parents('.moderationQueueEntry:eq(0)').data('queueID') ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- $('.moderationList .new').each(function(index, element) {
- var $element = $(element);
- if (WCF.inArray($element.data('queueID'), data.objectIDs)) {
- // remove new class
- $element.removeClass('new');
-
- // remove event
- $element.find('.columnAvatar').off('dblclick');
- }
- });
- }
-});
-
-/**
- * Marks all moderation queue entries as read.
- */
-WCF.Moderation.Queue.MarkAllAsRead = Class.extend({
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * Initializes the WCF.Moderation.Queue.MarkAllAsRead class.
- */
- init: function() {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
+ /**
+ * Initializes the mark as read for queue entries.
+ */
+ init: function () {
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ $(document).on('dblclick', '.moderationList .new .columnAvatar', $.proxy(this._dblclick, this));
+ },
- $('.markAllAsReadButton').click($.proxy(this._click, this));
- },
-
- /**
- * Handles clicks.
- *
- * @param object event
- */
- _click: function(event) {
- event.preventDefault();
+ /**
+ * Handles double clicks on avatar.
+ *
+ * @param object event
+ */
+ _dblclick: function (event) {
+ this._proxy.setOption('data', {
+ actionName: 'markAsRead',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
+ objectIDs: [$(event.currentTarget).parents('.moderationQueueEntry:eq(0)').data('queueID')]
+ });
+ this._proxy.sendRequest();
+ },
- this._proxy.setOption('data', {
- actionName: 'markAllAsRead',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
- });
- this._proxy.sendRequest();
- },
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ $('.moderationList .new').each(function (index, element) {
+ var $element = $(element);
+ if (WCF.inArray($element.data('queueID'), data.objectIDs)) {
+ // remove new class
+ $element.removeClass('new');
+
+ // remove event
+ $element.find('.columnAvatar').off('dblclick');
+ }
+ });
+ }
+ });
/**
- * Marks all queue entries as read.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
+ * Marks all moderation queue entries as read.
*/
- _success: function(data, textStatus, jqXHR) {
- // update dropdown
- var dropdown = WCF.Dropdown.Interactive.Handler.getDropdown('outstandingModeration');
- if (dropdown) {
- dropdown.getLinkList().find('.interactiveDropdownItemMarkAllAsRead').remove();
- dropdown.getItemList().find('.interactiveDropdownItemMarkAsRead').remove();
- }
+ WCF.Moderation.Queue.MarkAllAsRead = Class.extend({
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
- // remove badge in userpanel
- $('#outstandingModeration .badgeUpdate').remove();
+ /**
+ * Initializes the WCF.Moderation.Queue.MarkAllAsRead class.
+ */
+ init: function () {
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ $('.markAllAsReadButton').click($.proxy(this._click, this));
+ },
- // fix moderation list
- var $moderationList = $('.moderationList');
- $moderationList.find('.new').removeClass('new');
- $moderationList.find('.columnAvatar').off('dblclick');
- }
-});
+ /**
+ * Handles clicks.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ event.preventDefault();
+
+ this._proxy.setOption('data', {
+ actionName: 'markAllAsRead',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Marks all queue entries as read.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ // update dropdown
+ var dropdown = WCF.Dropdown.Interactive.Handler.getDropdown('outstandingModeration');
+ if (dropdown) {
+ dropdown.getLinkList().find('.interactiveDropdownItemMarkAllAsRead').remove();
+ dropdown.getItemList().find('.interactiveDropdownItemMarkAsRead').remove();
+ }
+
+ // remove badge in userpanel
+ $('#outstandingModeration .badgeUpdate').remove();
+
+ // fix moderation list
+ var $moderationList = $('.moderationList');
+ $moderationList.find('.new').removeClass('new');
+ $moderationList.find('.columnAvatar').off('dblclick');
+ }
+ });
+}
+else {
+ WCF.Moderation.Queue.MarkAsRead = Class.extend({
+ _proxy: {},
+ init: function() {},
+ _dblclick: function() {},
+ _success: function() {}
+ });
+
+ WCF.Moderation.Queue.MarkAllAsRead = Class.extend({
+ _proxy: {},
+ init: function() {},
+ _click: function() {},
+ _success: function() {}
+ });
+}
/**
* Namespace for activation related classes.
*/
WCF.Moderation.Activation = { };
-/**
- * Manages disabled content within moderation.
- *
- * @see WCF.Moderation.Management
- */
-WCF.Moderation.Activation.Management = WCF.Moderation.Management.extend({
- /**
- * @see WCF.Moderation.Management.init()
- */
- init: function(queueID, redirectURL) {
- this._buttonSelector = '#enableContent, #removeContent';
- this._className = 'wcf\\data\\moderation\\queue\\ModerationQueueActivationAction';
-
- this._super(queueID, redirectURL, 'wcf.moderation.activation.{actionName}.confirmMessage');
- }
-});
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Manages disabled content within moderation.
+ *
+ * @see WCF.Moderation.Management
+ */
+ WCF.Moderation.Activation.Management = WCF.Moderation.Management.extend({
+ /**
+ * @see WCF.Moderation.Management.init()
+ */
+ init: function (queueID, redirectURL) {
+ this._buttonSelector = '#enableContent, #removeContent';
+ this._className = 'wcf\\data\\moderation\\queue\\ModerationQueueActivationAction';
+
+ this._super(queueID, redirectURL, 'wcf.moderation.activation.{actionName}.confirmMessage');
+ }
+ });
+}
+else {
+ WCF.Moderation.Activation.Management = WCF.Moderation.Management.extend({
+ init: function() {},
+ _buttonSelector: "",
+ _className: "",
+ _confirmationTemplate: {},
+ _dialog: {},
+ _languageItem: "",
+ _proxy: {},
+ _queueID: 0,
+ _redirectURL: "",
+ _click: function() {},
+ _clickAssignedUser: function() {},
+ _success: function() {},
+ _failure: function() {},
+ _assignUser: function() {}
+ });
+}
/**
* Namespace for report related classes.
}
});
-/**
- * Manages reported content within moderation.
- *
- * @see WCF.Moderation.Management
- */
-WCF.Moderation.Report.Management = WCF.Moderation.Management.extend({
- /**
- * @see WCF.Moderation.Management.init()
- */
- init: function(queueID, redirectURL) {
- this._buttonSelector = '#removeContent, #removeReport';
- this._className = 'wcf\\data\\moderation\\queue\\ModerationQueueReportAction';
-
- this._super(queueID, redirectURL, 'wcf.moderation.report.{actionName}.confirmMessage');
-
- this._confirmationTemplate.removeContent = $('<div class="section"><dl><dt><label for="message">' + WCF.Language.get('wcf.moderation.report.removeContent.reason') + '</label></dt><dd><textarea name="message" id="message" cols="40" rows="3" /></dd></dl></div>');
- }
-});
-
-/**
- * User Panel implementation for moderation queues.
- *
- * @see WCF.User.Panel.Abstract
- */
-WCF.User.Panel.Moderation = WCF.User.Panel.Abstract.extend({
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Manages reported content within moderation.
+ *
+ * @see WCF.Moderation.Management
+ */
+ WCF.Moderation.Report.Management = WCF.Moderation.Management.extend({
+ /**
+ * @see WCF.Moderation.Management.init()
+ */
+ init: function (queueID, redirectURL) {
+ this._buttonSelector = '#removeContent, #removeReport';
+ this._className = 'wcf\\data\\moderation\\queue\\ModerationQueueReportAction';
+
+ this._super(queueID, redirectURL, 'wcf.moderation.report.{actionName}.confirmMessage');
+
+ this._confirmationTemplate.removeContent = $('<div class="section"><dl><dt><label for="message">' + WCF.Language.get('wcf.moderation.report.removeContent.reason') + '</label></dt><dd><textarea name="message" id="message" cols="40" rows="3" /></dd></dl></div>');
+ }
+ });
+
/**
- * @see WCF.User.Panel.Abstract.init()
+ * User Panel implementation for moderation queues.
+ *
+ * @see WCF.User.Panel.Abstract
*/
- init: function(options) {
- options.enableMarkAsRead = true;
+ WCF.User.Panel.Moderation = WCF.User.Panel.Abstract.extend({
+ /**
+ * @see WCF.User.Panel.Abstract.init()
+ */
+ init: function (options) {
+ options.enableMarkAsRead = true;
+
+ this._super($('#outstandingModeration'), 'outstandingModeration', options);
+
+ require(['EventHandler'], (function (EventHandler) {
+ EventHandler.add('com.woltlab.wcf.UserMenuMobile', 'more', (function (data) {
+ if (data.identifier === 'com.woltlab.wcf.moderation') {
+ this.toggle();
+ }
+ }).bind(this));
+ }).bind(this));
+ },
- this._super($('#outstandingModeration'), 'outstandingModeration', options);
+ /**
+ * @see WCF.User.Panel.Abstract._initDropdown()
+ */
+ _initDropdown: function () {
+ var $dropdown = this._super();
+
+ $('<li><a href="' + this._options.deletedContentLink + '" title="' + this._options.deletedContent + '" class="jsTooltip"><span class="icon icon24 fa-trash-o" /></a></li>').appendTo($dropdown.getLinkList());
+
+ return $dropdown;
+ },
- require(['EventHandler'], (function(EventHandler) {
- EventHandler.add('com.woltlab.wcf.UserMenuMobile', 'more', (function(data) {
- if (data.identifier === 'com.woltlab.wcf.moderation') {
- this.toggle();
- }
- }).bind(this));
- }).bind(this));
- },
-
- /**
- * @see WCF.User.Panel.Abstract._initDropdown()
- */
- _initDropdown: function() {
- var $dropdown = this._super();
+ /**
+ * @see WCF.User.Panel.Abstract._load()
+ */
+ _load: function () {
+ this._proxy.setOption('data', {
+ actionName: 'getOutstandingQueues',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
+ });
+ this._proxy.sendRequest();
+ },
- $('<li><a href="' + this._options.deletedContentLink + '" title="' + this._options.deletedContent + '" class="jsTooltip"><span class="icon icon24 fa-trash-o" /></a></li>').appendTo($dropdown.getLinkList());
+ /**
+ * @see WCF.User.Panel.Abstract._markAsRead()
+ */
+ _markAsRead: function (event, objectID) {
+ this._proxy.setOption('data', {
+ actionName: 'markAsRead',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
+ objectIDs: [objectID]
+ });
+ this._proxy.sendRequest();
+ },
- return $dropdown;
- },
-
- /**
- * @see WCF.User.Panel.Abstract._load()
- */
- _load: function() {
- this._proxy.setOption('data', {
- actionName: 'getOutstandingQueues',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract._markAsRead()
- */
- _markAsRead: function(event, objectID) {
- this._proxy.setOption('data', {
- actionName: 'markAsRead',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction',
- objectIDs: [ objectID ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract._markAllAsRead()
- */
- _markAllAsRead: function(event) {
- this._proxy.setOption('data', {
- actionName: 'markAllAsRead',
- className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract.resetItems()
- */
- resetItems: function() {
- this._super();
+ /**
+ * @see WCF.User.Panel.Abstract._markAllAsRead()
+ */
+ _markAllAsRead: function (event) {
+ this._proxy.setOption('data', {
+ actionName: 'markAllAsRead',
+ className: 'wcf\\data\\moderation\\queue\\ModerationQueueAction'
+ });
+ this._proxy.sendRequest();
+ },
- this._loadData = true;
- }
-});
+ /**
+ * @see WCF.User.Panel.Abstract.resetItems()
+ */
+ resetItems: function () {
+ this._super();
+
+ this._loadData = true;
+ }
+ });
+}
+else {
+ WCF.Moderation.Report.Management = WCF.Moderation.Management.extend({
+ init: function() {},
+ _buttonSelector: "",
+ _className: "",
+ _confirmationTemplate: {},
+ _dialog: {},
+ _languageItem: "",
+ _proxy: {},
+ _queueID: 0,
+ _redirectURL: "",
+ _click: function() {},
+ _clickAssignedUser: function() {},
+ _success: function() {},
+ _failure: function() {},
+ _assignUser: function() {}
+ });
+
+ WCF.User.Panel.Moderation = WCF.User.Panel.Abstract.extend({
+ init: function() {},
+ _initDropdown: function() {},
+ _load: function() {},
+ _markAsRead: function() {},
+ _markAllAsRead: function() {},
+ resetItems: function() {},
+ _badge: {},
+ _dropdown: {},
+ _identifier: "",
+ _loadData: true,
+ _markAllAsReadLink: {},
+ _options: {},
+ _proxy: {},
+ _triggerElement: {},
+ toggle: function() {},
+ _dblClick: function() {},
+ _success: function() {},
+ updateBadge: function() {}
+ });
+}
*/
WCF.Poll = { };
-/**
- * Handles poll option management.
- *
- * @param string containerID
- * @param array<object> optionList
- */
-WCF.Poll.Management = Class.extend({
- /**
- * container object
- * @var jQuery
- */
- _container: null,
-
- /**
- * number of options
- * @var int
- */
- _count: 0,
-
- /**
- * editor element id
- * @var string
- */
- _editorId: '',
-
- /**
- * maximum allowed number of options
- * @var int
- */
- _maxOptions: 0,
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes the WCF.Poll.Management class.
- *
- * @param {string} containerID
- * @param {Object[]} optionList
- * @param {int} maxOptions
- * @param {string} editorId
+ * Handles poll option management.
+ *
+ * @param string containerID
+ * @param array<object> optionList
*/
- init: function(containerID, optionList, maxOptions, editorId) {
- this._count = 0;
- this._maxOptions = maxOptions || -1;
- this._container = $('#' + containerID).children('ol:eq(0)');
- if (!this._container.length) {
- console.debug("[WCF.Poll.Management] Invalid container id given, aborting.");
- return;
- }
-
- optionList = optionList || [];
- this._createOptionList(optionList);
-
- // bind event listener
- if (editorId) {
- this._editorId = editorId;
+ WCF.Poll.Management = Class.extend({
+ /**
+ * container object
+ * @var jQuery
+ */
+ _container: null,
+
+ /**
+ * number of options
+ * @var int
+ */
+ _count: 0,
+
+ /**
+ * editor element id
+ * @var string
+ */
+ _editorId: '',
+
+ /**
+ * maximum allowed number of options
+ * @var int
+ */
+ _maxOptions: 0,
+
+ /**
+ * Initializes the WCF.Poll.Management class.
+ *
+ * @param {string} containerID
+ * @param {Object[]} optionList
+ * @param {int} maxOptions
+ * @param {string} editorId
+ */
+ init: function (containerID, optionList, maxOptions, editorId) {
+ this._count = 0;
+ this._maxOptions = maxOptions || -1;
+ this._container = $('#' + containerID).children('ol:eq(0)');
+ if (!this._container.length) {
+ console.debug("[WCF.Poll.Management] Invalid container id given, aborting.");
+ return;
+ }
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'reset_' + editorId, this._reset.bind(this));
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'submit_' + editorId, this._submit.bind(this));
- WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'validate_' + editorId, this._validate.bind(this));
- }
- else {
- this._container.closest('form').submit($.proxy(this._submit, this));
- }
-
- // init sorting
- require(['WoltLabSuite/Core/Ui/Sortable/List'], function (UiSortableList) {
- new UiSortableList({
- containerId: containerID,
- options: {
- toleranceElement: '> div'
- }
+ optionList = optionList || [];
+ this._createOptionList(optionList);
+
+ // bind event listener
+ if (editorId) {
+ this._editorId = editorId;
+
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'reset_' + editorId, this._reset.bind(this));
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'submit_' + editorId, this._submit.bind(this));
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'validate_' + editorId, this._validate.bind(this));
+ }
+ else {
+ this._container.closest('form').submit($.proxy(this._submit, this));
+ }
+
+ // init sorting
+ require(['WoltLabSuite/Core/Ui/Sortable/List'], function (UiSortableList) {
+ new UiSortableList({
+ containerId: containerID,
+ options: {
+ toleranceElement: '> div'
+ }
+ });
});
- });
- },
-
- /**
- * Creates the option list on init.
- *
- * @param array<object> optionList
- */
- _createOptionList: function(optionList) {
- for (var $i = 0, $length = optionList.length; $i < $length; $i++) {
- var $option = optionList[$i];
- this._createOption($option.optionValue, $option.optionID);
- }
-
- // add empty option
- this._createOption();
- },
-
- /**
- * Creates a new option element.
- *
- * @param string optionValue
- * @param integer optionID
- * @param jQuery insertAfter
- */
- _createOption: function(optionValue, optionID, insertAfter) {
- optionValue = optionValue || '';
- optionID = parseInt(optionID) || 0;
- insertAfter = insertAfter || null;
-
- var $listItem = $('<li class="sortableNode" />').data('optionID', optionID);
- if (insertAfter === null) {
- $listItem.appendTo(this._container);
- }
- else {
- $listItem.insertAfter(insertAfter);
- }
-
- // insert buttons
- var $container = $('<div class="pollOptionInput" />').appendTo($listItem);
- $('<span class="icon icon16 fa-arrows sortableNodeHandle" />').appendTo($container);
- $('<span class="icon icon16 fa-plus jsTooltip jsAddOption pointer" title="' + WCF.Language.get('wcf.poll.button.addOption') + '" />').click($.proxy(this._addOption, this)).appendTo($container);
- $('<span class="icon icon16 fa-times jsTooltip jsDeleteOption pointer" title="' + WCF.Language.get('wcf.poll.button.removeOption') + '" />').click($.proxy(this._removeOption, this)).appendTo($container);
-
- // insert input field
- var $input = $('<input type="text" value="' + optionValue + '" maxlength="255" />').keydown($.proxy(this._keyDown, this)).appendTo($container);
- $input.click(function() {
- // work-around for some weird focus issue on iOS/Android
- if (document.activeElement !== this) {
- this.focus();
+ },
+
+ /**
+ * Creates the option list on init.
+ *
+ * @param array<object> optionList
+ */
+ _createOptionList: function (optionList) {
+ for (var $i = 0, $length = optionList.length; $i < $length; $i++) {
+ var $option = optionList[$i];
+ this._createOption($option.optionValue, $option.optionID);
}
- });
-
- if (insertAfter !== null) {
- $input.focus();
- }
-
- WCF.DOMNodeInsertedHandler.execute();
-
- this._count++;
- if (this._count === this._maxOptions) {
- this._container.find('span.jsAddOption').removeClass('pointer').addClass('disabled');
- }
- },
-
- /**
- * Handles key down events for option input field.
- *
- * @param object event
- */
- _keyDown: function(event) {
- // ignore every key except for [Enter]
- if (event.which !== 13) {
- return;
- }
-
- $(event.currentTarget).parent().children('.jsAddOption').trigger('click');
-
- event.preventDefault();
- },
-
- /**
- * Adds a new option after current one.
- *
- * @param object event
- */
- _addOption: function(event) {
- if (this._count === this._maxOptions) {
- return false;
- }
-
- var $listItem = $(event.currentTarget).closest('li', this._container[0]);
-
- this._createOption(undefined, undefined, $listItem);
- },
-
- /**
- * Removes an option.
- *
- * @param object event
- */
- _removeOption: function(event) {
- $(event.currentTarget).closest('li', this._container[0]).remove();
-
- this._count--;
- this._container.find('span.jsAddOption').addClass('pointer').removeClass('disabled');
-
- if (this._container.children('li').length == 0) {
+
+ // add empty option
this._createOption();
- }
- },
-
- /**
- * Inserts hidden input elements storing the option values.
- *
- * @param {(Event|Object)} event
- */
- _submit: function(event) {
- var $options = [];
- this._container.children('li').each(function (index, listItem) {
- var $listItem = $(listItem);
- var $optionValue = $.trim($listItem.find('input').val());
+ },
+
+ /**
+ * Creates a new option element.
+ *
+ * @param string optionValue
+ * @param integer optionID
+ * @param jQuery insertAfter
+ */
+ _createOption: function (optionValue, optionID, insertAfter) {
+ optionValue = optionValue || '';
+ optionID = parseInt(optionID) || 0;
+ insertAfter = insertAfter || null;
- // ignore empty values
- if ($optionValue != '') {
- $options.push($listItem.data('optionID') + '_' + $optionValue);
+ var $listItem = $('<li class="sortableNode" />').data('optionID', optionID);
+ if (insertAfter === null) {
+ $listItem.appendTo(this._container);
}
- });
-
- if (typeof event.originalEvent === 'object' && event.originalEvent instanceof Event) {
- // create hidden input fields
- if ($options.length) {
- var $formSubmit = this._container.parents('form').find('.formSubmit');
+ else {
+ $listItem.insertAfter(insertAfter);
+ }
+
+ // insert buttons
+ var $container = $('<div class="pollOptionInput" />').appendTo($listItem);
+ $('<span class="icon icon16 fa-arrows sortableNodeHandle" />').appendTo($container);
+ $('<span class="icon icon16 fa-plus jsTooltip jsAddOption pointer" title="' + WCF.Language.get('wcf.poll.button.addOption') + '" />').click($.proxy(this._addOption, this)).appendTo($container);
+ $('<span class="icon icon16 fa-times jsTooltip jsDeleteOption pointer" title="' + WCF.Language.get('wcf.poll.button.removeOption') + '" />').click($.proxy(this._removeOption, this)).appendTo($container);
+
+ // insert input field
+ var $input = $('<input type="text" value="' + optionValue + '" maxlength="255" />').keydown($.proxy(this._keyDown, this)).appendTo($container);
+ $input.click(function () {
+ // work-around for some weird focus issue on iOS/Android
+ if (document.activeElement !== this) {
+ this.focus();
+ }
+ });
+
+ if (insertAfter !== null) {
+ $input.focus();
+ }
+
+ WCF.DOMNodeInsertedHandler.execute();
+
+ this._count++;
+ if (this._count === this._maxOptions) {
+ this._container.find('span.jsAddOption').removeClass('pointer').addClass('disabled');
+ }
+ },
+
+ /**
+ * Handles key down events for option input field.
+ *
+ * @param object event
+ */
+ _keyDown: function (event) {
+ // ignore every key except for [Enter]
+ if (event.which !== 13) {
+ return;
+ }
+
+ $(event.currentTarget).parent().children('.jsAddOption').trigger('click');
+
+ event.preventDefault();
+ },
+
+ /**
+ * Adds a new option after current one.
+ *
+ * @param object event
+ */
+ _addOption: function (event) {
+ if (this._count === this._maxOptions) {
+ return false;
+ }
+
+ var $listItem = $(event.currentTarget).closest('li', this._container[0]);
+
+ this._createOption(undefined, undefined, $listItem);
+ },
+
+ /**
+ * Removes an option.
+ *
+ * @param object event
+ */
+ _removeOption: function (event) {
+ $(event.currentTarget).closest('li', this._container[0]).remove();
+
+ this._count--;
+ this._container.find('span.jsAddOption').addClass('pointer').removeClass('disabled');
+
+ if (this._container.children('li').length == 0) {
+ this._createOption();
+ }
+ },
+
+ /**
+ * Inserts hidden input elements storing the option values.
+ *
+ * @param {(Event|Object)} event
+ */
+ _submit: function (event) {
+ var $options = [];
+ this._container.children('li').each(function (index, listItem) {
+ var $listItem = $(listItem);
+ var $optionValue = $.trim($listItem.find('input').val());
- for (var $i = 0, $length = $options.length; $i < $length; $i++) {
- $('<input type="hidden" name="pollOptions[' + $i + ']">').val($options[$i]).appendTo($formSubmit);
+ // ignore empty values
+ if ($optionValue != '') {
+ $options.push($listItem.data('optionID') + '_' + $optionValue);
+ }
+ });
+
+ if (typeof event.originalEvent === 'object' && event.originalEvent instanceof Event) {
+ // create hidden input fields
+ if ($options.length) {
+ var $formSubmit = this._container.parents('form').find('.formSubmit');
+
+ for (var $i = 0, $length = $options.length; $i < $length; $i++) {
+ $('<input type="hidden" name="pollOptions[' + $i + ']">').val($options[$i]).appendTo($formSubmit);
+ }
}
}
- }
- else {
- event.poll = { pollOptions: $options };
+ else {
+ event.poll = {pollOptions: $options};
+
+ // get form input fields
+ var parentContainer = this._container.parents('.messageTabMenuContent:eq(0)');
+ parentContainer.find('input').each(function (index, input) {
+ if (input.name) {
+ if (input.type !== 'checkbox' || input.checked) {
+ event.poll[input.name] = input.value;
+ }
+ }
+ });
+ }
+ },
+
+ /**
+ * Resets the poll option form.
+ *
+ * @private
+ */
+ _reset: function () {
+ // reset options
+ /** @type Element */
+ var container = this._container[0];
+ while (container.childElementCount > 1) {
+ container.removeChild(container.children[1]);
+ }
- // get form input fields
+ elBySel('input', container.children[0]).value = '';
+
+ // reset input fields and checkboxes
var parentContainer = this._container.parents('.messageTabMenuContent:eq(0)');
- parentContainer.find('input').each(function(index, input) {
+ parentContainer.find('input').each(function (index, input) {
if (input.name) {
- if (input.type !== 'checkbox' || input.checked) {
- event.poll[input.name] = input.value;
+ if (input.type === 'checkbox') {
+ input.checked = false;
+ }
+ else if (input.type === 'text') {
+ input.value = '';
+ }
+ else if (input.type === 'number') {
+ input.value = input.min;
}
}
});
- }
- },
-
- /**
- * Resets the poll option form.
- *
- * @private
- */
- _reset: function() {
- // reset options
- /** @type Element */
- var container = this._container[0];
- while (container.childElementCount > 1) {
- container.removeChild(container.children[1]);
- }
-
- elBySel('input', container.children[0]).value = '';
-
- // reset input fields and checkboxes
- var parentContainer = this._container.parents('.messageTabMenuContent:eq(0)');
- parentContainer.find('input').each(function(index, input) {
- if (input.name) {
- if (input.type === 'checkbox') {
- input.checked = false;
- }
- else if (input.type === 'text') {
- input.value = '';
- }
- else if (input.type === 'number') {
- input.value = input.min;
- }
- }
- });
-
- // reset date picker
- require(['WoltLabSuite/Core/Date/Picker'], (function(UiDatePicker) {
- UiDatePicker.clear('pollEndTime_' + this._editorId);
- }).bind(this));
- },
-
- _validate: function(data) {
- var question = elById('pollQuestion_' + this._editorId);
- if (question.value.trim() === '') {
- // no question provided, ignore
- return;
- }
-
- // get options
- var count = 0;
- elBySelAll('li input[type="text"]', this._container[0], function(input) {
- if (input.value.trim() !== '') {
- count++;
+
+ // reset date picker
+ require(['WoltLabSuite/Core/Date/Picker'], (function (UiDatePicker) {
+ UiDatePicker.clear('pollEndTime_' + this._editorId);
+ }).bind(this));
+ },
+
+ _validate: function (data) {
+ var question = elById('pollQuestion_' + this._editorId);
+ if (question.value.trim() === '') {
+ // no question provided, ignore
+ return;
}
- });
-
- if (count === 0) {
- data.api.throwError(this._container[0], WCF.Language.get('wcf.global.form.error.empty'));
- data.valid = false;
- }
- else {
- var pollMaxVotes = elById('pollMaxVotes_' + this._editorId);
- var num = ~~pollMaxVotes.value;
- if (num && num > count) {
- data.api.throwError(pollMaxVotes, WCF.Language.get('wcf.poll.maxVotes.error.invalid'));
+
+ // get options
+ var count = 0;
+ elBySelAll('li input[type="text"]', this._container[0], function (input) {
+ if (input.value.trim() !== '') {
+ count++;
+ }
+ });
+
+ if (count === 0) {
+ data.api.throwError(this._container[0], WCF.Language.get('wcf.global.form.error.empty'));
data.valid = false;
}
+ else {
+ var pollMaxVotes = elById('pollMaxVotes_' + this._editorId);
+ var num = ~~pollMaxVotes.value;
+ if (num && num > count) {
+ data.api.throwError(pollMaxVotes, WCF.Language.get('wcf.poll.maxVotes.error.invalid'));
+ data.valid = false;
+ }
+ }
}
- }
-});
+ });
+}
+else {
+ WCF.Poll.Management = Class.extend({
+ _container: {},
+ _count: 0,
+ _editorId: "",
+ _maxOptions: 0,
+ init: function() {},
+ _createOptionList: function() {},
+ _createOption: function() {},
+ _keyDown: function() {},
+ _addOption: function() {},
+ _removeOption: function() {},
+ _submit: function() {},
+ _reset: function() {},
+ _validate: function() {}
+ });
+}
/**
* Manages poll voting and result display.
*/
WCF.User.Panel = { };
-/**
- * Abstract implementation for user panel items providing an interactive dropdown.
- *
- * @param jQuery triggerElement
- * @param string identifier
- * @param object options
- */
-WCF.User.Panel.Abstract = Class.extend({
- /**
- * counter badge
- * @var jQuery
- */
- _badge: null,
-
- /**
- * interactive dropdown instance
- * @var WCF.Dropdown.Interactive.Instance
- */
- _dropdown: null,
-
- /**
- * dropdown identifier
- * @var string
- */
- _identifier: '',
-
- /**
- * true if data should be loaded using an AJAX request
- * @var boolean
- */
- _loadData: true,
-
- /**
- * header icon to mark all items belonging to this user panel item as read
- * @var jQuery
- */
- _markAllAsReadLink: null,
-
- /**
- * list of options required to dropdown initialization and UI features
- * @var object
- */
- _options: { },
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * trigger element
- * @var jQuery
- */
- _triggerElement: null,
-
- /**
- * Initializes the WCF.User.Panel.Abstract class.
- *
- * @param jQuery triggerElement
- * @param string identifier
- * @param object options
- */
- init: function(triggerElement, identifier, options) {
- this._dropdown = null;
- this._loadData = true;
- this._identifier = identifier;
- this._triggerElement = triggerElement;
- this._options = options;
-
- this._proxy = new WCF.Action.Proxy({
- showLoadingOverlay: false,
- success: $.proxy(this._success, this)
- });
-
- this._triggerElement.click($.proxy(this.toggle, this));
-
- if (this._options.showAllLink) {
- this._triggerElement.dblclick($.proxy(this._dblClick, this));
- }
-
- if (this._options.staticDropdown === true) {
- this._loadData = false;
- }
- else {
- var $badge = this._triggerElement.find('span.badge');
- if ($badge.length) {
- this._badge = $badge;
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Abstract implementation for user panel items providing an interactive dropdown.
+ *
+ * @param jQuery triggerElement
+ * @param string identifier
+ * @param object options
+ */
+ WCF.User.Panel.Abstract = Class.extend({
+ /**
+ * counter badge
+ * @var jQuery
+ */
+ _badge: null,
+
+ /**
+ * interactive dropdown instance
+ * @var WCF.Dropdown.Interactive.Instance
+ */
+ _dropdown: null,
+
+ /**
+ * dropdown identifier
+ * @var string
+ */
+ _identifier: '',
+
+ /**
+ * true if data should be loaded using an AJAX request
+ * @var boolean
+ */
+ _loadData: true,
+
+ /**
+ * header icon to mark all items belonging to this user panel item as read
+ * @var jQuery
+ */
+ _markAllAsReadLink: null,
+
+ /**
+ * list of options required to dropdown initialization and UI features
+ * @var object
+ */
+ _options: {},
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * trigger element
+ * @var jQuery
+ */
+ _triggerElement: null,
+
+ /**
+ * Initializes the WCF.User.Panel.Abstract class.
+ *
+ * @param jQuery triggerElement
+ * @param string identifier
+ * @param object options
+ */
+ init: function (triggerElement, identifier, options) {
+ this._dropdown = null;
+ this._loadData = true;
+ this._identifier = identifier;
+ this._triggerElement = triggerElement;
+ this._options = options;
+
+ this._proxy = new WCF.Action.Proxy({
+ showLoadingOverlay: false,
+ success: $.proxy(this._success, this)
+ });
+
+ this._triggerElement.click($.proxy(this.toggle, this));
+
+ if (this._options.showAllLink) {
+ this._triggerElement.dblclick($.proxy(this._dblClick, this));
}
- }
- },
-
- /**
- * Toggles the interactive dropdown.
- *
- * @param {Event?} event
- * @return {boolean}
- */
- toggle: function(event) {
- if (event instanceof Event) {
- event.preventDefault();
- }
-
- if (this._dropdown === null) {
- this._dropdown = this._initDropdown();
- }
-
- if (this._dropdown.toggle()) {
- if (!this._loadData) {
- // check if there are outstanding items but there are no outstanding ones in the current list
- if (this._badge !== null) {
- var $count = parseInt(this._badge.text()) || 0;
- if ($count && !this._dropdown.getItemList().children('.interactiveDropdownItemOutstanding').length) {
- this._loadData = true;
- }
+
+ if (this._options.staticDropdown === true) {
+ this._loadData = false;
+ }
+ else {
+ var $badge = this._triggerElement.find('span.badge');
+ if ($badge.length) {
+ this._badge = $badge;
}
}
+ },
+
+ /**
+ * Toggles the interactive dropdown.
+ *
+ * @param {Event?} event
+ * @return {boolean}
+ */
+ toggle: function (event) {
+ if (event instanceof Event) {
+ event.preventDefault();
+ }
- if (this._loadData) {
- this._loadData = false;
- this._load();
+ if (this._dropdown === null) {
+ this._dropdown = this._initDropdown();
}
- }
-
- return false;
- },
-
- /**
- * Forward to original URL by double clicking the trigger element.
- *
- * @param object event
- * @return boolean
- */
- _dblClick: function(event) {
- event.preventDefault();
-
- window.location = this._options.showAllLink;
-
- return false;
- },
-
- /**
- * Initializes the dropdown on first usage.
- *
- * @return WCF.Dropdown.Interactive.Instance
- */
- _initDropdown: function() {
- var $dropdown = WCF.Dropdown.Interactive.Handler.create(this._triggerElement, this._identifier, this._options);
- $('<li class="loading"><span class="icon icon24 fa-spinner" /> <span>' + WCF.Language.get('wcf.global.loading') + '</span></li>').appendTo($dropdown.getItemList());
-
- return $dropdown;
- },
-
- /**
- * Loads item list data via AJAX.
- */
- _load: function() {
- // override this in your own implementation to fetch display data
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- */
- _success: function(data) {
- if (data.returnValues.template !== undefined) {
- var $itemList = this._dropdown.getItemList().empty();
- $(data.returnValues.template).appendTo($itemList);
- if (!$itemList.children().length) {
- $('<li class="noItems">' + this._options.noItems + '</li>').appendTo($itemList);
+ if (this._dropdown.toggle()) {
+ if (!this._loadData) {
+ // check if there are outstanding items but there are no outstanding ones in the current list
+ if (this._badge !== null) {
+ var $count = parseInt(this._badge.text()) || 0;
+ if ($count && !this._dropdown.getItemList().children('.interactiveDropdownItemOutstanding').length) {
+ this._loadData = true;
+ }
+ }
+ }
+
+ if (this._loadData) {
+ this._loadData = false;
+ this._load();
+ }
}
- if (this._options.enableMarkAsRead) {
- var $outstandingItems = this._dropdown.getItemList().children('.interactiveDropdownItemOutstanding');
- if (this._markAllAsReadLink === null && $outstandingItems.length && this._options.markAllAsReadConfirmMessage) {
- var $button = this._markAllAsReadLink = $('<li class="interactiveDropdownItemMarkAllAsRead"><a href="#" title="' + WCF.Language.get('wcf.user.panel.markAllAsRead') + '" class="jsTooltip"><span class="icon icon24 fa-check" /></a></li>').appendTo(this._dropdown.getLinkList());
- $button.click((function(event) {
- this._dropdown.close();
-
- WCF.System.Confirmation.show(this._options.markAllAsReadConfirmMessage, (function(action) {
- if (action === 'confirm') {
- this._markAllAsRead();
- }
+ return false;
+ },
+
+ /**
+ * Forward to original URL by double clicking the trigger element.
+ *
+ * @param object event
+ * @return boolean
+ */
+ _dblClick: function (event) {
+ event.preventDefault();
+
+ window.location = this._options.showAllLink;
+
+ return false;
+ },
+
+ /**
+ * Initializes the dropdown on first usage.
+ *
+ * @return WCF.Dropdown.Interactive.Instance
+ */
+ _initDropdown: function () {
+ var $dropdown = WCF.Dropdown.Interactive.Handler.create(this._triggerElement, this._identifier, this._options);
+ $('<li class="loading"><span class="icon icon24 fa-spinner" /> <span>' + WCF.Language.get('wcf.global.loading') + '</span></li>').appendTo($dropdown.getItemList());
+
+ return $dropdown;
+ },
+
+ /**
+ * Loads item list data via AJAX.
+ */
+ _load: function () {
+ // override this in your own implementation to fetch display data
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ */
+ _success: function (data) {
+ if (data.returnValues.template !== undefined) {
+ var $itemList = this._dropdown.getItemList().empty();
+ $(data.returnValues.template).appendTo($itemList);
+
+ if (!$itemList.children().length) {
+ $('<li class="noItems">' + this._options.noItems + '</li>').appendTo($itemList);
+ }
+
+ if (this._options.enableMarkAsRead) {
+ var $outstandingItems = this._dropdown.getItemList().children('.interactiveDropdownItemOutstanding');
+ if (this._markAllAsReadLink === null && $outstandingItems.length && this._options.markAllAsReadConfirmMessage) {
+ var $button = this._markAllAsReadLink = $('<li class="interactiveDropdownItemMarkAllAsRead"><a href="#" title="' + WCF.Language.get('wcf.user.panel.markAllAsRead') + '" class="jsTooltip"><span class="icon icon24 fa-check" /></a></li>').appendTo(this._dropdown.getLinkList());
+ $button.click((function (event) {
+ this._dropdown.close();
+
+ WCF.System.Confirmation.show(this._options.markAllAsReadConfirmMessage, (function (action) {
+ if (action === 'confirm') {
+ this._markAllAsRead();
+ }
+ }).bind(this));
+
+ return false;
}).bind(this));
+ }
+
+ $outstandingItems.each((function (index, item) {
+ var $item = $(item).addClass('interactiveDropdownItemOutstandingIcon');
+ var $objectID = $item.data('objectID');
- return false;
+ var $button = $('<div class="interactiveDropdownItemMarkAsRead"><a href="#" title="' + WCF.Language.get('wcf.user.panel.markAsRead') + '" class="jsTooltip"><span class="icon icon16 fa-check" /></a></div>').appendTo($item);
+ $button.click((function (event) {
+ this._markAsRead(event, $objectID);
+
+ return false;
+ }).bind(this));
}).bind(this));
}
- $outstandingItems.each((function(index, item) {
- var $item = $(item).addClass('interactiveDropdownItemOutstandingIcon');
- var $objectID = $item.data('objectID');
+ this._dropdown.getItemList().children().each(function (index, item) {
+ var $item = $(item);
+ var $link = $item.data('link');
- var $button = $('<div class="interactiveDropdownItemMarkAsRead"><a href="#" title="' + WCF.Language.get('wcf.user.panel.markAsRead') + '" class="jsTooltip"><span class="icon icon16 fa-check" /></a></div>').appendTo($item);
- $button.click((function(event) {
- this._markAsRead(event, $objectID);
+ if ($link) {
+ if ($.browser.msie) {
+ $item.click(function (event) {
+ if (event.target.tagName !== 'A') {
+ window.location = $link;
+
+ return false;
+ }
+ });
+ }
+ else {
+ $item.addClass('interactiveDropdownItemShadow');
+ $('<a href="' + $link + '" class="interactiveDropdownItemShadowLink" />').appendTo($item);
+ }
- return false;
- }).bind(this));
- }).bind(this));
+ if ($item.data('linkReplaceAll')) {
+ $item.find('> .box48 a:not(.userLink)').prop('href', $link);
+ }
+ }
+ });
+
+ this._dropdown.rebuildScrollbar();
}
- this._dropdown.getItemList().children().each(function(index, item) {
- var $item = $(item);
- var $link = $item.data('link');
-
- if ($link) {
- if ($.browser.msie) {
- $item.click(function(event) {
- if (event.target.tagName !== 'A') {
- window.location = $link;
-
- return false;
- }
- });
- }
- else {
- $item.addClass('interactiveDropdownItemShadow');
- $('<a href="' + $link + '" class="interactiveDropdownItemShadowLink" />').appendTo($item);
- }
-
- if ($item.data('linkReplaceAll')) {
- $item.find('> .box48 a:not(.userLink)').prop('href', $link);
+ if (data.returnValues.totalCount !== undefined) {
+ this.updateBadge(data.returnValues.totalCount);
+ }
+
+ if (this._options.enableMarkAsRead) {
+ if (data.returnValues.markAsRead) {
+ var $item = this._dropdown.getItemList().children('li[data-object-id=' + data.returnValues.markAsRead + ']');
+ if ($item.length) {
+ $item.removeClass('interactiveDropdownItemOutstanding').data('isRead', true);
+ $item.children('.interactiveDropdownItemMarkAsRead').remove();
}
}
- });
+ else if (data.returnValues.markAllAsRead) {
+ this.resetItems();
+ this.updateBadge(0);
+ }
+ }
+ },
+
+ /**
+ * Marks an item as read.
+ *
+ * @param object event
+ * @param integer objectID
+ */
+ _markAsRead: function (event, objectID) {
+ // override this in your own implementation to mark an item as read
+ },
+
+ /**
+ * Marks all items as read.
+ */
+ _markAllAsRead: function () {
+ // override this in your own implementation to mark all items as read
+ },
+
+ /**
+ * Updates the badge's count or removes it if count reaches zero. Passing a negative number is undefined.
+ *
+ * @param integer count
+ */
+ updateBadge: function (count) {
+ count = parseInt(count) || 0;
- this._dropdown.rebuildScrollbar();
- }
-
- if (data.returnValues.totalCount !== undefined) {
- this.updateBadge(data.returnValues.totalCount);
- }
-
- if (this._options.enableMarkAsRead) {
- if (data.returnValues.markAsRead) {
- var $item = this._dropdown.getItemList().children('li[data-object-id=' + data.returnValues.markAsRead + ']');
- if ($item.length) {
- $item.removeClass('interactiveDropdownItemOutstanding').data('isRead', true);
- $item.children('.interactiveDropdownItemMarkAsRead').remove();
+ if (count) {
+ if (this._badge === null) {
+ this._badge = $('<span class="badge badgeUpdate" />').appendTo(this._triggerElement.children('a'));
+ this._badge.before(' ');
}
+
+ this._badge.text(count);
}
- else if (data.returnValues.markAllAsRead) {
- this.resetItems();
- this.updateBadge(0);
+ else if (this._badge !== null) {
+ this._badge.remove();
+ this._badge = null;
}
- }
- },
-
- /**
- * Marks an item as read.
- *
- * @param object event
- * @param integer objectID
- */
- _markAsRead: function(event, objectID) {
- // override this in your own implementation to mark an item as read
- },
-
- /**
- * Marks all items as read.
- */
- _markAllAsRead: function() {
- // override this in your own implementation to mark all items as read
- },
-
- /**
- * Updates the badge's count or removes it if count reaches zero. Passing a negative number is undefined.
- *
- * @param integer count
- */
- updateBadge: function(count) {
- count = parseInt(count) || 0;
-
- if (count) {
- if (this._badge === null) {
- this._badge = $('<span class="badge badgeUpdate" />').appendTo(this._triggerElement.children('a'));
- this._badge.before(' ');
+
+ if (this._options.enableMarkAsRead) {
+ if (!count && this._markAllAsReadLink !== null) {
+ this._markAllAsReadLink.remove();
+ this._markAllAsReadLink = null;
+ }
}
- this._badge.text(count);
- }
- else if (this._badge !== null) {
- this._badge.remove();
- this._badge = null;
- }
-
- if (this._options.enableMarkAsRead) {
- if (!count && this._markAllAsReadLink !== null) {
- this._markAllAsReadLink.remove();
- this._markAllAsReadLink = null;
+ WCF.System.Event.fireEvent('com.woltlab.wcf.userMenu', 'updateBadge', {
+ count: count,
+ identifier: this._identifier
+ });
+ },
+
+ /**
+ * Resets the dropdown's inner item list.
+ */
+ resetItems: function () {
+ // this method could be called from outside, but the dropdown was never
+ // toggled and thus never initialized
+ if (this._dropdown !== null) {
+ this._dropdown.resetItems();
}
}
-
- WCF.System.Event.fireEvent('com.woltlab.wcf.userMenu', 'updateBadge', {
- count: count,
- identifier: this._identifier
- });
- },
-
- /**
- * Resets the dropdown's inner item list.
- */
- resetItems: function() {
- // this method could be called from outside, but the dropdown was never
- // toggled and thus never initialized
- if (this._dropdown !== null) {
- this._dropdown.resetItems();
- }
- }
-});
-
-/**
- * User Panel implementation for user notifications.
- *
- * @see WCF.User.Panel.Abstract
- */
-WCF.User.Panel.Notification = WCF.User.Panel.Abstract.extend({
- /**
- * favico instance
- * @var Favico
- */
- _favico: null,
+ });
/**
- * @see WCF.User.Panel.Abstract.init()
+ * User Panel implementation for user notifications.
+ *
+ * @see WCF.User.Panel.Abstract
*/
- init: function(options) {
- options.enableMarkAsRead = true;
+ WCF.User.Panel.Notification = WCF.User.Panel.Abstract.extend({
+ /**
+ * favico instance
+ * @var Favico
+ */
+ _favico: null,
- this._super($('#userNotifications'), 'userNotifications', options);
-
- try {
- this._favico = new Favico({
- animation: 'none',
- type: 'circle'
- });
+ /**
+ * @see WCF.User.Panel.Abstract.init()
+ */
+ init: function (options) {
+ options.enableMarkAsRead = true;
- if (this._badge !== null) {
- var $count = parseInt(this._badge.text()) || 0;
- this._favico.badge($count);
- }
- }
- catch (e) {
- console.debug("[WCF.User.Panel.Notification] Failed to initialized Favico: " + e.message);
- }
-
- WCF.System.PushNotification.addCallback('userNotificationCount', $.proxy(this.updateUserNotificationCount, this));
-
- require(['EventHandler'], (function(EventHandler) {
- EventHandler.add('com.woltlab.wcf.UserMenuMobile', 'more', (function(data) {
- if (data.identifier === 'com.woltlab.wcf.notifications') {
- this.toggle();
+ this._super($('#userNotifications'), 'userNotifications', options);
+
+ try {
+ this._favico = new Favico({
+ animation: 'none',
+ type: 'circle'
+ });
+
+ if (this._badge !== null) {
+ var $count = parseInt(this._badge.text()) || 0;
+ this._favico.badge($count);
}
+ }
+ catch (e) {
+ console.debug("[WCF.User.Panel.Notification] Failed to initialized Favico: " + e.message);
+ }
+
+ WCF.System.PushNotification.addCallback('userNotificationCount', $.proxy(this.updateUserNotificationCount, this));
+
+ require(['EventHandler'], (function (EventHandler) {
+ EventHandler.add('com.woltlab.wcf.UserMenuMobile', 'more', (function (data) {
+ if (data.identifier === 'com.woltlab.wcf.notifications') {
+ this.toggle();
+ }
+ }).bind(this));
}).bind(this));
- }).bind(this));
- },
-
- /**
- * @see WCF.User.Panel.Abstract._initDropdown()
- */
- _initDropdown: function() {
- var $dropdown = this._super();
+ },
- $('<li><a href="' + this._options.settingsLink + '" title="' + WCF.Language.get('wcf.user.panel.settings') + '" class="jsTooltip"><span class="icon icon24 fa-cog" /></a></li>').appendTo($dropdown.getLinkList());
+ /**
+ * @see WCF.User.Panel.Abstract._initDropdown()
+ */
+ _initDropdown: function () {
+ var $dropdown = this._super();
+
+ $('<li><a href="' + this._options.settingsLink + '" title="' + WCF.Language.get('wcf.user.panel.settings') + '" class="jsTooltip"><span class="icon icon24 fa-cog" /></a></li>').appendTo($dropdown.getLinkList());
+
+ return $dropdown;
+ },
- return $dropdown;
- },
-
- /**
- * @see WCF.User.Panel.Abstract._load()
- */
- _load: function() {
- this._proxy.setOption('data', {
- actionName: 'getOutstandingNotifications',
- className: 'wcf\\data\\user\\notification\\UserNotificationAction'
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract._markAsRead()
- */
- _markAsRead: function(event, objectID) {
- this._proxy.setOption('data', {
- actionName: 'markAsConfirmed',
- className: 'wcf\\data\\user\\notification\\UserNotificationAction',
- objectIDs: [ objectID ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract._markAllAsRead()
- */
- _markAllAsRead: function(event) {
- this._proxy.setOption('data', {
- actionName: 'markAllAsConfirmed',
- className: 'wcf\\data\\user\\notification\\UserNotificationAction'
- });
- this._proxy.sendRequest();
- },
-
- /**
- * @see WCF.User.Panel.Abstract.resetItems()
- */
- resetItems: function() {
- this._super();
+ /**
+ * @see WCF.User.Panel.Abstract._load()
+ */
+ _load: function () {
+ this._proxy.setOption('data', {
+ actionName: 'getOutstandingNotifications',
+ className: 'wcf\\data\\user\\notification\\UserNotificationAction'
+ });
+ this._proxy.sendRequest();
+ },
- if (this._markAllAsReadLink) {
- this._markAllAsReadLink.remove();
- this._markAllAsReadLink = null;
- }
- },
-
- /**
- * @see WCF.User.Panel.Abstract.updateBadge()
- */
- updateBadge: function(count) {
- count = parseInt(count) || 0;
+ /**
+ * @see WCF.User.Panel.Abstract._markAsRead()
+ */
+ _markAsRead: function (event, objectID) {
+ this._proxy.setOption('data', {
+ actionName: 'markAsConfirmed',
+ className: 'wcf\\data\\user\\notification\\UserNotificationAction',
+ objectIDs: [objectID]
+ });
+ this._proxy.sendRequest();
+ },
- // update data attribute
- $('#userNotifications').attr('data-count', count);
+ /**
+ * @see WCF.User.Panel.Abstract._markAllAsRead()
+ */
+ _markAllAsRead: function (event) {
+ this._proxy.setOption('data', {
+ actionName: 'markAllAsConfirmed',
+ className: 'wcf\\data\\user\\notification\\UserNotificationAction'
+ });
+ this._proxy.sendRequest();
+ },
- if (this._favico !== null) {
- this._favico.badge(count);
- }
+ /**
+ * @see WCF.User.Panel.Abstract.resetItems()
+ */
+ resetItems: function () {
+ this._super();
+
+ if (this._markAllAsReadLink) {
+ this._markAllAsReadLink.remove();
+ this._markAllAsReadLink = null;
+ }
+ },
- this._super(count);
- },
+ /**
+ * @see WCF.User.Panel.Abstract.updateBadge()
+ */
+ updateBadge: function (count) {
+ count = parseInt(count) || 0;
+
+ // update data attribute
+ $('#userNotifications').attr('data-count', count);
+
+ if (this._favico !== null) {
+ this._favico.badge(count);
+ }
+
+ this._super(count);
+ },
+
+ /**
+ * Updates the badge counter and resets the dropdown's item list.
+ *
+ * @param integer count
+ */
+ updateUserNotificationCount: function (count) {
+ if (this._dropdown !== null) {
+ this._dropdown.resetItems();
+ }
+
+ this.updateBadge(count);
+ }
+ });
/**
- * Updates the badge counter and resets the dropdown's item list.
- *
- * @param integer count
+ * User Panel implementation for user menu dropdown.
+ *
+ * @see WCF.User.Panel.Abstract
*/
- updateUserNotificationCount: function(count) {
- if (this._dropdown !== null) {
- this._dropdown.resetItems();
+ WCF.User.Panel.UserMenu = WCF.User.Panel.Abstract.extend({
+ /**
+ * @see WCF.User.Panel.Abstract.init()
+ */
+ init: function () {
+ this._super($('#userMenu'), 'userMenu', {
+ pointerOffset: '13px',
+ staticDropdown: true
+ });
}
-
- this.updateBadge(count);
- }
-});
-
-/**
- * User Panel implementation for user menu dropdown.
- *
- * @see WCF.User.Panel.Abstract
- */
-WCF.User.Panel.UserMenu = WCF.User.Panel.Abstract.extend({
- /**
- * @see WCF.User.Panel.Abstract.init()
- */
- init: function() {
- this._super($('#userMenu'), 'userMenu', {
- pointerOffset: '13px',
- staticDropdown: true
- });
- }
-});
+ });
+}
+else {
+ WCF.User.Panel.Abstract = Class.extend({
+ _badge: {},
+ _dropdown: {},
+ _identifier: "",
+ _loadData: true,
+ _markAllAsReadLink: {},
+ _options: {},
+ _proxy: {},
+ _triggerElement: {},
+ init: function() {},
+ toggle: function() {},
+ _dblClick: function() {},
+ _initDropdown: function() {},
+ _load: function() {},
+ _success: function() {},
+ _markAsRead: function() {},
+ _markAllAsRead: function() {},
+ updateBadge: function() {},
+ resetItems: function() {}
+ });
+
+ WCF.User.Panel.Notification = WCF.User.Panel.Abstract.extend({
+ _favico: {},
+ init: function() {},
+ _initDropdown: function() {},
+ _load: function() {},
+ _markAsRead: function() {},
+ _markAllAsRead: function() {},
+ resetItems: function() {},
+ updateBadge: function() {},
+ updateUserNotificationCount: function() {},
+ _badge: {},
+ _dropdown: {},
+ _identifier: "",
+ _loadData: true,
+ _markAllAsReadLink: {},
+ _options: {},
+ _proxy: {},
+ _triggerElement: {},
+ toggle: function() {},
+ _dblClick: function() {},
+ _success: function() {}
+ });
+
+ WCF.User.Panel.UserMenu = WCF.User.Panel.Abstract.extend({
+ init: function() {},
+ _badge: {},
+ _dropdown: {},
+ _identifier: "",
+ _loadData: true,
+ _markAllAsReadLink: {},
+ _options: {},
+ _proxy: {},
+ _triggerElement: {},
+ toggle: function() {},
+ _dblClick: function() {},
+ _initDropdown: function() {},
+ _load: function() {},
+ _success: function() {},
+ _markAsRead: function() {},
+ _markAllAsRead: function() {},
+ updateBadge: function() {},
+ resetItems: function() {}
+ });
+}
/**
* Quick login box
}
});
-/**
- * User profile inline editor.
- *
- * @param integer userID
- * @param boolean editOnInit
- */
-WCF.User.Profile.Editor = Class.extend({
- /**
- * current action
- * @var string
- */
- _actionName: '',
-
- _active: false,
-
- /**
- * list of interface buttons
- * @var object
- */
- _buttons: { },
-
- /**
- * cached tab content
- * @var string
- */
- _cachedTemplate: '',
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * tab object
- * @var jQuery
- */
- _tab: null,
-
- /**
- * target user id
- * @var integer
- */
- _userID: 0,
-
- /**
- * Initializes the WCF.User.Profile.Editor object.
- *
- * @param integer userID
- * @param boolean editOnInit
- */
- init: function(userID, editOnInit) {
- this._actionName = '';
- this._active = false;
- this._cachedTemplate = '';
- this._tab = $('#about');
- this._userID = userID;
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- this._initButtons();
-
- // begin editing on page load
- if (editOnInit) {
- this._beginEdit();
- }
- },
-
- /**
- * Initializes interface buttons.
- */
- _initButtons: function() {
- // create buttons
- this._buttons = {
- beginEdit: $('.jsButtonEditProfile:eq(0)').click(this._beginEdit.bind(this))
- };
- },
-
- /**
- * Begins editing.
- *
- * @param {Event?} event event object
- */
- _beginEdit: function(event) {
- if (event) event.preventDefault();
-
- if (this._active) return;
- this._active = true;
-
- this._actionName = 'beginEdit';
- this._buttons.beginEdit.parent().addClass('active');
- $('#profileContent').wcfTabs('select', 'about');
-
- // load form
- this._proxy.setOption('data', {
- actionName: 'beginEdit',
- className: 'wcf\\data\\user\\UserProfileAction',
- objectIDs: [ this._userID ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Saves input values.
- */
- _save: function() {
- this._actionName = 'save';
-
- // collect values
- var $regExp = /values\[([a-zA-Z0-9._-]+)\]/;
- var $values = { };
- this._tab.find('input, textarea, select').each(function(index, element) {
- var $element = $(element);
- var $value = null;
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * User profile inline editor.
+ *
+ * @param integer userID
+ * @param boolean editOnInit
+ */
+ WCF.User.Profile.Editor = Class.extend({
+ /**
+ * current action
+ * @var string
+ */
+ _actionName: '',
+
+ _active: false,
+
+ /**
+ * list of interface buttons
+ * @var object
+ */
+ _buttons: {},
+
+ /**
+ * cached tab content
+ * @var string
+ */
+ _cachedTemplate: '',
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * tab object
+ * @var jQuery
+ */
+ _tab: null,
+
+ /**
+ * target user id
+ * @var integer
+ */
+ _userID: 0,
+
+ /**
+ * Initializes the WCF.User.Profile.Editor object.
+ *
+ * @param integer userID
+ * @param boolean editOnInit
+ */
+ init: function (userID, editOnInit) {
+ this._actionName = '';
+ this._active = false;
+ this._cachedTemplate = '';
+ this._tab = $('#about');
+ this._userID = userID;
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
- switch ($element.getTagName()) {
- case 'input':
- var $type = $element.attr('type');
-
- if (($type === 'radio' || $type === 'checkbox') && !$element.prop('checked')) {
- return;
- }
- break;
-
- case 'textarea':
- if ($element.data('redactor')) {
- $value = $element.redactor('code.get');
- }
- break;
+ this._initButtons();
+
+ // begin editing on page load
+ if (editOnInit) {
+ this._beginEdit();
}
+ },
+
+ /**
+ * Initializes interface buttons.
+ */
+ _initButtons: function () {
+ // create buttons
+ this._buttons = {
+ beginEdit: $('.jsButtonEditProfile:eq(0)').click(this._beginEdit.bind(this))
+ };
+ },
+
+ /**
+ * Begins editing.
+ *
+ * @param {Event?} event event object
+ */
+ _beginEdit: function (event) {
+ if (event) event.preventDefault();
+
+ if (this._active) return;
+ this._active = true;
+
+ this._actionName = 'beginEdit';
+ this._buttons.beginEdit.parent().addClass('active');
+ $('#profileContent').wcfTabs('select', 'about');
+
+ // load form
+ this._proxy.setOption('data', {
+ actionName: 'beginEdit',
+ className: 'wcf\\data\\user\\UserProfileAction',
+ objectIDs: [this._userID]
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Saves input values.
+ */
+ _save: function () {
+ this._actionName = 'save';
- var $name = $element.attr('name');
- if ($regExp.test($name)) {
- var $fieldName = RegExp.$1;
- if ($value === null) $value = $element.val();
+ // collect values
+ var $regExp = /values\[([a-zA-Z0-9._-]+)\]/;
+ var $values = {};
+ this._tab.find('input, textarea, select').each(function (index, element) {
+ var $element = $(element);
+ var $value = null;
- // check for checkboxes
- if ($element.attr('type') === 'checkbox' && /\[\]$/.test($name)) {
- if (!Array.isArray($values[$fieldName])) {
- $values[$fieldName] = [];
- }
+ switch ($element.getTagName()) {
+ case 'input':
+ var $type = $element.attr('type');
+
+ if (($type === 'radio' || $type === 'checkbox') && !$element.prop('checked')) {
+ return;
+ }
+ break;
- $values[$fieldName].push($value);
- }
- else {
- $values[$fieldName] = $value;
- }
- }
- });
-
- this._proxy.setOption('data', {
- actionName: 'save',
- className: 'wcf\\data\\user\\UserProfileAction',
- objectIDs: [ this._userID ],
- parameters: {
- values: $values
- }
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Restores back to default view.
- */
- _restore: function() {
- this._actionName = 'restore';
- this._active = false;
- this._buttons.beginEdit.parent().removeClass('active');
-
- this._destroyEditor();
-
- this._tab.html(this._cachedTemplate).children().css({ height: 'auto' });
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- switch (this._actionName) {
- case 'beginEdit':
- this._prepareEdit(data);
- break;
-
- case 'save':
- // save was successful, show parsed template
- if (data.returnValues.success) {
- this._cachedTemplate = data.returnValues.template;
- this._restore();
+ case 'textarea':
+ if ($element.data('redactor')) {
+ $value = $element.redactor('code.get');
+ }
+ break;
}
- else {
- this._prepareEdit(data, true);
+
+ var $name = $element.attr('name');
+ if ($regExp.test($name)) {
+ var $fieldName = RegExp.$1;
+ if ($value === null) $value = $element.val();
+
+ // check for checkboxes
+ if ($element.attr('type') === 'checkbox' && /\[\]$/.test($name)) {
+ if (!Array.isArray($values[$fieldName])) {
+ $values[$fieldName] = [];
+ }
+
+ $values[$fieldName].push($value);
+ }
+ else {
+ $values[$fieldName] = $value;
+ }
}
- break;
- }
- },
-
- /**
- * Prepares editing mode.
- *
- * @param object data
- * @param boolean disableCache
- */
- _prepareEdit: function(data, disableCache) {
- this._destroyEditor();
-
- // update template
- var self = this;
- this._tab.html(function(index, oldHTML) {
- if (disableCache !== true) {
- self._cachedTemplate = oldHTML;
- }
+ });
- return data.returnValues.template;
- });
-
- // block autocomplete
- this._tab.find('input[type=text]').attr('autocomplete', 'off');
-
- // bind event listener
- this._tab.find('.formSubmit > button[data-type=save]').click($.proxy(this._save, this));
- this._tab.find('.formSubmit > button[data-type=restore]').click($.proxy(this._restore, this));
- this._tab.find('input').keyup(function(event) {
- if (event.which === $.ui.keyCode.ENTER) {
- self._save();
+ this._proxy.setOption('data', {
+ actionName: 'save',
+ className: 'wcf\\data\\user\\UserProfileAction',
+ objectIDs: [this._userID],
+ parameters: {
+ values: $values
+ }
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Restores back to default view.
+ */
+ _restore: function () {
+ this._actionName = 'restore';
+ this._active = false;
+ this._buttons.beginEdit.parent().removeClass('active');
+
+ this._destroyEditor();
+
+ this._tab.html(this._cachedTemplate).children().css({height: 'auto'});
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ switch (this._actionName) {
+ case 'beginEdit':
+ this._prepareEdit(data);
+ break;
- event.preventDefault();
- return false;
- }
- });
- },
-
- /**
- * Destroys all editor instances within current tab.
- */
- _destroyEditor: function() {
- // destroy all editor instances
- this._tab.find('textarea').each(function(index, container) {
- var $container = $(container);
- if ($container.data('redactor')) {
- $container.redactor('core.destroy');
+ case 'save':
+ // save was successful, show parsed template
+ if (data.returnValues.success) {
+ this._cachedTemplate = data.returnValues.template;
+ this._restore();
+ }
+ else {
+ this._prepareEdit(data, true);
+ }
+ break;
}
- });
- }
-});
+ },
+
+ /**
+ * Prepares editing mode.
+ *
+ * @param object data
+ * @param boolean disableCache
+ */
+ _prepareEdit: function (data, disableCache) {
+ this._destroyEditor();
+
+ // update template
+ var self = this;
+ this._tab.html(function (index, oldHTML) {
+ if (disableCache !== true) {
+ self._cachedTemplate = oldHTML;
+ }
+
+ return data.returnValues.template;
+ });
+
+ // block autocomplete
+ this._tab.find('input[type=text]').attr('autocomplete', 'off');
+
+ // bind event listener
+ this._tab.find('.formSubmit > button[data-type=save]').click($.proxy(this._save, this));
+ this._tab.find('.formSubmit > button[data-type=restore]').click($.proxy(this._restore, this));
+ this._tab.find('input').keyup(function (event) {
+ if (event.which === $.ui.keyCode.ENTER) {
+ self._save();
+
+ event.preventDefault();
+ return false;
+ }
+ });
+ },
+
+ /**
+ * Destroys all editor instances within current tab.
+ */
+ _destroyEditor: function () {
+ // destroy all editor instances
+ this._tab.find('textarea').each(function (index, container) {
+ var $container = $(container);
+ if ($container.data('redactor')) {
+ $container.redactor('core.destroy');
+ }
+ });
+ }
+ });
+}
+else {
+ WCF.User.Profile.Editor = Class.extend({
+ _actionName: "",
+ _active: false,
+ _buttons: {},
+ _cachedTemplate: "",
+ _proxy: {},
+ _tab: {},
+ _userID: 0,
+ init: function() {},
+ _initButtons: function() {},
+ _beginEdit: function() {},
+ _save: function() {},
+ _restore: function() {},
+ _success: function() {},
+ _prepareEdit: function() {},
+ _destroyEditor: function() {}
+ });
+}
/**
* Namespace for registration functions.
*/
WCF.Notification = { };
-/**
- * Handles the notification list.
- */
-WCF.Notification.List = Class.extend({
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes the WCF.Notification.List object.
+ * Handles the notification list.
*/
- init: function() {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
+ WCF.Notification.List = Class.extend({
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
- // handle 'mark all as confirmed' buttons
- $('.contentHeaderNavigation .jsMarkAllAsConfirmed').click(function() {
- WCF.System.Confirmation.show(WCF.Language.get('wcf.user.notification.markAllAsConfirmed.confirmMessage'), function(action) {
- if (action === 'confirm') {
- new WCF.Action.Proxy({
- autoSend: true,
- data: {
- actionName: 'markAllAsConfirmed',
- className: 'wcf\\data\\user\\notification\\UserNotificationAction'
- },
- success: function() { window.location.reload(); }
+ /**
+ * Initializes the WCF.Notification.List object.
+ */
+ init: function () {
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ // handle 'mark all as confirmed' buttons
+ $('.contentHeaderNavigation .jsMarkAllAsConfirmed').click(function () {
+ WCF.System.Confirmation.show(WCF.Language.get('wcf.user.notification.markAllAsConfirmed.confirmMessage'), function (action) {
+ if (action === 'confirm') {
+ new WCF.Action.Proxy({
+ autoSend: true,
+ data: {
+ actionName: 'markAllAsConfirmed',
+ className: 'wcf\\data\\user\\notification\\UserNotificationAction'
+ },
+ success: function () {
+ window.location.reload();
+ }
+ });
+ }
+ });
+ });
+
+ // handle regular items
+ this._convertList();
+ },
+
+ /**
+ * Converts the notification item list to be in sync with the notification dropdown.
+ */
+ _convertList: function () {
+ $('.userNotificationItemList > .notificationItem').each((function (index, item) {
+ var $item = $(item);
+
+ if (!$item.data('isRead')) {
+ $item.find('a:not(.userLink)').prop('href', $item.data('link'));
+
+ var $markAsConfirmed = $('<a href="#" class="icon icon24 fa-check notificationItemMarkAsConfirmed jsTooltip" title="' + WCF.Language.get('wcf.user.notification.markAsConfirmed') + '" />').appendTo($item);
+ $markAsConfirmed.click($.proxy(this._markAsConfirmed, this));
+ }
+
+ // work-around for legacy notifications
+ if (!$item.find('a:not(.notificationItemMarkAsConfirmed)').length) {
+ $item.find('.details > p:eq(0)').html(function (index, oldHTML) {
+ return '<a href="' + $item.data('link') + '">' + oldHTML + '</a>';
});
}
+ }).bind(this));
+
+ WCF.DOMNodeInsertedHandler.execute();
+ },
+
+ /**
+ * Marks a single notification as confirmed.
+ *
+ * @param object event
+ */
+ _markAsConfirmed: function (event) {
+ event.preventDefault();
+
+ var $notificationID = $(event.currentTarget).parents('.notificationItem:eq(0)').data('objectID');
+
+ this._proxy.setOption('data', {
+ actionName: 'markAsConfirmed',
+ className: 'wcf\\data\\user\\notification\\UserNotificationAction',
+ objectIDs: [$notificationID]
});
- });
-
- // handle regular items
- this._convertList();
- },
-
- /**
- * Converts the notification item list to be in sync with the notification dropdown.
- */
- _convertList: function() {
- $('.userNotificationItemList > .notificationItem').each((function(index, item) {
- var $item = $(item);
+ this._proxy.sendRequest();
- if (!$item.data('isRead')) {
- $item.find('a:not(.userLink)').prop('href', $item.data('link'));
-
- var $markAsConfirmed = $('<a href="#" class="icon icon24 fa-check notificationItemMarkAsConfirmed jsTooltip" title="' + WCF.Language.get('wcf.user.notification.markAsConfirmed') + '" />').appendTo($item);
- $markAsConfirmed.click($.proxy(this._markAsConfirmed, this));
- }
+ return false;
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ var $item = $('.userNotificationItemList > .notificationItem[data-object-id=' + data.returnValues.markAsRead + ']');
- // work-around for legacy notifications
- if (!$item.find('a:not(.notificationItemMarkAsConfirmed)').length) {
- $item.find('.details > p:eq(0)').html(function(index, oldHTML) {
- return '<a href="' + $item.data('link') + '">' + oldHTML + '</a>';
- });
+ $item.data('isRead', true);
+ $item.find('.newContentBadge').remove();
+ $item.find('.notificationItemMarkAsConfirmed').remove();
+ $item.removeClass('notificationUnconfirmed');
+ }
+ });
+
+ /**
+ * Signature preview.
+ *
+ * @see WCF.Message.Preview
+ */
+ WCF.User.SignaturePreview = WCF.Message.Preview.extend({
+ /**
+ * @see WCF.Message.Preview._handleResponse()
+ */
+ _handleResponse: function (data) {
+ // get preview container
+ var $preview = $('#previewContainer');
+ if (!$preview.length) {
+ $preview = $('<section class="section" id="previewContainer"><h2 class="sectionTitle">' + WCF.Language.get('wcf.global.preview') + '</h2><div class="htmlContent"></div></section>').insertBefore($('#signatureContainer')).wcfFadeIn();
}
- }).bind(this));
-
- WCF.DOMNodeInsertedHandler.execute();
- },
-
- /**
- * Marks a single notification as confirmed.
- *
- * @param object event
- */
- _markAsConfirmed: function(event) {
- event.preventDefault();
-
- var $notificationID = $(event.currentTarget).parents('.notificationItem:eq(0)').data('objectID');
-
- this._proxy.setOption('data', {
- actionName: 'markAsConfirmed',
- className: 'wcf\\data\\user\\notification\\UserNotificationAction',
- objectIDs: [ $notificationID ]
- });
- this._proxy.sendRequest();
-
- return false;
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- var $item = $('.userNotificationItemList > .notificationItem[data-object-id=' + data.returnValues.markAsRead + ']');
-
- $item.data('isRead', true);
- $item.find('.newContentBadge').remove();
- $item.find('.notificationItemMarkAsConfirmed').remove();
- $item.removeClass('notificationUnconfirmed');
- }
-});
-
-/**
- * Signature preview.
- *
- * @see WCF.Message.Preview
- */
-WCF.User.SignaturePreview = WCF.Message.Preview.extend({
- /**
- * @see WCF.Message.Preview._handleResponse()
- */
- _handleResponse: function(data) {
- // get preview container
- var $preview = $('#previewContainer');
- if (!$preview.length) {
- $preview = $('<section class="section" id="previewContainer"><h2 class="sectionTitle">' + WCF.Language.get('wcf.global.preview') + '</h2><div class="htmlContent"></div></section>').insertBefore($('#signatureContainer')).wcfFadeIn();
- }
-
- $preview.children('div').first().html(data.returnValues.message);
- }
-});
+
+ $preview.children('div').first().html(data.returnValues.message);
+ }
+ });
+}
+else {
+ WCF.Notification.List = Class.extend({
+ _proxy: {},
+ init: function() {},
+ _convertList: function() {},
+ _markAsConfirmed: function() {},
+ _success: function() {}
+ });
+
+ WCF.User.SignaturePreview = WCF.Message.Preview.extend({
+ _handleResponse: function() {},
+ _className: "",
+ _messageFieldID: "",
+ _messageField: {},
+ _proxy: {},
+ _previewButton: {},
+ _previewButtonLabel: "",
+ init: function() {},
+ _click: function() {},
+ _getParameters: function() {},
+ _getMessage: function() {},
+ _success: function() {},
+ _failure: function() {}
+ });
+}
/**
* Loads recent activity events once the user scrolls to the very bottom.
*/
WCF.User.Action = {};
-/**
- * Handles user follow and unfollow links.
- */
-WCF.User.Action.Follow = Class.extend({
- /**
- * list with elements containing follow and unfollow buttons
- * @var array
- */
- _containerList: null,
-
- /**
- * CSS selector for follow buttons
- * @var string
- */
- _followButtonSelector: '.jsFollowButton',
-
- /**
- * id of the user that is currently being followed/unfollowed
- * @var integer
- */
- _userID: 0,
-
- /**
- * Initializes new WCF.User.Action.Follow object.
- *
- * @param array containerList
- * @param string followButtonSelector
- */
- init: function(containerList, followButtonSelector) {
- if (!containerList.length) {
- return;
- }
- this._containerList = containerList;
-
- if (followButtonSelector) {
- this._followButtonSelector = followButtonSelector;
- }
-
- // initialize proxy
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- // bind event listeners
- this._containerList.each($.proxy(function(index, container) {
- $(container).find(this._followButtonSelector).click($.proxy(this._click, this));
- }, this));
- },
-
- /**
- * Handles a click on a follow or unfollow button.
- *
- * @param object event
- */
- _click: function(event) {
- event.preventDefault();
- var link = $(event.target);
- if (!link.is('a')) {
- link = link.closest('a');
- }
- this._userID = link.data('objectID');
-
- this._proxy.setOption('data', {
- 'actionName': link.data('following') ? 'unfollow' : 'follow',
- 'className': 'wcf\\data\\user\\follow\\UserFollowAction',
- 'parameters': {
- data: {
- userID: this._userID
- }
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Handles user follow and unfollow links.
+ */
+ WCF.User.Action.Follow = Class.extend({
+ /**
+ * list with elements containing follow and unfollow buttons
+ * @var array
+ */
+ _containerList: null,
+
+ /**
+ * CSS selector for follow buttons
+ * @var string
+ */
+ _followButtonSelector: '.jsFollowButton',
+
+ /**
+ * id of the user that is currently being followed/unfollowed
+ * @var integer
+ */
+ _userID: 0,
+
+ /**
+ * Initializes new WCF.User.Action.Follow object.
+ *
+ * @param array containerList
+ * @param string followButtonSelector
+ */
+ init: function (containerList, followButtonSelector) {
+ if (!containerList.length) {
+ return;
}
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles the successful (un)following of a user.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- this._containerList.each($.proxy(function(index, container) {
- var button = $(container).find(this._followButtonSelector).get(0);
+ this._containerList = containerList;
- if (button && $(button).data('objectID') == this._userID) {
- button = $(button);
-
- // toogle icon title
- if (data.returnValues.following) {
- button.attr('data-tooltip', WCF.Language.get('wcf.user.button.unfollow')).children('.icon').removeClass('fa-plus').addClass('fa-minus');
- button.children('.invisible').text(WCF.Language.get('wcf.user.button.unfollow'));
- }
- else {
- button.attr('data-tooltip', WCF.Language.get('wcf.user.button.follow')).children('.icon').removeClass('fa-minus').addClass('fa-plus');
- button.children('.invisible').text(WCF.Language.get('wcf.user.button.follow'));
+ if (followButtonSelector) {
+ this._followButtonSelector = followButtonSelector;
+ }
+
+ // initialize proxy
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ // bind event listeners
+ this._containerList.each($.proxy(function (index, container) {
+ $(container).find(this._followButtonSelector).click($.proxy(this._click, this));
+ }, this));
+ },
+
+ /**
+ * Handles a click on a follow or unfollow button.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ event.preventDefault();
+ var link = $(event.target);
+ if (!link.is('a')) {
+ link = link.closest('a');
+ }
+ this._userID = link.data('objectID');
+
+ this._proxy.setOption('data', {
+ 'actionName': link.data('following') ? 'unfollow' : 'follow',
+ 'className': 'wcf\\data\\user\\follow\\UserFollowAction',
+ 'parameters': {
+ data: {
+ userID: this._userID
+ }
}
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Handles the successful (un)following of a user.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ this._containerList.each($.proxy(function (index, container) {
+ var button = $(container).find(this._followButtonSelector).get(0);
- button.data('following', data.returnValues.following);
-
- return false;
- }
- }, this));
-
- var $notification = new WCF.System.Notification();
- $notification.show();
- }
-});
-
-/**
- * Handles user ignore and unignore links.
- */
-WCF.User.Action.Ignore = Class.extend({
- /**
- * list with elements containing ignore and unignore buttons
- * @var array
- */
- _containerList: null,
-
- /**
- * CSS selector for ignore buttons
- * @var string
- */
- _ignoreButtonSelector: '.jsIgnoreButton',
-
- /**
- * id of the user that is currently being ignored/unignored
- * @var integer
- */
- _userID: 0,
-
- /**
- * Initializes new WCF.User.Action.Ignore object.
- *
- * @param array containerList
- * @param string ignoreButtonSelector
- */
- init: function(containerList, ignoreButtonSelector) {
- if (!containerList.length) {
- return;
- }
- this._containerList = containerList;
-
- if (ignoreButtonSelector) {
- this._ignoreButtonSelector = ignoreButtonSelector;
- }
-
- // initialize proxy
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- // bind event listeners
- this._containerList.each($.proxy(function(index, container) {
- $(container).find(this._ignoreButtonSelector).click($.proxy(this._click, this));
- }, this));
- },
-
- /**
- * Handles a click on a ignore or unignore button.
- *
- * @param object event
- */
- _click: function(event) {
- event.preventDefault();
- var link = $(event.target);
- if (!link.is('a')) {
- link = link.closest('a');
- }
- this._userID = link.data('objectID');
-
- this._proxy.setOption('data', {
- 'actionName': link.data('ignored') ? 'unignore' : 'ignore',
- 'className': 'wcf\\data\\user\\ignore\\UserIgnoreAction',
- 'parameters': {
- data: {
- userID: this._userID
+ if (button && $(button).data('objectID') == this._userID) {
+ button = $(button);
+
+ // toogle icon title
+ if (data.returnValues.following) {
+ button.attr('data-tooltip', WCF.Language.get('wcf.user.button.unfollow')).children('.icon').removeClass('fa-plus').addClass('fa-minus');
+ button.children('.invisible').text(WCF.Language.get('wcf.user.button.unfollow'));
+ }
+ else {
+ button.attr('data-tooltip', WCF.Language.get('wcf.user.button.follow')).children('.icon').removeClass('fa-minus').addClass('fa-plus');
+ button.children('.invisible').text(WCF.Language.get('wcf.user.button.follow'));
+ }
+
+ button.data('following', data.returnValues.following);
+
+ return false;
}
+ }, this));
+
+ var $notification = new WCF.System.Notification();
+ $notification.show();
+ }
+ });
+
+ /**
+ * Handles user ignore and unignore links.
+ */
+ WCF.User.Action.Ignore = Class.extend({
+ /**
+ * list with elements containing ignore and unignore buttons
+ * @var array
+ */
+ _containerList: null,
+
+ /**
+ * CSS selector for ignore buttons
+ * @var string
+ */
+ _ignoreButtonSelector: '.jsIgnoreButton',
+
+ /**
+ * id of the user that is currently being ignored/unignored
+ * @var integer
+ */
+ _userID: 0,
+
+ /**
+ * Initializes new WCF.User.Action.Ignore object.
+ *
+ * @param array containerList
+ * @param string ignoreButtonSelector
+ */
+ init: function (containerList, ignoreButtonSelector) {
+ if (!containerList.length) {
+ return;
+ }
+ this._containerList = containerList;
+
+ if (ignoreButtonSelector) {
+ this._ignoreButtonSelector = ignoreButtonSelector;
}
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles the successful (un)ignoring of a user.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- this._containerList.each($.proxy(function(index, container) {
- var button = $(container).find(this._ignoreButtonSelector).get(0);
- if (button && $(button).data('objectID') == this._userID) {
- button = $(button);
-
- // toogle icon title
- if (data.returnValues.isIgnoredUser) {
- button.attr('data-tooltip', WCF.Language.get('wcf.user.button.unignore')).children('.icon').removeClass('fa-ban').addClass('fa-circle-o');
- button.children('.invisible').text(WCF.Language.get('wcf.user.button.unignore'));
- }
- else {
- button.attr('data-tooltip', WCF.Language.get('wcf.user.button.ignore')).children('.icon').removeClass('fa-circle-o').addClass('fa-ban');
- button.children('.invisible').text(WCF.Language.get('wcf.user.button.ignore'));
+ // initialize proxy
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ // bind event listeners
+ this._containerList.each($.proxy(function (index, container) {
+ $(container).find(this._ignoreButtonSelector).click($.proxy(this._click, this));
+ }, this));
+ },
+
+ /**
+ * Handles a click on a ignore or unignore button.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ event.preventDefault();
+ var link = $(event.target);
+ if (!link.is('a')) {
+ link = link.closest('a');
+ }
+ this._userID = link.data('objectID');
+
+ this._proxy.setOption('data', {
+ 'actionName': link.data('ignored') ? 'unignore' : 'ignore',
+ 'className': 'wcf\\data\\user\\ignore\\UserIgnoreAction',
+ 'parameters': {
+ data: {
+ userID: this._userID
+ }
}
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Handles the successful (un)ignoring of a user.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ this._containerList.each($.proxy(function (index, container) {
+ var button = $(container).find(this._ignoreButtonSelector).get(0);
- button.data('ignored', data.returnValues.isIgnoredUser);
-
- return false;
- }
- }, this));
-
- var $notification = new WCF.System.Notification();
- $notification.show();
-
- // force rebuilding of popover cache
- var self = this;
- WCF.System.ObjectStore.invoke('WCF.User.ProfilePreview', function(profilePreview) {
- profilePreview.purge(self._userID);
- });
- }
-});
+ if (button && $(button).data('objectID') == this._userID) {
+ button = $(button);
+
+ // toogle icon title
+ if (data.returnValues.isIgnoredUser) {
+ button.attr('data-tooltip', WCF.Language.get('wcf.user.button.unignore')).children('.icon').removeClass('fa-ban').addClass('fa-circle-o');
+ button.children('.invisible').text(WCF.Language.get('wcf.user.button.unignore'));
+ }
+ else {
+ button.attr('data-tooltip', WCF.Language.get('wcf.user.button.ignore')).children('.icon').removeClass('fa-circle-o').addClass('fa-ban');
+ button.children('.invisible').text(WCF.Language.get('wcf.user.button.ignore'));
+ }
+
+ button.data('ignored', data.returnValues.isIgnoredUser);
+
+ return false;
+ }
+ }, this));
+
+ var $notification = new WCF.System.Notification();
+ $notification.show();
+
+ // force rebuilding of popover cache
+ var self = this;
+ WCF.System.ObjectStore.invoke('WCF.User.ProfilePreview', function (profilePreview) {
+ profilePreview.purge(self._userID);
+ });
+ }
+ });
+}
+else {
+ WCF.User.Action.Follow = Class.extend({
+ _containerList: {},
+ _followButtonSelector: "",
+ _userID: 0,
+ init: function() {},
+ _click: function() {},
+ _success: function() {}
+ });
+
+ WCF.User.Action.Ignore = Class.extend({
+ _containerList: {},
+ _ignoreButtonSelector: "",
+ _userID: 0,
+ init: function() {},
+ _click: function() {},
+ _success: function() {}
+ });
+}
/**
* Namespace for avatar functions.
*/
WCF.User.Avatar = {};
-/**
- * Avatar upload function
- *
- * @see WCF.Upload
- */
-WCF.User.Avatar.Upload = WCF.Upload.extend({
- /**
- * user id of avatar owner
- * @var integer
- */
- _userID: 0,
-
- /**
- * Initalizes a new WCF.User.Avatar.Upload object.
- *
- * @param integer userID
- */
- init: function(userID) {
- this._super($('#avatarUpload > dd > div'), undefined, 'wcf\\data\\user\\avatar\\UserAvatarAction');
- this._userID = userID || 0;
-
- $('#avatarForm input[type=radio]').change(function() {
- if ($(this).val() == 'custom') {
- $('#avatarUpload > dd > div').show();
- }
- else {
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Avatar upload function
+ *
+ * @see WCF.Upload
+ */
+ WCF.User.Avatar.Upload = WCF.Upload.extend({
+ /**
+ * user id of avatar owner
+ * @var integer
+ */
+ _userID: 0,
+
+ /**
+ * Initalizes a new WCF.User.Avatar.Upload object.
+ *
+ * @param integer userID
+ */
+ init: function (userID) {
+ this._super($('#avatarUpload > dd > div'), undefined, 'wcf\\data\\user\\avatar\\UserAvatarAction');
+ this._userID = userID || 0;
+
+ $('#avatarForm input[type=radio]').change(function () {
+ if ($(this).val() == 'custom') {
+ $('#avatarUpload > dd > div').show();
+ }
+ else {
+ $('#avatarUpload > dd > div').hide();
+ }
+ });
+ if (!$('#avatarForm input[type=radio][value=custom]:checked').length) {
$('#avatarUpload > dd > div').hide();
}
- });
- if (!$('#avatarForm input[type=radio][value=custom]:checked').length) {
- $('#avatarUpload > dd > div').hide();
- }
- },
-
- /**
- * @see WCF.Upload._initFile()
- */
- _initFile: function(file) {
- return $('#avatarUpload > dt > img');
- },
-
- /**
- * @see WCF.Upload._success()
- */
- _success: function(uploadID, data) {
- if (data.returnValues.url) {
- this._updateImage(data.returnValues.url);
+ },
+
+ /**
+ * @see WCF.Upload._initFile()
+ */
+ _initFile: function (file) {
+ return $('#avatarUpload > dt > img');
+ },
+
+ /**
+ * @see WCF.Upload._success()
+ */
+ _success: function (uploadID, data) {
+ if (data.returnValues.url) {
+ this._updateImage(data.returnValues.url);
+
+ // hide error
+ $('#avatarUpload > dd > .innerError').remove();
+
+ // show success message
+ var $notification = new WCF.System.Notification(WCF.Language.get('wcf.user.avatar.upload.success'));
+ $notification.show();
+ }
+ else if (data.returnValues.errorType) {
+ // show error
+ this._getInnerErrorElement().text(WCF.Language.get('wcf.user.avatar.upload.error.' + data.returnValues.errorType));
+ }
+ },
+
+ /**
+ * Updates the displayed avatar image.
+ *
+ * @param string url
+ */
+ _updateImage: function (url) {
+ $('#avatarUpload > dt > img').remove();
+ var $image = $('<img src="' + url + '" class="userAvatarImage" alt="" />').css({
+ 'height': 'auto',
+ 'max-height': '96px',
+ 'max-width': '96px',
+ 'width': 'auto'
+ });
- // hide error
- $('#avatarUpload > dd > .innerError').remove();
+ $('#avatarUpload > dt').prepend($image);
- // show success message
- var $notification = new WCF.System.Notification(WCF.Language.get('wcf.user.avatar.upload.success'));
- $notification.show();
- }
- else if (data.returnValues.errorType) {
- // show error
- this._getInnerErrorElement().text(WCF.Language.get('wcf.user.avatar.upload.error.' + data.returnValues.errorType));
- }
- },
-
- /**
- * Updates the displayed avatar image.
- *
- * @param string url
- */
- _updateImage: function(url) {
- $('#avatarUpload > dt > img').remove();
- var $image = $('<img src="' + url + '" class="userAvatarImage" alt="" />').css({
- 'height': 'auto',
- 'max-height': '96px',
- 'max-width': '96px',
- 'width': 'auto'
- });
-
- $('#avatarUpload > dt').prepend($image);
-
- WCF.DOMNodeInsertedHandler.execute();
- },
-
- /**
- * Returns the inner error element.
- *
- * @return jQuery
- */
- _getInnerErrorElement: function() {
- var $span = $('#avatarUpload > dd > .innerError');
- if (!$span.length) {
- $span = $('<small class="innerError"></span>');
- $('#avatarUpload > dd').append($span);
+ WCF.DOMNodeInsertedHandler.execute();
+ },
+
+ /**
+ * Returns the inner error element.
+ *
+ * @return jQuery
+ */
+ _getInnerErrorElement: function () {
+ var $span = $('#avatarUpload > dd > .innerError');
+ if (!$span.length) {
+ $span = $('<small class="innerError"></span>');
+ $('#avatarUpload > dd').append($span);
+ }
+
+ return $span;
+ },
+
+ /**
+ * @see WCF.Upload._getParameters()
+ */
+ _getParameters: function () {
+ return {
+ userID: this._userID
+ };
}
-
- return $span;
- },
-
- /**
- * @see WCF.Upload._getParameters()
- */
- _getParameters: function() {
- return {
- userID: this._userID
- };
- }
-});
+ });
+}
+else {
+ WCF.User.Avatar.Upload = WCF.Upload.extend({
+ _userID: 0,
+ init: function() {},
+ _initFile: function() {},
+ _success: function() {},
+ _updateImage: function() {},
+ _getInnerErrorElement: function() {},
+ _getParameters: function() {},
+ _name: "",
+ _buttonSelector: {},
+ _fileListSelector: {},
+ _fileUpload: {},
+ _className: "",
+ _iframe: {},
+ _internalFileID: 0,
+ _options: {},
+ _uploadMatrix: {},
+ _supportsAJAXUpload: true,
+ _overlay: {},
+ _createButton: function() {},
+ _insertButton: function() {},
+ _removeButton: function() {},
+ _upload: function() {},
+ _createUploadMatrix: function() {},
+ _error: function() {},
+ _progress: function() {},
+ _showOverlay: function() {},
+ _evaluateResponse: function() {},
+ _getFilename: function() {}
+ });
+}
/**
* Generic implementation for grouped user lists.
*/
WCF.User.ObjectWatch = {};
-/**
- * Handles subscribe/unsubscribe links.
- */
-WCF.User.ObjectWatch.Subscribe = Class.extend({
- /**
- * CSS selector for subscribe buttons
- * @var string
- */
- _buttonSelector: '.jsSubscribeButton',
-
- /**
- * list of buttons
- * @var object
- */
- _buttons: { },
-
- /**
- * dialog overlay
- * @var object
- */
- _dialog: null,
-
- /**
- * system notification
- * @var WCF.System.Notification
- */
- _notification: null,
-
- /**
- * reload page on unsubscribe
- * @var boolean
- */
- _reloadOnUnsubscribe: false,
-
- /**
- * WCF.User.ObjectWatch.Subscribe object.
- *
- * @param boolean reloadOnUnsubscribe
- */
- init: function(reloadOnUnsubscribe) {
- this._buttons = { };
- this._notification = null;
- this._reloadOnUnsubscribe = (reloadOnUnsubscribe === true);
-
- // initialize proxy
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- // bind event listeners
- $(this._buttonSelector).each($.proxy(function(index, button) {
- var $button = $(button);
- $button.addClass('pointer');
- var $objectType = $button.data('objectType');
- var $objectID = $button.data('objectID');
+if (COMPILER_TARGET_DEFAULT) {
+ /**
+ * Handles subscribe/unsubscribe links.
+ */
+ WCF.User.ObjectWatch.Subscribe = Class.extend({
+ /**
+ * CSS selector for subscribe buttons
+ * @var string
+ */
+ _buttonSelector: '.jsSubscribeButton',
+
+ /**
+ * list of buttons
+ * @var object
+ */
+ _buttons: {},
+
+ /**
+ * dialog overlay
+ * @var object
+ */
+ _dialog: null,
+
+ /**
+ * system notification
+ * @var WCF.System.Notification
+ */
+ _notification: null,
+
+ /**
+ * reload page on unsubscribe
+ * @var boolean
+ */
+ _reloadOnUnsubscribe: false,
+
+ /**
+ * WCF.User.ObjectWatch.Subscribe object.
+ *
+ * @param boolean reloadOnUnsubscribe
+ */
+ init: function (reloadOnUnsubscribe) {
+ this._buttons = {};
+ this._notification = null;
+ this._reloadOnUnsubscribe = (reloadOnUnsubscribe === true);
- if (this._buttons[$objectType] === undefined) {
- this._buttons[$objectType] = {};
- }
+ // initialize proxy
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
- this._buttons[$objectType][$objectID] = $button.click($.proxy(this._click, this));
- }, this));
-
- WCF.System.Event.addListener('com.woltlab.wcf.objectWatch', 'update', $.proxy(this._updateSubscriptionStatus, this));
- },
-
- /**
- * Handles a click on a subscribe button.
- *
- * @param object event
- */
- _click: function(event) {
- event.preventDefault();
- var $button = $(event.currentTarget);
-
- this._proxy.setOption('data', {
- actionName: 'manageSubscription',
- className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction',
- parameters: {
- objectID: $button.data('objectID'),
- objectType: $button.data('objectType')
- }
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- if (data.actionName === 'manageSubscription') {
- if (this._dialog === null) {
- this._dialog = $('<div>' + data.returnValues.template + '</div>').hide().appendTo(document.body);
- this._dialog.wcfDialog({
- title: WCF.Language.get('wcf.user.objectWatch.manageSubscription')
- });
- }
- else {
- this._dialog.html(data.returnValues.template);
- this._dialog.wcfDialog('open');
- }
+ // bind event listeners
+ $(this._buttonSelector).each($.proxy(function (index, button) {
+ var $button = $(button);
+ $button.addClass('pointer');
+ var $objectType = $button.data('objectType');
+ var $objectID = $button.data('objectID');
+
+ if (this._buttons[$objectType] === undefined) {
+ this._buttons[$objectType] = {};
+ }
+
+ this._buttons[$objectType][$objectID] = $button.click($.proxy(this._click, this));
+ }, this));
- // bind event listener
- this._dialog.find('.formSubmit > .jsButtonSave').data('objectID', data.returnValues.objectID).data('objectType', data.returnValues.objectType).click($.proxy(this._save, this));
- var $enableNotification = this._dialog.find('input[name=enableNotification]').disable();
+ WCF.System.Event.addListener('com.woltlab.wcf.objectWatch', 'update', $.proxy(this._updateSubscriptionStatus, this));
+ },
+
+ /**
+ * Handles a click on a subscribe button.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ event.preventDefault();
+ var $button = $(event.currentTarget);
- // toggle subscription
- this._dialog.find('input[name=subscribe]').change(function(event) {
- var $input = $(event.currentTarget);
- if ($input.val() == 1) {
- $enableNotification.enable();
+ this._proxy.setOption('data', {
+ actionName: 'manageSubscription',
+ className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction',
+ parameters: {
+ objectID: $button.data('objectID'),
+ objectType: $button.data('objectType')
+ }
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ if (data.actionName === 'manageSubscription') {
+ if (this._dialog === null) {
+ this._dialog = $('<div>' + data.returnValues.template + '</div>').hide().appendTo(document.body);
+ this._dialog.wcfDialog({
+ title: WCF.Language.get('wcf.user.objectWatch.manageSubscription')
+ });
}
else {
- $enableNotification.disable();
+ this._dialog.html(data.returnValues.template);
+ this._dialog.wcfDialog('open');
+ }
+
+ // bind event listener
+ this._dialog.find('.formSubmit > .jsButtonSave').data('objectID', data.returnValues.objectID).data('objectType', data.returnValues.objectType).click($.proxy(this._save, this));
+ var $enableNotification = this._dialog.find('input[name=enableNotification]').disable();
+
+ // toggle subscription
+ this._dialog.find('input[name=subscribe]').change(function (event) {
+ var $input = $(event.currentTarget);
+ if ($input.val() == 1) {
+ $enableNotification.enable();
+ }
+ else {
+ $enableNotification.disable();
+ }
+ });
+
+ // setup
+ var $selectedOption = this._dialog.find('input[name=subscribe]:checked');
+ if ($selectedOption.length && $selectedOption.val() == 1) {
+ $enableNotification.enable();
}
- });
-
- // setup
- var $selectedOption = this._dialog.find('input[name=subscribe]:checked');
- if ($selectedOption.length && $selectedOption.val() == 1) {
- $enableNotification.enable();
}
- }
- else if (data.actionName === 'saveSubscription' && this._dialog.is(':visible')) {
- this._dialog.wcfDialog('close');
-
- this._updateSubscriptionStatus({
- isSubscribed: data.returnValues.subscribe,
- objectID: data.returnValues.objectID
- });
-
-
- // show notification
- if (this._notification === null) {
- this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit'));
+ else if (data.actionName === 'saveSubscription' && this._dialog.is(':visible')) {
+ this._dialog.wcfDialog('close');
+
+ this._updateSubscriptionStatus({
+ isSubscribed: data.returnValues.subscribe,
+ objectID: data.returnValues.objectID
+ });
+
+
+ // show notification
+ if (this._notification === null) {
+ this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit'));
+ }
+
+ this._notification.show();
}
+ },
+
+ /**
+ * Saves the subscription.
+ *
+ * @param object event
+ */
+ _save: function (event) {
+ var $button = this._buttons[$(event.currentTarget).data('objectType')][$(event.currentTarget).data('objectID')];
+ var $subscribe = this._dialog.find('input[name=subscribe]:checked').val();
+ var $enableNotification = (this._dialog.find('input[name=enableNotification]').is(':checked')) ? 1 : 0;
- this._notification.show();
- }
- },
-
- /**
- * Saves the subscription.
- *
- * @param object event
- */
- _save: function(event) {
- var $button = this._buttons[$(event.currentTarget).data('objectType')][$(event.currentTarget).data('objectID')];
- var $subscribe = this._dialog.find('input[name=subscribe]:checked').val();
- var $enableNotification = (this._dialog.find('input[name=enableNotification]').is(':checked')) ? 1 : 0;
-
- this._proxy.setOption('data', {
- actionName: 'saveSubscription',
- className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction',
- parameters: {
- enableNotification: $enableNotification,
- objectID: $button.data('objectID'),
- objectType: $button.data('objectType'),
- subscribe: $subscribe
- }
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Updates subscription status and icon.
- *
- * @param object data
- */
- _updateSubscriptionStatus: function(data) {
- var $button = $(this._buttonSelector + '[data-object-id=' + data.objectID + ']');
- var $icon = $button.children('.icon');
- if (data.isSubscribed) {
- $icon.removeClass('fa-bookmark-o').addClass('fa-bookmark');
- $button.data('isSubscribed', true);
- }
- else {
- if ($button.data('removeOnUnsubscribe')) {
- $button.parent().remove();
+ this._proxy.setOption('data', {
+ actionName: 'saveSubscription',
+ className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction',
+ parameters: {
+ enableNotification: $enableNotification,
+ objectID: $button.data('objectID'),
+ objectType: $button.data('objectType'),
+ subscribe: $subscribe
+ }
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Updates subscription status and icon.
+ *
+ * @param object data
+ */
+ _updateSubscriptionStatus: function (data) {
+ var $button = $(this._buttonSelector + '[data-object-id=' + data.objectID + ']');
+ var $icon = $button.children('.icon');
+ if (data.isSubscribed) {
+ $icon.removeClass('fa-bookmark-o').addClass('fa-bookmark');
+ $button.data('isSubscribed', true);
}
else {
- $icon.removeClass('fa-bookmark').addClass('fa-bookmark-o');
- $button.data('isSubscribed', false);
+ if ($button.data('removeOnUnsubscribe')) {
+ $button.parent().remove();
+ }
+ else {
+ $icon.removeClass('fa-bookmark').addClass('fa-bookmark-o');
+ $button.data('isSubscribed', false);
+ }
+
+ if (this._reloadOnUnsubscribe) {
+ window.location.reload();
+ return;
+ }
}
- if (this._reloadOnUnsubscribe) {
- window.location.reload();
- return;
- }
- }
-
- WCF.System.Event.fireEvent('com.woltlab.wcf.objectWatch', 'updatedSubscription', data);
- }
-});
+ WCF.System.Event.fireEvent('com.woltlab.wcf.objectWatch', 'updatedSubscription', data);
+ }
+ });
+}
+else {
+ WCF.User.ObjectWatch.Subscribe = Class.extend({
+ _buttonSelector: "",
+ _buttons: {},
+ _dialog: {},
+ _notification: {},
+ _reloadOnUnsubscribe: false,
+ init: function() {},
+ _click: function() {},
+ _success: function() {},
+ _save: function() {},
+ _updateSubscriptionStatus: function() {}
+ });
+}
*/
WCF.Dropdown.Interactive = { };
-/**
- * General interface to create and manage interactive dropdowns.
- */
-WCF.Dropdown.Interactive.Handler = {
- /**
- * global container for interactive dropdowns
- * @var jQuery
- */
- _dropdownContainer: null,
-
- /**
- * list of dropdown instances by identifier
- * @var object<WCF.Dropdown.Interactive.Instance>
- */
- _dropdownMenus: { },
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Creates a new interactive dropdown instance.
- *
- * @param jQuery triggerElement
- * @param string identifier
- * @param object options
- * @return WCF.Dropdown.Interactive.Instance
+ * General interface to create and manage interactive dropdowns.
*/
- create: function(triggerElement, identifier, options) {
- if (this._dropdownContainer === null) {
- this._dropdownContainer = $('<div class="dropdownMenuContainer" />').appendTo(document.body);
- WCF.CloseOverlayHandler.addCallback('WCF.Dropdown.Interactive.Handler', $.proxy(this.closeAll, this));
- }
+ WCF.Dropdown.Interactive.Handler = {
+ /**
+ * global container for interactive dropdowns
+ * @var jQuery
+ */
+ _dropdownContainer: null,
- var $instance = new WCF.Dropdown.Interactive.Instance(this._dropdownContainer, triggerElement, identifier, options);
- this._dropdownMenus[identifier] = $instance;
+ /**
+ * list of dropdown instances by identifier
+ * @var object<WCF.Dropdown.Interactive.Instance>
+ */
+ _dropdownMenus: {},
- return $instance;
- },
-
- /**
- * Opens an interactive dropdown, returns false if identifier is unknown.
- *
- * @param string identifier
- * @return boolean
- */
- open: function(identifier) {
- if (this._dropdownMenus[identifier]) {
- this._dropdownMenus[identifier].open();
+ /**
+ * Creates a new interactive dropdown instance.
+ *
+ * @param jQuery triggerElement
+ * @param string identifier
+ * @param object options
+ * @return WCF.Dropdown.Interactive.Instance
+ */
+ create: function (triggerElement, identifier, options) {
+ if (this._dropdownContainer === null) {
+ this._dropdownContainer = $('<div class="dropdownMenuContainer" />').appendTo(document.body);
+ WCF.CloseOverlayHandler.addCallback('WCF.Dropdown.Interactive.Handler', $.proxy(this.closeAll, this));
+ }
- return true;
- }
+ var $instance = new WCF.Dropdown.Interactive.Instance(this._dropdownContainer, triggerElement, identifier, options);
+ this._dropdownMenus[identifier] = $instance;
+
+ return $instance;
+ },
- return false;
- },
-
- /**
- * Closes an interactive dropdown, returns false if identifier is unknown.
- *
- * @param string identifier
- * @return boolean
- */
- close: function(identifier) {
- if (this._dropdownMenus[identifier]) {
- this._dropdownMenus[identifier].close();
+ /**
+ * Opens an interactive dropdown, returns false if identifier is unknown.
+ *
+ * @param string identifier
+ * @return boolean
+ */
+ open: function (identifier) {
+ if (this._dropdownMenus[identifier]) {
+ this._dropdownMenus[identifier].open();
+
+ return true;
+ }
- return true;
- }
+ return false;
+ },
- return false;
- },
+ /**
+ * Closes an interactive dropdown, returns false if identifier is unknown.
+ *
+ * @param string identifier
+ * @return boolean
+ */
+ close: function (identifier) {
+ if (this._dropdownMenus[identifier]) {
+ this._dropdownMenus[identifier].close();
+
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * Closes all interactive dropdowns.
+ */
+ closeAll: function () {
+ for (var instance in this._dropdownMenus) {
+ if (this._dropdownMenus.hasOwnProperty(instance)) {
+ this._dropdownMenus[instance].close();
+ }
+ }
+ },
+
+ getOpenDropdown: function () {
+ for (var instance in this._dropdownMenus) {
+ if (this._dropdownMenus.hasOwnProperty(instance)) {
+ if (this._dropdownMenus[instance].isOpen()) {
+ return this._dropdownMenus[instance];
+ }
+ }
+ }
+
+ return null;
+ },
+
+ /**
+ * Returns the dropdown with given identifier or `undefined` if no such dropdown exists.
+ *
+ * @param string identifier
+ * @return {WCF.Dropdown.Interactive.Instance?}
+ */
+ getDropdown: function (identifier) {
+ return this._dropdownMenus[identifier];
+ }
+ };
/**
- * Closes all interactive dropdowns.
+ * Represents and manages a single interactive dropdown instance.
+ *
+ * @param jQuery dropdownContainer
+ * @param jQuery triggerElement
+ * @param string identifier
+ * @param object options
*/
- closeAll: function() {
- for (var instance in this._dropdownMenus) {
- if (this._dropdownMenus.hasOwnProperty(instance)) {
- this._dropdownMenus[instance].close();
+ WCF.Dropdown.Interactive.Instance = Class.extend({
+ /**
+ * dropdown container
+ * @var jQuery
+ */
+ _container: null,
+
+ /**
+ * inner item list
+ * @var jQuery
+ */
+ _itemList: null,
+
+ /**
+ * header link list
+ * @var jQuery
+ */
+ _linkList: null,
+
+ /**
+ * option list
+ * @var object
+ */
+ _options: {},
+
+ /**
+ * arrow pointer
+ * @var jQuery
+ */
+ _pointer: null,
+
+ /**
+ * trigger element
+ * @var jQuery
+ */
+ _triggerElement: null,
+
+ /**
+ * Represents and manages a single interactive dropdown instance.
+ *
+ * @param jQuery dropdownContainer
+ * @param jQuery triggerElement
+ * @param string identifier
+ * @param object options
+ */
+ init: function (dropdownContainer, triggerElement, identifier, options) {
+ this._options = options || {};
+ this._triggerElement = triggerElement;
+
+ var $itemContainer = null;
+ if (options.staticDropdown === true) {
+ this._container = this._triggerElement.find('.interactiveDropdownStatic:eq(0)').data('source', identifier).click(function (event) {
+ event.stopPropagation();
+ });
}
- }
- },
-
- getOpenDropdown: function () {
- for (var instance in this._dropdownMenus) {
- if (this._dropdownMenus.hasOwnProperty(instance)) {
- if (this._dropdownMenus[instance].isOpen()) {
- return this._dropdownMenus[instance];
+ else {
+ this._container = $('<div class="interactiveDropdown" data-source="' + identifier + '" />').click(function (event) {
+ event.stopPropagation();
+ });
+
+ var $header = $('<div class="interactiveDropdownHeader" />').appendTo(this._container);
+ $('<span class="interactiveDropdownTitle">' + options.title + '</span>').appendTo($header);
+ this._linkList = $('<ul class="interactiveDropdownLinks inlineList"></ul>').appendTo($header);
+
+ $itemContainer = $('<div class="interactiveDropdownItemsContainer" />').appendTo(this._container);
+ this._itemList = $('<ul class="interactiveDropdownItems" />').appendTo($itemContainer);
+
+ $('<a href="' + options.showAllLink + '" class="interactiveDropdownShowAll">' + WCF.Language.get('wcf.user.panel.showAll') + '</a>').appendTo(this._container);
+ }
+
+ this._pointer = $('<span class="elementPointer"><span /></span>').appendTo(this._container);
+
+ require(['Environment'], (function (Environment) {
+ if (Environment.platform() === 'desktop') {
+ if ($itemContainer !== null) {
+ // use jQuery scrollbar on desktop, mobile browsers have a similar display built-in
+ $itemContainer.perfectScrollbar({
+ suppressScrollX: true
+ });
+ }
}
+ }).bind(this));
+
+ this._container.appendTo(dropdownContainer);
+ },
+
+ /**
+ * Returns the dropdown container.
+ *
+ * @return jQuery
+ */
+ getContainer: function () {
+ return this._container;
+ },
+
+ /**
+ * Returns the inner item list.
+ *
+ * @return jQuery
+ */
+ getItemList: function () {
+ return this._itemList;
+ },
+
+ /**
+ * Returns the header link list.
+ *
+ * @return jQuery
+ */
+ getLinkList: function () {
+ return this._linkList;
+ },
+
+ /**
+ * Opens the dropdown.
+ */
+ open: function () {
+ WCF.Dropdown._closeAll();
+
+ this._triggerElement.addClass('open');
+ this._container.addClass('open');
+
+ WCF.System.Event.fireEvent('com.woltlab.wcf.Search', 'close');
+
+ this.render();
+ },
+
+ /**
+ * Closes the dropdown
+ */
+ close: function () {
+ this._triggerElement.removeClass('open');
+ this._container.removeClass('open');
+ },
+
+ /**
+ * Returns true if dropdown instance is visible.
+ *
+ * @returns {boolean}
+ */
+ isOpen: function () {
+ return this._triggerElement.hasClass('open');
+ },
+
+ /**
+ * Toggles the dropdown state, returns true if dropdown is open afterwards, else false.
+ *
+ * @return boolean
+ */
+ toggle: function () {
+ if (this._container.hasClass('open')) {
+ this.close();
+
+ return false;
}
- }
+ else {
+ WCF.Dropdown.Interactive.Handler.closeAll();
+
+ this.open();
+
+ return true;
+ }
+ },
- return null;
- },
+ /**
+ * Resets the inner item list and closes the dropdown.
+ */
+ resetItems: function () {
+ this._itemList.empty();
+
+ this.close();
+ },
+
+ /**
+ * Renders the dropdown.
+ */
+ render: function () {
+ require(['Ui/Alignment', 'Ui/Screen'], (function (UiAlignment, UiScreen) {
+ if (UiScreen.is('screen-lg')) {
+ UiAlignment.set(this._container[0], this._triggerElement[0], {
+ horizontal: 'right',
+ pointer: true
+ });
+ }
+ else {
+ this._container.css({
+ bottom: '',
+ left: '',
+ right: '',
+ top: elById('pageHeaderPanel').clientHeight + 'px'
+ });
+ }
+ }).bind(this));
+ },
+
+ /**
+ * Rebuilds the desktop scrollbar.
+ */
+ rebuildScrollbar: function () {
+ require(['Environment'], function (Environment) {
+ if (Environment.platform() === 'desktop') {
+ var $itemContainer = this._itemList.parent();
+
+ // do NOT use 'update', seems to be broken
+ $itemContainer.perfectScrollbar('destroy');
+ $itemContainer.perfectScrollbar({
+ suppressScrollX: true
+ });
+ }
+ }.bind(this));
+ }
+ });
/**
- * Returns the dropdown with given identifier or `undefined` if no such dropdown exists.
+ * Clipboard API
*
- * @param string identifier
- * @return {WCF.Dropdown.Interactive.Instance?}
+ * @deprecated 3.0 - please use `WoltLabSuite/Core/Controller/Clipboard` instead
*/
- getDropdown: function(identifier) {
- return this._dropdownMenus[identifier];
- }
-};
+ WCF.Clipboard = {
+ /**
+ * Initializes the clipboard API.
+ *
+ * @param string page
+ * @param integer hasMarkedItems
+ * @param object actionObjects
+ * @param integer pageObjectID
+ */
+ init: function(page, hasMarkedItems, actionObjects, pageObjectID) {
+ require(['EventHandler', 'WoltLabSuite/Core/Controller/Clipboard'], function(EventHandler, ControllerClipboard) {
+ ControllerClipboard.setup({
+ hasMarkedItems: (hasMarkedItems > 0),
+ pageClassName: page,
+ pageObjectId: pageObjectID
+ });
+
+ for (var type in actionObjects) {
+ if (actionObjects.hasOwnProperty(type)) {
+ (function (type) {
+ EventHandler.add('com.woltlab.wcf.clipboard', type, function (data) {
+ // only consider events if the action has been executed
+ if (data.responseData === null) {
+ return;
+ }
+
+ if (actionObjects[type].hasOwnProperty(data.responseData.actionName)) {
+ actionObjects[type][data.responseData.actionName].triggerEffect(data.responseData.objectIDs);
+ }
+ });
+ })(type);
+ }
+ }
+ });
+ },
+
+ /**
+ * Reloads the list of marked items.
+ */
+ reload: function() {
+ require(['WoltLabSuite/Core/Controller/Clipboard'], function(ControllerClipboard) {
+ ControllerClipboard.reload();
+ });
+ }
+ };
+}
+else {
+ WCF.Dropdown.Interactive.Handler = {
+ _dropdownContainer: {},
+ _dropdownMenus: {},
+ create: function() {},
+ open: function() {},
+ close: function() {},
+ closeAll: function() {},
+ getOpenDropdown: function() {},
+ getDropdown: function() {}
+ };
+
+ WCF.Dropdown.Interactive.Instance = Class.extend({
+ _container: {},
+ _itemList: {},
+ _linkList: {},
+ _options: {},
+ _pointer: {},
+ _triggerElement: {},
+ init: function() {},
+ getContainer: function() {},
+ getItemList: function() {},
+ getLinkList: function() {},
+ open: function() {},
+ close: function() {},
+ isOpen: function() {},
+ toggle: function() {},
+ resetItems: function() {},
+ render: function() {},
+ rebuildScrollbar: function() {}
+ });
+
+ WCF.Clipboard = {
+ init: function() {},
+ reload: function() {}
+ };
+}
/**
- * Represents and manages a single interactive dropdown instance.
- *
- * @param jQuery dropdownContainer
- * @param jQuery triggerElement
- * @param string identifier
- * @param object options
+ * @deprecated Use WoltLabSuite/Core/Timer/Repeating
*/
-WCF.Dropdown.Interactive.Instance = Class.extend({
+WCF.PeriodicalExecuter = Class.extend({
/**
- * dropdown container
- * @var jQuery
+ * callback for each execution cycle
+ * @var object
*/
- _container: null,
+ _callback: null,
/**
- * inner item list
- * @var jQuery
+ * interval
+ * @var integer
*/
- _itemList: null,
+ _delay: 0,
/**
- * header link list
- * @var jQuery
+ * interval id
+ * @var integer
*/
- _linkList: null,
+ _intervalID: null,
/**
- * option list
- * @var object
+ * execution state
+ * @var boolean
*/
- _options: { },
+ _isExecuting: false,
/**
- * arrow pointer
- * @var jQuery
+ * Initializes a periodical executer.
+ *
+ * @param function callback
+ * @param integer delay
*/
- _pointer: null,
+ init: function(callback, delay) {
+ if (!$.isFunction(callback)) {
+ console.debug('[WCF.PeriodicalExecuter] Given callback is invalid, aborting.');
+ return;
+ }
+
+ this._callback = callback;
+ this._interval = delay;
+ this.resume();
+ },
/**
- * trigger element
- * @var jQuery
+ * Executes callback.
*/
- _triggerElement: null,
-
- /**
- * Represents and manages a single interactive dropdown instance.
- *
- * @param jQuery dropdownContainer
- * @param jQuery triggerElement
- * @param string identifier
- * @param object options
- */
- init: function(dropdownContainer, triggerElement, identifier, options) {
- this._options = options || { };
- this._triggerElement = triggerElement;
-
- var $itemContainer = null;
- if (options.staticDropdown === true) {
- this._container = this._triggerElement.find('.interactiveDropdownStatic:eq(0)').data('source', identifier).click(function(event) { event.stopPropagation(); });
- }
- else {
- this._container = $('<div class="interactiveDropdown" data-source="' + identifier + '" />').click(function(event) { event.stopPropagation(); });
-
- var $header = $('<div class="interactiveDropdownHeader" />').appendTo(this._container);
- $('<span class="interactiveDropdownTitle">' + options.title + '</span>').appendTo($header);
- this._linkList = $('<ul class="interactiveDropdownLinks inlineList"></ul>').appendTo($header);
-
- $itemContainer = $('<div class="interactiveDropdownItemsContainer" />').appendTo(this._container);
- this._itemList = $('<ul class="interactiveDropdownItems" />').appendTo($itemContainer);
-
- $('<a href="' + options.showAllLink + '" class="interactiveDropdownShowAll">' + WCF.Language.get('wcf.user.panel.showAll') + '</a>').appendTo(this._container);
- }
-
- this._pointer = $('<span class="elementPointer"><span /></span>').appendTo(this._container);
-
- require(['Environment'], (function(Environment) {
- if (Environment.platform() === 'desktop') {
- if ($itemContainer !== null) {
- // use jQuery scrollbar on desktop, mobile browsers have a similar display built-in
- $itemContainer.perfectScrollbar({
- suppressScrollX: true
- });
- }
- }
- }).bind(this));
-
- this._container.appendTo(dropdownContainer);
- },
-
- /**
- * Returns the dropdown container.
- *
- * @return jQuery
- */
- getContainer: function() {
- return this._container;
- },
-
- /**
- * Returns the inner item list.
- *
- * @return jQuery
- */
- getItemList: function() {
- return this._itemList;
- },
-
- /**
- * Returns the header link list.
- *
- * @return jQuery
- */
- getLinkList: function() {
- return this._linkList;
- },
-
- /**
- * Opens the dropdown.
- */
- open: function() {
- WCF.Dropdown._closeAll();
-
- this._triggerElement.addClass('open');
- this._container.addClass('open');
-
- WCF.System.Event.fireEvent('com.woltlab.wcf.Search', 'close');
-
- this.render();
- },
-
- /**
- * Closes the dropdown
- */
- close: function() {
- this._triggerElement.removeClass('open');
- this._container.removeClass('open');
- },
-
- /**
- * Returns true if dropdown instance is visible.
- *
- * @returns {boolean}
- */
- isOpen: function() {
- return this._triggerElement.hasClass('open');
- },
-
- /**
- * Toggles the dropdown state, returns true if dropdown is open afterwards, else false.
- *
- * @return boolean
- */
- toggle: function() {
- if (this._container.hasClass('open')) {
- this.close();
-
- return false;
- }
- else {
- WCF.Dropdown.Interactive.Handler.closeAll();
-
- this.open();
-
- return true;
- }
- },
-
- /**
- * Resets the inner item list and closes the dropdown.
- */
- resetItems: function() {
- this._itemList.empty();
-
- this.close();
- },
-
- /**
- * Renders the dropdown.
- */
- render: function() {
- require(['Ui/Alignment', 'Ui/Screen'], (function (UiAlignment, UiScreen) {
- if (UiScreen.is('screen-lg')) {
- UiAlignment.set(this._container[0], this._triggerElement[0], {
- horizontal: 'right',
- pointer: true
- });
- }
- else {
- this._container.css({
- bottom: '',
- left: '',
- right: '',
- top: elById('pageHeaderPanel').clientHeight + 'px'
- });
- }
- }).bind(this));
- },
-
- /**
- * Rebuilds the desktop scrollbar.
- */
- rebuildScrollbar: function() {
- require(['Environment'], function(Environment) {
- if (Environment.platform() === 'desktop') {
- var $itemContainer = this._itemList.parent();
-
- // do NOT use 'update', seems to be broken
- $itemContainer.perfectScrollbar('destroy');
- $itemContainer.perfectScrollbar({
- suppressScrollX: true
- });
- }
- }.bind(this));
- }
-});
-
-/**
- * Clipboard API
- *
- * @deprecated 3.0 - please use `WoltLabSuite/Core/Controller/Clipboard` instead
- */
-WCF.Clipboard = {
- /**
- * Initializes the clipboard API.
- *
- * @param string page
- * @param integer hasMarkedItems
- * @param object actionObjects
- * @param integer pageObjectID
- */
- init: function(page, hasMarkedItems, actionObjects, pageObjectID) {
- require(['EventHandler', 'WoltLabSuite/Core/Controller/Clipboard'], function(EventHandler, ControllerClipboard) {
- ControllerClipboard.setup({
- hasMarkedItems: (hasMarkedItems > 0),
- pageClassName: page,
- pageObjectId: pageObjectID
- });
-
- for (var type in actionObjects) {
- if (actionObjects.hasOwnProperty(type)) {
- (function (type) {
- EventHandler.add('com.woltlab.wcf.clipboard', type, function (data) {
- // only consider events if the action has been executed
- if (data.responseData === null) {
- return;
- }
-
- if (actionObjects[type].hasOwnProperty(data.responseData.actionName)) {
- actionObjects[type][data.responseData.actionName].triggerEffect(data.responseData.objectIDs);
- }
- });
- })(type);
- }
- }
- });
- },
-
- /**
- * Reloads the list of marked items.
- */
- reload: function() {
- require(['WoltLabSuite/Core/Controller/Clipboard'], function(ControllerClipboard) {
- ControllerClipboard.reload();
- });
- }
-};
-
-/**
- * @deprecated Use WoltLabSuite/Core/Timer/Repeating
- */
-WCF.PeriodicalExecuter = Class.extend({
- /**
- * callback for each execution cycle
- * @var object
- */
- _callback: null,
-
- /**
- * interval
- * @var integer
- */
- _delay: 0,
-
- /**
- * interval id
- * @var integer
- */
- _intervalID: null,
-
- /**
- * execution state
- * @var boolean
- */
- _isExecuting: false,
-
- /**
- * Initializes a periodical executer.
- *
- * @param function callback
- * @param integer delay
- */
- init: function(callback, delay) {
- if (!$.isFunction(callback)) {
- console.debug('[WCF.PeriodicalExecuter] Given callback is invalid, aborting.');
- return;
- }
-
- this._callback = callback;
- this._interval = delay;
- this.resume();
- },
-
- /**
- * Executes callback.
- */
- _execute: function() {
- if (!this._isExecuting) {
- try {
- this._isExecuting = true;
- this._callback(this);
- this._isExecuting = false;
- }
- catch (e) {
- this._isExecuting = false;
- throw e;
- }
- }
- },
+ _execute: function() {
+ if (!this._isExecuting) {
+ try {
+ this._isExecuting = true;
+ this._callback(this);
+ this._isExecuting = false;
+ }
+ catch (e) {
+ this._isExecuting = false;
+ throw e;
+ }
+ }
+ },
/**
* Terminates loop.
}
});
-/**
- * Basic implementation for AJAXProxy-based deletion.
- *
- * @param string className
- * @param string containerSelector
- * @param string buttonSelector
- */
-WCF.Action.Delete = Class.extend({
- /**
- * delete button selector
- * @var string
- */
- _buttonSelector: '',
-
- /**
- * callback function called prior to triggering the delete effect
- * @var function
- */
- _callback: null,
-
- /**
- * action class name
- * @var string
- */
- _className: '',
-
- /**
- * container selector
- * @var string
- */
- _containerSelector: '',
-
- /**
- * list of known container ids
- * @var array<string>
- */
- _containers: [ ],
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes 'delete'-Proxy.
- *
- * @param string className
- * @param string containerSelector
- * @param string buttonSelector
+ * Basic implementation for AJAXProxy-based deletion.
+ *
+ * @param string className
+ * @param string containerSelector
+ * @param string buttonSelector
*/
- init: function(className, containerSelector, buttonSelector) {
- this._containerSelector = containerSelector;
- this._className = className;
- this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsDeleteButton';
- this._callback = null;
+ WCF.Action.Delete = Class.extend({
+ /**
+ * delete button selector
+ * @var string
+ */
+ _buttonSelector: '',
- this.proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
+ /**
+ * callback function called prior to triggering the delete effect
+ * @var function
+ */
+ _callback: null,
- this._initElements();
+ /**
+ * action class name
+ * @var string
+ */
+ _className: '',
- WCF.DOMNodeInsertedHandler.addCallback('WCF.Action.Delete' + this._className.hashCode(), $.proxy(this._initElements, this));
- },
-
- /**
- * Initializes available element containers.
- */
- _initElements: function() {
- $(this._containerSelector).each((function(index, container) {
- var $container = $(container);
- var $containerID = $container.wcfIdentify();
+ /**
+ * container selector
+ * @var string
+ */
+ _containerSelector: '',
+
+ /**
+ * list of known container ids
+ * @var array<string>
+ */
+ _containers: [],
+
+ /**
+ * Initializes 'delete'-Proxy.
+ *
+ * @param string className
+ * @param string containerSelector
+ * @param string buttonSelector
+ */
+ init: function (className, containerSelector, buttonSelector) {
+ this._containerSelector = containerSelector;
+ this._className = className;
+ this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsDeleteButton';
+ this._callback = null;
- if (!WCF.inArray($containerID, this._containers)) {
- var $deleteButton = $container.find(this._buttonSelector);
+ this.proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ this._initElements();
+
+ WCF.DOMNodeInsertedHandler.addCallback('WCF.Action.Delete' + this._className.hashCode(), $.proxy(this._initElements, this));
+ },
+
+ /**
+ * Initializes available element containers.
+ */
+ _initElements: function () {
+ $(this._containerSelector).each((function (index, container) {
+ var $container = $(container);
+ var $containerID = $container.wcfIdentify();
- if ($deleteButton.length) {
- this._containers.push($containerID);
- $deleteButton.click($.proxy(this._click, this));
+ if (!WCF.inArray($containerID, this._containers)) {
+ var $deleteButton = $container.find(this._buttonSelector);
+
+ if ($deleteButton.length) {
+ this._containers.push($containerID);
+ $deleteButton.click($.proxy(this._click, this));
+ }
}
+ }).bind(this));
+ },
+
+ /**
+ * Sends AJAX request.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $target = $(event.currentTarget);
+ event.preventDefault();
+
+ if ($target.data('confirmMessageHtml') || $target.data('confirmMessage')) {
+ WCF.System.Confirmation.show($target.data('confirmMessageHtml') ? $target.data('confirmMessageHtml') : $target.data('confirmMessage'), $.proxy(this._execute, this), {target: $target}, undefined, $target.data('confirmMessageHtml') ? true : false);
}
- }).bind(this));
- },
-
- /**
- * Sends AJAX request.
- *
- * @param object event
- */
- _click: function(event) {
- var $target = $(event.currentTarget);
- event.preventDefault();
+ else {
+ WCF.LoadingOverlayHandler.updateIcon($target);
+ this._sendRequest($target);
+ }
+ },
- if ($target.data('confirmMessageHtml') || $target.data('confirmMessage')) {
- WCF.System.Confirmation.show($target.data('confirmMessageHtml') ? $target.data('confirmMessageHtml') : $target.data('confirmMessage'), $.proxy(this._execute, this), { target: $target }, undefined, $target.data('confirmMessageHtml') ? true : false);
- }
- else {
- WCF.LoadingOverlayHandler.updateIcon($target);
- this._sendRequest($target);
- }
- },
-
- /**
- * Is called if the delete effect has been triggered on the given element.
- *
- * @param jQuery element
- */
- _didTriggerEffect: function(element) {
- // does nothing
- },
-
- /**
- * Executes deletion.
- *
- * @param string action
- * @param object parameters
- */
- _execute: function(action, parameters) {
- if (action === 'cancel') {
- return;
- }
+ /**
+ * Is called if the delete effect has been triggered on the given element.
+ *
+ * @param jQuery element
+ */
+ _didTriggerEffect: function (element) {
+ // does nothing
+ },
- WCF.LoadingOverlayHandler.updateIcon(parameters.target);
- this._sendRequest(parameters.target);
- },
-
- /**
- * Sends the request
- *
- * @param jQuery object
- */
- _sendRequest: function(object) {
- this.proxy.setOption('data', {
- actionName: 'delete',
- className: this._className,
- interfaceName: 'wcf\\data\\IDeleteAction',
- objectIDs: [ $(object).data('objectID') ]
- });
+ /**
+ * Executes deletion.
+ *
+ * @param string action
+ * @param object parameters
+ */
+ _execute: function (action, parameters) {
+ if (action === 'cancel') {
+ return;
+ }
+
+ WCF.LoadingOverlayHandler.updateIcon(parameters.target);
+ this._sendRequest(parameters.target);
+ },
- this.proxy.sendRequest();
- },
-
- /**
- * Deletes items from containers.
- *
- * @param object data
- * @param string textStatus
- * @param object jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- if (this._callback) {
- this._callback(data.objectIDs);
- }
+ /**
+ * Sends the request
+ *
+ * @param jQuery object
+ */
+ _sendRequest: function (object) {
+ this.proxy.setOption('data', {
+ actionName: 'delete',
+ className: this._className,
+ interfaceName: 'wcf\\data\\IDeleteAction',
+ objectIDs: [$(object).data('objectID')]
+ });
+
+ this.proxy.sendRequest();
+ },
- this.triggerEffect(data.objectIDs);
- },
-
- /**
- * Sets a callback function called prior to triggering the delete effect.
- *
- * @param {function} callback
- */
- setCallback: function(callback) {
- if (typeof callback !== 'function') {
- throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '" + this._className + "'.");
- }
+ /**
+ * Deletes items from containers.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param object jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ if (this._callback) {
+ this._callback(data.objectIDs);
+ }
+
+ this.triggerEffect(data.objectIDs);
+ },
- this._callback = callback;
- },
+ /**
+ * Sets a callback function called prior to triggering the delete effect.
+ *
+ * @param {function} callback
+ */
+ setCallback: function (callback) {
+ if (typeof callback !== 'function') {
+ throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '" + this._className + "'.");
+ }
+
+ this._callback = callback;
+ },
+
+ /**
+ * Triggers the delete effect for the objects with the given ids.
+ *
+ * @param array objectIDs
+ */
+ triggerEffect: function (objectIDs) {
+ for (var $index in this._containers) {
+ var $container = $('#' + this._containers[$index]);
+ var $button = $container.find(this._buttonSelector);
+ if (WCF.inArray($button.data('objectID'), objectIDs)) {
+ var self = this;
+ $container.wcfBlindOut('up', function () {
+ var $container = $(this).remove();
+ self._containers.splice(self._containers.indexOf($container.wcfIdentify()), 1);
+ self._didTriggerEffect($container);
+
+ if ($button.data('eventName')) {
+ WCF.System.Event.fireEvent('com.woltlab.wcf.action.delete', $button.data('eventName'), {
+ button: $button,
+ container: $container
+ });
+ }
+ });
+ }
+ }
+ }
+ });
/**
- * Triggers the delete effect for the objects with the given ids.
- *
- * @param array objectIDs
+ * Basic implementation for deletion of nested elements.
+ *
+ * The implementation requires the nested elements to be grouped as numbered lists
+ * (ol lists). The child elements of the deleted elements are moved to the parent
+ * element of the deleted element.
+ *
+ * @see WCF.Action.Delete
*/
- triggerEffect: function(objectIDs) {
- for (var $index in this._containers) {
- var $container = $('#' + this._containers[$index]);
- var $button = $container.find(this._buttonSelector);
- if (WCF.inArray($button.data('objectID'), objectIDs)) {
- var self = this;
- $container.wcfBlindOut('up',function() {
- var $container = $(this).remove();
- self._containers.splice(self._containers.indexOf($container.wcfIdentify()), 1);
- self._didTriggerEffect($container);
-
- if ($button.data('eventName')) {
- WCF.System.Event.fireEvent('com.woltlab.wcf.action.delete', $button.data('eventName'), {
- button: $button,
- container: $container
+ WCF.Action.NestedDelete = WCF.Action.Delete.extend({
+ /**
+ * @see WCF.Action.Delete.triggerEffect()
+ */
+ triggerEffect: function (objectIDs) {
+ for (var $index in this._containers) {
+ var $container = $('#' + this._containers[$index]);
+ if (WCF.inArray($container.find(this._buttonSelector).data('objectID'), objectIDs)) {
+ // move children up
+ if ($container.has('ol').has('li').length) {
+ if ($container.is(':only-child')) {
+ $container.parent().replaceWith($container.find('> ol'));
+ }
+ else {
+ $container.replaceWith($container.find('> ol > li'));
+ }
+
+ this._containers.splice(this._containers.indexOf($container.wcfIdentify()), 1);
+ this._didTriggerEffect($container);
+ }
+ else {
+ var self = this;
+ $container.wcfBlindOut('up', function () {
+ $(this).remove();
+ self._containers.splice(self._containers.indexOf($(this).wcfIdentify()), 1);
+ self._didTriggerEffect($(this));
});
}
- });
+ }
}
}
- }
-});
-
-/**
- * Basic implementation for deletion of nested elements.
- *
- * The implementation requires the nested elements to be grouped as numbered lists
- * (ol lists). The child elements of the deleted elements are moved to the parent
- * element of the deleted element.
- *
- * @see WCF.Action.Delete
- */
-WCF.Action.NestedDelete = WCF.Action.Delete.extend({
- /**
- * @see WCF.Action.Delete.triggerEffect()
- */
- triggerEffect: function(objectIDs) {
- for (var $index in this._containers) {
- var $container = $('#' + this._containers[$index]);
- if (WCF.inArray($container.find(this._buttonSelector).data('objectID'), objectIDs)) {
- // move children up
- if ($container.has('ol').has('li').length) {
- if ($container.is(':only-child')) {
- $container.parent().replaceWith($container.find('> ol'));
- }
- else {
- $container.replaceWith($container.find('> ol > li'));
- }
-
- this._containers.splice(this._containers.indexOf($container.wcfIdentify()), 1);
- this._didTriggerEffect($container);
+ });
+
+ /**
+ * Basic implementation for AJAXProxy-based toggle actions.
+ *
+ * @param string className
+ * @param jQuery containerList
+ * @param string buttonSelector
+ */
+ WCF.Action.Toggle = Class.extend({
+ /**
+ * toogle button selector
+ * @var string
+ */
+ _buttonSelector: '.jsToggleButton',
+
+ /**
+ * action class name
+ * @var string
+ */
+ _className: '',
+
+ /**
+ * container selector
+ * @var string
+ */
+ _containerSelector: '',
+
+ /**
+ * list of known container ids
+ * @var array<string>
+ */
+ _containers: [],
+
+ /**
+ * Initializes 'toggle'-Proxy
+ *
+ * @param string className
+ * @param string containerSelector
+ * @param string buttonSelector
+ */
+ init: function (className, containerSelector, buttonSelector) {
+ this._containerSelector = containerSelector;
+ this._className = className;
+ this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsToggleButton';
+ this._containers = [];
+
+ // initialize proxy
+ var options = {
+ success: $.proxy(this._success, this)
+ };
+ this.proxy = new WCF.Action.Proxy(options);
+
+ // bind event listener
+ this._initElements();
+ WCF.DOMNodeInsertedHandler.addCallback('WCF.Action.Toggle' + this._className.hashCode(), $.proxy(this._initElements, this));
+ },
+
+ /**
+ * Initializes available element containers.
+ */
+ _initElements: function () {
+ $(this._containerSelector).each($.proxy(function (index, container) {
+ var $container = $(container);
+ var $containerID = $container.wcfIdentify();
+
+ if (!WCF.inArray($containerID, this._containers)) {
+ this._containers.push($containerID);
+ $container.find(this._buttonSelector).click($.proxy(this._click, this));
}
- else {
- var self = this;
- $container.wcfBlindOut('up', function() {
- $(this).remove();
- self._containers.splice(self._containers.indexOf($(this).wcfIdentify()), 1);
- self._didTriggerEffect($(this));
- });
+ }, this));
+ },
+
+ /**
+ * Sends AJAX request.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $target = $(event.currentTarget);
+ event.preventDefault();
+
+ if ($target.data('confirmMessageHtml') || $target.data('confirmMessage')) {
+ WCF.System.Confirmation.show($target.data('confirmMessageHtml') ? $target.data('confirmMessageHtml') : $target.data('confirmMessage'), $.proxy(this._execute, this), {target: $target}, undefined, $target.data('confirmMessageHtml') ? true : false);
+ }
+ else {
+ WCF.LoadingOverlayHandler.updateIcon($target);
+ this._sendRequest($target);
+ }
+ },
+
+ /**
+ * Executes toggeling.
+ *
+ * @param string action
+ * @param object parameters
+ */
+ _execute: function (action, parameters) {
+ if (action === 'cancel') {
+ return;
+ }
+
+ WCF.LoadingOverlayHandler.updateIcon(parameters.target);
+ this._sendRequest(parameters.target);
+ },
+
+ _sendRequest: function (object) {
+ this.proxy.setOption('data', {
+ actionName: 'toggle',
+ className: this._className,
+ interfaceName: 'wcf\\data\\IToggleAction',
+ objectIDs: [$(object).data('objectID')]
+ });
+
+ this.proxy.sendRequest();
+ },
+
+ /**
+ * Toggles status icons.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param object jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ this.triggerEffect(data.objectIDs);
+ },
+
+ /**
+ * Triggers the toggle effect for the objects with the given ids.
+ *
+ * @param array objectIDs
+ */
+ triggerEffect: function (objectIDs) {
+ for (var $index in this._containers) {
+ var $container = $('#' + this._containers[$index]);
+ var $toggleButton = $container.find(this._buttonSelector);
+ if (WCF.inArray($toggleButton.data('objectID'), objectIDs)) {
+ $container.wcfHighlight();
+ this._toggleButton($container, $toggleButton);
}
}
+ },
+
+ /**
+ * Tiggers the toggle effect on a button
+ *
+ * @param jQuery $container
+ * @param jQuery $toggleButton
+ */
+ _toggleButton: function ($container, $toggleButton) {
+ var $newTitle = '';
+
+ // toggle icon source
+ WCF.LoadingOverlayHandler.updateIcon($toggleButton, false);
+ if ($toggleButton.hasClass('fa-square-o')) {
+ $toggleButton.removeClass('fa-square-o').addClass('fa-check-square-o');
+ $newTitle = ($toggleButton.data('disableTitle') ? $toggleButton.data('disableTitle') : WCF.Language.get('wcf.global.button.disable'));
+ $toggleButton.attr('title', $newTitle);
+ }
+ else {
+ $toggleButton.removeClass('fa-check-square-o').addClass('fa-square-o');
+ $newTitle = ($toggleButton.data('enableTitle') ? $toggleButton.data('enableTitle') : WCF.Language.get('wcf.global.button.enable'));
+ $toggleButton.attr('title', $newTitle);
+ }
+
+ // toggle css class
+ $container.toggleClass('disabled');
}
- }
-});
+ });
+}
+else {
+ WCF.Action.Delete = Class.extend({
+ _buttonSelector: "",
+ _callback: {},
+ _className: "",
+ _containerSelector: "",
+ _containers: {},
+ init: function() {},
+ _initElements: function() {},
+ _click: function() {},
+ _didTriggerEffect: function() {},
+ _execute: function() {},
+ _sendRequest: function() {},
+ _success: function() {},
+ setCallback: function() {},
+ triggerEffect: function() {}
+ });
+
+ WCF.Action.NestedDelete = WCF.Action.Delete.extend({
+ triggerEffect: function() {},
+ _buttonSelector: "",
+ _callback: {},
+ _className: "",
+ _containerSelector: "",
+ _containers: {},
+ init: function() {},
+ _initElements: function() {},
+ _click: function() {},
+ _didTriggerEffect: function() {},
+ _execute: function() {},
+ _sendRequest: function() {},
+ _success: function() {},
+ setCallback: function() {}
+ });
+
+ WCF.Action.Toggle = Class.extend({
+ _buttonSelector: "",
+ _className: "",
+ _containerSelector: "",
+ _containers: {},
+ init: function() {},
+ _initElements: function() {},
+ _click: function() {},
+ _execute: function() {},
+ _sendRequest: function() {},
+ _success: function() {},
+ triggerEffect: function() {},
+ _toggleButton: function() {}
+ });
+}
/**
- * Basic implementation for AJAXProxy-based toggle actions.
+ * Executes provided callback if scroll threshold is reached. Usuable to determine
+ * if user reached the bottom of an element to load new elements on the fly.
*
- * @param string className
- * @param jQuery containerList
- * @param string buttonSelector
+ * If you do not provide a value for 'reference' and 'target' it will assume you're
+ * monitoring page scrolls, otherwise a valid jQuery selector must be provided for both.
+ *
+ * @param integer threshold
+ * @param object callback
+ * @param string reference
+ * @param string target
*/
-WCF.Action.Toggle = Class.extend({
+WCF.Action.Scroll = Class.extend({
/**
- * toogle button selector
- * @var string
+ * callback used once threshold is reached
+ * @var object
*/
- _buttonSelector: '.jsToggleButton',
+ _callback: null,
/**
- * action class name
- * @var string
+ * reference object
+ * @var jQuery
*/
- _className: '',
+ _reference: null,
/**
- * container selector
- * @var string
+ * target object
+ * @var jQuery
*/
- _containerSelector: '',
+ _target: null,
/**
- * list of known container ids
- * @var array<string>
+ * threshold value
+ * @var integer
*/
- _containers: [ ],
+ _threshold: 0,
/**
- * Initializes 'toggle'-Proxy
+ * Initializes a new WCF.Action.Scroll object.
*
- * @param string className
- * @param string containerSelector
- * @param string buttonSelector
+ * @param integer threshold
+ * @param object callback
+ * @param string reference
+ * @param string target
*/
- init: function(className, containerSelector, buttonSelector) {
- this._containerSelector = containerSelector;
- this._className = className;
- this._buttonSelector = (buttonSelector) ? buttonSelector : '.jsToggleButton';
- this._containers = [ ];
+ init: function(threshold, callback, reference, target) {
+ this._threshold = parseInt(threshold);
+ if (this._threshold === 0) {
+ console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting.");
+ return;
+ }
- // initialize proxy
- var options = {
- success: $.proxy(this._success, this)
- };
- this.proxy = new WCF.Action.Proxy(options);
+ if ($.isFunction(callback)) this._callback = callback;
+ if (this._callback === null) {
+ console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting.");
+ return;
+ }
- // bind event listener
- this._initElements();
- WCF.DOMNodeInsertedHandler.addCallback('WCF.Action.Toggle' + this._className.hashCode(), $.proxy(this._initElements, this));
+ // bind element references
+ this._reference = $((reference) ? reference : window);
+ this._target = $((target) ? target : document);
+
+ // watch for scroll event
+ this.start();
+
+ // check if browser navigated back and jumped to offset before JavaScript was loaded
+ this._scroll();
},
/**
- * Initializes available element containers.
- */
- _initElements: function() {
- $(this._containerSelector).each($.proxy(function(index, container) {
- var $container = $(container);
- var $containerID = $container.wcfIdentify();
-
- if (!WCF.inArray($containerID, this._containers)) {
- this._containers.push($containerID);
- $container.find(this._buttonSelector).click($.proxy(this._click, this));
- }
- }, this));
- },
-
- /**
- * Sends AJAX request.
- *
- * @param object event
- */
- _click: function(event) {
- var $target = $(event.currentTarget);
- event.preventDefault();
-
- if ($target.data('confirmMessageHtml') || $target.data('confirmMessage')) {
- WCF.System.Confirmation.show($target.data('confirmMessageHtml') ? $target.data('confirmMessageHtml') : $target.data('confirmMessage'), $.proxy(this._execute, this), { target: $target }, undefined, $target.data('confirmMessageHtml') ? true : false);
- }
- else {
- WCF.LoadingOverlayHandler.updateIcon($target);
- this._sendRequest($target);
- }
- },
-
- /**
- * Executes toggeling.
- *
- * @param string action
- * @param object parameters
- */
- _execute: function(action, parameters) {
- if (action === 'cancel') {
- return;
- }
-
- WCF.LoadingOverlayHandler.updateIcon(parameters.target);
- this._sendRequest(parameters.target);
- },
-
- _sendRequest: function(object) {
- this.proxy.setOption('data', {
- actionName: 'toggle',
- className: this._className,
- interfaceName: 'wcf\\data\\IToggleAction',
- objectIDs: [ $(object).data('objectID') ]
- });
-
- this.proxy.sendRequest();
- },
-
- /**
- * Toggles status icons.
- *
- * @param object data
- * @param string textStatus
- * @param object jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- this.triggerEffect(data.objectIDs);
- },
-
- /**
- * Triggers the toggle effect for the objects with the given ids.
- *
- * @param array objectIDs
- */
- triggerEffect: function(objectIDs) {
- for (var $index in this._containers) {
- var $container = $('#' + this._containers[$index]);
- var $toggleButton = $container.find(this._buttonSelector);
- if (WCF.inArray($toggleButton.data('objectID'), objectIDs)) {
- $container.wcfHighlight();
- this._toggleButton($container, $toggleButton);
- }
- }
- },
-
- /**
- * Tiggers the toggle effect on a button
- *
- * @param jQuery $container
- * @param jQuery $toggleButton
- */
- _toggleButton: function($container, $toggleButton) {
- var $newTitle = '';
-
- // toggle icon source
- WCF.LoadingOverlayHandler.updateIcon($toggleButton, false);
- if ($toggleButton.hasClass('fa-square-o')) {
- $toggleButton.removeClass('fa-square-o').addClass('fa-check-square-o');
- $newTitle = ($toggleButton.data('disableTitle') ? $toggleButton.data('disableTitle') : WCF.Language.get('wcf.global.button.disable'));
- $toggleButton.attr('title', $newTitle);
- }
- else {
- $toggleButton.removeClass('fa-check-square-o').addClass('fa-square-o');
- $newTitle = ($toggleButton.data('enableTitle') ? $toggleButton.data('enableTitle') : WCF.Language.get('wcf.global.button.enable'));
- $toggleButton.attr('title', $newTitle);
- }
-
- // toggle css class
- $container.toggleClass('disabled');
- }
-});
-
-/**
- * Executes provided callback if scroll threshold is reached. Usuable to determine
- * if user reached the bottom of an element to load new elements on the fly.
- *
- * If you do not provide a value for 'reference' and 'target' it will assume you're
- * monitoring page scrolls, otherwise a valid jQuery selector must be provided for both.
- *
- * @param integer threshold
- * @param object callback
- * @param string reference
- * @param string target
- */
-WCF.Action.Scroll = Class.extend({
- /**
- * callback used once threshold is reached
- * @var object
- */
- _callback: null,
-
- /**
- * reference object
- * @var jQuery
- */
- _reference: null,
-
- /**
- * target object
- * @var jQuery
- */
- _target: null,
-
- /**
- * threshold value
- * @var integer
- */
- _threshold: 0,
-
- /**
- * Initializes a new WCF.Action.Scroll object.
- *
- * @param integer threshold
- * @param object callback
- * @param string reference
- * @param string target
- */
- init: function(threshold, callback, reference, target) {
- this._threshold = parseInt(threshold);
- if (this._threshold === 0) {
- console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting.");
- return;
- }
-
- if ($.isFunction(callback)) this._callback = callback;
- if (this._callback === null) {
- console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting.");
- return;
- }
-
- // bind element references
- this._reference = $((reference) ? reference : window);
- this._target = $((target) ? target : document);
-
- // watch for scroll event
- this.start();
-
- // check if browser navigated back and jumped to offset before JavaScript was loaded
- this._scroll();
- },
-
- /**
- * Calculates if threshold is reached and notifies callback.
+ * Calculates if threshold is reached and notifies callback.
*/
_scroll: function() {
var $targetHeight = this._target.height();
* @param jQuery buttonContainer
*/
_createButton: function(containerID, buttonContainer) {
- var $isOpen = this._containers[containerID].data('isOpen');
var $button = $('<span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-down" title="'+WCF.Language.get('wcf.global.button.collapsible')+'">').prependTo(buttonContainer);
$button.data('containerID', containerID).click($.proxy(this._toggleContainer, this));
*/
WCF.Option = { };
-/**
- * Handles option selection.
- */
-WCF.Option.Handler = Class.extend({
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes the WCF.Option.Handler class.
+ * Handles option selection.
*/
- init: function() {
- this._initOptions();
+ WCF.Option.Handler = Class.extend({
+ /**
+ * Initializes the WCF.Option.Handler class.
+ */
+ init: function () {
+ this._initOptions();
+
+ WCF.DOMNodeInsertedHandler.addCallback('WCF.Option.Handler', $.proxy(this._initOptions, this));
+ },
- WCF.DOMNodeInsertedHandler.addCallback('WCF.Option.Handler', $.proxy(this._initOptions, this));
- },
-
- /**
- * Initializes all options.
- */
- _initOptions: function() {
- $('.jsEnablesOptions').each($.proxy(this._initOption, this));
- },
-
- /**
- * Initializes an option.
- *
- * @param integer index
- * @param object option
- */
- _initOption: function(index, option) {
- // execute action on init
- this._change(option);
+ /**
+ * Initializes all options.
+ */
+ _initOptions: function () {
+ $('.jsEnablesOptions').each($.proxy(this._initOption, this));
+ },
- // bind event listener
- $(option).change($.proxy(this._handleChange, this));
- },
-
- /**
- * Applies whenever an option is changed.
- *
- * @param object event
- */
- _handleChange: function(event) {
- this._change($(event.target));
- },
-
- /**
- * Enables or disables options on option value change.
- *
- * @param object option
- */
- _change: function(option) {
- option = $(option);
+ /**
+ * Initializes an option.
+ *
+ * @param integer index
+ * @param object option
+ */
+ _initOption: function (index, option) {
+ // execute action on init
+ this._change(option);
+
+ // bind event listener
+ $(option).change($.proxy(this._handleChange, this));
+ },
- var disableOptions = eval(option.data('disableOptions'));
- var enableOptions = eval(option.data('enableOptions'));
+ /**
+ * Applies whenever an option is changed.
+ *
+ * @param object event
+ */
+ _handleChange: function (event) {
+ this._change($(event.target));
+ },
- // determine action by type
- switch(option.getTagName()) {
- case 'input':
- switch(option.attr('type')) {
- case 'checkbox':
- this._execute(option.prop('checked'), disableOptions, enableOptions);
+ /**
+ * Enables or disables options on option value change.
+ *
+ * @param object option
+ */
+ _change: function (option) {
+ option = $(option);
+
+ var disableOptions = eval(option.data('disableOptions'));
+ var enableOptions = eval(option.data('enableOptions'));
+
+ // determine action by type
+ switch (option.getTagName()) {
+ case 'input':
+ switch (option.attr('type')) {
+ case 'checkbox':
+ this._execute(option.prop('checked'), disableOptions, enableOptions);
+ break;
+
+ case 'radio':
+ if (option.prop('checked')) {
+ var isActive = true;
+ if (option.data('isBoolean') && option.val() != 1) {
+ isActive = false;
+ }
+
+ this._execute(isActive, disableOptions, enableOptions);
+ }
+ break;
+ }
break;
+
+ case 'select':
+ var $value = option.val();
+ var relevantDisableOptions = [];
+ var relevantEnableOptions = [];
- case 'radio':
- if (option.prop('checked')) {
- var isActive = true;
- if (option.data('isBoolean') && option.val() != 1) {
- isActive = false;
+ if (disableOptions.length > 0) {
+ for (var $index in disableOptions) {
+ var $item = disableOptions[$index];
+
+ if ($item.value == $value) {
+ relevantDisableOptions.push($item.option);
}
+ else {
+ relevantEnableOptions.push($item.option);
+ }
+ }
+ }
+
+ if (enableOptions.length > 0) {
+ for (var $index in enableOptions) {
+ var $item = enableOptions[$index];
- this._execute(isActive, disableOptions, enableOptions);
+ if ($item.value == $value) {
+ relevantEnableOptions.push($item.option);
+ }
+ else {
+ relevantDisableOptions.push($item.option);
+ }
}
+ }
+
+ this._execute(true, relevantDisableOptions, relevantEnableOptions);
break;
- }
- break;
-
- case 'select':
- var $value = option.val();
- var relevantDisableOptions = [];
- var relevantEnableOptions = [];
-
- if (disableOptions.length > 0) {
- for (var $index in disableOptions) {
- var $item = disableOptions[$index];
-
- if ($item.value == $value) {
- relevantDisableOptions.push($item.option);
- }
- else {
- relevantEnableOptions.push($item.option);
+ }
+ },
+
+ /**
+ * Enables or disables options.
+ *
+ * @param boolean isActive
+ * @param array disableOptions
+ * @param array enableOptions
+ */
+ _execute: function (isActive, disableOptions, enableOptions) {
+ if (disableOptions.length > 0) {
+ for (var $i = 0, $size = disableOptions.length; $i < $size; $i++) {
+ var $target = disableOptions[$i];
+ if ($.wcfIsset($target)) {
+ this._enableOption($target, !isActive);
+ }
+ else {
+ var $dl = $('.' + $target + 'Input');
+ if ($dl.length) {
+ this._enableOptions($dl.children('dd').find('input, select, textarea'), !isActive);
}
}
}
-
- if (enableOptions.length > 0) {
- for (var $index in enableOptions) {
- var $item = enableOptions[$index];
-
- if ($item.value == $value) {
- relevantEnableOptions.push($item.option);
- }
- else {
- relevantDisableOptions.push($item.option);
+ }
+
+ if (enableOptions.length > 0) {
+ for (var $i = 0, $size = enableOptions.length; $i < $size; $i++) {
+ var $target = enableOptions[$i];
+ if ($.wcfIsset($target)) {
+ this._enableOption($target, isActive);
+ }
+ else {
+ var $dl = $('.' + $target + 'Input');
+ if ($dl.length) {
+ this._enableOptions($dl.children('dd').find('input, select, textarea'), isActive);
}
}
}
+ }
+ },
+
+ /**
+ * Enables/Disables an option.
+ *
+ * @param string target
+ * @param boolean enable
+ */
+ _enableOption: function (target, enable) {
+ this._enableOptionElement($('#' + $.wcfEscapeID(target)), enable);
+ },
+
+ /**
+ * Enables/Disables an option element.
+ *
+ * @param string target
+ * @param boolean enable
+ */
+ _enableOptionElement: function (element, enable) {
+ element = $(element);
+ var $tagName = element.getTagName();
+
+ if ($tagName == 'select' || ($tagName == 'input' && (element.attr('type') == 'checkbox' || element.attr('type') == 'file' || element.attr('type') == 'radio'))) {
+ if (enable) element.enable();
+ else element.disable();
- this._execute(true, relevantDisableOptions, relevantEnableOptions);
- break;
- }
- },
-
- /**
- * Enables or disables options.
- *
- * @param boolean isActive
- * @param array disableOptions
- * @param array enableOptions
- */
- _execute: function(isActive, disableOptions, enableOptions) {
- if (disableOptions.length > 0) {
- for (var $i = 0, $size = disableOptions.length; $i < $size; $i++) {
- var $target = disableOptions[$i];
- if ($.wcfIsset($target)) {
- this._enableOption($target, !isActive);
- }
- else {
- var $dl = $('.' + $target + 'Input');
- if ($dl.length) {
- this._enableOptions($dl.children('dd').find('input, select, textarea'), !isActive);
- }
+ if (element.parents('.optionTypeBoolean:eq(0)')) {
+ var noElement = $('#' + element.wcfIdentify() + '_no');
+ if (enable) noElement.enable();
+ else noElement.disable();
}
}
- }
+ else {
+ if (enable) element.removeAttr('readonly');
+ else element.attr('readonly', true);
+ }
+
+ if (enable) {
+ element.closest('dl').removeClass('disabled');
+ }
+ else {
+ element.closest('dl').addClass('disabled');
+ }
+ },
- if (enableOptions.length > 0) {
- for (var $i = 0, $size = enableOptions.length; $i < $size; $i++) {
- var $target = enableOptions[$i];
- if ($.wcfIsset($target)) {
- this._enableOption($target, isActive);
- }
- else {
- var $dl = $('.' + $target + 'Input');
- if ($dl.length) {
- this._enableOptions($dl.children('dd').find('input, select, textarea'), isActive);
- }
- }
+ /**
+ * Enables/Disables an option consisting of multiple form elements.
+ *
+ * @param string target
+ * @param boolean enable
+ */
+ _enableOptions: function (targets, enable) {
+ for (var $i = 0, $length = targets.length; $i < $length; $i++) {
+ this._enableOptionElement(targets[$i], enable);
}
}
- },
-
+ });
+}
+else {
+ WCF.Option.Handler = Class.extend({
+ init: function() {},
+ _initOptions: function() {},
+ _initOption: function() {},
+ _handleChange: function() {},
+ _change: function() {},
+ _execute: function() {},
+ _enableOption: function() {},
+ _enableOptionElement: function() {},
+ _enableOptions: function() {}
+ });
+}
+
+WCF.PageVisibilityHandler = {
/**
- * Enables/Disables an option.
- *
- * @param string target
- * @param boolean enable
+ * list of callbacks
+ * @var WCF.Dictionary
*/
- _enableOption: function(target, enable) {
- this._enableOptionElement($('#' + $.wcfEscapeID(target)), enable);
- },
+ _callbacks: new WCF.Dictionary(),
/**
- * Enables/Disables an option element.
- *
- * @param string target
- * @param boolean enable
- */
- _enableOptionElement: function(element, enable) {
- element = $(element);
- var $tagName = element.getTagName();
-
- if ($tagName == 'select' || ($tagName == 'input' && (element.attr('type') == 'checkbox' || element.attr('type') == 'file' || element.attr('type') == 'radio'))) {
- if (enable) element.enable();
- else element.disable();
-
- if (element.parents('.optionTypeBoolean:eq(0)')) {
- var noElement = $('#' + element.wcfIdentify() + '_no');
- if (enable) noElement.enable();
- else noElement.disable();
- }
- }
- else {
- if (enable) element.removeAttr('readonly');
- else element.attr('readonly', true);
- }
-
- if (enable) {
- element.closest('dl').removeClass('disabled');
- }
- else {
- element.closest('dl').addClass('disabled');
- }
- },
-
- /**
- * Enables/Disables an option consisting of multiple form elements.
- *
- * @param string target
- * @param boolean enable
- */
- _enableOptions: function(targets, enable) {
- for (var $i = 0, $length = targets.length; $i < $length; $i++) {
- this._enableOptionElement(targets[$i], enable);
- }
- }
-});
-
-WCF.PageVisibilityHandler = {
- /**
- * list of callbacks
- * @var WCF.Dictionary
- */
- _callbacks: new WCF.Dictionary(),
-
- /**
- * indicates that event listeners are bound
- * @var boolean
+ * indicates that event listeners are bound
+ * @var boolean
*/
_isListening: false,
case 37: // arrow-left
case 39: // arrow-right
return;
- break;
case 38: // arrow up
this._selectPreviousItem();
return;
- break;
case 40: // arrow down
this._selectNextItem();
return;
- break;
case 13: // return key
return this._selectElement(event);
- break;
}
var $content = this._getSearchString(event);
}
};
-/**
- * Worker support for frontend based upon DatabaseObjectActions.
- *
- * @param string className
- * @param string title
- * @param object parameters
- * @param object callback
- */
-WCF.System.Worker = Class.extend({
- /**
- * worker aborted
- * @var boolean
- */
- _aborted: false,
-
- /**
- * DBOAction method name
- * @var string
- */
- _actionName: '',
-
- /**
- * callback invoked after worker completed
- * @var object
- */
- _callback: null,
-
- /**
- * DBOAction class name
- * @var string
- */
- _className: '',
-
- /**
- * dialog object
- * @var jQuery
- */
- _dialog: null,
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * dialog title
- * @var string
- */
- _title: '',
-
- /**
- * Initializes a new worker instance.
- *
- * @param string actionName
- * @param string className
- * @param string title
- * @param object parameters
- * @param object callback
- * @param object confirmMessage
- */
- init: function(actionName, className, title, parameters, callback) {
- this._aborted = false;
- this._actionName = actionName;
- this._callback = callback || null;
- this._className = className;
- this._dialog = null;
- this._proxy = new WCF.Action.Proxy({
- autoSend: true,
- data: {
- actionName: this._actionName,
- className: this._className,
- parameters: parameters || { }
- },
- showLoadingOverlay: false,
- success: $.proxy(this._success, this)
- });
- this._title = title;
- },
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Handles response from server.
- *
- * @param object data
+ * Worker support for frontend based upon DatabaseObjectActions.
+ *
+ * @param string className
+ * @param string title
+ * @param object parameters
+ * @param object callback
*/
- _success: function(data) {
- // init binding
- if (this._dialog === null) {
- this._dialog = $('<div />').hide().appendTo(document.body);
- this._dialog.wcfDialog({
- closeConfirmMessage: WCF.Language.get('wcf.worker.abort.confirmMessage'),
- closeViaModal: false,
- onClose: $.proxy(function() {
- this._aborted = true;
- this._proxy.abortPrevious();
-
- window.location.reload();
- }, this),
- title: this._title
- });
- }
+ WCF.System.Worker = Class.extend({
+ /**
+ * worker aborted
+ * @var boolean
+ */
+ _aborted: false,
- if (this._aborted) {
- return;
- }
+ /**
+ * DBOAction method name
+ * @var string
+ */
+ _actionName: '',
- if (data.returnValues.template) {
- this._dialog.html(data.returnValues.template);
- }
+ /**
+ * callback invoked after worker completed
+ * @var object
+ */
+ _callback: null,
- // update progress
- this._dialog.find('progress').attr('value', data.returnValues.progress).text(data.returnValues.progress + '%').next('span').text(data.returnValues.progress + '%');
+ /**
+ * DBOAction class name
+ * @var string
+ */
+ _className: '',
- // worker is still busy with its business, carry on
- if (data.returnValues.progress < 100) {
- // send request for next loop
- var $parameters = data.returnValues.parameters || { };
- $parameters.loopCount = data.returnValues.loopCount;
-
- this._proxy.setOption('data', {
- actionName: this._actionName,
- className: this._className,
- parameters: $parameters
- });
- this._proxy.sendRequest();
- }
- else if (this._callback !== null) {
- this._callback(this, data);
- }
- else {
- // exchange icon
- this._dialog.find('.fa-spinner').removeClass('fa-spinner').addClass('fa-check green');
- this._dialog.find('.contentHeader h1').text(WCF.Language.get('wcf.global.worker.completed'));
-
- // display continue button
- var $formSubmit = $('<div class="formSubmit" />').appendTo(this._dialog);
- $('<button class="buttonPrimary">' + WCF.Language.get('wcf.global.button.next') + '</button>').appendTo($formSubmit).focus().click(function() {
- if (data.returnValues.redirectURL) {
- window.location = data.returnValues.redirectURL;
- }
- else {
- window.location.reload();
- }
+ /**
+ * dialog object
+ * @var jQuery
+ */
+ _dialog: null,
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * dialog title
+ * @var string
+ */
+ _title: '',
+
+ /**
+ * Initializes a new worker instance.
+ *
+ * @param string actionName
+ * @param string className
+ * @param string title
+ * @param object parameters
+ * @param object callback
+ * @param object confirmMessage
+ */
+ init: function (actionName, className, title, parameters, callback) {
+ this._aborted = false;
+ this._actionName = actionName;
+ this._callback = callback || null;
+ this._className = className;
+ this._dialog = null;
+ this._proxy = new WCF.Action.Proxy({
+ autoSend: true,
+ data: {
+ actionName: this._actionName,
+ className: this._className,
+ parameters: parameters || {}
+ },
+ showLoadingOverlay: false,
+ success: $.proxy(this._success, this)
});
-
- this._dialog.wcfDialog('render');
- }
- }
-});
-
-/**
- * Default implementation for inline editors.
- *
- * @param string elementSelector
- */
-WCF.InlineEditor = Class.extend({
- /**
- * list of registered callbacks
- * @var array<object>
- */
- _callbacks: [ ],
-
- /**
- * list of dropdown selections
- * @var object
- */
- _dropdowns: { },
-
- /**
- * list of container elements
- * @var object
- */
- _elements: { },
-
- /**
- * notification object
- * @var WCF.System.Notification
- */
- _notification: null,
-
- /**
- * list of known options
- * @var array<object>
- */
- _options: [ ],
-
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * list of trigger elements by element id
- * @var object<object>
- */
- _triggerElements: { },
-
- /**
- * list of data to update upon success
- * @var array<object>
- */
- _updateData: [ ],
-
- /**
- * Initializes a new inline editor.
- */
- init: function(elementSelector) {
- var $elements = $(elementSelector);
- if (!$elements.length) {
- return;
- }
+ this._title = title;
+ },
- this._setOptions();
- var $quickOption = '';
- for (var $i = 0, $length = this._options.length; $i < $length; $i++) {
- if (this._options[$i].isQuickOption) {
- $quickOption = this._options[$i].optionName;
- break;
+ /**
+ * Handles response from server.
+ *
+ * @param object data
+ */
+ _success: function (data) {
+ // init binding
+ if (this._dialog === null) {
+ this._dialog = $('<div />').hide().appendTo(document.body);
+ this._dialog.wcfDialog({
+ closeConfirmMessage: WCF.Language.get('wcf.worker.abort.confirmMessage'),
+ closeViaModal: false,
+ onClose: $.proxy(function () {
+ this._aborted = true;
+ this._proxy.abortPrevious();
+
+ window.location.reload();
+ }, this),
+ title: this._title
+ });
}
- }
-
- var self = this;
- $elements.each(function(index, element) {
- var $element = $(element);
- var $elementID = $element.wcfIdentify();
- // find trigger element
- var $trigger = self._getTriggerElement($element);
- if ($trigger === null || $trigger.length !== 1) {
+ if (this._aborted) {
return;
}
- $trigger.on(WCF_CLICK_EVENT, $.proxy(self._show, self)).data('elementID', $elementID);
- if ($quickOption) {
- // simulate click on target action
- $trigger.disableSelection().data('optionName', $quickOption).dblclick($.proxy(self._click, self));
- }
-
- // store reference
- self._elements[$elementID] = $element;
- });
-
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- WCF.CloseOverlayHandler.addCallback('WCF.InlineEditor', $.proxy(this._closeAll, this));
-
- this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'), 'success');
- },
-
- /**
- * Closes all inline editors.
- */
- _closeAll: function() {
- for (var $elementID in this._elements) {
- this._hide($elementID);
- }
- },
-
- /**
- * Sets options for this inline editor.
- */
- _setOptions: function() {
- this._options = [ ];
- },
-
- /**
- * Register an option callback for validation and execution.
- *
- * @param object callback
- */
- registerCallback: function(callback) {
- if ($.isFunction(callback)) {
- this._callbacks.push(callback);
- }
- },
-
- /**
- * Returns the triggering element.
- *
- * @param jQuery element
- * @return jQuery
- */
- _getTriggerElement: function(element) {
- return null;
- },
-
- /**
- * Shows a dropdown menu if options are available.
- *
- * @param object event
- */
- _show: function(event) {
- event.preventDefault();
- var $elementID = $(event.currentTarget).data('elementID');
-
- // build dropdown
- var $trigger = null;
- if (!this._dropdowns[$elementID]) {
- this._triggerElements[$elementID] = $trigger = this._getTriggerElement(this._elements[$elementID]).addClass('dropdownToggle');
- var parent = $trigger[0].parentNode;
- if (parent && parent.nodeName === 'LI' && parent.childElementCount === 1) {
- // do not add a wrapper element if the trigger is the only child
- parent.classList.add('dropdown');
- }
- else {
- $trigger.wrap('<span class="dropdown" />');
+ if (data.returnValues.template) {
+ this._dialog.html(data.returnValues.template);
}
- this._dropdowns[$elementID] = $('<ul class="dropdownMenu" />').insertAfter($trigger);
- }
- this._dropdowns[$elementID].empty();
-
- // validate options
- var $hasOptions = false;
- var $lastElementType = '';
- for (var $i = 0, $length = this._options.length; $i < $length; $i++) {
- var $option = this._options[$i];
+ // update progress
+ this._dialog.find('progress').attr('value', data.returnValues.progress).text(data.returnValues.progress + '%').next('span').text(data.returnValues.progress + '%');
- if ($option.optionName === 'divider') {
- if ($lastElementType !== '' && $lastElementType !== 'divider') {
- $('<li class="dropdownDivider" />').appendTo(this._dropdowns[$elementID]);
- $lastElementType = $option.optionName;
- }
- }
- else if (this._validate($elementID, $option.optionName) || this._validateCallbacks($elementID, $option.optionName)) {
- var $listItem = $('<li><span>' + $option.label + '</span></li>').appendTo(this._dropdowns[$elementID]);
- $listItem.data('elementID', $elementID).data('optionName', $option.optionName).data('isQuickOption', ($option.isQuickOption ? true : false)).click($.proxy(this._click, this));
+ // worker is still busy with its business, carry on
+ if (data.returnValues.progress < 100) {
+ // send request for next loop
+ var $parameters = data.returnValues.parameters || {};
+ $parameters.loopCount = data.returnValues.loopCount;
- $hasOptions = true;
- $lastElementType = $option.optionName;
+ this._proxy.setOption('data', {
+ actionName: this._actionName,
+ className: this._className,
+ parameters: $parameters
+ });
+ this._proxy.sendRequest();
}
- }
-
- if ($hasOptions) {
- // if last child is divider, remove it
- var $lastChild = this._dropdowns[$elementID].children().last();
- if ($lastChild.hasClass('dropdownDivider')) {
- $lastChild.remove();
+ else if (this._callback !== null) {
+ this._callback(this, data);
}
-
- // check if only element is a quick option
- var $quickOption = null;
- var $count = 0;
- this._dropdowns[$elementID].children().each(function(index, child) {
- var $child = $(child);
- if (!$child.hasClass('dropdownDivider')) {
- if ($child.data('isQuickOption')) {
- $quickOption = $child;
+ else {
+ // exchange icon
+ this._dialog.find('.fa-spinner').removeClass('fa-spinner').addClass('fa-check green');
+ this._dialog.find('.contentHeader h1').text(WCF.Language.get('wcf.global.worker.completed'));
+
+ // display continue button
+ var $formSubmit = $('<div class="formSubmit" />').appendTo(this._dialog);
+ $('<button class="buttonPrimary">' + WCF.Language.get('wcf.global.button.next') + '</button>').appendTo($formSubmit).focus().click(function () {
+ if (data.returnValues.redirectURL) {
+ window.location = data.returnValues.redirectURL;
}
else {
- $count++;
+ window.location.reload();
}
- }
- });
-
- if (!$count) {
- $quickOption.trigger('click');
-
- if (this._triggerElements[$elementID]) {
- WCF.Dropdown.close(this._triggerElements[$elementID].parents('.dropdown').wcfIdentify());
- }
+ });
- return false;
+ this._dialog.wcfDialog('render');
}
}
-
- if ($trigger !== null) {
- WCF.Dropdown.initDropdown($trigger, true);
- }
-
- return false;
- },
+ });
/**
- * Validates an option.
- *
- * @param string elementID
- * @param string optionName
- * @returns boolean
+ * Default implementation for inline editors.
+ *
+ * @param string elementSelector
*/
- _validate: function(elementID, optionName) {
- return false;
- },
-
- /**
- * Validates an option provided by callbacks.
- *
- * @param string elementID
- * @param string optionName
- * @return boolean
- */
- _validateCallbacks: function(elementID, optionName) {
- var $length = this._callbacks.length;
- if ($length) {
- for (var $i = 0; $i < $length; $i++) {
- if (this._callbacks[$i].validate(this._elements[elementID], optionName)) {
- return true;
+ WCF.InlineEditor = Class.extend({
+ /**
+ * list of registered callbacks
+ * @var array<object>
+ */
+ _callbacks: [],
+
+ /**
+ * list of dropdown selections
+ * @var object
+ */
+ _dropdowns: {},
+
+ /**
+ * list of container elements
+ * @var object
+ */
+ _elements: {},
+
+ /**
+ * notification object
+ * @var WCF.System.Notification
+ */
+ _notification: null,
+
+ /**
+ * list of known options
+ * @var array<object>
+ */
+ _options: [],
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * list of trigger elements by element id
+ * @var object<object>
+ */
+ _triggerElements: {},
+
+ /**
+ * list of data to update upon success
+ * @var array<object>
+ */
+ _updateData: [],
+
+ /**
+ * Initializes a new inline editor.
+ */
+ init: function (elementSelector) {
+ var $elements = $(elementSelector);
+ if (!$elements.length) {
+ return;
+ }
+
+ this._setOptions();
+ var $quickOption = '';
+ for (var $i = 0, $length = this._options.length; $i < $length; $i++) {
+ if (this._options[$i].isQuickOption) {
+ $quickOption = this._options[$i].optionName;
+ break;
}
}
- }
+
+ var self = this;
+ $elements.each(function (index, element) {
+ var $element = $(element);
+ var $elementID = $element.wcfIdentify();
+
+ // find trigger element
+ var $trigger = self._getTriggerElement($element);
+ if ($trigger === null || $trigger.length !== 1) {
+ return;
+ }
+
+ $trigger.on(WCF_CLICK_EVENT, $.proxy(self._show, self)).data('elementID', $elementID);
+ if ($quickOption) {
+ // simulate click on target action
+ $trigger.disableSelection().data('optionName', $quickOption).dblclick($.proxy(self._click, self));
+ }
+
+ // store reference
+ self._elements[$elementID] = $element;
+ });
+
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ WCF.CloseOverlayHandler.addCallback('WCF.InlineEditor', $.proxy(this._closeAll, this));
+
+ this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'), 'success');
+ },
- return false;
- },
-
- /**
- * Handles AJAX responses.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- var $length = this._updateData.length;
- if (!$length) {
- return;
- }
+ /**
+ * Closes all inline editors.
+ */
+ _closeAll: function () {
+ for (var $elementID in this._elements) {
+ this._hide($elementID);
+ }
+ },
- this._updateState(data);
+ /**
+ * Sets options for this inline editor.
+ */
+ _setOptions: function () {
+ this._options = [];
+ },
- this._updateData = [ ];
- },
-
- /**
- * Update element states based upon update data.
- *
- * @param object data
- */
- _updateState: function(data) { },
-
- /**
- * Handles clicks within dropdown.
- *
- * @param object event
- */
- _click: function(event) {
- var $listItem = $(event.currentTarget);
- var $elementID = $listItem.data('elementID');
- var $optionName = $listItem.data('optionName');
+ /**
+ * Register an option callback for validation and execution.
+ *
+ * @param object callback
+ */
+ registerCallback: function (callback) {
+ if ($.isFunction(callback)) {
+ this._callbacks.push(callback);
+ }
+ },
- if (!this._execute($elementID, $optionName)) {
- this._executeCallback($elementID, $optionName);
- }
+ /**
+ * Returns the triggering element.
+ *
+ * @param jQuery element
+ * @return jQuery
+ */
+ _getTriggerElement: function (element) {
+ return null;
+ },
- this._hide($elementID);
- },
-
- /**
- * Executes actions associated with an option.
- *
- * @param string elementID
- * @param string optionName
- * @return boolean
- */
- _execute: function(elementID, optionName) {
- return false;
- },
-
- /**
- * Executes actions associated with an option provided by callbacks.
- *
- * @param string elementID
- * @param string optionName
- * @return boolean
- */
- _executeCallback: function(elementID, optionName) {
- var $length = this._callbacks.length;
- if ($length) {
- for (var $i = 0; $i < $length; $i++) {
- if (this._callbacks[$i].execute(this._elements[elementID], optionName)) {
- return true;
+ /**
+ * Shows a dropdown menu if options are available.
+ *
+ * @param object event
+ */
+ _show: function (event) {
+ event.preventDefault();
+ var $elementID = $(event.currentTarget).data('elementID');
+
+ // build dropdown
+ var $trigger = null;
+ if (!this._dropdowns[$elementID]) {
+ this._triggerElements[$elementID] = $trigger = this._getTriggerElement(this._elements[$elementID]).addClass('dropdownToggle');
+ var parent = $trigger[0].parentNode;
+ if (parent && parent.nodeName === 'LI' && parent.childElementCount === 1) {
+ // do not add a wrapper element if the trigger is the only child
+ parent.classList.add('dropdown');
+ }
+ else {
+ $trigger.wrap('<span class="dropdown" />');
}
+
+ this._dropdowns[$elementID] = $('<ul class="dropdownMenu" />').insertAfter($trigger);
}
- }
+ this._dropdowns[$elementID].empty();
+
+ // validate options
+ var $hasOptions = false;
+ var $lastElementType = '';
+ for (var $i = 0, $length = this._options.length; $i < $length; $i++) {
+ var $option = this._options[$i];
+
+ if ($option.optionName === 'divider') {
+ if ($lastElementType !== '' && $lastElementType !== 'divider') {
+ $('<li class="dropdownDivider" />').appendTo(this._dropdowns[$elementID]);
+ $lastElementType = $option.optionName;
+ }
+ }
+ else if (this._validate($elementID, $option.optionName) || this._validateCallbacks($elementID, $option.optionName)) {
+ var $listItem = $('<li><span>' + $option.label + '</span></li>').appendTo(this._dropdowns[$elementID]);
+ $listItem.data('elementID', $elementID).data('optionName', $option.optionName).data('isQuickOption', ($option.isQuickOption ? true : false)).click($.proxy(this._click, this));
+
+ $hasOptions = true;
+ $lastElementType = $option.optionName;
+ }
+ }
+
+ if ($hasOptions) {
+ // if last child is divider, remove it
+ var $lastChild = this._dropdowns[$elementID].children().last();
+ if ($lastChild.hasClass('dropdownDivider')) {
+ $lastChild.remove();
+ }
+
+ // check if only element is a quick option
+ var $quickOption = null;
+ var $count = 0;
+ this._dropdowns[$elementID].children().each(function (index, child) {
+ var $child = $(child);
+ if (!$child.hasClass('dropdownDivider')) {
+ if ($child.data('isQuickOption')) {
+ $quickOption = $child;
+ }
+ else {
+ $count++;
+ }
+ }
+ });
+
+ if (!$count) {
+ $quickOption.trigger('click');
+
+ if (this._triggerElements[$elementID]) {
+ WCF.Dropdown.close(this._triggerElements[$elementID].parents('.dropdown').wcfIdentify());
+ }
+
+ return false;
+ }
+ }
+
+ if ($trigger !== null) {
+ WCF.Dropdown.initDropdown($trigger, true);
+ }
+
+ return false;
+ },
- return false;
- },
-
- /**
- * Hides a dropdown menu.
- *
- * @param string elementID
- */
- _hide: function(elementID) {
- if (this._dropdowns[elementID]) {
- this._dropdowns[elementID].empty().removeClass('dropdownOpen');
+ /**
+ * Validates an option.
+ *
+ * @param string elementID
+ * @param string optionName
+ * @returns boolean
+ */
+ _validate: function (elementID, optionName) {
+ return false;
+ },
+
+ /**
+ * Validates an option provided by callbacks.
+ *
+ * @param string elementID
+ * @param string optionName
+ * @return boolean
+ */
+ _validateCallbacks: function (elementID, optionName) {
+ var $length = this._callbacks.length;
+ if ($length) {
+ for (var $i = 0; $i < $length; $i++) {
+ if (this._callbacks[$i].validate(this._elements[elementID], optionName)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * Handles AJAX responses.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ var $length = this._updateData.length;
+ if (!$length) {
+ return;
+ }
+
+ this._updateState(data);
+
+ this._updateData = [];
+ },
+
+ /**
+ * Update element states based upon update data.
+ *
+ * @param object data
+ */
+ _updateState: function (data) {
+ },
+
+ /**
+ * Handles clicks within dropdown.
+ *
+ * @param object event
+ */
+ _click: function (event) {
+ var $listItem = $(event.currentTarget);
+ var $elementID = $listItem.data('elementID');
+ var $optionName = $listItem.data('optionName');
+
+ if (!this._execute($elementID, $optionName)) {
+ this._executeCallback($elementID, $optionName);
+ }
+
+ this._hide($elementID);
+ },
+
+ /**
+ * Executes actions associated with an option.
+ *
+ * @param string elementID
+ * @param string optionName
+ * @return boolean
+ */
+ _execute: function (elementID, optionName) {
+ return false;
+ },
+
+ /**
+ * Executes actions associated with an option provided by callbacks.
+ *
+ * @param string elementID
+ * @param string optionName
+ * @return boolean
+ */
+ _executeCallback: function (elementID, optionName) {
+ var $length = this._callbacks.length;
+ if ($length) {
+ for (var $i = 0; $i < $length; $i++) {
+ if (this._callbacks[$i].execute(this._elements[elementID], optionName)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * Hides a dropdown menu.
+ *
+ * @param string elementID
+ */
+ _hide: function (elementID) {
+ if (this._dropdowns[elementID]) {
+ this._dropdowns[elementID].empty().removeClass('dropdownOpen');
+ }
}
- }
-});
-
-/**
- * Default implementation for ajax file uploads.
- *
- * @deprecated Use WoltLabSuite/Core/Upload
- *
- * @param jquery buttonSelector
- * @param jquery fileListSelector
- * @param string className
- * @param jquery options
- */
-WCF.Upload = Class.extend({
- /**
- * name of the upload field
- * @var string
- */
- _name: '__files[]',
-
- /**
- * button selector
- * @var jQuery
- */
- _buttonSelector: null,
-
- /**
- * file list selector
- * @var jQuery
- */
- _fileListSelector: null,
-
- /**
- * upload file
- * @var jQuery
- */
- _fileUpload: null,
-
- /**
- * class name
- * @var string
- */
- _className: '',
-
- /**
- * iframe for IE<10 fallback
- * @var jQuery
- */
- _iframe: null,
-
- /**
- * internal file id
- * @var integer
- */
- _internalFileID: 0,
-
- /**
- * additional options
- * @var jQuery
- */
- _options: {},
-
- /**
- * upload matrix
- * @var array
- */
- _uploadMatrix: [],
-
- /**
- * true, if the active user's browser supports ajax file uploads
- * @var boolean
- */
- _supportsAJAXUpload: true,
-
- /**
- * fallback overlay for stupid browsers
- * @var jquery
- */
- _overlay: null,
+ });
/**
- * Initializes a new upload handler.
- *
- * @param string buttonSelector
- * @param string fileListSelector
- * @param string className
- * @param object options
+ * Default implementation for ajax file uploads.
+ *
+ * @deprecated Use WoltLabSuite/Core/Upload
+ *
+ * @param jquery buttonSelector
+ * @param jquery fileListSelector
+ * @param string className
+ * @param jquery options
*/
- init: function(buttonSelector, fileListSelector, className, options) {
- this._buttonSelector = buttonSelector;
- this._fileListSelector = fileListSelector;
- this._className = className;
- this._internalFileID = 0;
- this._options = $.extend(true, {
- action: 'upload',
- multiple: false,
- url: 'index.php?ajax-upload/&t=' + SECURITY_TOKEN
- }, options || { });
+ WCF.Upload = Class.extend({
+ /**
+ * name of the upload field
+ * @var string
+ */
+ _name: '__files[]',
- this._options.url = WCF.convertLegacyURL(this._options.url);
- if (this._options.url.indexOf('index.php') === 0) {
- this._options.url = WSC_API_URL + this._options.url;
- }
+ /**
+ * button selector
+ * @var jQuery
+ */
+ _buttonSelector: null,
- // check for ajax upload support
- var $xhr = new XMLHttpRequest();
- this._supportsAJAXUpload = ($xhr && ('upload' in $xhr) && ('onprogress' in $xhr.upload));
+ /**
+ * file list selector
+ * @var jQuery
+ */
+ _fileListSelector: null,
- // create upload button
- this._createButton();
- },
-
- /**
- * Creates the upload button.
- */
- _createButton: function() {
- if (this._supportsAJAXUpload) {
- this._fileUpload = $('<input type="file" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/>');
- this._fileUpload.change($.proxy(this._upload, this));
- var $button = $('<p class="button uploadButton"><span>' + WCF.Language.get('wcf.global.button.upload') + '</span></p>');
- $button.prepend(this._fileUpload);
- }
- else {
- var $button = $('<p class="button uploadFallbackButton"><span>' + WCF.Language.get('wcf.global.button.upload') + '</span></p>');
- $button.click($.proxy(this._showOverlay, this));
- }
+ /**
+ * upload file
+ * @var jQuery
+ */
+ _fileUpload: null,
- this._insertButton($button);
- },
-
- /**
- * Inserts the upload button.
- *
- * @param jQuery button
- */
- _insertButton: function(button) {
- this._buttonSelector.prepend(button);
- },
-
- /**
- * Removes the upload button.
- */
- _removeButton: function() {
- var $selector = '.uploadButton';
- if (!this._supportsAJAXUpload) {
- $selector = '.uploadFallbackButton';
- }
+ /**
+ * class name
+ * @var string
+ */
+ _className: '',
- this._buttonSelector.find($selector).remove();
- },
+ /**
+ * iframe for IE<10 fallback
+ * @var jQuery
+ */
+ _iframe: null,
+
+ /**
+ * internal file id
+ * @var integer
+ */
+ _internalFileID: 0,
+
+ /**
+ * additional options
+ * @var jQuery
+ */
+ _options: {},
+
+ /**
+ * upload matrix
+ * @var array
+ */
+ _uploadMatrix: [],
+
+ /**
+ * true, if the active user's browser supports ajax file uploads
+ * @var boolean
+ */
+ _supportsAJAXUpload: true,
+
+ /**
+ * fallback overlay for stupid browsers
+ * @var jquery
+ */
+ _overlay: null,
+
+ /**
+ * Initializes a new upload handler.
+ *
+ * @param string buttonSelector
+ * @param string fileListSelector
+ * @param string className
+ * @param object options
+ */
+ init: function (buttonSelector, fileListSelector, className, options) {
+ this._buttonSelector = buttonSelector;
+ this._fileListSelector = fileListSelector;
+ this._className = className;
+ this._internalFileID = 0;
+ this._options = $.extend(true, {
+ action: 'upload',
+ multiple: false,
+ url: 'index.php?ajax-upload/&t=' + SECURITY_TOKEN
+ }, options || {});
+
+ this._options.url = WCF.convertLegacyURL(this._options.url);
+ if (this._options.url.indexOf('index.php') === 0) {
+ this._options.url = WSC_API_URL + this._options.url;
+ }
+
+ // check for ajax upload support
+ var $xhr = new XMLHttpRequest();
+ this._supportsAJAXUpload = ($xhr && ('upload' in $xhr) && ('onprogress' in $xhr.upload));
+
+ // create upload button
+ this._createButton();
+ },
+
+ /**
+ * Creates the upload button.
+ */
+ _createButton: function () {
+ if (this._supportsAJAXUpload) {
+ this._fileUpload = $('<input type="file" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/>');
+ this._fileUpload.change($.proxy(this._upload, this));
+ var $button = $('<p class="button uploadButton"><span>' + WCF.Language.get('wcf.global.button.upload') + '</span></p>');
+ $button.prepend(this._fileUpload);
+ }
+ else {
+ var $button = $('<p class="button uploadFallbackButton"><span>' + WCF.Language.get('wcf.global.button.upload') + '</span></p>');
+ $button.click($.proxy(this._showOverlay, this));
+ }
+
+ this._insertButton($button);
+ },
+
+ /**
+ * Inserts the upload button.
+ *
+ * @param jQuery button
+ */
+ _insertButton: function (button) {
+ this._buttonSelector.prepend(button);
+ },
+
+ /**
+ * Removes the upload button.
+ */
+ _removeButton: function () {
+ var $selector = '.uploadButton';
+ if (!this._supportsAJAXUpload) {
+ $selector = '.uploadFallbackButton';
+ }
+
+ this._buttonSelector.find($selector).remove();
+ },
+
+ /**
+ * Callback for file uploads.
+ *
+ * @param object event
+ * @param File file
+ * @param Blob blob
+ * @return integer
+ */
+ _upload: function (event, file, blob) {
+ var $uploadID = null;
+ var $files = [];
+ if (file) {
+ $files.push(file);
+ }
+ else if (blob) {
+ var $ext = '';
+ switch (blob.type) {
+ case 'image/png':
+ $ext = '.png';
+ break;
+
+ case 'image/jpeg':
+ $ext = '.jpg';
+ break;
+
+ case 'image/gif':
+ $ext = '.gif';
+ break;
+ }
+
+ $files.push({
+ name: 'pasted-from-clipboard' + $ext
+ });
+ }
+ else {
+ $files = this._fileUpload.prop('files');
+ }
+
+ if ($files.length) {
+ var $fd = new FormData();
+ $uploadID = this._createUploadMatrix($files);
+
+ // no more files left, abort
+ if (!this._uploadMatrix[$uploadID].length) {
+ return null;
+ }
+
+ for (var $i = 0, $length = $files.length; $i < $length; $i++) {
+ if (this._uploadMatrix[$uploadID][$i]) {
+ var $internalFileID = this._uploadMatrix[$uploadID][$i].data('internalFileID');
+
+ if (blob) {
+ $fd.append('__files[' + $internalFileID + ']', blob, $files[$i].name);
+ }
+ else {
+ $fd.append('__files[' + $internalFileID + ']', $files[$i]);
+ }
+ }
+ }
+
+ $fd.append('actionName', this._options.action);
+ $fd.append('className', this._className);
+ var $additionalParameters = this._getParameters();
+ for (var $name in $additionalParameters) {
+ $fd.append('parameters[' + $name + ']', $additionalParameters[$name]);
+ }
+
+ var self = this;
+ $.ajax({
+ type: 'POST',
+ url: this._options.url,
+ enctype: 'multipart/form-data',
+ data: $fd,
+ contentType: false,
+ processData: false,
+ success: function (data, textStatus, jqXHR) {
+ self._success($uploadID, data);
+ },
+ error: $.proxy(this._error, this),
+ xhr: function () {
+ var $xhr = $.ajaxSettings.xhr();
+ if ($xhr) {
+ $xhr.upload.addEventListener('progress', function (event) {
+ self._progress($uploadID, event);
+ }, false);
+ }
+ return $xhr;
+ },
+ xhrFields: {
+ withCredentials: true
+ }
+ });
+ }
+
+ return $uploadID;
+ },
+
+ /**
+ * Creates upload matrix for provided files.
+ *
+ * @param array<object> files
+ * @return integer
+ */
+ _createUploadMatrix: function (files) {
+ if (files.length) {
+ var $uploadID = this._uploadMatrix.length;
+ this._uploadMatrix[$uploadID] = [];
+
+ for (var $i = 0, $length = files.length; $i < $length; $i++) {
+ var $file = files[$i];
+ var $li = this._initFile($file);
+
+ if (!$li.hasClass('uploadFailed')) {
+ $li.data('filename', $file.name).data('internalFileID', this._internalFileID++);
+ this._uploadMatrix[$uploadID][$i] = $li;
+ }
+ }
+
+ return $uploadID;
+ }
+
+ return null;
+ },
+
+ /**
+ * Callback for success event.
+ *
+ * @param integer uploadID
+ * @param object data
+ */
+ _success: function (uploadID, data) {
+ },
+
+ /**
+ * Callback for error event.
+ *
+ * @param jQuery jqXHR
+ * @param string textStatus
+ * @param string errorThrown
+ */
+ _error: function (jqXHR, textStatus, errorThrown) {
+ },
+
+ /**
+ * Callback for progress event.
+ *
+ * @param integer uploadID
+ * @param object event
+ */
+ _progress: function (uploadID, event) {
+ var $percentComplete = Math.round(event.loaded * 100 / event.total);
+
+ for (var $i in this._uploadMatrix[uploadID]) {
+ this._uploadMatrix[uploadID][$i].find('progress').attr('value', $percentComplete);
+ }
+ },
+
+ /**
+ * Returns additional parameters.
+ *
+ * @return object
+ */
+ _getParameters: function () {
+ return {};
+ },
+
+ /**
+ * Initializes list item for uploaded file.
+ *
+ * @return jQuery
+ */
+ _initFile: function (file) {
+ return $('<li>' + file.name + ' (' + file.size + ')<progress max="100" /></li>').appendTo(this._fileListSelector);
+ },
+
+ /**
+ * Shows the fallback overlay (work in progress)
+ */
+ _showOverlay: function () {
+ // create iframe
+ if (this._iframe === null) {
+ this._iframe = $('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body);
+ }
+
+ // create overlay
+ if (!this._overlay) {
+ this._overlay = $('<div><form enctype="multipart/form-data" method="post" action="' + this._options.url + '" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);
+
+ var $form = this._overlay.find('form');
+ $('<dl class="wide"><dd><input type="file" id="__fileUpload" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/></dd></dl>').appendTo($form);
+ $('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo($form);
+
+ $('<input type="hidden" name="isFallback" value="1" />').appendTo($form);
+ $('<input type="hidden" name="actionName" value="' + this._options.action + '" />').appendTo($form);
+ $('<input type="hidden" name="className" value="' + this._className + '" />').appendTo($form);
+ var $additionalParameters = this._getParameters();
+ for (var $name in $additionalParameters) {
+ $('<input type="hidden" name="' + $name + '" value="' + $additionalParameters[$name] + '" />').appendTo($form);
+ }
+
+ $form.submit($.proxy(function () {
+ var $file = {
+ name: this._getFilename(),
+ size: ''
+ };
+
+ var $uploadID = this._createUploadMatrix([$file]);
+ var self = this;
+ this._iframe.data('loading', true).off('load').load(function () {
+ self._evaluateResponse($uploadID);
+ });
+ this._overlay.wcfDialog('close');
+ }, this));
+ }
+
+ this._overlay.wcfDialog({
+ title: WCF.Language.get('wcf.global.button.upload')
+ });
+ },
+
+ /**
+ * Evaluates iframe response.
+ *
+ * @param integer uploadID
+ */
+ _evaluateResponse: function (uploadID) {
+ var $returnValues = $.parseJSON(this._iframe.contents().find('pre').html());
+ this._success(uploadID, $returnValues);
+ },
+
+ /**
+ * Returns name of selected file.
+ *
+ * @return string
+ */
+ _getFilename: function () {
+ return $('#__fileUpload').val().split('\\').pop();
+ }
+ });
/**
- * Callback for file uploads.
- *
- * @param object event
- * @param File file
- * @param Blob blob
- * @return integer
+ * Default implementation for parallel AJAX file uploads.
+ *
+ * @deprecated Use WoltLabSuite/Core/Upload
*/
- _upload: function(event, file, blob) {
- var $uploadID = null;
- var $files = [ ];
- if (file) {
- $files.push(file);
- }
- else if (blob) {
- var $ext = '';
- switch (blob.type) {
- case 'image/png':
- $ext = '.png';
- break;
-
- case 'image/jpeg':
- $ext = '.jpg';
- break;
-
- case 'image/gif':
- $ext = '.gif';
- break;
- }
-
- $files.push({
- name: 'pasted-from-clipboard' + $ext
+ WCF.Upload.Parallel = WCF.Upload.extend({
+ /**
+ * @see WCF.Upload.init()
+ */
+ init: function (buttonSelector, fileListSelector, className, options) {
+ // force multiple uploads
+ options = $.extend(true, options || {}, {
+ multiple: true
});
- }
- else {
- $files = this._fileUpload.prop('files');
- }
-
- if ($files.length) {
- var $fd = new FormData();
- $uploadID = this._createUploadMatrix($files);
-
- // no more files left, abort
- if (!this._uploadMatrix[$uploadID].length) {
- return null;
- }
+ this._super(buttonSelector, fileListSelector, className, options);
+ },
+
+ /**
+ * @see WCF.Upload._upload()
+ */
+ _upload: function () {
+ var $files = this._fileUpload.prop('files');
for (var $i = 0, $length = $files.length; $i < $length; $i++) {
- if (this._uploadMatrix[$uploadID][$i]) {
- var $internalFileID = this._uploadMatrix[$uploadID][$i].data('internalFileID');
-
- if (blob) {
- $fd.append('__files[' + $internalFileID + ']', blob, $files[$i].name);
- }
- else {
- $fd.append('__files[' + $internalFileID + ']', $files[$i]);
- }
+ var $file = $files[$i];
+ var $formData = new FormData();
+ var $internalFileID = this._createUploadMatrix($file);
+
+ if (!this._uploadMatrix[$internalFileID].length) {
+ continue;
}
+
+ $formData.append('__files[' + $internalFileID + ']', $file);
+ $formData.append('actionName', this._options.action);
+ $formData.append('className', this._className);
+ var $additionalParameters = this._getParameters();
+ for (var $name in $additionalParameters) {
+ $formData.append('parameters[' + $name + ']', $additionalParameters[$name]);
+ }
+
+ this._sendRequest($internalFileID, $formData);
}
-
- $fd.append('actionName', this._options.action);
- $fd.append('className', this._className);
- var $additionalParameters = this._getParameters();
- for (var $name in $additionalParameters) {
- $fd.append('parameters[' + $name + ']', $additionalParameters[$name]);
- }
-
+ },
+
+ /**
+ * Sends an AJAX request to upload a file.
+ *
+ * @param integer internalFileID
+ * @param FormData formData
+ */
+ _sendRequest: function (internalFileID, formData) {
var self = this;
$.ajax({
type: 'POST',
url: this._options.url,
enctype: 'multipart/form-data',
- data: $fd,
+ data: formData,
contentType: false,
processData: false,
- success: function(data, textStatus, jqXHR) {
- self._success($uploadID, data);
+ success: function (data, textStatus, jqXHR) {
+ self._success(internalFileID, data);
},
error: $.proxy(this._error, this),
- xhr: function() {
+ xhr: function () {
var $xhr = $.ajaxSettings.xhr();
if ($xhr) {
- $xhr.upload.addEventListener('progress', function(event) {
- self._progress($uploadID, event);
+ $xhr.upload.addEventListener('progress', function (event) {
+ self._progress(internalFileID, event);
}, false);
}
return $xhr;
- },
- xhrFields: {
- withCredentials: true
}
});
- }
-
- return $uploadID;
- },
-
- /**
- * Creates upload matrix for provided files.
- *
- * @param array<object> files
- * @return integer
- */
- _createUploadMatrix: function(files) {
- if (files.length) {
- var $uploadID = this._uploadMatrix.length;
- this._uploadMatrix[$uploadID] = [ ];
-
- for (var $i = 0, $length = files.length; $i < $length; $i++) {
- var $file = files[$i];
- var $li = this._initFile($file);
-
- if (!$li.hasClass('uploadFailed')) {
- $li.data('filename', $file.name).data('internalFileID', this._internalFileID++);
- this._uploadMatrix[$uploadID][$i] = $li;
- }
- }
-
- return $uploadID;
- }
-
- return null;
- },
-
- /**
- * Callback for success event.
- *
- * @param integer uploadID
- * @param object data
- */
- _success: function(uploadID, data) { },
-
- /**
- * Callback for error event.
- *
- * @param jQuery jqXHR
- * @param string textStatus
- * @param string errorThrown
- */
- _error: function(jqXHR, textStatus, errorThrown) { },
-
- /**
- * Callback for progress event.
- *
- * @param integer uploadID
- * @param object event
- */
- _progress: function(uploadID, event) {
- var $percentComplete = Math.round(event.loaded * 100 / event.total);
-
- for (var $i in this._uploadMatrix[uploadID]) {
- this._uploadMatrix[uploadID][$i].find('progress').attr('value', $percentComplete);
- }
- },
-
- /**
- * Returns additional parameters.
- *
- * @return object
- */
- _getParameters: function() {
- return {};
- },
-
- /**
- * Initializes list item for uploaded file.
- *
- * @return jQuery
- */
- _initFile: function(file) {
- return $('<li>' + file.name + ' (' + file.size + ')<progress max="100" /></li>').appendTo(this._fileListSelector);
- },
-
- /**
- * Shows the fallback overlay (work in progress)
- */
- _showOverlay: function() {
- // create iframe
- if (this._iframe === null) {
- this._iframe = $('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body);
- }
+ },
- // create overlay
- if (!this._overlay) {
- this._overlay = $('<div><form enctype="multipart/form-data" method="post" action="' + this._options.url + '" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);
-
- var $form = this._overlay.find('form');
- $('<dl class="wide"><dd><input type="file" id="__fileUpload" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/></dd></dl>').appendTo($form);
- $('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo($form);
-
- $('<input type="hidden" name="isFallback" value="1" />').appendTo($form);
- $('<input type="hidden" name="actionName" value="' + this._options.action + '" />').appendTo($form);
- $('<input type="hidden" name="className" value="' + this._className + '" />').appendTo($form);
- var $additionalParameters = this._getParameters();
- for (var $name in $additionalParameters) {
- $('<input type="hidden" name="' + $name + '" value="' + $additionalParameters[$name] + '" />').appendTo($form);
- }
-
- $form.submit($.proxy(function() {
- var $file = {
- name: this._getFilename(),
- size: ''
- };
+ /**
+ * Creates upload matrix for provided file and returns its internal file id.
+ *
+ * @param object file
+ * @return integer
+ */
+ _createUploadMatrix: function (file) {
+ var $li = this._initFile(file);
+ if (!$li.hasClass('uploadFailed')) {
+ $li.data('filename', file.name).data('internalFileID', this._internalFileID);
+ this._uploadMatrix[this._internalFileID++] = $li;
- var $uploadID = this._createUploadMatrix([ $file ]);
- var self = this;
- this._iframe.data('loading', true).off('load').load(function() { self._evaluateResponse($uploadID); });
- this._overlay.wcfDialog('close');
- }, this));
- }
-
- this._overlay.wcfDialog({
- title: WCF.Language.get('wcf.global.button.upload')
- });
- },
-
- /**
- * Evaluates iframe response.
- *
- * @param integer uploadID
- */
- _evaluateResponse: function(uploadID) {
- var $returnValues = $.parseJSON(this._iframe.contents().find('pre').html());
- this._success(uploadID, $returnValues);
- },
-
- /**
- * Returns name of selected file.
- *
- * @return string
- */
- _getFilename: function() {
- return $('#__fileUpload').val().split('\\').pop();
- }
-});
-
-/**
- * Default implementation for parallel AJAX file uploads.
- *
- * @deprecated Use WoltLabSuite/Core/Upload
- */
-WCF.Upload.Parallel = WCF.Upload.extend({
- /**
- * @see WCF.Upload.init()
- */
- init: function(buttonSelector, fileListSelector, className, options) {
- // force multiple uploads
- options = $.extend(true, options || { }, {
- multiple: true
- });
-
- this._super(buttonSelector, fileListSelector, className, options);
- },
-
- /**
- * @see WCF.Upload._upload()
- */
- _upload: function() {
- var $files = this._fileUpload.prop('files');
- for (var $i = 0, $length = $files.length; $i < $length; $i++) {
- var $file = $files[$i];
- var $formData = new FormData();
- var $internalFileID = this._createUploadMatrix($file);
-
- if (!this._uploadMatrix[$internalFileID].length) {
- continue;
- }
-
- $formData.append('__files[' + $internalFileID + ']', $file);
- $formData.append('actionName', this._options.action);
- $formData.append('className', this._className);
- var $additionalParameters = this._getParameters();
- for (var $name in $additionalParameters) {
- $formData.append('parameters[' + $name + ']', $additionalParameters[$name]);
- }
-
- this._sendRequest($internalFileID, $formData);
- }
- },
-
- /**
- * Sends an AJAX request to upload a file.
- *
- * @param integer internalFileID
- * @param FormData formData
- */
- _sendRequest: function(internalFileID, formData) {
- var self = this;
- $.ajax({
- type: 'POST',
- url: this._options.url,
- enctype: 'multipart/form-data',
- data: formData,
- contentType: false,
- processData: false,
- success: function(data, textStatus, jqXHR) {
- self._success(internalFileID, data);
- },
- error: $.proxy(this._error, this),
- xhr: function() {
- var $xhr = $.ajaxSettings.xhr();
- if ($xhr) {
- $xhr.upload.addEventListener('progress', function(event) {
- self._progress(internalFileID, event);
- }, false);
- }
- return $xhr;
- }
- });
- },
-
- /**
- * Creates upload matrix for provided file and returns its internal file id.
- *
- * @param object file
- * @return integer
- */
- _createUploadMatrix: function(file) {
- var $li = this._initFile(file);
- if (!$li.hasClass('uploadFailed')) {
- $li.data('filename', file.name).data('internalFileID', this._internalFileID);
- this._uploadMatrix[this._internalFileID++] = $li;
-
- return this._internalFileID - 1;
- }
-
- return null;
- },
-
- /**
- * Callback for success event.
- *
- * @param integer internalFileID
- * @param object data
- */
- _success: function(internalFileID, data) { },
-
- /**
- * Callback for progress event.
- *
- * @param integer internalFileID
- * @param object event
- */
- _progress: function(internalFileID, event) {
- var $percentComplete = Math.round(event.loaded * 100 / event.total);
-
- this._uploadMatrix[internalFileID].find('progress').attr('value', $percentComplete);
- },
-
- /**
- * @see WCF.Upload._showOverlay()
- */
- _showOverlay: function() {
- // create iframe
- if (this._iframe === null) {
- this._iframe = $('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body);
- }
-
- // create overlay
- if (!this._overlay) {
- this._overlay = $('<div><form enctype="multipart/form-data" method="post" action="' + this._options.url + '" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);
-
- var $form = this._overlay.find('form');
- $('<dl class="wide"><dd><input type="file" id="__fileUpload" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/></dd></dl>').appendTo($form);
- $('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo($form);
-
- $('<input type="hidden" name="isFallback" value="1" />').appendTo($form);
- $('<input type="hidden" name="actionName" value="' + this._options.action + '" />').appendTo($form);
- $('<input type="hidden" name="className" value="' + this._className + '" />').appendTo($form);
- var $additionalParameters = this._getParameters();
- for (var $name in $additionalParameters) {
- $('<input type="hidden" name="' + $name + '" value="' + $additionalParameters[$name] + '" />').appendTo($form);
+ return this._internalFileID - 1;
}
- $form.submit($.proxy(function() {
- var $file = {
- name: this._getFilename(),
- size: ''
- };
-
- var $internalFileID = this._createUploadMatrix($file);
- var self = this;
- this._iframe.data('loading', true).off('load').load(function() { self._evaluateResponse($internalFileID); });
- this._overlay.wcfDialog('close');
- }, this));
- }
-
- this._overlay.wcfDialog({
- title: WCF.Language.get('wcf.global.button.upload')
- });
- },
-
- /**
- * Evaluates iframe response.
- *
- * @param integer internalFileID
- */
- _evaluateResponse: function(internalFileID) {
- var $returnValues = $.parseJSON(this._iframe.contents().find('pre').html());
- this._success(internalFileID, $returnValues);
- }
-});
-
-/**
- * Namespace for sortables.
- */
-WCF.Sortable = { };
-
-/**
- * Sortable implementation for lists.
- *
- * @param string containerID
- * @param string className
- * @param integer offset
- * @param object options
- */
-WCF.Sortable.List = Class.extend({
- /**
- * additional parameters for AJAX request
- * @var object
- */
- _additionalParameters: { },
-
- /**
- * action class name
- * @var string
- */
- _className: '',
-
- /**
- * container id
- * @var string
- */
- _containerID: '',
-
- /**
- * container object
- * @var jQuery
- */
- _container: null,
-
- /**
- * notification object
- * @var WCF.System.Notification
- */
- _notification: null,
-
- /**
- * show order offset
- * @var integer
- */
- _offset: 0,
-
- /**
- * list of options
- * @var object
- */
- _options: { },
-
- /**
- * proxy object
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * object structure
- * @var object
- */
- _structure: { },
-
- /**
- * Creates a new sortable list.
- *
- * @param string containerID
- * @param string className
- * @param integer offset
- * @param object options
- * @param boolean isSimpleSorting
- * @param object additionalParameters
- */
- init: function(containerID, className, offset, options, isSimpleSorting, additionalParameters) {
- this._additionalParameters = additionalParameters || { };
- this._containerID = $.wcfEscapeID(containerID);
- this._container = $('#' + this._containerID);
- this._className = className;
- this._offset = (offset) ? offset : 0;
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
- this._structure = { };
+ return null;
+ },
- // init sortable
- this._options = $.extend(true, {
- axis: 'y',
- connectWith: '#' + this._containerID + ' .sortableList',
- disableNesting: 'sortableNoNesting',
- doNotClear: true,
- errorClass: 'sortableInvalidTarget',
- forcePlaceholderSize: true,
- handle: '',
- helper: 'clone',
- items: 'li:not(.sortableNoSorting)',
- opacity: .6,
- placeholder: 'sortablePlaceholder',
- tolerance: 'pointer',
- toleranceElement: '> span'
- }, options || { });
+ /**
+ * Callback for success event.
+ *
+ * @param integer internalFileID
+ * @param object data
+ */
+ _success: function (internalFileID, data) {
+ },
- var sortableList = $('#' + this._containerID + ' .sortableList');
- if (sortableList.is('tbody') && this._options.helper === 'clone') {
- this._options.helper = this._tableRowHelper.bind(this);
+ /**
+ * Callback for progress event.
+ *
+ * @param integer internalFileID
+ * @param object event
+ */
+ _progress: function (internalFileID, event) {
+ var $percentComplete = Math.round(event.loaded * 100 / event.total);
- // explicitly set column widths to avoid column resizing during dragging
- var thead = sortableList.prev('thead');
- if (thead) {
- thead.find('th').each(function(index, element) {
- element = $(element);
-
- element.width(element.width());
- });
- }
- }
-
- if (isSimpleSorting) {
- sortableList.sortable(this._options);
- }
- else {
- sortableList.nestedSortable(this._options);
- }
+ this._uploadMatrix[internalFileID].find('progress').attr('value', $percentComplete);
+ },
- if (this._className) {
- var $formSubmit = this._container.find('.formSubmit');
- if (!$formSubmit.length) {
- $formSubmit = this._container.next('.formSubmit');
- if (!$formSubmit.length) {
- console.debug("[WCF.Sortable.Simple] Unable to find form submit for saving, aborting.");
- return;
+ /**
+ * @see WCF.Upload._showOverlay()
+ */
+ _showOverlay: function () {
+ // create iframe
+ if (this._iframe === null) {
+ this._iframe = $('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body);
+ }
+
+ // create overlay
+ if (!this._overlay) {
+ this._overlay = $('<div><form enctype="multipart/form-data" method="post" action="' + this._options.url + '" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);
+
+ var $form = this._overlay.find('form');
+ $('<dl class="wide"><dd><input type="file" id="__fileUpload" name="' + this._name + '" ' + (this._options.multiple ? 'multiple="true" ' : '') + '/></dd></dl>').appendTo($form);
+ $('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo($form);
+
+ $('<input type="hidden" name="isFallback" value="1" />').appendTo($form);
+ $('<input type="hidden" name="actionName" value="' + this._options.action + '" />').appendTo($form);
+ $('<input type="hidden" name="className" value="' + this._className + '" />').appendTo($form);
+ var $additionalParameters = this._getParameters();
+ for (var $name in $additionalParameters) {
+ $('<input type="hidden" name="' + $name + '" value="' + $additionalParameters[$name] + '" />').appendTo($form);
}
+
+ $form.submit($.proxy(function () {
+ var $file = {
+ name: this._getFilename(),
+ size: ''
+ };
+
+ var $internalFileID = this._createUploadMatrix($file);
+ var self = this;
+ this._iframe.data('loading', true).off('load').load(function () {
+ self._evaluateResponse($internalFileID);
+ });
+ this._overlay.wcfDialog('close');
+ }, this));
}
- $formSubmit.children('button[data-type="submit"]').click($.proxy(this._submit, this));
+ this._overlay.wcfDialog({
+ title: WCF.Language.get('wcf.global.button.upload')
+ });
+ },
+
+ /**
+ * Evaluates iframe response.
+ *
+ * @param integer internalFileID
+ */
+ _evaluateResponse: function (internalFileID) {
+ var $returnValues = $.parseJSON(this._iframe.contents().find('pre').html());
+ this._success(internalFileID, $returnValues);
}
- },
-
+ });
+}
+else {
+ WCF.System.Worker = Class.extend({
+ _aborted: false,
+ _actionName: "",
+ _callback: {},
+ _className: "",
+ _dialog: {},
+ _proxy: {},
+ _title: "",
+ init: function() {},
+ _success: function() {}
+ });
+
+ WCF.InlineEditor = Class.extend({
+ _callbacks: {},
+ _dropdowns: {},
+ _elements: {},
+ _notification: {},
+ _options: {},
+ _proxy: {},
+ _triggerElements: {},
+ _updateData: {},
+ init: function() {},
+ _closeAll: function() {},
+ _setOptions: function() {},
+ registerCallback: function() {},
+ _getTriggerElement: function() {},
+ _show: function() {},
+ _validate: function() {},
+ _validateCallbacks: function() {},
+ _success: function() {},
+ _updateState: function() {},
+ _click: function() {},
+ _execute: function() {},
+ _executeCallback: function() {},
+ _hide: function() {}
+ });
+
+ WCF.Upload = Class.extend({
+ _name: "",
+ _buttonSelector: {},
+ _fileListSelector: {},
+ _fileUpload: {},
+ _className: "",
+ _iframe: {},
+ _internalFileID: 0,
+ _options: {},
+ _uploadMatrix: {},
+ _supportsAJAXUpload: true,
+ _overlay: {},
+ init: function() {},
+ _createButton: function() {},
+ _insertButton: function() {},
+ _removeButton: function() {},
+ _upload: function() {},
+ _createUploadMatrix: function() {},
+ _success: function() {},
+ _error: function() {},
+ _progress: function() {},
+ _getParameters: function() {},
+ _initFile: function() {},
+ _showOverlay: function() {},
+ _evaluateResponse: function() {},
+ _getFilename: function() {}
+ });
+
+ WCF.Upload.Parallel = WCF.Upload.extend({
+ init: function() {},
+ _upload: function() {},
+ _sendRequest: function() {},
+ _createUploadMatrix: function() {},
+ _success: function() {},
+ _progress: function() {},
+ _showOverlay: function() {},
+ _evaluateResponse: function() {},
+ _name: "",
+ _buttonSelector: {},
+ _fileListSelector: {},
+ _fileUpload: {},
+ _className: "",
+ _iframe: {},
+ _internalFileID: 0,
+ _options: {},
+ _uploadMatrix: {},
+ _supportsAJAXUpload: true,
+ _overlay: {},
+ _createButton: function() {},
+ _insertButton: function() {},
+ _removeButton: function() {},
+ _error: function() {},
+ _getParameters: function() {},
+ _initFile: function() {},
+ _getFilename: function() {}
+ });
+}
+
+/**
+ * Namespace for sortables.
+ */
+WCF.Sortable = { };
+
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Fixes the width of the cells of the dragged table row.
- *
- * @param {Event} event
- * @param {jQuery} ui
- * @return {jQuery}
+ * Sortable implementation for lists.
+ *
+ * @param string containerID
+ * @param string className
+ * @param integer offset
+ * @param object options
*/
- _tableRowHelper: function(event, ui) {
- ui.children('td').each(function(index, element) {
- element = $(element);
-
- element.width(element.width());
- });
+ WCF.Sortable.List = Class.extend({
+ /**
+ * additional parameters for AJAX request
+ * @var object
+ */
+ _additionalParameters: {},
- return ui;
- },
-
- /**
- * Saves object structure.
- */
- _submit: function() {
- // reset structure
- this._structure = { };
+ /**
+ * action class name
+ * @var string
+ */
+ _className: '',
+
+ /**
+ * container id
+ * @var string
+ */
+ _containerID: '',
+
+ /**
+ * container object
+ * @var jQuery
+ */
+ _container: null,
+
+ /**
+ * notification object
+ * @var WCF.System.Notification
+ */
+ _notification: null,
+
+ /**
+ * show order offset
+ * @var integer
+ */
+ _offset: 0,
+
+ /**
+ * list of options
+ * @var object
+ */
+ _options: {},
+
+ /**
+ * proxy object
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * object structure
+ * @var object
+ */
+ _structure: {},
- // build structure
- this._container.find('.sortableList').each($.proxy(function(index, list) {
- var $list = $(list);
- var $parentID = $list.data('objectID');
+ /**
+ * Creates a new sortable list.
+ *
+ * @param string containerID
+ * @param string className
+ * @param integer offset
+ * @param object options
+ * @param boolean isSimpleSorting
+ * @param object additionalParameters
+ */
+ init: function (containerID, className, offset, options, isSimpleSorting, additionalParameters) {
+ this._additionalParameters = additionalParameters || {};
+ this._containerID = $.wcfEscapeID(containerID);
+ this._container = $('#' + this._containerID);
+ this._className = className;
+ this._offset = (offset) ? offset : 0;
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+ this._structure = {};
- if ($parentID !== undefined) {
- $list.children(this._options.items).each($.proxy(function(index, listItem) {
- var $objectID = $(listItem).data('objectID');
-
- if (!this._structure[$parentID]) {
- this._structure[$parentID] = [ ];
+ // init sortable
+ this._options = $.extend(true, {
+ axis: 'y',
+ connectWith: '#' + this._containerID + ' .sortableList',
+ disableNesting: 'sortableNoNesting',
+ doNotClear: true,
+ errorClass: 'sortableInvalidTarget',
+ forcePlaceholderSize: true,
+ handle: '',
+ helper: 'clone',
+ items: 'li:not(.sortableNoSorting)',
+ opacity: .6,
+ placeholder: 'sortablePlaceholder',
+ tolerance: 'pointer',
+ toleranceElement: '> span'
+ }, options || {});
+
+ var sortableList = $('#' + this._containerID + ' .sortableList');
+ if (sortableList.is('tbody') && this._options.helper === 'clone') {
+ this._options.helper = this._tableRowHelper.bind(this);
+
+ // explicitly set column widths to avoid column resizing during dragging
+ var thead = sortableList.prev('thead');
+ if (thead) {
+ thead.find('th').each(function (index, element) {
+ element = $(element);
+
+ element.width(element.width());
+ });
+ }
+ }
+
+ if (isSimpleSorting) {
+ sortableList.sortable(this._options);
+ }
+ else {
+ sortableList.nestedSortable(this._options);
+ }
+
+ if (this._className) {
+ var $formSubmit = this._container.find('.formSubmit');
+ if (!$formSubmit.length) {
+ $formSubmit = this._container.next('.formSubmit');
+ if (!$formSubmit.length) {
+ console.debug("[WCF.Sortable.Simple] Unable to find form submit for saving, aborting.");
+ return;
}
-
- this._structure[$parentID].push($objectID);
- }, this));
+ }
+
+ $formSubmit.children('button[data-type="submit"]').click($.proxy(this._submit, this));
}
- }, this));
+ },
- // send request
- var $parameters = $.extend(true, {
- data: {
- offset: this._offset,
- structure: this._structure
- }
- }, this._additionalParameters);
+ /**
+ * Fixes the width of the cells of the dragged table row.
+ *
+ * @param {Event} event
+ * @param {jQuery} ui
+ * @return {jQuery}
+ */
+ _tableRowHelper: function (event, ui) {
+ ui.children('td').each(function (index, element) {
+ element = $(element);
+
+ element.width(element.width());
+ });
+
+ return ui;
+ },
- this._proxy.setOption('data', {
- actionName: 'updatePosition',
- className: this._className,
- interfaceName: 'wcf\\data\\ISortableAction',
- parameters: $parameters
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Shows notification upon success.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- if (this._notification === null) {
- this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit'));
- }
+ /**
+ * Saves object structure.
+ */
+ _submit: function () {
+ // reset structure
+ this._structure = {};
+
+ // build structure
+ this._container.find('.sortableList').each($.proxy(function (index, list) {
+ var $list = $(list);
+ var $parentID = $list.data('objectID');
+
+ if ($parentID !== undefined) {
+ $list.children(this._options.items).each($.proxy(function (index, listItem) {
+ var $objectID = $(listItem).data('objectID');
+
+ if (!this._structure[$parentID]) {
+ this._structure[$parentID] = [];
+ }
+
+ this._structure[$parentID].push($objectID);
+ }, this));
+ }
+ }, this));
+
+ // send request
+ var $parameters = $.extend(true, {
+ data: {
+ offset: this._offset,
+ structure: this._structure
+ }
+ }, this._additionalParameters);
+
+ this._proxy.setOption('data', {
+ actionName: 'updatePosition',
+ className: this._className,
+ interfaceName: 'wcf\\data\\ISortableAction',
+ parameters: $parameters
+ });
+ this._proxy.sendRequest();
+ },
- this._notification.show();
- }
-});
+ /**
+ * Shows notification upon success.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function (data, textStatus, jqXHR) {
+ if (this._notification === null) {
+ this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit'));
+ }
+
+ this._notification.show();
+ }
+ });
+}
+else {
+ WCF.Sortable.List = Class.extend({
+ _additionalParameters: {},
+ _className: "",
+ _containerID: "",
+ _container: {},
+ _notification: {},
+ _offset: 0,
+ _options: {},
+ _proxy: {},
+ _structure: {},
+ init: function() {},
+ _tableRowHelper: function() {},
+ _submit: function() {},
+ _success: function() {}
+ });
+}
WCF.Popover = Class.extend({
/**
case 'getDate':
return window.__wcf_bc_datePicker.getDate(element);
- break;
case 'option':
if (parameters[0] === 'onClose') {
*/
WCF.Category = { };
-/**
- * Handles selection of categories.
- */
-WCF.Category.NestedList = Class.extend({
- /**
- * list of categories
- * @var object
- */
- _categories: { },
-
+if (COMPILER_TARGET_DEFAULT) {
/**
- * Initializes the WCF.Category.NestedList object.
+ * Handles selection of categories.
*/
- init: function() {
- var self = this;
- $('.jsCategory').each(function(index, category) {
- var $category = $(category).data('parentCategoryID', null).change($.proxy(self._updateSelection, self));
- self._categories[$category.val()] = $category;
-
- // find child categories
- var $childCategoryIDs = [ ];
- $category.parents('li').find('.jsChildCategory').each(function(innerIndex, childCategory) {
- var $childCategory = $(childCategory).data('parentCategoryID', $category.val()).change($.proxy(self._updateSelection, self));
- self._categories[$childCategory.val()] = $childCategory;
- $childCategoryIDs.push($childCategory.val());
+ WCF.Category.NestedList = Class.extend({
+ /**
+ * list of categories
+ * @var object
+ */
+ _categories: {},
+
+ /**
+ * Initializes the WCF.Category.NestedList object.
+ */
+ init: function () {
+ var self = this;
+ $('.jsCategory').each(function (index, category) {
+ var $category = $(category).data('parentCategoryID', null).change($.proxy(self._updateSelection, self));
+ self._categories[$category.val()] = $category;
- if ($childCategory.is(':checked')) {
- $category.prop('checked', 'checked');
- }
+ // find child categories
+ var $childCategoryIDs = [];
+ $category.parents('li').find('.jsChildCategory').each(function (innerIndex, childCategory) {
+ var $childCategory = $(childCategory).data('parentCategoryID', $category.val()).change($.proxy(self._updateSelection, self));
+ self._categories[$childCategory.val()] = $childCategory;
+ $childCategoryIDs.push($childCategory.val());
+
+ if ($childCategory.is(':checked')) {
+ $category.prop('checked', 'checked');
+ }
+ });
+
+ $category.data('childCategoryIDs', $childCategoryIDs);
});
-
- $category.data('childCategoryIDs', $childCategoryIDs);
- });
- },
-
- /**
- * Updates selection of categories.
- *
- * @param object event
- */
- _updateSelection: function(event) {
- var $category = $(event.currentTarget);
- var $parentCategoryID = $category.data('parentCategoryID');
+ },
- if ($category.is(':checked')) {
- // child category
- if ($parentCategoryID !== null) {
- // mark parent category as checked
- this._categories[$parentCategoryID].prop('checked', 'checked');
+ /**
+ * Updates selection of categories.
+ *
+ * @param object event
+ */
+ _updateSelection: function (event) {
+ var $category = $(event.currentTarget);
+ var $parentCategoryID = $category.data('parentCategoryID');
+
+ if ($category.is(':checked')) {
+ // child category
+ if ($parentCategoryID !== null) {
+ // mark parent category as checked
+ this._categories[$parentCategoryID].prop('checked', 'checked');
+ }
}
- }
- else {
- // top-level category
- if ($parentCategoryID === null) {
- // unmark all child categories
- var $childCategoryIDs = $category.data('childCategoryIDs');
- for (var $i = 0, $length = $childCategoryIDs.length; $i < $length; $i++) {
- this._categories[$childCategoryIDs[$i]].prop('checked', false);
+ else {
+ // top-level category
+ if ($parentCategoryID === null) {
+ // unmark all child categories
+ var $childCategoryIDs = $category.data('childCategoryIDs');
+ for (var $i = 0, $length = $childCategoryIDs.length; $i < $length; $i++) {
+ this._categories[$childCategoryIDs[$i]].prop('checked', false);
+ }
}
}
}
- }
-});
-
-/**
- * Handles selection of categories.
- */
-WCF.Category.FlexibleCategoryList = Class.extend({
- /**
- * category list container
- * @var jQuery
- */
- _list: null,
+ });
/**
- * list of children per category id
- * @var object<integer>
+ * Handles selection of categories.
*/
- _categories: { },
-
- init: function(elementID) {
- this._list = $('#' + elementID);
-
- this._buildStructure();
+ WCF.Category.FlexibleCategoryList = Class.extend({
+ /**
+ * category list container
+ * @var jQuery
+ */
+ _list: null,
- this._list.find('input:checked').each(function() {
- $(this).trigger('change');
- });
+ /**
+ * list of children per category id
+ * @var object<integer>
+ */
+ _categories: {},
- if (this._list.children('li').length < 2) {
- this._list.addClass('flexibleCategoryListDisabled');
- return;
- }
- },
-
- _buildStructure: function() {
- var self = this;
- this._list.find('.jsCategory').each(function(i, category) {
- var $category = $(category).change(self._updateSelection.bind(self));
- var $categoryID = parseInt($category.val());
- var $childCategories = [ ];
+ init: function (elementID) {
+ this._list = $('#' + elementID);
- $category.parents('li:eq(0)').find('.jsChildCategory').each(function(j, childCategory) {
- var $childCategory = $(childCategory);
- $childCategory.data('parentCategory', $category).change(self._updateSelection.bind(self));
-
- var $childCategoryID = parseInt($childCategory.val());
- $childCategories.push($childCategory);
-
- var $subChildCategories = [ ];
+ this._buildStructure();
+
+ this._list.find('input:checked').each(function () {
+ $(this).trigger('change');
+ });
+
+ if (this._list.children('li').length < 2) {
+ this._list.addClass('flexibleCategoryListDisabled');
+ return;
+ }
+ },
+
+ _buildStructure: function () {
+ var self = this;
+ this._list.find('.jsCategory').each(function (i, category) {
+ var $category = $(category).change(self._updateSelection.bind(self));
+ var $categoryID = parseInt($category.val());
+ var $childCategories = [];
- $childCategory.parents('li:eq(0)').find('.jsSubChildCategory').each(function(k, subChildCategory) {
- var $subChildCategory = $(subChildCategory);
- $subChildCategory.data('parentCategory', $childCategory).change(self._updateSelection.bind(self));
- $subChildCategories.push($subChildCategory);
+ $category.parents('li:eq(0)').find('.jsChildCategory').each(function (j, childCategory) {
+ var $childCategory = $(childCategory);
+ $childCategory.data('parentCategory', $category).change(self._updateSelection.bind(self));
+
+ var $childCategoryID = parseInt($childCategory.val());
+ $childCategories.push($childCategory);
+
+ var $subChildCategories = [];
+
+ $childCategory.parents('li:eq(0)').find('.jsSubChildCategory').each(function (k, subChildCategory) {
+ var $subChildCategory = $(subChildCategory);
+ $subChildCategory.data('parentCategory', $childCategory).change(self._updateSelection.bind(self));
+ $subChildCategories.push($subChildCategory);
+ });
+
+ self._categories[$childCategoryID] = $subChildCategories;
});
- self._categories[$childCategoryID] = $subChildCategories;
+ self._categories[$categoryID] = $childCategories;
});
-
- self._categories[$categoryID] = $childCategories;
- });
- },
-
- _updateSelection: function(event) {
- var $category = $(event.currentTarget);
- var $categoryID = parseInt($category.val());
- var $parentCategory = $category.data('parentCategory');
+ },
- if ($category.is(':checked')) {
- if ($parentCategory) {
- $parentCategory.prop('checked', 'checked');
-
- $parentCategory = $parentCategory.data('parentCategory');
+ _updateSelection: function (event) {
+ var $category = $(event.currentTarget);
+ var $categoryID = parseInt($category.val());
+ var $parentCategory = $category.data('parentCategory');
+
+ if ($category.is(':checked')) {
if ($parentCategory) {
$parentCategory.prop('checked', 'checked');
- }
- }
- }
- else {
- // uncheck child categories
- if (this._categories[$categoryID]) {
- for (var $i = 0, $length = this._categories[$categoryID].length; $i < $length; $i++) {
- var $childCategory = this._categories[$categoryID][$i];
- $childCategory.prop('checked', false);
- var $childCategoryID = parseInt($childCategory.val());
- if (this._categories[$childCategoryID]) {
- for (var $j = 0, $innerLength = this._categories[$childCategoryID].length; $j < $innerLength; $j++) {
- this._categories[$childCategoryID][$j].prop('checked', false);
- }
+ $parentCategory = $parentCategory.data('parentCategory');
+ if ($parentCategory) {
+ $parentCategory.prop('checked', 'checked');
}
}
}
-
- // uncheck direct parent if it has no more checked children
- if ($parentCategory) {
- var $parentCategoryID = parseInt($parentCategory.val());
- for (var $i = 0, $length = this._categories[$parentCategoryID].length; $i < $length; $i++) {
- if (this._categories[$parentCategoryID][$i].prop('checked')) {
- // at least one child is checked, break
- return;
+ else {
+ // uncheck child categories
+ if (this._categories[$categoryID]) {
+ for (var $i = 0, $length = this._categories[$categoryID].length; $i < $length; $i++) {
+ var $childCategory = this._categories[$categoryID][$i];
+ $childCategory.prop('checked', false);
+
+ var $childCategoryID = parseInt($childCategory.val());
+ if (this._categories[$childCategoryID]) {
+ for (var $j = 0, $innerLength = this._categories[$childCategoryID].length; $j < $innerLength; $j++) {
+ this._categories[$childCategoryID][$j].prop('checked', false);
+ }
+ }
}
}
- $parentCategory = $parentCategory.data('parentCategory');
+ // uncheck direct parent if it has no more checked children
if ($parentCategory) {
- $parentCategoryID = parseInt($parentCategory.val());
+ var $parentCategoryID = parseInt($parentCategory.val());
for (var $i = 0, $length = this._categories[$parentCategoryID].length; $i < $length; $i++) {
if (this._categories[$parentCategoryID][$i].prop('checked')) {
// at least one child is checked, break
return;
}
}
+
+ $parentCategory = $parentCategory.data('parentCategory');
+ if ($parentCategory) {
+ $parentCategoryID = parseInt($parentCategory.val());
+ for (var $i = 0, $length = this._categories[$parentCategoryID].length; $i < $length; $i++) {
+ if (this._categories[$parentCategoryID][$i].prop('checked')) {
+ // at least one child is checked, break
+ return;
+ }
+ }
+ }
}
}
}
- }
-});
+ });
+}
+else {
+ WCF.Category.NestedList = Class.extend({
+ _categories: {},
+ init: function() {},
+ _updateSelection: function() {}
+ });
+
+ WCF.Category.FlexibleCategoryList = Class.extend({
+ _list: {},
+ _categories: {},
+ init: function() {},
+ _buildStructure: function() {},
+ _updateSelection: function() {}
+ });
+}
/**
* Initializes WCF.Condition namespace.