Make the Web app aware of its context root
This commit is contained in:
parent
23a0053dad
commit
8509efc8af
|
@ -203,10 +203,8 @@ function maybeRedirectToWelcomePage(options) {
|
||||||
// save whether current user is guest or not, before navigating
|
// save whether current user is guest or not, before navigating
|
||||||
// to close page
|
// to close page
|
||||||
window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
|
window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
|
||||||
if (options.feedbackSubmitted)
|
assignWindowLocationPathname(
|
||||||
window.location.pathname = "close.html";
|
options.feedbackSubmitted ? "close.html" : "close2.html");
|
||||||
else
|
|
||||||
window.location.pathname = "close2.html";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,11 +217,42 @@ function maybeRedirectToWelcomePage(options) {
|
||||||
if (config.enableWelcomePage) {
|
if (config.enableWelcomePage) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
APP.settings.setWelcomePageEnabled(true);
|
APP.settings.setWelcomePageEnabled(true);
|
||||||
window.location.pathname = "/";
|
assignWindowLocationPathname('./');
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a specific pathname to window.location.pathname taking into account
|
||||||
|
* the context root of the Web app.
|
||||||
|
*
|
||||||
|
* @param {string} pathname - The pathname to assign to
|
||||||
|
* window.location.pathname. If the specified pathname is relative, the context
|
||||||
|
* root of the Web app will be prepended to the specified pathname before
|
||||||
|
* assigning it to window.location.pathname.
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
function assignWindowLocationPathname(pathname) {
|
||||||
|
const windowLocation = window.location;
|
||||||
|
|
||||||
|
if (!pathname.startsWith('/')) {
|
||||||
|
// XXX To support a deployment in a sub-directory, assume that the room
|
||||||
|
// (name) is the last non-directory component of the path (name).
|
||||||
|
let contextRoot = windowLocation.pathname;
|
||||||
|
|
||||||
|
contextRoot
|
||||||
|
= contextRoot.substring(0, contextRoot.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
|
// A pathname equal to ./ specifies the current directory. It will be
|
||||||
|
// fine but pointless to include it because contextRoot is the current
|
||||||
|
// directory.
|
||||||
|
pathname.startsWith('./') && (pathname = pathname.substring(2));
|
||||||
|
pathname = contextRoot + pathname;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowLocation.pathname = pathname;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create local tracks of specified types.
|
* Create local tracks of specified types.
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
|
@ -323,7 +352,7 @@ class ConferenceConnector {
|
||||||
case ConferenceErrors.NOT_ALLOWED_ERROR:
|
case ConferenceErrors.NOT_ALLOWED_ERROR:
|
||||||
{
|
{
|
||||||
// let's show some auth not allowed page
|
// let's show some auth not allowed page
|
||||||
window.location.pathname = "authError.html";
|
assignWindowLocationPathname('authError.html');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ export class AbstractApp extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new App instance.
|
* Initializes a new AbstractApp instance.
|
||||||
*
|
*
|
||||||
* @param {Object} props - The read-only React Component props with which
|
* @param {Object} props - The read-only React Component props with which
|
||||||
* the new instance is to be initialized.
|
* the new instance is to be initialized.
|
||||||
|
@ -334,13 +334,7 @@ export class AbstractApp extends Component {
|
||||||
// (2) A replace function would be provided to the Route in case it
|
// (2) A replace function would be provided to the Route in case it
|
||||||
// chose to redirect to another path.
|
// chose to redirect to another path.
|
||||||
this._onRouteEnter(route, nextState, pathname => {
|
this._onRouteEnter(route, nextState, pathname => {
|
||||||
// FIXME In order to minimize the modifications related to the
|
this._openURL(pathname);
|
||||||
// removal of react-router, the Web implementation is provided
|
|
||||||
// bellow because the replace function is used on Web only at the
|
|
||||||
// time of this writing. Provide a platform-agnostic implementation.
|
|
||||||
// It should likely find the best Route matching the specified
|
|
||||||
// pathname and navigate to it.
|
|
||||||
window.location.pathname = pathname;
|
|
||||||
|
|
||||||
// Do not proceed with the route because it chose to redirect to
|
// Do not proceed with the route because it chose to redirect to
|
||||||
// another path.
|
// another path.
|
||||||
|
|
|
@ -14,6 +14,27 @@ export class App extends AbstractApp {
|
||||||
*/
|
*/
|
||||||
static propTypes = AbstractApp.propTypes
|
static propTypes = AbstractApp.propTypes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new App instance.
|
||||||
|
*
|
||||||
|
* @param {Object} props - The read-only React Component props with which
|
||||||
|
* the new instance is to be initialized.
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
...this.state,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context root of window.location i.e. this Web App.
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
windowLocationContextRoot: this._getWindowLocationContextRoot()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inits the app before component will mount.
|
* Inits the app before component will mount.
|
||||||
*
|
*
|
||||||
|
@ -35,6 +56,22 @@ export class App extends AbstractApp {
|
||||||
return window.location;
|
return window.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the context root of this Web App from window.location.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {string} The context root of window.location i.e. this Web App.
|
||||||
|
*/
|
||||||
|
_getWindowLocationContextRoot() {
|
||||||
|
const pathname = this._getWindowLocation().pathname;
|
||||||
|
const contextRootEndIndex = pathname.lastIndexOf('/');
|
||||||
|
|
||||||
|
return (
|
||||||
|
contextRootEndIndex === -1
|
||||||
|
? '/'
|
||||||
|
: pathname.substring(0, contextRootEndIndex + 1));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates to a specific Route (via platform-specific means).
|
* Navigates to a specific Route (via platform-specific means).
|
||||||
*
|
*
|
||||||
|
@ -53,6 +90,7 @@ export class App extends AbstractApp {
|
||||||
= path.replace(
|
= path.replace(
|
||||||
/:room/g,
|
/:room/g,
|
||||||
store.getState()['features/base/conference'].room);
|
store.getState()['features/base/conference'].room);
|
||||||
|
path = this._routePath2WindowLocationPathname(path);
|
||||||
|
|
||||||
// Navigate to the specified Route.
|
// Navigate to the specified Route.
|
||||||
const windowLocation = this._getWindowLocation();
|
const windowLocation = this._getWindowLocation();
|
||||||
|
@ -69,4 +107,22 @@ export class App extends AbstractApp {
|
||||||
windowLocation.pathname = path;
|
windowLocation.pathname = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a specific Route path to a window.location.pathname.
|
||||||
|
*
|
||||||
|
* @param {string} path - A Route path to be converted to/represeted as a
|
||||||
|
* window.location.pathname.
|
||||||
|
* @private
|
||||||
|
* @returns {string} A window.location.pathname-compatible representation of
|
||||||
|
* the specified Route path.
|
||||||
|
*/
|
||||||
|
_routePath2WindowLocationPathname(path) {
|
||||||
|
let pathname = this.state.windowLocationContextRoot;
|
||||||
|
|
||||||
|
pathname.endsWith('/') || (pathname += '/');
|
||||||
|
pathname += path.startsWith('/') ? path.substring(1) : path;
|
||||||
|
|
||||||
|
return pathname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,15 +76,18 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the domain name.
|
* Returns the URL of this WelcomePage for display purposes. For
|
||||||
|
* historic/legacy reasons, the return value is referred to as domain.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns {string} Domain name.
|
* @returns {string} The URL of this WelcomePage for display purposes.
|
||||||
*/
|
*/
|
||||||
_getDomain() {
|
_getDomain() {
|
||||||
const windowLocation = window.location;
|
// As the returned URL is for display purposes, do not return the
|
||||||
|
// userinfo, query and fragment URI parts.
|
||||||
|
const wl = window.location;
|
||||||
|
|
||||||
return `${windowLocation.protocol}//${windowLocation.host}/`;
|
return `${wl.protocol}//${wl.host}${wl.pathname}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
26
utils.js
26
utils.js
|
@ -10,26 +10,22 @@
|
||||||
* Builds and returns the room name.
|
* Builds and returns the room name.
|
||||||
*/
|
*/
|
||||||
function getRoomName () { // eslint-disable-line no-unused-vars
|
function getRoomName () { // eslint-disable-line no-unused-vars
|
||||||
|
var getroomnode = config.getroomnode;
|
||||||
var path = window.location.pathname;
|
var path = window.location.pathname;
|
||||||
var roomName;
|
var roomName;
|
||||||
|
|
||||||
// determinde the room node from the url
|
// Determine the room node from the URL.
|
||||||
// TODO: just the roomnode or the whole bare jid?
|
if (getroomnode && typeof getroomnode === 'function') {
|
||||||
if (config.getroomnode && typeof config.getroomnode === 'function') {
|
|
||||||
// custom function might be responsible for doing the pushstate
|
// custom function might be responsible for doing the pushstate
|
||||||
roomName = config.getroomnode(path);
|
roomName = getroomnode.call(config, path);
|
||||||
} else {
|
} else {
|
||||||
/* fall back to default strategy
|
// Fall back to the default strategy of making assumptions about how the
|
||||||
* this is making assumptions about how the URL->room mapping happens.
|
// URL maps to the room (name). It currently assumes a deployment in
|
||||||
* It currently assumes deployment at root, with a rewrite like the
|
// which the last non-directory component of the path (name) is the
|
||||||
* following one (for nginx):
|
// room.
|
||||||
location ~ ^/([a-zA-Z0-9]+)$ {
|
roomName
|
||||||
rewrite ^/(.*)$ / break;
|
= path.substring(path.lastIndexOf('/') + 1).toLowerCase()
|
||||||
}
|
|| undefined;
|
||||||
*/
|
|
||||||
if (path.length > 1) {
|
|
||||||
roomName = path.substr(1).toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return roomName;
|
return roomName;
|
||||||
|
|
Loading…
Reference in New Issue