diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index dae354861..e2efc6119 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -67,6 +67,7 @@ import { CoreUserModule } from '@core/user/user.module';
import { CoreGradesModule } from '@core/grades/grades.module';
import { CoreSettingsModule } from '@core/settings/settings.module';
import { CoreSiteAddonsModule } from '@core/siteaddons/siteaddons.module';
+import { CoreCompileModule } from '@core/compile/compile.module';
// Addon modules.
import { AddonCalendarModule } from '@addon/calendar/calendar.module';
@@ -146,6 +147,7 @@ export const CORE_PROVIDERS: any[] = [
CoreGradesModule,
CoreSettingsModule,
CoreSiteAddonsModule,
+ CoreCompileModule,
AddonCalendarModule,
AddonUserProfileFieldModule,
AddonFilesModule,
diff --git a/src/components/compile-html/compile-html.ts b/src/components/compile-html/compile-html.ts
deleted file mode 100644
index 14d3fc082..000000000
--- a/src/components/compile-html/compile-html.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-// (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, NgModule, Input, OnInit, OnChanges, OnDestroy, ViewContainerRef, Compiler, ViewChild, ComponentRef, Injector,
- SimpleChange, ChangeDetectorRef
-} from '@angular/core';
-import {
- IonicModule, NavController, Platform, ActionSheetController, AlertController, LoadingController, ModalController,
- PopoverController, ToastController
-} from 'ionic-angular';
-import { TranslateModule, TranslateService } from '@ngx-translate/core';
-import { CoreLoggerProvider } from '../../providers/logger';
-
-// Import all modules that define components, directives and pipes.
-import { CoreComponentsModule } from '../components.module';
-import { CoreDirectivesModule } from '../../directives/directives.module';
-import { CorePipesModule } from '../../pipes/pipes.module';
-import { CoreCourseComponentsModule } from '../../core/course/components/components.module';
-import { CoreCourseDirectivesModule } from '../../core/course/directives/directives.module';
-import { CoreCoursesComponentsModule } from '../../core/courses/components/components.module';
-import { CoreSiteAddonsDirectivesModule } from '../../core/siteaddons/directives/directives.module';
-import { CoreSiteHomeComponentsModule } from '../../core/sitehome/components/components.module';
-import { CoreUserComponentsModule } from '../../core/user/components/components.module';
-
-// Import core providers.
-import { CORE_PROVIDERS } from '../../app/app.module';
-import { CORE_CONTENTLINKS_PROVIDERS } from '../../core/contentlinks/contentlinks.module';
-import { CORE_COURSE_PROVIDERS } from '../../core/course/course.module';
-import { CORE_COURSES_PROVIDERS } from '../../core/courses/courses.module';
-import { CORE_FILEUPLOADER_PROVIDERS } from '../../core/fileuploader/fileuploader.module';
-import { CORE_GRADES_PROVIDERS } from '../../core/grades/grades.module';
-import { CORE_LOGIN_PROVIDERS } from '../../core/login/login.module';
-import { CORE_MAINMENU_PROVIDERS } from '../../core/mainmenu/mainmenu.module';
-import { CORE_SHAREDFILES_PROVIDERS } from '../../core/sharedfiles/sharedfiles.module';
-import { CORE_SITEADDONS_PROVIDERS } from '../../core/siteaddons/siteaddons.module';
-import { CORE_SITEHOME_PROVIDERS } from '../../core/sitehome/sitehome.module';
-import { CORE_USER_PROVIDERS } from '../../core/user/user.module';
-import { IONIC_NATIVE_PROVIDERS } from '../../core/emulator/emulator.module';
-
-// Import other libraries and providers.
-import { DomSanitizer } from '@angular/platform-browser';
-import { FormBuilder, Validators } from '@angular/forms';
-import { Http } from '@angular/http';
-import { HttpClient } from '@angular/common/http';
-import { CoreConfigConstants } from '../../configconstants';
-import { CoreConstants } from '../../core/constants';
-import * as moment from 'moment';
-import { Md5 } from 'ts-md5/dist/md5';
-
-/**
- * This component has a behaviour similar to $compile for AngularJS. Given an HTML code, it will compile it so all its
- * components and directives are instantiated.
- *
- * IMPORTANT: Use this component only if it is a must. It will create and compile a new component and module everytime this
- * component is used, so it can slow down the app.
- *
- * This component isn't part of CoreComponentsModule to prevent circular dependencies. If you want to use it,
- * you need to import CoreCompileHtmlComponentsModule.
- *
- * You can provide some Javascript code (as text) to be executed inside the component. The context of the javascript code (this)
- * will be the component instance created to compile the template. This means your javascript code can interact with the template.
- * The component instance will have most of the providers so you can use them in the javascript code. E.g. if you want to use
- * CoreAppProvider, you can do it with "this.CoreAppProvider".
- */
-@Component({
- selector: 'core-compile-html',
- template: ''
-})
-export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
- // List of imports for dynamic module. Since the template can have any component we need to import all core components modules.
- protected IMPORTS = [
- IonicModule, TranslateModule.forChild(), CoreComponentsModule, CoreDirectivesModule, CorePipesModule,
- CoreCourseComponentsModule, CoreCoursesComponentsModule, CoreSiteHomeComponentsModule, CoreUserComponentsModule,
- CoreCourseDirectivesModule, CoreSiteAddonsDirectivesModule
- ];
-
- // Other Ionic/Angular providers that don't depend on where they are injected.
- protected OTHER_PROVIDERS = [
- TranslateService, Http, HttpClient, Platform, DomSanitizer, ActionSheetController, AlertController, LoadingController,
- ModalController, PopoverController, ToastController, FormBuilder
- ];
-
- @Input() text: string; // The HTML text to display.
- @Input() javascript: string; // The javascript to execute in the component.
-
- // Get the container where to put the content.
- @ViewChild('dynamicComponent', { read: ViewContainerRef }) container: ViewContainerRef;
-
- protected componentRef: ComponentRef;
- protected logger;
-
- constructor(logger: CoreLoggerProvider, protected compiler: Compiler, protected injector: Injector,
- protected cdr: ChangeDetectorRef, protected navCtrl: NavController) {
- this.logger = logger.getInstance('CoreCompileHtmlComponent');
- }
-
- /**
- * Detect changes on input properties.
- */
- ngOnChanges(changes: { [name: string]: SimpleChange }): void {
- if ((changes.text || changes.javascript) && this.text) {
- // Create a new component and a new module.
- const component = this.createComponent(),
- module = NgModule({imports: this.IMPORTS, declarations: [component]})(class {});
-
- // Compile the module and the component.
- this.compiler.compileModuleAndAllComponentsAsync(module).then((factories) => {
- // Search the factory of the component we just created.
- let componentFactory;
- for (const i in factories.componentFactories) {
- const factory = factories.componentFactories[i];
- if (factory.componentType == component) {
- componentFactory = factory;
- break;
- }
- }
-
- // Destroy previous components.
- this.componentRef && this.componentRef.destroy();
-
- // Create the component.
- this.componentRef = this.container.createComponent(componentFactory);
- });
- }
- }
-
- /**
- * Component destroyed.
- */
- ngOnDestroy(): void {
- this.componentRef && this.componentRef.destroy();
- }
-
- /**
- * Create a dynamic component to compile the HTML and run the javascript.
- *
- * @return {any} The component class.
- */
- protected createComponent(): any {
- // tslint:disable: no-this-assignment
- const compileInstance = this,
- providers = ( CORE_PROVIDERS).concat(CORE_CONTENTLINKS_PROVIDERS).concat(CORE_COURSE_PROVIDERS)
- .concat(CORE_COURSES_PROVIDERS).concat(CORE_FILEUPLOADER_PROVIDERS).concat(CORE_GRADES_PROVIDERS)
- .concat(CORE_LOGIN_PROVIDERS).concat(CORE_MAINMENU_PROVIDERS).concat(CORE_SHAREDFILES_PROVIDERS)
- .concat(CORE_SITEHOME_PROVIDERS).concat(CORE_SITEADDONS_PROVIDERS).concat(CORE_USER_PROVIDERS)
- .concat(IONIC_NATIVE_PROVIDERS).concat(this.OTHER_PROVIDERS);
-
- // Create the component, using the text as the template.
- return Component({
- template: this.text
- })
- (class CoreCompileHtmlFakeComponent implements OnInit {
-
- constructor() {
- // We cannot inject anything to this constructor. Use the Injector to inject all the providers into the instance.
- for (const i in providers) {
- const providerDef = providers[i];
- if (typeof providerDef == 'function' && providerDef.name) {
- try {
- // Inject the provider to the instance. We use the class name as the property name.
- this[providerDef.name] = compileInstance.injector.get(providerDef);
- } catch (ex) {
- compileInstance.logger.warn('Error injecting provider', providerDef.name, ex);
- }
- }
- }
-
- // Add some final components and providers.
- this['ChangeDetectorRef'] = compileInstance.cdr;
- this['NavController'] = compileInstance.navCtrl;
- this['Validators'] = Validators;
- this['CoreConfigConstants'] = CoreConfigConstants;
- this['CoreConstants'] = CoreConstants;
- this['moment'] = moment;
- this['Md5'] = Md5;
- this['componentContainer'] = compileInstance.container;
- }
-
- ngOnInit(): void {
- // If there is some javascript to run, do it now.
- if (compileInstance.javascript) {
- // tslint:disable: no-eval
- eval(compileInstance.javascript);
- }
- }
- });
- }
-}
diff --git a/src/core/compile/compile.module.ts b/src/core/compile/compile.module.ts
new file mode 100644
index 000000000..610277494
--- /dev/null
+++ b/src/core/compile/compile.module.ts
@@ -0,0 +1,27 @@
+// (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 { CoreCompileProvider } from './providers/compile';
+
+@NgModule({
+ declarations: [
+ ],
+ imports: [
+ ],
+ providers: [
+ CoreCompileProvider
+ ]
+})
+export class CoreCompileModule { }
diff --git a/src/components/compile-html/compile-html.module.ts b/src/core/compile/components/compile-html/compile-html.module.ts
similarity index 95%
rename from src/components/compile-html/compile-html.module.ts
rename to src/core/compile/components/compile-html/compile-html.module.ts
index 2bd45fc28..84616b2fa 100644
--- a/src/components/compile-html/compile-html.module.ts
+++ b/src/core/compile/components/compile-html/compile-html.module.ts
@@ -27,4 +27,4 @@ import { CoreCompileHtmlComponent } from './compile-html';
CoreCompileHtmlComponent
]
})
-export class CoreCompileHtmlComponentsModule {}
+export class CoreCompileHtmlComponentModule {}
diff --git a/src/core/compile/components/compile-html/compile-html.ts b/src/core/compile/components/compile-html/compile-html.ts
new file mode 100644
index 000000000..8253e2a92
--- /dev/null
+++ b/src/core/compile/components/compile-html/compile-html.ts
@@ -0,0 +1,150 @@
+// (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, NgModule, Input, OnInit, OnChanges, OnDestroy, ViewContainerRef, Compiler, ViewChild, ComponentRef,
+ SimpleChange, ChangeDetectorRef
+} from '@angular/core';
+import { IonicModule, NavController } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreCompileProvider } from '../../../compile/providers/compile';
+
+// Import all modules that define components, directives and pipes.
+import { CoreComponentsModule } from '../../../../components/components.module';
+import { CoreDirectivesModule } from '../../../../directives/directives.module';
+import { CorePipesModule } from '../../../../pipes/pipes.module';
+import { CoreCourseComponentsModule } from '../../../course/components/components.module';
+import { CoreCourseDirectivesModule } from '../../../course/directives/directives.module';
+import { CoreCoursesComponentsModule } from '../../../courses/components/components.module';
+import { CoreSiteAddonsDirectivesModule } from '../../../siteaddons/directives/directives.module';
+import { CoreSiteHomeComponentsModule } from '../../../sitehome/components/components.module';
+import { CoreUserComponentsModule } from '../../../user/components/components.module';
+
+/**
+ * This component has a behaviour similar to $compile for AngularJS. Given an HTML code, it will compile it so all its
+ * components and directives are instantiated.
+ *
+ * IMPORTANT: Use this component only if it is a must. It will create and compile a new component and module everytime this
+ * component is used, so it can slow down the app.
+ *
+ * This component has its own module to prevent circular dependencies. If you want to use it,
+ * you need to import CoreCompileHtmlComponentModule.
+ *
+ * You can provide some Javascript code (as text) to be executed inside the component. The context of the javascript code (this)
+ * will be the component instance created to compile the template. This means your javascript code can interact with the template.
+ * The component instance will have most of the providers so you can use them in the javascript code. E.g. if you want to use
+ * CoreAppProvider, you can do it with "this.CoreAppProvider".
+ */
+@Component({
+ selector: 'core-compile-html',
+ template: ''
+})
+export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
+ // List of imports for dynamic module. Since the template can have any component we need to import all core components modules.
+ protected IMPORTS = [
+ IonicModule, TranslateModule.forChild(), CoreComponentsModule, CoreDirectivesModule, CorePipesModule,
+ CoreCourseComponentsModule, CoreCoursesComponentsModule, CoreSiteHomeComponentsModule, CoreUserComponentsModule,
+ CoreCourseDirectivesModule, CoreSiteAddonsDirectivesModule
+ ];
+
+ @Input() text: string; // The HTML text to display.
+ @Input() javascript: string; // The Javascript to execute in the component.
+ @Input() jsData; // Data to pass to the fake component.
+
+ // Get the container where to put the content.
+ @ViewChild('dynamicComponent', { read: ViewContainerRef }) container: ViewContainerRef;
+
+ protected componentRef: ComponentRef;
+
+ constructor(protected compileProvider: CoreCompileProvider, protected compiler: Compiler,
+ protected cdr: ChangeDetectorRef, protected navCtrl: NavController) { }
+
+ /**
+ * Detect changes on input properties.
+ */
+ ngOnChanges(changes: { [name: string]: SimpleChange }): void {
+ if ((changes.text || changes.javascript) && this.text) {
+ // Create a new component and a new module.
+ const component = this.createComponent(),
+ module = NgModule({imports: this.IMPORTS, declarations: [component]})(class {});
+
+ // Compile the module and the component.
+ this.compiler.compileModuleAndAllComponentsAsync(module).then((factories) => {
+ // Search the factory of the component we just created.
+ let componentFactory;
+ for (const i in factories.componentFactories) {
+ const factory = factories.componentFactories[i];
+ if (factory.componentType == component) {
+ componentFactory = factory;
+ break;
+ }
+ }
+
+ // Destroy previous components.
+ this.componentRef && this.componentRef.destroy();
+
+ // Create the component.
+ this.componentRef = this.container.createComponent(componentFactory);
+ });
+ }
+ }
+
+ /**
+ * Component destroyed.
+ */
+ ngOnDestroy(): void {
+ this.componentRef && this.componentRef.destroy();
+ }
+
+ /**
+ * Create a dynamic component to compile the HTML and run the javascript.
+ *
+ * @return {any} The component class.
+ */
+ protected createComponent(): any {
+ // tslint:disable: no-this-assignment
+ const compileInstance = this;
+
+ // Create the component, using the text as the template.
+ return Component({
+ template: this.text
+ })
+ (class CoreCompileHtmlFakeComponent implements OnInit {
+
+ constructor() {
+ // If there is some javascript to run, prepare the instance.
+ if (compileInstance.javascript) {
+ compileInstance.compileProvider.injectLibraries(this);
+
+ // Add some more components and classes.
+ this['ChangeDetectorRef'] = compileInstance.cdr;
+ this['NavController'] = compileInstance.navCtrl;
+ this['componentContainer'] = compileInstance.container;
+
+ // Add the data passed to the component.
+ for (const name in compileInstance.jsData) {
+ this[name] = compileInstance.jsData[name];
+ }
+ }
+ }
+
+ ngOnInit(): void {
+ // If there is some javascript to run, do it now.
+ if (compileInstance.javascript) {
+ compileInstance.compileProvider.executeJavascript(this, compileInstance.javascript);
+ }
+ }
+ });
+ }
+}
diff --git a/src/core/compile/providers/compile.ts b/src/core/compile/providers/compile.ts
new file mode 100644
index 000000000..25738aa15
--- /dev/null
+++ b/src/core/compile/providers/compile.ts
@@ -0,0 +1,142 @@
+// (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, Injector } from '@angular/core';
+import {
+ Platform, ActionSheetController, AlertController, LoadingController, ModalController, PopoverController, ToastController
+} from 'ionic-angular';
+import { TranslateService } from '@ngx-translate/core';
+import { CoreLoggerProvider } from '../../../providers/logger';
+
+// Import core providers.
+import { CORE_PROVIDERS } from '../../../app/app.module';
+import { CORE_CONTENTLINKS_PROVIDERS } from '../../contentlinks/contentlinks.module';
+import { CORE_COURSE_PROVIDERS } from '../../course/course.module';
+import { CORE_COURSES_PROVIDERS } from '../../courses/courses.module';
+import { CORE_FILEUPLOADER_PROVIDERS } from '../../fileuploader/fileuploader.module';
+import { CORE_GRADES_PROVIDERS } from '../../grades/grades.module';
+import { CORE_LOGIN_PROVIDERS } from '../../login/login.module';
+import { CORE_MAINMENU_PROVIDERS } from '../../mainmenu/mainmenu.module';
+import { CORE_SHAREDFILES_PROVIDERS } from '../../sharedfiles/sharedfiles.module';
+import { CORE_SITEHOME_PROVIDERS } from '../../sitehome/sitehome.module';
+import { CORE_USER_PROVIDERS } from '../../user/user.module';
+import { IONIC_NATIVE_PROVIDERS } from '../../emulator/emulator.module';
+
+// Import only this provider to prevent circular dependencies.
+import { CoreSiteAddonsProvider } from '../../siteaddons/providers/siteaddons';
+
+// Import other libraries and providers.
+import { DomSanitizer } from '@angular/platform-browser';
+import { FormBuilder, Validators } from '@angular/forms';
+import { Http } from '@angular/http';
+import { HttpClient } from '@angular/common/http';
+import { CoreConfigConstants } from '../../../configconstants';
+import { CoreConstants } from '../../constants';
+import * as moment from 'moment';
+import { Md5 } from 'ts-md5/dist/md5';
+
+// Import core classes that can be useful for site addons.
+import { CoreSyncBaseProvider } from '../../../classes/base-sync';
+import { CoreCache } from '../../../classes/cache';
+import { CoreDelegate } from '../../../classes/delegate';
+import { CoreContentLinksHandlerBase } from '../../contentlinks/classes/base-handler';
+import { CoreContentLinksModuleGradeHandler } from '../../contentlinks/classes/module-grade-handler';
+import { CoreContentLinksModuleIndexHandler } from '../../contentlinks/classes/module-index-handler';
+import { CoreCourseModulePrefetchHandlerBase } from '../../course/classes/module-prefetch-handler';
+
+/**
+ * Service to provide functionalities regarding compiling dynamic HTML and Javascript.
+ */
+@Injectable()
+export class CoreCompileProvider {
+
+ protected logger;
+
+ // Other Ionic/Angular providers that don't depend on where they are injected.
+ protected OTHER_PROVIDERS = [
+ TranslateService, Http, HttpClient, Platform, DomSanitizer, ActionSheetController, AlertController, LoadingController,
+ ModalController, PopoverController, ToastController, FormBuilder
+ ];
+
+ constructor(protected injector: Injector, logger: CoreLoggerProvider) {
+ this.logger = logger.getInstance('CoreCompileProvider');
+ }
+
+ /**
+ * Eval some javascript using the context of the function.
+ *
+ * @param {string} javascript The javascript to eval.
+ * @return {any} Result of the eval.
+ */
+ protected evalInContext(javascript: string): any {
+ // tslint:disable: no-eval
+ return eval(javascript);
+ }
+
+ /**
+ * Execute some javascript code, using a certain instance as the context.
+ *
+ * @param {any} instance Instance to use as the context. In the JS code, "this" will be this instance.
+ * @param {string} javascript The javascript code to eval.
+ * @return {any} Result of the javascript execution.
+ */
+ executeJavascript(instance: any, javascript: string): any {
+ try {
+ return this.evalInContext.call(instance, javascript);
+ } catch (ex) {
+ this.logger.error('Error evaluating javascript', ex);
+ }
+ }
+
+ /**
+ * Inject all the core libraries in a certain object.
+ *
+ * @param {any} instance The instance where to inject the libraries.
+ */
+ injectLibraries(instance: any): void {
+ const providers = ( CORE_PROVIDERS).concat(CORE_CONTENTLINKS_PROVIDERS).concat(CORE_COURSE_PROVIDERS)
+ .concat(CORE_COURSES_PROVIDERS).concat(CORE_FILEUPLOADER_PROVIDERS).concat(CORE_GRADES_PROVIDERS)
+ .concat(CORE_LOGIN_PROVIDERS).concat(CORE_MAINMENU_PROVIDERS).concat(CORE_SHAREDFILES_PROVIDERS)
+ .concat(CORE_SITEHOME_PROVIDERS).concat([CoreSiteAddonsProvider]).concat(CORE_USER_PROVIDERS)
+ .concat(IONIC_NATIVE_PROVIDERS).concat(this.OTHER_PROVIDERS);
+
+ // We cannot inject anything to this constructor. Use the Injector to inject all the providers into the instance.
+ for (const i in providers) {
+ const providerDef = providers[i];
+ if (typeof providerDef == 'function' && providerDef.name) {
+ try {
+ // Inject the provider to the instance. We use the class name as the property name.
+ instance[providerDef.name] = this.injector.get(providerDef);
+ } catch (ex) {
+ this.logger.warn('Error injecting provider', providerDef.name, ex);
+ }
+ }
+ }
+
+ // Add some final classes.
+ instance['injector'] = this.injector;
+ instance['Validators'] = Validators;
+ instance['CoreConfigConstants'] = CoreConfigConstants;
+ instance['CoreConstants'] = CoreConstants;
+ instance['moment'] = moment;
+ instance['Md5'] = Md5;
+ instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider;
+ instance['CoreCache'] = CoreCache;
+ instance['CoreDelegate'] = CoreDelegate;
+ instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase;
+ instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
+ instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;
+ instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase;
+ }
+}
diff --git a/src/core/siteaddons/components/addon-content/addon-content.html b/src/core/siteaddons/components/addon-content/addon-content.html
index 3fb4aac18..6eb252ed4 100644
--- a/src/core/siteaddons/components/addon-content/addon-content.html
+++ b/src/core/siteaddons/components/addon-content/addon-content.html
@@ -1,3 +1,3 @@
-
+
diff --git a/src/core/siteaddons/components/addon-content/addon-content.ts b/src/core/siteaddons/components/addon-content/addon-content.ts
index f7e506d0a..32db323e0 100644
--- a/src/core/siteaddons/components/addon-content/addon-content.ts
+++ b/src/core/siteaddons/components/addon-content/addon-content.ts
@@ -28,6 +28,7 @@ export class CoreSiteAddonsAddonContentComponent implements OnInit {
@Input() component: string;
@Input() method: string;
@Input() args: any;
+ @Input() bootstrapResult: any; // Result of the bootstrap JS of the handler.
@Output() onContentLoaded?: EventEmitter; // Emits an event when the content is loaded.
@Output() onLoadingContent?: EventEmitter; // Emits an event when starts to load the content.
diff --git a/src/core/siteaddons/components/components.module.ts b/src/core/siteaddons/components/components.module.ts
index 5b7747e16..200e8be8f 100644
--- a/src/core/siteaddons/components/components.module.ts
+++ b/src/core/siteaddons/components/components.module.ts
@@ -17,7 +17,7 @@ import { CommonModule } from '@angular/common';
import { IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '../../../components/components.module';
-import { CoreCompileHtmlComponentsModule } from '../../../components/compile-html/compile-html.module';
+import { CoreCompileHtmlComponentModule } from '../../compile/components/compile-html/compile-html.module';
import { CoreSiteAddonsAddonContentComponent } from './addon-content/addon-content';
import { CoreSiteAddonsModuleIndexComponent } from './module-index/module-index';
@@ -30,7 +30,7 @@ import { CoreSiteAddonsModuleIndexComponent } from './module-index/module-index'
CommonModule,
IonicModule,
CoreComponentsModule,
- CoreCompileHtmlComponentsModule,
+ CoreCompileHtmlComponentModule,
TranslateModule.forChild()
],
providers: [
diff --git a/src/core/siteaddons/components/module-index/module-index.html b/src/core/siteaddons/components/module-index/module-index.html
index 6e6ef1862..d2078263f 100644
--- a/src/core/siteaddons/components/module-index/module-index.html
+++ b/src/core/siteaddons/components/module-index/module-index.html
@@ -9,4 +9,4 @@
-
+
diff --git a/src/core/siteaddons/components/module-index/module-index.ts b/src/core/siteaddons/components/module-index/module-index.ts
index 19220cdd5..256390380 100644
--- a/src/core/siteaddons/components/module-index/module-index.ts
+++ b/src/core/siteaddons/components/module-index/module-index.ts
@@ -37,6 +37,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
component: string;
method: string;
args: any;
+ bootstrapResult: any;
// Data for context menu.
externalUrl: string;
@@ -60,7 +61,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
this.refreshIcon = 'spinner';
if (this.module) {
- const handler = this.siteAddonsProvider.getModuleSiteAddonHandler(this.module.modname);
+ const handler = this.siteAddonsProvider.getSiteAddonHandler(this.module.modname);
if (handler) {
this.component = handler.addon.component;
this.method = handler.handlerSchema.method;
@@ -68,6 +69,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
courseid: this.courseId,
cmid: this.module.id
};
+ this.bootstrapResult = handler.bootstrapResult;
}
// Get the data for the context menu.
diff --git a/src/core/siteaddons/directives/call-ws-new-content.ts b/src/core/siteaddons/directives/call-ws-new-content.ts
index 38d2cd145..cf23d59f0 100644
--- a/src/core/siteaddons/directives/call-ws-new-content.ts
+++ b/src/core/siteaddons/directives/call-ws-new-content.ts
@@ -91,7 +91,8 @@ export class CoreSiteAddonsCallWSNewContentDirective extends CoreSiteAddonsCallW
title: this.title,
component: this.component,
method: this.method,
- args: args
+ args: args,
+ bootstrapResult: this.parentContent && this.parentContent.bootstrapResult
});
}
}
diff --git a/src/core/siteaddons/directives/new-content.ts b/src/core/siteaddons/directives/new-content.ts
index 4db053f85..a31920aa5 100644
--- a/src/core/siteaddons/directives/new-content.ts
+++ b/src/core/siteaddons/directives/new-content.ts
@@ -88,7 +88,8 @@ export class CoreSiteAddonsNewContentDirective implements OnInit {
title: this.title,
component: this.component,
method: this.method,
- args: args
+ args: args,
+ bootstrapResult: this.parentContent && this.parentContent.bootstrapResult
});
}
});
diff --git a/src/core/siteaddons/pages/addon-page/addon-page.html b/src/core/siteaddons/pages/addon-page/addon-page.html
index 16b323097..c2a75a760 100644
--- a/src/core/siteaddons/pages/addon-page/addon-page.html
+++ b/src/core/siteaddons/pages/addon-page/addon-page.html
@@ -11,5 +11,5 @@
-
+
diff --git a/src/core/siteaddons/pages/addon-page/addon-page.ts b/src/core/siteaddons/pages/addon-page/addon-page.ts
index 772c4dc91..714e50c74 100644
--- a/src/core/siteaddons/pages/addon-page/addon-page.ts
+++ b/src/core/siteaddons/pages/addon-page/addon-page.ts
@@ -32,12 +32,14 @@ export class CoreSiteAddonsAddonPage {
component: string;
method: string;
args: any;
+ bootstrapResult: any;
constructor(params: NavParams) {
this.title = params.get('title');
this.component = params.get('component');
this.method = params.get('method');
this.args = params.get('args');
+ this.bootstrapResult = params.get('bootstrapResult');
}
/**
diff --git a/src/core/siteaddons/providers/helper.ts b/src/core/siteaddons/providers/helper.ts
index 65d89d0b0..17431668a 100644
--- a/src/core/siteaddons/providers/helper.ts
+++ b/src/core/siteaddons/providers/helper.ts
@@ -18,16 +18,18 @@ import { CoreLangProvider } from '../../../providers/lang';
import { CoreLoggerProvider } from '../../../providers/logger';
import { CoreSite } from '../../../classes/site';
import { CoreSitesProvider } from '../../../providers/sites';
-import { CoreMainMenuDelegate, CoreMainMenuHandler, CoreMainMenuHandlerData } from '../../../core/mainmenu/providers/delegate';
+import { CoreUtilsProvider } from '../../../providers/utils/utils';
+import { CoreMainMenuDelegate, CoreMainMenuHandler, CoreMainMenuHandlerData } from '../../mainmenu/providers/delegate';
import {
CoreCourseModuleDelegate, CoreCourseModuleHandler, CoreCourseModuleHandlerData
-} from '../../../core/course/providers/module-delegate';
-import { CoreCourseModulePrefetchDelegate } from '../../../core/course/providers/module-prefetch-delegate';
-import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../../core/user/providers/user-delegate';
+} from '../../course/providers/module-delegate';
+import { CoreCourseModulePrefetchDelegate } from '../../course/providers/module-prefetch-delegate';
+import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../user/providers/user-delegate';
import { CoreDelegateHandler } from '../../../classes/delegate';
import { CoreSiteAddonsModuleIndexComponent } from '../components/module-index/module-index';
import { CoreSiteAddonsProvider } from './siteaddons';
import { CoreSiteAddonsModulePrefetchHandler } from '../classes/module-prefetch-handler';
+import { CoreCompileProvider } from '../../compile/providers/compile';
/**
* Helper service to provide functionalities regarding site addons. It basically has the features to load and register site
@@ -42,10 +44,42 @@ export class CoreSiteAddonsHelperProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector,
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider,
- private siteAddonsProvider: CoreSiteAddonsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate) {
+ private siteAddonsProvider: CoreSiteAddonsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate,
+ private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider) {
this.logger = logger.getInstance('CoreSiteAddonsHelperProvider');
}
+ /**
+ * Bootstrap a handler if it has some bootstrap JS.
+ *
+ * @param {any} addon Data of the addon.
+ * @param {string} handlerName Name of the handler in the addon.
+ * @param {any} handlerSchema Data about the handler.
+ * @return {Promise} Promise resolved when done. The resolve param is the result of the javascript execution (if any).
+ */
+ protected bootstrapHandler(addon: any, handlerName: string, handlerSchema: any): Promise {
+ if (!handlerSchema.bootstrap) {
+ return Promise.resolve();
+ }
+
+ const siteId = this.sitesProvider.getCurrentSiteId(),
+ preSets = {getFromCache: false}; // Try to ignore cache.
+
+ return this.siteAddonsProvider.getContent(addon.component, handlerSchema.bootstrap, {}, preSets).then((result) => {
+ if (!result.javascript || this.sitesProvider.getCurrentSiteId() != siteId) {
+ // No javascript or site has changed, stop.
+ return;
+ }
+
+ // Create a "fake" instance to hold all the libraries.
+ const instance = {};
+ this.compileProvider.injectLibraries(instance);
+
+ // Now execute the javascript using this instance.
+ return this.compileProvider.executeJavascript(instance, result.javascript);
+ });
+ }
+
/**
* Create a base handler for a site addon.
*
@@ -86,17 +120,6 @@ export class CoreSiteAddonsHelperProvider {
return this.getHandlerPrefixForStrings(handlerName) + key;
}
- /**
- * Get the unique name of a handler (addon + handler).
- *
- * @param {any} addon Data of the addon.
- * @param {string} handlerName Name of the handler inside the addon.
- * @return {string} Unique name.
- */
- protected getHandlerUniqueName(addon: any, handlerName: string): string {
- return addon.addon + '_' + handlerName;
- }
-
/**
* Check if a certain addon is a site addon and it's enabled in a certain site.
*
@@ -134,7 +157,7 @@ export class CoreSiteAddonsHelperProvider {
}
for (const lang in handlerSchema.lang) {
- const prefix = this.getHandlerPrefixForStrings(this.getHandlerUniqueName(addon, handlerName));
+ const prefix = this.getHandlerPrefixForStrings(this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName));
this.langProvider.addSiteAddonsStrings(lang, handlerSchema.lang[lang], prefix);
}
@@ -144,8 +167,11 @@ export class CoreSiteAddonsHelperProvider {
* Load a site addon.
*
* @param {any} addon Data of the addon.
+ * @return {Promise} Promise resolved when loaded.
*/
- loadSiteAddon(addon: any): void {
+ loadSiteAddon(addon: any): Promise {
+ const promises = [];
+
try {
if (!addon.parsedHandlers) {
addon.parsedHandlers = JSON.parse(addon.handlers);
@@ -153,11 +179,13 @@ export class CoreSiteAddonsHelperProvider {
// Register all the handlers.
for (const name in addon.parsedHandlers) {
- this.registerHandler(addon, name, addon.parsedHandlers[name]);
+ promises.push(this.registerHandler(addon, name, addon.parsedHandlers[name]));
}
} catch (ex) {
this.logger.warn('Error parsing site addon', ex);
}
+
+ return this.utils.allPromises(promises);
}
/**
@@ -166,26 +194,42 @@ export class CoreSiteAddonsHelperProvider {
* @param {any} addon Data of the addon.
* @param {string} handlerName Name of the handler in the addon.
* @param {any} handlerSchema Data about the handler.
+ * @return {Promise} Promise resolved when done.
*/
- registerHandler(addon: any, handlerName: string, handlerSchema: any): void {
+ registerHandler(addon: any, handlerName: string, handlerSchema: any): Promise {
this.loadHandlerLangStrings(addon, handlerName, handlerSchema);
- switch (handlerSchema.delegate) {
- case 'CoreMainMenuDelegate':
- this.registerMainMenuHandler(addon, handlerName, handlerSchema);
- break;
+ // Wait for the bootstrap JS to be executed.
+ return this.bootstrapHandler(addon, handlerName, handlerSchema).then((result) => {
+ let uniqueName;
- case 'CoreCourseModuleDelegate':
- this.registerModuleHandler(addon, handlerName, handlerSchema);
- break;
+ switch (handlerSchema.delegate) {
+ case 'CoreMainMenuDelegate':
+ uniqueName = this.registerMainMenuHandler(addon, handlerName, handlerSchema, result);
+ break;
- case 'CoreUserDelegate':
- this.registerUserProfileHandler(addon, handlerName, handlerSchema);
- break;
+ case 'CoreCourseModuleDelegate':
+ uniqueName = this.registerModuleHandler(addon, handlerName, handlerSchema, result);
+ break;
- default:
- // Nothing to do.
- }
+ case 'CoreUserDelegate':
+ uniqueName = this.registerUserProfileHandler(addon, handlerName, handlerSchema, result);
+ break;
+
+ default:
+ // Nothing to do.
+ }
+
+ if (uniqueName) {
+ // Store the handler data.
+ this.siteAddonsProvider.setSiteAddonHandler(uniqueName, {
+ addon: addon,
+ handlerName: handlerName,
+ handlerSchema: handlerSchema,
+ bootstrapResult: result
+ });
+ }
+ });
}
/**
@@ -194,15 +238,18 @@ export class CoreSiteAddonsHelperProvider {
* @param {any} addon Data of the addon.
* @param {string} handlerName Name of the handler in the addon.
* @param {any} handlerSchema Data about the handler.
+ * @param {any} [bootstrapResult] Result of executing the bootstrap JS.
+ * @return {string} A string to identify the handler.
*/
- protected registerMainMenuHandler(addon: any, handlerName: string, handlerSchema: any): void {
+ protected registerMainMenuHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult?: any): string {
if (!handlerSchema || !handlerSchema.displaydata) {
// Required data not provided, stop.
return;
}
// Create the base handler.
- const baseHandler = this.getBaseHandler(this.getHandlerUniqueName(addon, handlerName)),
+ const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName),
+ baseHandler = this.getBaseHandler(uniqueName),
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
let mainMenuHandler: CoreMainMenuHandler;
@@ -219,12 +266,15 @@ export class CoreSiteAddonsHelperProvider {
title: prefixedTitle,
component: addon.component,
method: handlerSchema.method,
+ bootstrapResult: bootstrapResult
}
};
}
});
this.mainMenuDelegate.registerHandler(mainMenuHandler);
+
+ return uniqueName;
}
/**
@@ -233,8 +283,10 @@ export class CoreSiteAddonsHelperProvider {
* @param {any} addon Data of the addon.
* @param {string} handlerName Name of the handler in the addon.
* @param {any} handlerSchema Data about the handler.
+ * @param {any} [bootstrapResult] Result of executing the bootstrap JS.
+ * @return {string} A string to identify the handler.
*/
- protected registerModuleHandler(addon: any, handlerName: string, handlerSchema: any): void {
+ protected registerModuleHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult?: any): string {
if (!handlerSchema || !handlerSchema.displaydata) {
// Required data not provided, stop.
return;
@@ -243,16 +295,10 @@ export class CoreSiteAddonsHelperProvider {
// Create the base handler.
const modName = addon.component.replace('mod_', ''),
baseHandler = this.getBaseHandler(modName),
- hasOfflineFunctions = !!(handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length);
+ hasOfflineFunctions = !!(handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length),
+ showDowloadButton = handlerSchema.downloadbutton;
let moduleHandler: CoreCourseModuleHandler;
- // Store the handler data.
- this.siteAddonsProvider.setModuleSiteAddonHandler(modName, {
- addon: addon,
- handlerName: handlerName,
- handlerSchema: handlerSchema
- });
-
// Extend the base handler, adding the properties required by the delegate.
moduleHandler = Object.assign(baseHandler, {
getData: (module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData => {
@@ -260,7 +306,7 @@ export class CoreSiteAddonsHelperProvider {
title: module.name,
icon: handlerSchema.displaydata.icon,
class: handlerSchema.displaydata.class,
- showDownloadButton: hasOfflineFunctions,
+ showDownloadButton: typeof showDowloadButton != 'undefined' ? showDowloadButton : hasOfflineFunctions,
action: (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void => {
event.preventDefault();
event.stopPropagation();
@@ -285,6 +331,8 @@ export class CoreSiteAddonsHelperProvider {
}
this.moduleDelegate.registerHandler(moduleHandler);
+
+ return modName;
}
/**
@@ -293,15 +341,18 @@ export class CoreSiteAddonsHelperProvider {
* @param {any} addon Data of the addon.
* @param {string} handlerName Name of the handler in the addon.
* @param {any} handlerSchema Data about the handler.
+ * @param {any} [bootstrapResult] Result of executing the bootstrap JS.
+ * @return {string} A string to identify the handler.
*/
- protected registerUserProfileHandler(addon: any, handlerName: string, handlerSchema: any): void {
+ protected registerUserProfileHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult?: any): string {
if (!handlerSchema || !handlerSchema.displaydata) {
// Required data not provided, stop.
return;
}
// Create the base handler.
- const baseHandler = this.getBaseHandler(this.getHandlerUniqueName(addon, handlerName)),
+ const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName),
+ baseHandler = this.getBaseHandler(uniqueName),
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
let userHandler: CoreUserProfileHandler;
@@ -332,7 +383,8 @@ export class CoreSiteAddonsHelperProvider {
args: {
courseid: courseId,
userid: user.id
- }
+ },
+ bootstrapResult: bootstrapResult
});
}
};
@@ -340,5 +392,7 @@ export class CoreSiteAddonsHelperProvider {
});
this.userDelegate.registerHandler(userHandler);
+
+ return uniqueName;
}
}
diff --git a/src/core/siteaddons/providers/siteaddons.ts b/src/core/siteaddons/providers/siteaddons.ts
index 489f3eca7..662fb7da7 100644
--- a/src/core/siteaddons/providers/siteaddons.ts
+++ b/src/core/siteaddons/providers/siteaddons.ts
@@ -23,9 +23,9 @@ import { CoreUtilsProvider } from '../../../providers/utils/utils';
import { CoreConfigConstants } from '../../../configconstants';
/**
- * Handler of a site addon representing a module.
+ * Handler of a site addon.
*/
-export interface CoreSiteAddonsModuleHandler {
+export interface CoreSiteAddonsHandler {
/**
* The site addon data.
* @type {any}
@@ -43,6 +43,12 @@ export interface CoreSiteAddonsModuleHandler {
* @type {any}
*/
handlerSchema: any;
+
+ /**
+ * Result of executing the bootstrap JS.
+ * @type {any}
+ */
+ bootstrapResult?: any;
}
export interface CoreSiteAddonsGetContentResult {
@@ -79,7 +85,7 @@ export class CoreSiteAddonsProvider {
protected ROOT_CACHE_KEY = 'CoreSiteAddons:';
protected logger;
- protected moduleSiteAddons: {[modName: string]: CoreSiteAddonsModuleHandler} = {};
+ protected siteAddons: {[name: string]: CoreSiteAddonsHandler} = {}; // Site addons registered.
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
private langProvider: CoreLangProvider, private appProvider: CoreAppProvider, private platform: Platform) {
@@ -179,10 +185,12 @@ export class CoreSiteAddonsProvider {
* @param {string} component Component where the class is. E.g. mod_assign.
* @param {string} method Method to execute in the class.
* @param {any} args The params for the method.
+ * @param {CoreSiteWSPreSets} [preSets] Extra options.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise} Promise resolved with the result.
*/
- getContent(component: string, method: string, args: any, siteId?: string): Promise {
+ getContent(component: string, method: string, args: any, preSets?: CoreSiteWSPreSets, siteId?: string)
+ : Promise {
this.logger.debug(`Get content for component '${component}' and method '${method}'`);
return this.sitesProvider.getSite(siteId).then((site) => {
@@ -194,10 +202,11 @@ export class CoreSiteAddonsProvider {
component: component,
method: method,
args: this.utils.objectToArrayOfObjects(argsToSend, 'name', 'value', true)
- }, preSets = {
- cacheKey: this.getContentCacheKey(component, method, args)
};
+ preSets = preSets || {};
+ preSets.cacheKey = this.getContentCacheKey(component, method, args);
+
return this.sitesProvider.getCurrentSite().read('tool_mobile_get_content', data, preSets);
}).then((result) => {
if (result.otherdata) {
@@ -226,13 +235,24 @@ export class CoreSiteAddonsProvider {
}
/**
- * Get the site addon handler for a certain module.
+ * Get the unique name of a handler (addon + handler).
*
- * @param {string} modName Name of the module.
- * @return {CoreSiteAddonsModuleHandler} Handler.
+ * @param {any} addon Data of the addon.
+ * @param {string} handlerName Name of the handler inside the addon.
+ * @return {string} Unique name.
*/
- getModuleSiteAddonHandler(modName: string): CoreSiteAddonsModuleHandler {
- return this.moduleSiteAddons[modName];
+ getHandlerUniqueName(addon: any, handlerName: string): string {
+ return addon.addon + '_' + handlerName;
+ }
+
+ /**
+ * Get a site addon handler.
+ *
+ * @param {string} name Unique name of the handler.
+ * @return {CoreSiteAddonsHandler} Handler.
+ */
+ getSiteAddonHandler(name: string): CoreSiteAddonsHandler {
+ return this.siteAddons[name];
}
/**
@@ -328,12 +348,12 @@ export class CoreSiteAddonsProvider {
}
/**
- * Set the site addon handler for a certain module.
+ * Store a site addon handler.
*
- * @param {string} modName Name of the module.
- * @param {CoreSiteAddonsModuleHandler} handler Handler to set.
+ * @param {string} name A unique name to identify the handler.
+ * @param {CoreSiteAddonsHandler} handler Handler to set.
*/
- setModuleSiteAddonHandler(modName: string, handler: CoreSiteAddonsModuleHandler): void {
- this.moduleSiteAddons[modName] = handler;
+ setSiteAddonHandler(name: string, handler: CoreSiteAddonsHandler): void {
+ this.siteAddons[name] = handler;
}
}
diff --git a/src/core/siteaddons/siteaddons.module.ts b/src/core/siteaddons/siteaddons.module.ts
index 053905ad3..132e0d809 100644
--- a/src/core/siteaddons/siteaddons.module.ts
+++ b/src/core/siteaddons/siteaddons.module.ts
@@ -13,7 +13,6 @@
// limitations under the License.
import { NgModule } from '@angular/core';
-import { Platform } from 'ionic-angular';
import { CoreSiteAddonsProvider } from './providers/siteaddons';
import { CoreSiteAddonsHelperProvider } from './providers/helper';
import { CoreSiteAddonsComponentsModule } from './components/components.module';
diff --git a/src/providers/addonmanager.ts b/src/providers/addonmanager.ts
index 53e5092f1..c03d74420 100644
--- a/src/providers/addonmanager.ts
+++ b/src/providers/addonmanager.ts
@@ -17,6 +17,7 @@ import { CoreEventsProvider } from './events';
import { CoreLoggerProvider } from './logger';
import { CoreSitesProvider } from './sites';
import { CoreSiteWSPreSets } from '../classes/site';
+import { CoreUtilsProvider } from './utils/utils';
import { CoreSiteAddonsProvider } from '../core/siteaddons/providers/siteaddons';
import { CoreSiteAddonsHelperProvider } from '../core/siteaddons/providers/helper';
@@ -29,7 +30,8 @@ export class CoreAddonManagerProvider {
protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider,
- private siteAddonsProvider: CoreSiteAddonsProvider, private siteAddonsHelperProvider: CoreSiteAddonsHelperProvider) {
+ private siteAddonsProvider: CoreSiteAddonsProvider, private siteAddonsHelperProvider: CoreSiteAddonsHelperProvider,
+ private utils: CoreUtilsProvider) {
logger = logger.getInstance('CoreAddonManagerProvider');
// Fetch the addons on login.
@@ -39,9 +41,10 @@ export class CoreAddonManagerProvider {
// Addons fetched, check that site hasn't changed.
if (siteId == this.sitesProvider.getCurrentSiteId() && addons.length) {
// Site is still the same. Load the addons and trigger the event.
- this.loadSiteAddons(addons);
+ this.loadSiteAddons(addons).then(() => {
+ eventsProvider.trigger(CoreEventsProvider.SITE_ADDONS_LOADED, {}, siteId);
+ });
- eventsProvider.trigger(CoreEventsProvider.SITE_ADDONS_LOADED, {}, siteId);
}
});
});
@@ -85,10 +88,15 @@ export class CoreAddonManagerProvider {
* Load site addons.
*
* @param {any[]} addons The addons to load.
+ * @return {Promise} Promise resolved when loaded.
*/
- loadSiteAddons(addons: any[]): void {
+ loadSiteAddons(addons: any[]): Promise {
+ const promises = [];
+
addons.forEach((addon) => {
- this.siteAddonsHelperProvider.loadSiteAddon(addon);
+ promises.push(this.siteAddonsHelperProvider.loadSiteAddon(addon));
});
+
+ return this.utils.allPromises(promises);
}
}