Merge m-c to b2g-inbound.
@ -0,0 +1,6 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
addMessageListener("AboutHome:SearchTriggered", function (msg) {
|
||||
sendAsyncMessage("AboutHomeTest:CheckRecordedSearch", msg.data);
|
||||
});
|
@ -6,6 +6,7 @@ support-files =
|
||||
app_bug575561.html
|
||||
app_subframe_bug575561.html
|
||||
authenticate.sjs
|
||||
aboutHome_content_script.js
|
||||
browser_bug479408_sample.html
|
||||
browser_bug678392-1.html
|
||||
browser_bug678392-2.html
|
||||
|
@ -9,6 +9,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
|
||||
"resource:///modules/AboutHome.jsm");
|
||||
|
||||
const TEST_CONTENT_HELPER = "chrome://mochitests/content/browser/browser/base/content/test/general/aboutHome_content_script.js";
|
||||
let gRightsVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
@ -110,21 +111,19 @@ let gTests = [
|
||||
let searchEventDeferred = Promise.defer();
|
||||
let doc = gBrowser.contentDocument;
|
||||
let engineName = doc.documentElement.getAttribute("searchEngineName");
|
||||
let mm = gBrowser.selectedTab.linkedBrowser.messageManager;
|
||||
|
||||
doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
|
||||
let data = JSON.parse(e.detail);
|
||||
mm.loadFrameScript(TEST_CONTENT_HELPER, false);
|
||||
|
||||
mm.addMessageListener("AboutHomeTest:CheckRecordedSearch", function (msg) {
|
||||
let data = JSON.parse(msg.data);
|
||||
is(data.engineName, engineName, "Detail is search engine name");
|
||||
|
||||
// We use executeSoon() to ensure that this code runs after the
|
||||
// count has been updated in browser.js, since it uses the same
|
||||
// event.
|
||||
executeSoon(function () {
|
||||
getNumberOfSearches(engineName).then(num => {
|
||||
is(num, numSearchesBefore + 1, "One more search recorded.");
|
||||
searchEventDeferred.resolve();
|
||||
});
|
||||
});
|
||||
}, true, true);
|
||||
|
||||
// Get the current number of recorded searches.
|
||||
let searchStr = "a search";
|
||||
|
@ -2400,86 +2400,6 @@ let SessionStoreInternal = {
|
||||
this._sendRestoreCompletedNotifications();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the tabs restoring order with the following priority:
|
||||
* Selected tab, pinned tabs, optimized visible tabs, other visible tabs and
|
||||
* hidden tabs.
|
||||
* @param aTabBrowser
|
||||
* Tab browser object
|
||||
* @param aTabs
|
||||
* Array of tab references
|
||||
* @param aTabData
|
||||
* Array of tab data
|
||||
* @param aSelectedTab
|
||||
* Index of selected tab (1 is first tab, 0 no selected tab)
|
||||
*/
|
||||
_setTabsRestoringOrder : function ssi__setTabsRestoringOrder(
|
||||
aTabBrowser, aTabs, aTabData, aSelectedTab) {
|
||||
|
||||
// Store the selected tab. Need to substract one to get the index in aTabs.
|
||||
let selectedTab;
|
||||
if (aSelectedTab > 0 && aTabs[aSelectedTab - 1]) {
|
||||
selectedTab = aTabs[aSelectedTab - 1];
|
||||
}
|
||||
|
||||
// Store the pinned tabs and hidden tabs.
|
||||
let pinnedTabs = [];
|
||||
let pinnedTabsData = [];
|
||||
let hiddenTabs = [];
|
||||
let hiddenTabsData = [];
|
||||
if (aTabs.length > 1) {
|
||||
for (let t = aTabs.length - 1; t >= 0; t--) {
|
||||
if (aTabData[t].pinned) {
|
||||
pinnedTabs.unshift(aTabs.splice(t, 1)[0]);
|
||||
pinnedTabsData.unshift(aTabData.splice(t, 1)[0]);
|
||||
} else if (aTabData[t].hidden) {
|
||||
hiddenTabs.unshift(aTabs.splice(t, 1)[0]);
|
||||
hiddenTabsData.unshift(aTabData.splice(t, 1)[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize the visible tabs only if there is a selected tab.
|
||||
if (selectedTab) {
|
||||
let selectedTabIndex = aTabs.indexOf(selectedTab);
|
||||
if (selectedTabIndex > 0) {
|
||||
let scrollSize = aTabBrowser.tabContainer.mTabstrip.scrollClientSize;
|
||||
let tabWidth = aTabs[0].getBoundingClientRect().width;
|
||||
let maxVisibleTabs = Math.ceil(scrollSize / tabWidth);
|
||||
if (maxVisibleTabs < aTabs.length) {
|
||||
let firstVisibleTab = 0;
|
||||
let nonVisibleTabsCount = aTabs.length - maxVisibleTabs;
|
||||
if (nonVisibleTabsCount >= selectedTabIndex) {
|
||||
// Selected tab is leftmost since we scroll to it when possible.
|
||||
firstVisibleTab = selectedTabIndex;
|
||||
} else {
|
||||
// Selected tab is rightmost or no more room to scroll right.
|
||||
firstVisibleTab = nonVisibleTabsCount;
|
||||
}
|
||||
aTabs = aTabs.splice(firstVisibleTab, maxVisibleTabs).concat(aTabs);
|
||||
aTabData =
|
||||
aTabData.splice(firstVisibleTab, maxVisibleTabs).concat(aTabData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the stored tabs in order.
|
||||
aTabs = pinnedTabs.concat(aTabs, hiddenTabs);
|
||||
aTabData = pinnedTabsData.concat(aTabData, hiddenTabsData);
|
||||
|
||||
// Load the selected tab to the first position and select it.
|
||||
if (selectedTab) {
|
||||
let selectedTabIndex = aTabs.indexOf(selectedTab);
|
||||
if (selectedTabIndex > 0) {
|
||||
aTabs = aTabs.splice(selectedTabIndex, 1).concat(aTabs);
|
||||
aTabData = aTabData.splice(selectedTabIndex, 1).concat(aTabData);
|
||||
}
|
||||
aTabBrowser.selectedTab = selectedTab;
|
||||
}
|
||||
|
||||
return [aTabs, aTabData];
|
||||
},
|
||||
|
||||
/**
|
||||
* Manage history restoration for a window
|
||||
* @param aWindow
|
||||
@ -2489,7 +2409,9 @@ let SessionStoreInternal = {
|
||||
* @param aTabData
|
||||
* Array of tab data
|
||||
* @param aSelectTab
|
||||
* Index of selected tab
|
||||
* Index of the tab to select. This is a 1-based index where "1"
|
||||
* indicates the first tab should be selected, and "0" indicates that
|
||||
* the currently selected tab will not be changed.
|
||||
* @param aRestoreImmediately
|
||||
* Flag to indicate whether the given set of tabs aTabs should be
|
||||
* restored/loaded immediately even if restore_on_demand = true
|
||||
@ -2525,9 +2447,10 @@ let SessionStoreInternal = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets the tabs restoring order.
|
||||
[aTabs, aTabData] =
|
||||
this._setTabsRestoringOrder(tabbrowser, aTabs, aTabData, aSelectTab);
|
||||
// If provided, set the selected tab.
|
||||
if (aSelectTab > 0 && aSelectTab <= aTabs.length) {
|
||||
tabbrowser.selectedTab = aTabs[aSelectTab - 1];
|
||||
}
|
||||
|
||||
// Prepare the tabs so that they can be properly restored. We'll pin/unpin
|
||||
// and show/hide tabs as necessary. We'll also set the labels, user typed
|
||||
|
@ -111,7 +111,6 @@ skip-if = true
|
||||
[browser_466937.js]
|
||||
[browser_467409-backslashplosion.js]
|
||||
[browser_477657.js]
|
||||
[browser_480148.js]
|
||||
[browser_480893.js]
|
||||
[browser_485482.js]
|
||||
[browser_485563.js]
|
||||
|
@ -1,216 +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/. */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 484108 **/
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(5);
|
||||
|
||||
// builds the tests state based on a few parameters
|
||||
function buildTestState(num, selected, hidden, pinned) {
|
||||
let state = { windows: [ { "tabs": [], "selected": selected + 1 } ] };
|
||||
while (num--) {
|
||||
state.windows[0].tabs.push({
|
||||
entries: [
|
||||
{ url: "http://example.com/?t=" + state.windows[0].tabs.length }
|
||||
]
|
||||
});
|
||||
let i = state.windows[0].tabs.length - 1;
|
||||
if (hidden.length > 0 && i == hidden[0]) {
|
||||
state.windows[0].tabs[i].hidden = true;
|
||||
hidden.splice(0, 1);
|
||||
}
|
||||
if (pinned.length > 0 && i == pinned[0]) {
|
||||
state.windows[0].tabs[i].pinned = true;
|
||||
pinned.splice(0, 1);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
let tests = [
|
||||
{ testNum: 1,
|
||||
totalTabs: 13,
|
||||
selectedTab: 0,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [],
|
||||
order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
},
|
||||
{ testNum: 2,
|
||||
totalTabs: 13,
|
||||
selectedTab: 12,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [],
|
||||
order: [12, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6]
|
||||
},
|
||||
{ testNum: 3,
|
||||
totalTabs: 13,
|
||||
selectedTab: 3,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [],
|
||||
order: [3, 4, 5, 6, 7, 8, 0, 1, 2, 9, 10, 11, 12]
|
||||
},
|
||||
{ testNum: 4,
|
||||
totalTabs: 13,
|
||||
selectedTab: 10,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [],
|
||||
order: [10, 7, 8, 9, 11, 12, 0, 1, 2, 3, 4, 5, 6]
|
||||
},
|
||||
{ testNum: 5,
|
||||
totalTabs: 13,
|
||||
selectedTab: 12,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [0, 4, 9],
|
||||
pinnedTabs: [],
|
||||
order: [12, 6, 7, 8, 10, 11, 1, 2, 3, 5, 0, 4, 9]
|
||||
},
|
||||
{ testNum: 6,
|
||||
totalTabs: 13,
|
||||
selectedTab: 3,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [1, 7, 12],
|
||||
pinnedTabs: [],
|
||||
order: [3, 4, 5, 6, 8, 9, 0, 2, 10, 11, 1, 7, 12]
|
||||
},
|
||||
{ testNum: 7,
|
||||
totalTabs: 13,
|
||||
selectedTab: 3,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [0, 1, 2],
|
||||
pinnedTabs: [],
|
||||
order: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2]
|
||||
},
|
||||
{ testNum: 8,
|
||||
totalTabs: 13,
|
||||
selectedTab: 0,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [0],
|
||||
order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
},
|
||||
{ testNum: 9,
|
||||
totalTabs: 13,
|
||||
selectedTab: 1,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [0],
|
||||
order: [1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
},
|
||||
{ testNum: 10,
|
||||
totalTabs: 13,
|
||||
selectedTab: 3,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [2],
|
||||
pinnedTabs: [0,1],
|
||||
order: [3, 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 2]
|
||||
},
|
||||
{ testNum: 11,
|
||||
totalTabs: 13,
|
||||
selectedTab: 12,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [0,1,2],
|
||||
order: [12, 0, 1, 2, 7, 8, 9, 10, 11, 3, 4, 5, 6]
|
||||
},
|
||||
{ testNum: 12,
|
||||
totalTabs: 13,
|
||||
selectedTab: 6,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [3,4,5],
|
||||
pinnedTabs: [0,1,2],
|
||||
order: [6, 0, 1, 2, 7, 8, 9, 10, 11, 12, 3, 4, 5]
|
||||
},
|
||||
{ testNum: 13,
|
||||
totalTabs: 13,
|
||||
selectedTab: 1,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [3,4,5],
|
||||
pinnedTabs: [0,1,2],
|
||||
order: [1, 0, 2, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5]
|
||||
},
|
||||
{ testNum: 14,
|
||||
totalTabs: 13,
|
||||
selectedTab: 2,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [],
|
||||
pinnedTabs: [0,1,2],
|
||||
order: [2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
},
|
||||
{ testNum: 15,
|
||||
totalTabs: 13,
|
||||
selectedTab: 3,
|
||||
shownTabs: 6,
|
||||
hiddenTabs: [1,4],
|
||||
pinnedTabs: [0,1,2],
|
||||
order: [3, 0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 4]
|
||||
}
|
||||
];
|
||||
|
||||
let tabMinWidth =
|
||||
parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
|
||||
let testIndex = 0;
|
||||
|
||||
function runNextTest() {
|
||||
if (tests.length == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
let wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
wu.garbageCollect();
|
||||
|
||||
setTimeout(function() {
|
||||
info ("Starting test " + (++testIndex));
|
||||
let test = tests.shift();
|
||||
let state = buildTestState(test.totalTabs, test.selectedTab,
|
||||
test.hiddenTabs, test.pinnedTabs);
|
||||
let tabbarWidth = Math.floor((test.shownTabs - 0.5) * tabMinWidth);
|
||||
let win = openDialog(location, "_blank", "chrome,all,dialog=no");
|
||||
let tabsRestored = [];
|
||||
|
||||
win.addEventListener("SSTabRestoring", function onSSTabRestoring(aEvent) {
|
||||
let tab = aEvent.originalTarget;
|
||||
let tabLink = tab.linkedBrowser.currentURI.spec;
|
||||
let tabIndex =
|
||||
tabLink.substring(tabLink.indexOf("?t=") + 3, tabLink.length);
|
||||
|
||||
// we need to compare with the tab's restoring index, no with the
|
||||
// position index, since the pinned tabs change the positions in the
|
||||
// tabbar.
|
||||
tabsRestored.push(tabIndex);
|
||||
|
||||
if (tabsRestored.length < state.windows[0].tabs.length)
|
||||
return;
|
||||
|
||||
// all of the tabs should be restoring or restored by now
|
||||
is(tabsRestored.length, state.windows[0].tabs.length,
|
||||
"Test #" + testIndex + ": Number of restored tabs is as expected");
|
||||
|
||||
is(tabsRestored.join(" "), test.order.join(" "),
|
||||
"Test #" + testIndex + ": 'visible' tabs restored first");
|
||||
|
||||
// cleanup
|
||||
win.removeEventListener("SSTabRestoring", onSSTabRestoring, false);
|
||||
win.close();
|
||||
executeSoon(runNextTest);
|
||||
}, false);
|
||||
|
||||
whenWindowLoaded(win, function(aEvent) {
|
||||
let extent =
|
||||
win.outerWidth - win.gBrowser.tabContainer.mTabstrip.scrollClientSize;
|
||||
let windowWidth = tabbarWidth + extent;
|
||||
win.resizeTo(windowWidth, win.outerHeight);
|
||||
ss.setWindowState(win, JSON.stringify(state), true);
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
runNextTest();
|
||||
}
|
@ -47,16 +47,14 @@ function test() {
|
||||
}
|
||||
|
||||
function testRestoreWithHiddenTabs() {
|
||||
let checked = false;
|
||||
let ssReady = false;
|
||||
let tabsRestored = false;
|
||||
|
||||
let check = function () {
|
||||
if (checked || !ssReady || !tabsRestored)
|
||||
return;
|
||||
|
||||
checked = true;
|
||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (needsRestore <= 4) {
|
||||
TabsProgressListener.unsetCallback();
|
||||
is(needsRestore, 4, "4/8 tabs restored");
|
||||
}
|
||||
});
|
||||
|
||||
waitForBrowserState(state, 4, function () {
|
||||
is(gBrowser.tabs.length, 8, "there are now eight tabs");
|
||||
is(gBrowser.visibleTabs.length, 4, "four visible tabs");
|
||||
|
||||
@ -64,25 +62,7 @@ function testRestoreWithHiddenTabs() {
|
||||
is(cw.GroupItems.groupItems.length, 2, "there are now two groupItems");
|
||||
|
||||
testSwitchToInactiveGroup();
|
||||
}
|
||||
|
||||
whenSessionStoreReady(function () {
|
||||
ssReady = true;
|
||||
check();
|
||||
});
|
||||
|
||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (4 < needsRestore)
|
||||
return;
|
||||
|
||||
TabsProgressListener.unsetCallback();
|
||||
is(needsRestore, 4, "4/8 tabs restored");
|
||||
|
||||
tabsRestored = true;
|
||||
check();
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function testSwitchToInactiveGroup() {
|
||||
@ -108,11 +88,16 @@ function testSwitchToInactiveGroup() {
|
||||
gBrowser.selectedTab = gBrowser.tabs[4];
|
||||
}
|
||||
|
||||
function whenSessionStoreReady(callback) {
|
||||
window.addEventListener("SSWindowStateReady", function onReady() {
|
||||
window.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
function waitForBrowserState(state, numTabs, callback) {
|
||||
let tabContainer = gBrowser.tabContainer;
|
||||
tabContainer.addEventListener("SSTabRestored", function onRestored() {
|
||||
if (--numTabs <= 0) {
|
||||
tabContainer.removeEventListener("SSTabRestored", onRestored, true);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
}, true);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function countTabs() {
|
||||
|
@ -17,6 +17,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
|
||||
// Url to fetch snippets, in the urlFormatter service format.
|
||||
const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl";
|
||||
@ -181,6 +183,12 @@ let AboutHome = {
|
||||
Cu.reportError(ex);
|
||||
break;
|
||||
}
|
||||
|
||||
Services.search.init(function(status) {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let engine = Services.search.currentEngine;
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
window.BrowserSearch.recordSearchInHealthReport(engine, "abouthome");
|
||||
@ -188,6 +196,12 @@ let AboutHome = {
|
||||
// Trigger a search through nsISearchEngine.getSubmission()
|
||||
let submission = engine.getSubmission(data.searchTerms, null, "homepage");
|
||||
window.loadURI(submission.uri.spec, null, submission.postData);
|
||||
|
||||
// Used for testing
|
||||
let mm = aMessage.target.messageManager;
|
||||
mm.sendAsyncMessage("AboutHome:SearchTriggered", aMessage.data.searchData);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -199,13 +213,26 @@ let AboutHome = {
|
||||
Components.utils.import("resource:///modules/sessionstore/SessionStore.jsm",
|
||||
wrapper);
|
||||
let ss = wrapper.SessionStore;
|
||||
|
||||
ss.promiseInitialized.then(function() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
Services.search.init(function (status){
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
deferred.reject(status);
|
||||
} else {
|
||||
deferred.resolve(Services.search.defaultEngine.name);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}).then(function(engineName) {
|
||||
let data = {
|
||||
showRestoreLastSession: ss.canRestoreLastSession,
|
||||
snippetsURL: AboutHomeUtils.snippetsURL,
|
||||
showKnowYourRights: AboutHomeUtils.showKnowYourRights,
|
||||
snippetsVersion: AboutHomeUtils.snippetsVersion,
|
||||
defaultEngineName: Services.search.defaultEngine.name
|
||||
defaultEngineName: engineName
|
||||
};
|
||||
|
||||
if (AboutHomeUtils.showKnowYourRights) {
|
||||
|
Before Width: | Height: | Size: 301 B After Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 370 B After Width: | Height: | Size: 679 B |
Before Width: | Height: | Size: 322 B |
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="#a6aeb4"/>
|
||||
<size android:width="1dp" />
|
||||
|
||||
</shape>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="#222"/>
|
||||
<size android:width="1dp" />
|
||||
|
||||
</shape>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<!-- Note that android:color="@color/toolbar_separator" (which uses a selector)
|
||||
directly in the <shape> does not appear to work, so instead we select
|
||||
between two shapes with different colors. -->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item gecko:state_private="true" android:drawable="@drawable/toolbar_separator_pb"/>
|
||||
<item android:drawable="@drawable/toolbar_separator"/>
|
||||
|
||||
</selector>
|
@ -15,19 +15,18 @@
|
||||
<!-- Note: any layout parameters setting the right edge of
|
||||
this View should be matched in the url_bar_translating_edge.
|
||||
|
||||
Note 2: On devices where the editing mode cancel items are
|
||||
wider than the tabs and similar buttons (e.g. hardware menu
|
||||
button), the url bar will shrink, in which case the LayoutParams
|
||||
of this View are changed dynamically. -->
|
||||
Note 2: On devices where the editing mode cancel button is
|
||||
wider than the tabs counter and nearby buttons, the url bar will
|
||||
shrink, in which case the LayoutParams of this View are
|
||||
changed dynamically. -->
|
||||
<ImageView android:id="@+id/url_bar_entry"
|
||||
style="@style/UrlBar.Button"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="-19dp"
|
||||
android:layout_marginRight="-15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toLeftOf="@+id/tabs"
|
||||
android:paddingRight="4dp"
|
||||
android:duplicateParentState="true"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
@ -43,8 +42,7 @@
|
||||
android:layout_toLeftOf="@+id/tabs"
|
||||
android:layout_alignTop="@id/url_bar_entry"
|
||||
android:layout_alignBottom="@id/url_bar_entry"
|
||||
android:layout_marginRight="-19dp"
|
||||
android:paddingRight="4dp"
|
||||
android:layout_marginRight="-15dp"
|
||||
android:duplicateParentState="true"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
@ -103,27 +101,22 @@
|
||||
style="@style/UrlBar.ImageButton.Icon"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@drawable/close_edit_mode"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:contentDescription="@string/edit_mode_cancel"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<org.mozilla.gecko.widget.ThemedView android:id="@+id/edit_separator"
|
||||
android:layout_toLeftOf="@id/edit_cancel"
|
||||
android:layout_width="1dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:background="@drawable/toolbar_separator_selector"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<!-- The left margin of the cancel button is larger than the right because
|
||||
the url bar drawable contains some whitespace, so we compensate by adding
|
||||
a negative right margin (value determined through experimentation). -->
|
||||
<org.mozilla.gecko.toolbar.ToolbarEditLayout android:id="@+id/edit_layout"
|
||||
style="@style/UrlBar.Button"
|
||||
android:layout_toLeftOf="@id/edit_separator"
|
||||
android:layout_toLeftOf="@id/edit_cancel"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginRight="-2dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:visibility="gone"/>
|
||||
android:paddingRight="8dp"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<org.mozilla.gecko.toolbar.ToolbarDisplayLayout android:id="@+id/display_layout"
|
||||
style="@style/UrlBar.Button"
|
||||
|
@ -27,10 +27,4 @@
|
||||
android:gravity="center_vertical|left"
|
||||
gecko:autoUpdateTheme="false"/>
|
||||
|
||||
<ImageButton android:id="@+id/go"
|
||||
style="@style/UrlBar.ImageButton.Icon"
|
||||
android:src="@drawable/ic_url_bar_go"
|
||||
android:contentDescription="@string/go"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</merge>
|
||||
|
@ -20,6 +20,7 @@ import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jayway.android.robotium.solo.Condition;
|
||||
import com.jayway.android.robotium.solo.Solo;
|
||||
|
||||
/**
|
||||
* A class representing any interactions that take place on the Toolbar.
|
||||
@ -69,13 +70,6 @@ public class ToolbarComponent extends BaseComponent {
|
||||
return (TextView) getToolbarView().findViewById(R.id.url_bar_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the View for the go button in the browser toolbar.
|
||||
*/
|
||||
private ImageButton getGoButton() {
|
||||
return (ImageButton) getToolbarView().findViewById(R.id.go);
|
||||
}
|
||||
|
||||
private ImageButton getBackButton() {
|
||||
DeviceHelper.assertIsTablet();
|
||||
return (ImageButton) getToolbarView().findViewById(R.id.back);
|
||||
@ -141,7 +135,7 @@ public class ToolbarComponent extends BaseComponent {
|
||||
WaitHelper.waitForPageLoad(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSolo.clickOnView(getGoButton());
|
||||
mSolo.sendKey(Solo.ENTER);
|
||||
}
|
||||
});
|
||||
waitForNotEditing();
|
||||
|
@ -34,10 +34,11 @@ import org.mozilla.gecko.util.MenuUtils;
|
||||
import org.mozilla.gecko.widget.ThemedImageButton;
|
||||
import org.mozilla.gecko.widget.ThemedImageView;
|
||||
import org.mozilla.gecko.widget.ThemedRelativeLayout;
|
||||
import org.mozilla.gecko.widget.ThemedView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.os.Build;
|
||||
@ -137,8 +138,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
private MenuPopup menuPopup;
|
||||
private List<View> focusOrder;
|
||||
|
||||
private final ThemedView editSeparator;
|
||||
private final View editCancel;
|
||||
private final ImageView editCancel;
|
||||
|
||||
private boolean shouldShrinkURLBar = false;
|
||||
|
||||
@ -220,8 +220,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
actionItemBar = (LinearLayout) findViewById(R.id.menu_items);
|
||||
hasSoftMenuButton = !HardwareUtils.hasMenuButton();
|
||||
|
||||
editSeparator = (ThemedView) findViewById(R.id.edit_separator);
|
||||
editCancel = findViewById(R.id.edit_cancel);
|
||||
editCancel = (ImageView) findViewById(R.id.edit_cancel);
|
||||
|
||||
// We use different layouts on phones and tablets, so adjust the focus
|
||||
// order appropriately.
|
||||
@ -328,6 +327,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
urlEditLayout.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
// This will select the url bar when entering editing mode.
|
||||
setSelected(hasFocus);
|
||||
if (focusChangeListener != null) {
|
||||
focusChangeListener.onFocusChange(v, hasFocus);
|
||||
@ -600,15 +600,14 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
}
|
||||
|
||||
private int getUrlBarEntryTranslation() {
|
||||
if (editSeparator == null) {
|
||||
if (editCancel == null) {
|
||||
// We are on tablet, and there is no animation so return a translation of 0.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We would ideally use the right-most point of the edit layout instead of the
|
||||
// edit separator and its margin, but it is not inflated when this code initially runs.
|
||||
final LayoutParams lp = (LayoutParams) editSeparator.getLayoutParams();
|
||||
return editSeparator.getLeft() - lp.leftMargin - urlBarEntry.getRight();
|
||||
// Subtract the right margin because it's negative.
|
||||
final LayoutParams lp = (LayoutParams) urlEditLayout.getLayoutParams();
|
||||
return urlEditLayout.getRight() - lp.rightMargin - urlBarEntry.getRight();
|
||||
}
|
||||
|
||||
private int getUrlBarCurveTranslation() {
|
||||
@ -850,12 +849,14 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
}
|
||||
|
||||
private void setUrlEditLayoutVisibility(final boolean showEditLayout, PropertyAnimator animator) {
|
||||
urlEditLayout.prepareAnimation(showEditLayout, animator);
|
||||
if (showEditLayout) {
|
||||
urlEditLayout.prepareShowAnimation(animator);
|
||||
}
|
||||
|
||||
if (animator == null) {
|
||||
final View viewToShow = (showEditLayout ? urlEditLayout : urlDisplayLayout);
|
||||
final View viewToHide = (showEditLayout ? urlDisplayLayout : urlEditLayout);
|
||||
|
||||
if (animator == null) {
|
||||
viewToHide.setVisibility(View.GONE);
|
||||
viewToShow.setVisibility(View.VISIBLE);
|
||||
|
||||
@ -864,29 +865,23 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
return;
|
||||
}
|
||||
|
||||
ViewHelper.setAlpha(viewToShow, 0.0f);
|
||||
animator.attach(viewToShow,
|
||||
PropertyAnimator.Property.ALPHA,
|
||||
1.0f);
|
||||
|
||||
animator.attach(viewToHide,
|
||||
PropertyAnimator.Property.ALPHA,
|
||||
0.0f);
|
||||
|
||||
animator.addPropertyAnimationListener(new PropertyAnimationListener() {
|
||||
@Override
|
||||
public void onPropertyAnimationStart() {
|
||||
viewToShow.setVisibility(View.VISIBLE);
|
||||
if (!showEditLayout) {
|
||||
urlEditLayout.setVisibility(View.GONE);
|
||||
urlDisplayLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
setCancelVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertyAnimationEnd() {
|
||||
viewToHide.setVisibility(View.GONE);
|
||||
ViewHelper.setAlpha(viewToHide, 1.0f);
|
||||
if (showEditLayout) {
|
||||
urlDisplayLayout.setVisibility(View.GONE);
|
||||
urlEditLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
setCancelVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@ -894,8 +889,7 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
}
|
||||
|
||||
private void setCancelVisibility(final int visibility) {
|
||||
if (editSeparator != null && editCancel != null) {
|
||||
editSeparator.setVisibility(visibility);
|
||||
if (editCancel != null) {
|
||||
editCancel.setVisibility(visibility);
|
||||
}
|
||||
}
|
||||
@ -1021,9 +1015,6 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
if (isAnimatingEntry)
|
||||
return;
|
||||
|
||||
// Highlight the toolbar from the start of the animation.
|
||||
setSelected(true);
|
||||
|
||||
urlDisplayLayout.prepareStartEditingAnimation();
|
||||
|
||||
// Slide toolbar elements.
|
||||
@ -1106,6 +1097,10 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
|
||||
updateProgressVisibility();
|
||||
|
||||
// The animation looks cleaner if the text in the URL bar is
|
||||
// not selected so clear the selection by clearing focus.
|
||||
urlEditLayout.clearFocus();
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
stopEditingWithoutAnimation();
|
||||
} else if (HardwareUtils.isTablet()) {
|
||||
@ -1338,9 +1333,6 @@ public class BrowserToolbar extends ThemedRelativeLayout
|
||||
menuButton.setPrivateMode(isPrivate);
|
||||
menuIcon.setPrivateMode(isPrivate);
|
||||
urlEditLayout.setPrivateMode(isPrivate);
|
||||
if (editSeparator != null) {
|
||||
editSeparator.setPrivateMode(isPrivate);
|
||||
}
|
||||
|
||||
if (backButton instanceof BackButton) {
|
||||
((BackButton) backButton).setPrivateMode(isPrivate);
|
||||
|
@ -8,12 +8,9 @@ package org.mozilla.gecko.toolbar;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator.PropertyAnimationListener;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnCommitListener;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnDismissListener;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.OnFilterListener;
|
||||
import org.mozilla.gecko.toolbar.ToolbarEditText.OnTextTypeChangeListener;
|
||||
import org.mozilla.gecko.toolbar.ToolbarEditText.TextType;
|
||||
import org.mozilla.gecko.widget.ThemedLinearLayout;
|
||||
|
||||
import android.content.Context;
|
||||
@ -21,9 +18,7 @@ import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
/**
|
||||
* {@code ToolbarEditLayout} is the UI for when the toolbar is in
|
||||
@ -34,9 +29,7 @@ import android.widget.ImageButton;
|
||||
public class ToolbarEditLayout extends ThemedLinearLayout {
|
||||
|
||||
private final ToolbarEditText mEditText;
|
||||
private final ImageButton mGo;
|
||||
|
||||
private OnCommitListener mCommitListener;
|
||||
private OnFocusChangeListener mFocusChangeListener;
|
||||
|
||||
public ToolbarEditLayout(Context context, AttributeSet attrs) {
|
||||
@ -45,28 +38,11 @@ public class ToolbarEditLayout extends ThemedLinearLayout {
|
||||
setOrientation(HORIZONTAL);
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.toolbar_edit_layout, this);
|
||||
mGo = (ImageButton) findViewById(R.id.go);
|
||||
mEditText = (ToolbarEditText) findViewById(R.id.url_edit_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
mGo.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mCommitListener != null) {
|
||||
mCommitListener.onCommit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mEditText.setOnTextTypeChangeListener(new OnTextTypeChangeListener() {
|
||||
@Override
|
||||
public void onTextTypeChange(ToolbarEditText editText, TextType textType) {
|
||||
updateGoButton(textType);
|
||||
}
|
||||
});
|
||||
|
||||
mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
@ -85,8 +61,6 @@ public class ToolbarEditLayout extends ThemedLinearLayout {
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
|
||||
mGo.setEnabled(enabled);
|
||||
mEditText.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@ -96,44 +70,13 @@ public class ToolbarEditLayout extends ThemedLinearLayout {
|
||||
mEditText.setPrivateMode(isPrivate);
|
||||
}
|
||||
|
||||
private void updateGoButton(TextType textType) {
|
||||
if (textType == TextType.EMPTY) {
|
||||
mGo.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
mGo.setVisibility(View.VISIBLE);
|
||||
|
||||
final int imageResource;
|
||||
final String contentDescription;
|
||||
|
||||
if (textType == TextType.SEARCH_QUERY) {
|
||||
imageResource = R.drawable.ic_url_bar_search;
|
||||
contentDescription = getContext().getString(R.string.search);
|
||||
} else {
|
||||
imageResource = R.drawable.ic_url_bar_go;
|
||||
contentDescription = getContext().getString(R.string.go);
|
||||
}
|
||||
|
||||
mGo.setImageResource(imageResource);
|
||||
mGo.setContentDescription(contentDescription);
|
||||
}
|
||||
|
||||
private void showSoftInput() {
|
||||
InputMethodManager imm =
|
||||
(InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
|
||||
void prepareAnimation(final boolean showing, final PropertyAnimator animator) {
|
||||
if (showing) {
|
||||
prepareShowAnimation(animator);
|
||||
} else {
|
||||
prepareHideAnimation(animator);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareShowAnimation(final PropertyAnimator animator) {
|
||||
void prepareShowAnimation(final PropertyAnimator animator) {
|
||||
if (animator == null) {
|
||||
mEditText.requestFocus();
|
||||
showSoftInput();
|
||||
@ -143,39 +86,17 @@ public class ToolbarEditLayout extends ThemedLinearLayout {
|
||||
animator.addPropertyAnimationListener(new PropertyAnimationListener() {
|
||||
@Override
|
||||
public void onPropertyAnimationStart() {
|
||||
ViewHelper.setAlpha(mGo, 0.0f);
|
||||
mEditText.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertyAnimationEnd() {
|
||||
ViewHelper.setAlpha(mGo, 1.0f);
|
||||
showSoftInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareHideAnimation(final PropertyAnimator animator) {
|
||||
if (animator == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
animator.addPropertyAnimationListener(new PropertyAnimationListener() {
|
||||
@Override
|
||||
public void onPropertyAnimationStart() {
|
||||
ViewHelper.setAlpha(mGo, 0.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertyAnimationEnd() {
|
||||
// The enclosing view is invisible, so unhide the go button.
|
||||
ViewHelper.setAlpha(mGo, 1.0f);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setOnCommitListener(OnCommitListener listener) {
|
||||
mCommitListener = listener;
|
||||
mEditText.setOnCommitListener(listener);
|
||||
}
|
||||
|
||||
|
@ -711,7 +711,7 @@ Sync11Service.prototype = {
|
||||
|
||||
// Go ahead and do remote setup, so that we can determine
|
||||
// conclusively that our passphrase is correct.
|
||||
if (this._remoteSetup()) {
|
||||
if (this._remoteSetup(test)) {
|
||||
// Username/password verified.
|
||||
this.status.login = LOGIN_SUCCEEDED;
|
||||
return true;
|
||||
|
@ -21,6 +21,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
|
||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
||||
"resource://gre/modules/Deprecated.jsm");
|
||||
|
||||
// A text encoder to UTF8, used whenever we commit the
|
||||
// engine metadata to disk.
|
||||
@ -2877,8 +2879,7 @@ SearchService.prototype = {
|
||||
"Search service falling back to synchronous initialization. " +
|
||||
"This is generally the consequence of an add-on using a deprecated " +
|
||||
"search service API.";
|
||||
// Bug 785487 - Disable warning until our own callers are fixed.
|
||||
//Deprecated.warning(warning, "https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIBrowserSearchService#async_warning");
|
||||
Deprecated.warning(warning, "https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIBrowserSearchService#async_warning");
|
||||
LOG(warning);
|
||||
|
||||
engineMetadataService.syncInit();
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Ci } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|