}).bind(this));
WCF.System.Event.addListener('com.woltlab.wcf.redactor', 'fixFormatting_' + $identifier, $.proxy(this.wbbcode.fixFormatting, this));
+
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor', 'destroy_' + $identifier, (function() {
+ this.wautosave.disable();
+ this.wautosave.purge();
+ this.core.destroy();
+
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.messageOptionsInline', 'submit_' + $identifier);
+ WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor', 'destroy_' + $identifier);
+
+ WCF.System.Dependency.Manager.reset('Redactor_' + $identifier);
+ }).bind(this));
},
/**
// convert HTML to BBCode upon submit
this.$textarea.parents('form').submit($.proxy(this.wutil.submit, this));
+
+ WCF.System.Event.addListener('com.woltlab.wcf.redactor', 'getText_' + _textarea.id, (function(data) {
+ data.message = this.wutil.getText();
+ }).bind(this));
},
/**
var $messageBody = this._container[this._activeElementID].addClass('jsInvalidQuoteTarget').find('.messageBody');
$messageBody.children('.icon-spinner').remove();
- var $content = $messageBody.children('div:eq(0)');
// insert wysiwyg
- $('' + data.returnValues.template).appendTo($content);
+ $('' + data.returnValues.template).appendTo($messageBody);
// bind buttons
- var $formSubmit = $content.find('.formSubmit');
+ var $formSubmit = $messageBody.find('.formSubmit');
var $saveButton = $formSubmit.find('button[data-type=save]').click($.proxy(this._save, this));
if (this._supportExtendedForm) $formSubmit.find('button[data-type=extended]').click($.proxy(this._prepareExtended, this));
$formSubmit.find('button[data-type=cancel]').click($.proxy(this._cancel, this));
delete this._callbacks[identifier];
}
+ },
+
+ reset: function(identifier) {
+ var index = this._loaded.indexOf(identifier);
+ if (index !== -1) {
+ this._loaded.splice(index, 1);
+ }
}
};
/**
* System-wide event system.
+ *
+ * @deprecated 2.2 - please use `EventHandler` instead
*/
WCF.System.Event = {
- /**
- * list of event listeners grouped by identifier and action.
- * @var object<object>
- */
- _listeners: { },
-
/**
* Registers a new event listener.
*
* @return string
*/
addListener: function(identifier, action, listener) {
- if (typeof this._listeners[identifier] === 'undefined') {
- this._listeners[identifier] = { };
- }
-
- if (typeof this._listeners[identifier][action] === 'undefined') {
- this._listeners[identifier][action] = [ ];
- }
-
- var $uuid = WCF.getUUID();
- this._listeners[identifier][action].push({
- callback: listener,
- uuid: $uuid
- });
-
- return $uuid;
+ return window.__wcf_bc_eventHandler.add(identifier, action, listener);
},
/**
* @return boolean
*/
removeListener: function(identifier, action, uuid) {
- if (this._listeners[identifier] && this._listeners[identifier][action]) {
- for (var $i = 0; $i < this._listeners[identifier][action].length; $i++) {
- if (this._listeners[identifier][action][$i].uuid == uuid) {
- this._listeners[identifier][action].splice($i, 1);
-
- return true;
- }
- }
- }
-
- return false;
+ return window.__wcf_bc_eventHandler.remove(identifier, action, uuid);
},
/**
* @return boolean
*/
removeAllListeners: function(identifier, action) {
- if (this._listeners[identifier] && this._listeners[identifier][action]) {
- delete this._listeners[identifier][action];
-
- return true;
- }
-
- return false;
+ return window.__wcf_bc_eventHandler.removeAll(identifier, action);
},
/**
* @param object data
*/
fireEvent: function(identifier, action, data) {
- data = data || { };
-
- if (this._listeners[identifier] && this._listeners[identifier][action]) {
- for (var $i = 0; $i < this._listeners[identifier][action].length; $i++) {
- this._listeners[identifier][action][$i].callback(data);
- }
- }
+ window.__wcf_bc_eventHandler.fire(identifier, action, data);
}
};
*/
define(
[
- 'favico', 'enquire', 'perfect-scrollbar', 'WoltLab/WCF/Date/Time/Relative',
- 'Ui/SimpleDropdown', 'WoltLab/WCF/Ui/Mobile', 'WoltLab/WCF/Ui/TabMenu', 'WoltLab/WCF/Ui/FlexibleMenu',
- 'Ui/Dialog', 'WoltLab/WCF/Ui/Tooltip', 'WoltLab/WCF/Language', 'WoltLab/WCF/Environment',
- 'WoltLab/WCF/Date/Picker'
+ 'favico', 'enquire', 'perfect-scrollbar', 'WoltLab/WCF/Date/Time/Relative',
+ 'Ui/SimpleDropdown', 'WoltLab/WCF/Ui/Mobile', 'WoltLab/WCF/Ui/TabMenu', 'WoltLab/WCF/Ui/FlexibleMenu',
+ 'Ui/Dialog', 'WoltLab/WCF/Ui/Tooltip', 'WoltLab/WCF/Language', 'WoltLab/WCF/Environment',
+ 'WoltLab/WCF/Date/Picker', 'EventHandler'
],
function(
favico, enquire, perfectScrollbar, DateTimeRelative,
UiSimpleDropdown, UiMobile, UiTabMenu, UiFlexibleMenu,
UiDialog, UiTooltip, Language, Environment,
- DatePicker
+ DatePicker, EventHandler
)
{
"use strict";
window.WCF.Language.add = Language.add;
window.WCF.Language.addObject = Language.addObject;
+ // WCF.System.Event compatibility
+ window.__wcf_bc_eventHandler = EventHandler;
+
/**
* @exports WoltLab/WCF/Bootstrap
*/
}
return parseInt(value);
+ },
+
+ /**
+ * Sets the inner HTML of given element and reinjects <script> elements to be properly executed.
+ *
+ * @see http://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0
+ * @param {Element} element target element
+ * @param {string} innerHtml HTML string
+ */
+ setInnerHtml: function(element, innerHtml) {
+ element.innerHTML = innerHtml;
+
+ var newScript, script, scripts = elBySelAll('script', element);
+ for (var i = 0, length = scripts.length; i < length; i++) {
+ script = scripts[i];
+ newScript = elCreate('script');
+ if (script.src) {
+ newScript.src = script.src;
+ }
+ else {
+ newScript.textContent = script.textContent;
+ }
+
+ element.appendChild(newScript);
+ script.parentNode.removeChild(script);
+ }
}
};
--- /dev/null
+define(['Ajax', 'Core', 'EventHandler', 'ObjectMap', 'Dom/Traverse', 'Dom/Util'], function(Ajax, Core, EventHandler, ObjectMap, DomTraverse, DomUtil) {
+ "use strict";
+
+ var _activeElement = null;
+ var _elements = new ObjectMap();
+ var _options = {};
+
+ var UiMessageInlineEditor = {
+ init: function(options) {
+ _options = Core.extend({
+ extendedForm: false,
+
+ className: '',
+ containerId: 0,
+ editorPrefix: 'messageEditor',
+
+ messageSelector: '.jsMessage'
+ }, options);
+
+ this._initElements();
+ },
+
+ _initElements: function() {
+ var button, element, elements = elBySelAll(_options.messageSelector);
+ for (var i = 0, length = elements.length; i < length; i++) {
+ element = elements[i];
+ if (_elements.has(element)) {
+ continue;
+ }
+
+ if (elAttrBool(element, 'data-can-edit')) {
+ button = elBySel('.jsMessageEditButton', element);
+ if (button !== null) {
+ button.addEventListener('click', this._click.bind(this, element));
+ }
+ }
+
+ _elements.set(element, {
+ messageBody: null,
+ messageBodyEditor: null,
+ messageFooter: null,
+ messageText: null
+ });
+ }
+ },
+
+ _click: function(element, event) {
+ event.preventDefault();
+
+ if (_activeElement !== null) {
+ // TODO: show notification
+ }
+
+ _activeElement = element;
+
+ this._prepare();
+
+ Ajax.api(this, {
+ actionName: 'beginEdit',
+ parameters: {
+ containerID: _options.containerId,
+ objectID: elAttr(element, 'data-object-id')
+ }
+ });
+ },
+
+ _prepare: function() {
+ var data = _elements.get(_activeElement);
+ if (data.messageBody === null) data.messageBody = elBySel('.messageBody', _activeElement);
+ if (data.messageFooter === null) data.messageFooter = elBySel('.messageFooter', _activeElement);
+ if (data.messageText === null) data.messageText = elBySel('.messageText', data.messageBody);
+
+ var messageBodyEditor = elCreate('div');
+ messageBodyEditor.className = 'messageBody editor';
+ data.messageBodyEditor = messageBodyEditor;
+
+ var icon = elCreate('span');
+ icon.className = 'icon icon48 fa-spinner';
+ messageBodyEditor.appendChild(icon);
+
+ DomUtil.insertAfter(messageBodyEditor, data.messageBody);
+
+ elHide(data.messageBody);
+ },
+
+ _showEditor: function(data) {
+ var id = this._getEditorId();
+ var elementData = _elements.get(_activeElement);
+
+ _activeElement.classList.add('jsInvalidQuoteTarget');
+ var icon = DomTraverse.childByClass(elementData.messageBodyEditor, 'icon');
+ icon.parentNode.removeChild(icon);
+
+ var messageBody = elementData.messageBodyEditor;
+ var editor = elCreate('div');
+ editor.className = 'editorContainer';
+ DomUtil.setInnerHtml(editor, data.returnValues.template);
+ messageBody.appendChild(editor);
+
+ // bind buttons
+ var formSubmit = elBySel('.formSubmit', editor);
+
+ var buttonSave = elBySel('button[data-type="save"]', formSubmit);
+ buttonSave.addEventListener('click', this._save.bind(this));
+
+ if (_options.extendedForm) {
+ var buttonExtended = elBySel('button[data-type="extended"]', formSubmit);
+ buttonExtended.addEventListener('click', this._prepareExtended.bind(this));
+ }
+
+ var buttonCancel = elBySel('button[data-type="cancel"]', formSubmit);
+ buttonCancel.addEventListener('click', this._restoreMessage.bind(this));
+
+ EventHandler.add('com.woltlab.wcf.redactor', 'submitEditor_' + id, (function(data) {
+ data.cancel = true;
+
+ this._save();
+ }).bind(this));
+
+ // hide message options
+ elHide(elementData.messageFooter);
+
+ var editorElement = elById(id);
+ if ($.browser.redactor) {
+ window.setTimeout((function() {
+ // TODO: quote manager
+ if (this._quoteManager) {
+ this._quoteManager.setAlternativeEditor($element);
+ }
+
+ // TODO
+ new WCF.Effect.Scroll().scrollTo(_activeElement, true);
+ }).bind(this), 250);
+ }
+ else {
+ editorElement.focus();
+ }
+ },
+
+ _restoreMessage: function() {
+ var elementData = _elements.get(_activeElement);
+
+ this._destroyEditor();
+
+ elRemove(elementData.messageBodyEditor);
+ elementData.messageBodyEditor = null;
+
+ elShow(elementData.messageBody);
+ elShow(elementData.messageFooter);
+ _activeElement.classList.remove('jsInvalidQuoteTarget');
+
+ _activeElement = null;
+
+ // @TODO
+ if (this._quoteManager) {
+ this._quoteManager.clearAlternativeEditor();
+ }
+ },
+
+ _save: function() {
+ var parameters = {
+ containerID: _options.containerId,
+ data: {
+ message: ''
+ },
+ objectID: elAttr(_activeElement, 'data-object-id'),
+ removeQuoteIDs: [] // @TODO
+ };
+
+ var id = this._getEditorId();
+ EventHandler.fire('com.woltlab.wcf.redactor', 'getText_' + id, parameters.data);
+ EventHandler.fire('com.woltlab.wcf.messageOptionsInline', 'submit_' + id, parameters);
+
+ Ajax.api(this, {
+ actionName: 'save',
+ parameters: parameters
+ });
+
+ this._hideEditor();
+ },
+
+ _showMessage: function() {
+
+ },
+
+ _prepareExtended: function() {
+
+ },
+
+ _hideEditor: function() {
+ var elementData = _elements.get(_activeElement);
+ elHide(DomTraverse.childByClass(elementData.messageBodyEditor, 'editorContainer'));
+
+ var icon = elCreate('span');
+ icon.className = 'icon icon48 fa-spinner';
+ elementData.messageBodyEditor.appendChild(icon);
+ },
+
+ _destroyEditor: function() {
+ EventHandler.fire('com.woltlab.wcf.redactor', 'destroy_' + this._getEditorId());
+ },
+
+ _getEditorId: function() {
+ return _options.editorPrefix + elAttr(_activeElement, 'data-object-id');
+ },
+
+ _ajaxSuccess: function(data) {
+ switch (data.actionName) {
+ case 'beginEdit':
+ this._showEditor(data);
+ break;
+
+ case 'save':
+ this._showMessage(data);
+ break;
+ }
+ },
+
+ _ajaxSetup: function() {
+ return {
+ data: {
+ className: _options.className,
+ interfaceName: 'wcf\\data\\IMessageInlineEditorAction'
+ }
+ };
+ }
+ };
+
+ return UiMessageInlineEditor;
+});
element.setAttribute(attribute, value);
};
+ /**
+ * Shorthand function to retrieve a boolean attribute.
+ *
+ * @param {Element} element target element
+ * @param {string} attribute attribute name
+ * @return {boolean} true if value is either `1` or `true`
+ */
+ window.elAttrBool = function(element, attribute) {
+ var value = elAttr(element, attribute);
+
+ return (value === "1" || value === "true");
+ };
+
/**
* Shorthand function to find elements by class name.
*
};
/**
- * Shorthand function to check if an object has a property while ignoring the chain.
+ * Shorthand function to hide an element by setting its 'display' value to 'none'.
*
- * @param {object} obj target object
- * @param {string} property property name
- * @return {boolean} false if property does not exist or belongs to the chain
+ * @param {Element} element DOM element
*/
- window.objOwns = function(obj, property) {
- return obj.hasOwnProperty(property);
+ window.elHide = function(element) {
+ element.style.setProperty('display', 'none');
};
/**
- * Shorthand function to hide an element by setting its 'display' value to 'none'.
+ * Shorthand function to remove an element.
*
* @param {Element} element DOM element
*/
- window.elHide = function(element) {
- element.style.setProperty('display', 'none');
+ window.elRemove = function(element) {
+ element.parentNode.removeChild(element);
};
/**
window.elShow = function(element) {
element.style.removeProperty('display');
};
+
+ /**
+ * Shorthand function to check if an object has a property while ignoring the chain.
+ *
+ * @param {object} obj target object
+ * @param {string} property property name
+ * @return {boolean} false if property does not exist or belongs to the chain
+ */
+ window.objOwns = function(obj, property) {
+ return obj.hasOwnProperty(property);
+ };
})(window, document);
&:not(.plain) > dd {
&:not(.floated) > label ~ small {
- margin-left: 20px;
+ margin-left: 24px;
}
> small:not(.innerError) {
> dd {
display: block;
margin: 0;
+ text-align: left;
width: 100%;
}
+
+ > dd + dt {
+ margin-top: 15px;
+ }
+
+ > dt:not(:empty) {
+ margin-bottom: 5px;
+ }
}
}
\ No newline at end of file
/* content - body */
.messageBody {
flex: 1 auto;
+
+ &.editor {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+
+ > .icon {
+ flex: 0 0 auto;
+ }
+
+ > .editorContainer {
+ flex: 1 auto;
+ }
+ }
}
/* content - footer */