MOBILE-2333 siteaddons: Support creating new components
Now site addons can return a ComponentRef instead of the component class in the getComponent functions of the delegates. This means they can create a new component on the fly using CoreCompileProvider.instantiateDynamicComponentmain
parent
ffa5a53fc6
commit
d98088f6a6
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, Optional } from '@angular/core';
|
import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, Optional } from '@angular/core';
|
||||||
import { NavParams, NavController, Content, PopoverController } from 'ionic-angular';
|
import { Content, PopoverController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController, NavOptions } from 'ionic-angular';
|
import { NavController, NavOptions } from 'ionic-angular';
|
||||||
import { AddonModBookProvider } from './book';
|
import { AddonModBookProvider } from './book';
|
||||||
import { AddonModBookIndexComponent } from '../components/index/index';
|
import { AddonModBookIndexComponent } from '../components/index/index';
|
||||||
|
@ -60,12 +60,14 @@ export class AddonModBookModuleHandler implements CoreCourseModuleHandler {
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
* The component returned must implement CoreCourseModuleMainComponent.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course object.
|
* @param {any} course The course object.
|
||||||
* @param {any} module The module object.
|
* @param {any} module The module object.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getMainComponent(course: any, module: any): any {
|
getMainComponent(injector: Injector, course: any, module: any): any | Promise<any> {
|
||||||
return AddonModBookIndexComponent;
|
return AddonModBookIndexComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,12 +58,14 @@ export class AddonModLabelModuleHandler implements CoreCourseModuleHandler {
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
* The component returned must implement CoreCourseModuleMainComponent.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course object.
|
* @param {any} course The course object.
|
||||||
* @param {any} module The module object.
|
* @param {any} module The module object.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getMainComponent(course: any, module: any): any {
|
getMainComponent(injector: Injector, course: any, module: any): any | Promise<any> {
|
||||||
// There's no need to implement this because label cannot be used in singleactivity course format.
|
// There's no need to implement this because label cannot be used in singleactivity course format.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
||||||
'../../../../core/user/providers/user-profile-field-delegate';
|
'../../../../core/user/providers/user-profile-field-delegate';
|
||||||
import { AddonUserProfileFieldCheckboxComponent } from '../component/checkbox';
|
import { AddonUserProfileFieldCheckboxComponent } from '../component/checkbox';
|
||||||
|
@ -60,10 +60,12 @@ export class AddonUserProfileFieldCheckboxHandler implements CoreUserProfileFiel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any {
|
getComponent(injector: Injector): any | Promise<any> {
|
||||||
return AddonUserProfileFieldCheckboxComponent;
|
return AddonUserProfileFieldCheckboxComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
||||||
'../../../../core/user/providers/user-profile-field-delegate';
|
'../../../../core/user/providers/user-profile-field-delegate';
|
||||||
import { AddonUserProfileFieldDatetimeComponent } from '../component/datetime';
|
import { AddonUserProfileFieldDatetimeComponent } from '../component/datetime';
|
||||||
|
@ -62,10 +62,12 @@ export class AddonUserProfileFieldDatetimeHandler implements CoreUserProfileFiel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any {
|
getComponent(injector: Injector): any | Promise<any> {
|
||||||
return AddonUserProfileFieldDatetimeComponent;
|
return AddonUserProfileFieldDatetimeComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
||||||
'../../../../core/user/providers/user-profile-field-delegate';
|
'../../../../core/user/providers/user-profile-field-delegate';
|
||||||
import { AddonUserProfileFieldMenuComponent } from '../component/menu';
|
import { AddonUserProfileFieldMenuComponent } from '../component/menu';
|
||||||
|
@ -60,10 +60,12 @@ export class AddonUserProfileFieldMenuHandler implements CoreUserProfileFieldHan
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any {
|
getComponent(injector: Injector): any | Promise<any> {
|
||||||
return AddonUserProfileFieldMenuComponent;
|
return AddonUserProfileFieldMenuComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
||||||
'../../../../core/user/providers/user-profile-field-delegate';
|
'../../../../core/user/providers/user-profile-field-delegate';
|
||||||
import { AddonUserProfileFieldTextComponent } from '../component/text';
|
import { AddonUserProfileFieldTextComponent } from '../component/text';
|
||||||
|
@ -57,10 +57,12 @@ export class AddonUserProfileFieldTextHandler implements CoreUserProfileFieldHan
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any {
|
getComponent(injector: Injector): any | Promise<any> {
|
||||||
return AddonUserProfileFieldTextComponent;
|
return AddonUserProfileFieldTextComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from
|
||||||
'../../../../core/user/providers/user-profile-field-delegate';
|
'../../../../core/user/providers/user-profile-field-delegate';
|
||||||
import { AddonUserProfileFieldTextareaComponent } from '../component/textarea';
|
import { AddonUserProfileFieldTextareaComponent } from '../component/textarea';
|
||||||
|
@ -66,10 +66,12 @@ export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFiel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any {
|
getComponent(injector: Injector): any | Promise<any> {
|
||||||
return AddonUserProfileFieldTextareaComponent;
|
return AddonUserProfileFieldTextareaComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component, Input, ViewChild, OnInit, OnChanges, DoCheck, ViewContainerRef, ComponentFactoryResolver,
|
Component, Input, ViewChild, OnInit, OnChanges, DoCheck, ViewContainerRef, ComponentFactoryResolver, ComponentRef,
|
||||||
KeyValueDiffers, SimpleChange
|
KeyValueDiffers, SimpleChange, ChangeDetectorRef, Optional, ElementRef
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +40,10 @@ import { CoreLoggerProvider } from '@providers/logger';
|
||||||
*
|
*
|
||||||
* Please notice that the component that you pass needs to be declared in entryComponents of the module to be created dynamically.
|
* Please notice that the component that you pass needs to be declared in entryComponents of the module to be created dynamically.
|
||||||
*
|
*
|
||||||
|
* Alternatively, you can also supply a ComponentRef instead of the class of the component. In this case, the component won't
|
||||||
|
* be instantiated because it already is, it will be attached to the view and the right data will be passed to it.
|
||||||
|
* Passing ComponentRef is meant for site addons, so we'll inject a NavController instance to the component.
|
||||||
|
*
|
||||||
* The contents of this component will be displayed if no component is supplied or it cannot be created. In the example above,
|
* The contents of this component will be displayed if no component is supplied or it cannot be created. In the example above,
|
||||||
* if no component is supplied then the template will show the message "Cannot render the data.".
|
* if no component is supplied then the template will show the message "Cannot render the data.".
|
||||||
*/
|
*/
|
||||||
|
@ -62,7 +67,8 @@ export class CoreDynamicComponent implements OnInit, OnChanges, DoCheck {
|
||||||
protected logger: any;
|
protected logger: any;
|
||||||
protected differ: any; // To detect changes in the data input.
|
protected differ: any; // To detect changes in the data input.
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private factoryResolver: ComponentFactoryResolver, differs: KeyValueDiffers) {
|
constructor(logger: CoreLoggerProvider, protected factoryResolver: ComponentFactoryResolver, differs: KeyValueDiffers,
|
||||||
|
@Optional() protected navCtrl: NavController, protected cdr: ChangeDetectorRef, protected element: ElementRef) {
|
||||||
this.logger = logger.getInstance('CoreDynamicComponent');
|
this.logger = logger.getInstance('CoreDynamicComponent');
|
||||||
this.differ = differs.find([]).create();
|
this.differ = differs.find([]).create();
|
||||||
}
|
}
|
||||||
|
@ -128,21 +134,32 @@ export class CoreDynamicComponent implements OnInit, OnChanges, DoCheck {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (this.component instanceof ComponentRef) {
|
||||||
// Create the component and add it to the container.
|
// A ComponentRef was supplied instead of the component class. Add it to the view.
|
||||||
const factory = this.factoryResolver.resolveComponentFactory(this.component),
|
this.container.insert(this.component.hostView);
|
||||||
componentRef = this.container.createComponent(factory);
|
this.instance = this.component.instance;
|
||||||
|
|
||||||
this.instance = componentRef.instance;
|
// This feature is usually meant for site addons. Inject some properties.
|
||||||
|
this.instance['ChangeDetectorRef'] = this.cdr;
|
||||||
|
this.instance['NavController'] = this.navCtrl;
|
||||||
|
this.instance['componentContainer'] = this.element.nativeElement;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// Create the component and add it to the container.
|
||||||
|
const factory = this.factoryResolver.resolveComponentFactory(this.component),
|
||||||
|
componentRef = this.container.createComponent(factory);
|
||||||
|
|
||||||
this.setInputData();
|
this.instance = componentRef.instance;
|
||||||
|
} catch (ex) {
|
||||||
|
this.logger.error('Error creating component', ex);
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
} catch (ex) {
|
}
|
||||||
this.logger.error('Error creating component', ex);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setInputData();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Code based on https://github.com/martinpritchardelevate/ionic-split-pane-demo
|
// Code based on https://github.com/martinpritchardelevate/ionic-split-pane-demo
|
||||||
|
|
||||||
import { Component, ViewChild, Input, ElementRef, OnInit } from '@angular/core';
|
import { Component, ViewChild, Input, ElementRef, OnInit, Optional } from '@angular/core';
|
||||||
import { NavController, Nav } from 'ionic-angular';
|
import { NavController, Nav } from 'ionic-angular';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,7 @@ export class CoreSplitViewComponent implements OnInit {
|
||||||
// Empty placeholder for the 'detail' page.
|
// Empty placeholder for the 'detail' page.
|
||||||
detailPage: any = null;
|
detailPage: any = null;
|
||||||
|
|
||||||
constructor(private masterNav: NavController, element: ElementRef) {
|
constructor(@Optional() private masterNav: NavController, element: ElementRef) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,24 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component, NgModule, Input, OnInit, OnChanges, OnDestroy, ViewContainerRef, Compiler, ViewChild, ComponentRef,
|
Component, Input, OnInit, OnChanges, OnDestroy, ViewContainerRef, ViewChild, ComponentRef, SimpleChange, ChangeDetectorRef,
|
||||||
SimpleChange, ChangeDetectorRef
|
ElementRef, Optional
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { IonicModule, NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { CoreCompileProvider } from '../../../compile/providers/compile';
|
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
|
* 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.
|
* components and directives are instantiated.
|
||||||
|
@ -51,13 +39,6 @@ import { CoreUserComponentsModule } from '../../../user/components/components.mo
|
||||||
template: '<ng-container #dynamicComponent></ng-container>'
|
template: '<ng-container #dynamicComponent></ng-container>'
|
||||||
})
|
})
|
||||||
export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
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() text: string; // The HTML text to display.
|
||||||
@Input() javascript: string; // The Javascript to execute in the component.
|
@Input() javascript: string; // The Javascript to execute in the component.
|
||||||
@Input() jsData; // Data to pass to the fake component.
|
@Input() jsData; // Data to pass to the fake component.
|
||||||
|
@ -66,9 +47,12 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||||
@ViewChild('dynamicComponent', { read: ViewContainerRef }) container: ViewContainerRef;
|
@ViewChild('dynamicComponent', { read: ViewContainerRef }) container: ViewContainerRef;
|
||||||
|
|
||||||
protected componentRef: ComponentRef<any>;
|
protected componentRef: ComponentRef<any>;
|
||||||
|
protected element;
|
||||||
|
|
||||||
constructor(protected compileProvider: CoreCompileProvider, protected compiler: Compiler,
|
constructor(protected compileProvider: CoreCompileProvider, protected cdr: ChangeDetectorRef, element: ElementRef,
|
||||||
protected cdr: ChangeDetectorRef, protected navCtrl: NavController) { }
|
@Optional() protected navCtrl: NavController) {
|
||||||
|
this.element = element.nativeElement;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect changes on input properties.
|
* Detect changes on input properties.
|
||||||
|
@ -76,26 +60,14 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||||
if ((changes.text || changes.javascript) && this.text) {
|
if ((changes.text || changes.javascript) && this.text) {
|
||||||
// Create a new component and a new module.
|
// Create a new component and a new module.
|
||||||
const component = this.createComponent(),
|
this.compileProvider.createAndCompileComponent(this.text, this.getComponentClass()).then((factory) => {
|
||||||
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.
|
// Destroy previous components.
|
||||||
this.componentRef && this.componentRef.destroy();
|
this.componentRef && this.componentRef.destroy();
|
||||||
|
|
||||||
// Create the component.
|
if (factory) {
|
||||||
this.componentRef = this.container.createComponent(componentFactory);
|
// Create the component.
|
||||||
|
this.componentRef = this.container.createComponent(factory);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,20 +80,16 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dynamic component to compile the HTML and run the javascript.
|
* Get a class that defines the dynamic component.
|
||||||
*
|
*
|
||||||
* @return {any} The component class.
|
* @return {any} The component class.
|
||||||
*/
|
*/
|
||||||
protected createComponent(): any {
|
protected getComponentClass(): any {
|
||||||
// tslint:disable: no-this-assignment
|
// tslint:disable: no-this-assignment
|
||||||
const compileInstance = this;
|
const compileInstance = this;
|
||||||
|
|
||||||
// Create the component, using the text as the template.
|
// Create the component, using the text as the template.
|
||||||
return Component({
|
return class CoreCompileHtmlFakeComponent implements OnInit {
|
||||||
template: this.text
|
|
||||||
})
|
|
||||||
(class CoreCompileHtmlFakeComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// If there is some javascript to run, prepare the instance.
|
// If there is some javascript to run, prepare the instance.
|
||||||
if (compileInstance.javascript) {
|
if (compileInstance.javascript) {
|
||||||
|
@ -130,7 +98,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||||
// Add some more components and classes.
|
// Add some more components and classes.
|
||||||
this['ChangeDetectorRef'] = compileInstance.cdr;
|
this['ChangeDetectorRef'] = compileInstance.cdr;
|
||||||
this['NavController'] = compileInstance.navCtrl;
|
this['NavController'] = compileInstance.navCtrl;
|
||||||
this['componentContainer'] = compileInstance.container;
|
this['componentContainer'] = compileInstance.element;
|
||||||
|
|
||||||
// Add the data passed to the component.
|
// Add the data passed to the component.
|
||||||
for (const name in compileInstance.jsData) {
|
for (const name in compileInstance.jsData) {
|
||||||
|
@ -145,6 +113,6 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||||
compileInstance.compileProvider.executeJavascript(this, compileInstance.javascript);
|
compileInstance.compileProvider.executeJavascript(this, compileInstance.javascript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable, Injector } from '@angular/core';
|
import { Injectable, Injector, Component, NgModule, Compiler, ComponentFactory, ComponentRef, NgModuleRef } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
Platform, ActionSheetController, AlertController, LoadingController, ModalController, PopoverController, ToastController
|
Platform, ActionSheetController, AlertController, LoadingController, ModalController, PopoverController, ToastController,
|
||||||
|
IonicModule
|
||||||
} from 'ionic-angular';
|
} from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
||||||
import { CoreLoggerProvider } from '../../../providers/logger';
|
import { CoreLoggerProvider } from '../../../providers/logger';
|
||||||
|
|
||||||
// Import core providers.
|
// Import core providers.
|
||||||
|
@ -55,6 +56,24 @@ import { CoreContentLinksModuleGradeHandler } from '../../contentlinks/classes/m
|
||||||
import { CoreContentLinksModuleIndexHandler } from '../../contentlinks/classes/module-index-handler';
|
import { CoreContentLinksModuleIndexHandler } from '../../contentlinks/classes/module-index-handler';
|
||||||
import { CoreCourseModulePrefetchHandlerBase } from '../../course/classes/module-prefetch-handler';
|
import { CoreCourseModulePrefetchHandlerBase } from '../../course/classes/module-prefetch-handler';
|
||||||
|
|
||||||
|
// 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';
|
||||||
|
|
||||||
|
// Import some components listed in entryComponents so they can be injected dynamically.
|
||||||
|
import { CoreCourseUnsupportedModuleComponent } from '../../course/components/unsupported-module/unsupported-module';
|
||||||
|
import { CoreCourseFormatSingleActivityComponent } from '../../course/formats/singleactivity/components/singleactivity';
|
||||||
|
import { CoreSiteAddonsModuleIndexComponent } from '../../siteaddons/components/module-index/module-index';
|
||||||
|
import { CoreSiteAddonsCourseOptionComponent } from '../../siteaddons/components/course-option/course-option';
|
||||||
|
import { CoreSiteAddonsCourseFormatComponent } from '../../siteaddons/components/course-format/course-format';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to provide functionalities regarding compiling dynamic HTML and Javascript.
|
* Service to provide functionalities regarding compiling dynamic HTML and Javascript.
|
||||||
*/
|
*/
|
||||||
|
@ -69,10 +88,46 @@ export class CoreCompileProvider {
|
||||||
ModalController, PopoverController, ToastController, FormBuilder
|
ModalController, PopoverController, ToastController, FormBuilder
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(protected injector: Injector, logger: CoreLoggerProvider) {
|
// 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
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(protected injector: Injector, logger: CoreLoggerProvider, protected compiler: Compiler) {
|
||||||
this.logger = logger.getInstance('CoreCompileProvider');
|
this.logger = logger.getInstance('CoreCompileProvider');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and compile a dynamic component.
|
||||||
|
*
|
||||||
|
* @param {string} template The template of the component.
|
||||||
|
* @param {any} componentClass The JS class of the component.
|
||||||
|
* @return {Promise<ComponentFactory<any>>} Promise resolved with the factory to instantiate the component.
|
||||||
|
*/
|
||||||
|
createAndCompileComponent(template: string, componentClass: any): Promise<ComponentFactory<any>> {
|
||||||
|
// Create the component using the template and the class.
|
||||||
|
const component = Component({
|
||||||
|
template: template
|
||||||
|
})
|
||||||
|
(componentClass);
|
||||||
|
|
||||||
|
// Now create the module containing the component.
|
||||||
|
const module = NgModule({imports: this.IMPORTS, declarations: [component]})(class {});
|
||||||
|
|
||||||
|
// Compile the module and the component.
|
||||||
|
return this.compiler.compileModuleAndAllComponentsAsync(module).then((factories) => {
|
||||||
|
// Search and return the factory of the component we just created.
|
||||||
|
for (const i in factories.componentFactories) {
|
||||||
|
const factory = factories.componentFactories[i];
|
||||||
|
if (factory.componentType == component) {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Eval some javascript using the context of the function.
|
* Eval some javascript using the context of the function.
|
||||||
*
|
*
|
||||||
|
@ -124,6 +179,9 @@ export class CoreCompileProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inject current service.
|
||||||
|
instance['CoreCompileProvider'] = this;
|
||||||
|
|
||||||
// Add some final classes.
|
// Add some final classes.
|
||||||
instance['injector'] = this.injector;
|
instance['injector'] = this.injector;
|
||||||
instance['Validators'] = Validators;
|
instance['Validators'] = Validators;
|
||||||
|
@ -138,5 +196,29 @@ export class CoreCompileProvider {
|
||||||
instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
|
instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
|
||||||
instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;
|
instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;
|
||||||
instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase;
|
instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase;
|
||||||
|
instance['CoreCourseUnsupportedModuleComponent'] = CoreCourseUnsupportedModuleComponent;
|
||||||
|
instance['CoreCourseFormatSingleActivityComponent'] = CoreCourseFormatSingleActivityComponent;
|
||||||
|
instance['CoreSiteAddonsModuleIndexComponent'] = CoreSiteAddonsModuleIndexComponent;
|
||||||
|
instance['CoreSiteAddonsCourseOptionComponent'] = CoreSiteAddonsCourseOptionComponent;
|
||||||
|
instance['CoreSiteAddonsCourseFormatComponent'] = CoreSiteAddonsCourseFormatComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate a dynamic component.
|
||||||
|
*
|
||||||
|
* @param {string} template The template of the component.
|
||||||
|
* @param {any} componentClass The JS class of the component.
|
||||||
|
* @param {Injector} [injector] The injector to use. It's recommended to pass it so NavController and similar can be injected.
|
||||||
|
* @return {Promise<ComponentRef<any>>} Promise resolved with the component instance.
|
||||||
|
*/
|
||||||
|
instantiateDynamicComponent(template: string, componentClass: any, injector?: Injector): Promise<ComponentRef<any>> {
|
||||||
|
injector = injector || this.injector;
|
||||||
|
|
||||||
|
return this.createAndCompileComponent(template, componentClass).then((factory) => {
|
||||||
|
if (factory) {
|
||||||
|
// Create and return the component.
|
||||||
|
return factory.create(injector, undefined, undefined, injector.get(NgModuleRef));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter, ViewChildren, QueryList
|
Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange, Output, EventEmitter, ViewChildren, QueryList, Injector
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Content } from 'ionic-angular';
|
import { Content } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
@ -69,7 +69,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
protected sectionStatusObserver;
|
protected sectionStatusObserver;
|
||||||
|
|
||||||
constructor(private cfDelegate: CoreCourseFormatDelegate, translate: TranslateService,
|
constructor(private cfDelegate: CoreCourseFormatDelegate, translate: TranslateService, private injector: Injector,
|
||||||
private courseHelper: CoreCourseHelperProvider, private domUtils: CoreDomUtilsProvider,
|
private courseHelper: CoreCourseHelperProvider, private domUtils: CoreDomUtilsProvider,
|
||||||
eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider, private content: Content,
|
eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider, private content: Content,
|
||||||
prefetchDelegate: CoreCourseModulePrefetchDelegate) {
|
prefetchDelegate: CoreCourseModulePrefetchDelegate) {
|
||||||
|
@ -194,19 +194,29 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
protected getComponents(): void {
|
protected getComponents(): void {
|
||||||
if (this.course) {
|
if (this.course) {
|
||||||
if (!this.courseFormatComponent) {
|
if (!this.courseFormatComponent) {
|
||||||
this.courseFormatComponent = this.cfDelegate.getCourseFormatComponent(this.course);
|
this.cfDelegate.getCourseFormatComponent(this.injector, this.course).then((component) => {
|
||||||
|
this.courseFormatComponent = component;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!this.courseSummaryComponent) {
|
if (!this.courseSummaryComponent) {
|
||||||
this.courseSummaryComponent = this.cfDelegate.getCourseSummaryComponent(this.course);
|
this.cfDelegate.getCourseSummaryComponent(this.injector, this.course).then((component) => {
|
||||||
|
this.courseSummaryComponent = component;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!this.sectionSelectorComponent) {
|
if (!this.sectionSelectorComponent) {
|
||||||
this.sectionSelectorComponent = this.cfDelegate.getSectionSelectorComponent(this.course);
|
this.cfDelegate.getSectionSelectorComponent(this.injector, this.course).then((component) => {
|
||||||
|
this.sectionSelectorComponent = component;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!this.singleSectionComponent) {
|
if (!this.singleSectionComponent) {
|
||||||
this.singleSectionComponent = this.cfDelegate.getSingleSectionComponent(this.course);
|
this.cfDelegate.getSingleSectionComponent(this.injector, this.course).then((component) => {
|
||||||
|
this.singleSectionComponent = component;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!this.allSectionsComponent) {
|
if (!this.allSectionsComponent) {
|
||||||
this.allSectionsComponent = this.cfDelegate.getAllSectionsComponent(this.course);
|
this.cfDelegate.getAllSectionsComponent(this.injector, this.course).then((component) => {
|
||||||
|
this.allSectionsComponent = component;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
|
@ -67,7 +67,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
|
||||||
protected prefetchHandler: CoreCourseModulePrefetchHandler;
|
protected prefetchHandler: CoreCourseModulePrefetchHandler;
|
||||||
protected statusObserver;
|
protected statusObserver;
|
||||||
|
|
||||||
constructor(protected navCtrl: NavController, protected prefetchDelegate: CoreCourseModulePrefetchDelegate,
|
constructor(@Optional() protected navCtrl: NavController, protected prefetchDelegate: CoreCourseModulePrefetchDelegate,
|
||||||
protected domUtils: CoreDomUtilsProvider, protected courseHelper: CoreCourseHelperProvider,
|
protected domUtils: CoreDomUtilsProvider, protected courseHelper: CoreCourseHelperProvider,
|
||||||
protected eventsProvider: CoreEventsProvider, protected sitesProvider: CoreSitesProvider) {
|
protected eventsProvider: CoreEventsProvider, protected sitesProvider: CoreSitesProvider) {
|
||||||
this.completionChanged = new EventEmitter();
|
this.completionChanged = new EventEmitter();
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnChanges, SimpleChange, ViewChild } from '@angular/core';
|
import { Component, Input, OnChanges, SimpleChange, ViewChild, Injector } from '@angular/core';
|
||||||
import { CoreCourseModuleDelegate } from '../../../providers/module-delegate';
|
import { CoreCourseModuleDelegate } from '../../../providers/module-delegate';
|
||||||
import { CoreCourseUnsupportedModuleComponent } from '../../../components/unsupported-module/unsupported-module';
|
import { CoreCourseUnsupportedModuleComponent } from '../../../components/unsupported-module/unsupported-module';
|
||||||
import { CoreDynamicComponent } from '../../../../../components/dynamic-component/dynamic-component';
|
import { CoreDynamicComponent } from '../../../../../components/dynamic-component/dynamic-component';
|
||||||
|
@ -36,7 +36,7 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
|
||||||
componentClass: any; // The class of the component to render.
|
componentClass: any; // The class of the component to render.
|
||||||
data: any = {}; // Data to pass to the component.
|
data: any = {}; // Data to pass to the component.
|
||||||
|
|
||||||
constructor(private moduleDelegate: CoreCourseModuleDelegate) { }
|
constructor(private moduleDelegate: CoreCourseModuleDelegate, private injector: Injector) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect changes on input properties.
|
* Detect changes on input properties.
|
||||||
|
@ -47,8 +47,9 @@ export class CoreCourseFormatSingleActivityComponent implements OnChanges {
|
||||||
const module = this.sections[0] && this.sections[0].modules && this.sections[0].modules[0];
|
const module = this.sections[0] && this.sections[0].modules && this.sections[0].modules[0];
|
||||||
if (module && !this.componentClass) {
|
if (module && !this.componentClass) {
|
||||||
// We haven't obtained the class yet. Get it now.
|
// We haven't obtained the class yet. Get it now.
|
||||||
this.componentClass = this.moduleDelegate.getMainComponent(this.course, module) ||
|
this.moduleDelegate.getMainComponent(this.injector, this.course, module).then((component) => {
|
||||||
CoreCourseUnsupportedModuleComponent;
|
this.componentClass = component || CoreCourseUnsupportedModuleComponent;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.data.courseId = this.course.id;
|
this.data.courseId = this.course.id;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreCourseFormatHandler } from '../../../providers/format-delegate';
|
import { CoreCourseFormatHandler } from '../../../providers/format-delegate';
|
||||||
import { CoreCourseFormatSingleActivityComponent } from '../components/singleactivity';
|
import { CoreCourseFormatSingleActivityComponent } from '../components/singleactivity';
|
||||||
|
|
||||||
|
@ -86,11 +86,13 @@ export class CoreCourseFormatSingleActivityHandler implements CoreCourseFormatHa
|
||||||
* Return the Component to use to display the course format instead of using the default one.
|
* Return the Component to use to display the course format instead of using the default one.
|
||||||
* Use it if you want to display a format completely different from the default one.
|
* Use it if you want to display a format completely different from the default one.
|
||||||
* If you want to customize the default format there are several methods to customize parts of it.
|
* If you want to customize the default format there are several methods to customize parts of it.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getCourseFormatComponent(course: any): any {
|
getCourseFormatComponent(injector: Injector, course: any): any | Promise<any> {
|
||||||
return CoreCourseFormatSingleActivityComponent;
|
return CoreCourseFormatSingleActivityComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, ViewChild, OnDestroy } from '@angular/core';
|
import { Component, ViewChild, OnDestroy, Injector } from '@angular/core';
|
||||||
import { IonicPage, NavParams, Content, NavController } from 'ionic-angular';
|
import { IonicPage, NavParams, Content, NavController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
|
@ -63,7 +63,7 @@ export class CoreCourseSectionPage implements OnDestroy {
|
||||||
private courseFormatDelegate: CoreCourseFormatDelegate, private courseOptionsDelegate: CoreCourseOptionsDelegate,
|
private courseFormatDelegate: CoreCourseFormatDelegate, private courseOptionsDelegate: CoreCourseOptionsDelegate,
|
||||||
private translate: TranslateService, private courseHelper: CoreCourseHelperProvider, eventsProvider: CoreEventsProvider,
|
private translate: TranslateService, private courseHelper: CoreCourseHelperProvider, eventsProvider: CoreEventsProvider,
|
||||||
private textUtils: CoreTextUtilsProvider, private coursesProvider: CoreCoursesProvider,
|
private textUtils: CoreTextUtilsProvider, private coursesProvider: CoreCoursesProvider,
|
||||||
sitesProvider: CoreSitesProvider, private navCtrl: NavController,
|
sitesProvider: CoreSitesProvider, private navCtrl: NavController, private injector: Injector,
|
||||||
private prefetchDelegate: CoreCourseModulePrefetchDelegate) {
|
private prefetchDelegate: CoreCourseModulePrefetchDelegate) {
|
||||||
this.course = navParams.get('course');
|
this.course = navParams.get('course');
|
||||||
this.sectionId = navParams.get('sectionId');
|
this.sectionId = navParams.get('sectionId');
|
||||||
|
@ -191,7 +191,8 @@ export class CoreCourseSectionPage implements OnDestroy {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Load the course handlers.
|
// Load the course handlers.
|
||||||
promises.push(this.courseOptionsDelegate.getHandlersToDisplay(this.course, refresh, false).then((handlers) => {
|
promises.push(this.courseOptionsDelegate.getHandlersToDisplay(this.injector, this.course, refresh, false)
|
||||||
|
.then((handlers) => {
|
||||||
// Add the courseId to the handler component data.
|
// Add the courseId to the handler component data.
|
||||||
handlers.forEach((handler) => {
|
handlers.forEach((handler) => {
|
||||||
handler.data.componentData = handler.data.componentData || {};
|
handler.data.componentData = handler.data.componentData || {};
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
@ -85,44 +85,54 @@ export interface CoreCourseFormatHandler extends CoreDelegateHandler {
|
||||||
* Return the Component to use to display the course format instead of using the default one.
|
* Return the Component to use to display the course format instead of using the default one.
|
||||||
* Use it if you want to display a format completely different from the default one.
|
* Use it if you want to display a format completely different from the default one.
|
||||||
* If you want to customize the default format there are several methods to customize parts of it.
|
* If you want to customize the default format there are several methods to customize parts of it.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getCourseFormatComponent?(course: any): any;
|
getCourseFormatComponent?(injector: Injector, course: any): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the course summary inside the default course format.
|
* Return the Component to use to display the course summary inside the default course format.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getCourseSummaryComponent?(course: any): any;
|
getCourseSummaryComponent?(injector: Injector, course: any): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the section selector inside the default course format.
|
* Return the Component to use to display the section selector inside the default course format.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getSectionSelectorComponent?(course: any): any;
|
getSectionSelectorComponent?(injector: Injector, course: any): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display a single section. This component will only be used if the user is viewing a
|
* Return the Component to use to display a single section. This component will only be used if the user is viewing a
|
||||||
* single section. If all the sections are displayed at once then it won't be used.
|
* single section. If all the sections are displayed at once then it won't be used.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getSingleSectionComponent?(course: any): any;
|
getSingleSectionComponent?(injector: Injector, course: any): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display all sections in a course.
|
* Return the Component to use to display all sections in a course.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getAllSectionsComponent?(course: any): any;
|
getAllSectionsComponent?(injector: Injector, course: any): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate the data required to load the course format.
|
* Invalidate the data required to load the course format.
|
||||||
|
@ -199,31 +209,40 @@ export class CoreCourseFormatDelegate extends CoreDelegate {
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display all sections in a course.
|
* Get the component to use to display all sections in a course.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getAllSectionsComponent(course: any): any {
|
getAllSectionsComponent(injector: Injector, course: any): Promise<any> {
|
||||||
return this.executeFunction(course.format, 'getAllSectionsComponent', [course]);
|
return Promise.resolve(this.executeFunction(course.format, 'getAllSectionsComponent', [injector, course])).catch((e) => {
|
||||||
|
this.logger.error('Error getting all sections component', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display a course format.
|
* Get the component to use to display a course format.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getCourseFormatComponent(course: any): any {
|
getCourseFormatComponent(injector: Injector, course: any): Promise<any> {
|
||||||
return this.executeFunction(course.format, 'getCourseFormatComponent', [course]);
|
return Promise.resolve(this.executeFunction(course.format, 'getCourseFormatComponent', [injector, course])).catch((e) => {
|
||||||
|
this.logger.error('Error getting course format component', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display the course summary in the default course format.
|
* Get the component to use to display the course summary in the default course format.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getCourseSummaryComponent(course: any): any {
|
getCourseSummaryComponent(injector: Injector, course: any): Promise<any> {
|
||||||
return this.executeFunction(course.format, 'getCourseSummaryComponent', [course]);
|
return Promise.resolve(this.executeFunction(course.format, 'getCourseSummaryComponent', [injector, course])).catch((e) => {
|
||||||
|
this.logger.error('Error getting course summary component', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,22 +278,29 @@ export class CoreCourseFormatDelegate extends CoreDelegate {
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display the section selector inside the default course format.
|
* Get the component to use to display the section selector inside the default course format.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getSectionSelectorComponent(course: any): any {
|
getSectionSelectorComponent(injector: Injector, course: any): Promise<any> {
|
||||||
return this.executeFunction(course.format, 'getSectionSelectorComponent', [course]);
|
return Promise.resolve(this.executeFunction(course.format, 'getSectionSelectorComponent', [injector, course]))
|
||||||
|
.catch((e) => {
|
||||||
|
this.logger.error('Error getting section selector component', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display a single section. This component will only be used if the user is viewing
|
* Get the component to use to display a single section. This component will only be used if the user is viewing
|
||||||
* a single section. If all the sections are displayed at once then it won't be used.
|
* a single section. If all the sections are displayed at once then it won't be used.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course to render.
|
* @param {any} course The course to render.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getSingleSectionComponent(course: any): any {
|
getSingleSectionComponent(injector: Injector, course: any): Promise<any> {
|
||||||
return this.executeFunction(course.format, 'getSingleSectionComponent', [course]);
|
return Promise.resolve(this.executeFunction(course.format, 'getSingleSectionComponent', [injector, course])).catch((e) => {
|
||||||
|
this.logger.error('Error getting single section component', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
|
@ -120,7 +120,7 @@ export class CoreCourseHelperProvider {
|
||||||
private utils: CoreUtilsProvider, private translate: TranslateService, private loginHelper: CoreLoginHelperProvider,
|
private utils: CoreUtilsProvider, private translate: TranslateService, private loginHelper: CoreLoginHelperProvider,
|
||||||
private courseOptionsDelegate: CoreCourseOptionsDelegate, private siteHomeProvider: CoreSiteHomeProvider,
|
private courseOptionsDelegate: CoreCourseOptionsDelegate, private siteHomeProvider: CoreSiteHomeProvider,
|
||||||
private eventsProvider: CoreEventsProvider, private fileHelper: CoreFileHelperProvider,
|
private eventsProvider: CoreEventsProvider, private fileHelper: CoreFileHelperProvider,
|
||||||
private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider) { }
|
private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider, private injector: Injector) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function treats every module on the sections provided to load the handler data, treat completion
|
* This function treats every module on the sections provided to load the handler data, treat completion
|
||||||
|
@ -275,7 +275,7 @@ export class CoreCourseHelperProvider {
|
||||||
if (courseHandlers) {
|
if (courseHandlers) {
|
||||||
promise = Promise.resolve(courseHandlers);
|
promise = Promise.resolve(courseHandlers);
|
||||||
} else {
|
} else {
|
||||||
promise = this.courseOptionsDelegate.getHandlersToDisplay(course);
|
promise = this.courseOptionsDelegate.getHandlersToDisplay(this.injector, course);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.then((handlers: CoreCourseOptionsHandlerToDisplay[]) => {
|
return promise.then((handlers: CoreCourseOptionsHandlerToDisplay[]) => {
|
||||||
|
@ -323,7 +323,7 @@ export class CoreCourseHelperProvider {
|
||||||
subPromises.push(this.courseProvider.getSections(course.id, false, true).then((courseSections) => {
|
subPromises.push(this.courseProvider.getSections(course.id, false, true).then((courseSections) => {
|
||||||
sections = courseSections;
|
sections = courseSections;
|
||||||
}));
|
}));
|
||||||
subPromises.push(this.courseOptionsDelegate.getHandlersToDisplay(course).then((cHandlers) => {
|
subPromises.push(this.courseOptionsDelegate.getHandlersToDisplay(this.injector, course).then((cHandlers) => {
|
||||||
handlers = cHandlers;
|
handlers = cHandlers;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController, NavOptions } from 'ionic-angular';
|
import { NavController, NavOptions } from 'ionic-angular';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
@ -38,12 +38,14 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||||
* The component returned must implement CoreCourseModuleMainComponent.
|
* The component returned must implement CoreCourseModuleMainComponent.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course object.
|
* @param {any} course The course object.
|
||||||
* @param {any} module The module object.
|
* @param {any} module The module object.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getMainComponent(course: any, module: any): any;
|
getMainComponent(injector: Injector, course: any, module: any): any | Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,17 +178,17 @@ export class CoreCourseModuleDelegate extends CoreDelegate {
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module.
|
* Get the component to render the module.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course object.
|
* @param {any} course The course object.
|
||||||
* @param {any} module The module object.
|
* @param {any} module The module object.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getMainComponent?(course: any, module: any): any {
|
getMainComponent(injector: Injector, course: any, module: any): Promise<any> {
|
||||||
const handler = this.enabledHandlers[module.modname];
|
const handler = this.enabledHandlers[module.modname];
|
||||||
if (handler && handler.getMainComponent) {
|
if (handler && handler.getMainComponent) {
|
||||||
const component = handler.getMainComponent(course, module);
|
return Promise.resolve(handler.getMainComponent(injector, course, module)).catch((err) => {
|
||||||
if (component) {
|
this.logger.error('Error getting main component', err);
|
||||||
return component;
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
@ -45,10 +45,11 @@ export interface CoreCourseOptionsHandler extends CoreDelegateHandler {
|
||||||
/**
|
/**
|
||||||
* Returns the data needed to render the handler.
|
* Returns the data needed to render the handler.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {number} courseId The course ID.
|
* @param {number} courseId The course ID.
|
||||||
* @return {CoreCourseOptionsHandlerData} Data.
|
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
|
||||||
*/
|
*/
|
||||||
getDisplayData?(courseId: number): CoreCourseOptionsHandlerData;
|
getDisplayData?(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should invalidate the data to determine if the handler is enabled for a certain course.
|
* Should invalidate the data to determine if the handler is enabled for a certain course.
|
||||||
|
@ -243,6 +244,7 @@ export class CoreCourseOptionsDelegate extends CoreDelegate {
|
||||||
* Get the list of handlers that should be displayed for a course.
|
* Get the list of handlers that should be displayed for a course.
|
||||||
* This function should be called only when the handlers need to be displayed, since it can call several WebServices.
|
* This function should be called only when the handlers need to be displayed, since it can call several WebServices.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} course The course object.
|
* @param {any} course The course object.
|
||||||
* @param {boolean} [refresh] True if it should refresh the list.
|
* @param {boolean} [refresh] True if it should refresh the list.
|
||||||
* @param {boolean} [isGuest] Whether it's guest.
|
* @param {boolean} [isGuest] Whether it's guest.
|
||||||
|
@ -250,7 +252,7 @@ export class CoreCourseOptionsDelegate extends CoreDelegate {
|
||||||
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
* @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions.
|
||||||
* @return {Promise<CoreCourseOptionsHandlerToDisplay[]>} Promise resolved with array of handlers.
|
* @return {Promise<CoreCourseOptionsHandlerToDisplay[]>} Promise resolved with array of handlers.
|
||||||
*/
|
*/
|
||||||
getHandlersToDisplay(course: any, refresh?: boolean, isGuest?: boolean, navOptions?: any, admOptions?: any):
|
getHandlersToDisplay(injector: Injector, course: any, refresh?: boolean, isGuest?: boolean, navOptions?: any, admOptions?: any):
|
||||||
Promise<CoreCourseOptionsHandlerToDisplay[]> {
|
Promise<CoreCourseOptionsHandlerToDisplay[]> {
|
||||||
course.id = parseInt(course.id, 10);
|
course.id = parseInt(course.id, 10);
|
||||||
|
|
||||||
|
@ -269,14 +271,19 @@ export class CoreCourseOptionsDelegate extends CoreDelegate {
|
||||||
// Call getHandlersForAccess to make sure the handlers have been loaded.
|
// Call getHandlersForAccess to make sure the handlers have been loaded.
|
||||||
return this.getHandlersForAccess(course.id, refresh, accessData, course.navOptions, course.admOptions);
|
return this.getHandlersForAccess(course.id, refresh, accessData, course.navOptions, course.admOptions);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const handlersToDisplay: CoreCourseOptionsHandlerToDisplay[] = [];
|
const handlersToDisplay: CoreCourseOptionsHandlerToDisplay[] = [],
|
||||||
|
promises = [];
|
||||||
|
|
||||||
this.coursesHandlers[course.id].enabledHandlers.forEach((handler) => {
|
this.coursesHandlers[course.id].enabledHandlers.forEach((handler) => {
|
||||||
handlersToDisplay.push({
|
promises.push(Promise.resolve(handler.getDisplayData(injector, course)).then((data) => {
|
||||||
data: handler.getDisplayData(course),
|
handlersToDisplay.push({
|
||||||
priority: handler.priority,
|
data: data,
|
||||||
prefetch: handler.prefetch
|
priority: handler.priority,
|
||||||
});
|
prefetch: handler.prefetch
|
||||||
|
});
|
||||||
|
}).catch((err) => {
|
||||||
|
this.logger.error('Error getting data for handler', handler.name, err);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort them by priority.
|
// Sort them by priority.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreCoursesProvider } from '../../providers/courses';
|
import { CoreCoursesProvider } from '../../providers/courses';
|
||||||
|
@ -31,7 +31,8 @@ import { CoreCoursesProvider } from '../../providers/courses';
|
||||||
export class CoreCoursesCourseListItemComponent implements OnInit {
|
export class CoreCoursesCourseListItemComponent implements OnInit {
|
||||||
@Input() course: any; // The course to render.
|
@Input() course: any; // The course to render.
|
||||||
|
|
||||||
constructor(private navCtrl: NavController, private translate: TranslateService, private coursesProvider: CoreCoursesProvider) {
|
constructor(@Optional() private navCtrl: NavController, private translate: TranslateService,
|
||||||
|
private coursesProvider: CoreCoursesProvider) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
import { Component, Input, OnInit, OnDestroy, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
|
@ -44,7 +44,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
|
||||||
protected isDestroyed = false;
|
protected isDestroyed = false;
|
||||||
protected courseStatusObserver;
|
protected courseStatusObserver;
|
||||||
|
|
||||||
constructor(private navCtrl: NavController, private courseHelper: CoreCourseHelperProvider,
|
constructor(@Optional() private navCtrl: NavController, private courseHelper: CoreCourseHelperProvider,
|
||||||
private courseFormatDelegate: CoreCourseFormatDelegate, private domUtils: CoreDomUtilsProvider,
|
private courseFormatDelegate: CoreCourseFormatDelegate, private domUtils: CoreDomUtilsProvider,
|
||||||
private courseProvider: CoreCourseProvider, eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) {
|
private courseProvider: CoreCourseProvider, eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) {
|
||||||
// Listen for status change in course.
|
// Listen for status change in course.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, Output, OnChanges, EventEmitter, SimpleChange } from '@angular/core';
|
import { Component, Input, Output, OnChanges, EventEmitter, SimpleChange, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
|
@ -43,9 +43,10 @@ export class CoreCoursesOverviewEventsComponent implements OnChanges {
|
||||||
next30Days: any[] = [];
|
next30Days: any[] = [];
|
||||||
future: any[] = [];
|
future: any[] = [];
|
||||||
|
|
||||||
constructor(private navCtrl: NavController, private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider,
|
constructor(@Optional() private navCtrl: NavController, private utils: CoreUtilsProvider,
|
||||||
private domUtils: CoreDomUtilsProvider, private sitesProvider: CoreSitesProvider,
|
private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider,
|
||||||
private courseProvider: CoreCourseProvider, private contentLinksHelper: CoreContentLinksHelperProvider) {
|
private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
|
||||||
|
private contentLinksHelper: CoreContentLinksHelperProvider) {
|
||||||
this.loadMore = new EventEmitter();
|
this.loadMore = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,9 @@ export class CoreGradesCourseComponent {
|
||||||
gradesTable: any;
|
gradesTable: any;
|
||||||
|
|
||||||
constructor(private gradesProvider: CoreGradesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams,
|
constructor(private gradesProvider: CoreGradesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams,
|
||||||
private gradesHelper: CoreGradesHelperProvider, private sitesProvider: CoreSitesProvider, private navCtrl: NavController,
|
private gradesHelper: CoreGradesHelperProvider, private sitesProvider: CoreSitesProvider,
|
||||||
private appProvider: CoreAppProvider, @Optional() private svComponent: CoreSplitViewComponent) {
|
@Optional() private navCtrl: NavController, private appProvider: CoreAppProvider,
|
||||||
|
@Optional() private svComponent: CoreSplitViewComponent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '../../course/providers/options-delegate';
|
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '../../course/providers/options-delegate';
|
||||||
import { CoreCourseProvider } from '../../course/providers/course';
|
import { CoreCourseProvider } from '../../course/providers/course';
|
||||||
|
@ -80,9 +80,11 @@ export class CoreGradesCourseOptionHandler implements CoreCourseOptionsHandler {
|
||||||
/**
|
/**
|
||||||
* Returns the data needed to render the handler.
|
* Returns the data needed to render the handler.
|
||||||
*
|
*
|
||||||
* @return {CoreCourseOptionsHandlerData} Data needed to render the handler.
|
* @param {Injector} injector Injector.
|
||||||
|
* @param {number} courseId The course ID.
|
||||||
|
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
|
||||||
*/
|
*/
|
||||||
getDisplayData(): CoreCourseOptionsHandlerData {
|
getDisplayData(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> {
|
||||||
return {
|
return {
|
||||||
title: 'core.grades.grades',
|
title: 'core.grades.grades',
|
||||||
class: 'core-grades-course-handler',
|
class: 'core-grades-course-handler',
|
||||||
|
|
|
@ -62,7 +62,7 @@ export class CoreSiteAddonsCallWSNewContentDirective extends CoreSiteAddonsCallW
|
||||||
|
|
||||||
constructor(element: ElementRef, translate: TranslateService, domUtils: CoreDomUtilsProvider,
|
constructor(element: ElementRef, translate: TranslateService, domUtils: CoreDomUtilsProvider,
|
||||||
siteAddonsProvider: CoreSiteAddonsProvider, @Optional() parentContent: CoreSiteAddonsAddonContentComponent,
|
siteAddonsProvider: CoreSiteAddonsProvider, @Optional() parentContent: CoreSiteAddonsAddonContentComponent,
|
||||||
protected utils: CoreUtilsProvider, protected navCtrl: NavController) {
|
protected utils: CoreUtilsProvider, @Optional() protected navCtrl: NavController) {
|
||||||
super(element, translate, domUtils, siteAddonsProvider, parentContent);
|
super(element, translate, domUtils, siteAddonsProvider, parentContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core';
|
import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreDomUtilsProvider } from '../../../providers/utils/dom';
|
import { CoreDomUtilsProvider } from '../../../providers/utils/dom';
|
||||||
import { CoreUtilsProvider } from '../../../providers/utils/utils';
|
import { CoreUtilsProvider } from '../../../providers/utils/utils';
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class CoreSiteAddonsNewContentDirective implements OnInit {
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
constructor(element: ElementRef, protected utils: CoreUtilsProvider, protected navCtrl: NavController,
|
constructor(element: ElementRef, protected utils: CoreUtilsProvider, @Optional() protected navCtrl: NavController,
|
||||||
@Optional() protected parentContent: CoreSiteAddonsAddonContentComponent, protected domUtils: CoreDomUtilsProvider,
|
@Optional() protected parentContent: CoreSiteAddonsAddonContentComponent, protected domUtils: CoreDomUtilsProvider,
|
||||||
protected siteAddonsProvider: CoreSiteAddonsProvider) {
|
protected siteAddonsProvider: CoreSiteAddonsProvider) {
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
|
|
|
@ -43,6 +43,9 @@ import { CoreCoursesProvider } from '../../courses/providers/courses';
|
||||||
* addons.
|
* addons.
|
||||||
*
|
*
|
||||||
* This code is split from CoreSiteAddonsProvider to prevent circular dependencies.
|
* This code is split from CoreSiteAddonsProvider to prevent circular dependencies.
|
||||||
|
*
|
||||||
|
* @todo: Support ViewChild and similar in site addons. Possible solution: make components and directives inject the instance
|
||||||
|
* inside the host DOM element?
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CoreSiteAddonsHelperProvider {
|
export class CoreSiteAddonsHelperProvider {
|
||||||
|
@ -337,7 +340,7 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
displaySectionSelector: (course: any): boolean => {
|
displaySectionSelector: (course: any): boolean => {
|
||||||
return typeof handlerSchema.displaysectionselector != 'undefined' ? handlerSchema.displaysectionselector : true;
|
return typeof handlerSchema.displaysectionselector != 'undefined' ? handlerSchema.displaysectionselector : true;
|
||||||
},
|
},
|
||||||
getCourseFormatComponent: (course: any): any => {
|
getCourseFormatComponent: (injector: Injector, course: any): any | Promise<any> => {
|
||||||
if (handlerSchema.method) {
|
if (handlerSchema.method) {
|
||||||
return CoreSiteAddonsCourseFormatComponent;
|
return CoreSiteAddonsCourseFormatComponent;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +380,8 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
: boolean | Promise<boolean> => {
|
: boolean | Promise<boolean> => {
|
||||||
return this.isHandlerEnabledForCourse(courseId, handlerSchema.restricttoenrolledcourses, bootstrapResult.restrict);
|
return this.isHandlerEnabledForCourse(courseId, handlerSchema.restricttoenrolledcourses, bootstrapResult.restrict);
|
||||||
},
|
},
|
||||||
getDisplayData: (courseId: number): CoreCourseOptionsHandlerData => {
|
getDisplayData: (injector: Injector, courseId: number):
|
||||||
|
CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> => {
|
||||||
return {
|
return {
|
||||||
title: prefixedTitle,
|
title: prefixedTitle,
|
||||||
class: handlerSchema.displaydata.class,
|
class: handlerSchema.displaydata.class,
|
||||||
|
@ -488,7 +492,7 @@ export class CoreSiteAddonsHelperProvider {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getMainComponent: (course: any, module: any): any => {
|
getMainComponent: (injector: Injector, course: any, module: any): any | Promise<any> => {
|
||||||
return CoreSiteAddonsModuleIndexComponent;
|
return CoreSiteAddonsModuleIndexComponent;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -144,7 +144,10 @@ export class CoreSiteAddonsProvider {
|
||||||
*/
|
*/
|
||||||
createDataForJS(bootstrapResult: any, contentResult?: any): any {
|
createDataForJS(bootstrapResult: any, contentResult?: any): any {
|
||||||
// First of all, add the data returned by the bootstrap JS (if any).
|
// First of all, add the data returned by the bootstrap JS (if any).
|
||||||
const data = this.utils.clone(bootstrapResult.jsResult || {});
|
let data = this.utils.clone(bootstrapResult.jsResult || {});
|
||||||
|
if (typeof data == 'boolean') {
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
|
|
||||||
// Now add some data returned by the bootstrap WS call.
|
// Now add some data returned by the bootstrap WS call.
|
||||||
data.BOOTSTRAP_TEMPLATES = this.utils.objectToKeyValueMap(bootstrapResult.templates, 'id', 'html');
|
data.BOOTSTRAP_TEMPLATES = this.utils.objectToKeyValueMap(bootstrapResult.templates, 'id', 'html');
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit, Injector } from '@angular/core';
|
||||||
import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate';
|
import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
|
||||||
|
@ -33,13 +33,16 @@ export class CoreUserProfileFieldComponent implements OnInit {
|
||||||
componentClass: any; // The class of the component to render.
|
componentClass: any; // The class of the component to render.
|
||||||
data: any = {}; // Data to pass to the component.
|
data: any = {}; // Data to pass to the component.
|
||||||
|
|
||||||
constructor(private ufDelegate: CoreUserProfileFieldDelegate, private utilsProvider: CoreUtilsProvider) { }
|
constructor(private ufDelegate: CoreUserProfileFieldDelegate, private utilsProvider: CoreUtilsProvider,
|
||||||
|
private injector: Injector) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.componentClass = this.ufDelegate.getComponent(this.field, this.signup);
|
this.ufDelegate.getComponent(this.injector, this.field, this.signup).then((component) => {
|
||||||
|
this.componentClass = component;
|
||||||
|
});
|
||||||
|
|
||||||
this.data.field = this.field;
|
this.data.field = this.field;
|
||||||
this.data.edit = this.utilsProvider.isTrueOrOne(this.edit);
|
this.data.edit = this.utilsProvider.isTrueOrOne(this.edit);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '../../course/providers/options-delegate';
|
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '../../course/providers/options-delegate';
|
||||||
import { CoreCourseProvider } from '../../course/providers/course';
|
import { CoreCourseProvider } from '../../course/providers/course';
|
||||||
|
@ -79,9 +79,11 @@ export class CoreUserParticipantsCourseOptionHandler implements CoreCourseOption
|
||||||
/**
|
/**
|
||||||
* Returns the data needed to render the handler.
|
* Returns the data needed to render the handler.
|
||||||
*
|
*
|
||||||
* @return {CoreCourseOptionsHandlerData} Data needed to render the handler.
|
* @param {Injector} injector Injector.
|
||||||
|
* @param {number} courseId The course ID.
|
||||||
|
* @return {CoreCourseOptionsHandlerData|Promise<CoreCourseOptionsHandlerData>} Data or promise resolved with the data.
|
||||||
*/
|
*/
|
||||||
getDisplayData(): CoreCourseOptionsHandlerData {
|
getDisplayData(injector: Injector, courseId: number): CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> {
|
||||||
return {
|
return {
|
||||||
title: 'core.user.participants',
|
title: 'core.user.participants',
|
||||||
class: 'core-user-participants-handler',
|
class: 'core-user-participants-handler',
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
|
@ -22,10 +22,12 @@ export interface CoreUserProfileFieldHandler extends CoreDelegateHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Component to use to display the user profile field.
|
* Return the Component to use to display the user profile field.
|
||||||
|
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||||
*
|
*
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @param {Injector} injector Injector.
|
||||||
|
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(): any;
|
getComponent(injector: Injector): any | Promise<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data to send for the field based on the input data.
|
* Get the data to send for the field based on the input data.
|
||||||
|
@ -75,17 +77,23 @@ export class CoreUserProfileFieldDelegate extends CoreDelegate {
|
||||||
/**
|
/**
|
||||||
* Get the component to use to display an user field.
|
* Get the component to use to display an user field.
|
||||||
*
|
*
|
||||||
|
* @param {Injector} injector Injector.
|
||||||
* @param {any} field User field to get the directive for.
|
* @param {any} field User field to get the directive for.
|
||||||
* @param {boolean} signup True if user is in signup page.
|
* @param {boolean} signup True if user is in signup page.
|
||||||
* @return {any} The component to use, undefined if not found.
|
* @return {Promise<any>} Promise resolved with component to use, undefined if not found.
|
||||||
*/
|
*/
|
||||||
getComponent(field: any, signup: boolean): any {
|
getComponent(injector: Injector, field: any, signup: boolean): Promise<any> {
|
||||||
const type = field.type || field.datatype;
|
const type = field.type || field.datatype;
|
||||||
|
let result;
|
||||||
if (signup) {
|
if (signup) {
|
||||||
return this.executeFunction(type, 'getComponent');
|
result = this.executeFunction(type, 'getComponent', [injector]);
|
||||||
} else {
|
} else {
|
||||||
return this.executeFunctionOnEnabled(type, 'getComponent');
|
result = this.executeFunctionOnEnabled(type, 'getComponent', [injector]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(result).catch((err) => {
|
||||||
|
this.logger.error('Error getting component for field', type, err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
@ -31,7 +31,7 @@ export class CoreAutoFocusDirective implements OnInit {
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
||||||
private navCtrl: NavController) {
|
@Optional() private navCtrl: NavController) {
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
|
||||||
import { CoreFileHelperProvider } from '../providers/file-helper';
|
import { CoreFileHelperProvider } from '../providers/file-helper';
|
||||||
import { CoreDomUtilsProvider } from '../providers/utils/dom';
|
import { CoreDomUtilsProvider } from '../providers/utils/dom';
|
||||||
import { CoreUtilsProvider } from '../providers/utils/utils';
|
import { CoreUtilsProvider } from '../providers/utils/utils';
|
||||||
|
|
|
@ -62,7 +62,7 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private platform: Platform,
|
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private platform: Platform,
|
||||||
private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private loggerProvider: CoreLoggerProvider,
|
private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private loggerProvider: CoreLoggerProvider,
|
||||||
private filepoolProvider: CoreFilepoolProvider, private appProvider: CoreAppProvider,
|
private filepoolProvider: CoreFilepoolProvider, private appProvider: CoreAppProvider,
|
||||||
private contentLinksHelper: CoreContentLinksHelperProvider, private navCtrl: NavController,
|
private contentLinksHelper: CoreContentLinksHelperProvider, @Optional() private navCtrl: NavController,
|
||||||
@Optional() private content: Content) {
|
@Optional() private content: Content) {
|
||||||
this.element = element.nativeElement;
|
this.element = element.nativeElement;
|
||||||
this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
|
this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
|
||||||
|
|
|
@ -39,7 +39,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
|
|
||||||
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
constructor(element: ElementRef, private domUtils: CoreDomUtilsProvider, private utils: CoreUtilsProvider,
|
||||||
private sitesProvider: CoreSitesProvider, private urlUtils: CoreUrlUtilsProvider,
|
private sitesProvider: CoreSitesProvider, private urlUtils: CoreUrlUtilsProvider,
|
||||||
private contentLinksHelper: CoreContentLinksHelperProvider, private navCtrl: NavController,
|
private contentLinksHelper: CoreContentLinksHelperProvider, @Optional() private navCtrl: NavController,
|
||||||
@Optional() private content: Content) {
|
@Optional() private content: Content) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
|
import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ export class CoreUserLinkDirective implements OnInit {
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
|
|
||||||
constructor(element: ElementRef, private navCtrl: NavController) {
|
constructor(element: ElementRef, @Optional() private navCtrl: NavController) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue