Skip to content

Commit

Permalink
feat(ElementPanel): display scope properties for children of Document…
Browse files Browse the repository at this point in the history
…Fragments

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
  • Loading branch information
caitp committed Mar 15, 2014
1 parent 49a130c commit 0e55aef
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 14 deletions.
42 changes: 28 additions & 14 deletions js/devtoolsBackground.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
var panels = chrome.devtools.panels;
var panels = chrome && chrome.devtools && chrome.devtools.panels;

function getScope(node) {
var scope = window.angular.element(node).scope();
if (!scope) {
// Might be a child of a DocumentFragment...
while (node && node.nodeType === 1) node = node.parentNode;
if (node && node.nodeType === 11) node = (node.parentNode || node.host);
return getScope(node);
}
return scope;
}

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

var getPanelContents = function () {
if (window.angular && $0) {
//TODO: can we move this scope export into updateElementProperties
var scope = window.angular.element($0).scope();
var scope = getScope($0);

// Export $scope to the console
window.$scope = scope;
return (function (scope) {
Expand All @@ -29,17 +41,19 @@ var getPanelContents = function () {
}
};

panels.elements.createSidebarPane(
"AngularJS Properties",
function (sidebar) {
panels.elements.onSelectionChanged.addListener(function updateElementProperties() {
sidebar.setExpression("(" + getPanelContents.toString() + ")()");
if (panels) {
panels.elements.createSidebarPane(
"AngularJS Properties",
function (sidebar) {
panels.elements.onSelectionChanged.addListener(function updateElementProperties() {
sidebar.setExpression("(" + getPanelContents.toString() + ")()");
});
});
});

// Angular panel
var angularPanel = panels.create(
"AngularJS",
"img/angular.png",
"panel.html"
);
// Angular panel
var angularPanel = panels.create(
"AngularJS",
"img/angular.png",
"panel.html"
);
}
1 change: 1 addition & 0 deletions karma.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ files = [
'js/directives/*.js',
'js/filters/*.js',
'js/services/*.js',
'js/devtoolsBackground.js'

'test/mock/*.js',
'test/*.js'
Expand Down
1 change: 1 addition & 0 deletions karma.e2e.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ files = [
'js/directives/*.js',
'js/filters/*.js',
'js/services/*.js',
'js/devtoolsBackground.js',

'test/mock/*.js',
'test/*.js'
Expand Down
41 changes: 41 additions & 0 deletions test/ElementsPanelSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
describe('elements panel', function() {
beforeEach(module(function($provide) {
$provide.factory('chromeExtension', createChromeExtensionMock);
}));

afterEach(function() {
$0 = null;
});


describe('angular properties sidebar', function() {
describe('getPanelContents()', function() {
it('should return properties for scope of selected element', inject(function($rootScope) {
var element = angular.element('<div><p>Hello, world</p></div>');
element.data('$scope', $rootScope);
$rootScope.text = "Hello, world!";
$0 = element[0];
expect (getPanelContents().text).toBe("Hello, world!");
$0 = element.children().eq(0)[0];
expect (getPanelContents().text).toBe("Hello, world!");
}));


it('should cross shadow DOM barrier via DocumentFragment#host', inject(function($rootScope) {
var parent = document.createElement('div'),
fragment = document.createDocumentFragment(),
child = document.createElement('p');
fragment.host = parent;
fragment.appendChild(child);
parent.appendChild(fragment);

parent = angular.element(parent);
parent.data('$scope', $rootScope);
$rootScope.text = "Fragmented fun for everyone";

$0 = child;
expect(getPanelContents().text).toBe("Fragmented fun for everyone");
}));
});
});
});

0 comments on commit 0e55aef

Please sign in to comment.