Using shorthand functions for DOM operations
authorAlexander Ebert <ebert@woltlab.com>
Sun, 12 Jul 2015 12:25:33 +0000 (14:25 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 12 Jul 2015 14:17:50 +0000 (16:17 +0200)
32 files changed:
wcfsetup/install/files/js/WoltLab/WCF/Ajax/Jsonp.js
wcfsetup/install/files/js/WoltLab/WCF/Ajax/Request.js
wcfsetup/install/files/js/WoltLab/WCF/Ajax/Status.js
wcfsetup/install/files/js/WoltLab/WCF/Bbcode/FromHtml.js
wcfsetup/install/files/js/WoltLab/WCF/Bbcode/ToHtml.js
wcfsetup/install/files/js/WoltLab/WCF/Bootstrap.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Clipboard.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Notice/Dismiss.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Popover.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Sitemap.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Style/Changer.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/User/Notification/Settings.js
wcfsetup/install/files/js/WoltLab/WCF/Date/Picker.js
wcfsetup/install/files/js/WoltLab/WCF/Date/Time/Relative.js
wcfsetup/install/files/js/WoltLab/WCF/Dictionary.js
wcfsetup/install/files/js/WoltLab/WCF/Dom/Util.js
wcfsetup/install/files/js/WoltLab/WCF/Language/Input.js
wcfsetup/install/files/js/WoltLab/WCF/List.js
wcfsetup/install/files/js/WoltLab/WCF/ObjectMap.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Collapsible/Sidebar.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Confirmation.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Dialog.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Dropdown/Simple.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/FlexibleMenu.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/ItemList.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Mobile.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Suggestion.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/TabMenu.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/TabMenu/Simple.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Tooltip.js
wcfsetup/install/files/js/require.build.js
wcfsetup/install/files/js/wcf.globalHelper.js [new file with mode: 0644]

index 6f501d513ff8f124407ff54b914ba9f78d2f79f6..df8efb161cb9cac62bc7d779c6091533d1049155 100644 (file)
@@ -55,9 +55,9 @@ define(['Core'], function(Core) {
                        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);
                }
index e068e75437c1f3f0f3015f66ff7d8aeddbea1830..b9d0c425873687e841135e6817c8000b864177ec 100644 (file)
@@ -293,13 +293,13 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt
                        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);
                                }
                        }
                }
index ef0425f3b4d3177fa606345f3b087c280c66f92e..5ca1ef59b5d669f8ebb70989e534190cd86a77c5 100644 (file)
@@ -21,14 +21,14 @@ define(['Language'], function(Language) {
                 * 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);
                        
index 3e95ff109134a66bf9caed8d648aadfbfb8205bd..97c302a2e456773f41464a7d94d2d43bd45c1621 100644 (file)
@@ -42,14 +42,14 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                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
@@ -66,7 +66,7 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                        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);
@@ -85,7 +85,7 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                        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++) {
@@ -105,8 +105,8 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                 * @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();
@@ -226,7 +226,7 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                                return;
                        }
                        
-                       var element, elements = container.getElementsByTagName(converter.tagName);
+                       var element, elements = elByTag(converter.tagName, container);
                        while (elements.length) {
                                element = elements[0];
                                
@@ -245,8 +245,8 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                 * @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) {
@@ -278,7 +278,7 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                _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;
                        }
                        
@@ -287,7 +287,7 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                        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]";
@@ -477,12 +477,12 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                 * @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]';
                        }
@@ -525,8 +525,8 @@ define(['EventHandler', 'StringUtil', 'Dom/Traverse'], function(EventHandler, St
                 * @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;
index 6431598ed42abafba01cb70d188682725a964e35..22a642cb892ee303878b5f78e6da2eb57b3f2a59 100644 (file)
@@ -42,7 +42,7 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/Bbcode/Pa
         * @return      {boolean}       true if `value` is a known highlighter
         */
        function isHighlighter(value) {
-               return __REDACTOR_CODE_HIGHLIGHTERS.hasOwnProperty(value);
+               return objOwns(__REDACTOR_CODE_HIGHLIGHTERS, value);
        }
        
        /**
index f26432f96a10c5f04e851759c73af9ec24fd7720..32234df72ee33b080ed6c1cf75f084990b59a788 100644 (file)
@@ -55,7 +55,7 @@ define(
                        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');
                        }
index 17e8dac000716c91de5059c19259d7e8c7ee4775..3e9782b55d81d3ab06ce68af81e904ede86329ad 100644 (file)
@@ -22,7 +22,7 @@ define(
        
        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 = {};
@@ -85,14 +85,14 @@ define(
                                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()
@@ -104,7 +104,7 @@ define(
                                        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);
@@ -119,7 +119,7 @@ define(
                _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;
                                        }
@@ -131,7 +131,7 @@ define(
                                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);
@@ -165,9 +165,9 @@ define(
                        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];
@@ -208,9 +208,9 @@ define(
                        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);
@@ -264,7 +264,7 @@ define(
                        }
                        
                        var triggerEvent = function() {
-                               var type = listItem.getAttribute('data-type');
+                               var type = elAttr(listItem, 'data-type');
                                
                                EventHandler.fire('com.woltlab.wcf.clipboard', type, {
                                        data: data,
@@ -293,12 +293,12 @@ define(
                                                                        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;
                                                                                        
@@ -366,7 +366,7 @@ define(
                                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,
@@ -389,7 +389,7 @@ define(
                 * @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',
@@ -420,8 +420,8 @@ define(
                _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');
                                                }
@@ -446,9 +446,9 @@ define(
                        
                        // 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));
                        
@@ -470,21 +470,21 @@ define(
                                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
@@ -493,26 +493,26 @@ define(
                                        
                                        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);
index 502898cb9fe72ed410eb7b7452a3af390968f520..ec19886ee3065b3cbdfd05d26ab3d8b03b3e6b73 100644 (file)
@@ -17,7 +17,7 @@ define(['Ajax'], function(Ajax) {
                 * Initializes dismiss buttons.
                 */
                setup: function() {
-                       var buttons = document.getElementsByClassName('jsDismissNoticeButton');
+                       var buttons = elByClass('jsDismissNoticeButton');
                        
                        if (buttons.length) {
                                var clickCallback = this._click.bind(this);
@@ -37,7 +37,7 @@ define(['Ajax'], function(Ajax) {
                                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;
index 6122f9654b28854b46619ffd089f889f9510346a..f8a220ae25857b232309e9a29fec7800b363b6a6 100644 (file)
@@ -47,19 +47,19 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                                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);
                        
@@ -129,7 +129,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                        
                        _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
                        });
@@ -158,7 +158,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                 * @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];
                                
@@ -175,12 +175,12 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                                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,
@@ -217,7 +217,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                        if (_activeId) {
                                var activeElement = _elements.get(_activeId).element;
                                
-                               if (activeElement.getAttribute('data-cache-id') === cacheId) {
+                               if (elAttr(activeElement, 'data-cache-id') === cacheId) {
                                        this._show();
                                }
                        }
@@ -307,7 +307,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                        _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);
index 5c2fad13afae41830d269a07bf181df2e74d0440..9e447f8482a518ae79eafea7256f1c1b11fdbfff 100644 (file)
@@ -20,7 +20,7 @@ define(['Ajax', 'EventHandler', 'Language', 'Dom/Util', 'Ui/Dialog', 'Ui/TabMenu
                 * Binds click handler.
                 */
                setup: function() {
-                       document.getElementById('sitemap').addEventListener('click', this._click.bind(this));
+                       elById('sitemap').addEventListener('click', this._click.bind(this));
                },
                
                /**
@@ -46,7 +46,7 @@ define(['Ajax', 'EventHandler', 'Language', 'Dom/Util', 'Ui/Dialog', 'Ui/TabMenu
                _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() {
@@ -64,7 +64,7 @@ define(['Ajax', 'EventHandler', 'Language', 'Dom/Util', 'Ui/Dialog', 'Ui/TabMenu
                                        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);
@@ -81,7 +81,7 @@ define(['Ajax', 'EventHandler', 'Language', 'Dom/Util', 'Ui/Dialog', 'Ui/TabMenu
                 * @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, {
index cd77cb8f4551e53d3cb9f2ade0cb4d16cafba100..8da9ead3b5cd1994798d5f9115a3c4d3d6c955dd 100644 (file)
@@ -17,17 +17,17 @@ define(['Ajax', 'Language', 'Ui/Dialog'], function(Ajax, Language, UiDialog) {
                 * 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);
                        
@@ -58,7 +58,7 @@ define(['Ajax', 'Language', 'Ui/Dialog'], function(Ajax, Language, UiDialog) {
                                                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];
                                                        
@@ -82,7 +82,7 @@ define(['Ajax', 'Language', 'Ui/Dialog'], function(Ajax, Language, UiDialog) {
                                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(); }
                        });
index fb9fc73b5ae781ca736a9617a02aac90200e72db..44b6a34853c018cf721dda4f5ac442130a1b1896 100644 (file)
@@ -25,11 +25,11 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function
                        _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;
                                }
@@ -47,15 +47,15 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function
                _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, {
@@ -101,23 +101,23 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function
                 * @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) {
@@ -137,12 +137,12 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function
                 * @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');
index 21c2fc184097f2b62060ee3f3295a3a3e7111c45..93d6b137c729f317df39876c003fb5a65b3a656e 100644 (file)
@@ -40,22 +40,22 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                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);
                                }
                                
@@ -63,28 +63,28 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                
                                // 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';
@@ -99,15 +99,15 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                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);
                                
@@ -134,7 +134,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                 */
                _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
@@ -154,7 +154,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                // 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 + "').");
                                }
                        }
@@ -162,7 +162,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                value = new Date((isMinDate ? 1970 : 2038), 0, 1).getTime();
                        }
                        
-                       element.setAttribute(attribute, value);
+                       elAttr(element, attribute, value);
                },
                
                /**
@@ -196,7 +196,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        }
                        
                        _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);
                                
@@ -209,12 +209,12 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        }
                        
                        // 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) {
@@ -338,8 +338,8 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                        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);
                                
@@ -382,7 +382,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                        cell.classList[(!cell.classList.contains('otherMonth') && ~~cell.textContent === day) ? 'add' : 'remove']('active');
                                }
                                
-                               _dateGrid.setAttribute('data-day', day);
+                               elAttr(_dateGrid, 'data-day', day);
                        }
                        
                        this._formatValue();
@@ -394,15 +394,15 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                _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
                                );
@@ -412,9 +412,9 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        }
                        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);
@@ -422,7 +422,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        }
                        
                        _input.value = value;
-                       _input.setAttribute('data-value', date.getTime());
+                       elAttr(_input, 'data-value', date.getTime());
                        data.shadow.value = shadowValue;
                },
                
@@ -434,27 +434,27 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                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);
@@ -465,20 +465,20 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        }
                        _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);
                        
@@ -487,7 +487,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                var day = i + _firstDayOfWeek;
                                if (day > 6) day -= 7;
                                
-                               span = document.createElement('span');
+                               span = elCreate('span');
                                span.textContent = weekdays[day];
                                item.appendChild(span);
                        }
@@ -495,11 +495,11 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        // 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);
                                        
@@ -507,10 +507,10 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                }
                        }
                        
-                       _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));
                        
@@ -527,7 +527,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        
                        _dateTime.appendChild(document.createTextNode('\u00A0:\u00A0'));
                        
-                       _dateMinute = document.createElement('select');
+                       _dateMinute = elCreate('select');
                        _dateMinute.className = 'minute';
                        _dateMinute.addEventListener('change', this._formatValue.bind(this));
                        
@@ -600,7 +600,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                                return;
                        }
                        
-                       _input.setAttribute('data-empty', false);
+                       elAttr(_input, 'data-empty', false);
                        
                        this._renderGrid(event.currentTarget.textContent);
                        
@@ -633,7 +633,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        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'));
@@ -668,7 +668,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                        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');
@@ -698,7 +698,7 @@ define(['DateUtil', 'Language', 'ObjectMap', 'Dom/ChangeListener', 'Ui/Alignment
                 * @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.");
index 343a0e02f318a9d9cbe5097bc91168ca45780460..6e4c36a47f7c99d7ee79b92946eaf92ef5eb0321 100644 (file)
@@ -9,7 +9,7 @@
 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;
        
        /**
@@ -35,14 +35,14 @@ define(['Dom/ChangeListener', 'Language', 'WoltLab/WCF/Date/Util', 'WoltLab/WCF/
                        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)) {
index 806c70917218c78c62c2cd7944d8b7d44077e14b..d8f927fffc51f6865aa9b125013c75d252898e8d 100644 (file)
@@ -11,7 +11,7 @@
 define([], function() {
        "use strict";
        
-       var _hasMap = window.hasOwnProperty('Map') && typeof window.Map === 'function';
+       var _hasMap = objOwns(window, 'Map') && typeof window.Map === 'function';
        
        /**
         * @constructor
index 190799d633748e67c96850009d5135da116305aa..24befc5e0d324d43c2bbfa2ac3027039be036a1d 100644 (file)
@@ -31,7 +31,7 @@ define([], function() {
                 * @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();
@@ -53,7 +53,7 @@ define([], function() {
                        do {
                                elementId = 'wcf' + _idCounter++;
                        }
-                       while (document.getElementById(elementId) !== null);
+                       while (elById(elementId) !== null);
                        
                        return elementId;
                },
@@ -70,10 +70,10 @@ define([], function() {
                                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;
index 5e1326c8eaee3e78380b0354e2f0d739eaa4346b..ad25bb8920afd036f393229aeac5f94ea8346033 100644 (file)
@@ -34,7 +34,7 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                                return;
                        }
                        
-                       var element = document.getElementById(elementId);
+                       var element = elById(elementId);
                        if (element === null) {
                                throw new Error("Expected a valid element id, cannot find '" + elementId + "'.");
                        }
@@ -77,25 +77,25 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                _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);
                        
@@ -113,10 +113,10 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                        // 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);
@@ -126,13 +126,13 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                        }
                        
                        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);
@@ -226,7 +226,7 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                        }
                        
                        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;
@@ -261,7 +261,7 @@ define(['Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traverse', 'Do
                                
                                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;
index f79d54ae77b5f6cddb3f0f65aad0c635cd4782e5..f461382cbe5133c6c3df751fd227004be9dfcacb 100644 (file)
@@ -9,7 +9,7 @@
 define([], function() {
        "use strict";
        
-       var _hasSet = window.hasOwnProperty('Set') && typeof window.Set === 'function';
+       var _hasSet = objOwns(window, 'Set') && typeof window.Set === 'function';
        
        /**
         * @constructor
index 0afad20c0b48d56f1d5de42c7e593061c6dca9e2..073fb8f5ed9088d75d7cdb3601c4566bad610367 100644 (file)
@@ -11,7 +11,7 @@
 define([], function() {
        "use strict";
        
-       var _hasMap = window.hasOwnProperty('WeakMap') && typeof window.WeakMap === 'function';
+       var _hasMap = objOwns(window, 'WeakMap') && typeof window.WeakMap === 'function';
        
        /**
         * @constructor
index bc7f3388af64cb3110f5636ca398929c67887549..bbb67995accd463da709485cb3daef297b564f29 100644 (file)
@@ -21,14 +21,14 @@ define(['Ajax', 'Language', 'Dom/Util'], function(Ajax, Language, DomUtil) {
                 * 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);
                        
@@ -41,12 +41,12 @@ define(['Ajax', 'Language', 'Dom/Util'], function(Ajax, Language, DomUtil) {
                 * @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);
                        
index 8c21bf03f4820ad8061c0155467905d98aec74a3..9a59796275268c1bb2fcb8189b382ac39e06b7d2 100644 (file)
@@ -95,28 +95,28 @@ define(['Core', 'Language', 'Ui/Dialog'], function(Core, Language, UiDialog) {
                 * 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);
index 9d69d7078a62f765e189af197ddde4a98319a70e..c8892009f7745a81a51772b479edcabbbc99530e 100644 (file)
@@ -38,9 +38,9 @@ define(
                        // 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);
@@ -93,7 +93,7 @@ define(
                        
                        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.");
                                }
@@ -122,8 +122,8 @@ define(
                        }
                        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();
@@ -218,57 +218,57 @@ define(
                _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;
@@ -326,20 +326,20 @@ define(
                        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);
@@ -364,13 +364,13 @@ define(
                        }
                        
                        // 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');
@@ -428,7 +428,7 @@ define(
                                return true;
                        }
                        
-                       if (_container.getAttribute('data-close-on-click') === 'true') {
+                       if (elAttr(_container, 'data-close-on-click') === 'true') {
                                this._close(event);
                        }
                        else {
@@ -458,37 +458,37 @@ define(
                                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'));
                        }
                },
                
index 743d3a80cda5b5494c64081d8324fda1425115f0..13f9821594bdf406c89c23d80d9d49526c86b9ae 100644 (file)
@@ -30,11 +30,11 @@ define(
                        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();
                        
@@ -65,7 +65,7 @@ define(
                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;
                        }
                        
@@ -91,11 +91,11 @@ define(
                                _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);
@@ -167,7 +167,7 @@ define(
                 */
                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;
@@ -278,7 +278,7 @@ define(
                 */
                _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];
@@ -314,7 +314,7 @@ define(
                 */
                _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));
@@ -344,15 +344,15 @@ define(
                                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));
index d82e9f87fc07ff76130071587f585146fd3ab283..726c790ca4c73fdc9f76b5215f5d030900dcb1f4 100644 (file)
@@ -23,8 +23,8 @@ define(['Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util',
                 * 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));
@@ -37,7 +37,7 @@ define(['Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util',
                 * @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.";
                        }
@@ -61,7 +61,7 @@ define(['Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util',
                 * 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');
@@ -142,13 +142,13 @@ define(['Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util',
                        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);
                                        
@@ -170,7 +170,7 @@ define(['Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util',
                                
                                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) {
index f389958e99ad72b7c25c6acfa41ac3462735e4e1..f2d8a1f0eba142c96cc275a677b063bb7de93657 100644 (file)
@@ -33,7 +33,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                 * @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.");
                        }
@@ -78,7 +78,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                                                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;
@@ -143,7 +143,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                        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
                                };
                                
@@ -177,14 +177,14 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                 * @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);
                        
@@ -196,12 +196,12 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                        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;
@@ -218,7 +218,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                                                }
                                        }
                                        
-                                       var inputElement = document.createElement('input');
+                                       var inputElement = elCreate('input');
                                        element.parentNode.insertBefore(inputElement, element);
                                        inputElement.id = element.id;
                                        
@@ -254,7 +254,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                        }
                        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'));
                        }
                },
                
@@ -337,15 +337,15 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                _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);
@@ -374,7 +374,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'WoltLab/WCF/Ui/Sugges
                        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);
index 829f13ff4e975b3b5ebe67d98dfd7c66bd5e7384..9eee9ca29f030e54726fb87311d7e23ca338cb4e 100644 (file)
@@ -25,9 +25,9 @@ define(
                 * 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');
@@ -97,35 +97,35 @@ define(
                        // 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) {
@@ -147,10 +147,10 @@ define(
                                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);
                                
@@ -171,7 +171,7 @@ define(
                },
                
                _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');
                        }
index 8a0b681f7ac0d23d7fcf16a1c13619e2a9daf7ff..fa72f04c6f7daa51eea67a0d6c7208106367e745 100644 (file)
@@ -26,7 +26,7 @@ define(['Ajax', 'Core', 'Ui/SimpleDropdown'], function(Ajax, Core, UiSimpleDropd
                        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.");
                        }
@@ -207,7 +207,7 @@ define(['Ajax', 'Core', 'Ui/SimpleDropdown'], function(Ajax, Core, UiSimpleDropd
                 */
                _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);
@@ -221,12 +221,12 @@ define(['Ajax', 'Core', 'Ui/SimpleDropdown'], function(Ajax, Core, UiSimpleDropd
                                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);
                                        
index b5114615514173860c5aba2d7c38d5a2906314cd..c540becc546cc7261da3f20ab00b505459a3c3c9 100644 (file)
@@ -29,7 +29,7 @@ define(['Dictionary', 'Dom/ChangeListener', 'Dom/Util', './TabMenu/Simple'], fun
                 * 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);
@@ -59,7 +59,7 @@ define(['Dictionary', 'Dom/ChangeListener', 'Dom/Util', './TabMenu/Simple'], fun
                        _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);
index d045520bfecc44a0e0e5eccc3eeeb7d0cb1b9535..50d39526862902295213834bf1af5ea818076844 100644 (file)
@@ -48,7 +48,7 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                        }
                        
                        // get children
-                       var tabs = nav.getElementsByTagName('li');
+                       var tabs = elByTag('li', nav);
                        if (tabs.length === null) {
                                return false;
                        }
@@ -56,13 +56,13 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                        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);
                        }
                        
@@ -100,10 +100,10 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                        }
                        
                        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);
                                });
                        }
                        
@@ -121,7 +121,7 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                        
                        // 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));
@@ -139,7 +139,7 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                                }
                                
                                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) {
@@ -196,14 +196,14 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                                }
                        }
                        
-                       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');
                                
@@ -228,7 +228,7 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                                        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;
@@ -283,7 +283,7 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                 * @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) {
@@ -291,12 +291,12 @@ define(['Dictionary', 'Dom/Traverse', 'Dom/Util', 'EventHandler'], function(Dict
                                        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);
                                                }
                                        }
                                }
index 2f07e3039bdd4f2fc31ab7a1d28dcf99d092f8ad..172f95bf47ac1845e163cff847449644f3a45e53 100644 (file)
@@ -24,22 +24,22 @@ define(['Environment', 'Dom/ChangeListener', 'Ui/Alignment'], function(Environme
                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();
                        
@@ -54,11 +54,11 @@ define(['Environment', 'Dom/ChangeListener', 'Ui/Alignment'], function(Environme
                                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));
@@ -75,15 +75,15 @@ define(['Environment', 'Dom/ChangeListener', 'Ui/Alignment'], function(Environme
                 */
                _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');
index 1bbb02e16984eb24888f44cdaa2d9c219a414f52..2d8497a1a62083419861c1dd94b2f299d6befbf1 100644 (file)
@@ -14,7 +14,8 @@
        include: [
                "requireLib",
                "require.config",
-               "require.linearExecution"
+               "require.linearExecution",
+               "wcf.globalHelper"
        ],
        excludeShallow: [
                'WoltLab/_Meta'
diff --git a/wcfsetup/install/files/js/wcf.globalHelper.js b/wcfsetup/install/files/js/wcf.globalHelper.js
new file mode 100644 (file)
index 0000000..9198429
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * 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);