MOBILE-2333 siteaddons: Run bootstrap JS and pass result to content JS
parent
823ea35b69
commit
8e87a1ade9
|
@ -67,6 +67,7 @@ import { CoreUserModule } from '@core/user/user.module';
|
||||||
import { CoreGradesModule } from '@core/grades/grades.module';
|
import { CoreGradesModule } from '@core/grades/grades.module';
|
||||||
import { CoreSettingsModule } from '@core/settings/settings.module';
|
import { CoreSettingsModule } from '@core/settings/settings.module';
|
||||||
import { CoreSiteAddonsModule } from '@core/siteaddons/siteaddons.module';
|
import { CoreSiteAddonsModule } from '@core/siteaddons/siteaddons.module';
|
||||||
|
import { CoreCompileModule } from '@core/compile/compile.module';
|
||||||
|
|
||||||
// Addon modules.
|
// Addon modules.
|
||||||
import { AddonCalendarModule } from '@addon/calendar/calendar.module';
|
import { AddonCalendarModule } from '@addon/calendar/calendar.module';
|
||||||
|
@ -146,6 +147,7 @@ export const CORE_PROVIDERS: any[] = [
|
||||||
CoreGradesModule,
|
CoreGradesModule,
|
||||||
CoreSettingsModule,
|
CoreSettingsModule,
|
||||||
CoreSiteAddonsModule,
|
CoreSiteAddonsModule,
|
||||||
|
CoreCompileModule,
|
||||||
AddonCalendarModule,
|
AddonCalendarModule,
|
||||||
AddonUserProfileFieldModule,
|
AddonUserProfileFieldModule,
|
||||||
AddonFilesModule,
|
AddonFilesModule,
|
||||||
|
|
|
@ -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: '<ng-container #dynamicComponent></ng-container>'
|
|
||||||
})
|
|
||||||
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<any>;
|
|
||||||
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 = (<any[]> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 { }
|
|
@ -27,4 +27,4 @@ import { CoreCompileHtmlComponent } from './compile-html';
|
||||||
CoreCompileHtmlComponent
|
CoreCompileHtmlComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CoreCompileHtmlComponentsModule {}
|
export class CoreCompileHtmlComponentModule {}
|
|
@ -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: '<ng-container #dynamicComponent></ng-container>'
|
||||||
|
})
|
||||||
|
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<any>;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 = (<any[]> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
<core-loading [hideUntil]="dataLoaded">
|
<core-loading [hideUntil]="dataLoaded">
|
||||||
<core-compile-html [text]="content" [javascript]="javascript"></core-compile-html>
|
<core-compile-html [text]="content" [javascript]="javascript" [jsData]="bootstrapResult"></core-compile-html>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -28,6 +28,7 @@ export class CoreSiteAddonsAddonContentComponent implements OnInit {
|
||||||
@Input() component: string;
|
@Input() component: string;
|
||||||
@Input() method: string;
|
@Input() method: string;
|
||||||
@Input() args: any;
|
@Input() args: any;
|
||||||
|
@Input() bootstrapResult: any; // Result of the bootstrap JS of the handler.
|
||||||
@Output() onContentLoaded?: EventEmitter<boolean>; // Emits an event when the content is loaded.
|
@Output() onContentLoaded?: EventEmitter<boolean>; // Emits an event when the content is loaded.
|
||||||
@Output() onLoadingContent?: EventEmitter<boolean>; // Emits an event when starts to load the content.
|
@Output() onLoadingContent?: EventEmitter<boolean>; // Emits an event when starts to load the content.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { CommonModule } from '@angular/common';
|
||||||
import { IonicModule } from 'ionic-angular';
|
import { IonicModule } from 'ionic-angular';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { CoreComponentsModule } from '../../../components/components.module';
|
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 { CoreSiteAddonsAddonContentComponent } from './addon-content/addon-content';
|
||||||
import { CoreSiteAddonsModuleIndexComponent } from './module-index/module-index';
|
import { CoreSiteAddonsModuleIndexComponent } from './module-index/module-index';
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ import { CoreSiteAddonsModuleIndexComponent } from './module-index/module-index'
|
||||||
CommonModule,
|
CommonModule,
|
||||||
IonicModule,
|
IonicModule,
|
||||||
CoreComponentsModule,
|
CoreComponentsModule,
|
||||||
CoreCompileHtmlComponentsModule,
|
CoreCompileHtmlComponentModule,
|
||||||
TranslateModule.forChild()
|
TranslateModule.forChild()
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
|
|
@ -9,4 +9,4 @@
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<core-site-addons-addon-content *ngIf="component && method" [component]="component" [method]="method" [args]="args" (onContentLoaded)="contentLoaded($event)" (onLoadingContent)="contentLoading($event)"></core-site-addons-addon-content>
|
<core-site-addons-addon-content *ngIf="component && method" [component]="component" [method]="method" [args]="args" [bootstrapResult]="bootstrapResult" (onContentLoaded)="contentLoaded($event)" (onLoadingContent)="contentLoading($event)"></core-site-addons-addon-content>
|
||||||
|
|
|
@ -37,6 +37,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
|
||||||
component: string;
|
component: string;
|
||||||
method: string;
|
method: string;
|
||||||
args: any;
|
args: any;
|
||||||
|
bootstrapResult: any;
|
||||||
|
|
||||||
// Data for context menu.
|
// Data for context menu.
|
||||||
externalUrl: string;
|
externalUrl: string;
|
||||||
|
@ -60,7 +61,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
|
||||||
this.refreshIcon = 'spinner';
|
this.refreshIcon = 'spinner';
|
||||||
|
|
||||||
if (this.module) {
|
if (this.module) {
|
||||||
const handler = this.siteAddonsProvider.getModuleSiteAddonHandler(this.module.modname);
|
const handler = this.siteAddonsProvider.getSiteAddonHandler(this.module.modname);
|
||||||
if (handler) {
|
if (handler) {
|
||||||
this.component = handler.addon.component;
|
this.component = handler.addon.component;
|
||||||
this.method = handler.handlerSchema.method;
|
this.method = handler.handlerSchema.method;
|
||||||
|
@ -68,6 +69,7 @@ export class CoreSiteAddonsModuleIndexComponent implements OnInit, OnDestroy, Co
|
||||||
courseid: this.courseId,
|
courseid: this.courseId,
|
||||||
cmid: this.module.id
|
cmid: this.module.id
|
||||||
};
|
};
|
||||||
|
this.bootstrapResult = handler.bootstrapResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the data for the context menu.
|
// Get the data for the context menu.
|
||||||
|
|
|
@ -91,7 +91,8 @@ export class CoreSiteAddonsCallWSNewContentDirective extends CoreSiteAddonsCallW
|
||||||
title: this.title,
|
title: this.title,
|
||||||
component: this.component,
|
component: this.component,
|
||||||
method: this.method,
|
method: this.method,
|
||||||
args: args
|
args: args,
|
||||||
|
bootstrapResult: this.parentContent && this.parentContent.bootstrapResult
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ export class CoreSiteAddonsNewContentDirective implements OnInit {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
component: this.component,
|
component: this.component,
|
||||||
method: this.method,
|
method: this.method,
|
||||||
args: args
|
args: args,
|
||||||
|
bootstrapResult: this.parentContent && this.parentContent.bootstrapResult
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,5 +11,5 @@
|
||||||
<ion-refresher [enabled]="content && content.dataLoaded" (ionRefresh)="refreshData($event)">
|
<ion-refresher [enabled]="content && content.dataLoaded" (ionRefresh)="refreshData($event)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-site-addons-addon-content [component]="component" [method]="method" [args]="args"></core-site-addons-addon-content>
|
<core-site-addons-addon-content [component]="component" [method]="method" [args]="args" [bootstrapResult]="bootstrapResult"></core-site-addons-addon-content>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -32,12 +32,14 @@ export class CoreSiteAddonsAddonPage {
|
||||||
component: string;
|
component: string;
|
||||||
method: string;
|
method: string;
|
||||||
args: any;
|
args: any;
|
||||||
|
bootstrapResult: any;
|
||||||
|
|
||||||
constructor(params: NavParams) {
|
constructor(params: NavParams) {
|
||||||
this.title = params.get('title');
|
this.title = params.get('title');
|
||||||
this.component = params.get('component');
|
this.component = params.get('component');
|
||||||
this.method = params.get('method');
|
this.method = params.get('method');
|
||||||
this.args = params.get('args');
|
this.args = params.get('args');
|
||||||
|
this.bootstrapResult = params.get('bootstrapResult');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,16 +18,18 @@ import { CoreLangProvider } from '../../../providers/lang';
|
||||||
import { CoreLoggerProvider } from '../../../providers/logger';
|
import { CoreLoggerProvider } from '../../../providers/logger';
|
||||||
import { CoreSite } from '../../../classes/site';
|
import { CoreSite } from '../../../classes/site';
|
||||||
import { CoreSitesProvider } from '../../../providers/sites';
|
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 {
|
import {
|
||||||
CoreCourseModuleDelegate, CoreCourseModuleHandler, CoreCourseModuleHandlerData
|
CoreCourseModuleDelegate, CoreCourseModuleHandler, CoreCourseModuleHandlerData
|
||||||
} from '../../../core/course/providers/module-delegate';
|
} from '../../course/providers/module-delegate';
|
||||||
import { CoreCourseModulePrefetchDelegate } from '../../../core/course/providers/module-prefetch-delegate';
|
import { CoreCourseModulePrefetchDelegate } from '../../course/providers/module-prefetch-delegate';
|
||||||
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../../core/user/providers/user-delegate';
|
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../user/providers/user-delegate';
|
||||||
import { CoreDelegateHandler } from '../../../classes/delegate';
|
import { CoreDelegateHandler } from '../../../classes/delegate';
|
||||||
import { CoreSiteAddonsModuleIndexComponent } from '../components/module-index/module-index';
|
import { CoreSiteAddonsModuleIndexComponent } from '../components/module-index/module-index';
|
||||||
import { CoreSiteAddonsProvider } from './siteaddons';
|
import { CoreSiteAddonsProvider } from './siteaddons';
|
||||||
import { CoreSiteAddonsModulePrefetchHandler } from '../classes/module-prefetch-handler';
|
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
|
* 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,
|
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector,
|
||||||
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
|
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
|
||||||
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider,
|
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');
|
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<any>} 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<any> {
|
||||||
|
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.
|
* Create a base handler for a site addon.
|
||||||
*
|
*
|
||||||
|
@ -86,17 +120,6 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
return this.getHandlerPrefixForStrings(handlerName) + key;
|
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.
|
* 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) {
|
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);
|
this.langProvider.addSiteAddonsStrings(lang, handlerSchema.lang[lang], prefix);
|
||||||
}
|
}
|
||||||
|
@ -144,8 +167,11 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
* Load a site addon.
|
* Load a site addon.
|
||||||
*
|
*
|
||||||
* @param {any} addon Data of the addon.
|
* @param {any} addon Data of the addon.
|
||||||
|
* @return {Promise<any>} Promise resolved when loaded.
|
||||||
*/
|
*/
|
||||||
loadSiteAddon(addon: any): void {
|
loadSiteAddon(addon: any): Promise<any> {
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!addon.parsedHandlers) {
|
if (!addon.parsedHandlers) {
|
||||||
addon.parsedHandlers = JSON.parse(addon.handlers);
|
addon.parsedHandlers = JSON.parse(addon.handlers);
|
||||||
|
@ -153,11 +179,13 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
|
|
||||||
// Register all the handlers.
|
// Register all the handlers.
|
||||||
for (const name in addon.parsedHandlers) {
|
for (const name in addon.parsedHandlers) {
|
||||||
this.registerHandler(addon, name, addon.parsedHandlers[name]);
|
promises.push(this.registerHandler(addon, name, addon.parsedHandlers[name]));
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
this.logger.warn('Error parsing site addon', 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 {any} addon Data of the addon.
|
||||||
* @param {string} handlerName Name of the handler in the addon.
|
* @param {string} handlerName Name of the handler in the addon.
|
||||||
* @param {any} handlerSchema Data about the handler.
|
* @param {any} handlerSchema Data about the handler.
|
||||||
|
* @return {Promise<any>} Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
registerHandler(addon: any, handlerName: string, handlerSchema: any): void {
|
registerHandler(addon: any, handlerName: string, handlerSchema: any): Promise<any> {
|
||||||
this.loadHandlerLangStrings(addon, handlerName, handlerSchema);
|
this.loadHandlerLangStrings(addon, handlerName, handlerSchema);
|
||||||
|
|
||||||
switch (handlerSchema.delegate) {
|
// Wait for the bootstrap JS to be executed.
|
||||||
case 'CoreMainMenuDelegate':
|
return this.bootstrapHandler(addon, handlerName, handlerSchema).then((result) => {
|
||||||
this.registerMainMenuHandler(addon, handlerName, handlerSchema);
|
let uniqueName;
|
||||||
break;
|
|
||||||
|
|
||||||
case 'CoreCourseModuleDelegate':
|
switch (handlerSchema.delegate) {
|
||||||
this.registerModuleHandler(addon, handlerName, handlerSchema);
|
case 'CoreMainMenuDelegate':
|
||||||
break;
|
uniqueName = this.registerMainMenuHandler(addon, handlerName, handlerSchema, result);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'CoreUserDelegate':
|
case 'CoreCourseModuleDelegate':
|
||||||
this.registerUserProfileHandler(addon, handlerName, handlerSchema);
|
uniqueName = this.registerModuleHandler(addon, handlerName, handlerSchema, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case 'CoreUserDelegate':
|
||||||
// Nothing to do.
|
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 {any} addon Data of the addon.
|
||||||
* @param {string} handlerName Name of the handler in the addon.
|
* @param {string} handlerName Name of the handler in the addon.
|
||||||
* @param {any} handlerSchema Data about the handler.
|
* @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) {
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
||||||
// Required data not provided, stop.
|
// Required data not provided, stop.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the base handler.
|
// 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);
|
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
|
||||||
let mainMenuHandler: CoreMainMenuHandler;
|
let mainMenuHandler: CoreMainMenuHandler;
|
||||||
|
|
||||||
|
@ -219,12 +266,15 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
title: prefixedTitle,
|
title: prefixedTitle,
|
||||||
component: addon.component,
|
component: addon.component,
|
||||||
method: handlerSchema.method,
|
method: handlerSchema.method,
|
||||||
|
bootstrapResult: bootstrapResult
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.mainMenuDelegate.registerHandler(mainMenuHandler);
|
this.mainMenuDelegate.registerHandler(mainMenuHandler);
|
||||||
|
|
||||||
|
return uniqueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,8 +283,10 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
* @param {any} addon Data of the addon.
|
* @param {any} addon Data of the addon.
|
||||||
* @param {string} handlerName Name of the handler in the addon.
|
* @param {string} handlerName Name of the handler in the addon.
|
||||||
* @param {any} handlerSchema Data about the handler.
|
* @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) {
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
||||||
// Required data not provided, stop.
|
// Required data not provided, stop.
|
||||||
return;
|
return;
|
||||||
|
@ -243,16 +295,10 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
// Create the base handler.
|
// Create the base handler.
|
||||||
const modName = addon.component.replace('mod_', ''),
|
const modName = addon.component.replace('mod_', ''),
|
||||||
baseHandler = this.getBaseHandler(modName),
|
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;
|
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.
|
// Extend the base handler, adding the properties required by the delegate.
|
||||||
moduleHandler = Object.assign(baseHandler, {
|
moduleHandler = Object.assign(baseHandler, {
|
||||||
getData: (module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData => {
|
getData: (module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData => {
|
||||||
|
@ -260,7 +306,7 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
title: module.name,
|
title: module.name,
|
||||||
icon: handlerSchema.displaydata.icon,
|
icon: handlerSchema.displaydata.icon,
|
||||||
class: handlerSchema.displaydata.class,
|
class: handlerSchema.displaydata.class,
|
||||||
showDownloadButton: hasOfflineFunctions,
|
showDownloadButton: typeof showDowloadButton != 'undefined' ? showDowloadButton : hasOfflineFunctions,
|
||||||
action: (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void => {
|
action: (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -285,6 +331,8 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.moduleDelegate.registerHandler(moduleHandler);
|
this.moduleDelegate.registerHandler(moduleHandler);
|
||||||
|
|
||||||
|
return modName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -293,15 +341,18 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
* @param {any} addon Data of the addon.
|
* @param {any} addon Data of the addon.
|
||||||
* @param {string} handlerName Name of the handler in the addon.
|
* @param {string} handlerName Name of the handler in the addon.
|
||||||
* @param {any} handlerSchema Data about the handler.
|
* @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) {
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
||||||
// Required data not provided, stop.
|
// Required data not provided, stop.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the base handler.
|
// 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);
|
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
|
||||||
let userHandler: CoreUserProfileHandler;
|
let userHandler: CoreUserProfileHandler;
|
||||||
|
|
||||||
|
@ -332,7 +383,8 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
args: {
|
args: {
|
||||||
courseid: courseId,
|
courseid: courseId,
|
||||||
userid: user.id
|
userid: user.id
|
||||||
}
|
},
|
||||||
|
bootstrapResult: bootstrapResult
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -340,5 +392,7 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.userDelegate.registerHandler(userHandler);
|
this.userDelegate.registerHandler(userHandler);
|
||||||
|
|
||||||
|
return uniqueName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ import { CoreUtilsProvider } from '../../../providers/utils/utils';
|
||||||
import { CoreConfigConstants } from '../../../configconstants';
|
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.
|
* The site addon data.
|
||||||
* @type {any}
|
* @type {any}
|
||||||
|
@ -43,6 +43,12 @@ export interface CoreSiteAddonsModuleHandler {
|
||||||
* @type {any}
|
* @type {any}
|
||||||
*/
|
*/
|
||||||
handlerSchema: any;
|
handlerSchema: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of executing the bootstrap JS.
|
||||||
|
* @type {any}
|
||||||
|
*/
|
||||||
|
bootstrapResult?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CoreSiteAddonsGetContentResult {
|
export interface CoreSiteAddonsGetContentResult {
|
||||||
|
@ -79,7 +85,7 @@ export class CoreSiteAddonsProvider {
|
||||||
protected ROOT_CACHE_KEY = 'CoreSiteAddons:';
|
protected ROOT_CACHE_KEY = 'CoreSiteAddons:';
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
protected moduleSiteAddons: {[modName: string]: CoreSiteAddonsModuleHandler} = {};
|
protected siteAddons: {[name: string]: CoreSiteAddonsHandler} = {}; // Site addons registered.
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
|
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
|
||||||
private langProvider: CoreLangProvider, private appProvider: CoreAppProvider, private platform: Platform) {
|
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} component Component where the class is. E.g. mod_assign.
|
||||||
* @param {string} method Method to execute in the class.
|
* @param {string} method Method to execute in the class.
|
||||||
* @param {any} args The params for the method.
|
* @param {any} args The params for the method.
|
||||||
|
* @param {CoreSiteWSPreSets} [preSets] Extra options.
|
||||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||||
* @return {Promise<CoreSiteAddonsGetContentResult>} Promise resolved with the result.
|
* @return {Promise<CoreSiteAddonsGetContentResult>} Promise resolved with the result.
|
||||||
*/
|
*/
|
||||||
getContent(component: string, method: string, args: any, siteId?: string): Promise<CoreSiteAddonsGetContentResult> {
|
getContent(component: string, method: string, args: any, preSets?: CoreSiteWSPreSets, siteId?: string)
|
||||||
|
: Promise<CoreSiteAddonsGetContentResult> {
|
||||||
this.logger.debug(`Get content for component '${component}' and method '${method}'`);
|
this.logger.debug(`Get content for component '${component}' and method '${method}'`);
|
||||||
|
|
||||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
@ -194,10 +202,11 @@ export class CoreSiteAddonsProvider {
|
||||||
component: component,
|
component: component,
|
||||||
method: method,
|
method: method,
|
||||||
args: this.utils.objectToArrayOfObjects(argsToSend, 'name', 'value', true)
|
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);
|
return this.sitesProvider.getCurrentSite().read('tool_mobile_get_content', data, preSets);
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.otherdata) {
|
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.
|
* @param {any} addon Data of the addon.
|
||||||
* @return {CoreSiteAddonsModuleHandler} Handler.
|
* @param {string} handlerName Name of the handler inside the addon.
|
||||||
|
* @return {string} Unique name.
|
||||||
*/
|
*/
|
||||||
getModuleSiteAddonHandler(modName: string): CoreSiteAddonsModuleHandler {
|
getHandlerUniqueName(addon: any, handlerName: string): string {
|
||||||
return this.moduleSiteAddons[modName];
|
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 {string} name A unique name to identify the handler.
|
||||||
* @param {CoreSiteAddonsModuleHandler} handler Handler to set.
|
* @param {CoreSiteAddonsHandler} handler Handler to set.
|
||||||
*/
|
*/
|
||||||
setModuleSiteAddonHandler(modName: string, handler: CoreSiteAddonsModuleHandler): void {
|
setSiteAddonHandler(name: string, handler: CoreSiteAddonsHandler): void {
|
||||||
this.moduleSiteAddons[modName] = handler;
|
this.siteAddons[name] = handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Platform } from 'ionic-angular';
|
|
||||||
import { CoreSiteAddonsProvider } from './providers/siteaddons';
|
import { CoreSiteAddonsProvider } from './providers/siteaddons';
|
||||||
import { CoreSiteAddonsHelperProvider } from './providers/helper';
|
import { CoreSiteAddonsHelperProvider } from './providers/helper';
|
||||||
import { CoreSiteAddonsComponentsModule } from './components/components.module';
|
import { CoreSiteAddonsComponentsModule } from './components/components.module';
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { CoreEventsProvider } from './events';
|
||||||
import { CoreLoggerProvider } from './logger';
|
import { CoreLoggerProvider } from './logger';
|
||||||
import { CoreSitesProvider } from './sites';
|
import { CoreSitesProvider } from './sites';
|
||||||
import { CoreSiteWSPreSets } from '../classes/site';
|
import { CoreSiteWSPreSets } from '../classes/site';
|
||||||
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { CoreSiteAddonsProvider } from '../core/siteaddons/providers/siteaddons';
|
import { CoreSiteAddonsProvider } from '../core/siteaddons/providers/siteaddons';
|
||||||
import { CoreSiteAddonsHelperProvider } from '../core/siteaddons/providers/helper';
|
import { CoreSiteAddonsHelperProvider } from '../core/siteaddons/providers/helper';
|
||||||
|
|
||||||
|
@ -29,7 +30,8 @@ export class CoreAddonManagerProvider {
|
||||||
protected logger;
|
protected logger;
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider,
|
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');
|
logger = logger.getInstance('CoreAddonManagerProvider');
|
||||||
|
|
||||||
// Fetch the addons on login.
|
// Fetch the addons on login.
|
||||||
|
@ -39,9 +41,10 @@ export class CoreAddonManagerProvider {
|
||||||
// Addons fetched, check that site hasn't changed.
|
// Addons fetched, check that site hasn't changed.
|
||||||
if (siteId == this.sitesProvider.getCurrentSiteId() && addons.length) {
|
if (siteId == this.sitesProvider.getCurrentSiteId() && addons.length) {
|
||||||
// Site is still the same. Load the addons and trigger the event.
|
// 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.
|
* Load site addons.
|
||||||
*
|
*
|
||||||
* @param {any[]} addons The addons to load.
|
* @param {any[]} addons The addons to load.
|
||||||
|
* @return {Promise<any>} Promise resolved when loaded.
|
||||||
*/
|
*/
|
||||||
loadSiteAddons(addons: any[]): void {
|
loadSiteAddons(addons: any[]): Promise<any> {
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
addons.forEach((addon) => {
|
addons.forEach((addon) => {
|
||||||
this.siteAddonsHelperProvider.loadSiteAddon(addon);
|
promises.push(this.siteAddonsHelperProvider.loadSiteAddon(addon));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this.utils.allPromises(promises);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue