Commit ea8fe577 authored by skerner@chromium.org's avatar skerner@chromium.org

Issue 21729: Add new event chrome.tabs.onStatusChange .

BUG=21729
TEST= Manually tested that onUpdated sends all tab info.  Updated unit tests.
Review URL: http://codereview.chromium.org/289006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30341 0039d316-1c4b-4281-b951-d872f2087c98
parent 7ef68bcb
...@@ -311,9 +311,16 @@ void ExtensionBrowserEventRouter::TabUpdated(TabContents* contents, ...@@ -311,9 +311,16 @@ void ExtensionBrowserEventRouter::TabUpdated(TabContents* contents,
// The state of the tab (as seen from the extension point of view) has // The state of the tab (as seen from the extension point of view) has
// changed. Send a notification to the extension. // changed. Send a notification to the extension.
ListValue args; ListValue args;
// First arg: The id of the tab that changed.
args.Append(Value::CreateIntegerValue(tab_id)); args.Append(Value::CreateIntegerValue(tab_id));
// Second arg: An object containing the changes to the tab state.
args.Append(changed_properties); args.Append(changed_properties);
// Third arg: An object containing the state of the tab.
args.Append(ExtensionTabUtil::CreateTabValue(contents));
std::string json_args; std::string json_args;
base::JSONWriter::Write(&args, false, &json_args); base::JSONWriter::Write(&args, false, &json_args);
......
...@@ -369,7 +369,8 @@ const char* BrowserEventAutomationProxy::events_[] = { ...@@ -369,7 +369,8 @@ const char* BrowserEventAutomationProxy::events_[] = {
"'selected':true,'url':'http://www.google.com'}]\"]", "'selected':true,'url':'http://www.google.com'}]\"]",
"[\"tabs.onUpdated\", \"[42, {'status': 'complete'," "[\"tabs.onUpdated\", \"[42, {'status': 'complete',"
"'url':'http://www.google.com'}]\"]", "'url':'http://www.google.com'}, {'id\':42,'index':1,'windowId':1,"
"'selected':true,'url':'http://www.google.com'}]\"]",
"[\"tabs.onMoved\", \"[42, {'windowId':1,'fromIndex':1,'toIndex':2}]\"]", "[\"tabs.onMoved\", \"[42, {'windowId':1,'fromIndex':1,'toIndex':2}]\"]",
......
...@@ -729,6 +729,7 @@ ...@@ -729,6 +729,7 @@
{ {
"type": "object", "type": "object",
"name": "changeInfo", "name": "changeInfo",
"description": "Lists the changes to the state of the tab that was updated.",
"properties": { "properties": {
"status": { "status": {
"type": "string", "type": "string",
...@@ -740,6 +741,11 @@ ...@@ -740,6 +741,11 @@
"description": "Only specified if the tab's URL changed." "description": "Only specified if the tab's URL changed."
} }
} }
},
{
"$ref": "Tab",
"name": "tab",
"description": "Gives the state of the tab that was updated."
} }
] ]
}, },
......
...@@ -4138,7 +4138,7 @@ For example: ...@@ -4138,7 +4138,7 @@ For example:
<div class="summary"> <div class="summary">
<!-- Note: intentionally longer 80 columns --> <!-- Note: intentionally longer 80 columns -->
<span class="subdued">chrome.tabs.</span><span>onUpdated</span><span class="subdued">.addListener</span>(function(<span>integer tabId, object changeInfo</span>) <span class="subdued">{...}</span>); <span class="subdued">chrome.tabs.</span><span>onUpdated</span><span class="subdued">.addListener</span>(function(<span>integer tabId, object changeInfo, Tab tab</span>) <span class="subdued">{...}</span>);
</div> </div>
<div class="description"> <div class="description">
...@@ -4191,7 +4191,7 @@ For example: ...@@ -4191,7 +4191,7 @@ For example:
</dl> </dl>
</dd> </dd>
</div> </div>
</div><div jsinstance="*1"> </div><div jsinstance="1">
<div> <div>
<dt> <dt>
<var>changeInfo</var> <var>changeInfo</var>
...@@ -4217,12 +4217,10 @@ For example: ...@@ -4217,12 +4217,10 @@ For example:
</em> </em>
</dt> </dt>
<dd class="todo"> <dd class="todo" style="display: none; ">
Undocumented. Undocumented.
</dd> </dd>
<dd style="display: none; "> <dd>Lists the changes to the state of the tab that was updated.</dd>
Description of this parameter from the json schema.
</dd>
<!-- OBJECT PROPERTIES --> <!-- OBJECT PROPERTIES -->
<dd> <dd>
...@@ -4312,6 +4310,47 @@ For example: ...@@ -4312,6 +4310,47 @@ For example:
</div> </div>
</dl> </dl>
</dd> </dd>
</div>
</div><div jsinstance="*2">
<div>
<dt>
<var>tab</var>
<em>
<!-- TYPE -->
<div style="display:inline">
(
<span class="optional" style="display: none; ">optional</span>
<span id="typeTemplate">
<span>
<a href="tabs.html#type-Tab">Tab</a>
</span>
<span style="display: none; ">
<span>
array of <span><span></span></span>
</span>
<span>paramType</span>
</span>
</span>
)
</div>
</em>
</dt>
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
<dd>Gives the state of the tab that was updated.</dd>
<!-- OBJECT PROPERTIES -->
<dd style="display: none; ">
<dl>
<div>
<div>
</div>
</div>
</dl>
</dd>
</div> </div>
</div> </div>
</dl> </dl>
......
...@@ -10,7 +10,7 @@ var testUrl = 'http://a.com:1337' + relativePath; ...@@ -10,7 +10,7 @@ var testUrl = 'http://a.com:1337' + relativePath;
var testFailureUrl = 'http://b.com:1337' + relativePath; var testFailureUrl = 'http://b.com:1337' + relativePath;
var testingFailure = false; var testingFailure = false;
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) { chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') if (changeInfo.status == 'complete')
return; return;
if (testingFailure) { if (testingFailure) {
......
...@@ -8,7 +8,7 @@ chrome.extension.onConnect.addListener(function(port) { ...@@ -8,7 +8,7 @@ chrome.extension.onConnect.addListener(function(port) {
}); });
}); });
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) { chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.test.log("Got update event: " + JSON.stringify(changeInfo)); chrome.test.log("Got update event: " + JSON.stringify(changeInfo));
if (changeInfo.status == "complete") { if (changeInfo.status == "complete") {
chrome.tabs.executeScript(tabId, {file: "c.js"}); chrome.tabs.executeScript(tabId, {file: "c.js"});
......
...@@ -121,7 +121,7 @@ chrome.test.runTests([ ...@@ -121,7 +121,7 @@ chrome.test.runTests([
chrome.tabs.update(tabs[1].id, {selected: true}, chrome.tabs.update(tabs[1].id, {selected: true},
pass(function(tab1){ pass(function(tab1){
// Check update of tab[1]. // Check update of tab[1].
chrome.test.assertEq(true, tab1.selected); chrome.test.assertEq(true, tab1.selected);
chrome.tabs.getAllInWindow(firstWindowId, pass(function(tabs) { chrome.tabs.getAllInWindow(firstWindowId, pass(function(tabs) {
assertEq(true, tabs[1].selected); assertEq(true, tabs[1].selected);
assertEq(false, tabs[2].selected); assertEq(false, tabs[2].selected);
...@@ -129,7 +129,7 @@ chrome.test.runTests([ ...@@ -129,7 +129,7 @@ chrome.test.runTests([
chrome.tabs.update(tabs[2].id, {selected: true}, chrome.tabs.update(tabs[2].id, {selected: true},
pass(function(tab2){ pass(function(tab2){
// Check update of tab[2]. // Check update of tab[2].
chrome.test.assertEq(true, tab2.selected); chrome.test.assertEq(true, tab2.selected);
chrome.tabs.getAllInWindow(firstWindowId, pass(function(tabs) { chrome.tabs.getAllInWindow(firstWindowId, pass(function(tabs) {
assertEq(false, tabs[1].selected); assertEq(false, tabs[1].selected);
assertEq(true, tabs[2].selected); assertEq(true, tabs[2].selected);
...@@ -162,7 +162,7 @@ chrome.test.runTests([ ...@@ -162,7 +162,7 @@ chrome.test.runTests([
pass(function(tab) { pass(function(tab) {
var letter = tab.url[tab.url.length-6]; var letter = tab.url[tab.url.length-6];
moveTabIds[letter] = tab.id; moveTabIds[letter] = tab.id;
// Assert on last callback that tabs were added in the order we created // Assert on last callback that tabs were added in the order we created
// them. // them.
if (letter == 'e') { if (letter == 'e') {
...@@ -195,15 +195,15 @@ chrome.test.runTests([ ...@@ -195,15 +195,15 @@ chrome.test.runTests([
chrome.test.assertEq(0, tabB.index); chrome.test.assertEq(0, tabB.index);
chrome.tabs.move(moveTabIds['e'], {"index": 2}, chrome.tabs.move(moveTabIds['e'], {"index": 2},
pass(function(tabE) { pass(function(tabE) {
chrome.test.assertEq(2, tabE.index); chrome.test.assertEq(2, tabE.index);
chrome.tabs.move(moveTabIds['d'], {"windowId": moveWindow2, chrome.tabs.move(moveTabIds['d'], {"windowId": moveWindow2,
"index": 2}, pass(function(tabD) { "index": 2}, pass(function(tabD) {
chrome.test.assertEq(2, tabD.index); chrome.test.assertEq(2, tabD.index);
})); }));
})); }));
})); }));
}, },
// Check that the tab/window state is what we expect after doing moves. // Check that the tab/window state is what we expect after doing moves.
function moveTabsCheck() { function moveTabsCheck() {
chrome.tabs.getAllInWindow(moveWindow1, pass(function(tabs) { chrome.tabs.getAllInWindow(moveWindow1, pass(function(tabs) {
...@@ -212,13 +212,13 @@ chrome.test.runTests([ ...@@ -212,13 +212,13 @@ chrome.test.runTests([
assertEq(pageUrl("a"), tabs[1].url); assertEq(pageUrl("a"), tabs[1].url);
assertEq(pageUrl("e"), tabs[2].url); assertEq(pageUrl("e"), tabs[2].url);
assertEq(pageUrl("c"), tabs[3].url); assertEq(pageUrl("c"), tabs[3].url);
chrome.tabs.getAllInWindow(moveWindow2, pass(function(tabs) { chrome.tabs.getAllInWindow(moveWindow2, pass(function(tabs) {
assertEq(3, tabs.length); assertEq(3, tabs.length);
assertEq(pageUrl("b"), tabs[0].url); assertEq(pageUrl("b"), tabs[0].url);
assertEq("chrome://newtab/", tabs[1].url); assertEq("chrome://newtab/", tabs[1].url);
assertEq(pageUrl("d"), tabs[2].url); assertEq(pageUrl("d"), tabs[2].url);
})); }));
})); }));
}, },
...@@ -253,14 +253,14 @@ chrome.test.runTests([ ...@@ -253,14 +253,14 @@ chrome.test.runTests([
pass(function(window1Url) { pass(function(window1Url) {
assertEq("string", typeof(window1Url)); assertEq("string", typeof(window1Url));
assertTrue(window1Url.length > 0); assertTrue(window1Url.length > 0);
// Take Second Capture // Take Second Capture
chrome.tabs.captureVisibleTab(moveWindow2, chrome.tabs.captureVisibleTab(moveWindow2,
pass(function(window2Url) { pass(function(window2Url) {
assertEq("string", typeof(window2Url)); assertEq("string", typeof(window2Url));
assertTrue(window2Url.length > 0); assertTrue(window2Url.length > 0);
assertTrue(window1Url != window2Url); assertTrue(window1Url != window2Url);
// Now pass null for windowId - it should come back with something // Now pass null for windowId - it should come back with something
// equal to either the first or second window. This is nondeterministic // equal to either the first or second window. This is nondeterministic
// depending on whether you let chrome stay focused, or click // depending on whether you let chrome stay focused, or click
...@@ -278,29 +278,53 @@ chrome.test.runTests([ ...@@ -278,29 +278,53 @@ chrome.test.runTests([
chrome.test.listenOnce(chrome.tabs.onCreated, function(tab) { chrome.test.listenOnce(chrome.tabs.onCreated, function(tab) {
assertEq(pageUrl("f"), tab.url); assertEq(pageUrl("f"), tab.url);
}); });
chrome.tabs.create({"windowId": moveWindow1, "url": pageUrl("f"), chrome.tabs.create({"windowId": moveWindow1, "url": pageUrl("f"),
"selected": true}, pass(function(tab) {})); "selected": true}, pass(function(tab) {}));
}, },
function tabsOnUpdated() { function tabsOnUpdatedIgnoreTabArg() {
// A third argument was added to the onUpdated event callback.
// Test that an event handler which ignores this argument works.
var onUpdatedCompleted = chrome.test.listenForever(chrome.tabs.onUpdated, var onUpdatedCompleted = chrome.test.listenForever(chrome.tabs.onUpdated,
function(tabid, info) { function(tabid, changeInfo) {
if (tabid == moveTabIds['a'] && info.status == "complete") { if (tabid == moveTabIds['a'] && changeInfo.status == "complete") {
onUpdatedCompleted(); onUpdatedCompleted();
} }
} }
); );
chrome.tabs.update(moveTabIds['a'], {"url": pageUrl("f")}, chrome.tabs.update(moveTabIds['a'], {"url": pageUrl("f")}, pass());
pass()); },
function tabsOnUpdated() {
var onUpdatedCompleted = chrome.test.listenForever(
chrome.tabs.onUpdated,
function(tabid, changeInfo, tab) {
// |tab| contains the id of the tab it describes.
// Test that |tabid| matches this id.
assertEq(tabid, tab.id);
// If |changeInfo| has a status property, than
// it should match the status of the tab in |tab|.
if (changeInfo.status) {
assertEq(changeInfo.status, tab.status);
}
if (tabid == moveTabIds['a'] && changeInfo.status == "complete") {
onUpdatedCompleted();
}
}
);
chrome.tabs.update(moveTabIds['a'], {"url": pageUrl("f")}, pass());
}, },
function tabsOnMoved() { function tabsOnMoved() {
chrome.test.listenOnce(chrome.tabs.onMoved, function(tabid, info) { chrome.test.listenOnce(chrome.tabs.onMoved, function(tabid, info) {
assertEq(moveTabIds['a'], tabid); assertEq(moveTabIds['a'], tabid);
}); });
chrome.tabs.move(moveTabIds['a'], {"index": 0}, pass()); chrome.tabs.move(moveTabIds['a'], {"index": 0}, pass());
}, },
...@@ -310,7 +334,7 @@ chrome.test.runTests([ ...@@ -310,7 +334,7 @@ chrome.test.runTests([
assertEq(moveTabIds['c'], tabid); assertEq(moveTabIds['c'], tabid);
} }
); );
chrome.tabs.update(moveTabIds['c'], {"selected": true}, chrome.tabs.update(moveTabIds['c'], {"selected": true},
pass()); pass());
}, },
...@@ -337,13 +361,13 @@ chrome.test.runTests([ ...@@ -337,13 +361,13 @@ chrome.test.runTests([
})); }));
})); }));
}, },
function relativeUrlTabsCreate() { function relativeUrlTabsCreate() {
// Will be called from relative.html // Will be called from relative.html
window.relativePageLoaded = chrome.test.callbackAdded(); window.relativePageLoaded = chrome.test.callbackAdded();
var createCompleted = chrome.test.callbackAdded(); var createCompleted = chrome.test.callbackAdded();
chrome.tabs.create({windowId: firstWindowId, url: 'relative.html'}, chrome.tabs.create({windowId: firstWindowId, url: 'relative.html'},
function(tab){ function(tab){
testTabId = tab.id; testTabId = tab.id;
createCompleted(); createCompleted();
...@@ -357,18 +381,18 @@ chrome.test.runTests([ ...@@ -357,18 +381,18 @@ chrome.test.runTests([
chrome.tabs.update(testTabId, {url: pageUrl("a")}, function(tab) { chrome.tabs.update(testTabId, {url: pageUrl("a")}, function(tab) {
chrome.test.assertEq(pageUrl("a"), tab.url); chrome.test.assertEq(pageUrl("a"), tab.url);
chrome.tabs.update(tab.id, {url: "relative.html"}, function(tab) { chrome.tabs.update(tab.id, {url: "relative.html"}, function(tab) {
}); });
}); });
}, },
function relativeUrlWindowsCreate() { function relativeUrlWindowsCreate() {
// Will be called from relative.html // Will be called from relative.html
window.relativePageLoaded = chrome.test.callbackAdded(); window.relativePageLoaded = chrome.test.callbackAdded();
chrome.windows.create({url: "relative.html"}); chrome.windows.create({url: "relative.html"});
}, },
function windowsOnCreated() { function windowsOnCreated() {
chrome.test.listenOnce(chrome.windows.onCreated, function(window) { chrome.test.listenOnce(chrome.windows.onCreated, function(window) {
chrome.test.assertTrue(window.width > 0); chrome.test.assertTrue(window.width > 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment