url += (url.indexOf('?') === -1) ? '?' : '&';
url += options.parameterName + '=' + callbackName;
- var script = document.createElement('script');
+ var script = elCreate('script');
script.async = true;
- script.setAttribute('src', url);
+ elAttr(script, 'src', url);
document.head.appendChild(script);
}
DomChangeListener.trigger();
// fix anchor tags generated through WCF::getAnchor()
- var links = document.querySelectorAll('a[href*="#"]');
+ var links = elBySelAll('a[href*="#"]');
for (var i = 0, length = links.length; i < length; i++) {
var link = links[i];
- var href = link.getAttribute('href');
+ var href = elAttr(link, 'href');
if (href.indexOf('AJAXProxy') !== -1 || href.indexOf('ajax-proxy') !== -1) {
href = href.substr(href.indexOf('#'));
- link.setAttribute('href', document.location.toString().replace(/#.*/, '') + href);
+ elAttr(link, 'href', document.location.toString().replace(/#.*/, '') + href);
}
}
}
* Initializes the status overlay on first usage.
*/
_init: function() {
- _overlay = document.createElement('div');
+ _overlay = elCreate('div');
_overlay.classList.add('spinner');
- var icon = document.createElement('span');
+ var icon = elCreate('span');
icon.className = 'icon icon48 fa-spinner';
_overlay.appendChild(icon);
- var title = document.createElement('span');
+ var title = elCreate('span');
title.textContent = Language.get('wcf.global.loading');
_overlay.appendChild(title);
convert: function(message) {
if (message.length) this._setup();
- var container = document.createElement('div');
+ var container = elCreate('div');
container.innerHTML = message;
// convert line breaks
- var elements = container.getElementsByTagName('P');
+ var elements = elByTag('P', container);
while (elements.length) elements[0].outerHTML = elements[0].innerHTML;
- elements = container.getElementsByTagName('BR');
+ elements = elByTag('BR', container);
while (elements.length) elements[0].outerHTML = "\n";
// prevent conversion taking place inside source bbcodes
this._restoreSourceElements(container, sourceElements);
// remove remaining HTML elements
- elements = container.getElementsByTagName('*');
+ elements = elByTag('*', container);
while (elements.length) elements[0].outerHTML = elements[0].innerHTML;
message = this._convertSpecials(container.innerHTML);
var elements, sourceElements = [], tmp;
for (var i = 0, length = _sourceConverter.length; i < length; i++) {
- elements = container.querySelectorAll(_sourceConverter[i].selector);
+ elements = elBySelAll(_sourceConverter[i].selector, container);
tmp = [];
for (var j = 0, innerLength = elements.length; j < innerLength; j++) {
* @param {array<object>} list of removed elements and their placeholders
*/
_preserveSourceElement: function(element, sourceElements) {
- var placeholder = document.createElement('var');
- placeholder.setAttribute('data-source', 'wcf');
+ var placeholder = elCreate('var');
+ elAttr(placeholder, 'data-source', 'wcf');
element.parentNode.insertBefore(placeholder, element);
var fragment = document.createDocumentFragment();
return;
}
- var element, elements = container.getElementsByTagName(converter.tagName);
+ var element, elements = elByTag(converter.tagName, container);
while (elements.length) {
element = elements[0];
* @param {Element} element target element
*/
_convertBlockquote: function(element) {
- var author = element.getAttribute('data-author') || '';
- var link = element.getAttribute('cite') || '';
+ var author = elAttr(element, 'data-author');
+ var link = elAttr(element, 'cite');
var open = '[quote]';
if (author) {
_convertImage: function(element) {
if (element.classList.contains('smiley')) {
// smiley
- element.outerHTML = (addSmileyPadding(element, true) ? ' ' : '') + element.getAttribute('alt') + (addSmileyPadding(element, false) ? ' ' : '');
+ element.outerHTML = (addSmileyPadding(element, true) ? ' ' : '') + elAttr(element, 'alt') + (addSmileyPadding(element, false) ? ' ' : '');
return;
}
width = (typeof width === 'string') ? ~~width.replace(/px$/, '') : 0;
if (element.classList.contains('redactorEmbeddedAttachment')) {
- var attachmentId = element.getAttribute('data-attachment-id');
+ var attachmentId = elAttr(element, 'data-attachment-id');
if (width > 0) {
element.outerHTML = "[attach=" + attachmentId + "," + float + "," + width + "][/attach]";
* @param {Element} element target element
*/
_convertTable: function(element) {
- var elements = element.getElementsByTagName('TD');
+ var elements = elByTag('TD', element);
while (elements.length) {
elements[0].outerHTML = '[td]' + elements[0].innerHTML + '[/td]\n';
}
- elements = element.getElementsByTagName('TR');
+ elements = elByTag('TR', element);
while (elements.length) {
elements[0].outerHTML = '\n[tr]\n' + elements[0].innerHTML + '[/tr]';
}
* @param {Element} element target element
*/
_convertSourceCodeBox: function(element) {
- var filename = element.getAttribute('data-filename').trim() || '';
- var highlighter = element.getAttribute('data-highlighter') || '';
+ var filename = elAttr(element, 'data-filename').trim() || '';
+ var highlighter = elAttr(element, 'data-highlighter');
window.dtdesign = element;
var list = DomTraverse.childByTag(element.children[0], 'OL');
var lineNumber = ~~list.getAttribute('start') || 1;
* @return {boolean} true if `value` is a known highlighter
*/
function isHighlighter(value) {
- return __REDACTOR_CODE_HIGHLIGHTERS.hasOwnProperty(value);
+ return objOwns(__REDACTOR_CODE_HIGHLIGHTERS, value);
}
/**
UiTooltip.setup();
// convert method=get into method=post
- var forms = document.querySelectorAll('form[method=get]');
+ var forms = elBySelAll('form[method=get]');
for (var i = 0, length = forms.length; i < length; i++) {
forms[i].setAttribute('method', 'post');
}
var _containers = new Dictionary();
var _editors = new Dictionary();
- var _elements = document.getElementsByClassName('jsClipboardContainer');
+ var _elements = elByClass('jsClipboardContainer');
var _itemData = new ObjectMap();
var _knownCheckboxes = new List();
var _options = {};
var containerData = _containers.get(containerId);
if (containerData === undefined) {
- var markAll = container.querySelector('.jsClipboardMarkAll');
+ var markAll = elBySel('.jsClipboardMarkAll', container);
if (markAll !== null) {
- markAll.setAttribute('data-container-id', containerId);
+ elAttr(markAll, 'data-container-id', containerId);
markAll.addEventListener('click', this._markAll.bind(this));
}
containerData = {
- checkboxes: container.getElementsByClassName('jsClipboardItem'),
+ checkboxes: elByClass('jsClipboardItem', container),
element: container,
markAll: markAll,
markedObjectIds: new List()
var checkbox = containerData.checkboxes[j];
if (!_knownCheckboxes.has(checkbox)) {
- checkbox.setAttribute('data-container-id', containerId);
+ elAttr(checkbox, 'data-container-id', containerId);
checkbox.addEventListener('click', _callbackCheckbox);
_knownCheckboxes.add(checkbox);
_initEditors: function() {
var getTypes = function(editor) {
try {
- var types = editor.getAttribute('data-types');
+ var types = elAttr(editor, 'data-types');
if (typeof types === 'string') {
return JSON.parse('{ "types": ' + types.replace(/'/g, '"') + '}').types;
}
return [];
};
- var editors = document.getElementsByClassName('jsClipboardEditor');
+ var editors = elByClass('jsClipboardEditor');
for (var i = 0, length = editors.length; i < length; i++) {
var editor = editors[i];
var types = getTypes(editor);
var isMarked = (checkbox.nodeName !== 'INPUT' || checkbox.checked);
var objectIds = [];
- var containerId = checkbox.getAttribute('data-container-id');
+ var containerId = elAttr(checkbox, 'data-container-id');
var data = _containers.get(containerId);
- var type = data.element.getAttribute('data-type');
+ var type = elAttr(data.element, 'data-type');
for (var i = 0, length = data.checkboxes.length; i < length; i++) {
var item = data.checkboxes[i];
var checkbox = event.currentTarget;
var objectId = ~~checkbox.getAttribute('data-object-id');
var isMarked = checkbox.checked;
- var containerId = checkbox.getAttribute('data-container-id');
+ var containerId = elAttr(checkbox, 'data-container-id');
var data = _containers.get(containerId);
- var type = data.element.getAttribute('data-type');
+ var type = elAttr(data.element, 'data-type');
var clipboardObject = DomTraverse.parentByClass(checkbox, 'jsClipboardObject');
data.markedObjectIds[(isMarked ? 'add' : 'delete')](objectId);
}
var triggerEvent = function() {
- var type = listItem.getAttribute('data-type');
+ var type = elAttr(listItem, 'data-type');
EventHandler.fire('com.woltlab.wcf.clipboard', type, {
data: data,
var items = UiConfirmation.getContentElement().querySelectorAll('input, select, textarea');
for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
- var name = item.getAttribute('name');
+ var name = elAttr(item, 'name');
switch (item.nodeName) {
case 'INPUT':
if (item.checked) {
- formData[name] = item.getAttribute('value');
+ formData[name] = elAttr(item, 'value');
}
break;
parameters: parameters
}, (function(responseData) {
if (data.actionName !== 'unmarkAll') {
- var type = listItem.getAttribute('data-type');
+ var type = elAttr(listItem, 'data-type');
EventHandler.fire('com.woltlab.wcf.clipboard', type, {
data: data,
* @param {object} event event object
*/
_unmarkAll: function(event) {
- var type = event.currentTarget.getAttribute('data-type');
+ var type = elAttr(event.currentTarget, 'data-type');
Ajax.api(this, {
actionName: 'unmarkAll',
_ajaxSuccess: function(data) {
if (data.actionName === 'unmarkAll') {
_containers.forEach((function(containerData) {
- if (containerData.element.getAttribute('data-type') === data.returnValues.objectType) {
- var clipboardObjects = containerData.element.getElementsByClassName('jsMarked');
+ if (elAttr(containerData.element, 'data-type') === data.returnValues.objectType) {
+ var clipboardObjects = elByClass('jsMarked', containerData.element);
while (clipboardObjects.length) {
clipboardObjects[0].classList.remove('jsMarked');
}
// rebuild markings
_containers.forEach((function(containerData) {
- var typeName = containerData.element.getAttribute('data-type');
+ var typeName = elAttr(containerData.element, 'data-type');
- var objectIds = (data.returnValues.markedItems && data.returnValues.markedItems.hasOwnProperty(typeName)) ? data.returnValues.markedItems[typeName] : [];
+ var objectIds = (data.returnValues.markedItems && objOwns(data.returnValues.markedItems, typeName)) ? data.returnValues.markedItems[typeName] : [];
this._rebuildMarkings(containerData, objectIds);
}).bind(this));
var lists = DomTraverse.childrenByTag(editor, 'UL');
var list = lists[0] || null;
if (list === null) {
- list = document.createElement('ul');
+ list = elCreate('ul');
}
fragment.appendChild(list);
- var listItem = document.createElement('li');
+ var listItem = elCreate('li');
listItem.classList.add('dropdown');
list.appendChild(listItem);
- var toggleButton = document.createElement('span');
+ var toggleButton = elCreate('span');
toggleButton.className = 'dropdownToggle button';
toggleButton.textContent = typeData.label;
listItem.appendChild(toggleButton);
- var itemList = document.createElement('ol');
+ var itemList = elCreate('ol');
itemList.classList.add('dropdownMenu');
// create editor items
var itemData = typeData.items[itemIndex];
- var item = document.createElement('li');
- var label = document.createElement('span');
+ var item = elCreate('li');
+ var label = elCreate('span');
label.textContent = itemData.label;
item.appendChild(label);
itemList.appendChild(item);
- item.setAttribute('data-type', typeName);
+ elAttr(item, 'data-type', typeName);
item.addEventListener('click', _callbackItem);
_itemData.set(item, itemData);
}
- var divider = document.createElement('li');
+ var divider = elCreate('li');
divider.classList.add('dropdownDivider');
itemList.appendChild(divider);
// add 'unmark all'
- var unmarkAll = document.createElement('li');
- unmarkAll.setAttribute('data-type', typeName);
- var label = document.createElement('span');
+ var unmarkAll = elCreate('li');
+ elAttr(unmarkAll, 'data-type', typeName);
+ var label = elCreate('span');
label.textContent = Language.get('wcf.clipboard.item.unmarkAll');
unmarkAll.appendChild(label);
itemList.appendChild(unmarkAll);
* Initializes dismiss buttons.
*/
setup: function() {
- var buttons = document.getElementsByClassName('jsDismissNoticeButton');
+ var buttons = elByClass('jsDismissNoticeButton');
if (buttons.length) {
var clickCallback = this._click.bind(this);
data: {
actionName: 'dismiss',
className: 'wcf\\data\\notice\\NoticeAction',
- objectIDs: [ button.getAttribute('data-object-id') ]
+ objectIDs: [ elAttr(button, 'data-object-id') ]
},
success: function() {
var parent = button.parentNode;
return;
}
- _popover = document.createElement('div');
+ _popover = elCreate('div');
_popover.classList.add('popover');
- _popoverContent = document.createElement('div');
+ _popoverContent = elCreate('div');
_popoverContent.classList.add('popoverContent');
_popover.appendChild(_popoverContent);
- var pointer = document.createElement('span');
+ var pointer = elCreate('span');
pointer.classList.add('elementPointer');
- pointer.appendChild(document.createElement('span'));
+ pointer.appendChild(elCreate('span'));
_popover.appendChild(pointer);
- _popoverLoading = document.createElement('span');
+ _popoverLoading = elCreate('span');
_popoverLoading.className = 'icon icon32 fa-spinner';
_popover.appendChild(_popoverLoading);
_handlers.set(options.identifier, {
attributeName: options.attributeName,
- elements: options.legacy ? options.className : document.getElementsByClassName(options.className),
+ elements: options.legacy ? options.className : elByClass(options.className),
legacy: options.legacy,
loadCallback: options.loadCallback
});
* @param {string} identifier handler identifier
*/
_initElements: function(options, identifier) {
- var elements = options.legacy ? document.querySelectorAll(options.elements) : options.elements;
+ var elements = options.legacy ? elBySelAll(options.elements) : options.elements;
for (var i = 0, length = elements.length; i < length; i++) {
var element = elements[i];
element.addEventListener('mouseenter', _callbackMouseEnter);
element.addEventListener('mouseleave', _callbackMouseLeave);
- if (element.nodeName === 'A' && element.getAttribute('href')) {
+ if (element.nodeName === 'A' && elAttr(element, 'href')) {
element.addEventListener('click', _callbackClick);
}
var cacheId = identifier + "-" + objectId;
- element.setAttribute('data-cache-id', cacheId);
+ elAttr(element, 'data-cache-id', cacheId);
_elements.set(id, {
element: element,
if (_activeId) {
var activeElement = _elements.get(_activeId).element;
- if (activeElement.getAttribute('data-cache-id') === cacheId) {
+ if (elAttr(activeElement, 'data-cache-id') === cacheId) {
this._show();
}
}
_activeId = _hoverId;
var elData = _elements.get(_activeId);
- var data = _cache.get(elData.element.getAttribute('data-cache-id'));
+ var data = _cache.get(elAttr(elData.element, 'data-cache-id'));
if (data.state === STATE_READY) {
_popoverContent.appendChild(data.content);
* Binds click handler.
*/
setup: function() {
- document.getElementById('sitemap').addEventListener('click', this._click.bind(this));
+ elById('sitemap').addEventListener('click', this._click.bind(this));
},
/**
_ajaxSuccess: function(data) {
_cache.push(data.returnValues.sitemapName);
- document.getElementById('sitemap_' + data.returnValues.sitemapName).innerHTML = data.returnValues.template;
+ elById('sitemap_' + data.returnValues.sitemapName).innerHTML = data.returnValues.template;
},
_dialogSetup: function() {
after: (function(content, data) {
_cache.push(data.returnValues.sitemapName);
- var tabMenuContainer = content.querySelector('.tabMenuContainer');
+ var tabMenuContainer = elBySel('.tabMenuContainer', content);
var menuId = DomUtil.identify(tabMenuContainer);
UiTabMenu.getTabMenu(menuId).select('sitemap_' + data.returnValues.sitemapName);
* @param {object<string, Element>} tabData tab data
*/
showTab: function(tabData) {
- var name = tabData.active.getAttribute('data-name').replace(/^sitemap_/, '');
+ var name = elAttr(tabData.active, 'data-name').replace(/^sitemap_/, '');
if (_cache.indexOf(name) === -1) {
Ajax.api(this, {
* Adds the style changer to the bottom navigation.
*/
setup: function() {
- var list = document.querySelector('#footerNavigation > ul.navigationItems');
+ var list = elBySel('#footerNavigation > ul.navigationItems');
if (list === null) {
return;
}
- var listItem = document.createElement('li');
+ var listItem = elCreate('li');
listItem.classList.add('styleChanger');
listItem.addEventListener('click', this.showDialog.bind(this));
- var link = document.createElement('a');
- link.setAttribute('href', '#');
+ var link = elCreate('a');
+ elAttr(link, 'href', '#');
link.textContent = Language.get('wcf.style.changeStyle');
listItem.appendChild(link);
className: 'wcf\\data\\style\\StyleAction'
},
after: (function(content) {
- var styles = content.querySelectorAll('.styleList > li');
+ var styles = elBySelAll('.styleList > li', content);
for (var i = 0, length = styles.length; i < length; i++) {
var style = styles[i];
data: {
actionName: 'changeStyle',
className: 'wcf\\data\\style\\StyleAction',
- objectIDs: [ event.currentTarget.getAttribute('data-style-id') ]
+ objectIDs: [ elAttr(event.currentTarget, 'data-style-id') ]
},
success: function() { window.location.reload(); }
});
_callbackClick = this._click.bind(this);
_callbackSelectType = this._selectType.bind(this);
- var group, mailSetting, groups = document.querySelectorAll('#notificationSettings .flexibleButtonGroup');
+ var group, mailSetting, groups = elBySelAll('#notificationSettings .flexibleButtonGroup');
for (var i = 0, length = groups.length; i < length; i++) {
group = groups[i];
- mailSetting = group.querySelector('.notificationSettingsEmail');
+ mailSetting = elBySel('.notificationSettingsEmail', group);
if (mailSetting === null) {
continue;
}
_initGroup: function(group, mailSetting) {
var groupId = ~~group.getAttribute('data-object-id');
- var disabledNotification = document.getElementById('settings_' + groupId + '_disabled');
+ var disabledNotification = elById('settings_' + groupId + '_disabled');
disabledNotification.addEventListener('click', function() { mailSetting.classList.remove('active'); });
- var enabledNotification = document.getElementById('settings_' + groupId + '_enabled');
+ var enabledNotification = elById('settings_' + groupId + '_enabled');
enabledNotification.addEventListener('click', function() { mailSetting.classList.add('active'); });
var mailValue = DomTraverse.childByTag(mailSetting, 'INPUT');
var button = DomTraverse.childByTag(mailSetting, 'A');
- button.setAttribute('data-object-id', groupId);
+ elAttr(button, 'data-object-id', groupId);
button.addEventListener('click', _callbackClick);
_data.set(groupId, {
* @returns {Element} dropdown menu object
*/
_createDropdown: function(objectId, initialValue) {
- var dropdownMenu = document.createElement('ul');
+ var dropdownMenu = elCreate('ul');
dropdownMenu.className = 'dropdownMenu';
- dropdownMenu.setAttribute('data-object-id', objectId);
+ elAttr(dropdownMenu, 'data-object-id', objectId);
var link, listItem, value, items = ['instant', 'daily', 'divider', 'none'];
for (var i = 0; i < 4; i++) {
value = items[i];
- listItem = document.createElement('li');
+ listItem = elCreate('li');
if (value === 'divider') {
listItem.className = 'dropdownDivider';
}
else {
- link = document.createElement('a');
+ link = elCreate('a');
link.textContent = Language.get('wcf.user.notification.mailNotificationType.' + value);
listItem.appendChild(link);
- listItem.setAttribute('data-value', value);
+ elAttr(listItem, 'data-value', value);
listItem.addEventListener('click', _callbackSelectType);
if (initialValue === value) {
* @param {Object} event event object
*/
_selectType: function(event) {
- var value = event.currentTarget.getAttribute('data-value');
+ var value = elAttr(event.currentTarget, 'data-value');
var groupId = ~~event.currentTarget.parentNode.getAttribute('data-object-id');
var data = _data.get(groupId);
data.mailValue.value = value;
- data.mailSetting.querySelector('span.title').textContent = Language.get('wcf.user.notification.mailNotificationType.' + value);
+ elBySel('span.title', data.mailSetting).textContent = Language.get('wcf.user.notification.mailNotificationType.' + value);
data.button.classList[(value === 'none') ? 'remove' : 'add']('yellow');
data.button.classList[(value === 'none') ? 'remove' : 'add']('active');
init: function() {
this._setup();
- var elements = document.querySelectorAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)');
+ var elements = elBySelAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)');
var now = new Date();
for (var i = 0, length = elements.length; i < length; i++) {
var element = elements[i];
element.classList.add('inputDatePicker');
element.readOnly = true;
- var isDateTime = (element.getAttribute('type') === 'datetime');
+ var isDateTime = (elAttr(element, 'type') === 'datetime');
- element.setAttribute('data-is-date-time', isDateTime);
+ elAttr(element, 'data-is-date-time', isDateTime);
// convert value
- var date = null, value = element.getAttribute('value') || '';
- if (element.getAttribute('value')) {
+ var date = null, value = elAttr(element, 'value');
+ if (elAttr(element, 'value')) {
date = new Date(value);
- element.setAttribute('data-value', date.getTime());
+ elAttr(element, 'data-value', date.getTime());
value = DateUtil['formatDate' + (isDateTime ? 'Time' : '')](date);
}
// handle birthday input
if (element.classList.contains('birthday')) {
- element.setAttribute('data-min-date', '100');
- element.setAttribute('data-max-date', 'now');
+ elAttr(element, 'data-min-date', '100');
+ elAttr(element, 'data-max-date', 'now');
}
this._initDateRange(element, now, true);
this._initDateRange(element, now, false);
- if (element.getAttribute('data-min-date') === element.getAttribute('data-max-date')) {
+ if (elAttr(element, 'data-min-date') === elAttr(element, 'data-max-date')) {
throw new Error("Minimum and maximum date cannot be the same (element id '" + element.id + "').");
}
// change type to prevent browser's datepicker to trigger
element.type = 'text';
element.value = value;
- element.setAttribute('data-empty', isEmpty);
+ elAttr(element, 'data-empty', isEmpty);
- if (element.getAttribute('data-placeholder')) {
- element.setAttribute('placeholder', element.getAttribute('data-placeholder'));
+ if (elAttr(element, 'data-placeholder')) {
+ elAttr(element, 'placeholder', elAttr(element, 'data-placeholder'));
}
// add a hidden element to hold the actual date
- var shadowElement = document.createElement('input');
+ var shadowElement = elCreate('input');
shadowElement.id = element.id + 'DatePicker';
shadowElement.name = element.name;
shadowElement.type = 'hidden';
element.addEventListener('click', _callbackOpen);
// create input addon
- var container = document.createElement('div');
+ var container = elCreate('div');
container.className = 'inputAddon';
- var button = document.createElement('a');
+ var button = elCreate('a');
button.className = 'inputSuffix';
button.addEventListener('click', _callbackOpen);
container.appendChild(button);
- var icon = document.createElement('span');
+ var icon = elCreate('span');
icon.className = 'icon icon16 fa-calendar';
button.appendChild(icon);
*/
_initDateRange: function(element, now, isMinDate) {
var attribute = 'data-' + (isMinDate ? 'min' : 'max') + '-date';
- var value = (element.hasAttribute(attribute)) ? element.getAttribute(attribute).trim() : '';
+ var value = (element.hasAttribute(attribute)) ? elAttr(element, attribute).trim() : '';
if (value.match(/^(\d{4})-(\d{2})-(\d{2})$/)) {
// YYYY-mm-dd
// element id, e.g. `datePicker-someOtherElement`
value = RegExp.$1;
- if (document.getElementById(value) === null) {
+ if (elById(value) === null) {
throw new Error("Reference date picker identified by '" + value + "' does not exists (element id: '" + element.id + "').");
}
}
value = new Date((isMinDate ? 1970 : 2038), 0, 1).getTime();
}
- element.setAttribute(attribute, value);
+ elAttr(element, attribute, value);
},
/**
}
_input = input;
- var data = _data.get(_input), date, value = _input.getAttribute('data-value');
+ var data = _data.get(_input), date, value = elAttr(_input, 'data-value');
if (value) {
date = new Date(+value);
}
// set min/max date
- _minDate = _input.getAttribute('data-min-date');
- if (_minDate.match(/^datePicker-(.+)$/)) _minDate = document.getElementById(RegExp.$1).getAttribute('data-value');
+ _minDate = elAttr(_input, 'data-min-date');
+ if (_minDate.match(/^datePicker-(.+)$/)) _minDate = elById(RegExp.$1).getAttribute('data-value');
_minDate = new Date(+_minDate);
- _maxDate = _input.getAttribute('data-max-date');
- if (_maxDate.match(/^datePicker-(.+)$/)) _maxDate = document.getElementById(RegExp.$1).getAttribute('data-value');
+ _maxDate = elAttr(_input, 'data-max-date');
+ if (_maxDate.match(/^datePicker-(.+)$/)) _maxDate = elById(RegExp.$1).getAttribute('data-value');
_maxDate = new Date(+_maxDate);
if (data.isDateTime) {
date.setDate(date.getDate() + 1);
}
- _dateGrid.setAttribute('data-month', month);
- _dateGrid.setAttribute('data-year', year);
+ elAttr(_dateGrid, 'data-month', month);
+ elAttr(_dateGrid, 'data-year', year);
_datePicker.insertBefore(fragment, _dateTime);
cell.classList[(!cell.classList.contains('otherMonth') && ~~cell.textContent === day) ? 'add' : 'remove']('active');
}
- _dateGrid.setAttribute('data-day', day);
+ elAttr(_dateGrid, 'data-day', day);
}
this._formatValue();
_formatValue: function() {
var data = _data.get(_input), date, value, shadowValue;
- if (_input.getAttribute('data-empty') === 'true') {
+ if (elAttr(_input, 'data-empty') === 'true') {
return;
}
if (data.isDateTime) {
date = new Date(
- _dateGrid.getAttribute('data-year'),
- _dateGrid.getAttribute('data-month'),
- _dateGrid.getAttribute('data-day'),
+ elAttr(_dateGrid, 'data-year'),
+ elAttr(_dateGrid, 'data-month'),
+ elAttr(_dateGrid, 'data-day'),
_dateHour.value,
_dateMinute.value
);
}
else {
date = new Date(
- _dateGrid.getAttribute('data-year'),
- _dateGrid.getAttribute('data-month'),
- _dateGrid.getAttribute('data-day')
+ elAttr(_dateGrid, 'data-year'),
+ elAttr(_dateGrid, 'data-month'),
+ elAttr(_dateGrid, 'data-day')
);
value = DateUtil.formatDate(date);
}
_input.value = value;
- _input.setAttribute('data-value', date.getTime());
+ elAttr(_input, 'data-value', date.getTime());
data.shadow.value = shadowValue;
},
return;
}
- _datePicker = document.createElement('div');
+ _datePicker = elCreate('div');
_datePicker.className = 'datePicker';
_datePicker.addEventListener('click', function(event) { event.stopPropagation(); });
- var pointer = document.createElement('span');
+ var pointer = elCreate('span');
pointer.className = 'elementPointer';
pointer.innerHTML = '<span></span>';
_datePicker.appendChild(pointer);
- var header = document.createElement('header');
+ var header = elCreate('header');
_datePicker.appendChild(header);
- _dateMonthPrevious = document.createElement('a');
+ _dateMonthPrevious = elCreate('a');
_dateMonthPrevious.className = 'icon icon16 fa-arrow-left previous';
_dateMonthPrevious.addEventListener('click', this.previousMonth.bind(this));
header.appendChild(_dateMonthPrevious);
- var monthYearContainer = document.createElement('span');
+ var monthYearContainer = elCreate('span');
header.appendChild(monthYearContainer);
- _dateMonth = document.createElement('select');
+ _dateMonth = elCreate('select');
_dateMonth.className = 'month';
_dateMonth.addEventListener('change', this._changeMonth.bind(this));
monthYearContainer.appendChild(_dateMonth);
}
_dateMonth.innerHTML = months;
- _dateYear = document.createElement('select');
+ _dateYear = elCreate('select');
_dateYear.className = 'year';
_dateYear.addEventListener('change', this._changeYear.bind(this));
monthYearContainer.appendChild(_dateYear);
- _dateMonthNext = document.createElement('a');
+ _dateMonthNext = elCreate('a');
_dateMonthNext.className = 'icon icon16 fa-arrow-right next';
_dateMonthNext.addEventListener('click', this.nextMonth.bind(this));
header.appendChild(_dateMonthNext);
- _dateGrid = document.createElement('ul');
+ _dateGrid = elCreate('ul');
_datePicker.appendChild(_dateGrid);
- var item = document.createElement('li');
+ var item = elCreate('li');
item.className = 'weekdays';
_dateGrid.appendChild(item);
var day = i + _firstDayOfWeek;
if (day > 6) day -= 7;
- span = document.createElement('span');
+ span = elCreate('span');
span.textContent = weekdays[day];
item.appendChild(span);
}
// create date grid
var callbackClick = this._click.bind(this), cell, row;
for (var i = 0; i < 5; i++) {
- row = document.createElement('li');
+ row = elCreate('li');
_dateGrid.appendChild(row);
for (var j = 0; j < 7; j++) {
- cell = document.createElement('a');
+ cell = elCreate('a');
cell.addEventListener('click', callbackClick);
_dateCells.push(cell);
}
}
- _dateTime = document.createElement('footer');
+ _dateTime = elCreate('footer');
_datePicker.appendChild(_dateTime);
- _dateHour = document.createElement('select');
+ _dateHour = elCreate('select');
_dateHour.className = 'hour';
_dateHour.addEventListener('change', this._formatValue.bind(this));
_dateTime.appendChild(document.createTextNode('\u00A0:\u00A0'));
- _dateMinute = document.createElement('select');
+ _dateMinute = elCreate('select');
_dateMinute.className = 'minute';
_dateMinute.addEventListener('change', this._formatValue.bind(this));
return;
}
- _input.setAttribute('data-empty', false);
+ elAttr(_input, 'data-empty', false);
this._renderGrid(event.currentTarget.textContent);
element = this._getElement(element);
var data = _data.get(element);
- element.setAttribute('data-value', date.getTime());
+ elAttr(element, 'data-value', date.getTime());
element.value = DateUtil['formatDate' + (data.isDateTime ? 'Time' : '')](date);
data.shadow.value = DateUtil.format(date, (data.isDateTime ? 'c' : 'Y-m-d'));
container.parentNode.insertBefore(element, container);
container.parentNode.removeChild(container);
- element.setAttribute('type', 'date' + (data.isDateTime ? 'time' : ''));
+ elAttr(element, 'type', 'date' + (data.isDateTime ? 'time' : ''));
element.value = data.shadow.value;
element.removeAttribute('data-value');
* @return {Element} input element
*/
_getElement: function(element) {
- if (typeof element === 'string') element = document.getElementById(element);
+ if (typeof element === 'string') element = elById(element);
if (!(element instanceof Element) || !element.classList.contains('inputDatePicker') || !_data.has(element)) {
throw new Error("Expected a valid date picker input element or id.");
define(['Dom/ChangeListener', 'Language', 'WoltLab/WCF/Date/Util', 'WoltLab/WCF/Timer/Repeating'], function(DomChangeListener, Language, DateUtil, Repeating) {
"use strict";
- var _elements = document.getElementsByTagName('time');
+ var _elements = elByTag('time');
var _offset = null;
/**
for (var i = 0, length = _elements.length; i < length; i++) {
var element = _elements[i];
- if (!element.classList.contains('datetime') || element.getAttribute('data-is-future-date')) continue;
+ if (!element.classList.contains('datetime') || elAttr(element, 'data-is-future-date')) continue;
- if (!element.getAttribute('title')) element.setAttribute('title', element.textContent.trim());
+ if (!element.getAttribute('title')) elAttr(element, 'title', element.textContent.trim());
var elTimestamp = ~~element.getAttribute('data-timestamp') + _offset;
- var elDate = element.getAttribute('data-date');
- var elTime = element.getAttribute('data-time');
- var elOffset = element.getAttribute('data-offset');
+ var elDate = elAttr(element, 'data-date');
+ var elTime = elAttr(element, 'data-time');
+ var elOffset = elAttr(element, 'data-offset');
// timestamp is less than 60 seconds ago
if (elTimestamp >= timestamp || timestamp < (elTimestamp + 60)) {
define([], function() {
"use strict";
- var _hasMap = window.hasOwnProperty('Map') && typeof window.Map === 'function';
+ var _hasMap = objOwns(window, 'Map') && typeof window.Map === 'function';
/**
* @constructor
* @return {DocumentFragment} fragment containing DOM nodes
*/
createFragmentFromHtml: function(html) {
- var tmp = document.createElement('div');
+ var tmp = elCreate('div');
tmp.innerHTML = html;
var fragment = document.createDocumentFragment();
do {
elementId = 'wcf' + _idCounter++;
}
- while (document.getElementById(elementId) !== null);
+ while (elById(elementId) !== null);
return elementId;
},
return null;
}
- var id = el.getAttribute('id');
+ var id = elAttr(el, 'id');
if (!id) {
id = this.getUniqueId();
- el.setAttribute('id', id);
+ elAttr(el, 'id', id);
}
return id;
return;
}
- var element = document.getElementById(elementId);
+ var element = elById(elementId);
if (element === null) {
throw new Error("Expected a valid element id, cannot find '" + elementId + "'.");
}
_initElement: function(elementId, element, values, availableLanguages, forceSelection) {
var container = element.parentNode;
if (!container.classList.contains('inputAddon')) {
- container = document.createElement('div');
+ container = elCreate('div');
container.className = 'inputAddon' + (element.nodeName === 'TEXTAREA' ? ' inputAddonTextarea' : '');
- container.setAttribute('data-input-id', elementId);
+ elAttr(container, 'data-input-id', elementId);
element.parentNode.insertBefore(container, element);
container.appendChild(element);
}
container.classList.add('dropdown');
- var button = document.createElement('span');
+ var button = elCreate('span');
button.className = 'button dropdownToggle inputPrefix';
- var span = document.createElement('span');
+ var span = elCreate('span');
span.textContent = Language.get('wcf.global.button.disabledI18n');
button.appendChild(span);
container.insertBefore(button, element);
- var dropdownMenu = document.createElement('ul');
+ var dropdownMenu = elCreate('ul');
dropdownMenu.className = 'dropdownMenu';
DomUtil.insertAfter(dropdownMenu, button);
// build language dropdown
for (var languageId in availableLanguages) {
if (availableLanguages.hasOwnProperty(languageId)) {
- var listItem = document.createElement('li');
- listItem.setAttribute('data-language-id', languageId);
+ var listItem = elCreate('li');
+ elAttr(listItem, 'data-language-id', languageId);
- span = document.createElement('span');
+ span = elCreate('span');
span.textContent = availableLanguages[languageId];
listItem.appendChild(span);
}
if (forceSelection !== true) {
- var listItem = document.createElement('li');
+ var listItem = elCreate('li');
listItem.className = 'dropdownDivider';
- listItem.setAttribute('data-language-id', 0);
+ elAttr(listItem, 'data-language-id', 0);
dropdownMenu.appendChild(listItem);
- listItem = document.createElement('li');
- span = document.createElement('span');
+ listItem = elCreate('li');
+ span = elCreate('span');
span.textContent = Language.get('wcf.global.button.disabledI18n');
listItem.appendChild(span);
listItem.addEventListener('click', callbackClick);
}
var dropdownMenu = UiSimpleDropdown.getDropdownMenu(containerId);
- var elementId = document.getElementById(containerId).getAttribute('data-input-id');
+ var elementId = elById(containerId).getAttribute('data-input-id');
var values = _values.get(elementId);
var item, languageId;
if (values.size) {
values.forEach(function(value, languageId) {
- input = document.createElement('input');
+ input = elCreate('input');
input.type = 'hidden';
input.name = elementId + '_i18n[' + languageId + ']';
input.value = value;
define([], function() {
"use strict";
- var _hasSet = window.hasOwnProperty('Set') && typeof window.Set === 'function';
+ var _hasSet = objOwns(window, 'Set') && typeof window.Set === 'function';
/**
* @constructor
define([], function() {
"use strict";
- var _hasMap = window.hasOwnProperty('WeakMap') && typeof window.WeakMap === 'function';
+ var _hasMap = objOwns(window, 'WeakMap') && typeof window.WeakMap === 'function';
/**
* @constructor
* Sets up the toggle button.
*/
setup: function() {
- var sidebar = document.querySelector('.sidebar');
+ var sidebar = elBySel('.sidebar');
if (sidebar === null) {
return;
}
- _isOpen = (sidebar.getAttribute('data-is-open') === 'true');
- _main = document.getElementById('main');
- _name = sidebar.getAttribute('data-sidebar-name');
+ _isOpen = (elAttr(sidebar, 'data-is-open') === 'true');
+ _main = elById('main');
+ _name = elAttr(sidebar, 'data-sidebar-name');
this._createUI(sidebar);
* @param {Element} sidebar sidebar element
*/
_createUI: function(sidebar) {
- var button = document.createElement('a');
+ var button = elCreate('a');
button.href = '#';
button.className = 'collapsibleButton jsTooltip';
- button.setAttribute('title', Language.get('wcf.global.button.collapsible'));
+ elAttr(button, 'title', Language.get('wcf.global.button.collapsible'));
- var span = document.createElement('span');
+ var span = elCreate('span');
span.appendChild(button);
DomUtil.prepend(span, sidebar);
* Creates the dialog DOM elements.
*/
_createDialog: function() {
- var dialog = document.createElement('div');
- dialog.setAttribute('id', 'wcfSystemConfirmation');
+ var dialog = elCreate('div');
+ elAttr(dialog, 'id', 'wcfSystemConfirmation');
dialog.classList.add('systemConfirmation');
- _text = document.createElement('p');
+ _text = elCreate('p');
dialog.appendChild(_text);
- _content = document.createElement('div');
- _content.setAttribute('id', 'wcfSystemConfirmationContent');
+ _content = elCreate('div');
+ elAttr(_content, 'id', 'wcfSystemConfirmationContent');
dialog.appendChild(_content);
- var formSubmit = document.createElement('div');
+ var formSubmit = elCreate('div');
formSubmit.classList.add('formSubmit');
dialog.appendChild(formSubmit);
- _confirmButton = document.createElement('button');
+ _confirmButton = elCreate('button');
_confirmButton.classList.add('buttonPrimary');
_confirmButton.textContent = Language.get('wcf.global.confirmation.confirm');
_confirmButton.addEventListener('click', this._confirm.bind(this));
formSubmit.appendChild(_confirmButton);
- var cancelButton = document.createElement('button');
+ var cancelButton = elCreate('button');
cancelButton.textContent = Language.get('wcf.global.confirmation.cancel');
cancelButton.addEventListener('click', function() { UiDialog.close('wcfSystemConfirmation'); });
formSubmit.appendChild(cancelButton);
// Fetch Ajax, as it cannot be provided because of a circular dependency
if (Ajax === undefined) Ajax = require('Ajax');
- _container = document.createElement('div');
+ _container = elCreate('div');
_container.classList.add('dialogOverlay');
- _container.setAttribute('aria-hidden', 'true');
+ elAttr(_container, 'aria-hidden', 'true');
_container.addEventListener('click', this._closeOnBackdrop.bind(this));
document.body.appendChild(_container);
var createOnly = true;
if (setupData.source === undefined) {
- var dialogElement = document.getElementById(setupData.id);
+ var dialogElement = elById(setupData.id);
if (dialogElement === null) {
throw new Error("Element id '" + setupData.id + "' is invalid and no source attribute was given.");
}
}
else {
if (typeof setupData.source === 'string') {
- var dialogElement = document.createElement('div');
- dialogElement.setAttribute('id', setupData.id);
+ var dialogElement = elCreate('div');
+ elAttr(dialogElement, 'id', setupData.id);
dialogElement.innerHTML = setupData.source;
setupData.source = document.createDocumentFragment();
_createDialog: function(id, html, options, createOnly) {
var element = null;
if (html === null) {
- element = document.getElementById(id);
+ element = elById(id);
if (element === null) {
throw new Error("Expected either a HTML string or an existing element id.");
}
}
- var dialog = document.createElement('div');
+ var dialog = elCreate('div');
dialog.classList.add('dialogContainer');
- dialog.setAttribute('aria-hidden', 'true');
- dialog.setAttribute('role', 'dialog');
- dialog.setAttribute('data-id', id);
+ elAttr(dialog, 'aria-hidden', 'true');
+ elAttr(dialog, 'role', 'dialog');
+ elAttr(dialog, 'data-id', id);
if (options.disposeOnClose) {
- dialog.setAttribute('data-dispose-on-close', true);
+ elAttr(dialog, 'data-dispose-on-close', true);
}
- var header = document.createElement('header');
+ var header = elCreate('header');
dialog.appendChild(header);
if (options.title) {
var titleId = DomUtil.getUniqueId();
- dialog.setAttribute('aria-labelledby', titleId);
+ elAttr(dialog, 'aria-labelledby', titleId);
- var title = document.createElement('span');
+ var title = elCreate('span');
title.classList.add('dialogTitle');
title.textContent = options.title;
- title.setAttribute('id', titleId);
+ elAttr(title, 'id', titleId);
header.appendChild(title);
}
if (options.closable) {
- var closeButton = document.createElement('a');
+ var closeButton = elCreate('a');
closeButton.className = 'dialogCloseButton jsTooltip';
- closeButton.setAttribute('title', options.closeButtonLabel);
- closeButton.setAttribute('aria-label', options.closeButtonLabel);
+ elAttr(closeButton, 'title', options.closeButtonLabel);
+ elAttr(closeButton, 'aria-label', options.closeButtonLabel);
closeButton.addEventListener('click', this._close.bind(this));
header.appendChild(closeButton);
- var span = document.createElement('span');
+ var span = elCreate('span');
span.textContent = options.closeButtonLabel;
closeButton.appendChild(span);
}
- var contentContainer = document.createElement('div');
+ var contentContainer = elCreate('div');
contentContainer.classList.add('dialogContent');
if (options.disableContentPadding) contentContainer.classList.add('dialogContentNoPadding');
dialog.appendChild(contentContainer);
var content;
if (element === null) {
- content = document.createElement('div');
+ content = elCreate('div');
if (typeof html === 'string') {
content.innerHTML = html;
if (typeof html === 'string') {
data.content.innerHTML = '';
- var content = document.createElement('div');
+ var content = elCreate('div');
content.innerHTML = html;
data.content.appendChild(content);
}
- if (data.dialog.getAttribute('aria-hidden') === 'true') {
- if (_container.getAttribute('aria-hidden') === 'true') {
+ if (elAttr(data.dialog, 'aria-hidden') === 'true') {
+ if (elAttr(_container, 'aria-hidden') === 'true') {
window.addEventListener('keyup', _keyupListener);
}
- data.dialog.setAttribute('aria-hidden', 'false');
- _container.setAttribute('aria-hidden', 'false');
- _container.setAttribute('data-close-on-click', (data.backdropCloseOnClick ? 'true' : 'false'));
+ elAttr(data.dialog, 'aria-hidden', 'false');
+ elAttr(_container, 'aria-hidden', 'false');
+ elAttr(_container, 'data-close-on-click', (data.backdropCloseOnClick ? 'true' : 'false'));
_activeDialog = id;
this.rebuild(id);
}
// ignore non-active dialogs
- if (data.dialog.getAttribute('aria-hidden') === 'true') {
+ if (elAttr(data.dialog, 'aria-hidden') === 'true') {
return;
}
var contentContainer = data.content.parentNode;
- var formSubmit = data.content.querySelector('.formSubmit');
+ var formSubmit = elBySel('.formSubmit', data.content);
var unavailableHeight = 0;
if (formSubmit !== null) {
contentContainer.classList.add('dialogForm');
return true;
}
- if (_container.getAttribute('data-close-on-click') === 'true') {
+ if (elAttr(_container, 'data-close-on-click') === 'true') {
this._close(event);
}
else {
data.onClose(id);
}
- if (data.dialog.getAttribute('data-dispose-on-close')) {
+ if (elAttr(data.dialog, 'data-dispose-on-close')) {
setTimeout(function() {
- if (data.dialog.getAttribute('aria-hidden') === 'true') {
+ if (elAttr(data.dialog, 'aria-hidden') === 'true') {
_container.removeChild(data.dialog);
_dialogs['delete'](id);
}
}, 5000);
}
else {
- data.dialog.setAttribute('aria-hidden', 'true');
+ elAttr(data.dialog, 'aria-hidden', 'true');
}
// get next active dialog
_activeDialog = null;
for (var i = 0; i < _container.childElementCount; i++) {
var child = _container.children[i];
- if (child.getAttribute('aria-hidden') === 'false') {
- _activeDialog = child.getAttribute('data-id');
+ if (elAttr(child, 'aria-hidden') === 'false') {
+ _activeDialog = elAttr(child, 'data-id');
break;
}
}
if (_activeDialog === null) {
- _container.setAttribute('aria-hidden', 'true');
- _container.setAttribute('data-close-on-click', 'false');
+ elAttr(_container, 'aria-hidden', 'true');
+ elAttr(_container, 'data-close-on-click', 'false');
window.removeEventListener('keyup', _keyupListener);
}
else {
data = _dialogs.get(_activeDialog);
- _container.setAttribute('data-close-on-click', (data.backdropCloseOnClick ? 'true' : 'false'));
+ elAttr(_container, 'data-close-on-click', (data.backdropCloseOnClick ? 'true' : 'false'));
}
},
if (_didInit) return;
_didInit = true;
- _menuContainer = document.createElement('div');
- _menuContainer.setAttribute('id', 'dropdownMenuContainer');
+ _menuContainer = elCreate('div');
+ elAttr(_menuContainer, 'id', 'dropdownMenuContainer');
document.body.appendChild(_menuContainer);
- _availableDropdowns = document.getElementsByClassName('dropdownToggle');
+ _availableDropdowns = elByClass('dropdownToggle');
this.initAll();
init: function(button, isLazyInitialization) {
this.setup();
- if (button.classList.contains('jsDropdownEnabled') || button.getAttribute('data-target')) {
+ if (button.classList.contains('jsDropdownEnabled') || elAttr(button, 'data-target')) {
return false;
}
_menus.set(containerId, menu);
if (!containerId.match(/^wcf\d+$/)) {
- menu.setAttribute('data-source', containerId);
+ elAttr(menu, 'data-source', containerId);
}
}
- button.setAttribute('data-target', containerId);
+ elAttr(button, 'data-target', containerId);
if (isLazyInitialization) {
setTimeout(function() { Core.triggerEvent(button, 'click'); }, 10);
*/
setAlignment: function(dropdown, dropdownMenu) {
// check if button belongs to an i18n textarea
- var button = dropdown.querySelector('.dropdownToggle');
+ var button = elBySel('.dropdownToggle', dropdown);
var refDimensionsElement = null;
if (button !== null && button.classList.contains('dropdownCaptionTextarea')) {
refDimensionsElement = button;
*/
_onDialogScroll: function(event) {
var dialogContent = event.currentTarget;
- var dropdowns = dialogContent.querySelectorAll('.dropdown.dropdownOpen');
+ var dropdowns = elBySelAll('.dropdown.dropdownOpen', dialogContent);
for (var i = 0, length = dropdowns.length; i < length; i++) {
var dropdown = dropdowns[i];
*/
_onScroll: function() {
_dropdowns.forEach((function(dropdown, containerId) {
- if (dropdown.getAttribute('data-is-overlay-dropdown-button') === true && dropdown.classList.contains('dropdownOpen')) {
+ if (elAttr(dropdown, 'data-is-overlay-dropdown-button') === true && dropdown.classList.contains('dropdownOpen')) {
this.setAlignment(dropdown, _menus.get(containerId));
}
}).bind(this));
event.preventDefault();
event.stopPropagation();
- targetId = event.currentTarget.getAttribute('data-target');
+ targetId = elAttr(event.currentTarget, 'data-target');
}
// check if 'isOverlayDropdownButton' is set which indicates if
// the dropdown toggle is in an overlay
var dropdown = _dropdowns.get(targetId);
- if (dropdown !== undefined && dropdown.getAttribute('data-is-overlay-dropdown-button') === null) {
+ if (dropdown !== undefined && elAttr(dropdown, 'data-is-overlay-dropdown-button') === null) {
var dialogContent = DomTraverse.parentByClass(dropdown, 'dialogContent');
- dropdown.setAttribute('data-is-overlay-dropdown-button', (dialogContent !== null));
+ elAttr(dropdown, 'data-is-overlay-dropdown-button', (dialogContent !== null));
if (dialogContent !== null) {
dialogContent.addEventListener('scroll', this._onDialogScroll.bind(this));
* Register default menus and set up event listeners.
*/
setup: function() {
- if (document.getElementById('mainMenu') !== null) this.register('mainMenu');
- var navigationHeader = document.querySelector('.navigationHeader');
+ if (elById('mainMenu') !== null) this.register('mainMenu');
+ var navigationHeader = elBySel('.navigationHeader');
if (navigationHeader !== null) this.register(DomUtil.identify(navigationHeader));
window.addEventListener('resize', this.rebuildAll.bind(this));
* @param {string} containerId element id
*/
register: function(containerId) {
- var container = document.getElementById(containerId);
+ var container = elById(containerId);
if (container === null) {
throw "Expected a valid element id, '" + containerId + "' does not exist.";
}
* Registers tab menus.
*/
registerTabMenus: function() {
- var tabMenus = document.querySelectorAll('.tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)');
+ var tabMenus = elBySelAll('.tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)');
for (var i = 0, length = tabMenus.length; i < length; i++) {
var tabMenu = tabMenus[i];
var nav = DomTraverse.childByTag(tabMenu, 'NAV');
if (hiddenItems.length) {
var dropdownMenu;
if (dropdown === undefined) {
- dropdown = document.createElement('li');
+ dropdown = elCreate('li');
dropdown.className = 'dropdown jsFlexibleMenuDropdown';
- var icon = document.createElement('a');
+ var icon = elCreate('a');
icon.className = 'icon icon16 fa-list';
dropdown.appendChild(icon);
- dropdownMenu = document.createElement('ul');
+ dropdownMenu = elCreate('ul');
dropdownMenu.classList.add('dropdownMenu');
dropdown.appendChild(dropdownMenu);
var self = this;
hiddenItems.forEach(function(hiddenItem) {
- var item = document.createElement('li');
+ var item = elCreate('li');
item.innerHTML = hiddenItem.innerHTML;
item.addEventListener('click', (function(event) {
* @param {object<string>} options option list
*/
init: function(elementId, values, options) {
- var element = document.getElementById(elementId);
+ var element = elById(elementId);
if (element === null) {
throw new Error("Expected a valid element id.");
}
if (options.submitFieldName.length) {
var input;
for (var i = 0, length = values.length; i < length; i++) {
- input = document.createElement('input');
+ input = elCreate('input');
input.type = 'hidden';
input.name = options.submitFieldName.replace(/{$objectId}/, values[i].objectId);
input.value = values[i].value;
for (var i = 0, length = items.length; i < length; i++) {
item = items[i];
value = {
- objectId: item.getAttribute('data-object-id'),
+ objectId: elAttr(item, 'data-object-id'),
value: DomTraverse.childByTag(item, 'SPAN').textContent
};
* @param {object<string>} options option list
*/
_createUI: function(element, options) {
- var list = document.createElement('ol');
+ var list = elCreate('ol');
list.className = 'inputItemList';
- list.setAttribute('data-element-id', element.id);
+ elAttr(list, 'data-element-id', element.id);
list.addEventListener('click', function(event) {
if (event.target === list) element.focus();
});
- var listItem = document.createElement('li');
+ var listItem = elCreate('li');
listItem.className = 'input';
list.appendChild(listItem);
listItem.appendChild(element);
if (options.maxLength !== -1) {
- element.setAttribute('maxLength', options.maxLength);
+ elAttr(element, 'maxLength', options.maxLength);
}
var shadow = null, values = [];
if (options.isCSV) {
- shadow = document.createElement('input');
+ shadow = elCreate('input');
shadow.className = 'itemListInputShadow';
shadow.type = 'hidden';
shadow.name = element.name;
}
}
- var inputElement = document.createElement('input');
+ var inputElement = elCreate('input');
element.parentNode.insertBefore(inputElement, element);
inputElement.id = element.id;
}
else if (!data.element.disabled) {
data.element.disabled = true;
- data.element.setAttribute('placeholder', Language.get('wcf.global.form.input.maxItems'));
+ elAttr(data.element, 'placeholder', Language.get('wcf.global.form.input.maxItems'));
}
},
_addItem: function(elementId, value) {
var data = _data.get(elementId);
- var listItem = document.createElement('li');
+ var listItem = elCreate('li');
listItem.className = 'item';
- var content = document.createElement('span');
+ var content = elCreate('span');
content.className = 'content';
- content.setAttribute('data-object-id', value.objectId);
+ elAttr(content, 'data-object-id', value.objectId);
content.textContent = value.value;
- var button = document.createElement('a');
+ var button = elCreate('a');
button.className = 'icon icon16 fa-times';
button.addEventListener('click', _callbackRemoveItem);
listItem.appendChild(content);
item = (event === null) ? item : event.currentTarget.parentNode;
var parent = item.parentNode;
- var elementId = parent.getAttribute('data-element-id');
+ var elementId = elAttr(parent, 'data-element-id');
var data = _data.get(elementId);
data.suggestion.removeExcludedValue(item.children[0].textContent);
* Initializes the mobile UI using enquire.js.
*/
setup: function() {
- _buttonGroupNavigations = document.getElementsByClassName('buttonGroupNavigation');
- _main = document.getElementById('main');
- _sidebar = _main.querySelector('#main > div > div > .sidebar');
+ _buttonGroupNavigations = elByClass('buttonGroupNavigation');
+ _main = elById('main');
+ _sidebar = elBySel('#main > div > div > .sidebar', _main);
if (Environment.touch()) {
document.documentElement.classList.add('touch');
// use icons if language item is empty/non-existant
var languageShowSidebar = 'wcf.global.sidebar.show' + sidebarPosition + 'Sidebar';
if (languageShowSidebar === Language.get(languageShowSidebar) || Language.get(languageShowSidebar) === '') {
- languageShowSidebar = document.createElement('span');
+ languageShowSidebar = elCreate('span');
languageShowSidebar.className = 'icon icon16 fa-angle-double-' + sidebarPosition.toLowerCase();
}
var languageHideSidebar = 'wcf.global.sidebar.hide' + sidebarPosition + 'Sidebar';
if (languageHideSidebar === Language.get(languageHideSidebar) || Language.get(languageHideSidebar) === '') {
- languageHideSidebar = document.createElement('span');
+ languageHideSidebar = elCreate('span');
languageHideSidebar.className = 'icon icon16 fa-angle-double-' + (sidebarPosition === 'Left' ? 'right' : 'left');
}
// add toggle buttons
- var showSidebar = document.createElement('span');
+ var showSidebar = elCreate('span');
showSidebar.className = 'button small mobileSidebarToggleButton';
showSidebar.addEventListener('click', function() { _main.classList.add('mobileShowSidebar'); });
if (languageShowSidebar instanceof Element) showSidebar.appendChild(languageShowSidebar);
else showSidebar.textContent = languageShowSidebar;
- var hideSidebar = document.createElement('span');
+ var hideSidebar = elCreate('span');
hideSidebar.className = 'button small mobileSidebarToggleButton';
hideSidebar.addEventListener('click', function() { _main.classList.remove('mobileShowSidebar'); });
if (languageHideSidebar instanceof Element) hideSidebar.appendChild(languageHideSidebar);
else hideSidebar.textContent = languageHideSidebar;
- document.querySelector('.content').appendChild(showSidebar);
+ elBySel('.content').appendChild(showSidebar);
_sidebar.appendChild(hideSidebar);
},
_initSearchBar: function() {
- var _searchBar = document.querySelector('.searchBar');
+ var _searchBar = elBySel('.searchBar');
_searchBar.addEventListener('click', function() {
if (_enabled) {
if (navigation.classList.contains('jsMobileButtonGroupNavigation')) continue;
else navigation.classList.add('jsMobileButtonGroupNavigation');
- var button = document.createElement('a');
+ var button = elCreate('a');
button.classList.add('dropdownLabel');
- var span = document.createElement('span');
+ var span = elCreate('span');
span.className = 'icon icon24 fa-list';
button.appendChild(span);
},
_closeAllMenus: function() {
- var openMenus = document.querySelectorAll('.jsMobileButtonGroupNavigation > ul.open');
+ var openMenus = elBySelAll('.jsMobileButtonGroupNavigation > ul.open');
for (var i = 0, length = openMenus.length; i < length; i++) {
openMenus[i].classList.remove('open');
}
this._dropdownMenu = null;
this._value = '';
- this._element = document.getElementById(elementId);
+ this._element = elById(elementId);
if (this._element === null) {
throw new Error("Expected a valid element id.");
}
*/
_ajaxSuccess: function(data) {
if (this._dropdownMenu === null) {
- this._dropdownMenu = document.createElement('div');
+ this._dropdownMenu = elCreate('div');
this._dropdownMenu.className = 'dropdownMenu';
UiSimpleDropdown.initFragment(this._element, this._dropdownMenu);
for (var i = 0, length = data.returnValues.length; i < length; i++) {
item = data.returnValues[i];
- anchor = document.createElement('a');
+ anchor = elCreate('a');
anchor.textContent = item.label;
- anchor.setAttribute('data-object-id', item.objectID);
+ elAttr(anchor, 'data-object-id', item.objectID);
anchor.addEventListener('click', this._select.bind(this));
- listItem = document.createElement('li');
+ listItem = elCreate('li');
if (i === 0) listItem.className = 'active';
listItem.appendChild(anchor);
* Initializes available tab menus.
*/
_init: function() {
- var container, containerId, returnValue, tabMenu, tabMenus = document.querySelectorAll('.tabMenuContainer:not(.staticTabMenuContainer)');
+ var container, containerId, returnValue, tabMenu, tabMenus = elBySelAll('.tabMenuContainer:not(.staticTabMenuContainer)');
for (var i = 0, length = tabMenus.length; i < length; i++) {
container = tabMenus[i];
containerId = DomUtil.identify(container);
_tabMenus.forEach(function(tabMenu) {
var foundError = false;
tabMenu.getContainers().forEach(function(container) {
- if (!foundError && container.getElementsByClassName('formError').length) {
+ if (!foundError && elByClass('formError', container).length) {
foundError = true;
tabMenu.select(container.id);
}
// get children
- var tabs = nav.getElementsByTagName('li');
+ var tabs = elByTag('li', nav);
if (tabs.length === null) {
return false;
}
var container, containers = DomTraverse.childrenByTag(this._container, 'DIV'), name;
for (var i = 0, length = containers.length; i < length; i++) {
container = containers[i];
- name = container.getAttribute('data-name');
+ name = elAttr(container, 'data-name');
if (!name) {
name = DomUtil.identify(container);
}
- container.setAttribute('data-name', name);
+ elAttr(container, 'data-name', name);
this._containers.set(name, container);
}
}
if (this._isLegacy) {
- this._container.setAttribute('data-is-legacy', true);
+ elAttr(this._container, 'data-is-legacy', true);
this._tabs.forEach(function(tab, name) {
- tab.setAttribute('aria-controls', name);
+ elAttr(tab, 'aria-controls', name);
});
}
// bind listeners
this._tabs.forEach((function(tab) {
- if (!oldTabs || oldTabs.get(tab.getAttribute('data-name')) !== tab) {
+ if (!oldTabs || oldTabs.get(elAttr(tab, 'data-name')) !== tab) {
tab.children[0].addEventListener('click', this._onClick.bind(this));
}
}).bind(this));
}
if (!selectTab) {
- var preselect = this._container.getAttribute('data-preselect') || '';
+ var preselect = elAttr(this._container, 'data-preselect');
if (preselect === "true" || !preselect) preselect = true;
if (preselect === true) {
}
}
- name = name || tab.getAttribute('data-name');
+ name = name || elAttr(tab, 'data-name');
// unmark active tab
- var oldTab = document.querySelector('#' + this._container.id + ' > nav > ul > li.active');
+ var oldTab = elBySel('#' + this._container.id + ' > nav > ul > li.active');
var oldContent = null;
if (oldTab) {
oldTab.classList.remove('active');
- oldContent = this._containers.get(oldTab.getAttribute('data-name'));
+ oldContent = this._containers.get(elAttr(oldTab, 'data-name'));
oldContent.classList.remove('active');
oldContent.classList.add('hidden');
active: tab,
activeName: name,
previous: oldTab,
- previousName: oldTab ? oldTab.getAttribute('data-name') : null
+ previousName: oldTab ? elAttr(oldTab, 'data-name') : null
});
var jQuery = (this._isLegacy && typeof window.jQuery === 'function') ? window.jQuery : null;
* @return {string} tab name
*/
_getTabName: function(tab) {
- var name = tab.getAttribute('data-name');
+ var name = elAttr(tab, 'data-name');
// handle legacy tab menus
if (!name) {
if (tab.children[0].href.match(/#([^#]+)$/)) {
name = RegExp.$1;
- if (document.getElementById(name) === null) {
+ if (elById(name) === null) {
name = null;
}
else {
this._isLegacy = true;
- tab.setAttribute('data-name', name);
+ elAttr(tab, 'data-name', name);
}
}
}
setup: function() {
if (Environment.platform() !== 'desktop') return;
- _tooltip = document.createElement('div');
- _tooltip.setAttribute('id', 'balloonTooltip');
+ _tooltip = elCreate('div');
+ elAttr(_tooltip, 'id', 'balloonTooltip');
_tooltip.classList.add('balloonTooltip');
- _text = document.createElement('span');
- _text.setAttribute('id', 'balloonTooltipText');
+ _text = elCreate('span');
+ elAttr(_text, 'id', 'balloonTooltipText');
_tooltip.appendChild(_text);
- _pointer = document.createElement('span');
+ _pointer = elCreate('span');
_pointer.classList.add('elementPointer');
- _pointer.appendChild(document.createElement('span'));
+ _pointer.appendChild(elCreate('span'));
_tooltip.appendChild(_pointer);
document.body.appendChild(_tooltip);
- _elements = document.getElementsByClassName('jsTooltip');
+ _elements = elByClass('jsTooltip');
this.init();
var element = _elements[0];
element.classList.remove('jsTooltip');
- var title = element.getAttribute('title');
+ var title = elAttr(element, 'title');
title = (typeof title === 'string') ? title.trim() : '';
if (title.length) {
- element.setAttribute('data-tooltip', title);
+ elAttr(element, 'data-tooltip', title);
element.removeAttribute('title');
element.addEventListener('mouseenter', this._mouseEnter.bind(this));
*/
_mouseEnter: function(event) {
var element = event.currentTarget;
- var title = element.getAttribute('title');
+ var title = elAttr(element, 'title');
title = (typeof title === 'string') ? title.trim() : '';
if (title !== '') {
- element.setAttribute('data-tooltip', title);
+ elAttr(element, 'data-tooltip', title);
element.removeAttribute('title');
}
- title = element.getAttribute('data-tooltip');
+ title = elAttr(element, 'data-tooltip');
// reset tooltip position
_tooltip.style.removeProperty('top');
include: [
"requireLib",
"require.config",
- "require.linearExecution"
+ "require.linearExecution",
+ "wcf.globalHelper"
],
excludeShallow: [
'WoltLab/_Meta'
--- /dev/null
+/**
+ * Collection of global short hand functions.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+(function(window, document) {
+ /**
+ * Shorthand function to retrieve or set an attribute.
+ *
+ * @param {Element} element target element
+ * @param {string} attribute attribute name
+ * @param {mixed=} value attribute value, omit if attribute should be read
+ * @return {(string|undefined)} attribute value, empty string if attribute is not set or undefined if `value` was omitted
+ */
+ window.elAttr = function(element, attribute, value) {
+ if (value === undefined) {
+ return element.getAttribute(attribute) || '';
+ }
+
+ element.setAttribute(attribute, value);
+ };
+
+ /**
+ * Shorthand function to find elements by class name.
+ *
+ * @param {string} className CSS class name
+ * @param {Element=} context target element, assuming `document` if omitted
+ * @return {NodeList} matching elements
+ */
+ window.elByClass = function(className, context) {
+ return (context || document).getElementsByClassName(className);
+ };
+
+ /**
+ * Shorthand function to retrieve an element by id.
+ *
+ * @param {string} id element id
+ * @return {(Element|null)} matching element or null if not found
+ */
+ window.elById = function(id) {
+ return document.getElementById(id);
+ };
+
+ /**
+ * Shorthand function to find an element by CSS selector.
+ *
+ * @param {string} selector CSS selector
+ * @param {Element=} context target element, assuming `document` if omitted
+ * @return {(Element|null)} matching element or null if no match
+ */
+ window.elBySel = function(selector, context) {
+ return (context || document).querySelector(selector);
+ };
+
+ /**
+ * Shorthand function to find elements by CSS selector.
+ *
+ * @param {string} selector CSS selector
+ * @param {Element=} context target element, assuming `document` if omitted
+ * @return {NodeList} matching elements
+ */
+ window.elBySelAll = function(selector, context) {
+ return (context || document).querySelectorAll(selector);
+ };
+
+ /**
+ * Shorthand function to find elements by tag name.
+ *
+ * @param {string} tagName element tag name
+ * @param {Element=} context target element, assuming `document` if omitted
+ * @return {NodeList} matching elements
+ */
+ window.elByTag = function(tagName, context) {
+ return (context || document).getElementsByTagName(tagName);
+ };
+
+ /**
+ * Shorthand function to create a DOM element.
+ *
+ * @param {string} tagName element tag name
+ * @return {Element} new DOM element
+ */
+ window.elCreate = function(tagName) {
+ return document.createElement(tagName);
+ };
+
+ /**
+ * 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);