Skip to content

Commit 0e55aef

Browse files
committedMar 15, 2014
feat(ElementPanel): display scope properties for children of DocumentFragments
Sort of related to angular/angular.js#6637 --- Currently, jqLite#inheritedData() will not find data if it needs to cross through document fragment barriers, such as the Shadow DOM barrier. This patch allows batarang to figure this out. In addition, it provides some tests for the angularjs properties sidebar of the element panel, which were missing previously. Closes angular#104
1 parent 49a130c commit 0e55aef

File tree

4 files changed

+71
-14
lines changed

4 files changed

+71
-14
lines changed
 

‎js/devtoolsBackground.js

+28-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
1-
var panels = chrome.devtools.panels;
1+
var panels = chrome && chrome.devtools && chrome.devtools.panels;
2+
3+
function getScope(node) {
4+
var scope = window.angular.element(node).scope();
5+
if (!scope) {
6+
// Might be a child of a DocumentFragment...
7+
while (node && node.nodeType === 1) node = node.parentNode;
8+
if (node && node.nodeType === 11) node = (node.parentNode || node.host);
9+
return getScope(node);
10+
}
11+
return scope;
12+
}
213

314
// The function below is executed in the context of the inspected page.
415

516
var getPanelContents = function () {
617
if (window.angular && $0) {
718
//TODO: can we move this scope export into updateElementProperties
8-
var scope = window.angular.element($0).scope();
19+
var scope = getScope($0);
20+
921
// Export $scope to the console
1022
window.$scope = scope;
1123
return (function (scope) {
@@ -29,17 +41,19 @@ var getPanelContents = function () {
2941
}
3042
};
3143

32-
panels.elements.createSidebarPane(
33-
"AngularJS Properties",
34-
function (sidebar) {
35-
panels.elements.onSelectionChanged.addListener(function updateElementProperties() {
36-
sidebar.setExpression("(" + getPanelContents.toString() + ")()");
44+
if (panels) {
45+
panels.elements.createSidebarPane(
46+
"AngularJS Properties",
47+
function (sidebar) {
48+
panels.elements.onSelectionChanged.addListener(function updateElementProperties() {
49+
sidebar.setExpression("(" + getPanelContents.toString() + ")()");
50+
});
3751
});
38-
});
3952

40-
// Angular panel
41-
var angularPanel = panels.create(
42-
"AngularJS",
43-
"img/angular.png",
44-
"panel.html"
45-
);
53+
// Angular panel
54+
var angularPanel = panels.create(
55+
"AngularJS",
56+
"img/angular.png",
57+
"panel.html"
58+
);
59+
}

‎karma.conf

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ files = [
1010
'js/directives/*.js',
1111
'js/filters/*.js',
1212
'js/services/*.js',
13+
'js/devtoolsBackground.js'
1314

1415
'test/mock/*.js',
1516
'test/*.js'

‎karma.e2e.conf

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ files = [
1010
'js/directives/*.js',
1111
'js/filters/*.js',
1212
'js/services/*.js',
13+
'js/devtoolsBackground.js',
1314

1415
'test/mock/*.js',
1516
'test/*.js'

‎test/ElementsPanelSpec.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
describe('elements panel', function() {
2+
beforeEach(module(function($provide) {
3+
$provide.factory('chromeExtension', createChromeExtensionMock);
4+
}));
5+
6+
afterEach(function() {
7+
$0 = null;
8+
});
9+
10+
11+
describe('angular properties sidebar', function() {
12+
describe('getPanelContents()', function() {
13+
it('should return properties for scope of selected element', inject(function($rootScope) {
14+
var element = angular.element('<div><p>Hello, world</p></div>');
15+
element.data('$scope', $rootScope);
16+
$rootScope.text = "Hello, world!";
17+
$0 = element[0];
18+
expect (getPanelContents().text).toBe("Hello, world!");
19+
$0 = element.children().eq(0)[0];
20+
expect (getPanelContents().text).toBe("Hello, world!");
21+
}));
22+
23+
24+
it('should cross shadow DOM barrier via DocumentFragment#host', inject(function($rootScope) {
25+
var parent = document.createElement('div'),
26+
fragment = document.createDocumentFragment(),
27+
child = document.createElement('p');
28+
fragment.host = parent;
29+
fragment.appendChild(child);
30+
parent.appendChild(fragment);
31+
32+
parent = angular.element(parent);
33+
parent.data('$scope', $rootScope);
34+
$rootScope.text = "Fragmented fun for everyone";
35+
36+
$0 = child;
37+
expect(getPanelContents().text).toBe("Fragmented fun for everyone");
38+
}));
39+
});
40+
});
41+
});

0 commit comments

Comments
 (0)
Please sign in to comment.