zoid
Version:
Cross domain components.
98 lines (74 loc) • 3.03 kB
JavaScript
/* @flow */
import { dasherizeToCamel, replaceObject } from 'belter/src';
import type { Component, ComponentDriverType } from '../component/component';
import { CONTEXT } from '../constants';
type AngularModule = {
directive : (string, () => {
scope : { [string] : '=' | '@' },
restrict : string,
controller : Array<string | Function>
}) => AngularModule
};
type Angular = {
module : (string, Array<string>) => AngularModule
};
export let angular : ComponentDriverType<*, Angular> = {
global() : ?Angular {
return window.angular;
},
register(component : Component<*>, ng : Angular) : AngularModule {
let module = ng.module(component.tag, []).directive(dasherizeToCamel(component.tag), () => {
let scope = {};
for (let key of component.getPropNames()) {
scope[key] = '=';
}
scope.props = '=';
return {
scope,
restrict: 'E',
controller: [ '$scope', '$element', ($scope, $element) => {
component.log(`instantiate_angular_component`);
function safeApply() {
if ($scope.$root.$$phase !== '$apply' && $scope.$root.$$phase !== '$digest') {
try {
$scope.$apply();
} catch (err) {
// pass
}
}
}
let getProps = () => {
let scopeProps;
if ($scope.props) {
scopeProps = $scope.props;
} else {
scopeProps = {};
for (let key of Object.keys(scope)) {
if ($scope[key] !== undefined) {
scopeProps[key] = $scope[key];
}
}
}
scopeProps = replaceObject(scopeProps, item => {
if (typeof item === 'function') {
return function angularWrapped() : mixed {
let result = item.apply(this, arguments);
safeApply();
return result;
};
}
return item;
});
return scopeProps;
};
let parent = component.init(getProps(), null, $element[0]);
parent.render(CONTEXT.IFRAME, $element[0]);
$scope.$watch(() => {
parent.updateProps(getProps());
});
} ]
};
});
return module;
}
};