diff --git a/src/addon/mod/url/components/components.module.ts b/src/addon/mod/url/components/components.module.ts
new file mode 100644
index 000000000..e1d413330
--- /dev/null
+++ b/src/addon/mod/url/components/components.module.ts
@@ -0,0 +1,45 @@
+// (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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { CoreCourseComponentsModule } from '@core/course/components/components.module';
+import { AddonModUrlIndexComponent } from './index/index';
+
+@NgModule({
+ declarations: [
+ AddonModUrlIndexComponent
+ ],
+ imports: [
+ CommonModule,
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ CoreCourseComponentsModule
+ ],
+ providers: [
+ ],
+ exports: [
+ AddonModUrlIndexComponent
+ ],
+ entryComponents: [
+ AddonModUrlIndexComponent
+ ]
+})
+export class AddonModUrlComponentsModule {}
diff --git a/src/addon/mod/url/components/index/index.html b/src/addon/mod/url/components/index/index.html
new file mode 100644
index 000000000..7f4f8dd28
--- /dev/null
+++ b/src/addon/mod/url/components/index/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'addon.mod_url.pointingtourl' | translate }}
+ {{ url }}
+
+
+
diff --git a/src/addon/mod/url/components/index/index.ts b/src/addon/mod/url/components/index/index.ts
new file mode 100644
index 000000000..df2cca224
--- /dev/null
+++ b/src/addon/mod/url/components/index/index.ts
@@ -0,0 +1,112 @@
+// (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 { Component } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreTextUtilsProvider } from '@providers/utils/text';
+import { CoreCourseProvider } from '@core/course/providers/course';
+import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
+import { AddonModUrlProvider } from '../../providers/url';
+import { AddonModUrlHelperProvider } from '../../providers/helper';
+import { CoreCourseHelperProvider } from '@core/course/providers/helper';
+
+/**
+ * Component that displays a url.
+ */
+@Component({
+ selector: 'addon-mod-url-index',
+ templateUrl: 'index.html',
+})
+export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceComponent {
+ component = AddonModUrlProvider.COMPONENT;
+
+ canGetUrl: boolean;
+ url: string;
+
+ constructor(private urlProvider: AddonModUrlProvider, private courseProvider: CoreCourseProvider,
+ protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
+ protected translate: TranslateService, private urlHelper: AddonModUrlHelperProvider,
+ protected courseHelper: CoreCourseHelperProvider) {
+ super(textUtils, courseHelper, translate, domUtils);
+ }
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit(): void {
+ super.ngOnInit();
+
+ this.canGetUrl = this.urlProvider.isGetUrlWSAvailable();
+
+ this.loadContent();
+ }
+
+ /**
+ * Perform the invalidate content function.
+ *
+ * @return {Promise} Resolved when done.
+ */
+ protected invalidateContent(): Promise {
+ return this.urlProvider.invalidateContent(this.module.id, this.courseId);
+ }
+
+ /**
+ * Download url contents.
+ *
+ * @param {boolean} [refresh] Whether we're refreshing data.
+ * @return {Promise} Promise resolved when done.
+ */
+ protected fetchContent(refresh?: boolean): Promise {
+ let canGetUrl = this.canGetUrl;
+
+ // Fetch the module data.
+ let promise;
+ if (canGetUrl) {
+ promise = this.urlProvider.getUrl(this.courseId, this.module.id);
+ } else {
+ promise = Promise.reject(null);
+ }
+
+ return promise.catch(() => {
+ canGetUrl = false;
+
+ // Fallback in case is not prefetch or not avalaible.
+ return this.courseProvider.getModule(this.module.id, this.courseId);
+ }).then((url) => {
+ if (!canGetUrl) {
+ if (!url.contents.length) {
+ // If the data was cached maybe we don't have contents. Reject.
+ return Promise.reject(null);
+ }
+ }
+
+ this.description = url.intro || url.description;
+ this.dataRetrieved.emit(url);
+
+ this.url = canGetUrl ? url.externalurl :
+ ((url.contents[0] && url.contents[0].fileurl) ? url.contents[0].fileurl : undefined);
+ });
+ }
+
+ /**
+ * Opens a file.
+ */
+ go(): void {
+ this.urlProvider.logView(this.module.instance).then(() => {
+ this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus);
+ });
+ this.urlHelper.open(this.url);
+ }
+}
diff --git a/src/addon/mod/url/lang/en.json b/src/addon/mod/url/lang/en.json
new file mode 100644
index 000000000..7d905f0cf
--- /dev/null
+++ b/src/addon/mod/url/lang/en.json
@@ -0,0 +1,4 @@
+{
+ "accessurl": "Access the URL",
+ "pointingtourl": "URL that the resource points to."
+}
\ No newline at end of file
diff --git a/src/addon/mod/url/pages/index/index.html b/src/addon/mod/url/pages/index/index.html
new file mode 100644
index 000000000..2c3b52af2
--- /dev/null
+++ b/src/addon/mod/url/pages/index/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/addon/mod/url/pages/index/index.module.ts b/src/addon/mod/url/pages/index/index.module.ts
new file mode 100644
index 000000000..0bad6f9ae
--- /dev/null
+++ b/src/addon/mod/url/pages/index/index.module.ts
@@ -0,0 +1,33 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { AddonModUrlComponentsModule } from '../../components/components.module';
+import { AddonModUrlIndexPage } from './index';
+
+@NgModule({
+ declarations: [
+ AddonModUrlIndexPage,
+ ],
+ imports: [
+ CoreDirectivesModule,
+ AddonModUrlComponentsModule,
+ IonicPageModule.forChild(AddonModUrlIndexPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonModUrlIndexPageModule {}
diff --git a/src/addon/mod/url/pages/index/index.ts b/src/addon/mod/url/pages/index/index.ts
new file mode 100644
index 000000000..1e0ec28c6
--- /dev/null
+++ b/src/addon/mod/url/pages/index/index.ts
@@ -0,0 +1,48 @@
+// (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 { Component, ViewChild } from '@angular/core';
+import { IonicPage, NavParams } from 'ionic-angular';
+import { AddonModUrlIndexComponent } from '../../components/index/index';
+
+/**
+ * Page that displays a url.
+ */
+@IonicPage({ segment: 'addon-mod-url-index' })
+@Component({
+ selector: 'page-addon-mod-url-index',
+ templateUrl: 'index.html',
+})
+export class AddonModUrlIndexPage {
+ @ViewChild(AddonModUrlIndexComponent) urlComponent: AddonModUrlIndexComponent;
+
+ title: string;
+ module: any;
+ courseId: number;
+
+ constructor(navParams: NavParams) {
+ this.module = navParams.get('module') || {};
+ this.courseId = navParams.get('courseId');
+ this.title = this.module.name;
+ }
+
+ /**
+ * Update some data based on the url instance.
+ *
+ * @param {any} url Url instance.
+ */
+ updateData(url: any): void {
+ this.title = url.name || this.title;
+ }
+}
diff --git a/src/addon/mod/url/providers/helper.ts b/src/addon/mod/url/providers/helper.ts
new file mode 100644
index 000000000..5a2c0dec9
--- /dev/null
+++ b/src/addon/mod/url/providers/helper.ts
@@ -0,0 +1,44 @@
+// (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 { CoreSitesProvider } from '@providers/sites';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
+
+/**
+ * Service that provides helper functions for urls.
+ */
+@Injectable()
+export class AddonModUrlHelperProvider {
+
+ constructor(private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
+ private contentLinksHelper: CoreContentLinksHelperProvider) { }
+
+ /**
+ * Opens a URL.
+ *
+ * @param {string} url The URL to go to.
+ */
+ open(url: string): void {
+ const modal = this.domUtils.showModalLoading();
+ this.contentLinksHelper.handleLink(url).then((treated) => {
+ if (!treated) {
+ return this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
+ }
+ }).finally(() => {
+ modal.dismiss();
+ });
+ }
+}
diff --git a/src/addon/mod/url/providers/link-handler.ts b/src/addon/mod/url/providers/link-handler.ts
new file mode 100644
index 000000000..c9ad1c24b
--- /dev/null
+++ b/src/addon/mod/url/providers/link-handler.ts
@@ -0,0 +1,30 @@
+// (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 { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler';
+import { CoreCourseHelperProvider } from '@core/course/providers/helper';
+import { AddonModUrlProvider } from './url';
+
+/**
+ * Handler to treat links to url.
+ */
+@Injectable()
+export class AddonModUrlLinkHandler extends CoreContentLinksModuleIndexHandler {
+ name = 'AddonModUrlLinkHandler';
+
+ constructor(courseHelper: CoreCourseHelperProvider) {
+ super(courseHelper, AddonModUrlProvider.COMPONENT, 'url');
+ }
+}
diff --git a/src/addon/mod/url/providers/module-handler.ts b/src/addon/mod/url/providers/module-handler.ts
new file mode 100644
index 000000000..7bc5e1166
--- /dev/null
+++ b/src/addon/mod/url/providers/module-handler.ts
@@ -0,0 +1,107 @@
+// (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 { NavController, NavOptions } from 'ionic-angular';
+import { AddonModUrlIndexComponent } from '../components/index/index';
+import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
+import { CoreCourseProvider } from '@core/course/providers/course';
+import { AddonModUrlProvider } from './url';
+import { AddonModUrlHelperProvider } from './helper';
+
+/**
+ * Handler to support url modules.
+ */
+@Injectable()
+export class AddonModUrlModuleHandler implements CoreCourseModuleHandler {
+ name = 'url';
+
+ constructor(private courseProvider: CoreCourseProvider, private urlProvider: AddonModUrlProvider,
+ private urlHelper: AddonModUrlHelperProvider) { }
+
+ /**
+ * Check if the handler is enabled on a site level.
+ *
+ * @return {boolean} Whether or not the handler is enabled on a site level.
+ */
+ isEnabled(): boolean {
+ return true;
+ }
+
+ /**
+ * Get the data required to display the module in the course contents view.
+ *
+ * @param {any} module The module object.
+ * @param {number} courseId The course ID.
+ * @param {number} sectionId The section ID.
+ * @return {CoreCourseModuleHandlerData} Data to render the module.
+ */
+ getData(module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData {
+ const handlerData = {
+ icon: this.courseProvider.getModuleIconSrc('url'),
+ title: module.name,
+ class: 'addon-mod_url-handler',
+ showDownloadButton: false,
+ action(event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void {
+ navCtrl.push('AddonModUrlIndexPage', {module: module, courseId: courseId}, options);
+ },
+ buttons: [ {
+ hidden: !(module.contents && module.contents[0] && module.contents[0].fileurl),
+ icon: 'link',
+ label: 'core.openinbrowser',
+ action: (event: Event, navCtrl: NavController, module: any, courseId: number): void => {
+ this.hideLinkButton(module, courseId).then((hide) => {
+ if (!hide) {
+ this.urlProvider.logView(module.instance).then(() => {
+ this.courseProvider.checkModuleCompletion(courseId, module.completionstatus);
+ });
+ this.urlHelper.open(module.contents[0].fileurl);
+ }
+ });
+ }
+ } ]
+ };
+
+ this.hideLinkButton(module, courseId).then((hideButton) => {
+ handlerData.buttons[0].hidden = hideButton;
+ });
+
+ return handlerData;
+ }
+
+ /**
+ * Returns if contents are loaded to show link button.
+ *
+ * @param {any} module The module object.
+ * @param {number} courseId The course ID.
+ * @return {Promise} Resolved when done.
+ */
+ protected hideLinkButton(module: any, courseId: number): Promise {
+ return this.courseProvider.loadModuleContents(module, courseId).then(() => {
+ return !(module.contents && module.contents[0] && module.contents[0].fileurl);
+ });
+ }
+
+ /**
+ * Get the component to render the module. This is needed to support singleactivity course format.
+ * The component returned must implement CoreCourseModuleMainComponent.
+ *
+ * @param {any} course The course object.
+ * @param {any} module The module object.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getMainComponent(course: any, module: any): any {
+ return AddonModUrlIndexComponent;
+ }
+}
diff --git a/src/addon/mod/url/providers/url.ts b/src/addon/mod/url/providers/url.ts
new file mode 100644
index 000000000..2472dccae
--- /dev/null
+++ b/src/addon/mod/url/providers/url.ts
@@ -0,0 +1,146 @@
+// (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 { CoreLoggerProvider } from '@providers/logger';
+import { CoreSitesProvider } from '@providers/sites';
+import { CoreUtilsProvider } from '@providers/utils/utils';
+import { CoreCourseProvider } from '@core/course/providers/course';
+
+/**
+ * Service that provides some features for urls.
+ */
+@Injectable()
+export class AddonModUrlProvider {
+ static COMPONENT = 'mmaModUrl';
+
+ protected ROOT_CACHE_KEY = 'mmaModUrl:';
+ protected logger;
+
+ constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
+ private utils: CoreUtilsProvider) {
+ this.logger = logger.getInstance('AddonModUrlProvider');
+ }
+
+ /**
+ * Get cache key for url data WS calls.
+ *
+ * @param {number} courseId Course ID.
+ * @return {string} Cache key.
+ */
+ protected getUrlCacheKey(courseId: number): string {
+ return this.ROOT_CACHE_KEY + 'url:' + courseId;
+ }
+
+ /**
+ * Get a url data.
+ *
+ * @param {number} courseId Course ID.
+ * @param {string} key Name of the property to check.
+ * @param {any} value Value to search.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved when the url is retrieved.
+ */
+ protected getUrlDataByKey(courseId: number, key: string, value: any, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ const params = {
+ courseids: [courseId]
+ },
+ preSets = {
+ cacheKey: this.getUrlCacheKey(courseId)
+ };
+
+ return site.read('mod_url_get_urls_by_courses', params, preSets).then((response) => {
+ if (response && response.urls) {
+ const currentUrl = response.urls.find((url) => {
+ return url[key] == value;
+ });
+ if (currentUrl) {
+ return currentUrl;
+ }
+ }
+
+ return Promise.reject(null);
+ });
+ });
+ }
+
+ /**
+ * Get a url by course module ID.
+ *
+ * @param {number} courseId Course ID.
+ * @param {number} cmId Course module ID.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved when the url is retrieved.
+ */
+ getUrl(courseId: number, cmId: number, siteId?: string): Promise {
+ return this.getUrlDataByKey(courseId, 'coursemodule', cmId, siteId);
+ }
+
+ /**
+ * Invalidate the prefetched content.
+ *
+ * @param {number} moduleId The module ID.
+ * @param {number} courseId Course ID of the module.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateContent(moduleId: number, courseId: number, siteId?: string): Promise {
+ siteId = siteId || this.sitesProvider.getCurrentSiteId();
+
+ const promises = [];
+
+ promises.push(this.invalidateUrlData(courseId, siteId));
+ promises.push(this.courseProvider.invalidateModule(moduleId, siteId));
+
+ return this.utils.allPromises(promises);
+ }
+
+ /**
+ * Invalidates url data.
+ *
+ * @param {number} courseid Course ID.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateUrlData(courseId: number, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKey(this.getUrlCacheKey(courseId));
+ });
+ }
+
+ /**
+ * Returns whether or not getUrl WS available or not.
+ *
+ * @return {boolean} If WS is abalaible.
+ * @since 3.3
+ */
+ isGetUrlWSAvailable(): boolean {
+ return this.sitesProvider.wsAvailableInCurrentSite('mod_url_get_urls_by_courses');
+ }
+
+ /**
+ * Report the url as being viewed.
+ *
+ * @param {number} id Module ID.
+ * @return {Promise} Promise resolved when the WS call is successful.
+ */
+ logView(id: number): Promise {
+ const params = {
+ urlid: id
+ };
+
+ return this.sitesProvider.getCurrentSite().write('mod_url_view_url', params);
+ }
+}
diff --git a/src/addon/mod/url/url.module.ts b/src/addon/mod/url/url.module.ts
new file mode 100644
index 000000000..3bdbc5912
--- /dev/null
+++ b/src/addon/mod/url/url.module.ts
@@ -0,0 +1,43 @@
+// (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 { NgModule } from '@angular/core';
+import { AddonModUrlComponentsModule } from './components/components.module';
+import { AddonModUrlModuleHandler } from './providers/module-handler';
+import { AddonModUrlProvider } from './providers/url';
+import { AddonModUrlLinkHandler } from './providers/link-handler';
+import { AddonModUrlHelperProvider } from './providers/helper';
+import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate';
+import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
+
+@NgModule({
+ declarations: [
+ ],
+ imports: [
+ AddonModUrlComponentsModule
+ ],
+ providers: [
+ AddonModUrlProvider,
+ AddonModUrlModuleHandler,
+ AddonModUrlHelperProvider,
+ AddonModUrlLinkHandler
+ ]
+})
+export class AddonModUrlModule {
+ constructor(moduleDelegate: CoreCourseModuleDelegate, moduleHandler: AddonModUrlModuleHandler,
+ contentLinksDelegate: CoreContentLinksDelegate, linkHandler: AddonModUrlLinkHandler) {
+ moduleDelegate.registerHandler(moduleHandler);
+ contentLinksDelegate.registerHandler(linkHandler);
+ }
+}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index f5e776ae6..4ac415d9d 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -79,6 +79,7 @@ import { AddonModLabelModule } from '@addon/mod/label/label.module';
import { AddonModResourceModule } from '@addon/mod/resource/resource.module';
import { AddonModFolderModule } from '@addon/mod/folder/folder.module';
import { AddonModPageModule } from '@addon/mod/page/page.module';
+import { AddonModUrlModule } from '@addon/mod/url/url.module';
import { AddonMessagesModule } from '@addon/messages/messages.module';
import { AddonPushNotificationsModule } from '@addon/pushnotifications/pushnotifications.module';
import { AddonRemoteThemesModule } from '@addon/remotethemes/remotethemes.module';
@@ -162,6 +163,7 @@ export const CORE_PROVIDERS: any[] = [
AddonModResourceModule,
AddonModFolderModule,
AddonModPageModule,
+ AddonModUrlModule,
AddonMessagesModule,
AddonPushNotificationsModule,
AddonRemoteThemesModule