});
</script>
<script data-relocate="true">
- require(['Language', 'WoltLab/WCF/BootstrapFrontend'], function(Language, BootstrapFrontend) {
+ require(['Language', 'WoltLab/WCF/BootstrapFrontend', 'User'], function(Language, BootstrapFrontend, User) {
Language.addObject({
'__days': [ '{lang}wcf.date.day.sunday{/lang}', '{lang}wcf.date.day.monday{/lang}', '{lang}wcf.date.day.tuesday{/lang}', '{lang}wcf.date.day.wednesday{/lang}', '{lang}wcf.date.day.thursday{/lang}', '{lang}wcf.date.day.friday{/lang}', '{lang}wcf.date.day.saturday{/lang}' ],
'__daysShort': [ '{lang}wcf.date.day.sun{/lang}', '{lang}wcf.date.day.mon{/lang}', '{lang}wcf.date.day.tue{/lang}', '{lang}wcf.date.day.wed{/lang}', '{lang}wcf.date.day.thu{/lang}', '{lang}wcf.date.day.fri{/lang}', '{lang}wcf.date.day.sat{/lang}' ],
},
styleChanger: {if $__wcf->getStyleHandler()->countStyles() > 1}true{else}false{/if}
});
+
+ User.init({@$__wcf->user->userID}, '{@$__wcf->user->username|encodeJS}');
});
// prevent jQuery and other libraries from utilizing define()
--- /dev/null
+<div class="section">
+ <dl{if $errorType[username]|isset} class="formError"{/if}>
+ <dt><label for="username">{lang}wcf.user.username{/lang}</label></dt>
+ <dd>
+ <input type="text" name="username" value="{$username}" required autofocus class="long">
+ {if $errorType[username]|isset}
+ <small class="innerError">
+ {if $errorType[username] == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.user.username.error.{$errorType[username]}{/lang}
+ {/if}
+ </small>
+ {/if}
+ </dd>
+ </dl>
+</div>
+
+{include file='captcha'}
+
+<div class="formSubmit">
+ <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" data-captcha-id="{@$captchaID}">
+</div>
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
- require(['Language', 'WoltLab/WCF/Acp/Bootstrap'], function(Language, AcpBootstrap) {
- Language.addObject({
- '__days': [ '{lang}wcf.date.day.sunday{/lang}', '{lang}wcf.date.day.monday{/lang}', '{lang}wcf.date.day.tuesday{/lang}', '{lang}wcf.date.day.wednesday{/lang}', '{lang}wcf.date.day.thursday{/lang}', '{lang}wcf.date.day.friday{/lang}', '{lang}wcf.date.day.saturday{/lang}' ],
- '__daysShort': [ '{lang}wcf.date.day.sun{/lang}', '{lang}wcf.date.day.mon{/lang}', '{lang}wcf.date.day.tue{/lang}', '{lang}wcf.date.day.wed{/lang}', '{lang}wcf.date.day.thu{/lang}', '{lang}wcf.date.day.fri{/lang}', '{lang}wcf.date.day.sat{/lang}' ],
- '__months': [ '{lang}wcf.date.month.january{/lang}', '{lang}wcf.date.month.february{/lang}', '{lang}wcf.date.month.march{/lang}', '{lang}wcf.date.month.april{/lang}', '{lang}wcf.date.month.may{/lang}', '{lang}wcf.date.month.june{/lang}', '{lang}wcf.date.month.july{/lang}', '{lang}wcf.date.month.august{/lang}', '{lang}wcf.date.month.september{/lang}', '{lang}wcf.date.month.october{/lang}', '{lang}wcf.date.month.november{/lang}', '{lang}wcf.date.month.december{/lang}' ],
- '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
- 'wcf.acp.search.noResults': '{lang}wcf.acp.search.noResults{/lang}',
- 'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
- 'wcf.date.relative.now': '{lang __literal=true}wcf.date.relative.now{/lang}',
- 'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang __literal=true}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
- 'wcf.date.relative.hours': '{capture assign=relativeHours}{lang __literal=true}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
- 'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang __literal=true}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
- 'wcf.date.dateFormat': '{lang}wcf.date.dateFormat{/lang}',
- 'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
- 'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
- 'wcf.date.hour': '{lang}wcf.date.hour{/lang}',
- 'wcf.date.minute': '{lang}wcf.date.minute{/lang}',
- 'wcf.date.timeFormat': '{lang}wcf.date.timeFormat{/lang}',
- 'wcf.date.firstDayOfTheWeek': '{lang}wcf.date.firstDayOfTheWeek{/lang}',
- 'wcf.global.button.add': '{lang}wcf.global.button.add{/lang}',
- 'wcf.global.button.cancel': '{lang}wcf.global.button.cancel{/lang}',
- 'wcf.global.button.close': '{lang}wcf.global.button.close{/lang}',
- 'wcf.global.button.collapsible': '{lang}wcf.global.button.collapsible{/lang}',
- 'wcf.global.button.delete': '{lang}wcf.global.button.delete{/lang}',
- 'wcf.global.button.disable': '{lang}wcf.global.button.disable{/lang}',
- 'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}',
- 'wcf.global.button.edit': '{lang}wcf.global.button.edit{/lang}',
- 'wcf.global.button.enable': '{lang}wcf.global.button.enable{/lang}',
- 'wcf.global.button.hide': '{lang}wcf.global.button.hide{/lang}',
- 'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
- 'wcf.global.button.next': '{lang}wcf.global.button.next{/lang}',
- 'wcf.global.button.preview': '{lang}wcf.global.button.preview{/lang}',
- 'wcf.global.button.reset': '{lang}wcf.global.button.reset{/lang}',
- 'wcf.global.button.save': '{lang}wcf.global.button.save{/lang}',
- 'wcf.global.button.search': '{lang}wcf.global.button.search{/lang}',
- 'wcf.global.button.submit': '{lang}wcf.global.button.submit{/lang}',
- 'wcf.global.button.upload': '{lang}wcf.global.button.upload{/lang}',
- 'wcf.global.confirmation.cancel': '{lang}wcf.global.confirmation.cancel{/lang}',
- 'wcf.global.confirmation.confirm': '{lang}wcf.global.confirmation.confirm{/lang}',
- 'wcf.global.confirmation.title': '{lang}wcf.global.confirmation.title{/lang}',
- 'wcf.global.decimalPoint': '{capture assign=decimalPoint}{lang}wcf.global.decimalPoint{/lang}{/capture}{$decimalPoint|encodeJS}',
- 'wcf.global.error.timeout': '{lang}wcf.global.error.timeout{/lang}',
- 'wcf.global.error.title': '{lang}wcf.global.error.title{/lang}',
- 'wcf.global.form.error.empty': '{lang}wcf.global.form.error.empty{/lang}',
- 'wcf.global.form.error.greaterThan': '{lang __literal=true}wcf.global.form.error.greaterThan{/lang}',
- 'wcf.global.form.error.lessThan': '{lang __literal=true}wcf.global.form.error.lessThan{/lang}',
- 'wcf.global.loading': '{lang}wcf.global.loading{/lang}',
- 'wcf.global.noSelection': '{lang}wcf.global.noSelection{/lang}',
- 'wcf.page.jumpTo': '{lang}wcf.page.jumpTo{/lang}',
- 'wcf.page.jumpTo.description': '{lang}wcf.page.jumpTo.description{/lang}',
- 'wcf.global.page.pagination': '{lang}wcf.global.page.pagination{/lang}',
- 'wcf.global.page.next': '{capture assign=pageNext}{lang}wcf.global.page.next{/lang}{/capture}{@$pageNext|encodeJS}',
- 'wcf.global.page.previous': '{capture assign=pagePrevious}{lang}wcf.global.page.previous{/lang}{/capture}{@$pagePrevious|encodeJS}',
- 'wcf.global.pageDirection': '{lang}wcf.global.pageDirection{/lang}',
- 'wcf.global.reason': '{lang}wcf.global.reason{/lang}',
- 'wcf.global.scrollUp': '{lang}wcf.global.scrollUp{/lang}',
- 'wcf.global.success': '{lang}wcf.global.success{/lang}',
- 'wcf.global.success.add': '{lang}wcf.global.success.add{/lang}',
- 'wcf.global.success.edit': '{lang}wcf.global.success.edit{/lang}',
- 'wcf.global.thousandsSeparator': '{capture assign=thousandsSeparator}{lang}wcf.global.thousandsSeparator{/lang}{/capture}{@$thousandsSeparator|encodeJS}',
- 'wcf.page.pagePosition': '{lang __literal=true}wcf.page.pagePosition{/lang}'
- {event name='javascriptLanguageImport'}
+ require(['Language', 'WoltLab/WCF/Acp/Bootstrap', 'User'], function(Language, AcpBootstrap, User) {
+ Language.addObject({
+ '__days': [ '{lang}wcf.date.day.sunday{/lang}', '{lang}wcf.date.day.monday{/lang}', '{lang}wcf.date.day.tuesday{/lang}', '{lang}wcf.date.day.wednesday{/lang}', '{lang}wcf.date.day.thursday{/lang}', '{lang}wcf.date.day.friday{/lang}', '{lang}wcf.date.day.saturday{/lang}' ],
+ '__daysShort': [ '{lang}wcf.date.day.sun{/lang}', '{lang}wcf.date.day.mon{/lang}', '{lang}wcf.date.day.tue{/lang}', '{lang}wcf.date.day.wed{/lang}', '{lang}wcf.date.day.thu{/lang}', '{lang}wcf.date.day.fri{/lang}', '{lang}wcf.date.day.sat{/lang}' ],
+ '__months': [ '{lang}wcf.date.month.january{/lang}', '{lang}wcf.date.month.february{/lang}', '{lang}wcf.date.month.march{/lang}', '{lang}wcf.date.month.april{/lang}', '{lang}wcf.date.month.may{/lang}', '{lang}wcf.date.month.june{/lang}', '{lang}wcf.date.month.july{/lang}', '{lang}wcf.date.month.august{/lang}', '{lang}wcf.date.month.september{/lang}', '{lang}wcf.date.month.october{/lang}', '{lang}wcf.date.month.november{/lang}', '{lang}wcf.date.month.december{/lang}' ],
+ '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
+ 'wcf.acp.search.noResults': '{lang}wcf.acp.search.noResults{/lang}',
+ 'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
+ 'wcf.date.relative.now': '{lang __literal=true}wcf.date.relative.now{/lang}',
+ 'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang __literal=true}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
+ 'wcf.date.relative.hours': '{capture assign=relativeHours}{lang __literal=true}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
+ 'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang __literal=true}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
+ 'wcf.date.dateFormat': '{lang}wcf.date.dateFormat{/lang}',
+ 'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
+ 'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
+ 'wcf.date.hour': '{lang}wcf.date.hour{/lang}',
+ 'wcf.date.minute': '{lang}wcf.date.minute{/lang}',
+ 'wcf.date.timeFormat': '{lang}wcf.date.timeFormat{/lang}',
+ 'wcf.date.firstDayOfTheWeek': '{lang}wcf.date.firstDayOfTheWeek{/lang}',
+ 'wcf.global.button.add': '{lang}wcf.global.button.add{/lang}',
+ 'wcf.global.button.cancel': '{lang}wcf.global.button.cancel{/lang}',
+ 'wcf.global.button.close': '{lang}wcf.global.button.close{/lang}',
+ 'wcf.global.button.collapsible': '{lang}wcf.global.button.collapsible{/lang}',
+ 'wcf.global.button.delete': '{lang}wcf.global.button.delete{/lang}',
+ 'wcf.global.button.disable': '{lang}wcf.global.button.disable{/lang}',
+ 'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}',
+ 'wcf.global.button.edit': '{lang}wcf.global.button.edit{/lang}',
+ 'wcf.global.button.enable': '{lang}wcf.global.button.enable{/lang}',
+ 'wcf.global.button.hide': '{lang}wcf.global.button.hide{/lang}',
+ 'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
+ 'wcf.global.button.next': '{lang}wcf.global.button.next{/lang}',
+ 'wcf.global.button.preview': '{lang}wcf.global.button.preview{/lang}',
+ 'wcf.global.button.reset': '{lang}wcf.global.button.reset{/lang}',
+ 'wcf.global.button.save': '{lang}wcf.global.button.save{/lang}',
+ 'wcf.global.button.search': '{lang}wcf.global.button.search{/lang}',
+ 'wcf.global.button.submit': '{lang}wcf.global.button.submit{/lang}',
+ 'wcf.global.button.upload': '{lang}wcf.global.button.upload{/lang}',
+ 'wcf.global.confirmation.cancel': '{lang}wcf.global.confirmation.cancel{/lang}',
+ 'wcf.global.confirmation.confirm': '{lang}wcf.global.confirmation.confirm{/lang}',
+ 'wcf.global.confirmation.title': '{lang}wcf.global.confirmation.title{/lang}',
+ 'wcf.global.decimalPoint': '{capture assign=decimalPoint}{lang}wcf.global.decimalPoint{/lang}{/capture}{$decimalPoint|encodeJS}',
+ 'wcf.global.error.timeout': '{lang}wcf.global.error.timeout{/lang}',
+ 'wcf.global.error.title': '{lang}wcf.global.error.title{/lang}',
+ 'wcf.global.form.error.empty': '{lang}wcf.global.form.error.empty{/lang}',
+ 'wcf.global.form.error.greaterThan': '{lang __literal=true}wcf.global.form.error.greaterThan{/lang}',
+ 'wcf.global.form.error.lessThan': '{lang __literal=true}wcf.global.form.error.lessThan{/lang}',
+ 'wcf.global.loading': '{lang}wcf.global.loading{/lang}',
+ 'wcf.global.noSelection': '{lang}wcf.global.noSelection{/lang}',
+ 'wcf.page.jumpTo': '{lang}wcf.page.jumpTo{/lang}',
+ 'wcf.page.jumpTo.description': '{lang}wcf.page.jumpTo.description{/lang}',
+ 'wcf.global.page.pagination': '{lang}wcf.global.page.pagination{/lang}',
+ 'wcf.global.page.next': '{capture assign=pageNext}{lang}wcf.global.page.next{/lang}{/capture}{@$pageNext|encodeJS}',
+ 'wcf.global.page.previous': '{capture assign=pagePrevious}{lang}wcf.global.page.previous{/lang}{/capture}{@$pagePrevious|encodeJS}',
+ 'wcf.global.pageDirection': '{lang}wcf.global.pageDirection{/lang}',
+ 'wcf.global.reason': '{lang}wcf.global.reason{/lang}',
+ 'wcf.global.scrollUp': '{lang}wcf.global.scrollUp{/lang}',
+ 'wcf.global.success': '{lang}wcf.global.success{/lang}',
+ 'wcf.global.success.add': '{lang}wcf.global.success.add{/lang}',
+ 'wcf.global.success.edit': '{lang}wcf.global.success.edit{/lang}',
+ 'wcf.global.thousandsSeparator': '{capture assign=thousandsSeparator}{lang}wcf.global.thousandsSeparator{/lang}{/capture}{@$thousandsSeparator|encodeJS}',
+ 'wcf.page.pagePosition': '{lang __literal=true}wcf.page.pagePosition{/lang}'
+ {event name='javascriptLanguageImport'}
+ });
+
+ AcpBootstrap.setup({
+ bootstrap: {
+ enableMobileMenu: {if $__isLogin|empty}true{else}false{/if}
+ }
+ });
+
+ User.init({@$__wcf->user->userID}, '{@$__wcf->user->username|encodeJS}');
});
-
- AcpBootstrap.setup({
- bootstrap: {
- enableMobileMenu: {if $__isLogin|empty}true{else}false{/if}
- }
- });
- });
});
</script>
{js application='wcf' lib='jquery'}
/**
* Holds userdata of the current user
+ *
+ * @deprecated use WCF/WoltLab/User
*/
WCF.User = {
/**
* Stores captcha callbacks used for captchas in AJAX contexts.
*/
WCF.System.Captcha = {
- /**
- * adds call
- * @var object<function>
- */
- _captchas: { },
-
/**
* Adds a callback for a certain captcha.
*
* @param function callback
*/
addCallback: function(captchaID, callback) {
- if (!$.isFunction(callback)) {
- console.debug('[WCF.System.Captcha] Given callback is no function');
- return;
- }
-
- this._captchas[captchaID] = callback;
+ require(['WoltLab/WCF/Controller/Captcha'], function(ControllerCaptcha) {
+ try {
+ ControllerCaptcha.add(captchaID, callback);
+ }
+ catch (e) {
+ if (e instanceof TypeError) {
+ console.debug('[WCF.System.Captcha] Given callback is no function');
+ return;
+ }
+
+ // ignore other errors
+ }
+ });
},
/**
* @return object
*/
getData: function(captchaID) {
- if (this._captchas[captchaID] === undefined) {
- console.debug('[WCF.System.Captcha] Unknow captcha id "' + captchaID + '"');
- return;
- }
+ var returnValue;
+ require(['WoltLab/WCF/Controller/Captcha'], function(ControllerCaptcha) {
+ try {
+ returnValue = ControllerCaptcha.getData(captchaID);
+ }
+ catch (e) {
+ console.debug('[WCF.System.Captcha] Unknow captcha id "' + captchaID + '"');
+ }
+ });
- return this._captchas[captchaID]();
+ return returnValue;
},
/**
* Removes the callback with the given captcha id.
*/
removeCallback: function(captchaID) {
- delete this._captchas[captchaID];
+ require(['WoltLab/WCF/Controller/Captcha'], function(ControllerCaptcha) {
+ try {
+ ControllerCaptcha.delete(captchaID);
+ }
+ catch (e) {
+ // ignore errors for unknown captchas
+ }
+ });
}
};
--- /dev/null
+/**
+ * Provides data of the active user.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/Controller/Captcha
+ */
+define(['Dictionary'], function(Dictionary) {
+ "use strict";
+
+ var _captchas = new Dictionary();
+
+ /**
+ * @exports WoltLab/WCF/Controller/Captcha
+ */
+ return {
+ /**
+ * Registers a captcha with the given identifier and callback used to get captcha data.
+ *
+ * @param {string} captchaId captcha identifier
+ * @param {function} callback callback to get captcha data
+ */
+ add: function(captchaId, callback) {
+ if (_captchas.has(captchaId)) {
+ throw new Error("Captcha with id '" + captchaId + "' is already registered.")
+ }
+
+ if (typeof callback !== 'function') {
+ throw new TypeError("Expected a valid callback for parameter 'callback'.");
+ }
+
+ _captchas.set(captchaId, callback);
+ },
+
+ /**
+ * Deletes the captcha with the given identifier.
+ *
+ * @param {string} captchaId identifier of the captcha to be deleted
+ */
+ 'delete': function(captchaId) {
+ if (!_captchas.has(captchaId)) {
+ throw new Error("Unknown captcha with id '" + captchaId + "'.")
+ }
+
+ _captchas.delete(captchaId)();
+ },
+
+ /**
+ * Returns true if a captcha with the given identifier exists.
+ *
+ * @param {string} captchaId captcha identifier
+ * @return {boolean}
+ */
+ has: function(captchaId) {
+ return _captchas.has(captchaId);
+ },
+
+ /**
+ * Returns the data of the captcha with the given identifier.
+ *
+ * @param {string} captchaId captcha identifier
+ * @return {Object} captcha data
+ */
+ getData: function(captchaId) {
+ if (!_captchas.has(captchaId)) {
+ throw new Error("Unknown captcha with id '" + captchaId + "'.")
+ }
+
+ return _captchas.get(captchaId)();
+ }
+ };
+});
elData(_container, 'close-on-click', (data.backdropCloseOnClick ? 'true' : 'false'));
_activeDialog = id;
- this.rebuild(id);
-
// set focus on first applicable element
var focusElement = elBySel('.jsDialogAutoFocus', data.dialog);
if (focusElement !== null && focusElement.offsetParent !== null) {
}
}
+ this.rebuild(id);
+
DomChangeListener.trigger();
},
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLab/WCF/Ui/Message/Reply
*/
-define(['Ajax', 'Core', 'EventHandler', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Notification', '../Scroll'], function(Ajax, Core, EventHandler, Language, DomChangeListener, DomUtil, UiNotification, UiScroll) {
+define(['Ajax', 'Core', 'EventHandler', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Dom/Traverse', 'Ui/Dialog', 'Ui/Notification', '../Scroll', 'EventKey', 'User', 'WoltLab/WCF/Controller/Captcha'],
+ function(Ajax, Core, EventHandler, Language, DomChangeListener, DomUtil, DomTraverse, UiDialog, UiNotification, UiScroll, EventKey, User, ControllerCaptcha) {
"use strict";
/**
// TODO: add event listener for submit through keyboard in Redactor
},
+ /**
+ * Submits the guest dialog.
+ *
+ * @param {Event} event
+ * @protected
+ */
+ _submitGuestDialog: function(event) {
+ // only submit when enter key is pressed
+ if (event.type === 'keypress' && !EventKey.Enter(event)) {
+ return;
+ }
+
+ var usernameInput = elBySel('input[name=username]', event.currentTarget.closest('.dialogContent'));
+ if (usernameInput.value === '') {
+ var error = DomTraverse.nextByClass(usernameInput, 'innerError');
+ if (!error) {
+ var error = elCreate('small');
+ error.className = 'innerError';
+ error.innerText = Language.get('wcf.global.form.error.empty');
+
+ DomUtil.insertAfter(error, usernameInput);
+
+ usernameInput.closest('dl').classList.add('formError');
+ }
+
+ return;
+ }
+
+ var parameters = {
+ parameters: {
+ data: {
+ username: usernameInput.value
+ }
+ }
+ };
+
+ var captchaId = elData(event.currentTarget, 'captcha-id');
+ if (ControllerCaptcha.has(captchaId)) {
+ parameters = Core.extend(parameters, ControllerCaptcha.getData(captchaId));
+ }
+
+ this._submit(undefined, parameters);
+ },
+
/**
* Validates the message and submits it to the server.
*
- * @param {Event} event event object
+ * @param {Event?} event event object
+ * @param {Object?} additionalParameters additional parameters sent to the server
* @protected
*/
- _submit: function(event) {
- event.preventDefault();
+ _submit: function(event, additionalParameters) {
+ if (event) {
+ event.preventDefault();
+ }
if (!this._validate()) {
// validation failed, bail out
EventHandler.fire('com.woltlab.wcf.redactor2', 'submit_text', parameters.data);
- Ajax.api(this, {
+ if (!User.userId && !additionalParameters) {
+ parameters.requireGuestDialog = true;
+ }
+
+ Ajax.api(this, Core.extend({
parameters: parameters
- });
+ }, additionalParameters));
},
/**
},
_ajaxSuccess: function(data) {
- this._insertMessage(data);
-
- this._reset();
+ if (!User.userId && !data.returnValues.guestDialogID) {
+ throw new Error("Missing 'guestDialogID' return value for guest.");
+ }
- this._hideLoadingOverlay();
+ if (!User.userId && data.returnValues.guestDialog) {
+ UiDialog.openStatic(data.returnValues.guestDialogID, data.returnValues.guestDialog, {
+ closable: false,
+ title: Language.get('wcf.global.confirmation.title')
+ });
+
+ var dialog = UiDialog.getDialog(data.returnValues.guestDialogID);
+ elBySel('input[type=submit]', dialog.content).addEventListener(WCF_CLICK_EVENT, this._submitGuestDialog.bind(this));
+ elBySel('input[type=text]', dialog.content).addEventListener('keypress', this._submitGuestDialog.bind(this));
+ }
+ else {
+ this._insertMessage(data);
+
+ if (!User.userId) {
+ UiDialog.close(data.returnValues.guestDialogID);
+ }
+
+ this._reset();
+
+ this._hideLoadingOverlay();
+ }
},
_ajaxFailure: function(data) {
--- /dev/null
+/**
+ * Provides data of the active user.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/User
+ */
+define([], function() {
+ "use strict";
+
+ var _didInit = false;
+
+ /**
+ * @exports WoltLab/WCF/User
+ */
+ return {
+ /**
+ * Initializes the user object.
+ *
+ * @param {int} userId id of the user, `0` for guests
+ * @param {string} username name of the user, empty for guests
+ */
+ init: function(userId, username) {
+ if (_didInit) {
+ throw new Error('User has already been initialized.');
+ }
+
+ // define non-writeable properties for userId and username
+ Object.defineProperty(this, 'userId', {
+ value: userId,
+ writable: false
+ });
+ Object.defineProperty(this, 'username', {
+ value: username,
+ writable: false
+ });
+
+ _didInit = true;
+ }
+ };
+});
'Ui/Screen': 'WoltLab/WCF/Ui/Screen',
'Ui/SimpleDropdown': 'WoltLab/WCF/Ui/Dropdown/Simple',
'Ui/TabMenu': 'WoltLab/WCF/Ui/TabMenu',
- 'Upload': 'WoltLab/WCF/Upload'
+ 'Upload': 'WoltLab/WCF/Upload',
+ 'User': 'WoltLab/WCF/User'
}
}
});
--- /dev/null
+<?php
+namespace wcf\data;
+use wcf\data\object\type\ObjectType;
+use wcf\system\captcha\CaptchaHandler;
+use wcf\system\captcha\ICaptchaHandler;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+use wcf\util\UserUtil;
+
+/**
+ * Provdes methods related to the guest dialog of message quick reply.
+ *
+ * @author Matthias Schmudt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\Data
+ * @since 3.0
+ */
+trait TMessageQuickReplyGuestDialogAction {
+ /**
+ * captcha object type used for guests or `null` if no captcha is used or available
+ * @var ObjectType
+ */
+ public $guestDialogCaptchaObjectType;
+
+ /**
+ * list of errors in the guest dialog with field as key and error type as value
+ * @var string[]
+ */
+ public $guestDialogErrors = [];
+
+ /**
+ * @see AbstractDatabaseObjectAction::$parameters
+ */
+ protected $parameters = [];
+
+ /**
+ * @see AbstractDatabaseObjectAction::readString()
+ */
+ abstract protected function readString($variableName, $allowEmpty = false, $arrayIndex = '');
+
+ /**
+ * Sets the guest dialog captcha.
+ *
+ * Needs to be called before all other methods in this trait.
+ */
+ protected function setGuestDialogCaptcha() {
+ $this->guestDialogCaptchaObjectType = CaptchaHandler::getInstance()->getObjectTypeByName(CAPTCHA_TYPE);
+ if ($this->guestDialogCaptchaObjectType === null) {
+ throw new \LogicException("Unknown captcha object type with name '".CAPTCHA_TYPE."'");
+ }
+
+ /** @var ICaptchaHandler $processor */
+ $processor = $this->guestDialogCaptchaObjectType->getProcessor();
+
+ if (!$processor->isAvailable()) {
+ $this->guestDialogCaptchaObjectType = null;
+ }
+ }
+
+ /**
+ * Validates the captcha in the guest dialog.
+ *
+ * @throws \BadMethodCallException
+ * @throws \LogicException
+ */
+ protected function validateGuestDialogCaptcha() {
+ // only relevant for guests
+ if (WCF::getUser()->userID) {
+ throw new \BadMethodCallException("Guest dialogs are only relevant for guests");
+ }
+
+ if (CAPTCHA_TYPE) {
+ /** @var ICaptchaHandler $processor */
+ $processor = $this->guestDialogCaptchaObjectType->getProcessor();
+
+ if ($processor->isAvailable()) {
+ try {
+ $processor->readFormParameters();
+ $processor->validate();
+ }
+ catch (UserInputException $e) {
+ $this->guestDialogErrors[$e->getField()] = $e->getType();
+ }
+ }
+ }
+ }
+
+ /**
+ * Validates the entered username in the guest dialog.
+ *
+ * @return string type of the validation error or empty if no error occured
+ * @throws \BadMethodCallException
+ */
+ protected function validateGuestDialogUsername() {
+ // only relevant for guests
+ if (WCF::getUser()->userID) {
+ throw new \BadMethodCallException("Guest dialogs are only relevant for guests");
+ }
+
+ try {
+ $this->readString('username', false, 'data');
+
+ if (!UserUtil::isValidUsername($this->parameters['data']['username'])) {
+ throw new UserInputException('username', 'notValid');
+ }
+ if (!UserUtil::isAvailableUsername($this->parameters['data']['username'])) {
+ throw new UserInputException('username', 'notUnique');
+ }
+ }
+ catch (UserInputException $e) {
+ $this->guestDialogErrors['username'] = $e->getType();
+ }
+ }
+}
$tableIndexName = call_user_func([$this->container, 'getDatabaseTableIndexName']);
$parameters['data'][$tableIndexName] = $parameters['objectID'];
$parameters['data']['time'] = TIME_NOW;
- $parameters['data']['userID'] = WCF::getUser()->userID ?: null;
- $parameters['data']['username'] = WCF::getUser()->username;
+
+ if (!isset($parameters['data']['userID'])) {
+ $parameters['data']['userID'] = WCF::getUser()->userID ?: null;
+ }
+
+ if (!isset($parameters['data']['username'])) {
+ $parameters['data']['username'] = WCF::getUser()->username;
+ }
// pre-parse message text
/*if ($parameters['data']['preParse']) {