Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-11-24 14:18:59 +01:00
Родитель 0203213000 45b2b36c4c
Коммит 2492fdb8a7
391 изменённых файлов: 8220 добавлений и 2957 удалений

Просмотреть файл

@ -1,5 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
REVIEWBOARD_URL = 'https://reviewboard.allizom.org/'

Просмотреть файл

@ -508,7 +508,7 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
const bool kIsKeyboardSelect = true; // is keyboard selection
const bool kIsVisualBidi = false; // use visual order for bidi text
nsPeekOffsetStruct pos(aAmount, aDirection, innerContentOffset,
0, kIsJumpLinesOk, kIsScrollViewAStop,
nsPoint(0, 0), kIsJumpLinesOk, kIsScrollViewAStop,
kIsKeyboardSelect, kIsVisualBidi,
aWordMovementType);
nsresult rv = frameAtOffset->PeekOffset(&pos);

Просмотреть файл

@ -434,6 +434,8 @@ pref("dom.ipc.processCount", 100000);
pref("dom.ipc.browser_frames.oop_by_default", false);
pref("dom.meta-viewport.enabled", true);
// SMS/MMS
pref("dom.sms.enabled", true);

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1416004676000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1416506840000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -451,10 +451,8 @@
<prefs>
</prefs>
</emItem>
<emItem blockID="i502" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<versionRange minVersion="0" maxVersion="*" severity="3">
<emItem blockID="i346" id="{a6e67e6f-8615-4fe0-a599-34a73fc3fba5}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
<prefs>
</prefs>
@ -546,8 +544,10 @@
<prefs>
</prefs>
</emItem>
<emItem blockID="i346" id="{a6e67e6f-8615-4fe0-a599-34a73fc3fba5}">
<versionRange minVersion="0" maxVersion="*" severity="1">
<emItem blockID="i502" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
@ -1469,6 +1469,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i788" id="{729c9605-0626-4792-9584-4cbe65b243e6}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i750" id="{46eddf51-a4f6-4476-8d6c-31c5187b2a2f}">
<versionRange minVersion="0" maxVersion="*" severity="1">
@ -2037,6 +2043,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i786" id="{63eb5ed4-e1b3-47ec-a253-f8462f205350}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
<versionRange minVersion="0" maxVersion="*" severity="1">

Просмотреть файл

@ -1642,10 +1642,10 @@ pref("shumway.disabled", true);
pref("image.mem.max_decoded_image_kb", 256000);
pref("loop.enabled", true);
pref("loop.server", "https://loop.services.mozilla.com");
pref("loop.server", "https://loop.services.mozilla.com/v0");
pref("loop.seenToS", "unseen");
pref("loop.gettingStarted.seen", false);
pref("loop.gettingStarted.url", "https://bugzilla.mozilla.org/show_bug.cgi?id=1099462");
pref("loop.gettingStarted.url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/hello/start");
pref("loop.learnMoreUrl", "https://www.firefox.com/hello/");
pref("loop.legal.ToS_url", "https://hello.firefox.com/legal/terms/");
pref("loop.legal.privacy_url", "https://www.mozilla.org/privacy/");
@ -1810,7 +1810,7 @@ pref("privacy.trackingprotection.ui.enabled", false);
#endif
#ifdef NIGHTLY_BUILD
pref("browser.tabs.remote.autostart.1", true);
pref("browser.tabs.remote.autostart.1", false);
#endif
// Temporary pref to allow printing in e10s windows on some platforms.
@ -1820,4 +1820,9 @@ pref("print.enable_e10s_testing", false);
pref("print.enable_e10s_testing", true);
#endif
#ifdef NIGHTLY_BUILD
// Enable e10s add-on interposition by default.
pref("extensions.interposition.enabled", true);
#endif
pref("browser.defaultbrowser.notificationbar", false);

Просмотреть файл

@ -99,16 +99,6 @@ let wrapper = {
iframe: null,
init: function (url, urlParams) {
let weave = Cc["@mozilla.org/weave/service;1"]
.getService(Ci.nsISupports)
.wrappedJSObject;
// Don't show about:accounts with FxA disabled.
if (!weave.fxAccountsEnabled) {
document.body.remove();
return;
}
// If a master-password is enabled, we want to encourage the user to
// unlock it. Things still work if not, but the user will probably need
// to re-auth next startup (in which case we will get here again and

Просмотреть файл

@ -720,7 +720,6 @@
enablehistory="true"
maxrows="6"
newlines="stripsurroundingwhitespace"
oninput="gBrowser.userTypedValue = this.value;"
ontextentered="this.handleCommand(param);"
ontextreverted="return this.handleRevert();"
pageproxystate="invalid"

Просмотреть файл

@ -193,6 +193,9 @@
() => {
this.swapDocShells(cb);
chatbar.focus();
this.close();
// chatboxForURL is a map of URL -> chatbox used to avoid opening
// duplicate chat windows. Ensure reattached chat windows aren't
// registered with about:blank as their URL, otherwise reattaching
@ -200,8 +203,6 @@
chatbar.chatboxForURL.delete("about:blank");
chatbar.chatboxForURL.set(this.src, Cu.getWeakReference(cb));
chatbar.focus();
this.close();
deferred.resolve(cb);
}
);
@ -527,7 +528,9 @@
let cb = this.chatboxForURL.get(aURL);
if (cb) {
cb = cb.get();
if (cb.parentNode) {
// A chatbox is still alive to us when it's parented and still has
// content.
if (cb.parentNode && cb.contentWindow) {
this.showChat(cb, aMode);
if (aCallback) {
if (cb._callbacks == null) {
@ -646,6 +649,7 @@
<parameter name="aOptions"/>
<body><![CDATA[
let deferred = Promise.defer();
let chatbar = this;
let options = "";
for (let name in aOptions)
options += "," + name + "=" + aOptions[name];
@ -661,6 +665,8 @@
let otherChatbox = otherWin.document.getElementById("chatter");
aChatbox.swapDocShells(otherChatbox);
aChatbox.close();
chatbar.chatboxForURL.set(aChatbox.src, Cu.getWeakReference(otherChatbox));
deferred.resolve(otherChatbox);
}, true);
return deferred.promise;

Просмотреть файл

@ -122,6 +122,10 @@ skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test un
[browser_alltabslistener.js]
[browser_autocomplete_a11y_label.js]
skip-if = e10s # Bug 1101993 - times out for unknown reasons when run in the dir (works on its own)
[browser_autocomplete_no_title.js]
skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
[browser_autocomplete_autoselect.js]
skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
[browser_backButtonFitts.js]
skip-if = os != "win" || e10s # The Fitts Law back button is only supported on Windows (bug 571454) / e10s - Bug 1099154: test touches content (attempts to add an event listener directly to the contentWindow)
[browser_blob-channelname.js]
@ -288,6 +292,8 @@ skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and
[browser_bug1015721.js]
skip-if = os == 'win' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
[browser_bug1064280_changeUrlInPinnedTab.js]
[browser_bug1070778.js]
skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
[browser_canonizeURL.js]
skip-if = e10s # Bug 1094510 - test hits the network in e10s mode only
[browser_contentAreaClick.js]

Просмотреть файл

@ -31,7 +31,7 @@ let tests = [
function revert(next) {
loadTabInWindow(window, function (tab) {
gURLBar.handleRevert();
is(gURLBar.value, "example.com", "URL bar had user/pass stripped after reverting");
is(gURLBar.textValue, "example.com", "URL bar had user/pass stripped after reverting");
gBrowser.removeTab(tab);
next();
});
@ -44,7 +44,7 @@ let tests = [
loadTabInWindow(win, function () {
openToolbarCustomizationUI(function () {
closeToolbarCustomizationUI(function () {
is(win.gURLBar.value, "example.com", "URL bar had user/pass stripped after customize");
is(win.gURLBar.textValue, "example.com", "URL bar had user/pass stripped after customize");
win.close();
next();
}, win);
@ -59,7 +59,7 @@ let tests = [
// error.
tab.linkedBrowser.loadURI("http://test1.example.com");
tab.linkedBrowser.stop();
is(gURLBar.value, "example.com", "URL bar had user/pass stripped after load error");
is(gURLBar.textValue, "example.com", "URL bar had user/pass stripped after load error");
gBrowser.removeTab(tab);
next();
});
@ -76,7 +76,7 @@ function loadTabInWindow(win, callback) {
return;
tab.linkedBrowser.removeEventListener("load", listener, true);
is(win.gURLBar.value, "example.com", "URL bar had user/pass stripped initially");
is(win.gURLBar.textValue, "example.com", "URL bar had user/pass stripped initially");
callback(tab);
}, true);
}

Просмотреть файл

@ -43,11 +43,14 @@ add_task(function* () {
let result = yield promise_first_result("open a search");
isnot(result, null, "Should have a result");
is(result.getAttribute("url"),
`moz-action:searchengine,{"engineName":"MozSearch","input":"open a search","searchQuery":"open a search"}`,
"Result should be a moz-action: for the correct search engine");
is(result.hasAttribute("image"), false, "Result shouldn't have an image attribute");
let tabPromise = promiseTabLoaded(gBrowser.selectedTab);
EventUtils.synthesizeMouseAtCenter(result, {});
yield tabPromise;
is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search");
is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search", "Correct URL should be loaded");
});

Просмотреть файл

@ -0,0 +1,59 @@
function repeat(limit, func) {
for (let i = 0; i < limit; i++) {
func(i);
}
}
function* promiseAutoComplete(inputText) {
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1), {});
yield promiseSearchComplete();
}
function is_selected(index) {
is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
}
add_task(function*() {
registerCleanupFunction(promiseClearHistory);
let visits = [];
repeat(10, i => {
visits.push({
uri: makeURI("http://example.com/autocomplete/?" + i),
});
});
yield PlacesTestUtils.addVisits(visits);
yield promiseAutoComplete("example.com/autocomplete");
let popup = gURLBar.popup;
let results = popup.richlistbox.children;
// 1 extra for the current search engine match
is(results.length, 11, "Should get 11 results");
is_selected(0);
info("Key Down to select the next item");
EventUtils.synthesizeKey("VK_DOWN", {});
is_selected(1);
info("Key Down 11 times should wrap around all the way around");
repeat(11, () => EventUtils.synthesizeKey("VK_DOWN", {}));
is_selected(1);
info("Key Up 11 times should wrap around the other way");
repeat(11, () => EventUtils.synthesizeKey("VK_UP", {}));
is_selected(1);
info("Page Up will go up the list, but not wrap");
EventUtils.synthesizeKey("VK_PAGE_UP", {})
is_selected(0);
info("Page Up again will wrap around to the end of the list");
EventUtils.synthesizeKey("VK_PAGE_UP", {})
is_selected(10);
EventUtils.synthesizeKey("VK_ESCAPE", {});
yield promisePopupHidden(gURLBar.popup);
});

Просмотреть файл

@ -0,0 +1,27 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function* check_title(inputText, expectedTitle) {
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
yield promiseSearchComplete();
ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results");
let result = gURLBar.popup.richlistbox.children[1];
is(result._title.textContent, expectedTitle, "Result title should be as expected");
}
add_task(function*() {
// This test is only relevant if UnifiedComplete is enabled.
if (!Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete"))
return;
let uri = NetUtil.newURI("http://bug1060642.example.com/beards/are/pretty/great");
yield PlacesTestUtils.addVisits([{uri: uri, title: ""}]);
yield check_title("bug1060642", "bug1060642.example.com");
gURLBar.popup.hidePopup();
yield promisePopupHidden(gURLBar.popup);
});

Просмотреть файл

@ -35,7 +35,7 @@ add_task(function* test_switchtab_override() {
onSearchComplete.apply(gURLBar);
deferred.resolve();
}
gURLBar.focus();
gURLBar.value = "dummy_pag";
EventUtils.synthesizeKey("e" , {});
@ -43,7 +43,6 @@ add_task(function* test_switchtab_override() {
info("Select second autocomplete popup entry");
EventUtils.synthesizeKey("VK_DOWN" , {});
EventUtils.synthesizeKey("VK_DOWN" , {});
ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
info("Override switch-to-tab");
@ -61,6 +60,7 @@ add_task(function* test_switchtab_override() {
EventUtils.synthesizeKey("VK_SHIFT" , { type: "keydown" });
EventUtils.synthesizeKey("VK_RETURN" , { });
info(`gURLBar.value = ${gURLBar.value}`);
EventUtils.synthesizeKey("VK_SHIFT" , { type: "keyup" });
yield deferred.promise;

Просмотреть файл

@ -21,26 +21,13 @@ add_task(function* test_switchtab_override_keynav() {
return promiseClearHistory();
});
info("Wait for autocomplete")
let searchDeferred = Promise.defer();
let onSearchComplete = gURLBar.onSearchComplete;
registerCleanupFunction(() => {
gURLBar.onSearchComplete = onSearchComplete;
});
gURLBar.onSearchComplete = function () {
ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
onSearchComplete.apply(gURLBar);
searchDeferred.resolve();
}
gURLBar.focus();
gURLBar.value = "dummy_pag";
EventUtils.synthesizeKey("e" , {});
yield searchDeferred.promise;
yield promiseSearchComplete();
info("Select second autocomplete popup entry");
EventUtils.synthesizeKey("VK_DOWN" , {});
EventUtils.synthesizeKey("VK_DOWN" , {});
ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
info("Shift+left on switch-to-tab entry");

Просмотреть файл

@ -0,0 +1,62 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function* promiseAutoComplete(inputText) {
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
yield promiseSearchComplete();
}
function is_selected(index) {
is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
}
add_task(function*() {
// This test is only relevant if UnifiedComplete is enabled.
if (!Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete"))
return;
registerCleanupFunction(() => {
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
});
let itemId =
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
NetUtil.newURI("http://example.com/?q=%s"),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"test");
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
// This item only needed so we can select the keyword item, select something
// else, then select the keyword item again.
itemId =
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
NetUtil.newURI("http://example.com/keyword"),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"keyword abc");
yield promiseAutoComplete("keyword a");
// First item should already be selected
is_selected(0);
// Select next one (important!)
EventUtils.synthesizeKey("VK_DOWN", {});
is_selected(1);
// Re-select keyword item
EventUtils.synthesizeKey("VK_UP", {});
is_selected(0);
EventUtils.synthesizeKey("b", {});
yield promiseSearchComplete();
is(gURLBar.value, "keyword ab", "urlbar should have expected input");
let result = gURLBar.popup.richlistbox.firstChild;
isnot(result, null, "Should have first item");
let uri = NetUtil.newURI(result.getAttribute("url"));
is(uri.spec, makeActionURI("keyword", {url: "http://example.com/?q=ab", input: "keyword ab"}).spec, "Expect correct url");
EventUtils.synthesizeKey("VK_ESCAPE", {});
yield promisePopupHidden(gURLBar.popup);
});

Просмотреть файл

@ -21,16 +21,15 @@ function test() {
function cycleTabs() {
gBrowser.selectedTab = fullURLTab;
is(gURLBar.value, testURL, 'gURLBar.value should be testURL after switching back to fullURLTab');
is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after switching back to fullURLTab');
gBrowser.selectedTab = partialURLTab;
is(gURLBar.value, testPartialURL, 'gURLBar.value should be testPartialURL after switching back to partialURLTab');
is(gURLBar.textValue, testPartialURL, 'gURLBar.textValue should be testPartialURL after switching back to partialURLTab');
gBrowser.selectedTab = deletedURLTab;
is(gURLBar.value, '', 'gURLBar.value should be "" after switching back to deletedURLTab');
is(gURLBar.textValue, '', 'gURLBar.textValue should be "" after switching back to deletedURLTab');
gBrowser.selectedTab = fullURLTab;
is(gURLBar.value, testURL, 'gURLBar.value should be testURL after switching back to fullURLTab');
is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after switching back to fullURLTab');
}
// function borrowed from browser_bug386835.js
@ -59,13 +58,13 @@ function test() {
function prepareDeletedURLTab(cb) {
gBrowser.selectedTab = deletedURLTab;
is(gURLBar.value, testURL, 'gURLBar.value should be testURL after initial switch to deletedURLTab');
is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after initial switch to deletedURLTab');
// simulate the user removing the whole url from the location bar
gPrefService.setBoolPref("browser.urlbar.clickSelectsAll", true);
urlbarBackspace(function () {
is(gURLBar.value, "", 'gURLBar.value should be "" (just set)');
is(gURLBar.textValue, "", 'gURLBar.textValue should be "" (just set)');
if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll"))
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
cb();
@ -74,13 +73,13 @@ function test() {
function prepareFullURLTab(cb) {
gBrowser.selectedTab = fullURLTab;
is(gURLBar.value, testURL, 'gURLBar.value should be testURL after initial switch to fullURLTab');
is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after initial switch to fullURLTab');
cb();
}
function preparePartialURLTab(cb) {
gBrowser.selectedTab = partialURLTab;
is(gURLBar.value, testURL, 'gURLBar.value should be testURL after initial switch to partialURLTab');
is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after initial switch to partialURLTab');
// simulate the user removing part of the url from the location bar
gPrefService.setBoolPref("browser.urlbar.clickSelectsAll", false);
@ -91,7 +90,7 @@ function test() {
if (deleted < charsToDelete) {
urlbarBackspace(arguments.callee);
} else {
is(gURLBar.value, testPartialURL, "gURLBar.value should be testPartialURL (just set)");
is(gURLBar.textValue, testPartialURL, "gURLBar.textValue should be testPartialURL (just set)");
if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll"))
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
cb();

Просмотреть файл

@ -31,7 +31,8 @@ let tests = [
setup: function() {
gURLBar.value = testActionURL;
gURLBar.valueIsTyped = true;
is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
is(gURLBar.value, testActionURL, "gURLBar starts with the correct real value");
is(gURLBar.textValue, testURL, "gURLBar starts with the correct display value");
// Focus the urlbar so we can select it all & copy
gURLBar.focus();
@ -73,7 +74,8 @@ let tests = [
gURLBar.value = testActionURL;
gURLBar.valueIsTyped = true;
// Sanity check that we have the right value
is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
is(gURLBar.value, testActionURL, "gURLBar starts with the correct real value");
is(gURLBar.textValue, testURL, "gURLBar starts with the correct display value");
// Now just select part of the value & cut that.
gURLBar.selectionStart = testURL.length - 10;

Просмотреть файл

@ -45,10 +45,12 @@ function testNext() {
gURLBar.addEventListener("focus", function onFocus() {
gURLBar.removeEventListener("focus", onFocus);
gURLBar.inputField.value = inputValue.slice(0, -1);
EventUtils.synthesizeKey(inputValue.slice(-1) , {});
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
});
gBrowser.selectedBrowser.focus();
gURLBar.inputField.value = inputValue;
gURLBar.focus();
}

Просмотреть файл

@ -37,10 +37,10 @@ function runShiftLeftClickTest() {
addPageShowListener(aWindow.gBrowser.selectedBrowser, function() {
executeSoon(function () {
info("URL should be loaded in a new window");
is(gURLBar.value, "", "Urlbar reverted to original value");
is(gURLBar.value, "", "Urlbar reverted to original value");
is(gFocusManager.focusedElement, null, "There should be no focused element");
is(gFocusManager.focusedWindow, aWindow.gBrowser.contentWindow, "Content window should be focused");
is(aWindow.gURLBar.value, TEST_VALUE, "New URL is loaded in new window");
is(aWindow.gURLBar.textValue, TEST_VALUE, "New URL is loaded in new window");
aWindow.close();
@ -61,7 +61,7 @@ function runNextTest() {
finish();
return;
}
info("Running test: " + test.desc);
// Tab will be blank if test.startValue is null
let tab = gBrowser.selectedTab = gBrowser.addTab(test.startValue);
@ -106,7 +106,7 @@ let gTests = [
is(gURLBar.value, "", "Urlbar reverted to original value");
ok(!gURLBar.focused, "Urlbar is no longer focused after urlbar command");
is(gBrowser.selectedTab, aTab, "Focus did not change to the new tab");
// Select the new background tab
gBrowser.selectedTab = gBrowser.selectedTab.nextSibling;
is(gURLBar.value, TEST_VALUE, "New URL is loaded in new tab");
@ -143,7 +143,7 @@ function triggerCommand(aClick, aEvent) {
if (aClick) {
is(gURLBar.getAttribute("pageproxystate"), "invalid",
"page proxy state must be invalid for go button to be visible");
EventUtils.synthesizeMouseAtCenter(gGoButton, aEvent);
EventUtils.synthesizeMouseAtCenter(gGoButton, aEvent);
}
else
EventUtils.synthesizeKey("VK_RETURN", aEvent);

Просмотреть файл

@ -41,7 +41,7 @@ function testNext() {
gURLBar.focus();
paste(inputValue, function() {
is(gURLBar.value, expectedURL, "entering '" + inputValue + "' strips relevant bits.");
is(gURLBar.textValue, expectedURL, "entering '" + inputValue + "' strips relevant bits.");
setTimeout(testNext, 0);
});

Просмотреть файл

@ -27,7 +27,7 @@ function test() {
};
let history = Cc["@mozilla.org/browser/history;1"]
.getService(Ci.mozIAsyncHistory);
history.updatePlaces({ uri: NetUtil.newURI("http://www.autofilltrimurl.com/")
history.updatePlaces({ uri: NetUtil.newURI("http://www.autofilltrimurl.com/whatever")
, visits: [ { transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED
, visitDate: Date.now() * 1000
} ]
@ -44,7 +44,8 @@ function continue_test() {
EventUtils.synthesizeKey(aTyped.substr(-1), {});
waitForSearchComplete(function () {
is(gURLBar.value, aExpected, "trim was applied correctly");
info(`Got value: ${gURLBar.value}`);
is(gURLBar.value, aExpected, "Autofilled value is as expected");
aCallback();
});
}
@ -53,9 +54,9 @@ function continue_test() {
test_autoFill("http://au", "http://autofilltrimurl.com/", function () {
test_autoFill("http://www.autofilltrimurl.com", "http://www.autofilltrimurl.com/", function () {
// Now ensure selecting from the popup correctly trims.
is(gURLBar.controller.matchCount, 1, "Found the expected number of matches");
is(gURLBar.controller.matchCount, 2, "Found the expected number of matches");
EventUtils.synthesizeKey("VK_DOWN", {});
is(gURLBar.value, "www.autofilltrimurl.com", "trim was applied correctly");
is(gURLBar.textValue, "www.autofilltrimurl.com/whatever", "trim was applied correctly");
gURLBar.closePopup();
waitForClearHistory(finish);
});

Просмотреть файл

@ -156,7 +156,7 @@ function runTest(test, cb) {
function doCheck() {
if (test.setURL || test.loadURL) {
gURLBar.valueIsTyped = !!test.setURL;
is(gURLBar.value, test.expectedURL, "url bar value set");
is(gURLBar.textValue, test.expectedURL, "url bar value set");
}
testCopy(test.copyVal, test.copyExpected, cb);
@ -180,7 +180,7 @@ function testCopy(copyVal, targetValue, cb) {
let endBracket = copyVal.indexOf(">");
if (startBracket == -1 || endBracket == -1 ||
startBracket > endBracket ||
copyVal.replace("<", "").replace(">", "") != gURLBar.value) {
copyVal.replace("<", "").replace(">", "") != gURLBar.textValue) {
ok(false, "invalid copyVal: " + copyVal);
}
gURLBar.selectionStart = startBracket;

Просмотреть файл

@ -51,12 +51,12 @@ let gTests = [
]
function checkCurrent(aTab) {
is(gURLBar.value, TEST_VALUE, "Urlbar should preserve the value on return keypress");
is(gURLBar.textValue, TEST_VALUE, "Urlbar should preserve the value on return keypress");
is(gBrowser.selectedTab, aTab, "New URL was loaded in the current tab");
}
function checkNewTab(aTab) {
is(gURLBar.value, TEST_VALUE, "Urlbar should preserve the value on return keypress");
is(gURLBar.textValue, TEST_VALUE, "Urlbar should preserve the value on return keypress");
isnot(gBrowser.selectedTab, aTab, "New URL was loaded in a new tab");
}

Просмотреть файл

@ -11,23 +11,23 @@ function test() {
function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
is(gURLBar.value, gURLBar.trimValue(goodURL), "location bar reflects loaded page");
is(gURLBar.textValue, gURLBar.trimValue(goodURL), "location bar reflects loaded page");
typeAndSubmit(badURL);
is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects loading page");
is(gURLBar.textValue, gURLBar.trimValue(badURL), "location bar reflects loading page");
gBrowser.contentWindow.stop();
is(gURLBar.value, gURLBar.trimValue(goodURL), "location bar reflects loaded page after stop()");
is(gURLBar.textValue, gURLBar.trimValue(goodURL), "location bar reflects loaded page after stop()");
gBrowser.removeCurrentTab();
gBrowser.selectedTab = gBrowser.addTab("about:blank");
is(gURLBar.value, "", "location bar is empty");
is(gURLBar.textValue, "", "location bar is empty");
typeAndSubmit(badURL);
is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects loading page");
is(gURLBar.textValue, gURLBar.trimValue(badURL), "location bar reflects loading page");
gBrowser.contentWindow.stop();
is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects stopped page in an empty tab");
is(gURLBar.textValue, gURLBar.trimValue(badURL), "location bar reflects stopped page in an empty tab");
gBrowser.removeCurrentTab();
finish();

Просмотреть файл

@ -5,7 +5,7 @@
function testVal(originalValue, targetValue) {
gURLBar.value = originalValue;
gURLBar.valueIsTyped = false;
is(gURLBar.value, targetValue || originalValue, "url bar value set");
is(gURLBar.textValue, targetValue || originalValue, "url bar value set");
}
function test() {
@ -96,7 +96,7 @@ function test() {
function testCopy(originalValue, targetValue, cb) {
waitForClipboard(targetValue, function () {
is(gURLBar.value, originalValue, "url bar copy value set");
is(gURLBar.textValue, originalValue, "url bar copy value set");
gURLBar.focus();
gURLBar.select();

Просмотреть файл

@ -6,6 +6,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
function closeAllNotifications () {
let notificationBox = document.getElementById("global-notificationbox");

Просмотреть файл

@ -132,9 +132,7 @@
-->
<method name="onBeforeValueGet">
<body><![CDATA[
if (this.hasAttribute("actiontype"))
return {value: this._value};
return null;
return {value: this._value};
]]></body>
</method>
@ -285,31 +283,31 @@
var mayInheritPrincipal = false;
var postData = null;
var action = this._parseActionUrl(url);
let action = this._parseActionUrl(this._value);
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
let matchLastLocationChange = true;
if (action) {
if (this.hasAttribute("actiontype")) {
if (action.type == "switchtab") {
url = action.params.url;
if (action.type == "switchtab") {
url = action.params.url;
if (this.hasAttribute("actiontype")) {
this.handleRevert();
let prevTab = gBrowser.selectedTab;
if (switchToTabHavingURI(url) &&
isTabEmpty(prevTab))
gBrowser.removeTab(prevTab);
return;
} else if (action.type == "keyword") {
url = action.params.url;
} else if (action.type == "searchengine") {
let engine = Services.search.getEngineByName(action.params.engineName);
let submission = engine.getSubmission(action.params.searchQuery);
url = submission.uri.spec;
postData = submission.postData;
} else if (action.type == "visiturl") {
url = action.params.url;
}
} else if (action.type == "keyword") {
url = action.params.url;
} else if (action.type == "searchengine") {
let engine = Services.search.getEngineByName(action.params.engineName);
let submission = engine.getSubmission(action.params.searchQuery);
url = submission.uri.spec;
postData = submission.postData;
} else if (action.type == "visiturl") {
url = action.params.url;
}
continueOperation.call(this);
}
@ -584,7 +582,11 @@
urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
urlbar.inputField.value.substring(end);
urlbar.selectionStart = urlbar.selectionEnd = start;
urlbar.removeAttribute("actiontype");
let event = document.createEvent("UIEvents");
event.initUIEvent("input", true, false, window, 0);
urlbar.dispatchEvent(event);
SetPageProxyState("invalid");
}
@ -704,8 +706,10 @@
]]></body>
</method>
<property name="textValue"
onget="return this.value;">
<property name="textValue">
<getter><![CDATA[
return this.inputField.value;
]]></getter>
<setter>
<![CDATA[
try {
@ -714,8 +718,10 @@
// Trim popup selected values, but never trim results coming from
// autofill.
if (this.popup.selectedIndex == -1)
if (this.popup.selectedIndex == -1 ||
this.mController.getStyleAt(this.popup.selectedIndex) == "autofill") {
this._disableTrim = true;
}
this.value = val;
this._disableTrim = false;
@ -740,7 +746,6 @@
// URL is in the format moz-action:ACTION,PARAMS
// Where PARAMS is a JSON encoded object.
aUrl = decodeURI(aUrl);
let [, type, params] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
let action = {
@ -786,6 +791,19 @@
this.inputField.setSelectionRange(aStartIndex, aEndIndex);
]]></body>
</method>
<method name="onInput">
<parameter name="aEvent"/>
<body><![CDATA[
if (!this.mIgnoreInput && this.mController.input == this) {
this._value = this.inputField.value;
gBrowser.userTypedValue = this.value;
this.valueIsTyped = true;
this.mController.handleText();
}
this.resetActionType();
]]></body>
</method>
</implementation>
<handlers>
@ -819,7 +837,7 @@
<handler event="dragstart" phase="capturing"><![CDATA[
// Drag only if the gesture starts from the input field.
if (this.inputField != event.originalTarget &&
if (this.inputField != event.originalTarget &&
!(this.inputField.compareDocumentPosition(event.originalTarget) &
Node.DOCUMENT_POSITION_CONTAINED_BY))
return;
@ -943,6 +961,35 @@
createBundle("chrome://browser/locale/places/places.properties");
</field>
<!-- Override this so that navigating between items results in an item
always being selected. This is contrary to the normal behaviour where
if you navigate beyond either end of the list, no item will be
selected. -->
<method name="getNextIndex">
<parameter name="reverse"/>
<parameter name="amount"/>
<parameter name="index"/>
<parameter name="maxRow"/>
<body><![CDATA[
if (maxRow < 0)
return -1;
let newIndex = index + (reverse ? -1 : 1) * amount;
// We don't want to wrap if navigation in any direction by one item.
// Otherwise we clamp to one end of the list.
// ie, hitting page-down will only cause is to wrap if we're already
// at one end of the list.
if (newIndex < 0) {
newIndex = index > 0 ? 0 : maxRow;
} else if (newIndex > maxRow) {
newIndex = index < maxRow ? maxRow : 0;
}
return newIndex;
]]></body>
</method>
<property name="maxResults" readonly="true">
<getter>
<![CDATA[
@ -1050,6 +1097,18 @@
</body>
</method>
<method name="onResultsAdded">
<body>
<![CDATA[
if (!Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete"))
return;
if (this._matchCount > 0 && this.selectedIndex == -1)
this.selectedIndex = 0;
]]>
</body>
</method>
</implementation>
</binding>

Просмотреть файл

@ -413,13 +413,12 @@ this.DownloadsCommon = {
if (shouldApplySmoothing) {
// Apply hysteresis to favor downward over upward swings. Trust only 30%
// of the new value if lower, and 10% if higher (exponential smoothing).
let (diff = aSeconds - aLastSeconds) {
aSeconds = aLastSeconds + (diff < 0 ? .3 : .1) * diff;
}
let diff = aSeconds - aLastSeconds;
aSeconds = aLastSeconds + (diff < 0 ? .3 : .1) * diff;
// If the new time is similar, reuse something close to the last time
// left, but subtract a little to provide forward progress.
let diff = aSeconds - aLastSeconds;
diff = aSeconds - aLastSeconds;
let diffPercent = diff / aLastSeconds * 100;
if (Math.abs(diff) < 5 || Math.abs(diffPercent) < 5) {
aSeconds = aLastSeconds - (diff < 0 ? .4 : .2);

Просмотреть файл

@ -21,6 +21,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "LOOP_SESSION_TYPE",
XPCOMUtils.defineLazyModuleGetter(this, "LoopContacts",
"resource:///modules/loop/LoopContacts.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
/**
* Attempts to open a websocket.
@ -326,6 +328,50 @@ let LoopCallsInternal = {
return true;
},
/**
* Block a caller so it will show up in the contacts list as a blocked contact.
* If the contact is not yet part of the users' contacts list, it will be added
* as a blocked contact directly.
*
* @param {String} callerId Email address or phone number that may identify
* the caller as an existing contact
* @param {Function} callback Function that will be invoked once the operation
* has completed. When an error occurs, it will be
* passed as its first argument
*/
blockDirectCaller: function(callerId, callback) {
let field = callerId.contains("@") ? "email" : "tel";
Task.spawn(function* () {
// See if we can find the caller in our database.
let contacts = yield LoopContacts.promise("search", {
q: callerId,
field: field
});
let contact;
if (contacts.length) {
for (contact of contacts) {
yield LoopContacts.promise("block", contact._guid);
}
} else {
// If the contact doesn't exist yet, add it as a blocked contact.
contact = {
id: MozLoopService.generateUUID(),
name: [callerId],
category: ["local"],
blocked: true
};
// Add the phone OR email field to the contact.
contact[field] = [{
pref: true,
value: callerId
}];
yield LoopContacts.promise("add", contact);
}
}).then(callback, callback);
},
/**
* Open call progress websocket and terminate with a reason of busy
* the server.
@ -400,6 +446,13 @@ this.LoopCalls = {
*/
startDirectCall: function(contact, callType) {
LoopCallsInternal.startDirectCall(contact, callType);
},
/**
* @see LoopCallsInternal#blockDirectCaller
*/
blockDirectCaller: function(callerId, callback) {
return LoopCallsInternal.blockDirectCaller(callerId, callback);
}
};
Object.freeze(LoopCalls);

Просмотреть файл

@ -774,7 +774,14 @@ let MozLoopServiceInternal = {
openChatWindow: function(conversationWindowData) {
// So I guess the origin is the loop server!?
let origin = this.loopServerUri;
let windowId = gLastWindowId++;
// Try getting a window ID that can (re-)identify this conversation, or resort
// to a globally unique one as a last resort.
// XXX We can clean this up once rooms and direct contact calling are the only
// two modes left.
let windowId = ("contact" in conversationWindowData) ?
conversationWindowData.contact._guid || gLastWindowId++ :
conversationWindowData.roomToken || conversationWindowData.callId ||
gLastWindowId++;
// Store the id as a string, as that's what we use elsewhere.
windowId = windowId.toString();
@ -1421,9 +1428,12 @@ this.MozLoopService = {
*/
openGettingStartedTour: Task.async(function(aSrc = null) {
try {
let url = new URL(Services.prefs.getCharPref("loop.gettingStarted.url"));
let urlStr = Services.prefs.getCharPref("loop.gettingStarted.url");
let url = new URL(Services.urlFormatter.formatURL(urlStr));
if (aSrc) {
url.searchParams.set("source", aSrc);
url.searchParams.set("utm_source", "firefox-browser");
url.searchParams.set("utm_medium", "firefox-browser");
url.searchParams.set("utm_campaign", aSrc);
}
let win = Services.wm.getMostRecentWindow("navigator:browser");
win.switchToTabHavingURI(url, true, {replaceQueryString: true});

Просмотреть файл

@ -20,6 +20,9 @@ loop.conversation = (function(mozL10n) {
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
// Matches strings of the form "<nonspaces>@<nonspaces>" or "+<digits>"
var EMAIL_OR_PHONE_RE = /^(:?\S+@\S+|\+\d+)$/;
var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
@ -505,14 +508,27 @@ loop.conversation = (function(mozL10n) {
declineAndBlock: function() {
navigator.mozLoop.stopAlerting();
var token = this.props.conversation.get("callToken");
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
var callerId = this.props.conversation.get("callerId");
// If this is a direct call, we'll need to block the caller directly.
if (callerId && EMAIL_OR_PHONE_RE.test(callerId)) {
navigator.mozLoop.calls.blockDirectCaller(callerId, function(err) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
// (bug 1103150).
console.log(err.fileName + ":" + err.lineNumber + ": " + err.message);
});
} else {
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
});
}
this._declineCall();
},

Просмотреть файл

@ -20,6 +20,9 @@ loop.conversation = (function(mozL10n) {
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
// Matches strings of the form "<nonspaces>@<nonspaces>" or "+<digits>"
var EMAIL_OR_PHONE_RE = /^(:?\S+@\S+|\+\d+)$/;
var IncomingCallView = React.createClass({
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
@ -505,14 +508,27 @@ loop.conversation = (function(mozL10n) {
declineAndBlock: function() {
navigator.mozLoop.stopAlerting();
var token = this.props.conversation.get("callToken");
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
var callerId = this.props.conversation.get("callerId");
// If this is a direct call, we'll need to block the caller directly.
if (callerId && EMAIL_OR_PHONE_RE.test(callerId)) {
navigator.mozLoop.calls.blockDirectCaller(callerId, function(err) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
// (bug 1103150).
console.log(err.fileName + ":" + err.lineNumber + ": " + err.message);
});
} else {
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
});
}
this._declineCall();
},

Просмотреть файл

@ -165,12 +165,11 @@ loop.panel = (function(_, mozL10n) {
});
var GettingStartedView = React.createClass({displayName: 'GettingStartedView',
componentDidMount: function() {
navigator.mozLoop.setLoopPref("gettingStarted.seen", true);
},
handleButtonClick: function() {
navigator.mozLoop.openGettingStartedTour();
navigator.mozLoop.openGettingStartedTour("getting-started");
navigator.mozLoop.setLoopPref("gettingStarted.seen", true);
var event = new CustomEvent("GettingStartedSeen");
window.dispatchEvent(event);
},
render: function() {
@ -287,7 +286,7 @@ loop.panel = (function(_, mozL10n) {
},
openGettingStartedTour: function() {
navigator.mozLoop.openGettingStartedTour("settingsMenu");
navigator.mozLoop.openGettingStartedTour("settings-menu");
},
render: function() {
@ -694,6 +693,7 @@ loop.panel = (function(_, mozL10n) {
getInitialState: function() {
return {
userProfile: this.props.userProfile || navigator.mozLoop.userProfile,
gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
};
},
@ -741,6 +741,12 @@ loop.panel = (function(_, mozL10n) {
this.updateServiceErrors();
},
_gettingStartedSeen: function() {
this.setState({
gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
});
},
/**
* The rooms feature is hidden by default for now. Once it gets mainstream,
* this method can be simplified.
@ -750,7 +756,6 @@ loop.panel = (function(_, mozL10n) {
return (
Tab({name: "call"},
React.DOM.div({className: "content-area"},
GettingStartedView(null),
CallUrlResult({client: this.props.client,
notifications: this.props.notifications,
callUrl: this.props.callUrl}),
@ -762,7 +767,6 @@ loop.panel = (function(_, mozL10n) {
return (
Tab({name: "rooms"},
GettingStartedView(null),
RoomList({dispatcher: this.props.dispatcher,
store: this.props.roomStore,
userDisplayName: this._getUserDisplayName()}),
@ -786,10 +790,12 @@ loop.panel = (function(_, mozL10n) {
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
},
_getUserDisplayName: function() {
@ -800,6 +806,17 @@ loop.panel = (function(_, mozL10n) {
render: function() {
var NotificationListView = sharedViews.NotificationListView;
if (!this.state.gettingStartedSeen) {
return (
React.DOM.div(null,
NotificationListView({notifications: this.props.notifications,
clearOnDocumentHidden: true}),
GettingStartedView(null),
ToSView(null)
)
);
}
return (
React.DOM.div(null,
NotificationListView({notifications: this.props.notifications,

Просмотреть файл

@ -165,12 +165,11 @@ loop.panel = (function(_, mozL10n) {
});
var GettingStartedView = React.createClass({
componentDidMount: function() {
navigator.mozLoop.setLoopPref("gettingStarted.seen", true);
},
handleButtonClick: function() {
navigator.mozLoop.openGettingStartedTour();
navigator.mozLoop.openGettingStartedTour("getting-started");
navigator.mozLoop.setLoopPref("gettingStarted.seen", true);
var event = new CustomEvent("GettingStartedSeen");
window.dispatchEvent(event);
},
render: function() {
@ -287,7 +286,7 @@ loop.panel = (function(_, mozL10n) {
},
openGettingStartedTour: function() {
navigator.mozLoop.openGettingStartedTour("settingsMenu");
navigator.mozLoop.openGettingStartedTour("settings-menu");
},
render: function() {
@ -694,6 +693,7 @@ loop.panel = (function(_, mozL10n) {
getInitialState: function() {
return {
userProfile: this.props.userProfile || navigator.mozLoop.userProfile,
gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
};
},
@ -741,6 +741,12 @@ loop.panel = (function(_, mozL10n) {
this.updateServiceErrors();
},
_gettingStartedSeen: function() {
this.setState({
gettingStartedSeen: navigator.mozLoop.getLoopPref("gettingStarted.seen"),
});
},
/**
* The rooms feature is hidden by default for now. Once it gets mainstream,
* this method can be simplified.
@ -750,7 +756,6 @@ loop.panel = (function(_, mozL10n) {
return (
<Tab name="call">
<div className="content-area">
<GettingStartedView />
<CallUrlResult client={this.props.client}
notifications={this.props.notifications}
callUrl={this.props.callUrl} />
@ -762,7 +767,6 @@ loop.panel = (function(_, mozL10n) {
return (
<Tab name="rooms">
<GettingStartedView />
<RoomList dispatcher={this.props.dispatcher}
store={this.props.roomStore}
userDisplayName={this._getUserDisplayName()}/>
@ -786,10 +790,12 @@ loop.panel = (function(_, mozL10n) {
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
},
_getUserDisplayName: function() {
@ -800,6 +806,17 @@ loop.panel = (function(_, mozL10n) {
render: function() {
var NotificationListView = sharedViews.NotificationListView;
if (!this.state.gettingStartedSeen) {
return (
<div>
<NotificationListView notifications={this.props.notifications}
clearOnDocumentHidden={true} />
<GettingStartedView />
<ToSView />
</div>
);
}
return (
<div>
<NotificationListView notifications={this.props.notifications}

Просмотреть файл

@ -107,7 +107,6 @@ body {
#fte-getstarted {
padding-top: 1em;
padding-bottom: 1em;
border-bottom: 1px solid #ccc;
margin-bottom: 1em;
}
@ -499,7 +498,7 @@ body[dir=rtl] .generate-url-spinner {
}
#powered-by-logo.en-GB,
#powered-by-logo.de-DE {
#powered-by-logo.de {
background-image: url("../img/02.png");
background-size: 21px 20px;
width: 21px;
@ -526,7 +525,7 @@ body[dir=rtl] .generate-url-spinner {
}
#powered-by-logo.en-GB,
#powered-by-logo.de-DE {
#powered-by-logo.de {
background-image: url("../img/02@2x.png");
}

Просмотреть файл

@ -75,6 +75,8 @@ loop.store.ConversationStore = (function() {
// Call Connection information
// The call id from the loop-server
callId: undefined,
// The caller id of the contacting side
callerId: undefined,
// The connection progress url to connect the websocket
progressURL: undefined,
// The websocket token that allows connection to the progress url

Просмотреть файл

@ -12,7 +12,7 @@
# Bug 1066176 tracks moving all functionality currently here
# to the Gruntfile and getting rid of this Makefile entirely.
LOOP_SERVER_URL := $(shell echo $${LOOP_SERVER_URL-http://localhost:5000})
LOOP_SERVER_URL := $(shell echo $${LOOP_SERVER_URL-http://localhost:5000/v0})
LOOP_FEEDBACK_API_URL := $(shell echo $${LOOP_FEEDBACK_API_URL-"https://input.allizom.org/api/v1/feedback"})
LOOP_FEEDBACK_PRODUCT_NAME := $(shell echo $${LOOP_FEEDBACK_PRODUCT_NAME-Loop})
LOOP_BRAND_WEBSITE_URL := $(shell echo $${LOOP_BRAND_WEBSITE_URL-"https://www.mozilla.org/firefox/"})

Просмотреть файл

@ -18,7 +18,7 @@ function getConfigFile(req, res) {
res.send([
"var loop = loop || {};",
"loop.config = loop.config || {};",
"loop.config.serverUrl = 'http://localhost:" + loopServerPort + "';",
"loop.config.serverUrl = 'http://localhost:" + loopServerPort + "/v0';",
"loop.config.feedbackApiUrl = '" + feedbackApiUrl + "';",
"loop.config.feedbackProductName = '" + feedbackProductName + "';",
// XXX Update with the real marketplace url once the FxOS Loop app is

Просмотреть файл

@ -175,7 +175,8 @@ describe("loop.panel", function() {
describe("loop.rooms.enabled on", function() {
beforeEach(function() {
navigator.mozLoop.getLoopPref = function(pref) {
if (pref === "rooms.enabled") {
if (pref === "rooms.enabled" ||
pref === "gettingStarted.seen") {
return true;
}
};
@ -208,6 +209,8 @@ describe("loop.panel", function() {
navigator.mozLoop.getLoopPref = function(pref) {
if (pref === "rooms.enabled") {
return false;
} else if (pref === "gettingStarted.seen") {
return true;
}
};
@ -373,6 +376,9 @@ describe("loop.panel", function() {
});
it("should render a GettingStarted view", function() {
navigator.mozLoop.getLoopPref = function(pref) {
return false;
};
var view = createTestPanelView();
TestUtils.findRenderedComponentWithType(view, loop.panel.GettingStartedView);

Просмотреть файл

@ -40,6 +40,7 @@ function* checkFxA401() {
add_task(function* setup() {
Services.prefs.setCharPref("loop.server", BASE_URL);
Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
MozLoopServiceInternal.mocks.pushHandler = mockPushHandler;
// Normally the same pushUrl would be registered but we change it in the test
// to be able to check for success on the second registration.
@ -51,6 +52,7 @@ add_task(function* setup() {
yield promiseDeletedOAuthParams(BASE_URL);
Services.prefs.clearUserPref("loop.server");
Services.prefs.clearUserPref("services.push.serverURL");
Services.prefs.clearUserPref("loop.gettingStarted.seen");
MozLoopServiceInternal.mocks.pushHandler = undefined;
delete mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA];
delete mockPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];

Просмотреть файл

@ -9,11 +9,13 @@
Components.utils.import("resource://gre/modules/Promise.jsm", this);
const {LoopRoomsInternal} = Components.utils.import("resource:///modules/loop/LoopRooms.jsm", {});
Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
registerCleanupFunction(function*() {
MozLoopService.doNotDisturb = false;
MozLoopServiceInternal.fxAOAuthProfile = null;
yield MozLoopServiceInternal.clearError("testing");
Services.prefs.clearUserPref("loop.gettingStarted.seen");
});
add_task(function* test_doNotDisturb() {

Просмотреть файл

@ -299,8 +299,8 @@ add_task(function* test_openRoom() {
Assert.ok(openedUrl, "should open a chat window");
// Stop the busy kicking in for following tests.
let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
// Stop the busy kicking in for following tests. (note: windowId can be 'fakeToken')
let windowId = openedUrl.match(/about:loopconversation\#(\w+)$/)[1];
let windowData = MozLoopService.getConversationWindowData(windowId);
Assert.equal(windowData.type, "room", "window data should contain room as the type");

Просмотреть файл

@ -123,14 +123,16 @@ function doOnloadOnce(aCallback) {
}
function* promiseOnLoad() {
let deferred = Promise.defer();
gBrowser.addEventListener("load", function onLoadListener(aEvent) {
info("onLoadListener: " + aEvent.originalTarget.location);
gBrowser.removeEventListener("load", onLoadListener, true);
deferred.resolve(aEvent);
}, true);
return deferred.promise;
return new Promise(resolve => {
gBrowser.addEventListener("load", function onLoadListener(aEvent) {
let cw = aEvent.target.defaultView;
let tab = gBrowser._getTabForContentWindow(cw);
if (tab) {
info("onLoadListener: " + aEvent.originalTarget.location);
gBrowser.removeEventListener("load", onLoadListener, true);
resolve(aEvent);
}
}, true);
});
}

Просмотреть файл

@ -648,8 +648,21 @@ let SessionStoreInternal = {
let uri = activePageData ? activePageData.url || null : null;
browser.userTypedValue = uri;
// Update tab label and icon again after the tab history was updated.
this.updateTabLabelAndIcon(tab, tabData);
// If the page has a title, set it.
if (activePageData) {
if (activePageData.title) {
tab.label = activePageData.title;
tab.crop = "end";
} else if (activePageData.url != "about:blank") {
tab.label = activePageData.url;
tab.crop = "center";
}
}
// Restore the tab icon.
if ("image" in tabData) {
win.gBrowser.setIcon(tab, tabData.image);
}
let event = win.document.createEvent("Events");
event.initEvent("SSTabRestoring", true, false);
@ -1860,26 +1873,6 @@ let SessionStoreInternal = {
}
},
updateTabLabelAndIcon(tab, tabData) {
let activePageData = tabData.entries[tabData.index - 1] || null;
// If the page has a title, set it.
if (activePageData) {
if (activePageData.title) {
tab.label = activePageData.title;
tab.crop = "end";
} else if (activePageData.url != "about:blank") {
tab.label = activePageData.url;
tab.crop = "center";
}
}
// Restore the tab icon.
if ("image" in tabData) {
tab.ownerDocument.defaultView.gBrowser.setIcon(tab, tabData.image);
}
},
/**
* Restores the session state stored in LastSession. This will attempt
* to merge data into the current session. If a window was opened at startup
@ -2552,17 +2545,9 @@ let SessionStoreInternal = {
this._windows[aWindow.__SSi].selected = aSelectTab;
}
// If we restore the selected tab, make sure it goes first.
let selectedIndex = aTabs.indexOf(tabbrowser.selectedTab);
if (selectedIndex > -1) {
this.restoreTab(tabbrowser.selectedTab, aTabData[selectedIndex]);
}
// Restore all tabs.
for (let t = 0; t < aTabs.length; t++) {
if (t != selectedIndex) {
this.restoreTab(aTabs[t], aTabData[t]);
}
this.restoreTab(aTabs[t], aTabData[t]);
}
},
@ -2668,10 +2653,6 @@ let SessionStoreInternal = {
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory",
{tabData: tabData, epoch: epoch});
// Update tab label and icon to show something
// while we wait for the messages to be processed.
this.updateTabLabelAndIcon(tab, tabData);
// Restore tab attributes.
if ("attributes" in tabData) {
TabAttributes.set(tab, tabData.attributes);

Просмотреть файл

@ -193,16 +193,16 @@ function test() {
is(browser.userTypedValue, null, "userTypedValue is empty to start");
is(browser.userTypedClear, 0, "userTypedClear is 0 to start");
gURLBar.value = "example.org";
let event = document.createEvent("Events");
event.initEvent("input", true, false);
gURLBar.dispatchEvent(event);
let inputText = "example.org";
gURLBar.focus();
gURLBar.value = inputText.slice(0, -1);
EventUtils.synthesizeKey(inputText.slice(-1) , {});
executeSoon(function () {
is(browser.userTypedValue, "example.org",
"userTypedValue was set when changing gURLBar.value");
"userTypedValue was set when changing URLBar value");
is(browser.userTypedClear, 0,
"userTypedClear was not changed when changing gURLBar.value");
"userTypedClear was not changed when changing URLBar value");
// Now make sure ss gets these values too
let newState = JSON.parse(ss.getBrowserState());
@ -235,7 +235,7 @@ function test() {
"userTypedValue was null after loading a URI");
is(browser.userTypedClear, 0,
"userTypeClear reset to 0");
is(gURLBar.value, gURLBar.trimValue("http://example.com/"),
is(gURLBar.textValue, gURLBar.trimValue("http://example.com/"),
"Address bar's value set after loading URI");
runNextTest();
});

Просмотреть файл

@ -98,25 +98,25 @@ support-files =
testactors.js
[browser_dbg_aaa_run_first_leaktest.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_addonactor.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_addon-sources.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_addon-modules.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_addon-modules-unpacked.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_addon-panels.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_addon-console.js]
skip-if = e10s || os == 'win' # bug 1005274
skip-if = e10s && debug || os == 'win' # bug 1005274
[browser_dbg_auto-pretty-print-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_auto-pretty-print-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_bfcache.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_blackboxing-01.js]
skip-if = e10s && debug
[browser_dbg_blackboxing-02.js]
@ -130,9 +130,9 @@ skip-if = e10s && debug
[browser_dbg_blackboxing-06.js]
skip-if = e10s && debug
[browser_dbg_breadcrumbs-access.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_break-on-dom-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_break-on-dom-02.js]
skip-if = e10s && debug
[browser_dbg_break-on-dom-03.js]
@ -150,7 +150,7 @@ skip-if = e10s && debug
[browser_dbg_break-on-dom-event-01.js]
skip-if = e10s || os == "mac" || e10s # Bug 895426
[browser_dbg_break-on-dom-event-02.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_breakpoints-actual-location.js]
skip-if = e10s && debug
[browser_dbg_breakpoints-actual-location2.js]
@ -180,21 +180,21 @@ skip-if = e10s && debug
[browser_dbg_breakpoints-reload.js]
skip-if = e10s && debug
[browser_dbg_chrome-create.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_chrome-debugging.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_clean-exit-window.js]
skip-if = true # Bug 933950 (leaky test)
[browser_dbg_clean-exit.js]
skip-if = true # Bug 1044985 (racy test)
[browser_dbg_closure-inspection.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_cmd-blackbox.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_cmd-break.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_cmd-dbg.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_conditional-breakpoints-01.js]
skip-if = e10s && debug
[browser_dbg_conditional-breakpoints-02.js]
@ -212,73 +212,73 @@ skip-if = e10s && debug
[browser_dbg_server-conditional-bp-04.js]
skip-if = e10s && debug
[browser_dbg_controller-evaluate-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_controller-evaluate-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_debugger-statement.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_editor-contextmenu.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_editor-mode.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_event-listeners-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_event-listeners-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_event-listeners-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_file-reload.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_function-display-name.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_global-method-override.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_globalactor.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_hide-toolbar-buttons.js]
skip-if = e10s
[browser_dbg_hit-counts-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_hit-counts-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_host-layout.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_iframes.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_instruments-pane-collapse.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_interrupts.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_listaddons.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_listtabs-01.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_listtabs-02.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_listtabs-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_location-changes-01-simple.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_location-changes-02-blank.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_location-changes-03-new.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_location-changes-04-breakpoint.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_multiple-windows.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_navigation.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_no-page-sources.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_on-pause-highlight.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_on-pause-raise.js]
skip-if = e10s || os == "linux" || e10s # Bug 888811 & bug 891176
skip-if = e10s && debug || os == "linux" # Bug 888811 & bug 891176
[browser_dbg_optimized-out-vars.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_panel-size.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_parser-01.js]
skip-if = e10s && debug
[browser_dbg_parser-02.js]
@ -300,13 +300,13 @@ skip-if = e10s && debug
[browser_dbg_parser-10.js]
skip-if = e10s && debug
[browser_dbg_pause-exceptions-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_pause-exceptions-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_pause-resume.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_pause-warning.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_paused-keybindings.js]
skip-if = e10s
[browser_dbg_pretty-print-01.js]
@ -338,21 +338,21 @@ skip-if = e10s && debug
[browser_dbg_pretty-print-on-paused.js]
skip-if = e10s && debug
[browser_dbg_progress-listener-bug.js]
skip-if = e10s
skip-if = e10a && debug
[browser_dbg_reload-preferred-script-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_reload-preferred-script-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_reload-preferred-script-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_reload-same-script.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_scripts-switching-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_scripts-switching-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_scripts-switching-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_search-autofill-identifier.js]
skip-if = e10s && debug
[browser_dbg_search-basic-01.js]
@ -400,13 +400,13 @@ skip-if = e10s && debug
[browser_dbg_source-maps-04.js]
skip-if = e10s # Bug 1093535
[browser_dbg_sources-cache.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_sources-labels.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_sources-sorting.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_split-console-paused-reload.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_stack-01.js]
skip-if = e10s && debug
[browser_dbg_stack-02.js]
@ -422,13 +422,13 @@ skip-if = e10s && debug
[browser_dbg_stack-07.js]
skip-if = e10s && debug
[browser_dbg_step-out.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tabactor-01.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_tabactor-02.js]
skip-if = e10s
skip-if = e10s # TODO
[browser_dbg_terminate-on-tab-close.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-01.js]
skip-if = e10s && debug
[browser_dbg_tracing-02.js]

Просмотреть файл

@ -14,15 +14,14 @@ function test() {
// GC from previous tests does not interfere with the debugger suite.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
ok(aTab, "Should have a tab available.");
ok(aDebuggee, "Should have a debuggee available.");
ok(aPanel, "Should have a debugger pane available.");
waitForSourceAndCaretAndScopes(aPanel, "-02.js", 1).then(() => {
resumeDebuggerThenCloseAndFinish(aPanel);
});
aDebuggee.firstCall();
callInTab(aTab, "firstCall");
});
}

Просмотреть файл

@ -5,7 +5,7 @@
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources, gPrefs, gOptions, gView;
let gFirstSourceLabel = "code_ugly-5.js";
@ -15,9 +15,8 @@ let gOriginalPref = Services.prefs.getBoolPref("devtools.debugger.auto-pretty-pr
Services.prefs.setBoolPref("devtools.debugger.auto-pretty-print", true);
function test(){
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -99,7 +98,6 @@ function testSourceIsPretty() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources, gFrames;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
@ -28,7 +27,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebuggee.firstCall();
callInTab(gTab, "firstCall");
});
function checkNavigationWhileNotFocused() {

Просмотреть файл

@ -8,7 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;
let gEvents = gView.EventListeners;

Просмотреть файл

@ -5,14 +5,13 @@
* Test that closing a tab with the debugger in a paused state exits cleanly.
*/
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -28,12 +27,11 @@ function testCleanExit() {
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_REFILLED);
}).then(() => closeDebuggerAndFinish(gPanel, { whilePaused: true }));
gDebuggee.runDebuggerStatement();
callInTab(gTab, "runDebuggerStatement");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

Просмотреть файл

@ -6,14 +6,12 @@ const TAB_URL = EXAMPLE_URL + "doc_closures.html";
// Test that inspecting a closure works as expected.
function test() {
let gPanel, gTab, gDebuggee, gDebugger;
let gPanel, gTab, gDebugger;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gDebuggee.gRecurseLimit = 2;
waitForSourceShown(gPanel, ".html")
.then(testClosure)
@ -24,13 +22,7 @@ function test() {
});
function testClosure() {
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
let gVars = gDebugger.DebuggerView.Variables;

Просмотреть файл

@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
Task.spawn(function() {
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin;
let frames = win.DebuggerController.StackFrames;
let framesView = win.DebuggerView.StackFrames;
@ -45,8 +45,7 @@ function test() {
"Evaluating shouldn't work while the debuggee isn't paused.");
}
// Allow this generator function to yield first.
executeSoon(() => debuggee.firstCall());
callInTab(tab, "firstCall");
yield waitForSourceAndCaretAndScopes(panel, "-02.js", 1);
checkView(0, 1, 1, [/secondCall/, 118]);

Просмотреть файл

@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
Task.spawn(function() {
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin;
let frames = win.DebuggerController.StackFrames;
let framesView = win.DebuggerView.StackFrames;
@ -38,7 +38,7 @@ function test() {
is(sources._cache.size, 2, "There should be two cached sources in the cache.");
// Allow this generator function to yield first.
executeSoon(() => debuggee.firstCall());
callInTab(tab, "firstCall");
yield waitForSourceAndCaretAndScopes(panel, "-02.js", 1);
checkView(0, 1, 1, [/secondCall/, 118]);

Просмотреть файл

@ -8,6 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
let gClient;
let gTab;
function test() {
if (!DebuggerServer.initialized) {
@ -22,7 +23,10 @@ function test() {
"Root actor should identify itself as a browser.");
addTab(TAB_URL)
.then(() => attachTabActorForUrl(gClient, TAB_URL))
.then((aTab) => {
gTab = aTab;
return attachTabActorForUrl(gClient, TAB_URL)
})
.then(testEarlyDebuggerStatement)
.then(testDebuggerStatement)
.then(closeConnection)
@ -45,8 +49,7 @@ function testEarlyDebuggerStatement([aGrip, aResponse]) {
// This should continue without nesting an event loop and calling
// the onPaused hook, because we haven't attached yet.
let debuggee = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
debuggee.runDebuggerStatement();
callInTab(gTab, "runDebuggerStatement");
gClient.removeListener("paused", onPaused);
@ -72,8 +75,7 @@ function testDebuggerStatement([aGrip, aResponse]) {
});
// Reach around the debugging protocol and execute the debugger statement.
let debuggee = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
debuggee.runDebuggerStatement();
callInTab(gTab, "runDebuggerStatement");
}
function closeConnection() {

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources, gContextMenu;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -21,7 +20,7 @@ function test() {
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest).then(null, info);
gDebuggee.firstCall();
callInTab(gTab, "firstCall");
});
function performTest() {

Просмотреть файл

@ -8,13 +8,12 @@
const TAB_URL = EXAMPLE_URL + "doc_editor-mode.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -29,7 +28,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebuggee.firstCall();
callInTab(gTab, "firstCall");
});
}
@ -85,7 +84,6 @@ function testSwitch2() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -8,6 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-01.html";
let gClient;
let gTab;
function test() {
if (!DebuggerServer.initialized) {
@ -22,7 +23,10 @@ function test() {
"Root actor should identify itself as a browser.");
addTab(TAB_URL)
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
.then((aTab) => {
gTab = aTab;
return attachThreadActorForUrl(gClient, TAB_URL)
})
.then(pauseDebuggee)
.then(testEventListeners)
.then(closeConnection)
@ -45,13 +49,7 @@ function pauseDebuggee(aThreadClient) {
deferred.resolve(aThreadClient);
});
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content);
});
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return deferred.promise;
}

Просмотреть файл

@ -9,6 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-03.html";
let gClient;
let gTab;
function test() {
if (!DebuggerServer.initialized) {
@ -23,7 +24,10 @@ function test() {
"Root actor should identify itself as a browser.");
addTab(TAB_URL)
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
.then((aTab) => {
gTab = aTab;
return attachThreadActorForUrl(gClient, TAB_URL);
})
.then(pauseDebuggee)
.then(testEventListeners)
.then(closeConnection)
@ -46,13 +50,7 @@ function pauseDebuggee(aThreadClient) {
deferred.resolve(aThreadClient);
});
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content);
});
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return deferred.promise;
}

Просмотреть файл

@ -9,6 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_native-event-handler.html";
let gClient;
let gTab;
function test() {
if (!DebuggerServer.initialized) {
@ -23,7 +24,10 @@ function test() {
"Root actor should identify itself as a browser.");
addTab(TAB_URL)
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
.then((aTab) => {
gTab = aTab;
return attachThreadActorForUrl(gClient, TAB_URL)
})
.then(pauseDebuggee)
.then(testEventListeners)
.then(closeConnection)
@ -46,13 +50,7 @@ function pauseDebuggee(aThreadClient) {
deferred.resolve(aThreadClient);
});
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content);
});
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return deferred.promise;
}

Просмотреть файл

@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_random-javascript.html";
const JS_URL = EXAMPLE_URL + "sjs_random-javascript.sjs";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let gDebugger = aPanel.panelWin;
let gEditor = gDebugger.DebuggerView.editor;
let gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_function-display-name.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -35,7 +34,7 @@ function testAnonCall() {
testInferredName();
});
gDebuggee.evalCall();
callInTab(gTab, "evalCall");
}
function testInferredName() {
@ -57,7 +56,6 @@ function testInferredName() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

Просмотреть файл

@ -10,7 +10,7 @@
const TAB_URL = EXAMPLE_URL + "doc_global-method-override.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let gDebugger = aPanel.panelWin;
ok(gDebugger, "Should have a debugger available.");
is(gDebugger.gThreadClient.state, "attached", "Debugger should be attached.");

Просмотреть файл

@ -9,16 +9,15 @@
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
const CODE_URL = "code_same-line-functions.js";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor;
function test() {
Task.async(function* () {
yield pushPrefs(["devtools.debugger.tracer", true]);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -44,9 +43,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function testHitCounts() {
@ -58,8 +55,7 @@ function testHitCounts() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
});
});

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
const CODE_URL = "code_same-line-functions.js";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor;
function test() {
Task.async(function* () {
yield pushPrefs(["devtools.debugger.tracer", true]);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -46,9 +45,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function testHitCountsBeforeStopping() {
@ -63,8 +60,7 @@ function testHitCountsAfterStopping() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
});
});

Просмотреть файл

@ -27,14 +27,14 @@ function testHosts(aHostTypes, aLayoutTypes) {
return Task.spawn(function() {
let [tab, debuggee, panel] = yield initDebugger("about:blank");
yield testHost(tab, debuggee, panel, firstHost, firstLayout);
yield switchAndTestHost(tab, debuggee, panel, secondHost, secondLayout);
yield switchAndTestHost(tab, debuggee, panel, thirdHost, thirdLayout);
yield testHost(tab, panel, firstHost, firstLayout);
yield switchAndTestHost(tab, panel, secondHost, secondLayout);
yield switchAndTestHost(tab, panel, thirdHost, thirdLayout);
yield teardown(panel);
});
}
function switchAndTestHost(aTab, aDebuggee, aPanel, aHostType, aLayoutType) {
function switchAndTestHost(aTab, aPanel, aHostType, aLayoutType) {
let gToolbox = aPanel._toolbox;
let gDebugger = aPanel.panelWin;
@ -48,7 +48,7 @@ function switchAndTestHost(aTab, aDebuggee, aPanel, aHostType, aLayoutType) {
yield layoutChanged;
ok(true, "The debugger's layout has changed.");
yield testHost(aTab, aDebuggee, aPanel, aHostType, aLayoutType);
yield testHost(aTab, aPanel, aHostType, aLayoutType);
});
function once(aTarget, aEvent) {
@ -58,7 +58,7 @@ function switchAndTestHost(aTab, aDebuggee, aPanel, aHostType, aLayoutType) {
}
}
function testHost(aTab, aDebuggee, aPanel, aHostType, aLayoutType) {
function testHost(aTab, aPanel, aHostType, aLayoutType) {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gPrefs, gOptions;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gPrefs = gDebugger.Prefs;
@ -146,7 +145,6 @@ function testPanesStartupPref() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gPrefs = null;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints, gTarget, gResumeButton, gResumeKey, gThreadClient;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources, gFrames;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -21,7 +20,7 @@ function test() {
gFrames = gDebugger.DebuggerView.StackFrames;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
gDebuggee.simpleCall();
callInTab(gTab, "simpleCall");
});
}
@ -62,7 +61,6 @@ function testLocationChange() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources, gFrames;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -21,7 +20,7 @@ function test() {
gFrames = gDebugger.DebuggerView.StackFrames;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
gDebuggee.simpleCall();
callInTab(gTab, "simpleCall");
});
}
@ -53,7 +52,6 @@ function testLocationChange() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -8,13 +8,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gToolbox, gToolboxTab;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gToolbox = gPanel._toolbox;
@ -69,7 +68,6 @@ function testResume() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gToolbox = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gNewTab, gFocusedWindow, gToolbox, gToolboxTab;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gToolbox = gPanel._toolbox;
@ -132,7 +131,6 @@ registerCleanupFunction(function() {
Services.prefs.setCharPref("devtools.toolbox.host", devtools.Toolbox.HostType.BOTTOM);
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;

Просмотреть файл

@ -8,7 +8,7 @@ function test() {
const TAB_URL = EXAMPLE_URL + "doc_closure-optimized-out.html";
let gDebugger, sources;
let [, debuggee, panel] = yield initDebugger(TAB_URL);
let [tab,, panel] = yield initDebugger(TAB_URL);
gDebugger = panel.panelWin;
sources = gDebugger.DebuggerView.Sources;
@ -18,11 +18,7 @@ function test() {
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
debuggee.document.querySelector("button"),
debuggee);
});
sendMouseClickToTab(tab, content.document.querySelector("button"));
yield waitForDebuggerEvents(panel, gDebugger.EVENTS.FETCHED_SCOPES);
let gVars = gDebugger.DebuggerView.Variables;

Просмотреть файл

@ -9,12 +9,11 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gPrefs, gSources, gInstruments;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gPrefs = gDebugger.Prefs;

Просмотреть файл

@ -7,14 +7,13 @@
const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gFrames, gVariables, gPrefs, gOptions;
function test() {
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gFrames = gDebugger.DebuggerView.StackFrames;
@ -78,9 +77,7 @@ function testPauseOnExceptionsDisabled() {
return finished;
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return finished;
}
@ -151,9 +148,7 @@ function testPauseOnExceptionsEnabled() {
return finished;
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return finished;
}
@ -236,7 +231,6 @@ function disableIgnoreCaughtExceptions() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gFrames = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gFrames, gVariables, gPrefs, gOptions;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gFrames = gDebugger.DebuggerView.StackFrames;
@ -105,13 +104,7 @@ function testPauseOnExceptionsAfterReload() {
return finished;
});
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
});
sendMouseClickToTab(gTab, content.document.querySelector("button"));
return finished;
}
@ -194,7 +187,6 @@ function disableIgnoreCaughtExceptions() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gFrames = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gResumeButton, gResumeKey, gFrames;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gResumeButton = gDebugger.document.getElementById("resume");
@ -69,7 +68,6 @@ function testResume() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gResumeButton = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gTarget, gToolbox;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gTarget = gPanel.target;
@ -90,7 +89,6 @@ function testResume() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gTarget = null;

Просмотреть файл

@ -6,7 +6,7 @@
* WebProgress argument's DOMWindow property in onStateChange() (bug 771655).
*/
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gOldListener;
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
@ -14,9 +14,8 @@ const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
function test() {
installListener();
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -37,7 +36,7 @@ function testPause() {
resumeDebuggerThenCloseAndFinish(gPanel);
});
gDebuggee.runDebuggerStatement();
callInTab(gTab, "runDebuggerStatement");
}
// This is taken almost verbatim from bug 771655.
@ -80,7 +79,6 @@ registerCleanupFunction(function() {
}
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gOldListener = null;

Просмотреть файл

@ -9,13 +9,12 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
const PREFERRED_URL = EXAMPLE_URL + "code_script-switching-02.js";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
@ -39,7 +38,6 @@ function finishTest() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gSources = null;

Просмотреть файл

@ -10,13 +10,12 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
const FIRST_URL = EXAMPLE_URL + "code_script-switching-01.js";
const SECOND_URL = EXAMPLE_URL + "code_script-switching-02.js";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
@ -52,7 +51,6 @@ function switchToSource(aUrl) {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gSources = null;

Просмотреть файл

@ -13,12 +13,11 @@ function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources, gStep;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = aPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -32,7 +31,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebuggee.firstCall();
callInTab(gTab, "firstCall");
});
}
@ -187,7 +186,6 @@ function testSwitchRunning() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-02.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
@ -29,7 +28,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebuggee.firstCall();
callInTab(gTab, "firstCall");
});
}
@ -176,7 +175,6 @@ function testSwitchRunning() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gView, gEditor, gL10N;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gView = gDebugger.DebuggerView;
@ -43,7 +42,6 @@ function testDebuggerLoadingError() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gView = null;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources, gUtils;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gSources, gUtils;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
@ -129,7 +128,6 @@ function checkSourcesOrder(aMethod) {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gSources = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_step-out.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gVars;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVars = gDebugger.DebuggerView.Variables;
@ -41,9 +40,7 @@ function testNormalReturn() {
gDebugger);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.getElementById("return"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.getElementById("return"));
}
function testReturnWithException() {
@ -65,9 +62,7 @@ function testReturnWithException() {
gDebugger);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.getElementById("throw"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.getElementById("throw"));
}
function resumeDebuggee() {
@ -78,7 +73,6 @@ function resumeDebuggee() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVars = null;

Просмотреть файл

@ -7,12 +7,11 @@
const TAB_URL = EXAMPLE_URL + "doc_terminate-on-tab-close.html";
let gTab, gDebuggee, gDebugger, gPanel;
let gTab, gDebugger, gPanel;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -27,12 +26,11 @@ function testTerminate() {
});
});
gDebuggee.debuggerThenThrow();
callInTab(gTab, "debuggerThenThrow");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

Просмотреть файл

@ -251,7 +251,7 @@ Selection.prototype = {
isHTMLNode: function() {
let xhtml_ns = "http://www.w3.org/1999/xhtml";
return this.isNode() && this.node.namespaceURI == xhtml_ns;
return this.isNode() && this.nodeFront.namespaceURI == xhtml_ns;
},
// Node type
@ -300,6 +300,24 @@ Selection.prototype = {
return this.isNode() && this.nodeFront.nodeType == Ci.nsIDOMNode.DOCUMENT_NODE;
},
/**
* @returns true if the selection is the <body> HTML element.
*/
isBodyNode: function() {
return this.isHTMLNode() &&
this.isConnected() &&
this.nodeFront.nodeName === "BODY";
},
/**
* @returns true if the selection is the <head> HTML element.
*/
isHeadNode: function() {
return this.isHTMLNode() &&
this.isConnected() &&
this.nodeFront.nodeName === "HEAD";
},
isDocumentTypeNode: function() {
return this.isNode() && this.nodeFront.nodeType == Ci.nsIDOMNode.DOCUMENT_TYPE_NODE;
},

Просмотреть файл

@ -57,7 +57,6 @@ function InspectorPanel(iframeWindow, toolbox) {
this.panelDoc = iframeWindow.document;
this.panelWin = iframeWindow;
this.panelWin.inspector = this;
this._inspector = null;
this._onBeforeNavigate = this._onBeforeNavigate.bind(this);
this._target.on("will-navigate", this._onBeforeNavigate);
@ -109,6 +108,10 @@ InspectorPanel.prototype = {
return this._target.client.traits.getUniqueSelector;
},
get canPasteInnerOrAdjacentHTML() {
return this._target.client.traits.pasteHTML;
},
_deferredOpen: function(defaultSelection) {
let deferred = promise.defer();
@ -573,7 +576,7 @@ InspectorPanel.prototype = {
* Returns the clipboard content if it is appropriate for pasting
* into the current node's outer HTML, otherwise returns null.
*/
_getClipboardContentForOuterHTML: function Inspector_getClipboardContentForOuterHTML() {
_getClipboardContentForPaste: function Inspector_getClipboardContentForPaste() {
let flavors = clipboard.currentFlavors;
if (flavors.indexOf("text") != -1 ||
(flavors.indexOf("html") != -1 && flavors.indexOf("image") == -1)) {
@ -642,15 +645,34 @@ InspectorPanel.prototype = {
editHTML.setAttribute("disabled", "true");
}
// Enable the "paste outer HTML" item if the selection is an element and
// the root actor has the appropriate trait (isOuterHTMLEditable) and if
// the clipbard content is appropriate.
let pasteOuterHTML = this.panelDoc.getElementById("node-menu-pasteouterhtml");
if (isEditableElement && this.isOuterHTMLEditable &&
this._getClipboardContentForOuterHTML()) {
pasteOuterHTML.removeAttribute("disabled");
let pasteInnerHTML = this.panelDoc.getElementById("node-menu-pasteinnerhtml");
let pasteBefore = this.panelDoc.getElementById("node-menu-pastebefore");
let pasteAfter = this.panelDoc.getElementById("node-menu-pasteafter");
let pasteFirstChild = this.panelDoc.getElementById("node-menu-pastefirstchild");
let pasteLastChild = this.panelDoc.getElementById("node-menu-pastelastchild");
// Is the clipboard content appropriate? Is the element editable?
if (isEditableElement && this._getClipboardContentForPaste()) {
pasteInnerHTML.disabled = !this.canPasteInnerOrAdjacentHTML;
// Enable the "paste outer HTML" item if the selection is an element and
// the root actor has the appropriate trait (isOuterHTMLEditable).
pasteOuterHTML.disabled = !this.isOuterHTMLEditable;
// Don't paste before / after a root or a BODY or a HEAD element.
pasteBefore.disabled = pasteAfter.disabled =
!this.canPasteInnerOrAdjacentHTML || this.selection.isRoot() ||
this.selection.isBodyNode() || this.selection.isHeadNode();
// Don't paste as a first / last child of a HTML document element.
pasteFirstChild.disabled = pasteLastChild.disabled =
!this.canPasteInnerOrAdjacentHTML || (this.selection.isHTMLNode() &&
this.selection.isRoot());
} else {
pasteOuterHTML.setAttribute("disabled", "true");
pasteOuterHTML.disabled = true;
pasteInnerHTML.disabled = true;
pasteBefore.disabled = true;
pasteAfter.disabled = true;
pasteFirstChild.disabled = true;
pasteLastChild.disabled = true;
}
// Enable the "copy image data-uri" item if the selection is previewable
@ -690,7 +712,7 @@ InspectorPanel.prototype = {
this._markupBox.setAttribute("collapsed", true);
this._markupBox.appendChild(this._markupFrame);
this._markupFrame.setAttribute("src", "chrome://browser/content/devtools/markup-view.xhtml");
this._markupFrame.setAttribute("aria-label", this.strings.GetStringFromName("inspector.panelLabel.markupView"))
this._markupFrame.setAttribute("aria-label", this.strings.GetStringFromName("inspector.panelLabel.markupView"));
},
_onMarkupFrameLoad: function InspectorPanel__onMarkupFrameLoad() {
@ -773,8 +795,7 @@ InspectorPanel.prototype = {
/**
* Edit the outerHTML of the selected Node.
*/
editHTML: function InspectorPanel_editHTML()
{
editHTML: function InspectorPanel_editHTML() {
if (!this.selection.isNode()) {
return;
}
@ -786,22 +807,49 @@ InspectorPanel.prototype = {
/**
* Paste the contents of the clipboard into the selected Node's outer HTML.
*/
pasteOuterHTML: function InspectorPanel_pasteOuterHTML()
{
let content = this._getClipboardContentForOuterHTML();
if (content) {
let node = this.selection.nodeFront;
this.markup.getNodeOuterHTML(node).then((oldContent) => {
this.markup.updateNodeOuterHTML(node, content, oldContent);
});
}
pasteOuterHTML: function InspectorPanel_pasteOuterHTML() {
let content = this._getClipboardContentForPaste();
if (!content)
return promise.reject("No clipboard content for paste");
let node = this.selection.nodeFront;
return this.markup.getNodeOuterHTML(node).then(oldContent => {
this.markup.updateNodeOuterHTML(node, content, oldContent);
});
},
/**
* Paste the contents of the clipboard into the selected Node's inner HTML.
*/
pasteInnerHTML: function InspectorPanel_pasteInnerHTML() {
let content = this._getClipboardContentForPaste();
if (!content)
return promise.reject("No clipboard content for paste");
let node = this.selection.nodeFront;
return this.markup.getNodeInnerHTML(node).then(oldContent => {
this.markup.updateNodeInnerHTML(node, content, oldContent);
});
},
/**
* Paste the contents of the clipboard as adjacent HTML to the selected Node.
* @param position The position as specified for Element.insertAdjacentHTML
* (i.e. "beforeBegin", "afterBegin", "beforeEnd", "afterEnd").
*/
pasteAdjacentHTML: function InspectorPanel_pasteAdjacent(position) {
let content = this._getClipboardContentForPaste();
if (!content)
return promise.reject("No clipboard content for paste");
let node = this.selection.nodeFront;
return this.markup.insertAdjacentHTMLToNode(node, position, content);
},
/**
* Copy the innerHTML of the selected Node to the clipboard.
*/
copyInnerHTML: function InspectorPanel_copyInnerHTML()
{
copyInnerHTML: function InspectorPanel_copyInnerHTML() {
if (!this.selection.isNode()) {
return;
}

Просмотреть файл

@ -59,10 +59,36 @@
label="&inspectorShowDOMProperties.label;"
oncommand="inspector.showDOMProperties()"/>
<menuseparator/>
<menuitem id="node-menu-pasteinnerhtml"
label="&inspectorHTMLPasteInner.label;"
accesskey="&inspectorHTMLPasteInner.accesskey;"
oncommand="inspector.pasteInnerHTML()"/>
<menuitem id="node-menu-pasteouterhtml"
label="&inspectorHTMLPasteOuter.label;"
accesskey="&inspectorHTMLPasteOuter.accesskey;"
oncommand="inspector.pasteOuterHTML()"/>
<menu id="node-menu-paste-extra-submenu"
label="&inspectorHTMLPasteExtraSubmenu.label;"
accesskey="&inspectorHTMLPasteExtraSubmenu.accesskey;">
<menupopup>
<menuitem id="node-menu-pastebefore"
label="&inspectorHTMLPasteBefore.label;"
accesskey="&inspectorHTMLPasteBefore.accesskey;"
oncommand="inspector.pasteAdjacentHTML('beforeBegin')"/>
<menuitem id="node-menu-pasteafter"
label="&inspectorHTMLPasteAfter.label;"
accesskey="&inspectorHTMLPasteAfter.accesskey;"
oncommand="inspector.pasteAdjacentHTML('afterEnd')"/>
<menuitem id="node-menu-pastefirstchild"
label="&inspectorHTMLPasteFirstChild.label;"
accesskey="&inspectorHTMLPasteFirstChild.accesskey;"
oncommand="inspector.pasteAdjacentHTML('afterBegin')"/>
<menuitem id="node-menu-pastelastchild"
label="&inspectorHTMLPasteLastChild.label;"
accesskey="&inspectorHTMLPasteLastChild.accesskey;"
oncommand="inspector.pasteAdjacentHTML('beforeEnd')"/>
</menupopup>
</menu>
<menuseparator/>
<menuitem id="node-menu-delete"
label="&inspectorHTMLDelete.label;"

Просмотреть файл

@ -15,7 +15,8 @@ support-files =
doc_inspector_highlighter_rect_iframe.html
doc_inspector_infobar_01.html
doc_inspector_infobar_02.html
doc_inspector_menu.html
doc_inspector_menu-01.html
doc_inspector_menu-02.html
doc_inspector_remove-iframe-during-load.html
doc_inspector_search.html
doc_inspector_search-suggestions.html
@ -54,7 +55,8 @@ support-files =
[browser_inspector_inspect-object-element.js]
[browser_inspector_invalidate.js]
[browser_inspector_keyboard-shortcuts.js]
[browser_inspector_menu.js]
[browser_inspector_menu-01.js]
[browser_inspector_menu-02.js]
[browser_inspector_navigation.js]
[browser_inspector_picker-stop-on-destroy.js]
[browser_inspector_picker-stop-on-tool-change.js]

Просмотреть файл

@ -14,7 +14,7 @@ thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: jsterm.focusInput is
// 1) menu items are disabled/enabled depending on the clicked node
// 2) actions triggered by the items work correctly
const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html";
const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu-01.html";
const MENU_SENSITIVITY_TEST_DATA = [
{
desc: "doctype node",
@ -28,41 +28,6 @@ const MENU_SENSITIVITY_TEST_DATA = [
}
];
const PASTE_OUTER_HTML_TEST_DATA = [
{
desc: "some text",
clipboardData: "some text",
clipboardDataType: undefined,
disabled: false
},
{
desc: "base64 encoded image data uri",
clipboardData:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" +
"AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==",
clipboardDataType: undefined,
disabled: true
},
{
desc: "html",
clipboardData: "<p>some text</p>",
clipboardDataType: "html",
disabled: false
},
{
desc: "empty string",
clipboardData: "",
clipboardDataType: undefined,
disabled: true
},
{
desc: "whitespace only",
clipboardData: " \n\n\t\n\n \n",
clipboardDataType: undefined,
disabled: true
},
];
const COPY_ITEMS_TEST_DATA = [
{
desc: "copy inner html",
@ -90,30 +55,25 @@ add_task(function* () {
let { inspector, toolbox } = yield openInspectorForURL(TEST_URL);
yield testMenuItemSensitivity();
yield testPasteOuterHTMLMenuItemSensitivity();
yield testCopyMenuItems();
yield testShowDOMProperties();
yield testPasteOuterHTMLMenu();
yield testDeleteNode();
yield testDeleteRootNode();
function* testMenuItemSensitivity() {
info("Testing sensitivity of menu items for different elements.");
// The sensibility for paste options are described in browser_inspector_menu-02.js
const MENU_ITEMS = [
"node-menu-copyinner",
"node-menu-copyouter",
"node-menu-copyuniqueselector",
"node-menu-delete",
"node-menu-pasteouterhtml",
"node-menu-pseudo-hover",
"node-menu-pseudo-active",
"node-menu-pseudo-focus"
];
// To ensure clipboard contains something to paste.
clipboard.set("<p>test</p>", "html");
for (let {desc, selector, disabled} of MENU_SENSITIVITY_TEST_DATA) {
info("Testing context menu entries for " + desc);
@ -135,25 +95,6 @@ add_task(function* () {
}
}
function* testPasteOuterHTMLMenuItemSensitivity() {
info("Checking 'Paste Outer HTML' menu item sensitivity for different types" +
"of data");
let nodeFront = yield getNodeFront("p", inspector);
let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine;
for (let data of PASTE_OUTER_HTML_TEST_DATA) {
let { desc, clipboardData, clipboardDataType, disabled } = data;
info("Checking 'Paste Outer HTML' for " + desc);
clipboard.set(clipboardData, clipboardDataType);
yield selectNode(nodeFront, inspector);
contextMenuClick(markupTagLine);
checkMenuItem("node-menu-pasteouterhtml", disabled);
}
}
function* testCopyMenuItems() {
info("Testing various copy actions of context menu.");
for (let {desc, id, text} of COPY_ITEMS_TEST_DATA) {
@ -190,27 +131,6 @@ add_task(function* () {
yield toolbox.toggleSplitConsole();
}
function* testPasteOuterHTMLMenu() {
info("Testing that 'Paste Outer HTML' menu item works.");
clipboard.set("this was pasted");
let nodeFront = yield getNodeFront("h1", inspector);
yield selectNode(nodeFront, inspector);
contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine);
let onNodeReselected = inspector.markup.once("reselectedonremoved");
let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml");
dispatchCommandEvent(menu);
info("Waiting for inspector selection to update");
yield onNodeReselected;
ok(content.document.body.outerHTML.contains(clipboard.get()),
"Clipboard content was pasted into the node's outer HTML.");
ok(!getNode("h1", { expectNoMatch: true }), "The original node was removed.");
}
function* testDeleteNode() {
info("Testing 'Delete Node' menu item for normal elements.");

Просмотреть файл

@ -0,0 +1,326 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test context menu functionality:
// 1) menu items are disabled/enabled depending on the clicked node
// 2) actions triggered by the items work correctly
///////////////////
//
// Whitelisting this test.
// As part of bug 1077403, the leaking uncaught rejection should be fixed.
//
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: jsterm.focusInput is not a function");
const MENU_SENSITIVITY_TEST_DATA = [
{
desc: "doctype node",
selector: null,
disabled: true,
},
{
desc: "element node",
selector: "#sensitivity",
disabled: false,
},
{
desc: "document element",
selector: "html",
disabled: {
"node-menu-pastebefore": true,
"node-menu-pasteafter": true,
"node-menu-pastefirstchild": true,
"node-menu-pastelastchild": true,
}
},
{
desc: "body",
selector: "body",
disabled: {
"node-menu-pastebefore": true,
"node-menu-pasteafter": true,
}
},
{
desc: "head",
selector: "head",
disabled: {
"node-menu-pastebefore": true,
"node-menu-pasteafter": true,
}
}
];
const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu-02.html";
const PASTE_HTML_TEST_SENSITIVITY_DATA = [
{
desc: "some text",
clipboardData: "some text",
clipboardDataType: undefined,
disabled: false
},
{
desc: "base64 encoded image data uri",
clipboardData:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" +
"AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==",
clipboardDataType: undefined,
disabled: true
},
{
desc: "html",
clipboardData: "<p>some text</p>",
clipboardDataType: "html",
disabled: false
},
{
desc: "empty string",
clipboardData: "",
clipboardDataType: undefined,
disabled: true
},
{
desc: "whitespace only",
clipboardData: " \n\n\t\n\n \n",
clipboardDataType: undefined,
disabled: true
},
];
const PASTE_ADJACENT_HTML_DATA = [
{
desc: "As First Child",
clipboardData: "2",
menuId: "node-menu-pastefirstchild",
},
{
desc: "As Last Child",
clipboardData: "4",
menuId: "node-menu-pastelastchild",
},
{
desc: "Before",
clipboardData: "1",
menuId: "node-menu-pastebefore",
},
{
desc: "After",
clipboardData: "<span>5</span>",
menuId: "node-menu-pasteafter",
},
];
let clipboard = require("sdk/clipboard");
registerCleanupFunction(() => {
clipboard = null;
});
add_task(function* () {
let { inspector, toolbox } = yield openInspectorForURL(TEST_URL);
yield testMenuItemSensitivity();
yield testPasteHTMLMenuItemsSensitivity();
yield testPasteOuterHTMLMenu();
yield testPasteInnerHTMLMenu();
yield testPasteAdjacentHTMLMenu();
function* testMenuItemSensitivity() {
info("Testing sensitivity of menu items for different elements.");
const MENU_ITEMS = [
"node-menu-pasteinnerhtml",
"node-menu-pasteouterhtml",
"node-menu-pastebefore",
"node-menu-pasteafter",
"node-menu-pastefirstchild",
"node-menu-pastelastchild",
];
// To ensure clipboard contains something to paste.
clipboard.set("<p>test</p>", "html");
for (let {desc, selector, disabled} of MENU_SENSITIVITY_TEST_DATA) {
info("Testing context menu entries for " + desc);
let front;
if (selector) {
front = yield getNodeFront(selector, inspector);
} else {
// Select the docType if no selector is provided
let {nodes} = yield inspector.walker.children(inspector.walker.rootNode);
front = nodes[0];
}
yield selectNode(front, inspector);
contextMenuClick(getContainerForNodeFront(front, inspector).tagLine);
for (let name of MENU_ITEMS) {
let disabledForMenu = typeof disabled === "object" ?
disabled[name] : disabled;
info(`${name} should be ${disabledForMenu ? "disabled" : "enabled"} ` +
`for ${desc}`);
checkMenuItem(name, disabledForMenu);
}
}
}
function* testPasteHTMLMenuItemsSensitivity() {
let menus = [
"node-menu-pasteinnerhtml",
"node-menu-pasteouterhtml",
"node-menu-pastebefore",
"node-menu-pasteafter",
"node-menu-pastefirstchild",
"node-menu-pastelastchild",
];
info("Checking Paste menu items sensitivity for different types" +
"of data");
let nodeFront = yield getNodeFront("#paste-area", inspector);
let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine;
for (let menuId of menus) {
for (let data of PASTE_HTML_TEST_SENSITIVITY_DATA) {
let { desc, clipboardData, clipboardDataType, disabled } = data;
let menuLabel = getLabelFor("#" + menuId);
info(`Checking ${menuLabel} for ${desc}`);
clipboard.set(clipboardData, clipboardDataType);
yield selectNode(nodeFront, inspector);
contextMenuClick(markupTagLine);
checkMenuItem(menuId, disabled);
}
}
}
function* testPasteOuterHTMLMenu() {
info("Testing that 'Paste Outer HTML' menu item works.");
clipboard.set("this was pasted (outerHTML)");
let outerHTMLSelector = "#paste-area h1";
let nodeFront = yield getNodeFront(outerHTMLSelector, inspector);
yield selectNode(nodeFront, inspector);
contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine);
let onNodeReselected = inspector.markup.once("reselectedonremoved");
let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml");
dispatchCommandEvent(menu);
info("Waiting for inspector selection to update");
yield onNodeReselected;
ok(content.document.body.outerHTML.contains(clipboard.get()),
"Clipboard content was pasted into the node's outer HTML.");
ok(!getNode(outerHTMLSelector, { expectNoMatch: true }),
"The original node was removed.");
}
function* testPasteInnerHTMLMenu() {
info("Testing that 'Paste Inner HTML' menu item works.");
clipboard.set("this was pasted (innerHTML)");
let innerHTMLSelector = "#paste-area .inner";
let getInnerHTML = () => content.document.querySelector(innerHTMLSelector).innerHTML;
let origInnerHTML = getInnerHTML();
let nodeFront = yield getNodeFront(innerHTMLSelector, inspector);
yield selectNode(nodeFront, inspector);
contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine);
let onMutation = inspector.once("markupmutation");
let menu = inspector.panelDoc.getElementById("node-menu-pasteinnerhtml");
dispatchCommandEvent(menu);
info("Waiting for mutation to occur");
yield onMutation;
ok(getInnerHTML() === clipboard.get(),
"Clipboard content was pasted into the node's inner HTML.");
ok(getNode(innerHTMLSelector), "The original node has been preserved.");
yield undoChange(inspector);
ok(getInnerHTML() === origInnerHTML, "Previous innerHTML has been " +
"restored after undo");
}
function* testPasteAdjacentHTMLMenu() {
let refSelector = "#paste-area .adjacent .ref";
let adjacentNode = content.document.querySelector(refSelector).parentNode;
let nodeFront = yield getNodeFront(refSelector, inspector);
yield selectNode(nodeFront, inspector);
let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine;
for (let { desc, clipboardData, menuId } of PASTE_ADJACENT_HTML_DATA) {
let menu = inspector.panelDoc.getElementById(menuId);
info(`Testing ${getLabelFor(menu)} for ${clipboardData}`);
clipboard.set(clipboardData);
contextMenuClick(markupTagLine);
let onMutation = inspector.once("markupmutation");
dispatchCommandEvent(menu);
info("Waiting for mutation to occur");
yield onMutation;
}
ok(adjacentNode.innerHTML.trim() === "1<span class=\"ref\">234</span>" +
"<span>5</span>", "The Paste as Last Child / as First Child / Before " +
"/ After worked as expected");
yield undoChange(inspector);
ok(adjacentNode.innerHTML.trim() === "1<span class=\"ref\">234</span>",
"Undo works for paste adjacent HTML");
}
function checkMenuItem(elementId, disabled) {
if (disabled) {
checkDisabled(elementId);
} else {
checkEnabled(elementId);
}
}
function checkEnabled(elementId) {
let elt = inspector.panelDoc.getElementById(elementId);
ok(!elt.hasAttribute("disabled"),
'"' + elt.label + '" context menu option is not disabled');
}
function checkDisabled(elementId) {
let elt = inspector.panelDoc.getElementById(elementId);
ok(elt.hasAttribute("disabled"),
'"' + elt.label + '" context menu option is disabled');
}
function dispatchCommandEvent(node) {
info("Dispatching command event on " + node);
let commandEvent = document.createEvent("XULCommandEvent");
commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
false, false, null);
node.dispatchEvent(commandEvent);
}
function contextMenuClick(element) {
info("Simulating contextmenu event on " + element);
let evt = element.ownerDocument.createEvent('MouseEvents');
let button = 2; // right click
evt.initMouseEvent('contextmenu', true, true,
element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
false, false, false, button, null);
element.dispatchEvent(evt);
}
function getLabelFor(elt) {
if (typeof elt === "string")
elt = inspector.panelDoc.querySelector(elt);
let isInPasteSubMenu = elt.matches("#node-menu-paste-extra-submenu *");
return `"${isInPasteSubMenu ? "Paste > " : ""}${elt.label}"`;
}
});

Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<title>Inspector Tree Menu Test</title>
<meta charset="utf-8">
</head>
<body>
<div>
<div id="paste-area">
<h1>Inspector Tree Menu Test</h1>
<p class="inner">Unset</p>
<p class="adjacent">
<span class="ref">3</span>
</p>
</div>
<p data-id="copy">Paragraph for testing copy</p>
<p id="sensitivity">Paragraph for sensitivity</p>
<p id="delete">This has to be deleted</p>
</div>
</body>
</html>

Просмотреть файл

@ -664,3 +664,43 @@ function executeInContent(name, data={}, objects={}, expectResponse=true) {
return promise.resolve();
}
}
/**
* Undo the last markup-view action and wait for the corresponding mutation to
* occur
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return a promise that resolves when the markup-mutation has been treated or
* rejects if no undo action is possible
*/
function undoChange(inspector) {
let canUndo = inspector.markup.undo.canUndo();
ok(canUndo, "The last change in the markup-view can be undone");
if (!canUndo) {
return promise.reject();
}
let mutated = inspector.once("markupmutation");
inspector.markup.undo.undo();
return mutated;
}
/**
* Redo the last markup-view action and wait for the corresponding mutation to
* occur
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return a promise that resolves when the markup-mutation has been treated or
* rejects if no redo action is possible
*/
function redoChange(inspector) {
let canRedo = inspector.markup.undo.canRedo();
ok(canRedo, "The last change in the markup-view can be redone");
if (!canRedo) {
return promise.reject();
}
let mutated = inspector.once("markupmutation");
inspector.markup.undo.redo();
return mutated;
}

Просмотреть файл

@ -33,7 +33,7 @@ loader.lazyGetter(this, "DOMParser", function() {
return Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
});
loader.lazyGetter(this, "AutocompletePopup", () => {
return require("devtools/shared/autocomplete-popup").AutocompletePopup
return require("devtools/shared/autocomplete-popup").AutocompletePopup;
});
/**
@ -521,16 +521,17 @@ MarkupView.prototype = {
// Retain the node so we can undo this...
this.walker.retainNode(aNode).then(() => {
let parent = aNode.parentNode();
let sibling = null;
let nextSibling = null;
this.undo.do(() => {
if (container.selected) {
this.navigate(this.getContainer(parent));
}
this.walker.removeNode(aNode).then(nextSibling => {
sibling = nextSibling;
this.walker.removeNode(aNode).then(siblings => {
let focusNode = siblings.previousSibling || parent;
nextSibling = siblings.nextSibling;
if (container.selected) {
this.navigate(this.getContainer(focusNode));
}
});
}, () => {
this.walker.insertBefore(aNode, parent, sibling);
this.walker.insertBefore(aNode, parent, nextSibling);
});
}).then(null, console.error);
},
@ -701,16 +702,19 @@ MarkupView.prototype = {
removedContainers.add(container);
}
// If there has been additions, flash the nodes
// If there has been additions, flash the nodes if their associated
// container exist (so if their parent is expanded in the inspector).
added.forEach(added => {
let addedContainer = this.getContainer(added);
addedOrEditedContainers.add(addedContainer);
if (addedContainer) {
addedOrEditedContainers.add(addedContainer);
// The node may be added as a result of an append, in which case it
// it will have been removed from another container first, but in
// these cases we don't want to flash both the removal and the
// addition
removedContainers.delete(container);
// The node may be added as a result of an append, in which case
// it will have been removed from another container first, but in
// these cases we don't want to flash both the removal and the
// addition
removedContainers.delete(container);
}
});
}
}
@ -799,20 +803,46 @@ MarkupView.prototype = {
container.expanded = false;
},
/**
* Returns either the innerHTML or the outerHTML for a remote node.
* @param aNode The NodeFront to get the outerHTML / innerHTML for.
* @param isOuter A boolean that, if true, makes the function return the
* outerHTML, otherwise the innerHTML.
* @returns A promise that will be resolved with the outerHTML / innerHTML.
*/
_getNodeHTML: function(aNode, isOuter) {
let walkerPromise = null;
if (isOuter) {
walkerPromise = this.walker.outerHTML(aNode);
} else {
walkerPromise = this.walker.innerHTML(aNode);
}
return walkerPromise.then(longstr => {
return longstr.string().then(html => {
longstr.release().then(null, console.error);
return html;
});
});
},
/**
* Retrieve the outerHTML for a remote node.
* @param aNode The NodeFront to get the outerHTML for.
* @returns A promise that will be resolved with the outerHTML.
*/
getNodeOuterHTML: function(aNode) {
let def = promise.defer();
this.walker.outerHTML(aNode).then(longstr => {
longstr.string().then(outerHTML => {
longstr.release().then(null, console.error);
def.resolve(outerHTML);
});
});
return def.promise;
return this._getNodeHTML(aNode, true);
},
/**
* Retrieve the innerHTML for a remote node.
* @param aNode The NodeFront to get the innerHTML for.
* @returns A promise that will be resolved with the innerHTML.
*/
getNodeInnerHTML: function(aNode) {
return this._getNodeHTML(aNode);
},
/**
@ -885,31 +915,89 @@ MarkupView.prototype = {
/**
* Replace the outerHTML of any node displayed in the inspector with
* some other HTML code
* @param aNode node which outerHTML will be replaced.
* @param newValue The new outerHTML to set on the node.
* @param oldValue The old outerHTML that will be used if the user undos the update.
* @param {NodeFront} node node which outerHTML will be replaced.
* @param {string} newValue The new outerHTML to set on the node.
* @param {string} oldValue The old outerHTML that will be used if the
* user undoes the update.
* @returns A promise that will resolve when the outer HTML has been updated.
*/
updateNodeOuterHTML: function(aNode, newValue, oldValue) {
let container = this._containers.get(aNode);
updateNodeOuterHTML: function(node, newValue, oldValue) {
let container = this.getContainer(node);
if (!container) {
return promise.reject();
}
// Changing the outerHTML removes the node which outerHTML was changed.
// Listen to this removal to reselect the right node afterwards.
this.reselectOnRemoved(aNode, "outerhtml");
return this.walker.setOuterHTML(aNode, newValue).then(null, () => {
this.reselectOnRemoved(node, "outerhtml");
return this.walker.setOuterHTML(node, newValue).then(null, () => {
this.cancelReselectOnRemoved();
});
},
/**
* Replace the innerHTML of any node displayed in the inspector with
* some other HTML code
* @param {Node} node node which innerHTML will be replaced.
* @param {string} newValue The new innerHTML to set on the node.
* @param {string} oldValue The old innerHTML that will be used if the user
* undoes the update.
* @returns A promise that will resolve when the inner HTML has been updated.
*/
updateNodeInnerHTML: function(node, newValue, oldValue) {
let container = this.getContainer(node);
if (!container) {
return promise.reject();
}
let def = promise.defer();
container.undo.do(() => {
this.walker.setInnerHTML(node, newValue).then(def.resolve, def.reject);
}, () => {
this.walker.setInnerHTML(node, oldValue);
});
return def.promise;
},
/**
* Insert adjacent HTML to any node displayed in the inspector.
*
* @param {NodeFront} node The reference node.
* @param {string} position The position as specified for Element.insertAdjacentHTML
* (i.e. "beforeBegin", "afterBegin", "beforeEnd", "afterEnd").
* @param {string} newValue The adjacent HTML.
* @returns A promise that will resolve when the adjacent HTML has
* been inserted.
*/
insertAdjacentHTMLToNode: function(node, position, value) {
let container = this.getContainer(node);
if (!container) {
return promise.reject();
}
let def = promise.defer();
let injectedNodes = [];
container.undo.do(() => {
this.walker.insertAdjacentHTML(node, position, value).then(nodeArray => {
injectedNodes = nodeArray.nodes;
return nodeArray;
}).then(def.resolve, def.reject);
}, () => {
this.walker.removeNodes(injectedNodes);
});
return def.promise;
},
/**
* Open an editor in the UI to allow editing of a node's outerHTML.
* @param aNode The NodeFront to edit.
*/
beginEditingOuterHTML: function(aNode) {
this.getNodeOuterHTML(aNode).then((oldValue)=> {
this.getNodeOuterHTML(aNode).then(oldValue => {
let container = this.getContainer(aNode);
if (!container) {
return;
@ -1216,7 +1304,7 @@ MarkupView.prototype = {
this._inspector.selection.off("new-node-front", this._boundOnNewSelection);
this._boundOnNewSelection = null;
this.walker.off("mutations", this._boundMutationObserver)
this.walker.off("mutations", this._boundMutationObserver);
this._boundMutationObserver = null;
this.walker.off("display-change", this._boundOnDisplayChange);
@ -1923,7 +2011,7 @@ function TextEditor(aContainer, aNode, aTemplate) {
}, () => {
this.node.setNodeValue(oldValue).then(() => {
this.markup.nodeChanged(this.node);
})
});
});
});
});
@ -2154,7 +2242,7 @@ ElementEditor.prototype = {
doMods.apply();
}, () => {
undoMods.apply();
})
});
} catch(ex) {
console.error(ex);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше