310 lines
9.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreLangProvider } from '../lang';
/*
* "Utils" service with helper functions for URLs.
*/
@Injectable()
export class CoreUrlUtilsProvider {
constructor(private langProvider: CoreLangProvider) {}
/**
* Add or remove 'www' from a URL. The url needs to have http or https protocol.
*
* @param {string} url URL to modify.
* @return {string} Modified URL.
*/
addOrRemoveWWW(url: string) : string {
if (url) {
if (url.match(/http(s)?:\/\/www\./)) {
// Already has www. Remove it.
url = url.replace('www.', '');
} else {
url = url.replace('https://', 'https://www.');
url = url.replace('http://', 'http://www.');
}
}
return url;
}
/**
* Extracts the parameters from a URL and stores them in an object.
*
* @param {string} url URL to treat.
* @return {any} Object with the params.
*/
extractUrlParams(url: string) : any {
let regex = /[?&]+([^=&]+)=?([^&]*)?/gi,
params = {};
url.replace(regex, (match: string, key: string, value: string) : string => {
params[key] = typeof value != 'undefined' ? value : '';
return match;
});
return params;
}
/**
* Generic function for adding the wstoken to Moodle urls and for pointing to the correct script.
* For download remote files from Moodle we need to use the special /webservice/pluginfile passing
* the ws token as a get parameter.
*
* @param {string} url The url to be fixed.
* @param {string} token Token to use.
* @return {string} Fixed URL.
*/
fixPluginfileURL(url: string, token: string) : string {
if (!url || !token) {
return '';
}
// First check if we need to fix this url or is already fixed.
if (url.indexOf('token=') != -1) {
return url;
}
// Check if is a valid URL (contains the pluginfile endpoint).
if (!this.isPluginFileUrl(url)) {
return url;
}
// In which way the server is serving the files? Are we using slash parameters?
if (url.indexOf('?file=') != -1 || url.indexOf('?forcedownload=') != -1 || url.indexOf('?rev=') != -1) {
url += '&';
} else {
url += '?';
}
// Always send offline=1 (for external repositories). It shouldn't cause problems for local files or old Moodles.
url += 'token=' + token + '&offline=1';
// Some webservices returns directly the correct download url, others not.
if (url.indexOf('/webservice/pluginfile') == -1) {
url = url.replace('/pluginfile', '/webservice/pluginfile');
}
return url;
}
/**
* Formats a URL, trim, lowercase, etc...
*
* @param {string} url The url to be formatted.
* @return {string} Fromatted url.
*/
formatURL(url: string) : string {
url = url.trim();
// Check if the URL starts by http or https.
if (! /^http(s)?\:\/\/.*/i.test(url)) {
// Test first allways https.
url = 'https://' + url;
}
// http allways in lowercase.
url = url.replace(/^http/i, 'http');
url = url.replace(/^https/i, 'https');
// Replace last slash.
url = url.replace(/\/$/, "");
return url;
}
/**
* Returns the URL to the documentation of the app, based on Moodle version and current language.
*
* @param {string} [release] Moodle release.
* @param {string} [page=Mobile_app] Docs page to go to.
* @return {Promise<string>} Promise resolved with the Moodle docs URL.
*/
getDocsUrl(release?: string, page = 'Mobile_app') : Promise<string> {
let docsUrl = 'https://docs.moodle.org/en/' + page;
if (typeof release != 'undefined') {
let version = release.substr(0, 3).replace('.', '');
// Check is a valid number.
if (parseInt(version) >= 24) {
// Append release number.
docsUrl = docsUrl.replace('https://docs.moodle.org/', 'https://docs.moodle.org/' + version + '/');
}
}
return this.langProvider.getCurrentLanguage().then((lang) => {
return docsUrl.replace('/en/', '/' + lang + '/');
}).catch(() => {
return docsUrl;
});
}
/**
* Given a URL, returns what's after the last '/' without params.
* Example:
* http://mysite.com/a/course.html?id=1 -> course.html
*
* @param {string} url URL to treat.
* @return {string} Last file without params.
*/
getLastFileWithoutParams(url: string) : string {
let filename = url.substr(url.lastIndexOf('/') + 1);
if (filename.indexOf('?') != -1) {
filename = filename.substr(0, filename.indexOf('?'));
}
return filename;
}
/**
* Get the protocol from a URL.
* E.g. http://www.google.com returns 'http'.
*
* @param {string} url URL to treat.
* @return {string} Protocol, undefined if no protocol found.
*/
getUrlProtocol(url: string) : string {
if (!url) {
return;
}
let matches = url.match(/^([^\/:\.\?]*):\/\//);
if (matches && matches[1]) {
return matches[1];
}
}
/**
* Get the scheme from a URL. Please notice that, if a URL has protocol, it will return the protocol.
* E.g. javascript:doSomething() returns 'javascript'.
*
* @param {string} url URL to treat.
* @return {string} Scheme, undefined if no scheme found.
*/
getUrlScheme(url: string) : string {
if (!url) {
return;
}
let matches = url.match(/^([a-z][a-z0-9+\-.]*):/);
if (matches && matches[1]) {
return matches[1];
}
}
/*
* Gets a username from a URL like: user@mysite.com.
*
* @param {string} url URL to treat.
* @return {string} Username. Undefined if no username found.
*/
getUsernameFromUrl(url: string) : string {
if (url.indexOf('@') > -1) {
// Get URL without protocol.
let withoutProtocol = url.replace(/.*?:\/\//, ''),
matches = withoutProtocol.match(/[^@]*/);
// Make sure that @ is at the start of the URL, not in a param at the end.
if (matches && matches.length && !matches[0].match(/[\/|?]/)) {
return matches[0];
}
}
}
/**
* Returns if a URL has any protocol (not a relative URL).
*
* @param {string} url The url to test against the pattern.
* @return {boolean} Whether the url is absolute.
*/
isAbsoluteURL(url: string) : boolean {
return /^[^:]{2,}:\/\//i.test(url) || /^(tel:|mailto:|geo:)/.test(url);
}
/**
* Returns if a URL is downloadable: plugin file OR theme/image.php OR gravatar.
*
* @param {string} url The URL to test.
* @return {boolean} Whether the URL is downloadable.
*/
isDownloadableUrl(url: string) : boolean {
return this.isPluginFileUrl(url) || this.isThemeImageUrl(url) || this.isGravatarUrl(url);
}
/**
* Returns if a URL is a gravatar URL.
*
* @param {string} url The URL to test.
* @return {boolean} Whether the URL is a gravatar URL.
*/
isGravatarUrl(url: string) : boolean {
return url && url.indexOf('gravatar.com/avatar') !== -1;
}
/**
* Check if a URL uses http or https protocol.
*
* @param {string} url The url to test.
* @return {boolean} Whether the url uses http or https protocol.
*/
isHttpURL(url: string) : boolean {
return /^https?\:\/\/.+/i.test(url);
}
/**
* Returns if a URL is a pluginfile URL.
*
* @param {string} url The URL to test.
* @return {boolean} Whether the URL is a pluginfile URL.
*/
isPluginFileUrl(url: string) : boolean {
return url && url.indexOf('/pluginfile.php') !== -1;
}
/**
* Returns if a URL is a theme image URL.
*
* @param {string} url The URL to test.
* @return {boolean} Whether the URL is a theme image URL.
*/
isThemeImageUrl(url: string) : boolean {
return url && url.indexOf('/theme/image.php') !== -1;
}
/**
* Remove protocol and www from a URL.
*
* @param {string} url URL to treat.
* @return {string} Treated URL.
*/
removeProtocolAndWWW(url: string) : string {
// Remove protocol.
url = url.replace(/.*?:\/\//g, '');
// Remove www.
url = url.replace(/^www./, '');
return url;
}
/**
* Remove the parameters from a URL, returning the URL without them.
*
* @param {string} url URL to treat.
* @return {string} URL without params.
*/
removeUrlParams(url: string) : string {
let matches = url.match(/^[^\?]+/);
return matches && matches[0];
}
}