Procházet zdrojové kódy

Make the Web app aware of its context root

j8
Lyubomir Marinov před 8 roky
rodič
revize
8509efc8af

+ 35
- 6
conference.js Zobrazit soubor

@@ -203,10 +203,8 @@ function maybeRedirectToWelcomePage(options) {
203 203
         // save whether current user is guest or not, before navigating
204 204
         // to close page
205 205
         window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
206
-        if (options.feedbackSubmitted)
207
-            window.location.pathname = "close.html";
208
-        else
209
-            window.location.pathname = "close2.html";
206
+        assignWindowLocationPathname(
207
+                options.feedbackSubmitted ? "close.html" : "close2.html");
210 208
         return;
211 209
     }
212 210
 
@@ -219,11 +217,42 @@ function maybeRedirectToWelcomePage(options) {
219 217
     if (config.enableWelcomePage) {
220 218
         setTimeout(() => {
221 219
             APP.settings.setWelcomePageEnabled(true);
222
-            window.location.pathname = "/";
220
+            assignWindowLocationPathname('./');
223 221
         }, 3000);
224 222
     }
225 223
 }
226 224
 
225
+/**
226
+ * Assigns a specific pathname to window.location.pathname taking into account
227
+ * the context root of the Web app.
228
+ *
229
+ * @param {string} pathname - The pathname to assign to
230
+ * window.location.pathname. If the specified pathname is relative, the context
231
+ * root of the Web app will be prepended to the specified pathname before
232
+ * assigning it to window.location.pathname.
233
+ * @return {void}
234
+ */
235
+function assignWindowLocationPathname(pathname) {
236
+    const windowLocation = window.location;
237
+
238
+    if (!pathname.startsWith('/')) {
239
+        // XXX To support a deployment in a sub-directory, assume that the room
240
+        // (name) is the last non-directory component of the path (name).
241
+        let contextRoot = windowLocation.pathname;
242
+
243
+        contextRoot
244
+            = contextRoot.substring(0, contextRoot.lastIndexOf('/') + 1);
245
+
246
+        // A pathname equal to ./ specifies the current directory. It will be
247
+        // fine but pointless to include it because contextRoot is the current
248
+        // directory.
249
+        pathname.startsWith('./') && (pathname = pathname.substring(2));
250
+        pathname = contextRoot + pathname;
251
+    }
252
+
253
+    windowLocation.pathname = pathname;
254
+}
255
+
227 256
 /**
228 257
  * Create local tracks of specified types.
229 258
  * @param {Object} options
@@ -323,7 +352,7 @@ class ConferenceConnector {
323 352
         case ConferenceErrors.NOT_ALLOWED_ERROR:
324 353
             {
325 354
                 // let's show some auth not allowed page
326
-                window.location.pathname = "authError.html";
355
+                assignWindowLocationPathname('authError.html');
327 356
             }
328 357
             break;
329 358
 

+ 2
- 8
react/features/app/components/AbstractApp.js Zobrazit soubor

@@ -38,7 +38,7 @@ export class AbstractApp extends Component {
38 38
     }
39 39
 
40 40
     /**
41
-     * Initializes a new App instance.
41
+     * Initializes a new AbstractApp instance.
42 42
      *
43 43
      * @param {Object} props - The read-only React Component props with which
44 44
      * the new instance is to be initialized.
@@ -334,13 +334,7 @@ export class AbstractApp extends Component {
334 334
         // (2) A replace function would be provided to the Route in case it
335 335
         // chose to redirect to another path.
336 336
         this._onRouteEnter(route, nextState, pathname => {
337
-            // FIXME In order to minimize the modifications related to the
338
-            // removal of react-router, the Web implementation is provided
339
-            // bellow because the replace function is used on Web only at the
340
-            // time of this writing. Provide a platform-agnostic implementation.
341
-            // It should likely find the best Route matching the specified
342
-            // pathname and navigate to it.
343
-            window.location.pathname = pathname;
337
+            this._openURL(pathname);
344 338
 
345 339
             // Do not proceed with the route because it chose to redirect to
346 340
             // another path.

+ 56
- 0
react/features/app/components/App.web.js Zobrazit soubor

@@ -14,6 +14,27 @@ export class App extends AbstractApp {
14 14
      */
15 15
     static propTypes = AbstractApp.propTypes
16 16
 
17
+    /**
18
+     * Initializes a new App instance.
19
+     *
20
+     * @param {Object} props - The read-only React Component props with which
21
+     * the new instance is to be initialized.
22
+     */
23
+    constructor(props) {
24
+        super(props);
25
+
26
+        this.state = {
27
+            ...this.state,
28
+
29
+            /**
30
+             * The context root of window.location i.e. this Web App.
31
+             *
32
+             * @type {string}
33
+             */
34
+            windowLocationContextRoot: this._getWindowLocationContextRoot()
35
+        };
36
+    }
37
+
17 38
     /**
18 39
      * Inits the app before component will mount.
19 40
      *
@@ -35,6 +56,22 @@ export class App extends AbstractApp {
35 56
         return window.location;
36 57
     }
37 58
 
59
+    /**
60
+     * Gets the context root of this Web App from window.location.
61
+     *
62
+     * @private
63
+     * @returns {string} The context root of window.location i.e. this Web App.
64
+     */
65
+    _getWindowLocationContextRoot() {
66
+        const pathname = this._getWindowLocation().pathname;
67
+        const contextRootEndIndex = pathname.lastIndexOf('/');
68
+
69
+        return (
70
+            contextRootEndIndex === -1
71
+                ? '/'
72
+                : pathname.substring(0, contextRootEndIndex + 1));
73
+    }
74
+
38 75
     /**
39 76
      * Navigates to a specific Route (via platform-specific means).
40 77
      *
@@ -53,6 +90,7 @@ export class App extends AbstractApp {
53 90
             = path.replace(
54 91
                 /:room/g,
55 92
                 store.getState()['features/base/conference'].room);
93
+        path = this._routePath2WindowLocationPathname(path);
56 94
 
57 95
         // Navigate to the specified Route.
58 96
         const windowLocation = this._getWindowLocation();
@@ -69,4 +107,22 @@ export class App extends AbstractApp {
69 107
             windowLocation.pathname = path;
70 108
         }
71 109
     }
110
+
111
+    /**
112
+     * Converts a specific Route path to a window.location.pathname.
113
+     *
114
+     * @param {string} path - A Route path to be converted to/represeted as a
115
+     * window.location.pathname.
116
+     * @private
117
+     * @returns {string} A window.location.pathname-compatible representation of
118
+     * the specified Route path.
119
+     */
120
+    _routePath2WindowLocationPathname(path) {
121
+        let pathname = this.state.windowLocationContextRoot;
122
+
123
+        pathname.endsWith('/') || (pathname += '/');
124
+        pathname += path.startsWith('/') ? path.substring(1) : path;
125
+
126
+        return pathname;
127
+    }
72 128
 }

+ 7
- 4
react/features/welcome/components/WelcomePage.web.js Zobrazit soubor

@@ -76,15 +76,18 @@ class WelcomePage extends AbstractWelcomePage {
76 76
     }
77 77
 
78 78
     /**
79
-     * Returns the domain name.
79
+     * Returns the URL of this WelcomePage for display purposes. For
80
+     * historic/legacy reasons, the return value is referred to as domain.
80 81
      *
81 82
      * @private
82
-     * @returns {string} Domain name.
83
+     * @returns {string} The URL of this WelcomePage for display purposes.
83 84
      */
84 85
     _getDomain() {
85
-        const windowLocation = window.location;
86
+        // As the returned URL is for display purposes, do not return the
87
+        // userinfo, query and fragment URI parts.
88
+        const wl = window.location;
86 89
 
87
-        return `${windowLocation.protocol}//${windowLocation.host}/`;
90
+        return `${wl.protocol}//${wl.host}${wl.pathname}`;
88 91
     }
89 92
 
90 93
     /**

+ 11
- 15
utils.js Zobrazit soubor

@@ -10,26 +10,22 @@
10 10
  * Builds and returns the room name.
11 11
  */
12 12
 function getRoomName () { // eslint-disable-line no-unused-vars
13
+    var getroomnode = config.getroomnode;
13 14
     var path = window.location.pathname;
14 15
     var roomName;
15 16
 
16
-    // determinde the room node from the url
17
-    // TODO: just the roomnode or the whole bare jid?
18
-    if (config.getroomnode && typeof config.getroomnode === 'function') {
17
+    // Determine the room node from the URL.
18
+    if (getroomnode && typeof getroomnode === 'function') {
19 19
         // custom function might be responsible for doing the pushstate
20
-        roomName = config.getroomnode(path);
20
+        roomName = getroomnode.call(config, path);
21 21
     } else {
22
-        /* fall back to default strategy
23
-         * this is making assumptions about how the URL->room mapping happens.
24
-         * It currently assumes deployment at root, with a rewrite like the
25
-         * following one (for nginx):
26
-         location ~ ^/([a-zA-Z0-9]+)$ {
27
-         rewrite ^/(.*)$ / break;
28
-         }
29
-        */
30
-        if (path.length > 1) {
31
-            roomName = path.substr(1).toLowerCase();
32
-        }
22
+        // Fall back to the default strategy of making assumptions about how the
23
+        // URL maps to the room (name). It currently assumes a deployment in
24
+        // which the last non-directory component of the path (name) is the
25
+        // room.
26
+        roomName
27
+            = path.substring(path.lastIndexOf('/') + 1).toLowerCase()
28
+                || undefined;
33 29
     }
34 30
 
35 31
     return roomName;

Načítá se…
Zrušit
Uložit