Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
feat(debug): Make ngProbe accept a CSS selector
Browse files Browse the repository at this point in the history
Closes #970
  • Loading branch information
vicb authored and [email protected] committed Apr 30, 2014
1 parent 5127add commit eb057c3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class AngularModule extends Module {
*/
abstract class Application {
static _find(String selector, [dom.Element defaultElement]) {
var element = dom.window.document.querySelector(selector);
var element = dom.document.querySelector(selector);
if (element == null) element = defaultElement;
if (element == null) {
throw "Could not find application element '$selector'.";
Expand Down
35 changes: 21 additions & 14 deletions lib/introspection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,44 @@ import 'package:angular/core/module_internal.dart';
import 'package:angular/core_dom/module_internal.dart';

/**
* Return the closest [ElementProbe] object for a given [Element].
* Return the [ElementProbe] object for the closest [Element] in the hierarchy.
*
* The node parameter could be:
* * a [dom.Node],
* * a CSS selector for this node.
*
* **NOTE:** This global method is here to make it easier to debug Angular
* application from the browser's REPL, unit or end-to-end tests. The
* function is not intended to be called from Angular application.
*/
ElementProbe ngProbe(dom.Node node) {
if (node == null) {
throw "ngProbe called without node";
ElementProbe ngProbe(nodeOrSelector) {
var errorMsg;
var node;
if (nodeOrSelector == null) throw "ngProbe called without node";
if (nodeOrSelector is String) {
var nodes = ngQuery(dom.document, nodeOrSelector);
if (nodes.isNotEmpty) node = nodes.first;
errorMsg = "Could not find a probe for the selector '$nodeOrSelector' nor its parents";
} else {
node = nodeOrSelector;
errorMsg = "Could not find a probe for the node '$node' nor its parents";
}
var origNode = node;
while (node != null) {
var probe = elementExpando[node];
if (probe != null) return probe;
node = node.parent;
}
throw "Could not find a probe for [$origNode]";
throw errorMsg;
}


/**
* Return the [Injector] associated with a current [Element].
*
* **NOTE**: This global method is here to make it easier to debug Angular
* application from the browser's REPL, unit or end-to-end tests. The function
* is not intended to be called from Angular application.
*/
Injector ngInjector(dom.Node node) => ngProbe(node).injector;
Injector ngInjector(nodeOrSelector) => ngProbe(nodeOrSelector).injector;


/**
Expand All @@ -47,7 +57,7 @@ Injector ngInjector(dom.Node node) => ngProbe(node).injector;
* application from the browser's REPL, unit or end-to-end tests. The function
* is not intended to be called from Angular application.
*/
Scope ngScope(dom.Node node) => ngProbe(node).scope;
Scope ngScope(nodeOrSelector) => ngProbe(nodeOrSelector).scope;


List<dom.Element> ngQuery(dom.Node element, String selector,
Expand All @@ -70,14 +80,11 @@ List<dom.Element> ngQuery(dom.Node element, String selector,
}

/**
* Return a List of directive controllers associated with a current [Element].
* Return a List of directives associated with a current [Element].
*
* **NOTE**: This global method is here to make it easier to debug Angular
* application from the browser's REPL, unit or end-to-end tests. The function
* is not intended to be called from Angular application.
*/
List<Object> ngDirectives(dom.Node node) {
ElementProbe probe = elementExpando[node];
return probe == null ? [] : probe.directives;
}
List<Object> ngDirectives(nodeOrSelector) => ngProbe(nodeOrSelector).directives;

13 changes: 8 additions & 5 deletions lib/introspection_js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ var elementExpando = new Expando('element');

publishToJavaScript() {
js.context
..['ngProbe'] = new js.JsFunction.withThis((_, dom.Node node) => _jsProbe(ngProbe(node)))
..['ngInjector'] = new js.JsFunction.withThis((_, dom.Node node) => _jsInjector(ngInjector(node)))
..['ngScope'] = new js.JsFunction.withThis((_, dom.Node node) => _jsScope(ngScope(node), ngProbe(node).injector.get(ScopeStatsConfig)))
..['ngProbe'] = new js.JsFunction.withThis((_, nodeOrSelector) =>
_jsProbe(ngProbe(nodeOrSelector)))
..['ngInjector'] = new js.JsFunction.withThis((_, nodeOrSelector) =>
_jsInjector(ngInjector(nodeOrSelector)))
..['ngScope'] = new js.JsFunction.withThis((_, nodeOrSelector) =>
_jsScope(ngScope(nodeOrSelector), ngProbe(nodeOrSelector).injector.get(ScopeStatsConfig)))
..['ngQuery'] = new js.JsFunction.withThis((_, dom.Node node, String selector, [String containsText]) =>
new js.JsArray.from(ngQuery(node, selector, containsText)));
new js.JsArray.from(ngQuery(node, selector, containsText)));
}

js.JsObject _jsProbe(ElementProbe probe) {
Expand All @@ -34,7 +37,7 @@ js.JsObject _jsProbe(ElementProbe probe) {
}

js.JsObject _jsInjector(Injector injector) =>
new js.JsObject.jsify({"get": injector.get})..['_dart_'] = injector;
new js.JsObject.jsify({"get": injector.get})..['_dart_'] = injector;

js.JsObject _jsScope(Scope scope, ScopeStatsConfig config) {
return new js.JsObject.jsify({
Expand Down
15 changes: 15 additions & 0 deletions test/introspection_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library introspection_spec;
import '_specs.dart';
import 'dart:js' as js;
import 'package:angular/application_factory.dart';
import 'dart:html';

void main() {
describe('introspection', () {
Expand Down Expand Up @@ -31,6 +32,20 @@ void main() {
expect(toHtml(ngQuery(div, 'li', 'xxx'))).toEqual('');
});

it('should select probe using CSS selector', (TestBed _) {
_.compile('<div ng-show="true">WORKS</div>');
document.body.append(_.rootElement);
var div = new Element.html('<div><p><span></span></p></div>');
var span = div.querySelector('span');
var shadowRoot = span.createShadowRoot();
shadowRoot.innerHtml = '<ul><li>stash</li><li>secret</li><ul>';

ElementProbe probe = ngProbe('[ng-show]');
expect(probe).toBeDefined();
expect(probe.injector.get(NgShow) is NgShow).toEqual(true);
_.rootElement.remove();
});

it('should select elements in the root shadow root', () {
var div = new Element.html('<div></div>');
var shadowRoot = div.createShadowRoot();
Expand Down

0 comments on commit eb057c3

Please sign in to comment.