Skip to content

Platform filters #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ng-sample/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {ImageTest} from "./examples/image/image-test";
import {NavigationTest} from "./examples/navigation/navigation-test";
import {ActionBarTest} from "./examples/action-bar/action-bar-test";
import {ModalTest} from "./examples/modal/modal-test";
import {PlatfromDirectivesTest} from "./examples/platform-directives/platform-directives-test";

nativeScriptBootstrap(RendererTest);
//nativeScriptBootstrap(Benchmark);
Expand All @@ -34,5 +35,6 @@ nativeScriptBootstrap(RendererTest);
//nativeScriptBootstrap(ListTestAsync);
//nativeScriptBootstrap(ImageTest);
//nativeScriptBootstrap(NavigationTest, [NS_ROUTER_PROVIDERS]);
//nativeScriptBootstrap(ActionBarTest, [NS_ROUTER_PROVIDERS], { startPageActionBarHidden: false });
// nativeScriptBootstrap(ActionBarTest, [NS_ROUTER_PROVIDERS], { startPageActionBarHidden: false });
// nativeScriptBootstrap(ModalTest);
// nativeScriptBootstrap(PlatfromDirectivesTest);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Component} from 'angular2/core';

@Component({
selector: 'action-bar-test',
template: `
<StackLayout>
<android><Label text="This is Android specific content"></Label></android>
<ios><Label text="This is IOS specific content"></Label></ios>
<Label
android:text="Android specific attribute"
ios:text="Ios specific attribute"></Label>
</StackLayout>
`
})
export class PlatfromDirectivesTest {
}


2 changes: 1 addition & 1 deletion ng-sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"homepage": "https://github.com/NativeScript/template-hello-world",
"dependencies": {
"tns-core-modules": "^2.0.0-angular-1",
"tns-core-modules": "^2.0.0-angular-2",
"nativescript-intl": "^0.0.2",
"angular2": "2.0.0-beta.9",
"parse5": "1.4.2",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"scripts": {},
"dependencies": {
"tns-core-modules": "^2.0.0-angular-1",
"tns-core-modules": "^2.0.0-angular-2",
"nativescript-intl": "^0.0.2",
"angular2": "2.0.0-beta.9",
"es6-shim": "^0.33.3",
Expand Down
3 changes: 2 additions & 1 deletion src/nativescript-angular/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import application = require('application');

export type ProviderArray = Array<Type | Provider | any[]>;

import {defaultPageProvider} from "./platform-providers";
import {defaultPageProvider, defaultDeviceProvider} from "./platform-providers";

import * as nativescriptIntl from "nativescript-intl";
global.Intl = nativescriptIntl;
Expand Down Expand Up @@ -68,6 +68,7 @@ export function bootstrap(appComponentType: any,
provide(ExceptionHandler, {useFactory: () => new ExceptionHandler(DOM, true), deps: []}),

defaultPageProvider,
defaultDeviceProvider,
NativeScriptRootRenderer,
provide(RootRenderer, {useClass: NativeScriptRootRenderer}),
NativeScriptRenderer,
Expand Down
5 changes: 4 additions & 1 deletion src/nativescript-angular/directives/ns-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {NumberValueAccessor} from '../value-accessors/number-value-accessor';
import {SelectedIndexValueAccessor} from '../value-accessors/selectedIndex-value-accessor';
import {TabViewDirective, TabViewItemDirective} from './tab-view';
import {ActionBarComponent, ActionBarScope, ActionItemDirective, NavigationButtonDirective} from './action-bar';
import {AndroidFilterComponent, IosFilterComponent} from './platform-filters';

export const NS_DIRECTIVES: Type[] = [
ListViewComponent,
Expand All @@ -22,5 +23,7 @@ export const NS_DIRECTIVES: Type[] = [
ActionBarComponent,
ActionBarScope,
ActionItemDirective,
NavigationButtonDirective
NavigationButtonDirective,
AndroidFilterComponent,
IosFilterComponent
];
25 changes: 25 additions & 0 deletions src/nativescript-angular/directives/platform-filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Component, Inject} from 'angular2/core';
import {Device, platformNames} from "platform";
import {DEVICE} from "../platform-providers";

@Component({
selector: "android",
template: `<ng-content *ngIf="show"></ng-content>`,
})
export class AndroidFilterComponent {
public show: boolean;
constructor( @Inject(DEVICE) device: Device) {
this.show = (device.os === platformNames.android);
}
}

@Component({
selector: "ios",
template: `<ng-content *ngIf="show"></ng-content>`,
})
export class IosFilterComponent {
public show: boolean;
constructor( @Inject(DEVICE) device: Device) {
this.show = (device.os === platformNames.ios);
}
}
7 changes: 6 additions & 1 deletion src/nativescript-angular/platform-providers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {topmost} from 'ui/frame';
import {Page} from 'ui/page';
import {provide, Provider, OpaqueToken} from 'angular2/src/core/di';
import {Device, ScreenMetrics, device, screen} from "platform";

export const APP_ROOT_VIEW = new OpaqueToken('App Root View');
export const DEVICE = new OpaqueToken('platfrom device');

export const defaultPageProvider = provide(Page, {useFactory: getDefaultPage});
export const defaultPageProvider = provide(Page, { useFactory: getDefaultPage });

export function getDefaultPage(): Page {
const frame = topmost();
Expand All @@ -14,3 +16,6 @@ export function getDefaultPage(): Page {
return null;
}
}

export const defaultDeviceProvider = provide(DEVICE, { useValue: device });

121 changes: 67 additions & 54 deletions src/nativescript-angular/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,28 @@ import {
RenderComponentType,
RenderDebugInfo
} from 'angular2/src/core/render/api';
import {APP_ROOT_VIEW} from "./platform-providers";
import {APP_ROOT_VIEW, DEVICE} from "./platform-providers";
import {isBlank} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {COMPONENT_VARIABLE, CONTENT_ATTR} from 'angular2/src/platform/dom/dom_renderer';
import {View} from "ui/core/view";
import * as application from "application";
import {topmost} from 'ui/frame';
import {Page} from 'ui/page';
import * as util from "./view-util";
import {traceLog, ViewUtil, NgView} from "./view-util";
import {escapeRegexSymbols} from "utils/utils";
import { Device } from "platform";

export { rendererTraceCategory } from "./view-util";

@Injectable()
export class NativeScriptRootRenderer implements RootRenderer {
private _rootView: View = null;
constructor(@Optional() @Inject(APP_ROOT_VIEW) rootView: View) {
private _viewUtil: ViewUtil;

constructor( @Optional() @Inject(APP_ROOT_VIEW) rootView: View, @Inject(DEVICE) device: Device) {
this._rootView = rootView;
this._viewUtil = new ViewUtil(device);
}

private _registeredComponents: Map<string, NativeScriptRenderer> = new Map<string, NativeScriptRenderer>();
Expand All @@ -38,6 +42,10 @@ export class NativeScriptRootRenderer implements RootRenderer {
return <Page>this.rootView.page;
}

public get viewUtil(): ViewUtil {
return this._viewUtil;
}

renderComponent(componentProto: RenderComponentType): Renderer {
var renderer = this._registeredComponents.get(componentProto.id);
if (isBlank(renderer)) {
Expand All @@ -53,140 +61,145 @@ export class NativeScriptRenderer extends Renderer {
private componentProtoId: string;
private hasComponentStyles: boolean;
private rootRenderer: NativeScriptRootRenderer;

private get viewUtil(): ViewUtil {
return this.rootRenderer.viewUtil;
}

constructor(private _rootRenderer: NativeScriptRootRenderer, private componentProto: RenderComponentType) {
super();
this.rootRenderer = _rootRenderer;
let page = this.rootRenderer.page;
let stylesLength = componentProto.styles.length;
this.componentProtoId = componentProto.id;
for(let i = 0; i < stylesLength; i++) {
for (let i = 0; i < stylesLength; i++) {
this.hasComponentStyles = true;
let cssString = componentProto.styles[i] + "";
const realCSS = this.replaceNgAttribute(cssString, this.componentProtoId);
application.addCss(realCSS);
}
util.traceLog('NativeScriptRenderer created');
traceLog('NativeScriptRenderer created');
}

private attrReplacer = new RegExp(escapeRegexSymbols(CONTENT_ATTR), "g");
private attrSanitizer = /-/g;

private replaceNgAttribute(input: string, componentId: string): string {
return input.replace(this.attrReplacer,
"_ng_content_" + componentId.replace(this.attrSanitizer, "_"));
"_ng_content_" + componentId.replace(this.attrSanitizer, "_"));
}

renderComponent(componentProto: RenderComponentType): Renderer {
return this._rootRenderer.renderComponent(componentProto);
}

selectRootElement(selector: string): util.NgView {
util.traceLog('selectRootElement: ' + selector);
const rootView = <util.NgView><any>this.rootRenderer.rootView;
selectRootElement(selector: string): NgView {
traceLog('selectRootElement: ' + selector);
const rootView = <NgView><any>this.rootRenderer.rootView;
rootView.nodeName = 'ROOT';
return rootView;
}

createViewRoot(hostElement: util.NgView): util.NgView {
util.traceLog('CREATE VIEW ROOT: ' + hostElement.nodeName);
createViewRoot(hostElement: NgView): NgView {
traceLog('CREATE VIEW ROOT: ' + hostElement.nodeName);
return hostElement;
}

projectNodes(parentElement: util.NgView, nodes: util.NgView[]): void {
util.traceLog('NativeScriptRenderer.projectNodes');
projectNodes(parentElement: NgView, nodes: NgView[]): void {
traceLog('NativeScriptRenderer.projectNodes');
nodes.forEach((node) => {
util.insertChild(parentElement, node);
this.viewUtil.insertChild(parentElement, node);
});
}

attachViewAfter(anchorNode: util.NgView, viewRootNodes: util.NgView[]) {
util.traceLog('NativeScriptRenderer.attachViewAfter: ' + anchorNode.nodeName + ' ' + anchorNode);
const parent = (<util.NgView>anchorNode.parent || anchorNode.templateParent);
const insertPosition = util.getChildIndex(parent, anchorNode);
attachViewAfter(anchorNode: NgView, viewRootNodes: NgView[]) {
traceLog('NativeScriptRenderer.attachViewAfter: ' + anchorNode.nodeName + ' ' + anchorNode);
const parent = (<NgView>anchorNode.parent || anchorNode.templateParent);
const insertPosition = this.viewUtil.getChildIndex(parent, anchorNode);

viewRootNodes.forEach((node, index) => {
const childIndex = insertPosition + index + 1;
util.insertChild(parent, node, childIndex);
this.viewUtil.insertChild(parent, node, childIndex);
this.animateNodeEnter(node);
});
}

detachView(viewRootNodes: util.NgView[]) {
util.traceLog('NativeScriptRenderer.detachView');
detachView(viewRootNodes: NgView[]) {
traceLog('NativeScriptRenderer.detachView');
for (var i = 0; i < viewRootNodes.length; i++) {
var node = viewRootNodes[i];
util.removeChild(<util.NgView>node.parent, node);
this.viewUtil.removeChild(<NgView>node.parent, node);
this.animateNodeLeave(node);
}
}

animateNodeEnter(node: util.NgView) {
animateNodeEnter(node: NgView) {
}

animateNodeLeave(node: util.NgView) {
animateNodeLeave(node: NgView) {
}

public destroyView(hostElement: util.NgView, viewAllNodes: util.NgView[]) {
util.traceLog("NativeScriptRenderer.destroyView");
public destroyView(hostElement: NgView, viewAllNodes: NgView[]) {
traceLog("NativeScriptRenderer.destroyView");
// Seems to be called on component dispose only (router outlet)
//TODO: handle this when we resolve routing and navigation.
}

setElementProperty(renderElement: util.NgView, propertyName: string, propertyValue: any) {
util.traceLog("NativeScriptRenderer.setElementProperty " + renderElement + ': ' + propertyName + " = " + propertyValue);
util.setProperty(renderElement, propertyName, propertyValue);
setElementProperty(renderElement: NgView, propertyName: string, propertyValue: any) {
traceLog("NativeScriptRenderer.setElementProperty " + renderElement + ': ' + propertyName + " = " + propertyValue);
this.viewUtil.setProperty(renderElement, propertyName, propertyValue);
}

setElementAttribute(renderElement: util.NgView, attributeName: string, attributeValue: string) {
util.traceLog("NativeScriptRenderer.setElementAttribute " + renderElement + ': ' + attributeName + " = " + attributeValue);
setElementAttribute(renderElement: NgView, attributeName: string, attributeValue: string) {
traceLog("NativeScriptRenderer.setElementAttribute " + renderElement + ': ' + attributeName + " = " + attributeValue);
return this.setElementProperty(renderElement, attributeName, attributeValue);
}

setElementClass(renderElement: util.NgView, className: string, isAdd: boolean): void {
util.traceLog("NativeScriptRenderer.setElementClass " + className + " - " + isAdd);
setElementClass(renderElement: NgView, className: string, isAdd: boolean): void {
traceLog("NativeScriptRenderer.setElementClass " + className + " - " + isAdd);

if (isAdd) {
util.addClass(renderElement, className);
this.viewUtil.addClass(renderElement, className);
} else {
util.removeClass(renderElement, className);
this.viewUtil.removeClass(renderElement, className);
}
}

setElementStyle(renderElement: util.NgView, styleName: string, styleValue: string): void {
util.setStyleProperty(renderElement, styleName, styleValue);
setElementStyle(renderElement: NgView, styleName: string, styleValue: string): void {
this.viewUtil.setStyleProperty(renderElement, styleName, styleValue);
}

/**
* Used only in debug mode to serialize property changes to comment nodes,
* such as <template> placeholders.
*/
setBindingDebugInfo(renderElement: util.NgView, propertyName: string, propertyValue: string): void {
util.traceLog('NativeScriptRenderer.setBindingDebugInfo: ' + renderElement + ', ' + propertyName + ' = ' + propertyValue);
setBindingDebugInfo(renderElement: NgView, propertyName: string, propertyValue: string): void {
traceLog('NativeScriptRenderer.setBindingDebugInfo: ' + renderElement + ', ' + propertyName + ' = ' + propertyValue);
}

setElementDebugInfo(renderElement: any, info: RenderDebugInfo): void {
util.traceLog('NativeScriptRenderer.setElementDebugInfo: ' + renderElement);
traceLog('NativeScriptRenderer.setElementDebugInfo: ' + renderElement);
}

/**
* Calls a method on an element.
*/
invokeElementMethod(renderElement: util.NgView, methodName: string, args: Array<any>) {
util.traceLog("NativeScriptRenderer.invokeElementMethod " + methodName + " " + args);
invokeElementMethod(renderElement: NgView, methodName: string, args: Array<any>) {
traceLog("NativeScriptRenderer.invokeElementMethod " + methodName + " " + args);
}

setText(renderNode: any, text: string) {
util.traceLog("NativeScriptRenderer.setText");
traceLog("NativeScriptRenderer.setText");
}

public createTemplateAnchor(parentElement: util.NgView): util.NgView {
util.traceLog('NativeScriptRenderer.createTemplateAnchor');
return util.createTemplateAnchor(parentElement);
public createTemplateAnchor(parentElement: NgView): NgView {
traceLog('NativeScriptRenderer.createTemplateAnchor');
return this.viewUtil.createTemplateAnchor(parentElement);
}

public createElement(parentElement: util.NgView, name: string): util.NgView {
util.traceLog('NativeScriptRenderer.createElement: ' + name + ' parent: ' + parentElement + ', ' + (parentElement ? parentElement.nodeName : 'null'));
return util.createView(name, parentElement, (view) => {
public createElement(parentElement: NgView, name: string): NgView {
traceLog('NativeScriptRenderer.createElement: ' + name + ' parent: ' + parentElement + ', ' + (parentElement ? parentElement.nodeName : 'null'));
return this.viewUtil.createView(name, parentElement, (view) => {
// Set an attribute to the view to scope component-specific css.
// The property name is pre-generated by Angular.
if (this.hasComponentStyles) {
Expand All @@ -196,13 +209,13 @@ export class NativeScriptRenderer extends Renderer {
});
}

public createText(value: string): util.NgView {
util.traceLog('NativeScriptRenderer.createText');
return util.createText(value);;
public createText(value: string): NgView {
traceLog('NativeScriptRenderer.createText');
return this.viewUtil.createText(value);;
}

public listen(renderElement: util.NgView, eventName: string, callback: Function): Function {
util.traceLog('NativeScriptRenderer.listen: ' + eventName);
public listen(renderElement: NgView, eventName: string, callback: Function): Function {
traceLog('NativeScriptRenderer.listen: ' + eventName);
let zonedCallback = (<any>global).zone.bind(callback);
renderElement.on(eventName, zonedCallback);
return () => renderElement.off(eventName, zonedCallback);
Expand Down
Loading