Merge mozilla-central to mozilla-inbound on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2015-01-12 15:09:33 +01:00
Родитель 18f1ac701b 830e9e7d40
Коммит 56977f0315
82 изменённых файлов: 684 добавлений и 452 удалений

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

@ -51,6 +51,10 @@
background: url("chrome://b2g/content/images/exitfullscreen-hdpi.png") no-repeat center;
}
.controlBar[fullscreen-unavailable] .fullscreenButton {
display: none;
}
.playButton {
background: url("chrome://b2g/content/images/pause-hdpi.png") no-repeat center;
}
@ -61,7 +65,7 @@
* is hidden by videocontrols.xml, and that alters the position of the
* play button. This workaround moves it back to center.
*/
.controlBar.audio-only .playButton {
.controlBar[fullscreen-unavailable] .playButton {
transform: translateX(28px);
}

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

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

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3bf54932bcae08eb6cab2453a2be007835423cbd",
"revision": "4f9b71ccf0770ad99ba7f802d951f569e10b1021",
"repo_path": "integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -441,7 +441,6 @@ panel[noactions] > richlistbox > richlistitem.overridable-action > .ac-url-box >
#PopupSearchAutoComplete {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-search-autocomplete-result-popup");
margin-left: -23px;
}
/* Overlay a badge on top of the icon of additional open search providers

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

@ -1132,22 +1132,27 @@
"search-panel-one-offs-header")
header.collapsed = list.collapsed = !engines.length;
if (!engines.length)
return;
// 49px is the min-width of each search engine button,
// adapt this const when changing the css.
// It's actually 48px + 1px of right border.
const ENGINE_WIDTH = 49;
let panel = document.getElementById("PopupSearchAutoComplete");
// The + 23 is because the panel width only spans to the textbox
// size, but we also want it to include the magnifier icon's width.
let minWidth = parseInt(panel.width) + 23;
// Ensure the panel is wide enough to fit at least 3 engines.
minWidth = Math.max(minWidth, ENGINE_WIDTH * 3);
// The panel width only spans to the textbox size, but we also want it
// to include the magnifier icon's width.
let ltr = getComputedStyle(this).direction == "ltr";
let magnifierWidth = parseInt(getComputedStyle(panel)[
ltr ? "marginLeft" : "marginRight"
]) * -1;
let minWidth = parseInt(panel.width) + magnifierWidth;
if (engines.length) {
// Ensure the panel is wide enough to fit at least 3 engines.
minWidth = Math.max(minWidth, ENGINE_WIDTH * 3);
}
panel.setAttribute("style", "min-width: " + minWidth + "px");
if (!engines.length)
return;
let panelWidth = parseInt(panel.clientWidth);
// The + 1 is because the last button doesn't have a right border.
let enginesPerRow = Math.floor((panelWidth + 1) / ENGINE_WIDTH);

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

@ -20,6 +20,11 @@ loop.conversationViews = (function(mozL10n) {
// This duplicates a similar function in contacts.jsx that isn't used in the
// conversation window. If we get too many of these, we might want to consider
// finding a logical place for them to be shared.
// XXXdmose this code is already out of sync with the code in contacts.jsx
// which, unlike this code, now has unit tests. We should totally do the
// above.
function _getPreferredEmail(contact) {
// A contact may not contain email addresses, but only a phone number.
if (!contact.email || contact.email.length === 0) {
@ -761,6 +766,25 @@ loop.conversationViews = (function(mozL10n) {
return React.createElement("p", {className: "error"}, mozL10n.get("unable_retrieve_url"));
},
_getTitleMessage: function() {
var callStateReason =
this.props.store.getStoreState("callStateReason");
if (callStateReason === "reject" || callStateReason === "busy" ||
callStateReason === "setup") {
var contactDisplayName = _getContactDisplayName(this.props.contact);
if (contactDisplayName.length) {
return mozL10n.get(
"contact_unavailable_title",
{"contactName": contactDisplayName});
}
return mozL10n.get("generic_contact_unavailable_title");
} else {
return mozL10n.get("generic_failure_title");
}
},
retryCall: function() {
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
},
@ -784,7 +808,7 @@ loop.conversationViews = (function(mozL10n) {
render: function() {
return (
React.createElement("div", {className: "call-window"},
React.createElement("h2", null, mozL10n.get("generic_failure_title")),
React.createElement("h2", null, this._getTitleMessage() ),
React.createElement("p", {className: "btn-label"}, mozL10n.get("generic_failure_with_reason2")),
@ -1048,6 +1072,7 @@ loop.conversationViews = (function(mozL10n) {
CallIdentifierView: CallIdentifierView,
ConversationDetailView: ConversationDetailView,
CallFailedView: CallFailedView,
_getContactDisplayName: _getContactDisplayName,
GenericFailureView: GenericFailureView,
IncomingCallView: IncomingCallView,
IncomingConversationView: IncomingConversationView,

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

@ -20,6 +20,11 @@ loop.conversationViews = (function(mozL10n) {
// This duplicates a similar function in contacts.jsx that isn't used in the
// conversation window. If we get too many of these, we might want to consider
// finding a logical place for them to be shared.
// XXXdmose this code is already out of sync with the code in contacts.jsx
// which, unlike this code, now has unit tests. We should totally do the
// above.
function _getPreferredEmail(contact) {
// A contact may not contain email addresses, but only a phone number.
if (!contact.email || contact.email.length === 0) {
@ -761,6 +766,25 @@ loop.conversationViews = (function(mozL10n) {
return <p className="error">{mozL10n.get("unable_retrieve_url")}</p>;
},
_getTitleMessage: function() {
var callStateReason =
this.props.store.getStoreState("callStateReason");
if (callStateReason === "reject" || callStateReason === "busy" ||
callStateReason === "setup") {
var contactDisplayName = _getContactDisplayName(this.props.contact);
if (contactDisplayName.length) {
return mozL10n.get(
"contact_unavailable_title",
{"contactName": contactDisplayName});
}
return mozL10n.get("generic_contact_unavailable_title");
} else {
return mozL10n.get("generic_failure_title");
}
},
retryCall: function() {
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
},
@ -784,7 +808,7 @@ loop.conversationViews = (function(mozL10n) {
render: function() {
return (
<div className="call-window">
<h2>{mozL10n.get("generic_failure_title")}</h2>
<h2>{ this._getTitleMessage() }</h2>
<p className="btn-label">{mozL10n.get("generic_failure_with_reason2")}</p>
@ -1048,6 +1072,7 @@ loop.conversationViews = (function(mozL10n) {
CallIdentifierView: CallIdentifierView,
ConversationDetailView: ConversationDetailView,
CallFailedView: CallFailedView,
_getContactDisplayName: _getContactDisplayName,
GenericFailureView: GenericFailureView,
IncomingCallView: IncomingCallView,
IncomingConversationView: IncomingConversationView,

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

@ -279,7 +279,7 @@
.call-window h2 {
font-size: 1.5em;
font-weight: normal;
text-align: center;
/* compensate for reset.css overriding this; values borrowed from
Firefox Mac html.css */
margin: 0.83em 0;

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

@ -412,6 +412,61 @@ describe("loop.conversationViews", function () {
sinon.assert.calledOnce(fakeAudio.play);
expect(fakeAudio.loop).to.equal(false);
});
it("should show 'something went wrong' when the reason is 'media-fail'",
function () {
store.setStoreState({callStateReason: "media-fail"});
view = mountTestComponent({contact: contact});
sinon.assert.calledWith(document.mozL10n.get, "generic_failure_title");
});
it("should show 'contact unavailable' when the reason is 'reject'",
function () {
store.setStoreState({callStateReason: "reject"});
view = mountTestComponent({contact: contact});
sinon.assert.calledWithExactly(document.mozL10n.get,
"contact_unavailable_title",
{contactName: loop.conversationViews._getContactDisplayName(contact)});
});
it("should show 'contact unavailable' when the reason is 'busy'",
function () {
store.setStoreState({callStateReason: "busy"});
view = mountTestComponent({contact: contact});
sinon.assert.calledWithExactly(document.mozL10n.get,
"contact_unavailable_title",
{contactName: loop.conversationViews._getContactDisplayName(contact)});
});
it("should show 'contact unavailable' when the reason is 'setup'",
function () {
store.setStoreState({callStateReason: "setup"});
view = mountTestComponent({contact: contact});
sinon.assert.calledWithExactly(document.mozL10n.get,
"contact_unavailable_title",
{contactName: loop.conversationViews._getContactDisplayName(contact)});
});
it("should display a generic contact unavailable msg when the reason is" +
" 'busy' and no display name is available", function() {
store.setStoreState({callStateReason: "busy"});
var phoneOnlyContact = {
tel: [{"pref": true, type: "work", value: ""}]
};
view = mountTestComponent({contact: phoneOnlyContact});
sinon.assert.calledWith(document.mozL10n.get,
"generic_contact_unavailable_title");
});
});
describe("OngoingConversationView", function() {
@ -531,7 +586,10 @@ describe("loop.conversationViews", function () {
it("should render the CallFailedView when the call state is 'terminated'",
function() {
store.setStoreState({callState: CALL_STATES.TERMINATED});
store.setStoreState({
callState: CALL_STATES.TERMINATED,
contact: contact
});
view = mountTestComponent();

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

@ -74,6 +74,11 @@
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
feedbackClient: stageFeedbackApiClient
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: {},
mozLoop: navigator.mozLoop,
sdkDriver: {}
});
// Local mocks
@ -376,13 +381,14 @@
React.createElement(Example, {summary: "Call Failed", dashed: "true",
style: {width: "260px", height: "265px"}},
React.createElement("div", {className: "fx-embedded"},
React.createElement(CallFailedView, {dispatcher: dispatcher})
React.createElement(CallFailedView, {dispatcher: dispatcher, store: conversationStore})
)
),
React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true",
style: {width: "260px", height: "265px"}},
React.createElement("div", {className: "fx-embedded"},
React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true})
React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true,
store: conversationStore})
)
)
),

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

@ -74,6 +74,11 @@
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
feedbackClient: stageFeedbackApiClient
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: {},
mozLoop: navigator.mozLoop,
sdkDriver: {}
});
// Local mocks
@ -376,13 +381,14 @@
<Example summary="Call Failed" dashed="true"
style={{width: "260px", height: "265px"}}>
<div className="fx-embedded">
<CallFailedView dispatcher={dispatcher} />
<CallFailedView dispatcher={dispatcher} store={conversationStore} />
</div>
</Example>
<Example summary="Call Failed — with call URL error" dashed="true"
style={{width: "260px", height: "265px"}}>
<div className="fx-embedded">
<CallFailedView dispatcher={dispatcher} emailLinkError={true} />
<CallFailedView dispatcher={dispatcher} emailLinkError={true}
store={conversationStore} />
</div>
</Example>
</Section>

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

@ -2408,28 +2408,28 @@ let DefaultBrowserCheck = {
},
prompt: function(win) {
let brandBundle = win.document.getElementById("bundle_brand");
let shellBundle = win.document.getElementById("bundle_shell");
let brandShortName = brandBundle.getString("brandShortName");
let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage2",
[brandShortName]);
let yesButton = shellBundle.getFormattedString("setDefaultBrowserConfirm.label",
[brandShortName]);
let notNowButton = shellBundle.getString("setDefaultBrowserNotNow.label");
let notNowButtonKey = shellBundle.getString("setDefaultBrowserNotNow.accesskey");
let neverLabel = shellBundle.getString("setDefaultBrowserNever.label");
let neverKey = shellBundle.getString("setDefaultBrowserNever.accesskey");
let useNotificationBar = Services.prefs.getBoolPref("browser.defaultbrowser.notificationbar");
let brandBundle = win.document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
let shellBundle = win.document.getElementById("bundle_shell");
let buttonPrefix = "setDefaultBrowser" + (useNotificationBar ? "" : "Alert");
let yesButton = shellBundle.getFormattedString(buttonPrefix + "Confirm.label",
[brandShortName]);
let notNowButton = shellBundle.getString(buttonPrefix + "NotNow.label");
if (useNotificationBar) {
let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage2",
[brandShortName]);
let optionsMessage = shellBundle.getString("setDefaultBrowserOptions.label");
let optionsKey = shellBundle.getString("setDefaultBrowserOptions.accesskey");
let neverLabel = shellBundle.getString("setDefaultBrowserNever.label");
let neverKey = shellBundle.getString("setDefaultBrowserNever.accesskey");
let yesButtonKey = shellBundle.getString("setDefaultBrowserConfirm.accesskey");
let notNowButtonKey = shellBundle.getString("setDefaultBrowserNotNow.accesskey");
let notificationBox = win.document.getElementById("high-priority-global-notificationbox");
@ -2467,6 +2467,10 @@ let DefaultBrowserCheck = {
} else {
// Modal prompt
let promptTitle = shellBundle.getString("setDefaultBrowserTitle");
let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
[brandShortName]);
let dontAskLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
[brandShortName]);
let ps = Services.prompt;
let dontAsk = { value: false };
@ -2474,7 +2478,7 @@ let DefaultBrowserCheck = {
(ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1) +
ps.BUTTON_POS_0_DEFAULT;
let rv = ps.confirmEx(win, promptTitle, promptMessage, buttonFlags,
yesButton, notNowButton, null, neverLabel, dontAsk);
yesButton, notNowButton, null, dontAskLabel, dontAsk);
if (rv == 0) {
this.setAsDefault();
} else if (dontAsk.value) {

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

@ -80,14 +80,21 @@
</hbox>
</groupbox>
</hbox>
#ifdef XP_WIN
<vbox align="start">
<label accesskey="&allowPagesToUseColors.accesskey;"
control="useDocumentColors">&allowPagesToUseColors.label;</label>
#else
<vbox>
#endif
<label accesskey="&overridePageColors.accesskey;"
control="useDocumentColors">&overridePageColors.label;</label>
<menulist id="useDocumentColors" preference="browser.display.document_color_use">
<menupopup>
<menuitem label="&allowPagesToUseColors.automatic.label;" value="0" id="documentColorAutomatic"/>
<menuitem label="&allowPagesToUseColors.always.label;" value="1" id="documentColorAlways"/>
<menuitem label="&allowPagesToUseColors.never.label;" value="2" id="documentColorNever"/>
<menuitem label="&overridePageColors.always.label;"
value="2" id="documentColorAlways"/>
<menuitem label="&overridePageColors.auto.label;"
value="0" id="documentColorAutomatic"/>
<menuitem label="&overridePageColors.never.label;"
value="1" id="documentColorNever"/>
</menupopup>
</menulist>
</vbox>

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

@ -751,6 +751,11 @@
<handler event="click" button="0">
<![CDATA[
// Ignore clicks on the search go button.
if (event.originalTarget.getAttribute("anonid") == "search-go-button") {
return;
}
// Open the suggestions whenever clicking on the search icon or if there
// is text in the textbox.
if (event.originalTarget.getAttribute("anonid") == "searchbar-search-button" ||

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

@ -3,6 +3,7 @@
const searchbar = document.getElementById("searchbar");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid", "searchbar-search-button");
const goButton = document.getAnonymousElementByAttribute(searchbar, "anonid", "search-go-button");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
@ -318,3 +319,19 @@ add_task(function* refocus_window_doesnt_open_popup_keyboard() {
searchPopup.removeEventListener("popupshowing", listener, false);
textbox.value = "";
});
// Clicking the search go button shouldn't open the popup
add_no_popup_task(function* search_go_doesnt_open_popup() {
gBrowser.selectedTab = gBrowser.addTab();
gURLBar.focus();
textbox.value = "foo";
searchbar.inputChanged();
let promise = promiseOnLoad();
EventUtils.synthesizeMouseAtCenter(goButton, {});
yield promise;
textbox.value = "";
gBrowser.removeCurrentTab();
});

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

@ -391,16 +391,6 @@ let NetMonitorController = {
!this._target.isApp);
},
/**
* Getter that tells if the server includes the transferred (compressed /
* encoded) response size.
* @type boolean
*/
get supportsTransferredResponseSize() {
return this.webConsoleClient &&
this.webConsoleClient.traits.transferredResponseSize;
},
/**
* Getter that tells if the server can do network performance statistics.
* @type boolean
@ -600,7 +590,6 @@ NetworkEventsHandler.prototype = {
case "responseContent":
NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
contentSize: aPacket.contentSize,
transferredSize: aPacket.transferredSize,
mimeType: aPacket.mimeType
});
this.webConsoleClient.getResponseContent(actor, this._onResponseContent);

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

@ -416,11 +416,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
$("#requests-menu-network-summary-button").hidden = true;
$("#requests-menu-network-summary-label").hidden = true;
}
if (!NetMonitorController.supportsTransferredResponseSize) {
$("#requests-menu-transferred-header-box").hidden = true;
$("#requests-menu-item-template .requests-menu-transferred").hidden = true;
}
},
/**
@ -804,8 +799,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* Sorts all network requests in this container by a specified detail.
*
* @param string aType
* Either "status", "method", "file", "domain", "type", "transferred",
* "size" or "waterfall".
* Either "status", "method", "file", "domain", "type", "size" or
* "waterfall".
*/
sortBy: function(aType = "waterfall") {
let target = $("#requests-menu-" + aType + "-button");
@ -866,13 +861,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.sortContents((a, b) => !this._byType(a, b));
}
break;
case "transferred":
if (direction == "ascending") {
this.sortContents(this._byTransferred);
} else {
this.sortContents((a, b) => !this._byTransferred(a, b));
}
break;
case "size":
if (direction == "ascending") {
this.sortContents(this._bySize);
@ -1005,13 +993,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
: firstType > secondType;
},
_byTransferred: function({ attachment: first }, { attachment: second }) {
return first.transferredSize > second.transferredSize;
},
_bySize: function({ attachment: first }, { attachment: second }) {
return first.contentSize > second.contentSize;
},
_bySize: function({ attachment: first }, { attachment: second })
first.contentSize > second.contentSize,
/**
* Refreshes the status displayed in this container's footer, providing
@ -1176,10 +1159,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
requestItem.attachment.contentSize = value;
this.updateMenuView(requestItem, key, value);
break;
case "transferredSize":
requestItem.attachment.transferredSize = value;
this.updateMenuView(requestItem, key, value);
break;
case "mimeType":
requestItem.attachment.mimeType = value;
this.updateMenuView(requestItem, key, value);
@ -1328,20 +1307,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
node.setAttribute("tooltiptext", text);
break;
}
case "transferredSize": {
let text;
if (aValue === null) {
text = L10N.getStr("networkMenu.sizeUnavailable");
} else {
let kb = aValue / 1024;
let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS);
text = L10N.getFormatStr("networkMenu.sizeKB", size);
}
let node = $(".requests-menu-transferred", target);
node.setAttribute("value", text);
node.setAttribute("tooltiptext", text);
break;
}
case "mimeType": {
let type = this._getAbbreviatedMimeType(aValue);
let node = $(".requests-menu-type", target);

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

@ -101,16 +101,6 @@
flex="1">
</button>
</hbox>
<hbox id="requests-menu-transferred-header-box"
class="requests-menu-header requests-menu-transferred"
align="center">
<button id="requests-menu-transferred-button"
class="requests-menu-header-button requests-menu-transferred"
data-key="transferred"
label="&netmonitorUI.toolbar.transferred;"
flex="1">
</button>
</hbox>
<hbox id="requests-menu-size-header-box"
class="requests-menu-header requests-menu-size"
align="center">
@ -184,8 +174,6 @@
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-type"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-transferred"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-size"
crop="end"/>
<hbox class="requests-menu-subitem requests-menu-waterfall"

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

@ -65,8 +65,6 @@ function test() {
is(requestItem.attachment.headersSize, undefined,
"The headersSize should not yet be set.");
is(requestItem.attachment.transferredSize, undefined,
"The transferredSize should not yet be set.");
is(requestItem.attachment.contentSize, undefined,
"The contentSize should not yet be set.");
@ -158,8 +156,6 @@ function test() {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_RESPONSE_CONTENT, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
is(requestItem.attachment.transferredSize, "12",
"The transferredSize attachment has an incorrect value.");
is(requestItem.attachment.contentSize, "12",
"The contentSize attachment has an incorrect value.");
is(requestItem.attachment.mimeType, "text/plain; charset=utf-8",
@ -168,7 +164,6 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
});
});
@ -188,7 +183,6 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
});
});

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

@ -202,7 +202,6 @@ function test() {
statusText: "Switching Protocols",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -212,7 +211,6 @@ function test() {
statusText: "Created",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -222,7 +220,6 @@ function test() {
statusText: "See Other",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -232,7 +229,6 @@ function test() {
statusText: "Not Found",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -242,7 +238,6 @@ function test() {
statusText: "Not Implemented",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});

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

@ -102,24 +102,6 @@ function test() {
testHeaders("type", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing transferred sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing transferred sort, descending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "descending");
return testContents([4, 3, 2, 1, 0]);
})
.then(() => {
info("Testing transferred sort, ascending. Checking sort loops correctly.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing size sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
@ -217,7 +199,6 @@ function test() {
statusText: "Meh",
type: "1",
fullMimeType: "text/1",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -228,7 +209,6 @@ function test() {
statusText: "Meh",
type: "2",
fullMimeType: "text/2",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
time: true
});
@ -239,7 +219,6 @@ function test() {
statusText: "Meh",
type: "3",
fullMimeType: "text/3",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -250,7 +229,6 @@ function test() {
statusText: "Meh",
type: "4",
fullMimeType: "text/4",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
time: true
});
@ -261,7 +239,6 @@ function test() {
statusText: "Meh",
type: "5",
fullMimeType: "text/5",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});

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

@ -130,7 +130,6 @@ function test() {
statusText: "Meh",
type: "1",
fullMimeType: "text/1",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -143,7 +142,6 @@ function test() {
statusText: "Meh",
type: "2",
fullMimeType: "text/2",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
time: true
});
@ -156,7 +154,6 @@ function test() {
statusText: "Meh",
type: "3",
fullMimeType: "text/3",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -169,7 +166,6 @@ function test() {
statusText: "Meh",
type: "4",
fullMimeType: "text/4",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
time: true
});
@ -182,7 +178,6 @@ function test() {
statusText: "Meh",
type: "5",
fullMimeType: "text/5",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});

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

@ -12,12 +12,6 @@ function test() {
let { document, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
// Disable transferred size column support for this test.
// Without this, the waterfall only has enough room for one division, which
// would remove most of the value of this test.
document.querySelector("#requests-menu-transferred-header-box").hidden = true;
document.querySelector("#requests-menu-item-template .requests-menu-transferred").hidden = true;
RequestsMenu.lazyUpdate = false;
ok(document.querySelector("#requests-menu-waterfall-label"),

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

@ -264,7 +264,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Widget index of item: " + widgetIndex);
info("Visible index of item: " + visibleIndex);
let { fuzzyUrl, status, statusText, type, fullMimeType, transferred, size, time } = aData;
let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
let { attachment, target } = aRequestItem
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
@ -319,14 +319,6 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
is(value, type, "The displayed type is incorrect.");
is(tooltip, fullMimeType, "The tooltip type is incorrect.");
}
if (transferred !== undefined) {
let value = target.querySelector(".requests-menu-transferred").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("tooltiptext");
info("Displayed transferred size: " + value);
info("Tooltip transferred size: " + tooltip);
is(value, transferred, "The displayed transferred size is incorrect.");
is(tooltip, transferred, "The tooltip transferred size is incorrect.");
}
if (size !== undefined) {
let value = target.querySelector(".requests-menu-size").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-size").getAttribute("tooltiptext");

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

@ -42,14 +42,8 @@
- in the network table toolbar, above the "type" column. -->
<!ENTITY netmonitorUI.toolbar.type "Type">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.transferred): This is the label displayed
- in the network table toolbar, above the "transferred" column, which is the
- compressed / encoded size. -->
<!ENTITY netmonitorUI.toolbar.transferred "Transferred">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.size): This is the label displayed
- in the network table toolbar, above the "size" column, which is the
- uncompressed / decoded size. -->
- in the network table toolbar, above the "size" column. -->
<!ENTITY netmonitorUI.toolbar.size "Size">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.waterfall): This is the label displayed

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

@ -129,11 +129,6 @@ networkMenu.summary=One request, #2 KB, #3 s;#1 requests, #2 KB, #3 s
# in the network menu specifying the size of a request (in kilobytes).
networkMenu.sizeKB=%S KB
# LOCALIZATION NOTE (networkMenu.sizeUnavailable): This is the label displayed
# in the network menu specifying the transferred size of a request is
# unavailable.
networkMenu.sizeUnavailable=
# LOCALIZATION NOTE (networkMenu.totalMS): This is the label displayed
# in the network menu specifying the time for a request to finish (in milliseconds).
networkMenu.totalMS=→ %S ms

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

@ -225,6 +225,12 @@ peer_ended_conversation2=The person you were calling has ended the conversation.
conversation_has_ended=Your conversation has ended.
restart_call=Rejoin
## LOCALIZATION NOTE (contact_unavailable_title): The title displayed
## when a contact is unavailable. Don't translate the part between {{..}}
## because this will be replaced by the contact's name.
contact_unavailable_title={{contactName}} is unavailable.
generic_contact_unavailable_title=This person is unavailable.
generic_failure_title=Something went wrong.
generic_failure_with_reason2=You can try again or email a link to be reached at later.
generic_failure_no_reason2=Would you like to try again?

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

@ -6,12 +6,12 @@
<!ENTITY window.width "38em">
<!ENTITY window.macWidth "41em">
<!ENTITY allowPagesToUseColors.label "Allow pages to choose their own colors, instead of my selections above:">
<!ENTITY allowPagesToUseColors.accesskey "A">
<!ENTITY overridePageColors.label "Override the colors specified by the page with my selections above:">
<!ENTITY overridePageColors.accesskey "O">
<!ENTITY allowPagesToUseColors.automatic.label "Automatic">
<!ENTITY allowPagesToUseColors.always.label "Always">
<!ENTITY allowPagesToUseColors.never.label "Never">
<!ENTITY overridePageColors.always.label "Always">
<!ENTITY overridePageColors.auto.label "Only with High Contrast themes">
<!ENTITY overridePageColors.never.label "Never">
<!ENTITY color "Text and Background">
<!ENTITY textColor.label "Text:">

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

@ -17,12 +17,14 @@ setDefaultBrowserNotNow.accesskey = N
setDefaultBrowserNever.label = Don't ask me again
setDefaultBrowserNever.accesskey = D
# LOCALIZATION NOTE (setDefaultBrowserTitle, setDefaultBrowserMessage, setDefaultBrowserDontAsk):
# LOCALIZATION NOTE (setDefaultBrowserTitle, setDefaultBrowserMessage, setDefaultBrowserDontAsk, setDefaultBrowserAlertConfirm.label, setDefaultBrowserAlertNotNow.label):
# These strings are used as an alternative to the ones above, in a modal dialog.
# %S will be replaced by brandShortName
setDefaultBrowserTitle=Default Browser
setDefaultBrowserMessage=%S is not currently set as your default browser. Would you like to make it your default browser?
setDefaultBrowserDontAsk=Always perform this check when starting %S.
setDefaultBrowserAlertConfirm.label=Use %S as my default browser
setDefaultBrowserAlertNotNow.label=Not now
desktopBackgroundLeafNameWin=Desktop Background.bmp
DesktopBackgroundDownloading=Saving Picture…

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

@ -45,6 +45,10 @@
background: url("chrome://browser/skin/images/exitfullscreen-hdpi.png") no-repeat center;
}
.controlBar[fullscreen-unavailable] .fullscreenButton {
display: none;
}
.playButton {
background: url("chrome://browser/skin/images/pause-hdpi.png") no-repeat center;
}
@ -55,7 +59,7 @@
* is hidden by videocontrols.xml, and that alters the position of the
* play button. This workaround moves it back to center.
*/
.controlBar.audio-only .playButton {
.controlBar[fullscreen-unavailable] .playButton {
transform: translateX(28px);
}

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

@ -2,6 +2,10 @@
* 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/. */
#PopupSearchAutoComplete {
-moz-margin-start: -24px;
}
.searchbar-textbox {
min-height: 22px;
background-color: -moz-field;
@ -24,7 +28,6 @@
height: 16px;
width: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
-moz-margin-start: 2px;
}
.searchbar-engine-button {
@ -72,14 +75,12 @@ menuitem[cmd="cmd_clearhistory"][disabled] {
.searchbar-search-button-container {
-moz-box-align: center;
padding: 2px 3px;
-moz-padding-end: 2px;
}
.searchbar-search-button {
list-style-image: url("chrome://browser/skin/search-indicator.png");
-moz-image-region: rect(0, 20px, 20px, 0);
margin: -2px -2px;
-moz-margin-start: 2px;
}
.searchbar-search-button[addengines="true"] {
@ -240,7 +241,7 @@ searchbar[oneoffui] .searchbar-engine-button {
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-moz-padding-start: 6px;
-moz-padding-start: 5px;
width: 14px;
height: 14px;
}

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

@ -2,6 +2,10 @@
* 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/. */
#PopupSearchAutoComplete {
-moz-margin-start: -23px;
}
.searchbar-dropmarker-image {
--searchbar-dropmarker-url: url("chrome://browser/skin/searchbar-dropmarker.png");
--searchbar-dropmarker-2x-url: url("chrome://browser/skin/searchbar-dropmarker@2x.png");
@ -49,8 +53,6 @@
.searchbar-search-button-container {
-moz-box-align: center;
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.search-go-button {
@ -60,7 +62,8 @@
.searchbar-search-button {
list-style-image: url("chrome://browser/skin/search-indicator.png");
-moz-image-region: rect(0, 20px, 20px, 0);
margin: 0 -3px;
-moz-margin-start: 3px;
-moz-margin-end: 1px;
}
.searchbar-search-button[addengines="true"] {

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

@ -166,11 +166,6 @@
width: 8em;
}
.requests-menu-transferred {
text-align: center;
width: 8em;
}
/* Network requests table: status codes */
box.requests-menu-status {

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

@ -2,6 +2,10 @@
* 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/. */
#PopupSearchAutoComplete {
-moz-margin-start: -25px;
}
.searchbar-dropmarker-image {
--searchbar-dropmarker-url: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
}
@ -21,7 +25,6 @@
width: 16px;
list-style-image: url("chrome://global/skin/icons/folder-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
-moz-margin-start: 2px;
}
.searchbar-engine-button {
@ -83,14 +86,14 @@
.searchbar-search-button-container {
-moz-box-align: center;
padding: 3px 4px;
-moz-padding-end: 2px;
}
.searchbar-search-button {
list-style-image: url("chrome://browser/skin/search-indicator.png");
-moz-image-region: rect(0, 20px, 20px, 0);
margin: -2px -2px;
margin-top: 1px;
margin-bottom: 1px;
-moz-margin-start: 4px;
}
.searchbar-search-button[addengines="true"] {

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

@ -290,6 +290,7 @@ if test -n "$gonkdir" ; then
AC_SUBST(MOZ_AUDIO_OFFLOAD)
AC_DEFINE(MOZ_AUDIO_OFFLOAD)
MOZ_FMP4=
MOZ_B2G_CAMERA=1
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEDROID=1
if test -d "$gonkdir/system/bluetoothd"; then

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

@ -40,6 +40,7 @@
#include "AutoRwLock.h"
#include "GonkCameraHwMgr.h"
#include "GonkRecorderProfiles.h"
#include "GrallocImages.h"
#include "CameraCommon.h"
#include "GonkCameraParameters.h"
#include "DeviceStorageFileDescriptor.h"

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

@ -183,7 +183,13 @@ GonkCameraHardware::Init()
#if defined(MOZ_WIDGET_GONK)
#if ANDROID_VERSION >= 19
#if ANDROID_VERSION >= 21
sp<IGraphicBufferProducer> producer;
sp<IGonkGraphicBufferConsumer> consumer;
GonkBufferQueue::createBufferQueue(&producer, &consumer);
mNativeWindow = new GonkNativeWindow(consumer, GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
mCamera->setPreviewTarget(producer);
#elif ANDROID_VERSION >= 19
mNativeWindow = new GonkNativeWindow(GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
sp<GonkBufferQueue> bq = mNativeWindow->getBufferQueue();
bq->setSynchronousMode(false);

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

@ -1154,7 +1154,11 @@ status_t GonkRecorder::setupMediaSource(
return err;
}
*mediaSource = cameraSource;
#if ANDROID_VERSION >= 21
} else if (mVideoSource == VIDEO_SOURCE_SURFACE) {
#else
} else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
#endif
return BAD_VALUE;
} else {
return INVALID_OPERATION;

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

@ -29,6 +29,7 @@ DEFINE_KEYNAME_WITH_SAME_NAME(Unidentified)
* Our Internal Key Values (must have "Moz" prefix)
*****************************************************************************/
DEFINE_KEYNAME_INTERNAL(PrintableKey, "MozPrintableKey")
DEFINE_KEYNAME_INTERNAL(HomeScreen, "MozHomeScreen")
/******************************************************************************
* Modifier Keys

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

@ -2195,7 +2195,11 @@ TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId)
{
if (aEvent.mClass == eWheelEventClass) {
if (aEvent.mClass == eWheelEventClass
#ifdef MOZ_WIDGET_GONK
|| aEvent.mClass == eTouchEventClass
#endif
) {
// Wheel events must be sent to APZ directly from the widget. New APZ-
// aware events should follow suit and move there as well. However, we
// do need to inform the child process of the correct target and block

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

@ -1059,15 +1059,16 @@ AutoMounter::UpdateState()
vol->StartUnmount(mResponseCallback);
return; // UpdateState will be called again when the Unmount command completes
}
case nsIVolume::STATE_IDLE: {
LOG("UpdateState: Volume %s is nsIVolume::STATE_IDLE", vol->NameStr());
case nsIVolume::STATE_IDLE:
case nsIVolume::STATE_MOUNT_FAIL: {
LOG("UpdateState: Volume %s is %s", vol->NameStr(), vol->StateStr());
if (vol->IsFormatting() && !vol->IsFormatRequested()) {
vol->SetFormatRequested(false);
LOG("UpdateState: Mounting %s", vol->NameStr());
vol->StartMount(mResponseCallback);
break;
}
if (tryToShare && vol->IsSharingEnabled()) {
if (tryToShare && vol->IsSharingEnabled() && volState == nsIVolume::STATE_IDLE) {
// Volume is unmounted. We can go ahead and share.
LOG("UpdateState: Sharing %s", vol->NameStr());
vol->StartShare(mResponseCallback);

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

@ -337,11 +337,13 @@ Volume::SetState(Volume::STATE aNewState)
break;
case nsIVolume::STATE_MOUNTED:
case nsIVolume::STATE_MOUNT_FAIL:
mMountRequested = false;
mIsFormatting = false;
mIsSharing = false;
mIsUnmounting = false;
break;
case nsIVolume::STATE_FORMATTING:
mFormatRequested = false;
mIsFormatting = true;
@ -541,7 +543,12 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
// then the AutoMounter will set the volume as STATE_MOUNTED.
SetState(nsIVolume::STATE_CHECKMNT);
} else {
SetState(newState);
if (State() == nsIVolume::STATE_CHECKING && newState == nsIVolume::STATE_IDLE) {
LOG("Mount of volume '%s' failed", NameStr());
SetState(nsIVolume::STATE_MOUNT_FAIL);
} else {
SetState(newState);
}
}
break;
}

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

@ -5,10 +5,12 @@
#include "nsISupports.idl"
#include "nsIVolumeStat.idl"
[scriptable, uuid(946B5334-6EC9-11E4-8689-F3061E5D46B0)]
[scriptable, uuid(EE752CB8-8FD7-11E4-A602-70221D5D46B0)]
interface nsIVolume : nsISupports
{
// These MUST match the states from android's system/vold/Volume.h header
// Note: Changes made to the STATE_xxx names should also be reflected in the
// NS_VolumeStateStr function found in Volume.cpp
const long STATE_INIT = -1;
const long STATE_NOMEDIA = 0;
const long STATE_IDLE = 1;
@ -20,6 +22,7 @@ interface nsIVolume : nsISupports
const long STATE_SHARED = 7;
const long STATE_SHAREDMNT = 8;
const long STATE_CHECKMNT = 100;
const long STATE_MOUNT_FAIL = 101;
// The name of the volume. Often there is only one volume, called sdcard.
// But some phones support multiple volumes.

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

@ -38,6 +38,7 @@ NS_VolumeStateStr(int32_t aState)
case nsIVolume::STATE_SHARED: return "Shared";
case nsIVolume::STATE_SHAREDMNT: return "Shared-Mounted";
case nsIVolume::STATE_CHECKMNT: return "Check-Mounted";
case nsIVolume::STATE_MOUNT_FAIL: return "Mount-Fail";
}
return "???";
}

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

@ -89,7 +89,7 @@ APZCTreeManager::CalculatePendingDisplayPort(
APZCTreeManager::APZCTreeManager()
: mInputQueue(new InputQueue()),
mTreeLock("APZCTreeLock"),
mHitResultForInputBlock(NoApzcHit),
mHitResultForInputBlock(HitNothing),
mRetainedTouchIdentifier(-1),
mTouchCount(0),
mApzcTreeLog("apzctree")
@ -561,7 +561,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
}
nsEventStatus result = nsEventStatus_eIgnore;
Matrix4x4 transformToApzc;
HitTestResult hitResult = NoApzcHit;
HitTestResult hitResult = HitNothing;
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
@ -572,7 +572,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin,
&hitResult);
if (apzc) {
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc);
wheelInput.mLocalOrigin =
@ -580,7 +580,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ hitResult == ApzcHitRegion,
/* aTargetConfirmed = */ hitResult == HitLayer,
wheelInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -595,7 +595,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
&hitResult);
if (apzc) {
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc);
panInput.mLocalPanStartPoint = TransformTo<ParentLayerPixel>(
transformToApzc, panInput.mPanStartPoint);
@ -603,7 +603,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
transformToApzc, panInput.mPanDisplacement, panInput.mPanStartPoint);
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ hitResult == ApzcHitRegion,
/* aTargetConfirmed = */ hitResult == HitLayer,
panInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -620,13 +620,13 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
&hitResult);
if (apzc) {
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc);
pinchInput.mLocalFocusPoint = TransformTo<ParentLayerPixel>(
transformToApzc, pinchInput.mFocusPoint);
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ hitResult == ApzcHitRegion,
/* aTargetConfirmed = */ hitResult == HitLayer,
pinchInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -641,13 +641,13 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
&hitResult);
if (apzc) {
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
transformToApzc = GetScreenToApzcTransform(apzc);
tapInput.mLocalPoint = TransformTo<ParentLayerPixel>(
transformToApzc, tapInput.mPoint);
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ hitResult == ApzcHitRegion,
/* aTargetConfirmed = */ hitResult == HitLayer,
tapInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -658,7 +658,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
break;
}
}
if (hitResult == OverscrolledApzc) {
if (hitResult == HitOverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault;
}
return result;
@ -715,9 +715,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// NS_TOUCH_START event contains all active touches of the current
// session thus resetting mTouchCount.
mTouchCount = aInput.mTouches.Length();
mHitResultForInputBlock = NoApzcHit;
mHitResultForInputBlock = HitNothing;
nsRefPtr<AsyncPanZoomController> apzc = GetTouchInputBlockAPZC(aInput, &mHitResultForInputBlock);
// XXX the following check assumes mHitResultForInputBlock == ApzcHitRegion
// XXX the following check assumes mHitResultForInputBlock == HitLayer
// (and that mApzcForInputBlock was the confirmed target of the previous
// input block). Eventually it would be better to move this into InputQueue
// and have it auto-generated when we start processing events in a new
@ -769,7 +769,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
nsEventStatus result = nsEventStatus_eIgnore;
if (mApzcForInputBlock) {
MOZ_ASSERT(mHitResultForInputBlock == ApzcHitRegion || mHitResultForInputBlock == ApzcContentRegion);
MOZ_ASSERT(mHitResultForInputBlock == HitLayer || mHitResultForInputBlock == HitDispatchToContentRegion);
mApzcForInputBlock->GetGuid(aOutTargetGuid);
// For computing the input for the APZC, used the cached transform.
@ -782,7 +782,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
transformToApzc, ScreenPoint(touchData.mScreenPoint));
}
result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
/* aTargetConfirmed = */ mHitResultForInputBlock == ApzcHitRegion,
/* aTargetConfirmed = */ mHitResultForInputBlock == HitLayer,
aInput, aOutInputBlockId);
// For computing the event to pass back to Gecko, use the up-to-date transforms.
@ -797,7 +797,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
outTransform, touchData.mScreenPoint);
}
}
if (mHitResultForInputBlock == OverscrolledApzc) {
if (mHitResultForInputBlock == HitOverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault;
}
@ -817,7 +817,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// don't keep dangling references and leak things.
if (mTouchCount == 0) {
mApzcForInputBlock = nullptr;
mHitResultForInputBlock = NoApzcHit;
mHitResultForInputBlock = HitNothing;
mRetainedTouchIdentifier = -1;
}
@ -848,18 +848,18 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
// Transform the refPoint.
// If the event hits an overscrolled APZC, instruct the caller to ignore it.
HitTestResult hitResult = NoApzcHit;
HitTestResult hitResult = HitNothing;
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y),
&hitResult);
if (apzc) {
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
apzc->GetGuid(aOutTargetGuid);
Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
}
if (hitResult == OverscrolledApzc) {
if (hitResult == HitOverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault;
}
return result;
@ -1215,13 +1215,13 @@ already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHitResult)
{
MonitorAutoLock lock(mTreeLock);
HitTestResult hitResult = NoApzcHit;
HitTestResult hitResult = HitNothing;
ParentLayerPoint point = ViewAs<ParentLayerPixel>(aPoint,
PixelCastJustification::ScreenIsParentLayerForRoot);
nsRefPtr<AsyncPanZoomController> target = GetAPZCAtPoint(mRootNode, point, &hitResult);
// If we are in an overscrolled APZC, we should be returning nullptr.
MOZ_ASSERT(!(target && (hitResult == OverscrolledApzc)));
MOZ_ASSERT(!(target && (hitResult == HitOverscrolledApzc)));
if (aOutHitResult) {
*aOutHitResult = hitResult;
}
@ -1366,25 +1366,25 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
ParentLayerPoint childPoint = ViewAs<ParentLayerPixel>(hitTestPointForChildLayers.ref(),
PixelCastJustification::MovingDownToChildren);
result = GetAPZCAtPoint(node->GetLastChild(), childPoint, aOutHitResult);
if (*aOutHitResult == OverscrolledApzc) {
if (*aOutHitResult == HitOverscrolledApzc) {
// We matched an overscrolled APZC, abort.
return nullptr;
}
}
// If we didn't match anything in the subtree, check |node|.
if (!result) {
if (*aOutHitResult == HitNothing) {
APZCTM_LOG("Testing ParentLayer point %s (Layer %s) against node %p\n",
Stringify(aHitTestPoint).c_str(),
hitTestPointForChildLayers ? Stringify(hitTestPointForChildLayers.ref()).c_str() : "nil",
node);
HitTestResult hitResult = node->HitTest(aHitTestPoint);
if (hitResult != HitTestResult::NoApzcHit) {
if (hitResult != HitTestResult::HitNothing) {
result = node->GetNearestContainingApzc();
APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n",
result, node, hitResult);
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
// If event regions are disabled, *aOutHitResult will be ApzcHitRegion
MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
// If event regions are disabled, *aOutHitResult will be HitLayer
*aOutHitResult = hitResult;
}
}
@ -1392,14 +1392,14 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
// If we are overscrolled, and the point matches us or one of our children,
// the result is inside an overscrolled APZC, inform our caller of this
// (callers typically ignore events targeted at overscrolled APZCs).
if (result && apzc && apzc->IsOverscrolled()) {
if (*aOutHitResult != HitNothing && apzc && apzc->IsOverscrolled()) {
APZCTM_LOG("Result is inside overscrolled APZC %p\n", apzc);
*aOutHitResult = OverscrolledApzc;
*aOutHitResult = HitOverscrolledApzc;
return nullptr;
}
if (result) {
if (!gfxPrefs::LayoutEventRegionsEnabled()) {
if (*aOutHitResult != HitNothing) {
if (result && !gfxPrefs::LayoutEventRegionsEnabled()) {
// When event-regions are disabled, we treat scrollinfo layers as
// regular scrollable layers. Unfortunately, their "hit region" (which
// we create from the composition bounds) is their full area, and they

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

@ -11,10 +11,10 @@ namespace mozilla {
namespace layers {
enum HitTestResult {
NoApzcHit,
ApzcHitRegion,
ApzcContentRegion,
OverscrolledApzc,
HitNothing,
HitLayer,
HitDispatchToContentRegion,
HitOverscrolledApzc,
};
}

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

@ -195,24 +195,24 @@ HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
// If there's no APZC, then we do need to check against the mEventRegions
// (which contains the layer's visible region) for obscuration purposes.
if (!gfxPrefs::LayoutEventRegionsEnabled() && GetApzc()) {
return HitTestResult::ApzcHitRegion;
return HitTestResult::HitLayer;
}
// convert into Layer coordinate space
Maybe<LayerPoint> pointInLayerPixels = Untransform(aPoint);
if (!pointInLayerPixels) {
return HitTestResult::NoApzcHit;
return HitTestResult::HitNothing;
}
LayerIntPoint point = RoundedToInt(pointInLayerPixels.ref());
// test against event regions in Layer coordinate space
if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
return HitTestResult::NoApzcHit;
return HitTestResult::HitNothing;
}
if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) {
return HitTestResult::ApzcContentRegion;
return HitTestResult::HitDispatchToContentRegion;
}
return HitTestResult::ApzcHitRegion;
return HitTestResult::HitLayer;
}
void

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

@ -2551,6 +2551,25 @@ protected:
manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
rootApzc = ApzcOf(root);
}
void CreateBug1119497LayerTree() {
const char* layerTreeSyntax = "c(tt)";
// LayerID 0 12
// 0 is the root and doesn't have an APZC
// 1 is behind 2 and does have an APZC
// 2 entirely covers 1 and should take all the input events
nsIntRegion layerVisibleRegions[] = {
nsIntRegion(nsIntRect(0, 0, 100, 100)),
nsIntRegion(nsIntRect(0, 0, 100, 100)),
nsIntRegion(nsIntRect(0, 0, 100, 100)),
};
root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
}
};
TEST_F(APZEventRegionsTester, HitRegionImmediateResponse) {
@ -2640,7 +2659,20 @@ TEST_F(APZEventRegionsTester, Obscuration) {
HitTestResult result;
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result);
EXPECT_EQ(child, hit.get());
EXPECT_EQ(HitTestResult::ApzcHitRegion, result);
EXPECT_EQ(HitTestResult::HitLayer, result);
}
TEST_F(APZEventRegionsTester, Bug1119497) {
SCOPED_GFX_PREF(LayoutEventRegionsEnabled, bool, true);
CreateBug1119497LayerTree();
HitTestResult result;
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 50), &result);
// We should hit layers[2], so |result| will be HitLayer but there's no
// actual APZC in that parent chain, so |hit| should be nullptr.
EXPECT_EQ(nullptr, hit.get());
EXPECT_EQ(HitTestResult::HitLayer, result);
}
class TaskRunMetrics {

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

@ -859,14 +859,14 @@ abstract class BaseTest extends BaseRobocopTest {
Actions.EventExpecter pageShowExpecter = mActions.expectGeckoEvent("Content:PageShow");
if (devType.equals("tablet")) {
Element fwdBtn = mDriver.findElement(getActivity(), R.id.forward);
fwdBtn.click();
mSolo.waitForView(R.id.forward);
mSolo.clickOnView(mSolo.getView(R.id.forward));
} else {
mActions.sendSpecialKey(Actions.SpecialKey.MENU);
waitForText("^New Tab$");
if (!osVersion.equals("2.x")) {
Element fwdBtn = mDriver.findElement(getActivity(), R.id.forward);
fwdBtn.click();
mSolo.waitForView(R.id.forward);
mSolo.clickOnView(mSolo.getView(R.id.forward));
} else {
mSolo.clickOnText("^Forward$");
}
@ -879,14 +879,14 @@ abstract class BaseTest extends BaseRobocopTest {
public void reload() {
if (devType.equals("tablet")) {
Element reloadBtn = mDriver.findElement(getActivity(), R.id.reload);
reloadBtn.click();
mSolo.waitForView(R.id.reload);
mSolo.clickOnView(mSolo.getView(R.id.reload));
} else {
mActions.sendSpecialKey(Actions.SpecialKey.MENU);
waitForText("^New Tab$");
if (!osVersion.equals("2.x")) {
Element reloadBtn = mDriver.findElement(getActivity(), R.id.reload);
reloadBtn.click();
mSolo.waitForView(R.id.reload);
mSolo.clickOnView(mSolo.getView(R.id.reload));
} else {
mSolo.clickOnText("^Reload$");
}

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

@ -32,17 +32,52 @@ function copyStringAndToast(string, notifyString) {
}
let Passwords = {
_logins: [],
_getLogins: function() {
let logins;
try {
logins = Services.logins.getAllLogins();
} catch(e) {
// Master password was not entered
debug("Master password permissions error: " + e);
logins = [];
}
logins.sort((a, b) => a.hostname.localeCompare(b.hostname));
return this._logins = logins;
},
init: function () {
window.addEventListener("popstate", this , false);
Services.obs.addObserver(this, "passwordmgr-storage-changed", false);
this._loadList();
this._loadList(this._getLogins());
document.getElementById("copyusername-btn").addEventListener("click", this._copyUsername.bind(this), false);
document.getElementById("copypassword-btn").addEventListener("click", this._copyPassword.bind(this), false);
document.getElementById("details-header").addEventListener("click", this._openLink.bind(this), false);
let filterInput = document.getElementById("filter-input");
let filterContainer = document.getElementById("filter-input-container");
filterInput.addEventListener("input", this._filter.bind(this), false);
filterInput.addEventListener("blur", (event) => {
filterContainer.setAttribute("hidden", true);
});
document.getElementById("filter-button").addEventListener("click", (event) => {
filterContainer.removeAttribute("hidden");
filterInput.focus();
}, false);
document.getElementById("filter-clear").addEventListener("click", (event) => {
filterInput.blur();
filterInput.value = "";
this._loadList(this._logins);
}, false);
this._showList();
},
@ -51,27 +86,16 @@ let Passwords = {
window.removeEventListener("popstate", this, false);
},
_loadList: function () {
let logins;
try {
logins = Services.logins.getAllLogins();
} catch(e) {
// Master password was not entered
debug("Master password permissions error: " + e);
return;
}
logins.forEach(login => login.QueryInterface(Ci.nsILoginMetaInfo));
logins.sort((a, b) => a.hostname.localeCompare(b.hostname));
// Clear all content before filling the logins
_loadList: function (logins) {
let list = document.getElementById("logins-list");
list.innerHTML = "";
let newList = list.cloneNode(false);
logins.forEach(login => {
let item = this._createItemForLogin(login);
list.appendChild(item);
newList.appendChild(item);
});
list.parentNode.replaceChild(newList, list);
},
_showList: function () {
@ -158,7 +182,7 @@ let Passwords = {
switch(topic) {
case "passwordmgr-storage-changed": {
// Reload passwords content.
this._loadList();
this._loadList(this._getLogins());
break;
}
}
@ -217,6 +241,26 @@ let Passwords = {
let url = clickEvent.currentTarget.getAttribute("link");
let BrowserApp = gChromeWin.BrowserApp;
BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id });
},
_filter: function(event) {
let value = event.target.value;
let logins = this._logins.filter((login) => {
if (login.hostname.toLowerCase().indexOf(value) != -1) {
return true;
}
if (login.username &&
login.username.toLowerCase().indexOf(value) != -1) {
return true;
}
if (login.httpRealm &&
login.httpRealm.toLowerCase().indexOf(value) != -1) {
return true;
}
return false;
});
this._loadList(logins);
}
};

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

@ -23,6 +23,9 @@
<body dir="&locale.dir;">
<div id="passwords-header" class="header">
<div>&aboutPasswords.title;</div>
<ul class="toolbar-buttons">
<li id="filter-button"></li>
</ul>
</div>
<div id="logins-list" class="list" hidden="true">
</div>
@ -43,5 +46,9 @@
</div>
</div>
</div>
<div id="filter-input-container" hidden="true">
<input id="filter-input" type="search"/>
<div id="filter-clear"></div>
</div>
</body>
</html>

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

@ -16,13 +16,14 @@ Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import('resource://gre/modules/Payment.jsm');
Cu.import("resource://gre/modules/NotificationDB.jsm");
Cu.import("resource://gre/modules/SpatialNavigation.jsm");
// TODO: Lazy load this based on a message...?
Cu.import("resource://gre/modules/DownloadNotifications.jsm");
#ifdef ACCESSIBILITY
Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
#endif
XPCOMUtils.defineLazyModuleGetter(this, "DownloadNotifications",
"resource://gre/modules/DownloadNotifications.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
@ -372,6 +373,7 @@ var BrowserApp = {
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
CastingApps.init();
DownloadNotifications.init();
// Delay this a minute because there's no rush
setTimeout(() => {
@ -466,7 +468,6 @@ var BrowserApp = {
NativeWindow.init();
LightWeightThemeWebInstaller.init();
DownloadNotifications.init();
FormAssistant.init();
IndexedDB.init();
HealthReportStatusListener.init();

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

@ -1,6 +1,10 @@
/* 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/. */
%filter substitution
%include defines.inc
.hidden {
display: none;
}
@ -30,3 +34,71 @@
/* hostname is not localized, so keep the margin on the left side */
margin-left: .67em;
}
.toolbar-buttons {
list-style: none;
}
.toolbar-buttons > li {
background-position: center;
background-size: 32px 32px;
background-repeat: no-repeat;
height: 32px;
width: 32px;
margin: 0 15px;
}
#filter-input-container {
position: fixed;
bottom: 0;
width: 100%;
padding: 10px 0;
display: flex;
background: @color_about_background@;
border-top: 2px solid @color_about_item_border@;
}
#filter-input-container[hidden] {
display: none;
}
#filter-input {
flex: 1;
padding: 5px;
-moz-margin-start: 10px;
border-radius: 3px;
}
#filter-button {
background-image: url("resource://android/res/drawable-mdpi-v4/ab_search.png");
}
#filter-clear {
background-image: url("resource://android/res/drawable-mdpi-v4/close_edit_mode_light.png");
background-position: center;
background-size: 12px 12px;
background-repeat: no-repeat;
height: 32px;
width: 32px;
margin: 0 5px;
}
@media screen and (min-resolution: 1.25dppx) {
#filter-button {
background-image: url("resource://android/res/drawable-hdpi-v4/ab_search.png");
}
#filter-clear {
background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png");
}
}
@media screen and (min-resolution: 2dppx) {
#filter-button {
background-image: url("resource://android/res/drawable-xhdpi-v4/ab_search.png");
}
#filter-clear {
background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png");
}
}

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

@ -36,7 +36,7 @@ chrome.jar:
% override chrome://global/skin/netError.css chrome://browser/skin/netError.css
#ifdef NIGHTLY_BUILD
skin/aboutPasswords.css (aboutPasswords.css)
* skin/aboutPasswords.css (aboutPasswords.css)
#endif
skin/images/search.png (images/search.png)

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

@ -80,6 +80,10 @@
background: url("chrome://browser/skin/images/exitfullscreen-hdpi.png") no-repeat center;
}
.controlBar[fullscreen-unavailable] .fullscreenButton {
display: none;
}
/* bars */
.scrubberStack {
width: 100%;

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

@ -32,7 +32,7 @@ REPOSITORY_PATH_PREFIX = 'python/mozboot'
REPOSITORY_PATHS = [
'mozboot/__init__.py',
'mozboot/android-ndk-r8e.rb',
'mozboot/android-ndk.rb',
'mozboot/android.py',
'mozboot/base.py',
'mozboot/bootstrap.py',

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

@ -1,5 +1,9 @@
require "formula"
# This is an antiquated version pinned to NDK revision r8e. That's
# the revision Mozilla's automation currently uses. We could push
# this to https://github.com/Homebrew/homebrew-versions if there's a
# problem shipping it locally.
class AndroidNdk < Formula
homepage "http://developer.android.com/sdk/ndk/index.html"

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

@ -324,11 +324,16 @@ class OSXBootstrapper(BaseBootstrapper):
def ensure_homebrew_mobile_android_packages(self):
import android
# If we're run from a downloaded bootstrap.py, then android-ndk.rb is
# fetched into a temporary directory. This finds that directory.
import inspect
path_to_android = os.path.abspath(os.path.dirname(inspect.getfile(android)))
# We don't need wget because we install the Android SDK and NDK from
# packages. If we used the android.py module, we'd need wget.
packages = [
('android-sdk', 'android-sdk'),
('android-ndk', 'android-ndk-r8e.rb'), # This is a locally provided brew formula!
('android-ndk', os.path.join(path_to_android, 'android-ndk.rb')), # This is a locally provided brew formula!
('ant', 'ant'),
('brew-cask', 'caskroom/cask/brew-cask'), # For installing Java later.
]

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

@ -37,8 +37,8 @@
}
function loadedmetadata(event) {
var fullscreenButton = findElementByAttribute(video, 'class', 'fullscreenButton');
is(fullscreenButton.hidden, true, 'Fullscreen button is hidden');
var controlBar = findElementByAttribute(video, "class", "controlBar");
is(controlBar.getAttribute("fullscreen-unavailable"), "true", "Fullscreen button is hidden");
SimpleTest.finish();
}

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

@ -21,6 +21,10 @@
-moz-user-focus: none;
}
.controlBar[fullscreen-unavailable] > .fullscreenButton {
display: none;
}
.mediaControlsFrame {
direction: ltr;
/* Prevent unwanted style inheritance. See bug 554717. */

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

@ -343,12 +343,7 @@
get isAudioOnly() { return this._isAudioOnly; },
set isAudioOnly(val) {
this._isAudioOnly = val;
if (this._isAudioOnly) {
this.controlBar.setAttribute("audio-only", true);
} else {
this.controlBar.removeAttribute("audio-only");
}
this.adjustControlSize();
this.setFullscreenButtonState();
if (!this.isTopLevelSyntheticDocument)
return;
@ -1065,9 +1060,12 @@
setFullscreenButtonState : function () {
if (this.isAudioOnly || !document.mozFullScreenEnabled) {
this.fullscreenButton.hidden = true;
this.controlBar.setAttribute("fullscreen-unavailable", true);
this.adjustControlSize();
return;
}
this.controlBar.removeAttribute("fullscreen-unavailable");
this.adjustControlSize();
var attrName = this.isVideoInFullScreen() ? "exitfullscreenlabel" : "enterfullscreenlabel";
var value = this.fullscreenButton.getAttribute(attrName);
@ -1392,8 +1390,8 @@
this._volumeControlWidth +
this._fullscreenButtonWidth;
let isAudioOnly = this.isAudioOnly;
if (isAudioOnly) {
let isFullscreenUnavailable = this.controlBar.hasAttribute("fullscreen-unavailable");
if (isFullscreenUnavailable) {
// When the fullscreen button is hidden we add margin-end to the volume stack.
minWidthAllControls -= this._fullscreenButtonWidth - this._volumeStackMarginEnd;
}
@ -1401,6 +1399,7 @@
let minHeightForControlBar = this._controlBarHeight;
let minWidthOnlyPlayPause = this._playButtonWidth + this._muteButtonWidth;
let isAudioOnly = this.isAudioOnly;
let videoHeight = isAudioOnly ? minHeightForControlBar : this.video.clientHeight;
let videoWidth = isAudioOnly ? minWidthAllControls : this.video.clientWidth;

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

@ -83,7 +83,6 @@ function WebConsoleActor(aConnection, aParentActor)
this.traits = {
customNetworkRequest: !this._parentIsContentActor,
transferredResponseSize: true,
evaluateJSAsync: true
};
}
@ -1976,7 +1975,6 @@ NetworkEventActor.prototype =
updateType: "responseContent",
mimeType: aContent.mimeType,
contentSize: aContent.text.length,
transferredSize: aContent.transferredSize,
discardResponseBody: aDiscardedResponseBody,
};

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

@ -4,7 +4,7 @@
"use strict";
const {Cc, Ci, Cu, Cr} = require("chrome");
const {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -57,47 +57,13 @@ function NetworkResponseListener(aOwner, aHttpActivity)
this.receivedData = "";
this.httpActivity = aHttpActivity;
this.bodySize = 0;
let channel = this.httpActivity.channel;
this._wrappedNotificationCallbacks = channel.notificationCallbacks;
channel.notificationCallbacks = this;
}
exports.NetworkResponseListener = NetworkResponseListener;
NetworkResponseListener.prototype = {
QueryInterface:
XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIInputStreamCallback,
Ci.nsIRequestObserver, Ci.nsIInterfaceRequestor,
Ci.nsISupports]),
// nsIInterfaceRequestor implementation
/**
* This object implements nsIProgressEventSink, but also needs to forward
* interface requests to the notification callbacks of other objects.
*/
getInterface(iid) {
if (iid.equals(Ci.nsIProgressEventSink)) {
return this;
}
if (this._wrappedNotificationCallbacks) {
return this._wrappedNotificationCallbacks.getInterface(iid);
}
throw Cr.NS_ERROR_NO_INTERFACE;
},
/**
* Forward notifications for interfaces this object implements, in case other
* objects also implemented them.
*/
_forwardNotification(iid, method, args) {
if (!this._wrappedNotificationCallbacks) {
return;
}
try {
let impl = this._wrappedNotificationCallbacks.getInterface(iid);
impl[method].apply(impl, args);
} catch(e if e.result == Cr.NS_ERROR_NO_INTERFACE) {}
},
Ci.nsIRequestObserver, Ci.nsISupports]),
/**
* This NetworkResponseListener tracks the NetworkMonitor.openResponses object
@ -106,12 +72,6 @@ NetworkResponseListener.prototype = {
*/
_foundOpenResponse: false,
/**
* If the channel already had notificationCallbacks, hold them here internally
* so that we can forward getInterface requests to that object.
*/
_wrappedNotificationCallbacks: null,
/**
* The response listener owner.
*/
@ -134,15 +94,10 @@ NetworkResponseListener.prototype = {
receivedData: null,
/**
* The uncompressed, decoded response body size.
* The network response body size.
*/
bodySize: null,
/**
* Response body size on the wire, potentially compressed / encoded.
*/
transferredSize: null,
/**
* The nsIRequest we are started for.
*/
@ -222,23 +177,6 @@ NetworkResponseListener.prototype = {
this.sink.outputStream.close();
},
// nsIProgressEventSink implementation
/**
* Handle progress event as data is transferred. This is used to record the
* size on the wire, which may be compressed / encoded.
*/
onProgress: function(request, context, progress, progressMax) {
this.transferredSize = progress;
// Need to forward as well to keep things like Download Manager's progress
// bar working properly.
this._forwardNotification(Ci.nsIProgressEventSink, 'onProgress', arguments);
},
onStatus: function () {
this._forwardNotification(Ci.nsIProgressEventSink, 'onStatus', arguments);
},
/**
* Find the open response object associated to the current request. The
* NetworkMonitor._httpResponseExaminer() method saves the response headers in
@ -321,7 +259,6 @@ NetworkResponseListener.prototype = {
};
response.size = response.text.length;
response.transferredSize = this.transferredSize;
try {
response.mimeType = this.request.contentType;
@ -342,7 +279,6 @@ NetworkResponseListener.prototype = {
this.httpActivity.owner.
addResponseContent(response, this.httpActivity.discardResponseBody);
this._wrappedNotificationCallbacks = null;
this.httpActivity.channel = null;
this.httpActivity.owner = null;
this.httpActivity = null;

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

@ -92,7 +92,7 @@
background-clip: content-box;
}
.controlBar[audio-only] > .volumeStack {
.controlBar[fullscreen-unavailable] > .volumeStack {
/* This value is duplicated in the videocontrols.xml adjustControlSize function. */
-moz-margin-end: 8px;
}

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

@ -92,7 +92,7 @@
background-clip: content-box;
}
.controlBar[audio-only] > .volumeStack {
.controlBar[fullscreen-unavailable] > .volumeStack {
/* This value is duplicated in the videocontrols.xml adjustControlSize function. */
-moz-margin-end: 8px;
}

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

@ -115,6 +115,48 @@ MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const
return event;
}
WidgetMouseEvent
MultiTouchInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
{
NS_ABORT_IF_FALSE(NS_IsMainThread(),
"Can only convert To WidgetMouseEvent on main thread");
uint32_t mouseEventType = NS_EVENT_NULL;
switch (mType) {
case MultiTouchInput::MULTITOUCH_START:
mouseEventType = NS_MOUSE_BUTTON_DOWN;
break;
case MultiTouchInput::MULTITOUCH_MOVE:
mouseEventType = NS_MOUSE_MOVE;
break;
case MultiTouchInput::MULTITOUCH_CANCEL:
case MultiTouchInput::MULTITOUCH_END:
mouseEventType = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
break;
}
WidgetMouseEvent event(true, mouseEventType, aWidget,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
const SingleTouchData& firstTouch = mTouches[0];
event.refPoint.x = firstTouch.mScreenPoint.x;
event.refPoint.y = firstTouch.mScreenPoint.y;
event.time = mTime;
event.button = WidgetMouseEvent::eLeftButton;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.modifiers = modifiers;
if (mouseEventType != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
return event;
}
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
// the B2G emulator we can only receive mouse events, but we need to be able
// to pan correctly. To do this, we convert the events into a format that the

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

@ -216,6 +216,7 @@ public:
explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because
// on the B2G emulator we can only receive mouse events, but we need to be

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

@ -1289,6 +1289,13 @@ KEY_MAP_GTK (VideoModeNext, GDK_Next_VMode)
KEY_MAP_WIN (ZoomToggle, VK_ZOOM)
KEY_MAP_QT (ZoomToggle, Qt::Key_Zoom)
/******************************************************************************
* Keys not defined by any standards
******************************************************************************/
// HomeScreen
KEY_MAP_ANDROID (HomeScreen, AKEYCODE_HOME)
#undef KEY_MAP_WIN
#undef KEY_MAP_WIN_JPN
#undef KEY_MAP_WIN_KOR

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

@ -24,7 +24,6 @@
#include "gfxPrefs.h"
#include "libui/Input.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Mutex.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TouchEvents.h"
@ -333,21 +332,6 @@ GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp a
aOutTouch.mTimeStamp = sampleTime;
}
// Some touch events get sent as mouse events. If APZ doesn't capture the event
// and if a touch only has 1 touch input, we can send a mouse event.
void
GeckoTouchDispatcher::DispatchMouseEvent(MultiTouchInput& aMultiTouch,
bool aForwardToChildren)
{
WidgetMouseEvent mouseEvent = ToWidgetMouseEvent(aMultiTouch, nullptr);
if (mouseEvent.message == NS_EVENT_NULL) {
return;
}
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = !aForwardToChildren;
nsWindow::DispatchInputEvent(mouseEvent);
}
static bool
IsExpired(const MultiTouchInput& aTouch)
{
@ -372,9 +356,7 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
return;
}
bool captured = false;
WidgetTouchEvent event = aMultiTouch.ToWidgetTouchEvent(nullptr);
nsEventStatus status = nsWindow::DispatchInputEvent(event, &captured);
nsWindow::DispatchTouchInput(aMultiTouch);
if (mEnabledUniformityInfo && profiler_is_active()) {
const char* touchAction = "Invalid";
@ -395,54 +377,6 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
TouchDataPayload* payload = new TouchDataPayload(touchPoint);
PROFILER_MARKER_PAYLOAD(touchAction, payload);
}
if (!captured && (aMultiTouch.mTouches.Length() == 1)) {
bool forwardToChildren = status != nsEventStatus_eConsumeNoDefault;
DispatchMouseEvent(aMultiTouch, forwardToChildren);
}
}
WidgetMouseEvent
GeckoTouchDispatcher::ToWidgetMouseEvent(const MultiTouchInput& aMultiTouch,
nsIWidget* aWidget) const
{
NS_ABORT_IF_FALSE(NS_IsMainThread(),
"Can only convert To WidgetMouseEvent on main thread");
uint32_t mouseEventType = NS_EVENT_NULL;
switch (aMultiTouch.mType) {
case MultiTouchInput::MULTITOUCH_START:
mouseEventType = NS_MOUSE_BUTTON_DOWN;
break;
case MultiTouchInput::MULTITOUCH_MOVE:
mouseEventType = NS_MOUSE_MOVE;
break;
case MultiTouchInput::MULTITOUCH_CANCEL:
case MultiTouchInput::MULTITOUCH_END:
mouseEventType = NS_MOUSE_BUTTON_UP;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
break;
}
WidgetMouseEvent event(true, mouseEventType, aWidget,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
const SingleTouchData& firstTouch = aMultiTouch.mTouches[0];
event.refPoint.x = firstTouch.mScreenPoint.x;
event.refPoint.y = firstTouch.mScreenPoint.y;
event.time = aMultiTouch.mTime;
event.button = WidgetMouseEvent::eLeftButton;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.modifiers = aMultiTouch.modifiers;
if (mouseEventType != NS_MOUSE_MOVE) {
event.clickCount = 1;
}
return event;
}
} // namespace mozilla

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

@ -60,7 +60,6 @@ private:
void SendTouchEvent(MultiTouchInput& aData);
void DispatchMouseEvent(MultiTouchInput& aMultiTouch,
bool aForwardToChildren);
WidgetMouseEvent ToWidgetMouseEvent(const MultiTouchInput& aData, nsIWidget* aWidget) const;
// mTouchQueueLock are used to protect the vector below
// as it is accessed on the vsync thread and main thread

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

@ -47,6 +47,9 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TouchEvents.h"
#include "nsThreadUtils.h"
#include "HwcComposer2D.h"
@ -227,33 +230,89 @@ nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp)
}
}
nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent, bool* aWasCaptured)
/*static*/ nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
{
if (aWasCaptured) {
*aWasCaptured = false;
}
if (!gFocusedWindow) {
return nsEventStatus_eIgnore;
}
gFocusedWindow->UserActivity();
nsEventStatus status;
aEvent.widget = gFocusedWindow;
gFocusedWindow->DispatchEvent(&aEvent, status);
return status;
}
/*static*/ void
nsWindow::DispatchTouchInput(MultiTouchInput& aInput)
{
if (!gFocusedWindow) {
return;
}
gFocusedWindow->UserActivity();
gFocusedWindow->DispatchTouchInputViaAPZ(aInput);
}
void
nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
{
if (!mAPZC) {
// In general mAPZC should not be null, but during initial setup
// it might be, so we handle that case by ignoring touch input there.
return;
}
// First send it through the APZ code
mozilla::layers::ScrollableLayerGuid guid;
uint64_t inputBlockId;
nsEventStatus rv = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
// If the APZ says to drop it, then we drop it
if (rv == nsEventStatus_eConsumeNoDefault) {
return;
}
// Convert it to an event we can send to Gecko
WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
// If there is an event capturing child process, send it directly there.
// This happens if we already sent a touchstart event through the root
// process hit test and it ended up going to a child process. The event
// capturing process should get all subsequent touch events in the same
// event block. In this case the TryCapture call below will return true,
// and the child process will take care of responding to the event as needed
// so we don't need to do anything else here.
if (TabParent* capturer = TabParent::GetEventCapturer()) {
bool captured = capturer->TryCapture(aEvent);
if (aWasCaptured) {
*aWasCaptured = captured;
}
if (captured) {
return nsEventStatus_eConsumeNoDefault;
InputAPZContext context(guid, inputBlockId);
if (capturer->TryCapture(event)) {
return;
}
}
nsEventStatus status;
gFocusedWindow->DispatchEvent(&aEvent, status);
return status;
// If it didn't get captured, dispatch the event into the gecko root process
// for "normal" flow. The event might get sent to the child process still,
// but if it doesn't we need to notify the APZ of various things. All of
// that happens in DispatchEventForAPZ
rv = DispatchEventForAPZ(&event, guid, inputBlockId);
// Finally, if the touch event had only one touch point, generate a mouse
// event for it and send it through the gecko root process.
// Technically we should not need to do this if the touch event was routed
// to the child process, but that seems to expose a bug in B2G where the
// keyboard doesn't go away in some cases.
// Also for now we're dispatching mouse events from all touch events because
// we need this for click events to work in the chrome process. Once we have
// APZ and ChromeProcessController::HandleSingleTap working for the chrome
// process we shouldn't need to do this at all.
if (event.touches.Length() == 1) {
WidgetMouseEvent mouseEvent = aInput.ToWidgetMouseEvent(this);
if (mouseEvent.message != NS_EVENT_NULL) {
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = (rv == nsEventStatus_eConsumeNoDefault);
DispatchEvent(&mouseEvent, rv);
}
}
}
NS_IMETHODIMP

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

@ -16,6 +16,7 @@
#ifndef nsWindow_h
#define nsWindow_h
#include "InputData.h"
#include "nsBaseWidget.h"
#include "nsRegion.h"
#include "nsIIdleServiceInternal.h"
@ -51,8 +52,8 @@ public:
static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
static void DoDraw(void);
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent,
bool* aWasCaptured = nullptr);
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent);
static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
NS_IMETHOD Create(nsIWidget *aParent,
void *aNativeParent,
@ -87,6 +88,7 @@ public:
return NS_OK;
}
virtual nsIntPoint WidgetToScreenOffset();
void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus);
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,