Introduced WoltLab/WCF/Environment as a replacement for $.browser
authorAlexander Ebert <ebert@woltlab.com>
Wed, 20 May 2015 18:31:50 +0000 (20:31 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 20 May 2015 18:31:50 +0000 (20:31 +0200)
wcfsetup/install/files/js/WoltLab/WCF/Bootstrap.js
wcfsetup/install/files/js/WoltLab/WCF/Controller/Popover.js
wcfsetup/install/files/js/WoltLab/WCF/Core.js
wcfsetup/install/files/js/WoltLab/WCF/Environment.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLab/WCF/UI/Dialog.js
wcfsetup/install/files/js/WoltLab/WCF/UI/Mobile.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.config.js

index 73d47ecc896def13c9f9754d8a68779b88297c63..ff371d32da1873b847cf0051746476e4dfe71134 100644 (file)
  */
 define(
        [
-               'jquery',            'favico',                 'enquire',                'WoltLab/WCF/Date/Time/Relative',
+               'favico',            'enquire',                'WoltLab/WCF/Date/Time/Relative',
                'UI/SimpleDropdown', 'WoltLab/WCF/UI/Mobile',  'WoltLab/WCF/UI/TabMenu', 'WoltLab/WCF/UI/FlexibleMenu',
-               'UI/Dialog',         'WoltLab/WCF/UI/Tooltip', 'WoltLab/WCF/Language'
+               'UI/Dialog',         'WoltLab/WCF/UI/Tooltip', 'WoltLab/WCF/Language',   'WoltLab/WCF/Environment'
        ], 
        function(
-                $,                   favico,                   enquire,                  relativeTime,
-                simpleDropdown,      UIMobile,                 UITabMenu,                UIFlexibleMenu,
-                UIDialog,            UITooltip,                Language
+                favico,              enquire,                  DateTimeRelative,
+                UISimpleDropdown,    UIMobile,                 UITabMenu,                UIFlexibleMenu,
+                UIDialog,            UITooltip,                Language,                 Environment
        )
 {
        "use strict";
@@ -37,8 +37,11 @@ define(
                 * Initializes the core UI modifications and unblocks jQuery's ready event.
                 */
                setup: function() {
-                       relativeTime.setup();
-                       simpleDropdown.setup();
+                       Environment.setup();
+                       
+                       DateTimeRelative.setup();
+                       
+                       UISimpleDropdown.setup();
                        UIMobile.setup();
                        UITabMenu.setup();
                        UIFlexibleMenu.setup();
@@ -51,13 +54,21 @@ define(
                                forms[i].setAttribute('method', 'post');
                        }
                        
-                       if ($.browser.msie) {
+                       if (Environment.browser() === 'microsoft') {
                                window.onbeforeunload = function() {
                                        /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
                                };
                        }
                        
-                       $.holdReady(false);
+                       // DEBUG ONLY
+                       var interval = 0;
+                       interval = window.setInterval(function() {
+                               if (typeof window.jQuery === 'function') {
+                                       window.clearInterval(interval);
+                                       
+                                       window.jQuery.holdReady(false);
+                               }
+                       }, 20);
                }
        };
        
index 9b6992ff95d9944af917abad3084267ced5cefe0..8334bf604e9d04da9e2fe1b6a88ef93e983a2c96 100644 (file)
@@ -6,7 +6,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/Controller/Popover
  */
-define(['Dictionary', 'DOM/Util', 'UI/Alignment'], function(Dictionary, DOMUtil, UIAlignment) {
+define(['Dictionary', 'Environment', 'DOM/Util', 'UI/Alignment'], function(Dictionary, Environment, DOMUtil, UIAlignment) {
        "use strict";
        
        var _activeId = null;
@@ -119,7 +119,7 @@ define(['Dictionary', 'DOM/Util', 'UI/Alignment'], function(Dictionary, DOMUtil,
                 * @param       {object<string, *>}     options         handler options
                 */
                init: function(options) {
-                       if ($.browser.mobile) {
+                       if (Environment.platform() !== 'desktop') {
                                return;
                        }
                        
index b52d5e333ba72965135e739d9e8801ff37501c24..249c7e97648c99360fc81cb56161015f1b7282a8 100644 (file)
@@ -26,17 +26,17 @@ define([], function() {
                        }
                        
                        return url.replace(/^index\.php\/(.*?)\/\?/, function(match, controller) {
-                               var $parts = controller.split(/([A-Z][a-z0-9]+)/);
-                               var $controller = '';
-                               for (var $i = 0, $length = $parts.length; $i < $length; $i++) {
-                                       var $part = $parts[$i].trim();
-                                       if ($part.length) {
-                                               if ($controller.length) $controller += '-';
-                                               $controller += $part.toLowerCase();
+                               var parts = controller.split(/([A-Z][a-z0-9]+)/);
+                               var controller = '';
+                               for (var i = 0, length = parts.length; i < length; i++) {
+                                       var part = parts[i].trim();
+                                       if (part.length) {
+                                               if (controller.length) controller += '-';
+                                               controller += part.toLowerCase();
                                        }
                                }
                                
-                               return 'index.php?' + $controller + '/&';
+                               return 'index.php?' + controller + '/&';
                        });
                },
                
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Environment.js b/wcfsetup/install/files/js/WoltLab/WCF/Environment.js
new file mode 100644 (file)
index 0000000..528077e
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * Provides basic details on the JavaScript environment.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLab/WCF/Environment
+ */
+define([], function() {
+       "use strict";
+       
+       var _browser = 'other';
+       var _editor = 'none';
+       var _platform = 'desktop';
+       var _touch = false;
+       
+       /**
+        * @constructor
+        */
+       function Environment() {};
+       Environment.prototype = {
+               /**
+                * Determines environment variables.
+                */
+               setup: function() {
+                       if (typeof window.chrome === 'object') {
+                               // this detects Opera as well, we could check for window.opr if we need to
+                               _browser = 'chrome';
+                       }
+                       else {
+                               var styles = window.getComputedStyle(document.documentElement);
+                               for (var i = 0, length = styles.length; i < length; i++) {
+                                       var property = styles[i];
+                                       
+                                       if (property.indexOf('-ms-') === 0) {
+                                               // it is tempting to use 'msie', but it wouldn't really represent 'Edge'
+                                               _browser = 'microsoft';
+                                       }
+                                       else if (property.indexOf('-moz-') === 0) {
+                                               _browser = 'firefox';
+                                       }
+                                       else if (property.indexOf('-webkit-') === 0) {
+                                               _browser = 'safari';
+                                       }
+                               }
+                       }
+                       
+                       var ua = window.navigator.userAgent.toLowerCase();
+                       if (ua.indexOf('crios') !== -1) {
+                               _browser = 'chrome';
+                               _platform = 'ios';
+                       }
+                       else if (/(?:iphone|ipad|ipod)/.test(ua)) {
+                               _browser = 'safari';
+                               _platform = 'ios';
+                       }
+                       else if (ua.indexOf('android') !== -1) {
+                               _platform = 'android';
+                       }
+                       else if (ua.indexOf('iemobile') !== -1) {
+                               _browser = 'microsoft';
+                               _platform = 'windows';
+                       }
+                       
+                       if (_platform === 'desktop' && (ua.indexOf('mobile') !== -1 || ua.indexOf('tablet') !== -1)) {
+                               _platform = 'mobile';
+                       }
+                       
+                       _editor = 'redactor';
+                       _touch = (!!('ontouchstart' in window) || (!!('msMaxTouchPoints' in window.navigator) && window.navigator.msMaxTouchPoints > 0) || window.DocumentTouch && document instanceof DocumentTouch);
+               },
+               
+               /**
+                * Returns the lower-case browser identifier.
+                * 
+                * Possible values:
+                *  - chrome: Chrome and Opera
+                *  - firefox
+                *  - microsoft: Internet Explorer and Microsoft Edge
+                *  - safari
+                * 
+                * @return      {string}        browser identifier
+                */
+               browser: function() {
+                       return _browser;
+               },
+               
+               /**
+                * Returns the available editor's name or an empty string.
+                * 
+                * @return      {string}        editor name
+                */
+               editor: function() {
+                       return _editor;
+               },
+               
+               /**
+                * Returns the browser platform.
+                * 
+                * Possible values:
+                *  - desktop
+                *  - android
+                *  - ios: iPhone, iPad and iPod
+                *  - windows: Windows on phones/tablets
+                * 
+                * @return      {string}        browser platform
+                */
+               platform: function() {
+                       return _platform;
+               },
+               
+               /**
+                * Returns true if browser is potentially used with a touchscreen.
+                * 
+                * Warning: Detecting touch is unreliable and should be avoided at all cost.
+                * 
+                * @deprecated  2.2 - exists for backward-compatibility only, will be removed in the future
+                * 
+                * @return      {boolean}       true if a touchscreen is present
+                */
+               touch: function() {
+                       return _touch;
+               }
+       };
+       
+       return new Environment();
+});
index 97ee658bea3f60dd84bb8faf47a7d75e2838f823..74ec468d3bde2649d2569905c6aafc5c855270eb 100644 (file)
@@ -6,7 +6,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/UI/Dialog
  */
-define(['jquery', 'enquire', 'Core', 'Dictionary', 'Language', 'DOM/Util'], function($, enquire, Core, Dictionary, Language, DOMUtil) {
+define(['enquire', 'Core', 'Dictionary', 'Environment', 'Language', 'DOM/Util'], function(enquire, Core, Dictionary, Environment, Language, DOMUtil) {
        "use strict";
        
        var _activeDialog = null;
@@ -298,7 +298,7 @@ define(['jquery', 'enquire', 'Core', 'Dictionary', 'Language', 'DOM/Util'], func
                        contentContainer.style.setProperty('max-height', ~~maximumHeight + 'px');
                        
                        // fix for a calculation bug in Chrome causing the scrollbar to overlap the border
-                       if ($.browser.chrome) {
+                       if (Environment.browser() === 'chrome') {
                                if (data.content.scrollHeight > maximumHeight) {
                                        data.content.style.setProperty('margin-right', '-1px');
                                }
index bce846d5386f2696e80c68ffac87c9100bcc6506..f58ac94cb63d0e95d52377b9a4e33ffaad6a37a6 100644 (file)
@@ -6,7 +6,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/UI/Mobile
  */
-define(['jquery', 'enquire', 'Language', 'DOM/Traverse'], function($, enquire, Language, DOMTraverse) {
+define(['enquire', 'Environment', 'Language', 'DOM/Traverse'], function(enquire, Environment, Language, DOMTraverse) {
        "use strict";
        
        var _buttonGroupNavigations = null;
@@ -27,10 +27,14 @@ define(['jquery', 'enquire', 'Language', 'DOM/Traverse'], function($, enquire, L
                        _main = document.getElementById('main');
                        _sidebar = _main.querySelector('#main > div > div > .sidebar');
                        
-                       if ($.browser.touch) {
+                       if (Environment.touch()) {
                                document.documentElement.classList.add('touch');
                        }
                        
+                       if (Environment.platform() !== 'desktop') {
+                               document.documentElement.classList.add('mobile');
+                       }
+                       
                        enquire.register('screen and (max-width: 800px)', {
                                match: this.enable.bind(this),
                                unmatch: this.disable.bind(this),
@@ -38,7 +42,7 @@ define(['jquery', 'enquire', 'Language', 'DOM/Traverse'], function($, enquire, L
                                deferSetup: true
                        });
                        
-                       if ($.browser.msie && _sidebar.clientWidth > 305) {
+                       if (Environment.browser() === 'microsoft' && _sidebar.clientWidth > 305) {
                                this._fixSidebarIE();
                        }
                },
@@ -49,7 +53,7 @@ define(['jquery', 'enquire', 'Language', 'DOM/Traverse'], function($, enquire, L
                enable: function() {
                        _enabled = true;
                        
-                       if ($.browser.msie) this._fixSidebarIE();
+                       if (Environment.browser() === 'microsoft') this._fixSidebarIE();
                },
                
                /**
@@ -58,7 +62,7 @@ define(['jquery', 'enquire', 'Language', 'DOM/Traverse'], function($, enquire, L
                disable: function() {
                        _enabled = false;
                        
-                       if ($.browser.msie) this._fixSidebarIE();
+                       if (Environment.browser() === 'microsoft') this._fixSidebarIE();
                },
                
                _fixSidebarIE: function() {
index c3f94cba989b42cc60ce71cef9cbb541c3aff5c5..a9e10791d7a9eb76d0c4d8a761c8a0bf586e7070 100644 (file)
@@ -6,7 +6,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/UI/TabMenu/Simple
  */
-define(['jquery', 'Dictionary', 'DOM/Util', 'EventHandler'], function($, Dictionary, DOMUtil, EventHandler) {
+define(['Dictionary', 'DOM/Util', 'EventHandler'], function(Dictionary, DOMUtil, EventHandler) {
        "use strict";
        
        /**
index b402504436933985aa6b70a43bf075a3ffc144e7..7763a6f8f6a56f27658dce6ad395d71024648836 100644 (file)
@@ -6,7 +6,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/UI/Tooltip
  */
-define(['jquery', 'UI/Alignment'], function($, UIAlignment) {
+define(['Environment', 'UI/Alignment'], function(Environment, UIAlignment) {
        "use strict";
        
        var _elements = null;
@@ -23,7 +23,7 @@ define(['jquery', 'UI/Alignment'], function($, UIAlignment) {
                 * Initializes the tooltip element and binds event listener.
                 */
                setup: function() {
-                       if ($.browser.mobile) return;
+                       if (Environment.platform() !== 'desktop') return;
                        
                        _tooltip = document.createElement('div');
                        _tooltip.setAttribute('id', 'balloonTooltip');
index 5dcfd82a4b2adb640be864c82d26a11f68de7fb4..4d49395e16d337540cd1656d6cf57399a23a57ef 100644 (file)
@@ -11,6 +11,7 @@ requirejs.config({
                        'Dictionary': 'WoltLab/WCF/Dictionary',
                        'DOM/Traverse': 'WoltLab/WCF/DOM/Traverse',
                        'DOM/Util': 'WoltLab/WCF/DOM/Util',
+                       'Environment': 'WoltLab/WCF/Environment',
                        'EventHandler': 'WoltLab/WCF/Event/Handler',
                        'Language': 'WoltLab/WCF/Language',
                        'UI/Alignment': 'WoltLab/WCF/UI/Alignment',