Merge m-c to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-10-09 14:25:57 +02:00
commit 8ef8035706
68 changed files with 569 additions and 126 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1212764 - Clobber needed for bug 957911 Bug 1212347 - Disable geckoview_example by default and forget build artifacts.

View File

@ -123,12 +123,12 @@ onDisable.define(Theme, (theme, {window, newTheme}) => {
const LightTheme = Theme({ const LightTheme = Theme({
name: "theme-light", name: "theme-light",
styles: "chrome://browser/skin/devtools/light-theme.css", styles: "chrome://devtools/skin/themes/light-theme.css",
}); });
const DarkTheme = Theme({ const DarkTheme = Theme({
name: "theme-dark", name: "theme-dark",
styles: "chrome://browser/skin/devtools/dark-theme.css", styles: "chrome://devtools/skin/themes/dark-theme.css",
}); });
exports.LightTheme = LightTheme; exports.LightTheme = LightTheme;

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/> <project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf"> <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -1,9 +1,9 @@
{ {
"git": { "git": {
"git_revision": "e698df503ff700eb5782e3d50c6eb753567d3451", "git_revision": "1609aecaba381c14eff95d5084e59280f53b7d8b",
"remote": "https://git.mozilla.org/releases/gaia.git", "remote": "https://git.mozilla.org/releases/gaia.git",
"branch": "" "branch": ""
}, },
"revision": "bd073200a776c714b8160a38c77f980b19fd97c2", "revision": "0ee9cf8106722d20ae20c83e7b91a08273c1d0fa",
"repo_path": "integration/gaia-central" "repo_path": "integration/gaia-central"
} }

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/> <project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf"> <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1609aecaba381c14eff95d5084e59280f53b7d8b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/> <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -48,11 +48,17 @@ html[dir="rtl"] .conversation-toolbar > li {
.conversation-toolbar .btn { .conversation-toolbar .btn {
background-position: center; background-position: center;
background-size: 24px; background-size: 28px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: transparent; background-color: transparent;
height: 24px; height: 28px;
width: 24px; width: 33px;
}
.btn-hangup-entry > .btn {
/* Make the button the width of the background, so that we don't get an
extra gap which appears to push the toolbar in further than necessary */
width: 28px;
} }
.conversation-toolbar-media-btn-group-box { .conversation-toolbar-media-btn-group-box {

View File

@ -26,7 +26,7 @@ npm_install:
.PHONY: dist .PHONY: dist
dist: dist:
mkdir -p dist mkdir -p dist
cp -pR content dist cp -pR content/* dist
NODE_ENV="production" $(NODE_LOCAL_BIN)/webpack \ NODE_ENV="production" $(NODE_LOCAL_BIN)/webpack \
-p -v --display-errors -p -v --display-errors
sed 's#webappEntryPoint.js#js/standalone.js#' \ sed 's#webappEntryPoint.js#js/standalone.js#' \

View File

@ -52,11 +52,18 @@ function chromeTimeToDate(aTime)
* GUID of the folder where items will be inserted * GUID of the folder where items will be inserted
* @param items * @param items
* bookmark items to be inserted * bookmark items to be inserted
* @param errorAccumulator
* function that gets called with any errors thrown so we don't drop them on the floor.
*/ */
function* insertBookmarkItems(parentGuid, items) { function* insertBookmarkItems(parentGuid, items, errorAccumulator) {
for (let item of items) { for (let item of items) {
try { try {
if (item.type == "url") { if (item.type == "url") {
if (item.url.trim().startsWith("chrome:")) {
// Skip invalid chrome URIs. Creating an actual URI always reports
// messages to the console, so we avoid doing that.
continue;
}
yield PlacesUtils.bookmarks.insert({ yield PlacesUtils.bookmarks.insert({
parentGuid, url: item.url, title: item.name parentGuid, url: item.url, title: item.name
}); });
@ -65,10 +72,11 @@ function* insertBookmarkItems(parentGuid, items) {
parentGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title: item.name parentGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title: item.name
})).guid; })).guid;
yield insertBookmarkItems(newFolderGuid, item.children); yield insertBookmarkItems(newFolderGuid, item.children, errorAccumulator);
} }
} catch (e) { } catch (e) {
Cu.reportError(e); Cu.reportError(e);
errorAccumulator(e);
} }
} }
} }
@ -202,6 +210,8 @@ function GetBookmarksResource(aProfileFolder) {
migrate: function(aCallback) { migrate: function(aCallback) {
return Task.spawn(function* () { return Task.spawn(function* () {
let gotErrors = false;
let errorGatherer = () => gotErrors = true;
let jsonStream = yield new Promise(resolve => let jsonStream = yield new Promise(resolve =>
NetUtil.asyncFetch({ uri: NetUtil.newURI(bookmarksFile), NetUtil.asyncFetch({ uri: NetUtil.newURI(bookmarksFile),
loadUsingSystemPrincipal: true loadUsingSystemPrincipal: true
@ -230,7 +240,7 @@ function GetBookmarksResource(aProfileFolder) {
parentGuid = parentGuid =
yield MigrationUtils.createImportedBookmarksFolder("Chrome", parentGuid); yield MigrationUtils.createImportedBookmarksFolder("Chrome", parentGuid);
} }
yield insertBookmarkItems(parentGuid, roots.bookmark_bar.children); yield insertBookmarkItems(parentGuid, roots.bookmark_bar.children, errorGatherer);
} }
// Importing bookmark menu items // Importing bookmark menu items
@ -242,10 +252,13 @@ function GetBookmarksResource(aProfileFolder) {
parentGuid = parentGuid =
yield MigrationUtils.createImportedBookmarksFolder("Chrome", parentGuid); yield MigrationUtils.createImportedBookmarksFolder("Chrome", parentGuid);
} }
yield insertBookmarkItems(parentGuid, roots.other.children); yield insertBookmarkItems(parentGuid, roots.other.children, errorGatherer);
}
if (gotErrors) {
throw "The migration included errors.";
} }
}.bind(this)).then(() => aCallback(true), }.bind(this)).then(() => aCallback(true),
e => { Cu.reportError(e); aCallback(false) }); e => aCallback(false));
} }
}; };
} }

View File

@ -657,19 +657,35 @@ Cookies.prototype = {
* - Creation time least significant integer * - Creation time least significant integer
* - Record delimiter "*" * - Record delimiter "*"
* *
* Unfortunately, "*" can also occur inside the value of the cookie, so we
* can't rely exclusively on it as a record separator.
*
* @note All the times are in FILETIME format. * @note All the times are in FILETIME format.
*/ */
_parseCookieBuffer(aTextBuffer) { _parseCookieBuffer(aTextBuffer) {
// Note the last record is an empty string. // Note the last record is an empty string...
let records = [r for each (r in aTextBuffer.split("*\n")) if (r)]; let records = [];
let lines = aTextBuffer.split("\n");
while (lines.length > 0) {
let record = lines.splice(0, 9);
// ... which means this is going to be a 1-element array for that record
if (record.length > 1) {
records.push(record);
}
}
for (let record of records) { for (let record of records) {
let [name, value, hostpath, flags, let [name, value, hostpath, flags,
expireTimeLo, expireTimeHi] = record.split("\n"); expireTimeLo, expireTimeHi] = record;
// IE stores deleted cookies with a zero-length value, skip them. // IE stores deleted cookies with a zero-length value, skip them.
if (value.length == 0) if (value.length == 0)
continue; continue;
// IE sometimes has cookies created by apps that use "~~local~~/local/file/path"
// as the hostpath, ignore those:
if (hostpath.startsWith("~~local~~"))
continue;
let hostLen = hostpath.indexOf("/"); let hostLen = hostpath.indexOf("/");
let host = hostpath.substr(0, hostLen); let host = hostpath.substr(0, hostLen);
let path = hostpath.substr(hostLen); let path = hostpath.substr(hostLen);

View File

@ -274,7 +274,7 @@ PlacesController.prototype = {
this.newItem("bookmark"); this.newItem("bookmark");
break; break;
case "placesCmd_new:separator": case "placesCmd_new:separator":
this.newSeparator().catch(Cu.reportError); this.newSeparator().catch(Components.utils.reportError);
break; break;
case "placesCmd_show:info": case "placesCmd_show:info":
this.showBookmarkPropertiesForSelection(); this.showBookmarkPropertiesForSelection();
@ -1309,8 +1309,8 @@ PlacesController.prototype = {
// source, otherwise report an error and fallback to a copy. // source, otherwise report an error and fallback to a copy.
if (!doCopy && if (!doCopy &&
!PlacesControllerDragHelper.canMoveUnwrappedNode(item)) { !PlacesControllerDragHelper.canMoveUnwrappedNode(item)) {
Cu.reportError("Tried to move an unmovable Places node, " + Components.utils.reportError("Tried to move an unmovable " +
"reverting to a copy operation."); "Places node, reverting to a copy operation.");
doCopy = true; doCopy = true;
} }
let guid = yield PlacesUIUtils.getTransactionForData( let guid = yield PlacesUIUtils.getTransactionForData(
@ -1346,8 +1346,8 @@ PlacesController.prototype = {
// If this is not a copy, check for safety that we can move the source, // If this is not a copy, check for safety that we can move the source,
// otherwise report an error and fallback to a copy. // otherwise report an error and fallback to a copy.
if (action != "copy" && !PlacesControllerDragHelper.canMoveUnwrappedNode(items[i])) { if (action != "copy" && !PlacesControllerDragHelper.canMoveUnwrappedNode(items[i])) {
Components.utils.reportError("Tried to move an unmovable Places node, " + Components.utils.reportError("Tried to move an unmovable Places " +
"reverting to a copy operation."); "node, reverting to a copy operation.");
action = "copy"; action = "copy";
} }
transactions.push( transactions.push(
@ -1625,8 +1625,8 @@ var PlacesControllerDragHelper = {
// If this is not a copy, check for safety that we can move the source, // If this is not a copy, check for safety that we can move the source,
// otherwise report an error and fallback to a copy. // otherwise report an error and fallback to a copy.
if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(unwrapped)) { if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(unwrapped)) {
Components.utils.reportError("Tried to move an unmovable Places node, " + Components.utils.reportError("Tried to move an unmovable Places " +
"reverting to a copy operation."); "node, reverting to a copy operation.");
doCopy = true; doCopy = true;
} }
if (PlacesUIUtils.useAsyncTransactions) { if (PlacesUIUtils.useAsyncTransactions) {

View File

@ -2490,7 +2490,7 @@ var SessionStoreInternal = {
global: this._globalState.getState() global: this._globalState.getState()
}; };
if (Cu.isModuleLoaded("resource:///modules/devtools/scratchpad-manager.jsm")) { if (Cu.isModuleLoaded("resource:///modules/devtools/client/scratchpad/scratchpad-manager.jsm")) {
// get open Scratchpad window states too // get open Scratchpad window states too
let scratchpads = ScratchpadManager.getSessionState(); let scratchpads = ScratchpadManager.getSessionState();
if (scratchpads && scratchpads.length) { if (scratchpads && scratchpads.length) {

View File

@ -12,7 +12,7 @@
#ifdef MOZ_ANDROID_MAX_SDK_VERSION #ifdef MOZ_ANDROID_MAX_SDK_VERSION
android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@" android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@"
#endif #endif
android:targetSdkVersion="@ANDROID_TARGET_SDK@"/> android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

View File

@ -39,6 +39,7 @@ support-files =
[browser_inspector_delete-selected-node-03.js] [browser_inspector_delete-selected-node-03.js]
[browser_inspector_destroy-after-navigation.js] [browser_inspector_destroy-after-navigation.js]
[browser_inspector_destroy-before-ready.js] [browser_inspector_destroy-before-ready.js]
[browser_inspector_expand-collapse.js]
[browser_inspector_gcli-inspect-command.js] [browser_inspector_gcli-inspect-command.js]
skip-if = e10s # GCLI isn't e10s compatible. See bug 1128988. skip-if = e10s # GCLI isn't e10s compatible. See bug 1128988.
[browser_inspector_highlighter-01.js] [browser_inspector_highlighter-01.js]

View File

@ -0,0 +1,54 @@
/* 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";
// Tests that context menu items exapnd all and collapse are shown properly.
const TEST_URL = "data:text/html;charset=utf-8,<div id='parent-node'><div id='child-node'></div></div>";
add_task(function* () {
// Test is often exceeding time-out threshold, similar to Bug 1137765
requestLongerTimeout(2);
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
let nodeMenuCollapseElement = inspector.panelDoc.getElementById("node-menu-collapse");
let nodeMenuExpandElement = inspector.panelDoc.getElementById("node-menu-expand");
info("Selecting the parent node");
let front = yield getNodeFrontForSelector("#parent-node", inspector);
yield selectNode(front, inspector);
info("Simulating context menu click on the selected node container.");
contextMenuClick(getContainerForNodeFront(front, inspector).tagLine);
ok(nodeMenuCollapseElement.hasAttribute("disabled"), "Collapse option is disabled");
ok(!nodeMenuExpandElement.hasAttribute("disabled"), "ExpandAll option is enabled");
info("Testing whether expansion works properly");
dispatchCommandEvent(nodeMenuExpandElement);
info("Waiting for expansion to occur");
yield waitForMultipleChildrenUpdates(inspector);
let markUpContainer = getContainerForNodeFront(front, inspector);
ok(markUpContainer.expanded, "node has been successfully expanded");
//reslecting node after expansion
yield selectNode(front, inspector);
info("Testing whether collapse works properly");
info("Simulating context menu click on the selected node container.");
contextMenuClick(getContainerForNodeFront(front, inspector).tagLine);
ok(!nodeMenuCollapseElement.hasAttribute("disabled"), "Collapse option is enabled");
dispatchCommandEvent(nodeMenuCollapseElement);
info("Waiting for collapse to occur");
yield waitForMultipleChildrenUpdates(inspector);
ok(!markUpContainer.expanded, "node has been successfully collapsed");
});

View File

@ -481,6 +481,35 @@ function dispatchCommandEvent(node) {
node.dispatchEvent(commandEvent); node.dispatchEvent(commandEvent);
} }
/**
* A helper that simulates a contextmenu event on the given chrome DOM element.
*/
function contextMenuClick(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);
}
/**
* A helper that fetches a front for a node that matches the given selector or
* doctype node if the selector is falsy.
*/
function* getNodeFrontForSelector(selector, inspector) {
if (selector) {
info("Retrieving front for selector " + selector);
return getNodeFront(selector, inspector);
} else {
info("Retrieving front for doctype node");
let {nodes} = yield inspector.walker.children(inspector.walker.rootNode);
return nodes[0];
}
}
/** /**
* Encapsulate some common operations for highlighter's tests, to have * Encapsulate some common operations for highlighter's tests, to have
* the tests cleaner, without exposing directly `inspector`, `highlighter`, and * the tests cleaner, without exposing directly `inspector`, `highlighter`, and
@ -534,3 +563,33 @@ const getHighlighterHelperFor = (type) => Task.async(
}; };
} }
); );
// The expand all operation of the markup-view calls itself recursively and
// there's not one event we can wait for to know when it's done
// so use this helper function to wait until all recursive children updates are done.
function* waitForMultipleChildrenUpdates(inspector) {
// As long as child updates are queued up while we wait for an update already
// wait again
if (inspector.markup._queuedChildUpdates &&
inspector.markup._queuedChildUpdates.size) {
yield waitForChildrenUpdated(inspector);
return yield waitForMultipleChildrenUpdates(inspector);
}
}
/**
* Using the markupview's _waitForChildren function, wait for all queued
* children updates to be handled.
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return a promise that resolves when all queued children updates have been
* handled
*/
function waitForChildrenUpdated({markup}) {
info("Waiting for queued children updates to be handled");
let def = promise.defer();
markup._waitForChildren().then(() => {
executeSoon(def.resolve);
});
return def.promise;
}

View File

@ -13,9 +13,9 @@
<head> <head>
<link rel="stylesheet" href="chrome://browser/skin/" type="text/css"/> <link rel="stylesheet" href="chrome://browser/skin/" type="text/css"/>
<link rel="stylesheet" href="chrome://browser/content/devtools/widgets.css" type="text/css"/> <link rel="stylesheet" href="chrome://browser/content/devtools/widgets.css" type="text/css"/>
<link rel="stylesheet" href="chrome://browser/skin/devtools/common.css" type="text/css"/> <link rel="stylesheet" href="chrome://devtools/skin/themes/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://browser/skin/devtools/widgets.css" type="text/css"/> <link rel="stylesheet" href="chrome://devtools/skin/themes/widgets.css" type="text/css"/>
<link rel="stylesheet" href="chrome://browser/skin/devtools/memory.css" type="text/css"/> <link rel="stylesheet" href="chrome://devtools/skin/themes/memory.css" type="text/css"/>
<script type="application/javascript;version=1.8" <script type="application/javascript;version=1.8"
src="chrome://devtools/content/shared/theme-switching.js"/> src="chrome://devtools/content/shared/theme-switching.js"/>

View File

@ -8,10 +8,10 @@ Bug 1067491 - Test taking a census over the RDP.
<title>Census Tree 01</title> <title>Census Tree 01</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link href="chrome://browser/content/devtools/widgets.css" type="text/css" /> <link href="chrome://browser/content/devtools/widgets.css" type="text/css" />
<link href="chrome://browser/skin/devtools/light-theme.css" type="text/css" /> <link href="chrome://devtools/skin/themes/light-theme.css" type="text/css" />
<link href="chrome://browser/skin/devtools/common.css" type="text/css" /> <link href="chrome://devtools/skin/themes/common.css" type="text/css" />
<link href="chrome://browser/skin/devtools/widgets.css" type="text/css" /> <link href="chrome://devtools/skin/themes/widgets.css" type="text/css" />
<link href="chrome://browser/skin/devtools/memory.css" type="text/css" /> <link href="chrome://devtools/skin/themes/memory.css" type="text/css" />
</head> </head>
<body> <body>
<ul id="container" style="width:100%;height:300px;"></ul> <ul id="container" style="width:100%;height:300px;"></ul>

View File

@ -1145,8 +1145,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
// Then set spectrum's color and listen to color changes to preview them // Then set spectrum's color and listen to color changes to preview them
if (this.activeSwatch) { if (this.activeSwatch) {
this.currentSwatchColor = this.activeSwatch.nextSibling; this.currentSwatchColor = this.activeSwatch.nextSibling;
this._colorUnit = this._originalColor = this.currentSwatchColor.textContent;
colorUtils.classifyColor(this.currentSwatchColor.textContent);
let color = this.activeSwatch.style.backgroundColor; let color = this.activeSwatch.style.backgroundColor;
this.spectrum.then(spectrum => { this.spectrum.then(spectrum => {
spectrum.off("changed", this._onSpectrumColorChange); spectrum.off("changed", this._onSpectrumColorChange);
@ -1224,7 +1223,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
_toDefaultType: function(color) { _toDefaultType: function(color) {
let colorObj = new colorUtils.CssColor(color); let colorObj = new colorUtils.CssColor(color);
colorObj.colorUnit = this._colorUnit; colorObj.setAuthoredUnitFromColor(this._originalColor);
return colorObj.toString(); return colorObj.toString();
}, },

View File

@ -72,6 +72,7 @@ support-files =
[browser_ruleview_colorpicker-release-outside-frame.js] [browser_ruleview_colorpicker-release-outside-frame.js]
[browser_ruleview_colorpicker-revert-on-ESC.js] [browser_ruleview_colorpicker-revert-on-ESC.js]
[browser_ruleview_colorpicker-swatch-displayed.js] [browser_ruleview_colorpicker-swatch-displayed.js]
[browser_ruleview_colorUnit.js]
[browser_ruleview_completion-existing-property_01.js] [browser_ruleview_completion-existing-property_01.js]
[browser_ruleview_completion-existing-property_02.js] [browser_ruleview_completion-existing-property_02.js]
[browser_ruleview_completion-new-property_01.js] [browser_ruleview_completion-new-property_01.js]

View File

@ -0,0 +1,59 @@
/* vim: set ft=javascript 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 that color selection respects the user pref.
const TEST_URI = `
<style type='text/css'>
#testid {
color: blue;
}
</style>
<div id='testid' class='testclass'>Styled Node</div>
`;
add_task(function*() {
let TESTS = [
{name: "hex", result: "#0F0"},
{name: "rgb", result: "rgb(0, 255, 0)"}
];
for (let {name, result} of TESTS) {
info("starting test for " + name);
Services.prefs.setCharPref("devtools.defaultColorUnit", name);
yield addTab("data:text/html;charset=utf-8," +
encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield basicTest(view, name, result);
}
});
function* basicTest(view, name, result) {
let cPicker = view.tooltips.colorPicker;
let swatch = getRuleViewProperty(view, "#testid", "color").valueSpan
.querySelector(".ruleview-colorswatch");
let onShown = cPicker.tooltip.once("shown");
swatch.click();
yield onShown;
let testNode = yield getNode("#testid");
yield simulateColorPickerChange(view, cPicker, [0, 255, 0, 1], {
element: testNode,
name: "color",
value: "rgb(0, 255, 0)"
});
let spectrum = yield cPicker.spectrum;
let onHidden = cPicker.tooltip.once("hidden");
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
yield onHidden;
is(getRuleViewPropertyValue(view, "#testid", "color"), result,
"changing the color used the " + name + " unit");
}

View File

@ -92,6 +92,20 @@ CssColor.prototype = {
this._colorUnit = unit; this._colorUnit = unit;
}, },
/**
* If the current color unit pref is "authored", then set the
* default color unit from the given color. Otherwise, leave the
* color unit untouched.
*
* @param {String} color The color to use
*/
setAuthoredUnitFromColor: function(color) {
if (Services.prefs.getCharPref(COLOR_UNIT_PREF) ===
CssColor.COLORUNIT.authored) {
this._colorUnit = classifyColor(color);
}
},
get hasAlpha() { get hasAlpha() {
if (!this.valid) { if (!this.valid) {
return false; return false;

View File

@ -25,5 +25,10 @@ function run_test() {
for (let test of CLASSIFY_TESTS) { for (let test of CLASSIFY_TESTS) {
let result = colorUtils.classifyColor(test.input); let result = colorUtils.classifyColor(test.input);
equal(result, test.output, "test classifyColor(" + test.input + ")"); equal(result, test.output, "test classifyColor(" + test.input + ")");
let obj = new colorUtils.CssColor("purple");
obj.setAuthoredUnitFromColor(test.input);
equal(obj.colorUnit, test.output,
"test setAuthoredUnitFromColor(" + test.input + ")");
} }
} }

View File

@ -8,7 +8,10 @@ import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.ActivityResultHandlerMap; import org.mozilla.gecko.util.ActivityResultHandlerMap;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.util.Log;
public class ActivityHandlerHelper { public class ActivityHandlerHelper {
private static final String LOGTAG = "GeckoActivityHandlerHelper"; private static final String LOGTAG = "GeckoActivityHandlerHelper";
@ -22,6 +25,26 @@ public class ActivityHandlerHelper {
startIntentForActivity(GeckoAppShell.getGeckoInterface().getActivity(), intent, activityResultHandler); startIntentForActivity(GeckoAppShell.getGeckoInterface().getActivity(), intent, activityResultHandler);
} }
/**
* Starts the Activity, catching & logging if the Activity fails to start.
*
* We catch to prevent callers from passing in invalid Intents and crashing the browser.
*
* @return true if the Activity is successfully started, false otherwise.
*/
public static boolean startIntentAndCatch(final String logtag, final Context context, final Intent intent) {
try {
context.startActivity(intent);
return true;
} catch (final ActivityNotFoundException e) {
Log.w(logtag, "Activity not found.", e);
return false;
} catch (final SecurityException e) {
Log.w(logtag, "Forbidden to launch activity.", e);
return false;
}
}
public static void startIntentForActivity(Activity activity, Intent intent, ActivityResultHandler activityResultHandler) { public static void startIntentForActivity(Activity activity, Intent intent, ActivityResultHandler activityResultHandler) {
activity.startActivityForResult(intent, mActivityResultHandlerMap.put(activityResultHandler)); activity.startActivityForResult(intent, mActivityResultHandlerMap.put(activityResultHandler));
} }

View File

@ -13,7 +13,7 @@
#ifdef MOZ_ANDROID_MAX_SDK_VERSION #ifdef MOZ_ANDROID_MAX_SDK_VERSION
android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@" android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@"
#endif #endif
android:targetSdkVersion="@ANDROID_TARGET_SDK@"/> android:targetSdkVersion="22"/>
#include ../services/manifests/FxAccountAndroidManifest_permissions.xml.in #include ../services/manifests/FxAccountAndroidManifest_permissions.xml.in
#include ../services/manifests/HealthReportAndroidManifest_permissions.xml.in #include ../services/manifests/HealthReportAndroidManifest_permissions.xml.in

View File

@ -1542,7 +1542,7 @@ public class BrowserApp extends GeckoApp
} }
GeckoAppShell.openUriExternal(url, "text/plain", "", "", GeckoAppShell.openUriExternal(url, "text/plain", "", "",
Intent.ACTION_SEND, tab.getDisplayTitle()); Intent.ACTION_SEND, tab.getDisplayTitle(), false);
// Context: Sharing via chrome list (no explicit session is active) // Context: Sharing via chrome list (no explicit session is active)
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST); Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);
@ -1783,7 +1783,7 @@ public class BrowserApp extends GeckoApp
} else if ("Reader:Share".equals(event)) { } else if ("Reader:Share".equals(event)) {
final String title = message.getString("title"); final String title = message.getString("title");
final String url = message.getString("url"); final String url = message.getString("url");
GeckoAppShell.openUriExternal(url, "text/plain", "", "", Intent.ACTION_SEND, title); GeckoAppShell.openUriExternal(url, "text/plain", "", "", Intent.ACTION_SEND, title, false);
} else if ("Sanitize:ClearHistory".equals(event)) { } else if ("Sanitize:ClearHistory".equals(event)) {
handleClearHistory(message.optBoolean("clearSearchHistory", false)); handleClearHistory(message.optBoolean("clearSearchHistory", false));
callback.sendSuccess(true); callback.sendSuccess(true);

View File

@ -639,7 +639,7 @@ public abstract class GeckoApp
final String url = ReaderModeUtils.stripAboutReaderUrl(tab.getURL()); final String url = ReaderModeUtils.stripAboutReaderUrl(tab.getURL());
text += "\n\n" + url; text += "\n\n" + url;
} }
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title); GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title, false);
// Context: Sharing via chrome list (no explicit session is active) // Context: Sharing via chrome list (no explicit session is active)
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST); Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);

View File

@ -55,13 +55,13 @@ import org.mozilla.gecko.util.NativeJSContainer;
import org.mozilla.gecko.util.NativeJSObject; import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ProxySelector; import org.mozilla.gecko.util.ProxySelector;
import org.mozilla.gecko.util.ThreadUtils; import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -106,6 +106,7 @@ import android.os.SystemClock;
import android.os.Vibrator; import android.os.Vibrator;
import android.provider.Browser; import android.provider.Browser;
import android.provider.Settings; import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
@ -1011,6 +1012,17 @@ public class GeckoAppShell
return true; return true;
} }
@WrapForJNI
public static boolean openUriExternal(String targetURI,
String mimeType,
String packageName,
String className,
String action,
String title) {
// Default to showing prompt in private browsing to be safe.
return openUriExternal(targetURI, mimeType, packageName, className, action, title, true);
}
/** /**
* Given the inputs to <code>getOpenURIIntent</code>, plus an optional * Given the inputs to <code>getOpenURIIntent</code>, plus an optional
* package name and class name, create and fire an intent to open the * package name and class name, create and fire an intent to open the
@ -1024,15 +1036,20 @@ public class GeckoAppShell
* @param action an Android action specifier, such as * @param action an Android action specifier, such as
* <code>Intent.ACTION_SEND</code>. * <code>Intent.ACTION_SEND</code>.
* @param title the title to use in <code>ACTION_SEND</code> intents. * @param title the title to use in <code>ACTION_SEND</code> intents.
* @return true if the activity started successfully; false otherwise. * @param showPromptInPrivateBrowsing whether or not the user should be prompted when opening
* this uri from private browsing. This should be true
* when the user doesn't explicitly choose to open an an
* external app (e.g. just clicked a link).
* @return true if the activity started successfully or the user was prompted to open the
* application; false otherwise.
*/ */
@WrapForJNI
public static boolean openUriExternal(String targetURI, public static boolean openUriExternal(String targetURI,
String mimeType, String mimeType,
String packageName, String packageName,
String className, String className,
String action, String action,
String title) { String title,
final boolean showPromptInPrivateBrowsing) {
final Context context = getContext(); final Context context = getContext();
final Intent intent = getOpenURIIntent(context, targetURI, final Intent intent = getOpenURIIntent(context, targetURI,
mimeType, action, title); mimeType, action, title);
@ -1051,15 +1068,16 @@ public class GeckoAppShell
} }
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
context.startActivity(intent); if (!showPromptInPrivateBrowsing) {
return true; return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
} catch (ActivityNotFoundException e) { } else {
Log.w(LOGTAG, "Activity not found.", e); // Ideally we retrieve the Activity from the calling args, rather than
return false; // statically, but since this method is called from Gecko and I'm
} catch (SecurityException e) { // unfamiliar with that code, this is a simpler solution.
Log.w(LOGTAG, "Forbidden to launch activity.", e); final FragmentActivity fragmentActivity = (FragmentActivity) getGeckoInterface().getActivity();
return false; return ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser(
context, fragmentActivity.getSupportFragmentManager(), intent);
} }
} }

View File

@ -12,14 +12,15 @@ import org.mozilla.gecko.util.JSONUtils;
import org.mozilla.gecko.util.NativeEventListener; import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject; import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.WebActivityMapper; import org.mozilla.gecko.util.WebActivityMapper;
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -53,15 +54,15 @@ public final class IntentHelper implements GeckoEventListener,
private static IntentHelper instance; private static IntentHelper instance;
private final Activity activity; private final FragmentActivity activity;
private IntentHelper(Activity activity) { private IntentHelper(final FragmentActivity activity) {
this.activity = activity; this.activity = activity;
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this, EVENTS); EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this, EVENTS);
EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this, NATIVE_EVENTS); EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this, NATIVE_EVENTS);
} }
public static IntentHelper init(Activity activity) { public static IntentHelper init(final FragmentActivity activity) {
if (instance == null) { if (instance == null) {
instance = new IntentHelper(activity); instance = new IntentHelper(activity);
} else { } else {
@ -122,7 +123,7 @@ public final class IntentHelper implements GeckoEventListener,
message.optString("packageName"), message.optString("packageName"),
message.optString("className"), message.optString("className"),
message.optString("action"), message.optString("action"),
message.optString("title")); message.optString("title"), false);
} }
private void openForResult(final JSONObject message) throws JSONException { private void openForResult(final JSONObject message) throws JSONException {
@ -201,7 +202,8 @@ public final class IntentHelper implements GeckoEventListener,
// (Bug 1192436) We don't know if marketIntent matches any Activities (e.g. non-Play // (Bug 1192436) We don't know if marketIntent matches any Activities (e.g. non-Play
// Store devices). If it doesn't, clicking the link will cause no action to occur. // Store devices). If it doesn't, clicking the link will cause no action to occur.
activity.startActivity(marketIntent); ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser(
activity, activity.getSupportFragmentManager(), marketIntent);
callback.sendSuccess(null); callback.sendSuccess(null);
} else { } else {

View File

@ -271,7 +271,7 @@ public class ZoomedView extends FrameLayout implements LayerView.DynamicToolbarL
toolbarHeight = getResources().getDimensionPixelSize(R.dimen.zoomed_view_toolbar_height); toolbarHeight = getResources().getDimensionPixelSize(R.dimen.zoomed_view_toolbar_height);
containterSize = getResources().getDimensionPixelSize(R.dimen.drawable_dropshadow_size); containterSize = getResources().getDimensionPixelSize(R.dimen.drawable_dropshadow_size);
cornerRadius = getResources().getDimensionPixelSize(R.dimen.button_corner_radius); cornerRadius = getResources().getDimensionPixelSize(R.dimen.standard_corner_radius);
moveToolbar(true); moveToolbar(true);
} }

View File

@ -147,6 +147,7 @@ public class HistoryPanel extends HomeFragment {
selected = rangeItem; selected = rangeItem;
mRangeAdapter.notifyDataSetChanged(); mRangeAdapter.notifyDataSetChanged();
getLoaderManager().getLoader(LOADER_ID_HISTORY).forceLoad(); getLoaderManager().getLoader(LOADER_ID_HISTORY).forceLoad();
mList.smoothScrollToPosition(0);
} }
} }
}); });

View File

@ -197,7 +197,7 @@ public abstract class HomeFragment extends Fragment {
return false; return false;
} else { } else {
GeckoAppShell.openUriExternal(info.url, SHARE_MIME_TYPE, "", "", GeckoAppShell.openUriExternal(info.url, SHARE_MIME_TYPE, "", "",
Intent.ACTION_SEND, info.getDisplayTitle()); Intent.ACTION_SEND, info.getDisplayTitle(), false);
// Context: Sharing via chrome homepage contextmenu list (home session should be active) // Context: Sharing via chrome homepage contextmenu list (home session should be active)
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST); Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);

View File

@ -705,6 +705,19 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY find_matchcase "Aa"> <!ENTITY find_matchcase "Aa">
<!ENTITY intent_uri_cannot_open "Cannot open link"> <!ENTITY intent_uri_cannot_open "Cannot open link">
<!-- LOCALIZATION NOTE (intent_uri_private_browsing_prompt): This string will
appear in an alert when a user, who is currently in private browsing,
clicks a link that will open an external Android application. "&formatS;"
will be replaced with the name of the application that will be opened. -->
<!ENTITY intent_uri_private_browsing_prompt "This link will open in &formatS;. Are you sure you want to exit Private Browsing?">
<!-- LOCALIZATION NOTE (intent_uri_private_browsing_multiple_match_title): This
string will appear as the title of an alert when a user, who is currently
in private browsing, clicks a link that will open an external Android
application and more than one application is available to open that link.
We don't have control over the style of this dialog and it looks
unpolished when this string is longer than one line so ideally keep it
short! -->
<!ENTITY intent_uri_private_browsing_multiple_match_title "Exit Private Browsing?">
<!-- DevTools Authentication --> <!-- DevTools Authentication -->
<!-- LOCALIZATION NOTE (devtools_auth_scan_header): This header text appears <!-- LOCALIZATION NOTE (devtools_auth_scan_header): This header text appears

View File

@ -549,6 +549,7 @@ gbjar.sources += [
'widget/DoorHanger.java', 'widget/DoorHanger.java',
'widget/DoorhangerConfig.java', 'widget/DoorhangerConfig.java',
'widget/EllipsisTextView.java', 'widget/EllipsisTextView.java',
'widget/ExternalIntentDuringPrivateBrowsingPromptFragment.java',
'widget/FadedMultiColorTextView.java', 'widget/FadedMultiColorTextView.java',
'widget/FadedSingleColorTextView.java', 'widget/FadedSingleColorTextView.java',
'widget/FadedTextView.java', 'widget/FadedTextView.java',

View File

@ -16,7 +16,7 @@
android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal"> android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/text_and_tabs_tray_grey"/> <solid android:color="@color/text_and_tabs_tray_grey"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>
@ -32,7 +32,7 @@
android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal"> android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/placeholder_active_grey"/> <solid android:color="@color/placeholder_active_grey"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>
@ -47,7 +47,7 @@
android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal"> android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/toolbar_grey_pressed"/> <solid android:color="@color/toolbar_grey_pressed"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>
@ -62,7 +62,7 @@
android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal"> android:insetRight="@dimen/tablet_browser_toolbar_menu_item_inset_horizontal">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/tablet_highlight_focused"/> <solid android:color="@color/tablet_highlight_focused"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>

View File

@ -15,7 +15,7 @@
android:insetRight="@dimen/tablet_tab_strip_button_inset"> android:insetRight="@dimen/tablet_tab_strip_button_inset">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/highlight_dark"/> <solid android:color="@color/highlight_dark"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>
@ -30,7 +30,7 @@
android:insetRight="@dimen/tablet_tab_strip_button_inset"> android:insetRight="@dimen/tablet_tab_strip_button_inset">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/tablet_highlight_focused"/> <solid android:color="@color/tablet_highlight_focused"/>
<corners android:radius="@dimen/tablet_browser_toolbar_menu_item_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</inset> </inset>

View File

@ -7,5 +7,5 @@
android:shape="rectangle" > android:shape="rectangle" >
<solid android:color="@color/link_blue_pressed" /> <solid android:color="@color/link_blue_pressed" />
<corners <corners
android:radius="@dimen/button_corner_radius" /> android:radius="@dimen/standard_corner_radius" />
</shape> </shape>

View File

@ -7,5 +7,5 @@
android:shape="rectangle" > android:shape="rectangle" >
<solid android:color="@color/action_orange" /> <solid android:color="@color/action_orange" />
<corners <corners
android:radius="@dimen/button_corner_radius" /> android:radius="@dimen/standard_corner_radius" />
</shape> </shape>

View File

@ -7,5 +7,5 @@
android:shape="rectangle" > android:shape="rectangle" >
<solid android:color="@color/link_blue" /> <solid android:color="@color/link_blue" />
<corners <corners
android:radius="@dimen/button_corner_radius" /> android:radius="@dimen/standard_corner_radius" />
</shape> </shape>

View File

@ -7,5 +7,5 @@
android:shape="rectangle" > android:shape="rectangle" >
<solid android:color="@color/action_orange_pressed" /> <solid android:color="@color/action_orange_pressed" />
<corners <corners
android:radius="@dimen/button_corner_radius" /> android:radius="@dimen/standard_corner_radius" />
</shape> </shape>

View File

@ -13,16 +13,16 @@
<item android:state_pressed="true"> <item android:state_pressed="true">
<shape> <shape>
<solid android:color="@color/toolbar_grey_pressed"/> <solid android:color="@color/toolbar_grey_pressed"/>
<corners android:topLeftRadius="@dimen/button_corner_radius" <corners android:topLeftRadius="@dimen/standard_corner_radius"
android:topRightRadius="@dimen/button_corner_radius"/> android:topRightRadius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<solid android:color="@color/toolbar_grey"/> <solid android:color="@color/toolbar_grey"/>
<corners android:topLeftRadius="@dimen/button_corner_radius" <corners android:topLeftRadius="@dimen/standard_corner_radius"
android:topRightRadius="@dimen/button_corner_radius"/> android:topRightRadius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>

View File

@ -7,14 +7,14 @@
<item android:state_pressed="true"> <item android:state_pressed="true">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/remote_tabs_setup_button_background_hit"/> <solid android:color="@color/remote_tabs_setup_button_background_hit"/>
<corners android:radius="@dimen/button_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
<item> <item>
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/action_orange"/> <solid android:color="@color/action_orange"/>
<corners android:radius="@dimen/button_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
</selector> </selector>

View File

@ -6,14 +6,14 @@
<item android:state_pressed="true"> <item android:state_pressed="true">
<shape> <shape>
<solid android:color="@color/toolbar_grey_pressed"/> <solid android:color="@color/toolbar_grey_pressed"/>
<corners android:radius="4dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
<item> <item>
<shape> <shape>
<solid android:color="@color/toolbar_grey"/> <solid android:color="@color/toolbar_grey"/>
<corners android:radius="4dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
</selector> </selector>

View File

@ -11,7 +11,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<!-- @color/fennec_ui_orange with alpha --> <!-- @color/fennec_ui_orange with alpha -->
<solid android:color="#B3FF9500"/> <solid android:color="#B3FF9500"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -22,7 +22,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<!-- @color/private_browsing_purple with alpha --> <!-- @color/private_browsing_purple with alpha -->
<solid android:color="#B3CF68FF"/> <solid android:color="#B3CF68FF"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -33,7 +33,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<!-- @color/private_browsing_purple with alpha --> <!-- @color/private_browsing_purple with alpha -->
<solid android:color="#B3CF68FF"/> <solid android:color="#B3CF68FF"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -43,7 +43,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<!-- @color/fennec_ui_orange with alpha --> <!-- @color/fennec_ui_orange with alpha -->
<solid android:color="#B3FF9500"/> <solid android:color="#B3FF9500"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -52,7 +52,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#FFFF0000"/> <solid android:color="#FFFF0000"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -65,7 +65,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/private_browsing_purple"/> <solid android:color="@color/private_browsing_purple"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>
@ -77,7 +77,7 @@
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="@color/fennec_ui_orange"/> <solid android:color="@color/fennec_ui_orange"/>
<corners android:radius="3dp"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>
</item> </item>

View File

@ -5,6 +5,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/toolbar_grey"/> <solid android:color="@color/toolbar_grey"/>
<corners android:radius="@dimen/button_corner_radius"/> <corners android:radius="@dimen/standard_corner_radius"/>
</shape> </shape>

View File

@ -9,7 +9,7 @@
Base application theme. This could be overridden by GeckoBaseTheme Base application theme. This could be overridden by GeckoBaseTheme
in other res/values-XXX/themes.xml. in other res/values-XXX/themes.xml.
--> -->
<style name="GeckoBase" parent="@android:style/Theme.Holo.Light"> <style name="GeckoBase" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBar">false</item> <item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
@ -24,7 +24,8 @@
<style name="GeckoTitleDialogBase" parent="@android:style/Theme.Holo.Light.Dialog" /> <style name="GeckoTitleDialogBase" parent="@android:style/Theme.Holo.Light.Dialog" />
<style name="GeckoPreferencesBase" parent="GeckoBase"> <style name="GeckoPreferencesBase" parent="@android:style/Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBar">true</item> <item name="android:windowActionBar">true</item>
<item name="android:windowNoTitle">false</item> <item name="android:windowNoTitle">false</item>
<item name="android:actionBarStyle">@style/ActionBar.GeckoPreferences</item> <item name="android:actionBarStyle">@style/ActionBar.GeckoPreferences</item>

View File

@ -0,0 +1,19 @@
<?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/. -->
<resources>
<style name="ActionBarTitleTextStyle" parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title">
<item name="android:textColor">#fff</item>
</style>
<style name="ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
<item name="android:colorControlNormal">#fff</item>
<!-- This color is the system default. -->
<item name="android:colorControlHighlight">#65696D</item>
</style>
</resources>

View File

@ -8,20 +8,29 @@
<!-- <!--
Base application theme. Base application theme.
--> -->
<style name="GeckoBase" parent="@android:style/Theme.Material.Light.DarkActionBar"> <style name="GeckoBase" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:colorPrimary">@color/text_and_tabs_tray_grey</item> <item name="android:colorPrimary">@color/text_and_tabs_tray_grey</item>
<item name="android:colorPrimaryDark">@color/text_and_tabs_tray_grey</item> <item name="android:colorPrimaryDark">@color/text_and_tabs_tray_grey</item>
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
<item name="android:actionBarStyle">@style/GeckoActionBar</item> <item name="android:actionBarStyle">@style/GeckoActionBar</item>
<item name="android:actionBarTheme">@style/ActionBarTheme</item>
<item name="android:colorAccent">@color/action_orange</item> <item name="android:colorAccent">@color/action_orange</item>
</style> </style>
<style name="GeckoPreferencesBase" parent="GeckoBase">
<item name="android:windowActionBar">true</item>
<item name="android:windowNoTitle">false</item>
<item name="android:actionBarStyle">@style/ActionBar.GeckoPreferences</item>
</style>
<style name="ActionBar.FxAccountStatusActivity" parent="@android:style/Widget.Material.ActionBar.Solid"> <style name="ActionBar.FxAccountStatusActivity" parent="@android:style/Widget.Material.ActionBar.Solid">
<item name="android:displayOptions">homeAsUp|showTitle</item> <item name="android:displayOptions">homeAsUp|showTitle</item>
<item name="android:titleTextStyle">@style/ActionBarTitleTextStyle</item>
</style> </style>
<style name="ActionBar.GeckoPreferences" parent="@android:style/Widget.Material.ActionBar.Solid"> <style name="ActionBar.GeckoPreferences" parent="@android:style/Widget.Material.ActionBar.Solid">
<item name="android:titleTextStyle">@style/ActionBarTitleTextStyle</item>
</style> </style>
<style name="GeckoAppBase" parent="Gecko"> <style name="GeckoAppBase" parent="Gecko">

View File

@ -154,4 +154,7 @@
<color name="private_active_text">#FFFFFF</color> <color name="private_active_text">#FFFFFF</color>
<!-- This color is from a 2.3 Samsung device. -->
<color name="gingerbread_menu_background_color">#1b1b1b</color>
</resources> </resources>

View File

@ -5,7 +5,7 @@
<resources> <resources>
<dimen name="button_corner_radius">3dp</dimen> <dimen name="standard_corner_radius">4dp</dimen>
<dimen name="autocomplete_min_width">200dp</dimen> <dimen name="autocomplete_min_width">200dp</dimen>
<dimen name="autocomplete_row_height">32dp</dimen> <dimen name="autocomplete_row_height">32dp</dimen>
@ -46,7 +46,6 @@
<dimen name="tablet_browser_toolbar_menu_item_padding_horizontal">19dp</dimen> <dimen name="tablet_browser_toolbar_menu_item_padding_horizontal">19dp</dimen>
<dimen name="tablet_browser_toolbar_menu_item_inset_vertical">5dp</dimen> <dimen name="tablet_browser_toolbar_menu_item_inset_vertical">5dp</dimen>
<dimen name="tablet_browser_toolbar_menu_item_inset_horizontal">3dp</dimen> <dimen name="tablet_browser_toolbar_menu_item_inset_horizontal">3dp</dimen>
<dimen name="tablet_browser_toolbar_menu_item_corner_radius">5dp</dimen>
<dimen name="tablet_tab_strip_button_inset">5dp</dimen> <dimen name="tablet_tab_strip_button_inset">5dp</dimen>
<!-- Dimensions used by Favicons and FaviconView --> <!-- Dimensions used by Favicons and FaviconView -->

View File

@ -9,9 +9,13 @@
Base application theme. This could be overridden by GeckoBaseTheme Base application theme. This could be overridden by GeckoBaseTheme
in other res/values-XXX/themes.xml. in other res/values-XXX/themes.xml.
--> -->
<style name="GeckoBase" parent="@android:style/Theme.Light"> <style name="GeckoBase" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
<!-- AppCompat sets this to transparent by default:
http://stackoverflow.com/a/31777488 -->
<item name="android:panelBackground">@color/gingerbread_menu_background_color</item>
</style> </style>
<style name="GeckoDialogBase" parent="@android:style/Theme.Dialog"> <style name="GeckoDialogBase" parent="@android:style/Theme.Dialog">
@ -21,8 +25,9 @@
<style name="GeckoTitleDialogBase" parent="@android:style/Theme.Dialog" /> <style name="GeckoTitleDialogBase" parent="@android:style/Theme.Dialog" />
<style name="GeckoPreferencesBase" parent="GeckoBase"> <style name="GeckoPreferencesBase" parent="@android:style/Theme.Light">
<item name="android:windowNoTitle">false</item> <item name="android:windowNoTitle">false</item>
<item name="android:windowContentOverlay">@null</item>
</style> </style>
<!-- <!--

View File

@ -595,6 +595,8 @@
<string name="remote_tabs_last_synced">&remote_tabs_last_synced;</string> <string name="remote_tabs_last_synced">&remote_tabs_last_synced;</string>
<string name="intent_uri_cannot_open">&intent_uri_cannot_open;</string> <string name="intent_uri_cannot_open">&intent_uri_cannot_open;</string>
<string name="intent_uri_private_browsing_prompt">&intent_uri_private_browsing_prompt;</string>
<string name="intent_uri_private_browsing_multiple_match_title">&intent_uri_private_browsing_multiple_match_title;</string>
<string name="devtools_auth_scan_header">&devtools_auth_scan_header;</string> <string name="devtools_auth_scan_header">&devtools_auth_scan_header;</string>
</resources> </resources>

View File

@ -0,0 +1,98 @@
// 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/.
package org.mozilla.gecko.widget;
import org.mozilla.gecko.ActivityHandlerHelper;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import java.util.List;
/**
* A DialogFragment to contain a dialog that appears when the user clicks an Intent:// URI during private browsing. The
* dialog appears to notify the user that a clicked link will open in an external application, potentially leaking their
* browsing history.
*/
public class ExternalIntentDuringPrivateBrowsingPromptFragment extends DialogFragment {
private static final String LOGTAG = ExternalIntentDuringPrivateBrowsingPromptFragment.class.getSimpleName();
private static final String FRAGMENT_TAG = "ExternalIntentPB";
private static final String KEY_APPLICATION_NAME = "matchingApplicationName";
private static final String KEY_INTENT = "intent";
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Bundle args = getArguments();
final CharSequence matchingApplicationName = args.getCharSequence(KEY_APPLICATION_NAME);
final Intent intent = args.getParcelable(KEY_INTENT);
final Context context = getActivity();
final String promptMessage = context.getString(R.string.intent_uri_private_browsing_prompt, matchingApplicationName);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(promptMessage)
.setTitle(intent.getDataString())
.setPositiveButton(R.string.button_yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
context.startActivity(intent);
}
})
.setNegativeButton(R.string.button_no, null /* we do nothing if the user rejects */ );
return builder.create();
}
/**
* @return true if the Activity is started or a dialog is shown. false if the Activity fails to start.
*/
public static boolean showDialogOrAndroidChooser(final Context context, final FragmentManager fragmentManager,
final Intent intent) {
final Tab selectedTab = Tabs.getInstance().getSelectedTab();
if (selectedTab == null || !selectedTab.isPrivate()) {
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
}
final PackageManager pm = context.getPackageManager();
final List<ResolveInfo> matchingActivities = pm.queryIntentActivities(intent, 0);
if (matchingActivities.size() == 1) {
final ExternalIntentDuringPrivateBrowsingPromptFragment fragment = new ExternalIntentDuringPrivateBrowsingPromptFragment();
final Bundle args = new Bundle(2);
args.putCharSequence(KEY_APPLICATION_NAME, matchingActivities.get(0).loadLabel(pm));
args.putParcelable(KEY_INTENT, intent);
fragment.setArguments(args);
fragment.show(fragmentManager, FRAGMENT_TAG);
// We don't know the results of the user interaction with the fragment so just return true.
return true;
} else if (matchingActivities.size() > 1) {
// We want to show the Android Intent Chooser. However, we have no way of distinguishing regular tabs from
// private tabs to the chooser. Thus, if a user chooses "Always" in regular browsing mode, the chooser will
// not be shown and the URL will be opened. Therefore we explicitly show the chooser (which notably does not
// have an "Always" option).
final String androidChooserTitle =
context.getResources().getString(R.string.intent_uri_private_browsing_multiple_match_title);
final Intent chooserIntent = Intent.createChooser(intent, androidChooserTitle);
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, chooserIntent);
} else {
// Normally, we show about:neterror when an Intent does not resolve
// but we don't have the references here to do that so log instead.
Log.w(LOGTAG, "showDialogOrAndroidChooser unexpectedly called with Intent that does not resolve");
return false;
}
}
}

View File

@ -123,3 +123,6 @@ fi
if ! test "$NIGHTLY_BUILD"; then if ! test "$NIGHTLY_BUILD"; then
MOZ_ANDROID_NATIVE_ACCOUNT_UI=1 MOZ_ANDROID_NATIVE_ACCOUNT_UI=1
fi fi
# Disable GeckoView by default.
export MOZ_DISABLE_GECKOVIEW=1

View File

@ -16,6 +16,7 @@ import org.mozilla.gecko.util.ColorUtils;
import org.mozilla.search.providers.SearchEngine; import org.mozilla.search.providers.SearchEngine;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
@ -141,10 +142,20 @@ public class PostSearchFragment extends Fragment {
TelemetryContract.Method.INTENT, "search-result"); TelemetryContract.Method.INTENT, "search-result");
} }
i.addCategory(Intent.CATEGORY_BROWSABLE);
i.setComponent(null);
if (AppConstants.Versions.feature15Plus) {
i.setSelector(null);
}
startActivity(i); startActivity(i);
return true; return true;
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
Log.e(LOG_TAG, "Error parsing intent URI", e); Log.e(LOG_TAG, "Error parsing intent URI", e);
} catch (SecurityException e) {
Log.e(LOG_TAG, "SecurityException handling arbitrary intent content");
} catch (ActivityNotFoundException e) {
Log.e(LOG_TAG, "Intent not actionable");
} }
return false; return false;

View File

@ -91,7 +91,8 @@ static int mar_consume_index(MarFile *mar, char **buf, const char *buf_end) {
name = *buf; name = *buf;
/* find namelen; must take care not to read beyond buf_end */ /* find namelen; must take care not to read beyond buf_end */
while (**buf) { while (**buf) {
if (*buf == buf_end) /* buf_end points one byte past the end of buf's allocation */
if (*buf == (buf_end - 1))
return -1; return -1;
++(*buf); ++(*buf);
} }

View File

@ -15,6 +15,7 @@ import time
import random import random
import urlparse import urlparse
import os.path import os.path
import re
from external_tools.detect_repo import detect_git, detect_hg, detect_local from external_tools.detect_repo import detect_git, detect_hg, detect_local
try: try:
@ -40,6 +41,7 @@ from mozharness.mozilla.repo_manifest import (load_manifest, rewrite_remotes,
B2GMakefileErrorList = MakefileErrorList + [ B2GMakefileErrorList = MakefileErrorList + [
{'substr': r'''NS_ERROR_FILE_ALREADY_EXISTS: Component returned failure code''', 'level': ERROR}, {'substr': r'''NS_ERROR_FILE_ALREADY_EXISTS: Component returned failure code''', 'level': ERROR},
{'substr': r'''no version information available''', 'level': DEBUG}, {'substr': r'''no version information available''', 'level': DEBUG},
{'regex': re.compile(r'''\[/build_stage/.*\] \[l10n\] \[\S+\]: \d+ missing compared to en-US:'''), 'level': DEBUG},
] ]
B2GMakefileErrorList.insert(0, {'substr': r'/bin/bash: java: command not found', 'level': WARNING}) B2GMakefileErrorList.insert(0, {'substr': r'/bin/bash: java: command not found', 'level': WARNING})

View File

@ -660,17 +660,16 @@ function isUsableAddon(aAddon) {
if (aAddon.type == "theme" && aAddon.internalName == XPIProvider.defaultSkin) if (aAddon.type == "theme" && aAddon.internalName == XPIProvider.defaultSkin)
return true; return true;
if (mustSign(aAddon.type)) { if (aAddon._installLocation.name == KEY_APP_SYSTEM_ADDONS &&
aAddon.signedState != AddonManager.SIGNEDSTATE_SYSTEM) {
return false;
}
if (aAddon._installLocation.name != KEY_APP_SYSTEM_DEFAULTS && mustSign(aAddon.type)) {
if (aAddon.signedState <= AddonManager.SIGNEDSTATE_MISSING) if (aAddon.signedState <= AddonManager.SIGNEDSTATE_MISSING)
return false; return false;
if (aAddon.foreignInstall && aAddon.signedState < AddonManager.SIGNEDSTATE_SIGNED) if (aAddon.foreignInstall && aAddon.signedState < AddonManager.SIGNEDSTATE_SIGNED)
return false; return false;
if (aAddon._installLocation.name == KEY_APP_SYSTEM_ADDONS ||
aAddon._installLocation.name == KEY_APP_SYSTEM_DEFAULTS) {
if (aAddon.signedState != AddonManager.SIGNEDSTATE_SYSTEM)
return false;
}
} }
if (aAddon.blocklistState == Blocklist.STATE_BLOCKED) if (aAddon.blocklistState == Blocklist.STATE_BLOCKED)
@ -2525,7 +2524,7 @@ this.XPIProvider = {
if (!REQUIRE_SIGNING) if (!REQUIRE_SIGNING)
Services.prefs.addObserver(PREF_XPI_SIGNATURES_REQUIRED, this, false); Services.prefs.addObserver(PREF_XPI_SIGNATURES_REQUIRED, this, false);
Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS, false); Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS, false);
if (Cu.isModuleLoaded("resource:///modules/devtools/ToolboxProcess.jsm")) { if (Cu.isModuleLoaded("resource:///modules/devtools/client/framework/ToolboxProcess.jsm")) {
// If BrowserToolboxProcess is already loaded, set the boolean to true // If BrowserToolboxProcess is already loaded, set the boolean to true
// and do whatever is needed // and do whatever is needed
this._toolboxProcessLoaded = true; this._toolboxProcessLoaded = true;

View File

@ -2,9 +2,6 @@
// application versions // application versions
const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet"; const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet";
// Enable signature checks for these tests
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
BootstrapMonitor.init(); BootstrapMonitor.init();
const featureDir = FileUtils.getDir("ProfD", ["features"]); const featureDir = FileUtils.getDir("ProfD", ["features"]);
@ -60,7 +57,9 @@ function* check_installed(inProfile, ...versions) {
do_check_true(uri instanceof AM_Ci.nsIFileURL); do_check_true(uri instanceof AM_Ci.nsIFileURL);
do_check_eq(uri.file.path, file.path); do_check_eq(uri.file.path, file.path);
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SYSTEM); if (inProfile) {
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SYSTEM);
}
// Verify the add-on actually started // Verify the add-on actually started
BootstrapMonitor.checkAddonStarted(id, versions[i]); BootstrapMonitor.checkAddonStarted(id, versions[i]);
@ -273,19 +272,18 @@ add_task(function* test_bad_profile_cert() {
yield promiseShutdownManager(); yield promiseShutdownManager();
}); });
// Switching to app defaults that contain a bad certificate should ignore the // Switching to app defaults that contain a bad certificate should still work
// bad add-on
add_task(function* test_bad_app_cert() { add_task(function* test_bad_app_cert() {
gAppInfo.version = "3"; gAppInfo.version = "3";
distroDir.leafName = "app3"; distroDir.leafName = "app3";
startupManager(); startupManager();
// Add-on will still be present just not active // Add-on will still be present
let addon = yield promiseAddonByID("system1@tests.mozilla.org"); let addon = yield promiseAddonByID("system1@tests.mozilla.org");
do_check_neq(addon, null); do_check_neq(addon, null);
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN); do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
yield check_installed(false, null, null, "1.0"); yield check_installed(false, "1.0", null, "1.0");
yield promiseShutdownManager(); yield promiseShutdownManager();
}); });

View File

@ -8,9 +8,6 @@ const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
Components.utils.import("resource://testing-common/httpd.js"); Components.utils.import("resource://testing-common/httpd.js");
const { computeHash } = Components.utils.import("resource://gre/modules/addons/ProductAddonChecker.jsm"); const { computeHash } = Components.utils.import("resource://gre/modules/addons/ProductAddonChecker.jsm");
// Enable signature checks for these tests
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
BootstrapMonitor.init(); BootstrapMonitor.init();
const featureDir = FileUtils.getDir("ProfD", ["features"], false); const featureDir = FileUtils.getDir("ProfD", ["features"], false);
@ -176,7 +173,9 @@ function* check_installed(inProfile, ...versions) {
do_check_true(uri instanceof AM_Ci.nsIFileURL); do_check_true(uri instanceof AM_Ci.nsIFileURL);
do_check_eq(uri.file.path, file.path); do_check_eq(uri.file.path, file.path);
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SYSTEM); if (inProfile) {
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SYSTEM);
}
// Verify the add-on actually started // Verify the add-on actually started
BootstrapMonitor.checkAddonStarted(id, versions[i]); BootstrapMonitor.checkAddonStarted(id, versions[i]);
@ -352,6 +351,15 @@ const TESTS = {
], ],
finalState: [true, null, "3.0", "3.0", null, "1.0"] finalState: [true, null, "3.0", "3.0", null, "1.0"]
}, },
// A bad certificate should stop updates
badCert: {
fails: true,
updateList: [
{ id: "system1@tests.mozilla.org", version: "1.0", path: "system1_1_badcert.xpi" },
{ id: "system3@tests.mozilla.org", version: "1.0", path: "system3_1.xpi" }
],
}
} }
add_task(function* setup() { add_task(function* setup() {