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 { 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,
|
||||
|
|
|
@ -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
|
||||
]
|
||||
})
|
||||
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-compile-html [text]="content" [javascript]="javascript"></core-compile-html>
|
||||
<core-compile-html [text]="content" [javascript]="javascript" [jsData]="bootstrapResult"></core-compile-html>
|
||||
</core-loading>
|
||||
|
|
|
@ -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<boolean>; // Emits an event when the content is loaded.
|
||||
@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 { 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: [
|
||||
|
|
|
@ -9,4 +9,4 @@
|
|||
</core-context-menu>
|
||||
</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;
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,5 +11,5 @@
|
|||
<ion-refresher [enabled]="content && content.dataLoaded" (ionRefresh)="refreshData($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</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>
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<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.
|
||||
*
|
||||
|
@ -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<any>} Promise resolved when loaded.
|
||||
*/
|
||||
loadSiteAddon(addon: any): void {
|
||||
loadSiteAddon(addon: any): Promise<any> {
|
||||
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<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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<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}'`);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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<any>} Promise resolved when loaded.
|
||||
*/
|
||||
loadSiteAddons(addons: any[]): void {
|
||||
loadSiteAddons(addons: any[]): Promise<any> {
|
||||
const promises = [];
|
||||
|
||||
addons.forEach((addon) => {
|
||||
this.siteAddonsHelperProvider.loadSiteAddon(addon);
|
||||
promises.push(this.siteAddonsHelperProvider.loadSiteAddon(addon));
|
||||
});
|
||||
|
||||
return this.utils.allPromises(promises);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue