Skip to content

Commit

Permalink
changes dart-archive#1
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb committed Apr 24, 2014
1 parent dbce753 commit 9a81af3
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 194 deletions.
16 changes: 15 additions & 1 deletion lib/change_detection/dirty_checking_change_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library dirty_checking_change_detector;

import 'dart:collection';
import 'package:angular/change_detection/change_detection.dart';
import 'package:angular/change_detection/watch_group.dart';

/**
* [DirtyCheckingChangeDetector] determines which object properties have changed
Expand Down Expand Up @@ -369,7 +370,7 @@ class _ChangeIterator<H> implements Iterator<Record<H>>{
* removing efficient. [DirtyCheckingRecord] also has a [nextChange] field which
* creates a single linked list of all of the changes for efficient traversal.
*/
class DirtyCheckingRecord<H> implements Record<H>, WatchRecord<H> {
class DirtyCheckingRecord<H> implements WatchRecord<H> {
static const List<String> _MODE_NAMES =
const ['MARKER', 'IDENT', 'GETTER', 'MAP[]', 'ITERABLE', 'MAP'];
static const int _MODE_MARKER_ = 0;
Expand Down Expand Up @@ -456,6 +457,19 @@ class DirtyCheckingRecord<H> implements Record<H>, WatchRecord<H> {
return;
}

while (obj is LocalContext) {
var ctx = obj as LocalContext;
if (ctx.hasProperty(field)) {
_object = obj;
_mode = _MODE_MAP_FIELD_;
_getter = null;
return;
}
obj = ctx.parent;
}

if (obj == null) throw "$field property does not exist on $_object";

if (obj is Map) {
_mode = _MODE_MAP_FIELD_;
_getter = null;
Expand Down
46 changes: 18 additions & 28 deletions lib/change_detection/prototype_map.dart
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
part of angular.watch_group;

class PrototypeMap<K, V> implements Map<K,V> {
final Map<K, V> prototype;
final Map<K, V> self = new Map();
// todo(vicb) rename to ContextLocals + rename the file
class LocalContext {
// todo(vicb) _parentContext
final Object parent;
final Map _locals = <String, Object>{};

PrototypeMap(this.prototype);

void operator []=(name, value) {
self[name] = value;
LocalContext(this.parent, [Map<String, Object> locals = null]) {
if (locals != null) _locals.addAll(locals);
_locals[r'$parent'] = parent;
}
V operator [](name) => self.containsKey(name) ? self[name] : prototype[name];

bool get isEmpty => self.isEmpty && prototype.isEmpty;
bool get isNotEmpty => self.isNotEmpty || prototype.isNotEmpty;
// todo(vbe) include prototype keys ?
Iterable<K> get keys => self.keys;
// todo(vbe) include prototype values ?
Iterable<V> get values => self.values;
int get length => self.length;
static LocalContext wrapper(context, Map<String, Object> locals) =>
new LocalContext(context, locals);

bool hasProperty(String prop) => _locals.containsKey(prop);

void forEach(fn) {
// todo(vbe) include prototype ?
self.forEach(fn);
void operator[]=(String prop, value) {
_locals[prop] = value;
}
V remove(key) => self.remove(key);
clear() => self.clear;
// todo(vbe) include prototype ?
bool containsKey(key) => self.containsKey(key);
// todo(vbe) include prototype ?
bool containsValue(key) => self.containsValue(key);
void addAll(map) {
self.addAll(map);

dynamic operator[](String prop) {
assert(hasProperty(prop));
return _locals[prop];
}
// todo(vbe) include prototype ?
V putIfAbsent(key, fn) => self.putIfAbsent(key, fn);
}
6 changes: 4 additions & 2 deletions lib/change_detection/watch_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ part 'prototype_map.dart';
* * [value]: The current value of the watched expression.
* * [previousValue]: The previous value of the watched expression.
*
* If the expression is watching a collection (a list or a map), then [value] is wrapped in
* a [CollectionChangeItem] that lists all the changes.
* Notes:
*
* * [value] is a [CollectionChangeRecord] when a Collection is being watched
* * [value] is a [MapChangeRecord] when a [Map] is being watched
*/
typedef void ReactionFn(value, previousValue);
typedef void ChangeLog(String expression, current, previous);
Expand Down
2 changes: 1 addition & 1 deletion lib/core/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export "package:angular/core/module_internal.dart" show
FilterMap,
Interpolate,
VmTurnZone,
PrototypeMap,
RootScope,
LocalContext,
Scope,
ScopeDigestTTL,
ScopeEvent,
Expand Down
1 change: 1 addition & 0 deletions lib/core/module_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class CoreModule extends Module {
type(ScopeStats);
type(ScopeStatsEmitter);
factory(ScopeStatsConfig, (i) => new ScopeStatsConfig());
// todo (vicb)
value(Object, {}); // RootScope context
type(VmTurnZone);

Expand Down
46 changes: 29 additions & 17 deletions lib/core/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,16 @@ class Scope {
/**
* The default execution context for [watch]es [observe]ers, and [eval]uation.
*/
final context;
// todo(vicb) was final
var _context;

get context => _context;
set context(ctx) {

print("scope: setting context to $ctx");
_context = ctx;

}

/**
* The [RootScope] of the application.
Expand Down Expand Up @@ -182,9 +191,12 @@ class Scope {
/// Do not use. Exposes internal state for testing.
bool get hasOwnStreams => _streams != null && _streams._scope == this;

Scope(Object this.context, this.rootScope, this._parentScope,
// todo(vicb) this.context
Scope(Object _context, this.rootScope, this._parentScope,
this._readWriteGroup, this._readOnlyGroup, this.id,
this._stats);
this._stats) {
context = _context;
}

/**
* Use [watch] to set up change detection on an expression.
Expand All @@ -204,7 +216,7 @@ class Scope {
* by reference. When watching a collection, the reaction function receives a
* [CollectionChangeItem] that lists all the changes.
*/
Watch watch(String expression, ReactionFn reactionFn, {context,
Watch watch(String expression, ReactionFn reactionFn, {context,
FormatterMap formatters, bool canChangeModel: true, bool collection: false}) {
assert(isAttached);
assert(expression is String);
Expand Down Expand Up @@ -244,8 +256,8 @@ class Scope {
expression is String ||
expression is Function);
if (expression is String && expression.isNotEmpty) {
var obj = locals == null ? context : new ScopeLocals(context, locals);
return rootScope._parser(expression).eval(obj);
var ctx = locals == null ? context : new LocalContext(context, locals);
return rootScope._parser(expression).eval(ctx);
}

assert(locals == null);
Expand Down Expand Up @@ -321,7 +333,7 @@ class Scope {
_parentScope = null;
}

_assertInternalStateConsistency() {
void _assertInternalStateConsistency() {
assert((() {
rootScope._verifyStreams(null, '', []);
return true;
Expand Down Expand Up @@ -358,7 +370,7 @@ class Scope {
}
}

_mapEqual(Map a, Map b) => a.length == b.length &&
bool _mapEqual(Map a, Map b) => a.length == b.length &&
a.keys.every((k) => b.containsKey(k) && a[k] == b[k]);

/**
Expand Down Expand Up @@ -399,7 +411,7 @@ class ScopeStats {
processStopwatch.elapsedMicroseconds;
}

_stopwatchReset() {
void _stopwatchReset() {
fieldStopwatch.reset();
evalStopwatch.reset();
processStopwatch.reset();
Expand Down Expand Up @@ -464,9 +476,9 @@ class ScopeStatsEmitter {

static pad(String str, int size) => _PAD_.substring(0, max(size - str.length, 0)) + str;

_ms(num value) => '${pad(_nfDec.format(value), 9)} ms';
_us(num value) => _ms(value / 1000);
_tally(num value) => '${pad(_nfInt.format(value), 6)}';
String _ms(num value) => '${pad(_nfDec.format(value), 9)} ms';
String _us(num value) => _ms(value / 1000);
String _tally(num value) => '${pad(_nfInt.format(value), 6)}';

/**
* Emit a message based on the phase and state of stopwatches.
Expand All @@ -490,9 +502,8 @@ class ScopeStatsEmitter {
return (prefix == '1' ? _HEADER_ : '') + ' #$prefix:';
}

String _stat(AvgStopwatch s) {
return '${_tally(s.count)} / ${_us(s.elapsedMicroseconds)} @(${_tally(s.ratePerMs)} #/ms)';
}
String _stat(AvgStopwatch s) =>
'${_tally(s.count)} / ${_us(s.elapsedMicroseconds)} @(${_tally(s.ratePerMs)} #/ms)';
}

/**
Expand All @@ -503,6 +514,7 @@ class ScopeStatsConfig {
var emit = false;

ScopeStatsConfig();

ScopeStatsConfig.enabled() {
emit = true;
}
Expand Down Expand Up @@ -568,8 +580,8 @@ class RootScope extends Scope {
* followed by change detection
* on non-DOM listeners. Any changes detected are process using the reaction function. The digest
* phase is repeated as long as at least one change has been detected. By default, after 5
* iterations the model is considered unstable and angular exists with an exception. (See
* ScopeDigestTTL)
* iterations the model is considered unstable and angular exits with an exception. (See
* [ScopeDigestTTL])
*
* ##flush
*
Expand Down
3 changes: 2 additions & 1 deletion lib/core_dom/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Injector forceNewDirectivesAndFilters(Injector injector, List<Module> modules) {
modules.add(new Module()
..factory(Scope, (i) {
var scope = i.parent.get(Scope);
return scope.createChild(new PrototypeMap(scope.context));
//todo(vicb)
return scope.createChild(scope.context);
}));

return injector.createChild(modules,
Expand Down
24 changes: 14 additions & 10 deletions lib/core_dom/element_binder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,16 @@ class ElementBinder {
probe.directives.add(controller);
assert((linkMapTimer = _perf.startTimer('ng.view.link.map', ref.type)) != false);


if (ref.annotation is Controller) {
scope.context[(ref.annotation as Controller).publishAs] = controller;
// todo(vicb)
print("_link context = $controller");
scope.context = controller;
}

var tasks = new _TaskList(controller is AttachAware ? () {
if (scope.isAttached) controller.attach();
} : null);
var tasks = new _TaskList(controller is AttachAware ?
() {if (scope.isAttached) controller.attach();} :
null);

_createAttrMappings(controller, scope, ref, nodeAttrs, formatters, tasks);

Expand Down Expand Up @@ -273,16 +276,17 @@ class ElementBinder {

directiveRefs.forEach((DirectiveRef ref) {
Directive annotation = ref.annotation;
var visibility = ref.annotation.visibility;
if (ref.annotation is Controller) {
scope = scope.createChild(new PrototypeMap(scope.context));

if (annotation is Controller) {
//todo(vicb)
scope = scope.createChild(scope.context);
nodeModule.value(Scope, scope);
}

_createDirectiveFactories(ref, nodeModule, node, nodesAttrsDirectives, nodeAttrs,
visibility);
if (ref.annotation.module != null) {
nodeModule.install(ref.annotation.module());
annotation.visibility);
if (annotation.module != null) {
nodeModule.install(annotation.module());
}
});

Expand Down
5 changes: 3 additions & 2 deletions lib/core_dom/module_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import 'package:angular/core/module_internal.dart';
import 'package:angular/core/parser/parser.dart';
import 'package:angular/core_dom/dom_util.dart' as util;

import 'package:angular/change_detection/watch_group.dart' show Watch, PrototypeMap;
// todo vicb
import 'package:angular/change_detection/watch_group.dart' show Watch, LocalContext;
import 'package:angular/core/registry.dart';

import 'package:angular/directive/module.dart' show NgBaseCss;
Expand Down Expand Up @@ -61,7 +62,7 @@ class CoreDomModule extends Module {
type(TranscludingComponentFactory);
type(Content);
value(ContentPort, null);

type(Http);
type(UrlRewriter);
type(HttpBackend);
Expand Down
3 changes: 3 additions & 0 deletions lib/core_dom/mustache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ class TextMustache {
FormatterMap formatters) {
String expression = interpolate(template);

print('Mustache: watching $expression');

scope.watch(expression,
_updateMarkup,
canChangeModel: false,
formatters: formatters);
}

void _updateMarkup(text, previousText) {
print('Mustache: changed $previousText -> $text');
_element.text = text;
}
}
Expand Down
14 changes: 7 additions & 7 deletions lib/core_dom/shadow_dom_component_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ class ShadowDomComponentFactory implements ComponentFactory {
FactoryFn call(dom.Node node, DirectiveRef ref) {
return (Injector injector) {
var component = ref.annotation as Component;
Scope scope = injector.get(Scope);
ViewCache viewCache = injector.get(ViewCache);
Http http = injector.get(Http);
TemplateCache templateCache = injector.get(TemplateCache);
DirectiveMap directives = injector.get(DirectiveMap);
NgBaseCss baseCss = injector.get(NgBaseCss);
final scope = injector.get(Scope);
final viewCache = injector.get(ViewCache);
final http = injector.get(Http);
final templateCache = injector.get(TemplateCache);
final directives = injector.get(DirectiveMap);
final baseCss = injector.get(NgBaseCss);
// This is a bit of a hack since we are returning different type then we are.
var componentFactory = new _ComponentFactory(node, ref.type, component,
injector.get(dom.NodeTreeSanitizer), _expando, baseCss);
var controller = componentFactory.call(injector, scope, viewCache, http, templateCache,
directives);

componentFactory.shadowScope.context[component.publishAs] = controller;
componentFactory.shadowScope.context = controller;
return controller;
};
}
Expand Down
2 changes: 1 addition & 1 deletion lib/core_dom/transcluding_component_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class TranscludingComponentFactory implements ComponentFactory {
childInjector = injector.createChild([childModule], name: SHADOW_DOM_INJECTOR_NAME);

var controller = childInjector.get(ref.type);
shadowScope.context[component.publishAs] = controller;
shadowScope.context = controller;
ComponentFactory._setupOnShadowDomAttach(controller, templateLoader, shadowScope);
return controller;
};
Expand Down
Loading

0 comments on commit 9a81af3

Please sign in to comment.