diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts index 3cf9e6489..28bfbb5b0 100644 --- a/src/addons/calendar/services/calendar.ts +++ b/src/addons/calendar/services/calendar.ts @@ -38,7 +38,7 @@ import { SafeUrl } from '@angular/platform-browser'; import { CoreNavigator } from '@services/navigator'; import { AddonCalendarFilter } from './calendar-helper'; import { AddonCalendarSyncEvents, AddonCalendarSyncProvider } from './calendar-sync'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePlatform } from '@services/platform'; import { CoreReminderData, @@ -1168,7 +1168,7 @@ export class AddonCalendarProvider { */ async getViewUrl(view: string, time?: number, courseId?: string, siteId?: string): Promise { const site = await CoreSites.getSite(siteId); - let url = CoreText.concatenatePaths(site.getURL(), 'calendar/view.php?view=' + view); + let url = CorePath.concatenatePaths(site.getURL(), 'calendar/view.php?view=' + view); if (time) { url += '&time=' + time; diff --git a/src/addons/messageoutput/airnotifier/services/airnotifier.ts b/src/addons/messageoutput/airnotifier/services/airnotifier.ts index 86c498b18..3138488cf 100644 --- a/src/addons/messageoutput/airnotifier/services/airnotifier.ts +++ b/src/addons/messageoutput/airnotifier/services/airnotifier.ts @@ -24,7 +24,7 @@ import { makeSingleton, Translate } from '@singletons'; import { CoreEvents, CoreEventSiteData } from '@singletons/events'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; const ROOT_CACHE_KEY = 'mmaMessageOutputAirnotifier:'; @@ -214,7 +214,7 @@ export class AddonMessageOutputAirnotifierProvider { handler: (data, resolve) => { resolve(data[0]); - const url = CoreText.concatenatePaths( + const url = CorePath.concatenatePaths( site.getURL(), site.isVersionGreaterEqualThan('3.11') ? 'message/output/airnotifier/checkconfiguration.php' : diff --git a/src/addons/mod/assign/services/assign-offline.ts b/src/addons/mod/assign/services/assign-offline.ts index 954c68b0f..36946ebbd 100644 --- a/src/addons/mod/assign/services/assign-offline.ts +++ b/src/addons/mod/assign/services/assign-offline.ts @@ -20,7 +20,7 @@ import { CoreSites } from '@services/sites'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModAssignOutcomes, AddonModAssignSavePluginData } from './assign'; import { AddonModAssignSubmissionsDBRecord, @@ -237,7 +237,7 @@ export class AddonModAssignOfflineProvider { const siteFolderPath = CoreFile.getSiteFolder(site.getId()); const submissionFolderPath = 'offlineassign/' + assignId + '/' + userId; - return CoreText.concatenatePaths(siteFolderPath, submissionFolderPath); + return CorePath.concatenatePaths(siteFolderPath, submissionFolderPath); } /** @@ -277,7 +277,7 @@ export class AddonModAssignOfflineProvider { async getSubmissionPluginFolder(assignId: number, pluginName: string, userId?: number, siteId?: string): Promise { const folderPath = await this.getSubmissionFolder(assignId, userId, siteId); - return CoreText.concatenatePaths(folderPath, pluginName); + return CorePath.concatenatePaths(folderPath, pluginName); } /** diff --git a/src/addons/mod/data/services/data-offline.ts b/src/addons/mod/data/services/data-offline.ts index 2bb674171..c4defe031 100644 --- a/src/addons/mod/data/services/data-offline.ts +++ b/src/addons/mod/data/services/data-offline.ts @@ -19,7 +19,7 @@ import { CoreSites } from '@services/sites'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModDataAction, AddonModDataEntryWSField } from './data'; import { AddonModDataEntryDBRecord, DATA_ENTRY_TABLE } from './database/data'; @@ -207,7 +207,7 @@ export class AddonModDataOfflineProvider { const siteFolderPath = CoreFile.getSiteFolder(site.getId()); const folderPath = 'offlinedatabase/' + dataId; - return CoreText.concatenatePaths(siteFolderPath, folderPath); + return CorePath.concatenatePaths(siteFolderPath, folderPath); } /** @@ -222,7 +222,7 @@ export class AddonModDataOfflineProvider { async getEntryFieldFolder(dataId: number, entryId: number, fieldId: number, siteId?: string): Promise { const folderPath = await this.getDatabaseFolder(dataId, siteId); - return CoreText.concatenatePaths(folderPath, entryId + '_' + fieldId); + return CorePath.concatenatePaths(folderPath, entryId + '_' + fieldId); } /** diff --git a/src/addons/mod/forum/services/forum-offline.ts b/src/addons/mod/forum/services/forum-offline.ts index cbc4767a4..31c9fb8e9 100644 --- a/src/addons/mod/forum/services/forum-offline.ts +++ b/src/addons/mod/forum/services/forum-offline.ts @@ -25,7 +25,7 @@ import { DISCUSSIONS_TABLE, REPLIES_TABLE, } from './database/offline'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Service to handle offline forum. @@ -342,7 +342,7 @@ export class AddonModForumOfflineProvider { const site = await CoreSites.getSite(siteId); const siteFolderPath = CoreFile.getSiteFolder(site.getId()); - return CoreText.concatenatePaths(siteFolderPath, 'offlineforum/' + forumId); + return CorePath.concatenatePaths(siteFolderPath, 'offlineforum/' + forumId); } /** @@ -356,7 +356,7 @@ export class AddonModForumOfflineProvider { async getNewDiscussionFolder(forumId: number, timeCreated: number, siteId?: string): Promise { const folderPath = await this.getForumFolder(forumId, siteId); - return CoreText.concatenatePaths(folderPath, 'newdisc_' + timeCreated); + return CorePath.concatenatePaths(folderPath, 'newdisc_' + timeCreated); } /** @@ -373,7 +373,7 @@ export class AddonModForumOfflineProvider { const site = await CoreSites.getSite(siteId); userId = userId || site.getUserId(); - return CoreText.concatenatePaths(folderPath, 'reply_' + postId + '_' + userId); + return CorePath.concatenatePaths(folderPath, 'reply_' + postId + '_' + userId); } /** diff --git a/src/addons/mod/glossary/services/glossary-offline.ts b/src/addons/mod/glossary/services/glossary-offline.ts index 47319388b..3b69008f3 100644 --- a/src/addons/mod/glossary/services/glossary-offline.ts +++ b/src/addons/mod/glossary/services/glossary-offline.ts @@ -19,7 +19,7 @@ import { CoreSites } from '@services/sites'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModGlossaryOfflineEntryDBRecord, OFFLINE_ENTRIES_TABLE_NAME } from './database/glossary'; import { AddonModGlossaryDiscardedEntry, AddonModGlossaryEntryOption } from './glossary'; @@ -214,7 +214,7 @@ export class AddonModGlossaryOfflineProvider { const siteFolderPath = CoreFile.getSiteFolder(site.getId()); const folderPath = 'offlineglossary/' + glossaryId; - return CoreText.concatenatePaths(siteFolderPath, folderPath); + return CorePath.concatenatePaths(siteFolderPath, folderPath); } /** @@ -229,7 +229,7 @@ export class AddonModGlossaryOfflineProvider { async getEntryFolder(glossaryId: number, concept: string, timeCreated: number, siteId?: string): Promise { const folderPath = await this.getGlossaryFolder(glossaryId, siteId); - return CoreText.concatenatePaths(folderPath, 'newentry_' + concept + '_' + timeCreated); + return CorePath.concatenatePaths(folderPath, 'newentry_' + concept + '_' + timeCreated); } /** diff --git a/src/addons/mod/imscp/services/imscp.ts b/src/addons/mod/imscp/services/imscp.ts index 7175ae599..40297c0cc 100644 --- a/src/addons/mod/imscp/services/imscp.ts +++ b/src/addons/mod/imscp/services/imscp.ts @@ -25,7 +25,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; const ROOT_CACHE_KEY = 'mmaModImscp:'; @@ -155,7 +155,7 @@ export class AddonModImscpProvider { return false; } - const filePath = CoreText.concatenatePaths(item.filepath, item.filename); + const filePath = CorePath.concatenatePaths(item.filepath, item.filename); const filePathAlt = filePath.charAt(0) === '/' ? filePath.substring(1) : '/' + filePath; // Check if it's main file. @@ -178,7 +178,7 @@ export class AddonModImscpProvider { try { const dirPath = await CoreFilepool.getPackageDirUrlByUrl(siteId, module.url || ''); - return CoreText.concatenatePaths(dirPath, itemHref); + return CorePath.concatenatePaths(dirPath, itemHref); } catch (error) { // Error getting directory, there was an error downloading or we're in browser. Return online URL if connected. if (CoreNetwork.isOnline()) { diff --git a/src/addons/mod/resource/services/resource-helper.ts b/src/addons/mod/resource/services/resource-helper.ts index d0f5c7557..aba1b9533 100644 --- a/src/addons/mod/resource/services/resource-helper.ts +++ b/src/addons/mod/resource/services/resource-helper.ts @@ -26,7 +26,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreUtilsOpenFileOptions } from '@services/utils/utils'; import { makeSingleton, Translate } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModResource, AddonModResourceProvider } from './resource'; /** @@ -77,7 +77,7 @@ export class AddonModResourceHelperProvider { const dirPath = await CoreFilepool.getPackageDirUrlByUrl(CoreSites.getCurrentSiteId(), module.url!); // This URL is going to be injected in an iframe, we need trustAsResourceUrl to make it work in a browser. - return CoreText.concatenatePaths(dirPath, mainFilePath); + return CorePath.concatenatePaths(dirPath, mainFilePath); } catch (e) { // Error getting directory, there was an error downloading or we're in browser. Return online URL. if (CoreNetwork.isOnline() && mainFile.fileurl) { diff --git a/src/addons/mod/scorm/services/scorm.ts b/src/addons/mod/scorm/services/scorm.ts index 756721a61..cd22b9962 100644 --- a/src/addons/mod/scorm/services/scorm.ts +++ b/src/addons/mod/scorm/services/scorm.ts @@ -28,7 +28,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreWS, CoreWSExternalFile, CoreWSExternalWarning, CoreWSFile, CoreWSPreSets } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModScormOffline } from './scorm-offline'; import { AddonModScormAutoSyncEventData, AddonModScormSyncProvider } from './scorm-sync'; @@ -970,7 +970,7 @@ export class AddonModScormProvider { const dirPath = await CoreFilepool.getPackageDirUrlByUrl(siteId, scorm.moduleurl ?? ''); - return CoreText.concatenatePaths(dirPath, launchUrl); + return CorePath.concatenatePaths(dirPath, launchUrl); } /** diff --git a/src/addons/mod/wiki/components/index/index.ts b/src/addons/mod/wiki/components/index/index.ts index 852380f03..620576522 100644 --- a/src/addons/mod/wiki/components/index/index.ts +++ b/src/addons/mod/wiki/components/index/index.ts @@ -29,7 +29,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { Translate, NgZone } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { Subscription } from 'rxjs'; import { Md5 } from 'ts-md5'; import { AddonModWikiPageDBRecord } from '../../services/database/wiki'; @@ -686,7 +686,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp content = content.trim(); if (content.length > 0) { - const editUrl = CoreText.concatenatePaths(CoreSites.getRequiredCurrentSite().getURL(), '/mod/wiki/edit.php'); + const editUrl = CorePath.concatenatePaths(CoreSites.getRequiredCurrentSite().getURL(), '/mod/wiki/edit.php'); content = content.replace(/href="edit\.php/g, 'href="' + editUrl); } diff --git a/src/addons/mod/workshop/services/workshop-offline.ts b/src/addons/mod/workshop/services/workshop-offline.ts index 0884e9403..f566a2855 100644 --- a/src/addons/mod/workshop/services/workshop-offline.ts +++ b/src/addons/mod/workshop/services/workshop-offline.ts @@ -20,7 +20,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { makeSingleton } from '@singletons'; import { CoreFormFields } from '@singletons/form'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { AddonModWorkshopAssessmentDBRecord, AddonModWorkshopEvaluateAssessmentDBRecord, @@ -630,7 +630,7 @@ export class AddonModWorkshopOfflineProvider { const siteFolderPath = CoreFile.getSiteFolder(site.getId()); const workshopFolderPath = 'offlineworkshop/' + workshopId + '/'; - return CoreText.concatenatePaths(siteFolderPath, workshopFolderPath); + return CorePath.concatenatePaths(siteFolderPath, workshopFolderPath); } /** @@ -643,7 +643,7 @@ export class AddonModWorkshopOfflineProvider { async getSubmissionFolder(workshopId: number, siteId?: string): Promise { const folderPath = await this.getWorkshopFolder(workshopId, siteId); - return CoreText.concatenatePaths(folderPath, 'submission'); + return CorePath.concatenatePaths(folderPath, 'submission'); } /** @@ -659,7 +659,7 @@ export class AddonModWorkshopOfflineProvider { folderPath += 'assessment/'; - return CoreText.concatenatePaths(folderPath, String(assessmentId)); + return CorePath.concatenatePaths(folderPath, String(assessmentId)); } } diff --git a/src/core/components/local-file/local-file.ts b/src/core/components/local-file/local-file.ts index 7931d0e45..dec294335 100644 --- a/src/core/components/local-file/local-file.ts +++ b/src/core/components/local-file/local-file.ts @@ -26,7 +26,7 @@ import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils, CoreUtilsOpenFileOptions, OpenFileAction } from '@services/utils/utils'; import { CoreForms } from '@singletons/form'; import { CoreApp } from '@services/app'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Component to handle a local file. Only files inside the app folder can be managed. @@ -183,7 +183,7 @@ export class CoreLocalFileComponent implements OnInit { const modal = await CoreDomUtils.showModalLoading(); const fileAndDir = CoreFile.getFileAndDirectoryFromPath(this.relativePath); - const newPath = CoreText.concatenatePaths(fileAndDir.directory, newName); + const newPath = CorePath.concatenatePaths(fileAndDir.directory, newName); try { // Check if there's a file with this name. diff --git a/src/core/components/recaptcha/recaptcha.ts b/src/core/components/recaptcha/recaptcha.ts index 0e143c079..d4f8211b0 100644 --- a/src/core/components/recaptcha/recaptcha.ts +++ b/src/core/components/recaptcha/recaptcha.ts @@ -17,7 +17,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { CoreLang } from '@services/lang'; import { CoreSites } from '@services/sites'; import { CoreUtils } from '@services/utils/utils'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Component that allows answering a recaptcha. @@ -62,7 +62,7 @@ export class CoreRecaptchaComponent implements OnInit { // Open the recaptcha challenge in an InAppBrowser. // The app used to use an iframe for this, but the app can no longer access the iframe to create the required callbacks. // The app cannot render the recaptcha directly because it has problems with the local protocols and domains. - const src = CoreText.concatenatePaths(this.siteUrl!, 'webservice/recaptcha.php?lang=' + this.lang); + const src = CorePath.concatenatePaths(this.siteUrl!, 'webservice/recaptcha.php?lang=' + this.lang); const inAppBrowserWindow = CoreUtils.openInApp(src); if (!inAppBrowserWindow) { diff --git a/src/core/components/split-view/split-view.scss b/src/core/components/split-view/split-view.scss index fa9da2e18..ab8692946 100644 --- a/src/core/components/split-view/split-view.scss +++ b/src/core/components/split-view/split-view.scss @@ -74,6 +74,7 @@ --menu-border-width: 0px; --menu-box-shadow: none; --menu-z: 0px; + --selected-item-border-width: 0px; --selected-item-color: transparent; } diff --git a/src/core/directives/format-text.ts b/src/core/directives/format-text.ts index 39f35765b..d0f1ee5fc 100644 --- a/src/core/directives/format-text.ts +++ b/src/core/directives/format-text.ts @@ -46,7 +46,7 @@ import { CoreComponentsRegistry } from '@singletons/components-registry'; import { CoreCollapsibleItemDirective } from './collapsible-item'; import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { AsyncComponent } from '@classes/async-component'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreDom } from '@singletons/dom'; import { CoreEvents } from '@singletons/events'; import { CoreRefreshContext, CORE_REFRESH_CONTEXT } from '@/core/utils/refresh-context'; @@ -808,7 +808,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncCompo // Check if it's a Vimeo video. If it is, use the wsplayer script instead to make restricted videos work. const matches = src.match(/https?:\/\/player\.vimeo\.com\/video\/([0-9]+)([?&]+h=([a-zA-Z0-9]*))?/); if (matches && matches[1]) { - let newUrl = CoreText.concatenatePaths(site.getURL(), '/media/player/vimeo/wsplayer.php?video=') + + let newUrl = CorePath.concatenatePaths(site.getURL(), '/media/player/vimeo/wsplayer.php?video=') + matches[1] + '&token=' + site.getToken(); let privacyHash: string | undefined | null = matches[3]; diff --git a/src/core/features/course/pages/course-summary/course-summary.ts b/src/core/features/course/pages/course-summary/course-summary.ts index d9b6e719a..1d9da6d56 100644 --- a/src/core/features/course/pages/course-summary/course-summary.ts +++ b/src/core/features/course/pages/course-summary/course-summary.ts @@ -37,7 +37,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreCoursesHelper, CoreCourseWithImageAndColor } from '@features/courses/services/courses-helper'; import { Subscription } from 'rxjs'; import { CoreColors } from '@singletons/colors'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; import { CorePlatform } from '@services/platform'; @@ -122,8 +122,8 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy { } const currentSiteUrl = CoreSites.getRequiredCurrentSite().getURL(); - this.enrolUrl = CoreText.concatenatePaths(currentSiteUrl, 'enrol/index.php?id=' + this.courseId); - this.courseUrl = CoreText.concatenatePaths(currentSiteUrl, 'course/view.php?id=' + this.courseId); + this.enrolUrl = CorePath.concatenatePaths(currentSiteUrl, 'enrol/index.php?id=' + this.courseId); + this.courseUrl = CorePath.concatenatePaths(currentSiteUrl, 'course/view.php?id=' + this.courseId); await this.getCourse(); } diff --git a/src/core/features/course/pages/index/index.ts b/src/core/features/course/pages/index/index.ts index b17570ba6..fe34bd923 100644 --- a/src/core/features/course/pages/index/index.ts +++ b/src/core/features/course/pages/index/index.ts @@ -28,7 +28,7 @@ import { CONTENTS_PAGE_NAME } from '@features/course/course.module'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreCoursesHelper, CoreCourseWithImageAndColor } from '@features/courses/services/courses-helper'; import { CoreColors } from '@singletons/colors'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Page that displays the list of courses the user is enrolled in. @@ -149,7 +149,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { } this.currentPagePath = CoreNavigator.getCurrentPath(); - this.contentsTab.page = CoreText.concatenatePaths(this.currentPagePath, this.contentsTab.page); + this.contentsTab.page = CorePath.concatenatePaths(this.currentPagePath, this.contentsTab.page); this.contentsTab.pageParams = { course: this.course, sectionId: CoreNavigator.getRouteNumberParam('sectionId'), @@ -207,7 +207,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { // Create the full path. handlers.forEach((handler, index) => { - handler.data.page = CoreText.concatenatePaths(this.currentPagePath, handler.data.page); + handler.data.page = CorePath.concatenatePaths(this.currentPagePath, handler.data.page); handler.data.pageParams = handler.data.pageParams || {}; // Check if this handler should be the first selected tab. diff --git a/src/core/features/courses/services/handlers/request-push-click.ts b/src/core/features/courses/services/handlers/request-push-click.ts index 265e9f0f9..c9425ee49 100644 --- a/src/core/features/courses/services/handlers/request-push-click.ts +++ b/src/core/features/courses/services/handlers/request-push-click.ts @@ -22,7 +22,7 @@ import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreCourses } from '../courses'; /** @@ -58,7 +58,7 @@ export class CoreCoursesRequestPushClickHandlerService implements CorePushNotifi if (notification.name == 'courserequested') { // Feature not supported in the app, open in browser. const site = await CoreSites.getSite(notification.site); - const url = CoreText.concatenatePaths(site.getURL(), 'course/pending.php'); + const url = CorePath.concatenatePaths(site.getURL(), 'course/pending.php'); await site.openInBrowserWithAutoLogin(url); diff --git a/src/core/features/emulator/components/capture-media/capture-media.ts b/src/core/features/emulator/components/capture-media/capture-media.ts index 116ec54c4..4095878c3 100644 --- a/src/core/features/emulator/components/capture-media/capture-media.ts +++ b/src/core/features/emulator/components/capture-media/capture-media.ts @@ -25,7 +25,7 @@ import { ModalController, Media, Translate } from '@singletons'; import { CoreError } from '@classes/errors/error'; import { CoreCaptureError } from '@classes/errors/captureerror'; import { CoreCanceledError } from '@classes/errors/cancelederror'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePlatform } from '@services/platform'; /** @@ -151,7 +151,7 @@ export class CoreEmulatorCaptureMediaComponent implements OnInit, OnDestroy { this.fileEntry = await CoreFile.createFile(this.filePath); // Now create the media instance. - let absolutePath = CoreText.concatenatePaths(CoreFile.getBasePathInstant(), this.filePath); + let absolutePath = CorePath.concatenatePaths(CoreFile.getBasePathInstant(), this.filePath); if (CorePlatform.is('ios')) { // In iOS we need to remove the file:// part. @@ -557,7 +557,7 @@ export class CoreEmulatorCaptureMediaComponent implements OnInit, OnDestroy { protected getFilePath(): string { const fileName = this.type + '_' + CoreTimeUtils.readableTimestamp() + '.' + this.extension; - return CoreText.concatenatePaths(CoreFileProvider.TMPFOLDER, 'media/' + fileName); + return CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'media/' + fileName); } /** diff --git a/src/core/features/emulator/services/file.ts b/src/core/features/emulator/services/file.ts index cfd35de11..a8f1cf58b 100644 --- a/src/core/features/emulator/services/file.ts +++ b/src/core/features/emulator/services/file.ts @@ -14,8 +14,7 @@ import { Injectable } from '@angular/core'; import { File, Entry, DirectoryEntry, FileEntry, IWriteOptions, RemoveResult } from '@ionic-native/file/ngx'; - -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Implement the File Error because the ionic-native plugin doesn't implement it. @@ -58,7 +57,7 @@ export class FileMock extends File { * @return Returns a Promise that resolves to true if the directory exists or rejects with an error. */ async checkDir(path: string, dir: string): Promise { - const fullPath = CoreText.concatenatePaths(path, dir); + const fullPath = CorePath.concatenatePaths(path, dir); await this.resolveDirectoryUrl(fullPath); @@ -73,7 +72,7 @@ export class FileMock extends File { * @return Returns a Promise that resolves with a boolean or rejects with an error. */ async checkFile(path: string, file: string): Promise { - const entry = await this.resolveLocalFilesystemUrl(CoreText.concatenatePaths(path, file)); + const entry = await this.resolveLocalFilesystemUrl(CorePath.concatenatePaths(path, file)); if (entry.isFile) { return true; @@ -144,7 +143,7 @@ export class FileMock extends File { async copyFileOrDir(sourcePath: string, sourceName: string, destPath: string, destName: string): Promise { const destFixed = this.fixPathAndName(destPath, destName); - const source = await this.resolveLocalFilesystemUrl(CoreText.concatenatePaths(sourcePath, sourceName)); + const source = await this.resolveLocalFilesystemUrl(CorePath.concatenatePaths(sourcePath, sourceName)); const destParentDir = await this.resolveDirectoryUrl(destFixed.path); @@ -424,7 +423,7 @@ export class FileMock extends File { async moveFileOrDir(sourcePath: string, sourceName: string, destPath: string, destName: string): Promise { const destFixed = this.fixPathAndName(destPath, destName); - const source = await this.resolveLocalFilesystemUrl(CoreText.concatenatePaths(sourcePath, sourceName)); + const source = await this.resolveLocalFilesystemUrl(CorePath.concatenatePaths(sourcePath, sourceName)); const destParentDir = await this.resolveDirectoryUrl(destFixed.path); @@ -440,7 +439,7 @@ export class FileMock extends File { */ protected fixPathAndName(path: string, name: string): {path: string; name: string} { - const fullPath = CoreText.concatenatePaths(path, name); + const fullPath = CorePath.concatenatePaths(path, name); return { path: fullPath.substring(0, fullPath.lastIndexOf('/')), diff --git a/src/core/features/emulator/services/zip.ts b/src/core/features/emulator/services/zip.ts index bfc0a9c4e..742c1377e 100644 --- a/src/core/features/emulator/services/zip.ts +++ b/src/core/features/emulator/services/zip.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { Zip } from '@ionic-native/zip/ngx'; import * as JSZip from 'jszip'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { File } from '@singletons'; /** @@ -41,7 +41,7 @@ export class ZipMock extends Zip { await File.createDir(destination, folder, true); // Folder created, add it to the destination path. - destination = CoreText.concatenatePaths(destination, folder); + destination = CorePath.concatenatePaths(destination, folder); } } @@ -101,7 +101,7 @@ export class ZipMock extends Zip { const fileData = await file.async('blob'); // File read and parent folder created, now write the file. - const parentFolder = CoreText.concatenatePaths(destination, fileDir); + const parentFolder = CorePath.concatenatePaths(destination, fileDir); await File.writeFile(parentFolder, fileName, fileData, { replace: true }); } else { diff --git a/src/core/features/fileuploader/services/fileuploader-helper.ts b/src/core/features/fileuploader/services/fileuploader-helper.ts index ab401b17c..752d29511 100644 --- a/src/core/features/fileuploader/services/fileuploader-helper.ts +++ b/src/core/features/fileuploader/services/fileuploader-helper.ts @@ -36,7 +36,7 @@ import { CoreCaptureError } from '@classes/errors/captureerror'; import { CoreIonLoadingElement } from '@classes/ion-loading'; import { CoreWSUploadFileResult } from '@services/ws'; import { CoreSites } from '@services/sites'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; import { CorePlatform } from '@services/platform'; @@ -162,7 +162,7 @@ export class CoreFileUploaderHelperProvider { // Get unique name for the copy. const newName = await CoreFile.getUniqueNameInFolder(CoreFileProvider.TMPFOLDER, name); - const filePath = CoreText.concatenatePaths(CoreFileProvider.TMPFOLDER, newName); + const filePath = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, newName); // Write the data into the file. fileEntry = await CoreFile.writeFileDataInFile( @@ -222,7 +222,7 @@ export class CoreFileUploaderHelperProvider { const newName = await CoreFile.getUniqueNameInFolder(CoreFileProvider.TMPFOLDER, fileName, defaultExt); // Now move or copy the file. - const destPath = CoreText.concatenatePaths(CoreFileProvider.TMPFOLDER, newName); + const destPath = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, newName); if (shouldDelete) { return CoreFile.moveExternalFile(path, destPath); } else { diff --git a/src/core/features/fileuploader/services/fileuploader.ts b/src/core/features/fileuploader/services/fileuploader.ts index c9f94dac0..ce010dd8e 100644 --- a/src/core/features/fileuploader/services/fileuploader.ts +++ b/src/core/features/fileuploader/services/fileuploader.ts @@ -32,7 +32,7 @@ import { CoreEmulatorCaptureMediaComponent } from '@features/emulator/components import { CoreError } from '@classes/errors/error'; import { CoreSite } from '@classes/site'; import { CoreFileEntry, CoreFileHelper } from '@services/file-helper'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * File upload options. @@ -579,7 +579,7 @@ export class CoreFileUploaderProvider { } else { // Local file, copy it. // Use copy instead of move to prevent having a unstable state if some copies succeed and others don't. - const destFile = CoreText.concatenatePaths(folderPath, file.name); + const destFile = CorePath.concatenatePaths(folderPath, file.name); result.offline++; await CoreFile.copyFile(file.toURL(), destFile); diff --git a/src/core/features/h5p/classes/core.ts b/src/core/features/h5p/classes/core.ts index e77c7c752..97e243923 100644 --- a/src/core/features/h5p/classes/core.ts +++ b/src/core/features/h5p/classes/core.ts @@ -24,7 +24,7 @@ import { CoreH5PContentValidator, CoreH5PSemantics } from './content-validator'; import { Translate } from '@singletons'; import { CoreH5PContentBeingSaved } from './storage'; import { CoreH5PLibraryAddTo } from './validator'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Equivalent to H5P's H5PCore class. @@ -149,7 +149,7 @@ export class CoreH5PCore { urls.push(libUrl + script); }); - urls.push(CoreText.concatenatePaths(libUrl, 'moodle/js/h5p_overrides.js')); + urls.push(CorePath.concatenatePaths(libUrl, 'moodle/js/h5p_overrides.js')); return urls; } @@ -457,7 +457,7 @@ export class CoreH5PCore { // Add URL prefix if not external. if (asset.path.indexOf('://') == -1 && assetsFolderPath) { - url = CoreText.concatenatePaths(assetsFolderPath, url); + url = CorePath.concatenatePaths(assetsFolderPath, url); } // Add version if set. diff --git a/src/core/features/h5p/classes/file-storage.ts b/src/core/features/h5p/classes/file-storage.ts index 76dc636af..7a58af39d 100644 --- a/src/core/features/h5p/classes/file-storage.ts +++ b/src/core/features/h5p/classes/file-storage.ts @@ -29,7 +29,6 @@ import { } from './core'; import { CONTENTS_LIBRARIES_TABLE_NAME, CONTENT_TABLE_NAME, CoreH5PLibraryCachedAssetsDBRecord } from '../services/database/h5p'; import { CoreH5PLibraryBeingSaved } from './storage'; -import { CoreText } from '@singletons/text'; /** * Equivalent to Moodle's implementation of H5PFileStorage. @@ -62,7 +61,7 @@ export class CoreH5PFileStorage { // Create new file for cached assets. const fileName = key + '.' + (type == 'scripts' ? 'js' : 'css'); - const path = CoreText.concatenatePaths(cachedAssetsPath, fileName); + const path = CorePath.concatenatePaths(cachedAssetsPath, fileName); // Store concatenated content. const content = await this.concatenateFiles(assets, type, cachedAssetsPath); @@ -72,7 +71,7 @@ export class CoreH5PFileStorage { // Now update the files data. files[type] = [ { - path: CoreText.concatenatePaths(CoreH5PFileStorage.CACHED_ASSETS_FOLDER_NAME, fileName), + path: CorePath.concatenatePaths(CoreH5PFileStorage.CACHED_ASSETS_FOLDER_NAME, fileName), version: '', }, ]; @@ -148,7 +147,7 @@ export class CoreH5PFileStorage { const cachedAssetsFolder = this.getCachedAssetsFolderPath(entry.foldername, site.getId()); ['js', 'css'].forEach((type) => { - const path = CoreText.concatenatePaths(cachedAssetsFolder, entry.hash + '.' + type); + const path = CorePath.concatenatePaths(cachedAssetsFolder, entry.hash + '.' + type); promises.push(CoreFile.removeFile(path)); }); @@ -260,7 +259,7 @@ export class CoreH5PFileStorage { protected async getCachedAsset(key: string, extension: string): Promise { try { - const path = CoreText.concatenatePaths(CoreH5PFileStorage.CACHED_ASSETS_FOLDER_NAME, key + extension); + const path = CorePath.concatenatePaths(CoreH5PFileStorage.CACHED_ASSETS_FOLDER_NAME, key + extension); const size = await CoreFile.getFileSize(path); @@ -285,7 +284,7 @@ export class CoreH5PFileStorage { * @return Path. */ getCachedAssetsFolderPath(folderName: string, siteId: string): string { - return CoreText.concatenatePaths( + return CorePath.concatenatePaths( this.getContentFolderPath(folderName, siteId), CoreH5PFileStorage.CACHED_ASSETS_FOLDER_NAME, ); @@ -314,7 +313,7 @@ export class CoreH5PFileStorage { * @return Folder path. */ getContentFolderPath(folderName: string, siteId: string): string { - return CoreText.concatenatePaths( + return CorePath.concatenatePaths( this.getExternalH5PFolderPath(siteId), 'packages/' + folderName + '/content', ); @@ -345,7 +344,7 @@ export class CoreH5PFileStorage { * @return Folder path. */ getContentIndexPath(folderName: string, siteId: string): string { - return CoreText.concatenatePaths(this.getContentFolderPath(folderName, siteId), 'index.html'); + return CorePath.concatenatePaths(this.getContentFolderPath(folderName, siteId), 'index.html'); } /** @@ -354,7 +353,7 @@ export class CoreH5PFileStorage { * @return Folder path. */ getCoreH5PPath(): string { - return CoreText.concatenatePaths(CoreFile.getWWWPath(), '/assets/lib/h5p/'); + return CorePath.concatenatePaths(CoreFile.getWWWPath(), '/assets/lib/h5p/'); } /** @@ -374,7 +373,7 @@ export class CoreH5PFileStorage { * @return Folder path. */ getExternalH5PFolderPath(siteId: string): string { - return CoreText.concatenatePaths(CoreFile.getSiteFolder(siteId), 'h5p'); + return CorePath.concatenatePaths(CoreFile.getSiteFolder(siteId), 'h5p'); } /** @@ -384,7 +383,7 @@ export class CoreH5PFileStorage { * @return Folder path. */ getLibrariesFolderPath(siteId: string): string { - return CoreText.concatenatePaths(this.getExternalH5PFolderPath(siteId), 'libraries'); + return CorePath.concatenatePaths(this.getExternalH5PFolderPath(siteId), 'libraries'); } /** @@ -404,7 +403,7 @@ export class CoreH5PFileStorage { folderName = CoreH5PCore.libraryToString(libraryData, true); } - return CoreText.concatenatePaths(this.getLibrariesFolderPath(siteId), folderName); + return CorePath.concatenatePaths(this.getLibrariesFolderPath(siteId), folderName); } /** diff --git a/src/core/features/h5p/classes/helper.ts b/src/core/features/h5p/classes/helper.ts index 126ee649f..94bbf1602 100644 --- a/src/core/features/h5p/classes/helper.ts +++ b/src/core/features/h5p/classes/helper.ts @@ -21,7 +21,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreH5P } from '../services/h5p'; import { CoreH5PCore, CoreH5PDisplayOptions } from './core'; import { CoreError } from '@classes/errors/error'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Equivalent to Moodle's H5P helper class. @@ -131,13 +131,13 @@ export class CoreH5PHelper { return { baseUrl: CoreFile.getWWWPath(), url: CoreFile.convertFileSrc( - CoreText.concatenatePaths( + CorePath.concatenatePaths( basePath, CoreH5P.h5pCore.h5pFS.getExternalH5PFolderPath(site.getId()), ), ), urlLibraries: CoreFile.convertFileSrc( - CoreText.concatenatePaths( + CorePath.concatenatePaths( basePath, CoreH5P.h5pCore.h5pFS.getLibrariesFolderPath(site.getId()), ), @@ -155,7 +155,7 @@ export class CoreH5PHelper { crossorigin: null, libraryConfig: null, pluginCacheBuster: '', - libraryUrl: CoreText.concatenatePaths(CoreH5P.h5pCore.h5pFS.getCoreH5PPath(), 'js'), + libraryUrl: CorePath.concatenatePaths(CoreH5P.h5pCore.h5pFS.getCoreH5PPath(), 'js'), }; } @@ -197,7 +197,7 @@ export class CoreH5PHelper { ): Promise { const folderName = CoreMimetypeUtils.removeExtension(file.name); - const destFolder = CoreText.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); + const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); // Unzip the file. await CoreFile.unzipFile(file.toURL(), destFolder, onProgress); diff --git a/src/core/features/h5p/classes/player.ts b/src/core/features/h5p/classes/player.ts index b42a61ebc..bcdd7dad2 100644 --- a/src/core/features/h5p/classes/player.ts +++ b/src/core/features/h5p/classes/player.ts @@ -21,7 +21,7 @@ import { CoreH5P } from '../services/h5p'; import { CoreH5PCore, CoreH5PDisplayOptions, CoreH5PContentData, CoreH5PDependenciesFiles } from './core'; import { CoreH5PCoreSettings, CoreH5PHelper } from './helper'; import { CoreH5PStorage } from './storage'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Equivalent to Moodle's H5P player class. @@ -51,7 +51,7 @@ export class CoreH5PPlayer { params.component = component; } - return CoreUrlUtils.addParamsToUrl(CoreText.concatenatePaths(siteUrl, '/h5p/embed.php'), params); + return CoreUrlUtils.addParamsToUrl(CorePath.concatenatePaths(siteUrl, '/h5p/embed.php'), params); } /** @@ -78,7 +78,7 @@ export class CoreH5PPlayer { const contentId = this.getContentId(id); const basePath = CoreFile.getBasePathInstant(); const contentUrl = CoreFile.convertFileSrc( - CoreText.concatenatePaths( + CorePath.concatenatePaths( basePath, this.h5pCore.h5pFS.getContentFolderPath(content.folderName, site.getId()), ), @@ -122,7 +122,7 @@ export class CoreH5PPlayer { JSON.stringify(result.settings).replace(/\//g, '\\/') + ''; // Add our own script to handle the params. - html += ''; @@ -132,7 +132,7 @@ export class CoreH5PPlayer { // Include the required JS at the beginning of the body, like Moodle web does. // Load the embed.js to allow communication with the parent window. html += ''; + CorePath.concatenatePaths(this.h5pCore.h5pFS.getCoreH5PPath(), 'moodle/js/embed.js') + '">'; result.jsRequires.forEach((jsUrl) => { html += ''; @@ -364,7 +364,7 @@ export class CoreH5PPlayer { * @return The embed URL. */ protected getEmbedUrl(siteUrl: string, h5pUrl: string): string { - return CoreText.concatenatePaths(siteUrl, '/h5p/embed.php') + '?url=' + h5pUrl; + return CorePath.concatenatePaths(siteUrl, '/h5p/embed.php') + '?url=' + h5pUrl; } /** @@ -382,7 +382,7 @@ export class CoreH5PPlayer { * @return URL. */ getResizerScriptUrl(): string { - return CoreText.concatenatePaths(this.h5pCore.h5pFS.getCoreH5PPath(), 'js/h5p-resizer.js'); + return CorePath.concatenatePaths(this.h5pCore.h5pFS.getCoreH5PPath(), 'js/h5p-resizer.js'); } /** diff --git a/src/core/features/h5p/classes/storage.ts b/src/core/features/h5p/classes/storage.ts index a94453190..7539e8e80 100644 --- a/src/core/features/h5p/classes/storage.ts +++ b/src/core/features/h5p/classes/storage.ts @@ -15,7 +15,7 @@ import { CoreFile, CoreFileProvider } from '@services/file'; import { CoreSites } from '@services/sites'; import { CoreUtils } from '@services/utils/utils'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreH5PCore, CoreH5PLibraryBasicData } from './core'; import { CoreH5PFramework } from './framework'; import { CoreH5PMetadata } from './metadata'; @@ -199,8 +199,8 @@ export class CoreH5PStorage { await this.h5pCore.saveContent(content, folderName, fileUrl, siteId); // Save the content files in their right place in FS. - const destFolder = CoreText.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); - const contentPath = CoreText.concatenatePaths(destFolder, 'content'); + const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); + const contentPath = CorePath.concatenatePaths(destFolder, 'content'); try { await this.h5pCore.h5pFS.saveContent(contentPath, folderName, siteId); diff --git a/src/core/features/h5p/classes/validator.ts b/src/core/features/h5p/classes/validator.ts index 7eca0f96f..cc0d2ec5c 100644 --- a/src/core/features/h5p/classes/validator.ts +++ b/src/core/features/h5p/classes/validator.ts @@ -16,7 +16,7 @@ import { CoreError } from '@classes/errors/error'; import { FileEntry, DirectoryEntry } from '@ionic-native/file/ngx'; import { CoreFile, CoreFileFormat } from '@services/file'; import { Translate } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreH5PSemantics } from './content-validator'; import { CoreH5PCore, CoreH5PLibraryBasicData, CoreH5PMissingLibrary } from './core'; import { CoreH5PFramework } from './framework'; @@ -126,7 +126,7 @@ export class CoreH5PValidator { return; } - const libDirPath = CoreText.concatenatePaths(packagePath, entry.name); + const libDirPath = CorePath.concatenatePaths(packagePath, entry.name); const libraryData = await this.getLibraryData( entry, libDirPath); @@ -144,7 +144,7 @@ export class CoreH5PValidator { * @return Promise resolved with boolean: whether the library has an icon file. */ protected async libraryHasIcon(libPath: string): Promise { - const path = CoreText.concatenatePaths(libPath, 'icon.svg'); + const path = CorePath.concatenatePaths(libPath, 'icon.svg'); try { // Check if the file exists. @@ -219,7 +219,7 @@ export class CoreH5PValidator { * @return Promise resolved with the parsed file contents. */ protected readH5PContentJsonFile(packagePath: string): Promise { - const path = CoreText.concatenatePaths(packagePath, 'content/content.json'); + const path = CorePath.concatenatePaths(packagePath, 'content/content.json'); return CoreFile.readFile(path, CoreFileFormat.FORMATJSON); } @@ -231,7 +231,7 @@ export class CoreH5PValidator { * @return Promise resolved with the parsed file contents. */ protected readH5PJsonFile(packagePath: string): Promise { - const path = CoreText.concatenatePaths(packagePath, 'h5p.json'); + const path = CorePath.concatenatePaths(packagePath, 'h5p.json'); return CoreFile.readFile(path, CoreFileFormat.FORMATJSON); } @@ -243,7 +243,7 @@ export class CoreH5PValidator { * @return Promise resolved with the parsed file contents. */ protected readLibraryJsonFile(libPath: string): Promise { - const path = CoreText.concatenatePaths(libPath, 'library.json'); + const path = CorePath.concatenatePaths(libPath, 'library.json'); return CoreFile.readFile(path, CoreFileFormat.FORMATJSON); } @@ -256,14 +256,14 @@ export class CoreH5PValidator { */ protected async readLibraryLanguageFiles(libPath: string): Promise { try { - const path = CoreText.concatenatePaths(libPath, 'language'); + const path = CorePath.concatenatePaths(libPath, 'language'); const langIndex: CoreH5PLibraryLangsJsonData = {}; // Read all the files in the language directory. const entries = await CoreFile.getDirectoryContents(path); await Promise.all(entries.map(async (entry) => { - const langFilePath = CoreText.concatenatePaths(path, entry.name); + const langFilePath = CorePath.concatenatePaths(path, entry.name); try { const langFileData = await CoreFile.readFile( @@ -293,7 +293,7 @@ export class CoreH5PValidator { */ protected async readLibrarySemanticsFile(libPath: string): Promise { try { - const path = CoreText.concatenatePaths(libPath, 'semantics.json'); + const path = CorePath.concatenatePaths(libPath, 'semantics.json'); return await CoreFile.readFile(path, CoreFileFormat.FORMATJSON); } catch (error) { diff --git a/src/core/features/h5p/services/h5p.ts b/src/core/features/h5p/services/h5p.ts index fc4693645..023d76988 100644 --- a/src/core/features/h5p/services/h5p.ts +++ b/src/core/features/h5p/services/h5p.ts @@ -28,7 +28,7 @@ import { CoreH5PValidator } from '../classes/validator'; import { makeSingleton } from '@singletons'; import { CoreError } from '@classes/errors/error'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Service to provide H5P functionalities. @@ -207,7 +207,7 @@ export class CoreH5PProvider { * @return Treated url. */ treatH5PUrl(url: string, siteUrl: string): string { - if (url.indexOf(CoreText.concatenatePaths(siteUrl, '/webservice/pluginfile.php')) === 0) { + if (url.indexOf(CorePath.concatenatePaths(siteUrl, '/webservice/pluginfile.php')) === 0) { url = url.replace('/webservice/pluginfile', '/pluginfile'); } diff --git a/src/core/features/login/pages/email-signup/email-signup.ts b/src/core/features/login/pages/email-signup/email-signup.ts index 5e1616980..87d674d55 100644 --- a/src/core/features/login/pages/email-signup/email-signup.ts +++ b/src/core/features/login/pages/email-signup/email-signup.ts @@ -33,7 +33,7 @@ import { import { CoreNavigator } from '@services/navigator'; import { CoreForms } from '@singletons/form'; import { CoreRecaptchaComponent } from '@components/recaptcha/recaptcha'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreDom } from '@singletons/dom'; /** @@ -161,7 +161,7 @@ export class CoreLoginEmailSignupPage implements OnInit { try { // Get site config. this.siteConfig = await CoreSites.getSitePublicConfig(this.siteUrl); - this.signupUrl = CoreText.concatenatePaths(this.siteConfig.httpswwwroot, 'login/signup.php'); + this.signupUrl = CorePath.concatenatePaths(this.siteConfig.httpswwwroot, 'login/signup.php'); if (this.treatSiteConfig()) { // Check content verification. @@ -373,7 +373,7 @@ export class CoreLoginEmailSignupPage implements OnInit { */ showContactOnSite(): void { CoreUtils.openInBrowser( - CoreText.concatenatePaths(this.siteUrl, '/login/verify_age_location.php'), + CorePath.concatenatePaths(this.siteUrl, '/login/verify_age_location.php'), { showBrowserWarning: false }, ); } diff --git a/src/core/features/login/services/login-helper.ts b/src/core/features/login/services/login-helper.ts index c513b3d22..1a02f0e80 100644 --- a/src/core/features/login/services/login-helper.ts +++ b/src/core/features/login/services/login-helper.ts @@ -36,7 +36,7 @@ import { CoreNavigator, CoreRedirectPayload } from '@services/navigator'; import { CoreCanceledError } from '@classes/errors/cancelederror'; import { CoreCustomURLSchemes } from '@services/urlschemes'; import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; import { SafeHtml } from '@angular/platform-browser'; import { CoreLoginError } from '@classes/errors/loginerror'; @@ -399,8 +399,8 @@ export class CoreLoginHelperProvider { } const validProviders: CoreSiteIdentityProvider[] = []; - const httpUrl = CoreText.concatenatePaths(siteConfig.wwwroot, 'auth/oauth2/'); - const httpsUrl = CoreText.concatenatePaths(siteConfig.httpswwwroot, 'auth/oauth2/'); + const httpUrl = CorePath.concatenatePaths(siteConfig.wwwroot, 'auth/oauth2/'); + const httpsUrl = CorePath.concatenatePaths(siteConfig.httpswwwroot, 'auth/oauth2/'); if (siteConfig.identityproviders && siteConfig.identityproviders.length) { siteConfig.identityproviders.forEach((provider) => { diff --git a/src/core/features/question/services/question.ts b/src/core/features/question/services/question.ts index 37914ca4b..7a873e6c6 100644 --- a/src/core/features/question/services/question.ts +++ b/src/core/features/question/services/question.ts @@ -21,7 +21,7 @@ import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; import { CoreWSExternalFile } from '@services/ws'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreQuestionAnswerDBRecord, CoreQuestionDBRecord, @@ -332,7 +332,7 @@ export class CoreQuestionProvider { const siteFolderPath = CoreFile.getSiteFolder(siteId); const questionFolderPath = 'offlinequestion/' + type + '/' + component + '/' + componentId; - return CoreText.concatenatePaths(siteFolderPath, questionFolderPath); + return CorePath.concatenatePaths(siteFolderPath, questionFolderPath); } /** diff --git a/src/core/features/sharedfiles/components/list/list.ts b/src/core/features/sharedfiles/components/list/list.ts index f56e5318f..f336c0890 100644 --- a/src/core/features/sharedfiles/components/list/list.ts +++ b/src/core/features/sharedfiles/components/list/list.ts @@ -21,7 +21,7 @@ import { CoreSharedFiles } from '@features/sharedfiles/services/sharedfiles'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Component to display the list of shared files, either as a modal or inside a page. @@ -113,7 +113,7 @@ export class CoreSharedFilesListComponent implements OnInit, OnDestroy { * @param folder The folder to open. */ openFolder(folder: DirectoryEntry): void { - const path = CoreText.concatenatePaths(this.path || '', folder.name); + const path = CorePath.concatenatePaths(this.path || '', folder.name); if (this.isModal) { this.path = path; diff --git a/src/core/features/sharedfiles/services/sharedfiles.ts b/src/core/features/sharedfiles/services/sharedfiles.ts index 599299576..2cc6bd042 100644 --- a/src/core/features/sharedfiles/services/sharedfiles.ts +++ b/src/core/features/sharedfiles/services/sharedfiles.ts @@ -26,7 +26,7 @@ import { CoreSites } from '@services/sites'; import { CoreEvents } from '@singletons/events'; import { makeSingleton } from '@singletons'; import { APP_SCHEMA, CoreSharedFilesDBRecord, SHARED_FILES_TABLE_NAME } from './database/sharedfiles'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Service to share files with the app. @@ -157,7 +157,7 @@ export class CoreSharedFilesProvider { async getSiteSharedFiles(siteId?: string, path?: string, mimetypes?: string[]): Promise<(FileEntry | DirectoryEntry)[]> { let pathToGet = this.getSiteSharedFilesDirPath(siteId); if (path) { - pathToGet = CoreText.concatenatePaths(pathToGet, path); + pathToGet = CorePath.concatenatePaths(pathToGet, path); } try { @@ -240,7 +240,7 @@ export class CoreSharedFilesProvider { newName = newName || entry.name; const sharedFilesFolder = this.getSiteSharedFilesDirPath(siteId); - const newPath = CoreText.concatenatePaths(sharedFilesFolder, newName); + const newPath = CorePath.concatenatePaths(sharedFilesFolder, newName); // Create dir if it doesn't exist already. await CoreFile.createDir(sharedFilesFolder); diff --git a/src/core/features/siteplugins/services/siteplugins-helper.ts b/src/core/features/siteplugins/services/siteplugins-helper.ts index 6d15020ba..ddc7db3a9 100644 --- a/src/core/features/siteplugins/services/siteplugins-helper.ts +++ b/src/core/features/siteplugins/services/siteplugins-helper.ts @@ -85,7 +85,7 @@ import { CoreContentLinksDelegate } from '@features/contentlinks/services/conten import { CoreContentLinksModuleListHandler } from '@features/contentlinks/classes/module-list-handler'; import { CoreObject } from '@singletons/object'; import { CoreUrlUtils } from '@services/utils/url'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; const HANDLER_DISABLED = 'core_site_plugins_helper_handler_disabled'; @@ -168,7 +168,7 @@ export class CoreSitePluginsHelperProvider { // Make sure it's an absolute URL. Do not use toAbsoluteURL because it can change the behaviour and break plugin styles. let url = handlerSchema.styles?.url; if (url && !CoreUrlUtils.isAbsoluteURL(url)) { - url = CoreText.concatenatePaths(site.getURL(), url); + url = CorePath.concatenatePaths(site.getURL(), url); } if (url && handlerSchema.styles?.version) { diff --git a/src/core/features/tag/pages/index/index.page.ts b/src/core/features/tag/pages/index/index.page.ts index 86722010b..1e72b4866 100644 --- a/src/core/features/tag/pages/index/index.page.ts +++ b/src/core/features/tag/pages/index/index.page.ts @@ -43,7 +43,7 @@ export class CoreTagIndexPage implements OnInit { areas: CoreTagAreaDisplay[] = []; /** - * View loaded. + * @inheritdoc */ async ngOnInit(): Promise { this.tagId = CoreNavigator.getRouteNumberParam('tagId') || this.tagId; @@ -143,7 +143,14 @@ export class CoreTagIndexPage implements OnInit { * @param area Area. */ openArea(area: CoreTagAreaDisplay): void { - this.selectedAreaId = area.id; + if (area.id === this.selectedAreaId) { + // Already opened. + return; + } + + if (CoreScreen.isTablet) { + this.selectedAreaId = area.id; + } const params = { tagId: this.tagId, diff --git a/src/core/features/xapi/services/xapi.ts b/src/core/features/xapi/services/xapi.ts index 769a477fc..6b7c1b1d1 100644 --- a/src/core/features/xapi/services/xapi.ts +++ b/src/core/features/xapi/services/xapi.ts @@ -20,7 +20,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreSite } from '@classes/site'; import { CoreXAPIOffline, CoreXAPIOfflineSaveStatementsOptions } from './offline'; import { makeSingleton } from '@singletons'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; /** * Service to provide XAPI functionalities. @@ -65,7 +65,7 @@ export class CoreXAPIProvider { async getUrl(contextId: number, type: string, siteId?: string): Promise { const site = await CoreSites.getSite(siteId); - return CoreText.concatenatePaths(site.getURL(), `xapi/${type}/${contextId}`); + return CorePath.concatenatePaths(site.getURL(), `xapi/${type}/${contextId}`); } /** diff --git a/src/core/services/file.ts b/src/core/services/file.ts index a6123084a..98db0183b 100644 --- a/src/core/services/file.ts +++ b/src/core/services/file.ts @@ -28,6 +28,7 @@ import { makeSingleton, File, Zip, WebView } from '@singletons'; import { CoreFileEntry } from '@services/file-helper'; import { CoreText } from '@singletons/text'; import { CorePlatform } from '@services/platform'; +import { CorePath } from '@singletons/path'; /** * Progress event used when writing a file data into a file. @@ -911,7 +912,7 @@ export class CoreFileProvider { if (path.indexOf(this.basePath) > -1) { return path; } else { - return CoreText.concatenatePaths(this.basePath, path); + return CorePath.concatenatePaths(this.basePath, path); } } @@ -1233,7 +1234,7 @@ export class CoreFileProvider { */ getWWWAbsolutePath(): string { if (window.cordova && cordova.file && cordova.file.applicationDirectory) { - return CoreText.concatenatePaths(cordova.file.applicationDirectory, 'www'); + return CorePath.concatenatePaths(cordova.file.applicationDirectory, 'www'); } // Cannot use Cordova to get it, use the WebView URL. diff --git a/src/core/services/filepool.ts b/src/core/services/filepool.ts index 33e7eca95..5041969e1 100644 --- a/src/core/services/filepool.ts +++ b/src/core/services/filepool.ts @@ -53,7 +53,7 @@ import { CoreDatabaseTable } from '@classes/database/database-table'; import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy'; import { lazyMap, LazyMap } from '../utils/lazy-map'; import { asyncInstance, AsyncInstance } from '../utils/async-instance'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; import { CoreSite } from '@classes/site'; @@ -815,7 +815,7 @@ export class CoreFilepoolProvider { if (file.filepath && file.filepath !== '/') { path = file.filepath.substring(1) + path; } - path = CoreText.concatenatePaths(dirPath, path); + path = CorePath.concatenatePaths(dirPath, path); } if (prefetch) { @@ -909,7 +909,7 @@ export class CoreFilepoolProvider { if (file.filepath && file.filepath !== '/') { path = file.filepath.substring(1) + path; } - path = CoreText.concatenatePaths(dirPath, path); + path = CorePath.concatenatePaths(dirPath, path); } if (prefetch) { diff --git a/src/core/services/urlschemes.ts b/src/core/services/urlschemes.ts index bf9ebbe17..5f21ea24b 100644 --- a/src/core/services/urlschemes.ts +++ b/src/core/services/urlschemes.ts @@ -21,7 +21,7 @@ import { CoreContentLinksHelper } from '@features/contentlinks/services/contentl import { CoreLoginHelper, CoreLoginSSOData } from '@features/login/services/login-helper'; import { ApplicationInit, makeSingleton, Translate } from '@singletons'; import { CoreLogger } from '@singletons/logger'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CoreConstants } from '../constants'; import { CoreApp } from './app'; import { CoreNavigator, CoreRedirectPayload } from './navigator'; @@ -164,7 +164,7 @@ export class CoreCustomURLSchemesProvider { if (data.redirect && !data.redirect.match(/^https?:\/\//)) { // Redirect is a relative URL. Append the site URL. - data.redirect = CoreText.concatenatePaths(data.siteUrl, data.redirect); + data.redirect = CorePath.concatenatePaths(data.siteUrl, data.redirect); } let siteIds = [siteId]; diff --git a/src/core/services/utils/iframe.ts b/src/core/services/utils/iframe.ts index 5637d72ca..4a25a0f67 100644 --- a/src/core/services/utils/iframe.ts +++ b/src/core/services/utils/iframe.ts @@ -30,7 +30,7 @@ import { CoreLogger } from '@singletons/logger'; import { CoreUrl } from '@singletons/url'; import { CoreWindow } from '@singletons/window'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; /** @@ -422,7 +422,7 @@ export class CoreIframeUtilsProvider { if (src) { const dirAndFile = CoreFile.getFileAndDirectoryFromPath(src); if (dirAndFile.directory) { - url = CoreText.concatenatePaths(dirAndFile.directory, url); + url = CorePath.concatenatePaths(dirAndFile.directory, url); } else { this.logger.warn('Cannot get iframe dir path to open relative url', url, element); @@ -549,7 +549,7 @@ export class CoreIframeUtilsProvider { */ injectiOSScripts(userScriptWindow: WKUserScriptWindow): void { const wwwPath = CoreFile.getWWWAbsolutePath(); - const linksPath = CoreText.concatenatePaths(wwwPath, 'assets/js/iframe-treat-links.js'); + const linksPath = CorePath.concatenatePaths(wwwPath, 'assets/js/iframe-treat-links.js'); userScriptWindow.WKUserScript?.addScript({ id: 'CoreIframeUtilsLinksScript', file: linksPath }); diff --git a/src/core/services/utils/text.ts b/src/core/services/utils/text.ts index 265a8c889..88fcc37e5 100644 --- a/src/core/services/utils/text.ts +++ b/src/core/services/utils/text.ts @@ -27,6 +27,7 @@ import { CoreDomUtils } from './dom'; import { CoreText } from '@singletons/text'; import { CoreUrl } from '@singletons/url'; import { AlertButton } from '@ionic/angular'; +import { CorePath } from '@singletons/path'; /** * Different type of errors the app can treat. @@ -300,10 +301,10 @@ export class CoreTextUtilsProvider { * @param leftPath Left path. * @param rightPath Right path. * @return Concatenated path. - * @deprecated since 4.0. Use CoreText instead. + * @deprecated since 4.0. Use CorePath instead. */ concatenatePaths(leftPath: string, rightPath: string): string { - return CoreText.concatenatePaths(leftPath, rightPath); + return CorePath.concatenatePaths(leftPath, rightPath); } /** @@ -787,7 +788,7 @@ export class CoreTextUtilsProvider { return { text }; } - const draftfileUrl = CoreText.concatenatePaths(siteUrl, 'draftfile.php'); + const draftfileUrl = CorePath.concatenatePaths(siteUrl, 'draftfile.php'); const matches = text.match(new RegExp(this.escapeForRegex(draftfileUrl) + '[^\'" ]+', 'ig')); if (!matches || !matches.length) { @@ -858,7 +859,7 @@ export class CoreTextUtilsProvider { return treatedText; } - const draftfileUrl = CoreText.concatenatePaths(siteUrl, 'draftfile.php'); + const draftfileUrl = CorePath.concatenatePaths(siteUrl, 'draftfile.php'); const draftfileUrlRegexPrefix = this.escapeForRegex(draftfileUrl) + '/[^/]+/[^/]+/[^/]+/[^/]+/'; files.forEach((file) => { diff --git a/src/core/services/utils/url.ts b/src/core/services/utils/url.ts index b429d2ec3..841f10b31 100644 --- a/src/core/services/utils/url.ts +++ b/src/core/services/utils/url.ts @@ -20,7 +20,7 @@ import { CoreConstants } from '@/core/constants'; import { makeSingleton } from '@singletons'; import { CoreUrl } from '@singletons/url'; import { CoreSites } from '@services/sites'; -import { CoreText } from '@singletons/text'; +import { CorePath } from '@singletons/path'; import { CorePlatform } from '@services/platform'; /* @@ -119,8 +119,8 @@ export class CoreUrlUtilsProvider { // Do not use tokenpluginfile if site doesn't use slash params, the URL doesn't work. // Also, only use it for "core" pluginfile endpoints. Some plugins can implement their own endpoint (like customcert). return !CoreConstants.CONFIG.disableTokenFile && !!accessKey && !url.match(/[&?]file=/) && ( - url.indexOf(CoreText.concatenatePaths(siteUrl, 'pluginfile.php')) === 0 || - url.indexOf(CoreText.concatenatePaths(siteUrl, 'webservice/pluginfile.php')) === 0); + url.indexOf(CorePath.concatenatePaths(siteUrl, 'pluginfile.php')) === 0 || + url.indexOf(CorePath.concatenatePaths(siteUrl, 'webservice/pluginfile.php')) === 0); } /** @@ -202,7 +202,7 @@ export class CoreUrlUtilsProvider { url = url.replace(/(\/webservice)?\/pluginfile\.php/, '/tokenpluginfile.php/' + accessKey); } else { // Use pluginfile.php. Some webservices returns directly the correct download url, others not. - if (url.indexOf(CoreText.concatenatePaths(siteUrl, 'pluginfile.php')) === 0) { + if (url.indexOf(CorePath.concatenatePaths(siteUrl, 'pluginfile.php')) === 0) { url = url.replace('/pluginfile', '/webservice/pluginfile'); } diff --git a/src/core/singletons/path.ts b/src/core/singletons/path.ts index d92bbf7a3..e2bcb0552 100644 --- a/src/core/singletons/path.ts +++ b/src/core/singletons/path.ts @@ -70,7 +70,7 @@ export class CorePath { * @return Relative path. */ static changeRelativePath(currentFolder: string, path: string, newFolder: string): string { - return CoreText.concatenatePaths(CorePath.calculateRelativePath(newFolder, currentFolder), path); + return CorePath.concatenatePaths(CorePath.calculateRelativePath(newFolder, currentFolder), path); } /** diff --git a/src/core/singletons/url.ts b/src/core/singletons/url.ts index 9b69cba3b..67f105e70 100644 --- a/src/core/singletons/url.ts +++ b/src/core/singletons/url.ts @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { CorePath } from './path'; import { CoreText } from './text'; /** @@ -277,7 +278,7 @@ export class CoreUrl { path: url.startsWith('/') ? undefined : parsedParentUrl?.path, }); - return CoreText.concatenatePaths(treatedParentUrl, url); + return CorePath.concatenatePaths(treatedParentUrl, url); } /**