244 lines
8.9 KiB
JavaScript
244 lines
8.9 KiB
JavaScript
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2016-2021 (original work) Open Assessment Technologies SA ;
|
|
*/
|
|
define([
|
|
'jquery',
|
|
'lodash',
|
|
'i18n',
|
|
'util/url',
|
|
'core/logger',
|
|
'core/request',
|
|
'taoClientDiagnostic/tools/getConfig',
|
|
'taoClientDiagnostic/tools/getLabels',
|
|
'taoClientDiagnostic/tools/getPlatformInfo',
|
|
'taoClientDiagnostic/tools/getStatus'
|
|
], function($, _, __, urlHelper, loggerFactory, request, getConfig, getLabels, getPlatformInfo, getStatus) {
|
|
'use strict';
|
|
|
|
/**
|
|
* @type {logger}
|
|
* @private
|
|
*/
|
|
const logger = loggerFactory('taoClientDiagnostic/browser');
|
|
|
|
/**
|
|
* Some default values
|
|
* @type {object}
|
|
* @private
|
|
*/
|
|
const _defaults = {
|
|
id: 'browser',
|
|
browserVersionAction: 'whichBrowser',
|
|
browserVersionController: 'CompatibilityChecker',
|
|
browserVersionExtension: 'taoClientDiagnostic',
|
|
action: 'check',
|
|
controller: 'DiagnosticChecker',
|
|
browserslistUrl: 'https://oat-sa.github.io/browserslist-app-tao/api.json'
|
|
};
|
|
|
|
/**
|
|
* Placeholder variables for custom messages
|
|
* @type {object}
|
|
* @private
|
|
*/
|
|
const _placeHolders = {
|
|
CURRENT_BROWSER: '%CURRENT_BROWSER%',
|
|
CURRENT_OS: '%CURRENT_OS%'
|
|
};
|
|
|
|
/**
|
|
* List of translated texts per level.
|
|
* The level is provided through the config as a numeric value, starting from 1.
|
|
* @type {object}
|
|
* @private
|
|
*/
|
|
const _messages = [
|
|
// level 1
|
|
{
|
|
title: __('Operating system and web browser'),
|
|
status: __('Checking the browser...'),
|
|
browser: __('Web browser'),
|
|
os: __('Operating system')
|
|
}
|
|
];
|
|
|
|
/**
|
|
* Fallback name to recover from connectivity error
|
|
* @param {string}
|
|
* @private
|
|
*/
|
|
const unknown = __('Unknown');
|
|
|
|
/**
|
|
* Performs a browser support test
|
|
*
|
|
* @param {object} config - Some optional configs
|
|
* @param {string} [config.id] - The identifier of the test
|
|
* @param {string} [config.action] - The name of the action to call to get the browser checker
|
|
* @param {string} [config.controller] - The name of the controller to call to get the browser checker
|
|
* @param {string} [config.extension] - The name of the extension containing the controller to call to get the browser checker
|
|
* @param {string} [config.level] - The intensity level of the test. It will aim which messages list to use.
|
|
* @returns {object}
|
|
*/
|
|
return function browserTester(config) {
|
|
const initConfig = getConfig(config, _defaults);
|
|
const labels = getLabels(_messages, initConfig.level);
|
|
|
|
/**
|
|
* Fetches the list of fully supported browsers
|
|
* @returns {Promise<Array>}
|
|
* @private
|
|
*/
|
|
const fetchBrowserList = () => request({ url: initConfig.browserslistUrl, noToken: true }).catch(() => []);
|
|
|
|
/**
|
|
* Checks the current browser against the list of fully supported browsers
|
|
* @param platformInfo
|
|
* @returns {Promise<boolean>}
|
|
* @private
|
|
*/
|
|
function checkBrowserSupport(platformInfo) {
|
|
const currentDevice = platformInfo.isMobile ? 'mobile' : 'desktop';
|
|
const currentOS = platformInfo.os.toLowerCase();
|
|
const currentBrowser = platformInfo.browser.toLowerCase();
|
|
const currentVersion = platformInfo.browserVersion;
|
|
return fetchBrowserList().then(list =>
|
|
list.some(entry => {
|
|
const { browser, device, os, versions } = entry;
|
|
|
|
if (currentDevice !== device) {
|
|
return false;
|
|
}
|
|
|
|
if (os && os.toLowerCase() !== currentOS) {
|
|
return false;
|
|
}
|
|
|
|
if (browser.toLowerCase() !== currentBrowser) {
|
|
return false;
|
|
}
|
|
|
|
// Using lodash because of IE support.
|
|
// Some useful traversal algorithms are needed and they don't have polyfill in our bundles.
|
|
// The versions come with an inconsistent format and they need to be processed upfront.
|
|
return _(versions)
|
|
.map(version => version.split('-'))
|
|
.flatten()
|
|
.value()
|
|
.some(version => currentVersion.localeCompare(version, void 0, { numeric: true }) >= 0);
|
|
}, {})
|
|
);
|
|
}
|
|
|
|
return {
|
|
/**
|
|
* Performs a browser support test, then call a function to provide the result
|
|
* @param {Function} done
|
|
*/
|
|
start(done) {
|
|
getPlatformInfo(window, initConfig)
|
|
.catch(err => {
|
|
logger.error(err);
|
|
return {
|
|
browser: unknown,
|
|
browserVersion: '',
|
|
os: unknown,
|
|
osVersion: '',
|
|
isMobile: false
|
|
};
|
|
})
|
|
.then(platformInfo =>
|
|
checkBrowserSupport(platformInfo).then(browserSupported =>
|
|
Object.assign(platformInfo, { browserSupported })
|
|
)
|
|
)
|
|
.then(platformInfo => {
|
|
request({
|
|
url: urlHelper.route(initConfig.action, initConfig.controller, initConfig.extension),
|
|
data: platformInfo,
|
|
method: 'POST',
|
|
noToken: true
|
|
})
|
|
.catch(() => {
|
|
return {
|
|
success: false,
|
|
type: 'error',
|
|
message: __('Unable to validate the data as the server did not respond in time.')
|
|
};
|
|
})
|
|
.then(data => {
|
|
const percentage = 'success' === data.type ? 100 : 'warning' === data.type ? 33 : 0;
|
|
const status = this.getFeedback(percentage, data);
|
|
const summary = this.getSummary(platformInfo);
|
|
|
|
status.customMsgRenderer = customMsg => {
|
|
return (customMsg || '')
|
|
.replace(_placeHolders.CURRENT_BROWSER, summary.browser.value)
|
|
.replace(_placeHolders.CURRENT_OS, summary.os.value);
|
|
};
|
|
|
|
done(status, summary, platformInfo);
|
|
});
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Gets the labels loaded for the tester
|
|
* @returns {object}
|
|
*/
|
|
get labels() {
|
|
return labels;
|
|
},
|
|
|
|
/**
|
|
* Builds the results summary
|
|
* @param {object} results
|
|
* @returns {object}
|
|
*/
|
|
getSummary(results) {
|
|
const currentBrowser = `${results.browser} ${results.browserVersion}`;
|
|
const currentOs = `${results.os} ${results.osVersion}`;
|
|
return {
|
|
browser: {
|
|
message: labels.browser,
|
|
value: currentBrowser
|
|
},
|
|
os: {
|
|
message: labels.os,
|
|
value: currentOs
|
|
}
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Gets the feedback status for the provided result value
|
|
* @param {number} result
|
|
* @param {object} data
|
|
* @returns {object}
|
|
*/
|
|
getFeedback(result, data) {
|
|
const status = getStatus(result, data);
|
|
|
|
status.id = initConfig.id;
|
|
status.title = labels.title;
|
|
|
|
return status;
|
|
}
|
|
};
|
|
};
|
|
});
|