Merge m-c to b2ginbound, a=merge

--HG--
extra : commitid : 7YFKL9gqXNj
This commit is contained in:
Wes Kocher 2015-10-27 14:21:40 -07:00
Родитель 73262739ba bef1f84b4d
Коммит fc06478918
186 изменённых файлов: 2658 добавлений и 1307 удалений

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

@ -936,8 +936,8 @@ chatbox[customSize] {
}
chatbox[customSize="loopChatEnabled"] {
/* 325px as defined per UX */
height: 325px;
/* 430px as defined per UX */
height: 430px;
}
#chat-window[customSize="loopChatEnabled"] {
@ -946,8 +946,13 @@ chatbox[customSize="loopChatEnabled"] {
}
chatbox[customSize="loopChatMessageAppended"] {
/* 400px as defined per UX */
height: 400px;
/* 430px as defined per UX */
height: 430px;
}
chatbox[customSize="loopChatDisabledMessageAppended"] {
/* 388px as defined per UX */
height: 388px;
}
#chat-window[customSize="loopChatMessageAppended"] {
@ -971,8 +976,8 @@ chatbar {
}
chatbar[customSize] > .chatbar-innerbox {
/* 425px to make room for the maximum custom-size chatbox; currently 'loopChatMessageAppended'. */
margin-top: -425px;
/* 450px to make room for the maximum custom-size chatbox; currently 'loopChatMessageAppended'. */
margin-top: -450px;
}
/* Apply crisp rendering for favicons at exactly 2dppx resolution */

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

@ -5136,11 +5136,10 @@
<method name="_getDragTargetTab">
<parameter name="event"/>
<parameter name="isLink"/>
<body><![CDATA[
let tab = event.target.localName == "tab" ? event.target : null;
if (tab &&
(event.type == "drop" || event.type == "dragover") &&
event.dataTransfer.dropEffect == "link") {
if (tab && isLink) {
let boxObject = tab.boxObject;
if (event.screenX < boxObject.screenX + boxObject.width * .25 ||
event.screenX > boxObject.screenX + boxObject.width * .75)
@ -5152,9 +5151,10 @@
<method name="_getDropIndex">
<parameter name="event"/>
<parameter name="isLink"/>
<body><![CDATA[
var tabs = this.childNodes;
var tab = this._getDragTargetTab(event);
var tab = this._getDragTargetTab(event, isLink);
if (window.getComputedStyle(this, null).direction == "ltr") {
for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
@ -5168,13 +5168,13 @@
]]></body>
</method>
<method name="_setEffectAllowedForDataTransfer">
<method name="_getDropEffectForTabDrag">
<parameter name="event"/>
<body><![CDATA[
var dt = event.dataTransfer;
// Disallow dropping multiple items
if (dt.mozItemCount > 1)
return dt.effectAllowed = "none";
return "none";
var types = dt.mozTypesAt(0);
var sourceNode = null;
@ -5190,22 +5190,20 @@
// and vice versa.
if (PrivateBrowsingUtils.isWindowPrivate(window) !=
PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView))
return dt.effectAllowed = "none";
return "none";
if (window.gMultiProcessBrowser !=
sourceNode.ownerDocument.defaultView.gMultiProcessBrowser)
return dt.effectAllowed = "none";
return "none";
let copyModifier = this.tabbrowser.AppConstants.platform == "macosx" ? event.altKey : event.ctrlKey;
return dt.effectAllowed = copyModifier ? "copy" : "move";
return dt.dropEffect == "copy" ? "copy" : "move";
}
}
if (browserDragAndDrop.canDropLink(event)) {
// Here we need to do this manually
return dt.effectAllowed = dt.dropEffect = "link";
return "link";
}
return dt.effectAllowed = "none";
return "none";
]]></body>
</method>
@ -5482,7 +5480,7 @@
]]></handler>
<handler event="dragstart"><![CDATA[
var tab = this._getDragTargetTab(event);
var tab = this._getDragTargetTab(event, false);
if (!tab || this._isCustomizing)
return;
@ -5556,7 +5554,7 @@
]]></handler>
<handler event="dragover"><![CDATA[
var effects = this._setEffectAllowedForDataTransfer(event);
var effects = this._getDropEffectForTabDrag(event);
var ind = this._tabDropIndicator;
if (effects == "" || effects == "none") {
@ -5597,7 +5595,7 @@
this._finishAnimateTabMove();
if (effects == "link") {
let tab = this._getDragTargetTab(event);
let tab = this._getDragTargetTab(event, true);
if (tab) {
if (!this._dragTime)
this._dragTime = Date.now();
@ -5623,7 +5621,7 @@
newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
}
else {
let newIndex = this._getDropIndex(event);
let newIndex = this._getDropIndex(event, effects == "link");
if (newIndex == this.childNodes.length) {
let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
if (ltr)
@ -5654,7 +5652,7 @@
var dt = event.dataTransfer;
var dropEffect = dt.dropEffect;
var draggedTab;
if (dropEffect != "link") { // copy or move
if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) { // tab copy or move
draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
// not our drop then
if (!draggedTab)
@ -5665,7 +5663,7 @@
event.stopPropagation();
if (draggedTab && dropEffect == "copy") {
// copy the dropped tab (wherever it's from)
let newIndex = this._getDropIndex(event);
let newIndex = this._getDropIndex(event, false);
let newTab = this.tabbrowser.duplicateTab(draggedTab);
this.tabbrowser.moveTabTo(newTab, newIndex);
if (draggedTab.parentNode != this || event.shiftKey)
@ -5684,7 +5682,7 @@
// swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between
// windows)
let newIndex = this._getDropIndex(event);
let newIndex = this._getDropIndex(event, false);
let newTab = this.tabbrowser.addTab("about:blank");
let newBrowser = this.tabbrowser.getBrowserForTab(newTab);
let draggedBrowserURL = draggedTab.linkedBrowser.currentURI.spec;
@ -5732,10 +5730,10 @@
if (event.shiftKey)
bgLoad = !bgLoad;
let tab = this._getDragTargetTab(event);
let tab = this._getDragTargetTab(event, true);
if (!tab || dropEffect == "copy") {
// We're adding a new tab.
let newIndex = this._getDropIndex(event);
let newIndex = this._getDropIndex(event, true);
let newTab = this.tabbrowser.loadOneTab(url, {inBackground: bgLoad, allowThirdPartyFixup: true});
this.tabbrowser.moveTabTo(newTab, newIndex);
} else {

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

@ -2,6 +2,7 @@
support-files =
file_dom_notifications.html
[browser_notification_close.js]
[browser_notification_do_not_disturb.js]
[browser_notification_open_settings.js]
[browser_notification_remove_permission.js]

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

@ -0,0 +1,48 @@
"use strict";
let tab;
let notification;
let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
add_task(function* test_notificationClose() {
let pm = Services.perms;
pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
yield BrowserTestUtils.withNewTab({
gBrowser,
url: notificationURL
}, function* dummyTabTask(aBrowser) {
let win = aBrowser.contentWindow.wrappedJSObject;
notification = win.showNotification2();
yield BrowserTestUtils.waitForEvent(notification, "show");
info("Notification alert showing");
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
if (!alertWindow) {
ok(true, "Notifications don't use XUL windows on all platforms.");
notification.close();
return;
}
let alertCloseButton = alertWindow.document.querySelector(".alertCloseButton");
is(alertCloseButton.localName, "toolbarbutton", "close button found");
let promiseBeforeUnloadEvent =
BrowserTestUtils.waitForEvent(alertWindow, "beforeunload");
let closedTime = alertWindow.Date.now();
alertCloseButton.click();
info("Clicked on close button");
let beforeUnloadEvent = yield promiseBeforeUnloadEvent;
ok(true, "Alert should close when the close button is clicked");
let currentTime = alertWindow.Date.now();
// The notification will self-close at 12 seconds, so this checks
// that the notification closed before the timeout.
ok(currentTime - closedTime < 5000,
"Close requested at " + closedTime + ", actually closed at " + currentTime);
});
});
add_task(function* cleanup() {
Services.perms.remove(makeURI(notificationURL), "desktop-notification");
});

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

@ -64,7 +64,7 @@ function onAlertShowing() {
is(doNotDisturbMenuItem.localName, "menuitem", "menuitem found");
alertWindow.addEventListener("beforeunload", onAlertClosing);
doNotDisturbMenuItem.click();
info("Clicked on do-not-disturb menuitem")
info("Clicked on do-not-disturb menuitem");
}
function onAlertClosing(event) {

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

@ -199,10 +199,16 @@ extensions.registerAPI((extension, context) => {
},
onLocationChange(browser, webProgress, request, locationURI, flags) {
if (!webProgress.isTopLevel) {
return;
}
let gBrowser = browser.ownerDocument.defaultView.gBrowser;
let tab = gBrowser.getTabForBrowser(browser);
let tabId = TabManager.getId(tab);
let [needed, changeInfo] = sanitize(extension, {url: locationURI.spec});
let [needed, changeInfo] = sanitize(extension, {
status: webProgress.isLoadingDocument ? "loading" : "complete",
url: locationURI.spec
});
if (needed) {
fire(tabId, changeInfo, TabManager.convert(extension, tab));
}
@ -213,11 +219,12 @@ extensions.registerAPI((extension, context) => {
AllWindowEvents.addListener("TabAttrModified", listener);
AllWindowEvents.addListener("TabPinned", listener);
AllWindowEvents.addListener("TabUnpinned", listener);
return () => {
AllWindowEvents.removeListener("progress", progressListener);
AllWindowEvents.addListener("TabAttrModified", listener);
AllWindowEvents.addListener("TabPinned", listener);
AllWindowEvents.addListener("TabUnpinned", listener);
AllWindowEvents.removeListener("TabAttrModified", listener);
AllWindowEvents.removeListener("TabPinned", listener);
AllWindowEvents.removeListener("TabUnpinned", listener);
};
}).api(),

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

@ -530,7 +530,7 @@ global.AllWindowEvents = {
let listeners = this._listeners.get(type);
listeners.delete(listener);
if (listeners.length == 0) {
if (listeners.size == 0) {
this._listeners.delete(type);
if (this._listeners.size == 0) {
WindowListManager.removeOpenListener(this.openListener);

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

@ -3,6 +3,8 @@ support-files =
head.js
context.html
ctxmenu-image.png
context_tabs_onUpdated_page.html
context_tabs_onUpdated_iframe.html
[browser_ext_simple.js]
[browser_ext_currentWindow.js]
@ -16,6 +18,7 @@ support-files =
[browser_ext_tabs_executeScript.js]
[browser_ext_tabs_query.js]
[browser_ext_tabs_update.js]
[browser_ext_tabs_onUpdated.js]
[browser_ext_tabs_sendMessage.js]
[browser_ext_windows_update.js]
[browser_ext_contentscript_connect.js]

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

@ -1,21 +1,3 @@
function* focusWindow(win)
{
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
if (fm.activeWindow == win) {
return;
}
let promise = new Promise(resolve => {
win.addEventListener("focus", function listener() {
win.removeEventListener("focus", listener, true);
resolve();
}, true);
});
win.focus();
yield promise;
}
function genericChecker()
{
var kind = "background";

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

@ -0,0 +1,78 @@
add_task(function* () {
let win1 = yield BrowserTestUtils.openNewBrowserWindow();
yield focusWindow(win1);
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
"content_scripts": [{
"matches": ["http://mochi.test/*/context_tabs_onUpdated_page.html"],
"js": ["content-script.js"],
"run_at": "document_start"
},],
},
background: function() {
var pageURL = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
var expectedSequence = [
{ status: "loading" },
{ status: "loading", url: pageURL },
{ status: "complete" }
];
var collectedSequence = [];
browser.tabs.onUpdated.addListener(function (tabId, updatedInfo) {
collectedSequence.push(updatedInfo);
});
browser.runtime.onMessage.addListener(function () {
if (collectedSequence.length !== expectedSequence.length) {
browser.test.assertEq(
JSON.stringify(expectedSequence),
JSON.stringify(collectedSequence),
"got unexpected number of updateInfo data"
);
} else {
for (var i = 0; i < expectedSequence.length; i++) {
browser.test.assertEq(
expectedSequence[i].status,
collectedSequence[i].status,
"check updatedInfo status"
);
if (expectedSequence[i].url || collectedSequence[i].url) {
browser.test.assertEq(
expectedSequence[i].url,
collectedSequence[i].url,
"check updatedInfo url"
);
}
}
}
browser.test.notifyPass("tabs.onUpdated");
});
browser.tabs.create({ url: pageURL });
},
files: {
"content-script.js": `
window.addEventListener("message", function(evt) {
if (evt.data == "frame-updated") {
browser.runtime.sendMessage("load-completed");
}
}, true);
`,
}
});
yield Promise.all([
extension.startup(),
extension.awaitFinish("tabs.onUpdated")
]);
yield extension.unload();
yield BrowserTestUtils.closeWindow(win1);
});

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

@ -0,0 +1,17 @@
<html>
<body>
<h3>test iframe</h3>
<script>
window.onload = function() {
window.onhashchange = function() {
window.parent.postMessage("updated-iframe-url", "*");
}
// NOTE: without the this setTimeout the location change is not fired
// even without the "fire only for top level windows" fix
setTimeout(function() {
window.location.hash="updated-iframe-url";
}, 0);
}
</script>
</body>
</html>

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

@ -0,0 +1,16 @@
<html>
<body>
<h3>test page</h3>
<iframe src="about:blank"></iframe>
<script>
window.onmessage = function(evt) {
if (evt.data === "updated-iframe-url") {
window.postMessage("frame-updated", "*");
}
};
window.onload = function() {
document.querySelector('iframe').setAttribute("src", "context_tabs_onUpdated_iframe.html");
};
</script>
</body>
</html>

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

@ -5,3 +5,21 @@ function makeWidgetId(id)
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}
function* focusWindow(win)
{
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
if (fm.activeWindow == win) {
return;
}
let promise = new Promise(resolve => {
win.addEventListener("focus", function listener() {
win.removeEventListener("focus", listener, true);
resolve();
}, true);
});
win.focus();
yield promise;
}

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

@ -530,13 +530,13 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
}
.context-url-view-wrapper {
padding: 12px;
margin-bottom: 0.5em;
padding: 14px 15px;
background-color: #dbf7ff;
}
.showing-room-name > .text-chat-entries > .text-chat-scroller > .context-url-view-wrapper {
padding-top: 0;
margin-bottom: 0;
}
.room-context {
@ -755,7 +755,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.media-wrapper > .focus-stream {
width: 100%;
/* A reasonable height */
height: 70%;
height: 55%;
}
.media-wrapper.receiving-screen-share > .focus-stream {
@ -831,7 +831,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
/* This is temp, to echo the .media-wrapper > .text-chat-view above */
height: 30%;
height: 45%;
}
.media-wrapper.receiving-screen-share > .screen {
@ -930,7 +930,12 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.media-wrapper > .focus-stream {
flex: 1 1 auto;
height: auto;
/* To keep the aspect ratio of video. Update accordingly with chatbox[customSize] width */
height: 263px;
}
.desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
height: calc(100% - 263px);
}
}
@ -960,6 +965,10 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
text-align: start;
}
.text-chat-scroller div:nth-child(2) {
margin-top: .5em;
}
/* Sent text chat entries should be on the right */
.text-chat-entry.sent {
/* aligns paragraph to right side */
@ -1208,8 +1217,6 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
.text-chat-view {
display: flex;
flex-flow: column nowrap;
/* 120px max-height of .text-chat-entries plus 40px of .text-chat-box */
max-height: 160px;
/* 60px min-height of .text-chat-entries plus 40px of .text-chat-box */
min-height: 100px;
height: auto;
@ -1220,7 +1227,6 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
.text-chat-entries {
flex: 1 1 auto;
max-height: 120px;
min-height: 60px;
}

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

@ -119,7 +119,11 @@ loop.store.TextChatStore = (function() {
// Notify MozLoopService if appropriate that a message has been appended
// and it should therefore check if we need a different sized window or not.
if (message.contentType !== CHAT_CONTENT_TYPES.ROOM_NAME) {
window.dispatchEvent(new CustomEvent("LoopChatMessageAppended"));
if (this._storeState.textChatEnabled) {
window.dispatchEvent(new CustomEvent("LoopChatMessageAppended"));
} else {
window.dispatchEvent(new CustomEvent("LoopChatDisabledMessageAppended"));
}
}
},

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

@ -963,6 +963,7 @@ var MozLoopServiceInternal = {
const kSizeMap = {
LoopChatEnabled: "loopChatEnabled",
LoopChatDisabledMessageAppended: "loopChatDisabledMessageAppended",
LoopChatMessageAppended: "loopChatMessageAppended"
};
@ -981,6 +982,7 @@ var MozLoopServiceInternal = {
window.addEventListener("LoopChatEnabled", onChatEvent);
window.addEventListener("LoopChatMessageAppended", onChatEvent);
window.addEventListener("LoopChatDisabledMessageAppended", onChatEvent);
injectLoopAPI(window);

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

@ -96,6 +96,7 @@ describe("loop.store.TextChatStore", function() {
});
it("should dispatch a LoopChatMessageAppended event", function() {
store.setStoreState({ textChatEnabled: true });
store.receivedTextChatMessage({
contentType: CHAT_CONTENT_TYPES.TEXT,
message: "Hello!"
@ -141,6 +142,7 @@ describe("loop.store.TextChatStore", function() {
});
it("should dipatch a LoopChatMessageAppended event", function() {
store.setStoreState({ textChatEnabled: true });
store.sendTextChatMessage({
contentType: CHAT_CONTENT_TYPES.TEXT,
message: "Hello!"
@ -246,6 +248,23 @@ describe("loop.store.TextChatStore", function() {
}]);
});
it("should dispatch a LoopChatDisabledMessageAppended event", function() {
store.setStoreState({ textChatEnabled: false });
store.updateRoomInfo(new sharedActions.UpdateRoomInfo({
roomName: "Let's share!",
roomUrl: "fake",
roomContextUrls: [{
description: "A wonderful event2",
location: "http://wonderful.invalid2",
thumbnail: "fake2"
}]
}));
sinon.assert.calledOnce(window.dispatchEvent);
sinon.assert.calledWithExactly(window.dispatchEvent,
new CustomEvent("LoopChatDisabledMessageAppended"));
});
it("should not dispatch a LoopChatMessageAppended event", function() {
store.updateRoomInfo(new sharedActions.UpdateRoomInfo({
roomName: "Let's share!",

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

@ -898,7 +898,7 @@
),
React.createElement(Section, {name: "DesktopRoomConversationView"},
React.createElement(FramedExample, {height: 398,
React.createElement(FramedExample, {height: 448,
onContentsRendered: invitationRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)",
width: 348},
@ -932,7 +932,7 @@
),
React.createElement(FramedExample, {dashed: true,
height: 398,
height: 448,
onContentsRendered: desktopRoomStoreLoading.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation (loading)",
width: 348},
@ -952,7 +952,7 @@
),
React.createElement(FramedExample, {dashed: true,
height: 398,
height: 448,
onContentsRendered: roomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation",
width: 348},
@ -1006,7 +1006,7 @@
),
React.createElement(FramedExample, {dashed: true,
height: 398,
height: 448,
onContentsRendered: desktopLocalFaceMuteRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation local face-mute",
width: 348},
@ -1022,7 +1022,7 @@
),
React.createElement(FramedExample, {dashed: true,
height: 398,
height: 448,
onContentsRendered: desktopRemoteFaceMuteRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation remote face-mute",
width: 348},

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

@ -898,7 +898,7 @@
</Section>
<Section name="DesktopRoomConversationView">
<FramedExample height={398}
<FramedExample height={448}
onContentsRendered={invitationRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"
width={348}>
@ -932,7 +932,7 @@
</FramedExample>
<FramedExample dashed={true}
height={398}
height={448}
onContentsRendered={desktopRoomStoreLoading.activeRoomStore.forcedUpdate}
summary="Desktop room conversation (loading)"
width={348}>
@ -952,7 +952,7 @@
</FramedExample>
<FramedExample dashed={true}
height={398}
height={448}
onContentsRendered={roomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation"
width={348}>
@ -1006,7 +1006,7 @@
</FramedExample>
<FramedExample dashed={true}
height={398}
height={448}
onContentsRendered={desktopLocalFaceMuteRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation local face-mute"
width={348}>
@ -1022,7 +1022,7 @@
</FramedExample>
<FramedExample dashed={true}
height={398}
height={448}
onContentsRendered={desktopRemoteFaceMuteRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation remote face-mute"
width={348} >

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

@ -2669,20 +2669,36 @@ ContentPermissionPrompt.prototype = {
_promptWebNotifications : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
var actions = [
{
stringId: "webNotifications.alwaysReceive",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {},
},
{
stringId: "webNotifications.neverShow",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {},
},
];
var actions;
var browser = this._getBrowserForRequest(aRequest);
// Only show "allow for session" in PB mode, we don't
// support "allow for session" in non-PB mode.
if (PrivateBrowsingUtils.isBrowserPrivate(browser)) {
actions = [
{
stringId: "webNotifications.receiveForSession",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
callback: function() {},
}
];
} else {
actions = [
{
stringId: "webNotifications.alwaysReceive",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {},
},
{
stringId: "webNotifications.neverShow",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {},
},
];
}
var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),

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

@ -375,6 +375,8 @@ geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
webNotifications.receiveForSession=Receive for this session
webNotifications.receiveForSession.accesskey=s
webNotifications.alwaysReceive=Always Receive Notifications
webNotifications.alwaysReceive.accesskey=A
webNotifications.neverShow=Always Block Notifications

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

@ -48,9 +48,8 @@ mozstdName=Disconnect.me basic protection (Recommended).
mozstdDesc=Allows some trackers so websites function properly.
mozfullName=Disconnect.me strict protection.
mozfullDesc=Blocks known trackers. Some sites may not function properly.
# LOCALIZATION NOTE (blocklistChangeRequiresRestart, restartTitle): %S = brandShortName
# LOCALIZATION NOTE (blocklistChangeRequiresRestart): %S = brandShortName
blocklistChangeRequiresRestart=%S must restart to change block lists.
shouldRestartTitle=Restart %S
#### Master Password

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

@ -29,6 +29,7 @@
"mozilla/components-imports": 1,
"mozilla/import-headjs-globals": 1,
"mozilla/mark-test-function-used": 1,
"mozilla/var-only-at-top-level": 1,
// Disallow using variables outside the blocks they are defined (especially
// since only let and const are used, see "no-var").
@ -270,8 +271,9 @@
"no-unused-vars": 2,
// Allow using variables before they are defined.
"no-use-before-define": 0,
// Require let or const instead of var.
"no-var": 2,
// We use var-only-at-top-level instead of no-var as we allow top level
// vars.
"no-var": 0,
// Allow using TODO/FIXME comments.
"no-warning-comments": 0,
// Disallow use of the with statement.

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

@ -9,7 +9,9 @@ const { getSnapshotStatusText } = require("../utils");
const { snapshotState: states } = require("../constants");
const { snapshot: snapshotModel } = require("../models");
const TAKE_SNAPSHOT_TEXT = "Take snapshot";
const TREE_ROW_HEIGHT = 10;
// If HEAP_TREE_ROW_HEIGHT changes, be sure to change `var(--heap-tree-row-height)`
// in `devtools/client/themes/memory.css`
const HEAP_TREE_ROW_HEIGHT = 14;
/**
* Creates a hash map mapping node IDs to its parent node.
@ -45,7 +47,7 @@ function createTreeProperties (census) {
renderItem: (item, depth, focused, arrow) => new TreeItem({ item, depth, focused, arrow }),
getRoots: () => census.children,
getKey: node => node.id,
itemHeight: TREE_ROW_HEIGHT,
itemHeight: HEAP_TREE_ROW_HEIGHT,
};
}
@ -85,6 +87,13 @@ const Heap = module.exports = createClass({
break;
case states.SAVED_CENSUS:
pane = dom.div({ className: "heap-view-panel", "data-state": "loaded" },
dom.div({ className: "header" },
dom.span({ className: "heap-tree-item-bytes" }, "Bytes"),
dom.span({ className: "heap-tree-item-count" }, "Count"),
dom.span({ className: "heap-tree-item-total-bytes" }, "Total Bytes"),
dom.span({ className: "heap-tree-item-total-count" }, "Total Count"),
dom.span({ className: "heap-tree-item-name" }, "Name")
),
Tree(createTreeProperties(snapshot.census))
);
break;

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

@ -15,13 +15,15 @@ const TreeItem = module.exports = createClass({
render() {
let { item, depth, arrow, focused } = this.props;
return dom.div({ className: "heap-tree-item", style: { marginLeft: depth * INDENT }},
arrow,
dom.span({ className: "heap-tree-item-name" }, item.name),
return dom.div({ className: "heap-tree-item" },
dom.span({ className: "heap-tree-item-bytes" }, item.bytes),
dom.span({ className: "heap-tree-item-count" }, item.count),
dom.span({ className: "heap-tree-item-total-bytes" }, item.totalBytes),
dom.span({ className: "heap-tree-item-total-count" }, item.totalCount)
dom.span({ className: "heap-tree-item-total-count" }, item.totalCount),
dom.span({ className: "heap-tree-item-name", style: { marginLeft: depth * INDENT }},
arrow,
item.name
)
);
}
});

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

@ -141,6 +141,14 @@ A marker generated via `console.timeStamp(label)`.
* DOMString causeName - the label passed into `console.timeStamp(label)`
if passed in.
## document::DOMContentLoaded
A marker generated when the DOMContentLoaded event is fired.
## document::Load
A marker generated when the document's "load" event is fired.
## Parse HTML
## Parse XML

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

@ -91,6 +91,16 @@ const TIMELINE_BLUEPRINT = {
label: L10N.getStr("marker.label.domevent"),
fields: Formatters.DOMEventFields,
},
"document::DOMContentLoaded": {
group: 1,
colorName: "graphs-full-red",
label: "DOMContentLoaded"
},
"document::Load": {
group: 1,
colorName: "graphs-full-blue",
label: "Load"
},
"Javascript": {
group: 1,
colorName: "graphs-yellow",

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

@ -56,6 +56,7 @@ skip-if = true # Bug 1161817
[browser_perf-loading-02.js]
[browser_perf-marker-details-01.js]
skip-if = os == 'linux' # Bug 1172120
[browser_perf-markers-docload.js]
[browser_perf-options-01.js]
[browser_perf-options-02.js]
[browser_perf-options-03.js]

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

@ -0,0 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the sidebar is updated with "DOMContentLoaded" and "load" markers.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { PerformanceController } = panel.panelWin;
loadFrameScripts();
yield startRecording(panel);
ok(true, "Recording has started.");
evalInDebuggee("document.location.reload()");
yield waitUntil(() => {
// Wait until we get the necessary markers.
let markers = PerformanceController.getCurrentRecording().getMarkers();
if (!markers.some(m => m.name == "document::DOMContentLoaded") ||
!markers.some(m => m.name == "document::Load")) {
return false;
}
ok(markers.filter(m => m.name == "document::DOMContentLoaded").length == 1,
"There should only be one `DOMContentLoaded` marker.");
ok(markers.filter(m => m.name == "document::Load").length == 1,
"There should only be one `load` marker.");
return true;
});
yield stopRecording(panel);
ok(true, "Recording has ended.");
yield teardown(panel);
finish();
}
/**
* Takes a string `script` and evaluates it directly in the content
* in potentially a different process.
*/
function evalInDebuggee (script) {
let { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
let deferred = Promise.defer();
if (!mm) {
throw new Error("`loadFrameScripts()` must be called when using MessageManager.");
}
let id = generateUUID().toString();
mm.sendAsyncMessage("devtools:test:eval", { script: script, id: id });
mm.addMessageListener("devtools:test:eval:response", handler);
function handler ({ data }) {
if (id !== data.id) {
return;
}
mm.removeMessageListener("devtools:test:eval:response", handler);
deferred.resolve(data.value);
}
return deferred.promise;
}

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

@ -33,4 +33,30 @@ add_task(function *() {
is(widget.getCssValue(),
"drop-shadow(2px 1px 5px black) url(example.svg#filter)",
"setCssValue should work for string-typed values");
info("Test parsing of mixed-case function names");
widget.setCssValue("BLUR(2px) Contrast(200%) Drop-Shadow(2px 1px 5px Black)");
is(widget.getCssValue(),
"BLUR(2px) Contrast(200%) Drop-Shadow(2px 1px 5px Black)",
"setCssValue should work for mixed-case function names");
info("Test parsing of invalid filter value");
widget.setCssValue("totallyinvalid");
is(widget.getCssValue(), "none",
"setCssValue should turn completely invalid value to 'none'");
info("Test parsing of invalid function argument");
widget.setCssValue("blur('hello')");
is(widget.getCssValue(), "blur(0px)",
"setCssValue should replace invalid function argument with default");
info("Test parsing of invalid function argument #2");
widget.setCssValue("drop-shadow(whatever)");
is(widget.getCssValue(), "drop-shadow()",
"setCssValue should replace invalid drop-shadow argument with empty string");
info("Test parsing of mixed invalid argument");
widget.setCssValue("contrast(5%) whatever invert('xxx')");
is(widget.getCssValue(), "contrast(5%) invert(0%)",
"setCssValue should handle multiple errors");
});

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

@ -22,6 +22,7 @@ function* performTest() {
testParseCssProperty(doc, parser);
testParseCssVar(doc, parser);
testParseURL(doc, parser);
testParseFilter(doc, parser);
host.destroy();
}
@ -249,3 +250,13 @@ function testParseURL(doc, parser) {
target.innerHTML = "";
}
}
function testParseFilter(doc, parser) {
let frag = parser.parseCssProperty("filter", "something invalid", {
filterSwatchClass: "test-filterswatch"
});
let swatchCount = frag.querySelectorAll(".test-filterswatch").length;
is(swatchCount, 1, "filter swatch was created");
}

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

@ -10,8 +10,10 @@
*/
const EventEmitter = require("devtools/shared/event-emitter");
const { Cu } = require("chrome");
const { ViewHelpers } = Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm", {});
const { Cu, Cc, Ci } = require("chrome");
const { ViewHelpers } =
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm",
{});
const STRINGS_URI = "chrome://browser/locale/devtools/filterwidget.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
const {cssTokenizer} = require("devtools/client/shared/css-parsing-utils");
@ -19,6 +21,10 @@ const {cssTokenizer} = require("devtools/client/shared/css-parsing-utils");
loader.lazyGetter(this, "asyncStorage",
() => require("devtools/shared/async-storage"));
loader.lazyGetter(this, "DOMUtils", () => {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
});
const DEFAULT_FILTER_TYPE = "length";
const UNIT_MAPPING = {
percentage: "%",
@ -307,8 +313,11 @@ CSSFilterEditorWidget.prototype = {
let value = startValue + direction * multiplier;
const [min, max] = this._definition(filter.name).range;
value = value < min ? min :
value > max ? max : value;
if (value < min) {
value = min;
} else if (value > max) {
value = max;
}
input.value = fixFloat(value);
@ -323,8 +332,8 @@ CSSFilterEditorWidget.prototype = {
let {start, end, value} = num;
let split = input.value.split("");
let computed = fixFloat(value + direction * multiplier),
dotIndex = computed.indexOf(".0");
let computed = fixFloat(value + direction * multiplier);
let dotIndex = computed.indexOf(".0");
if (dotIndex > -1) {
computed = computed.slice(0, -2);
@ -343,10 +352,10 @@ CSSFilterEditorWidget.prototype = {
},
_input: function(e) {
let filterEl = e.target.closest(".filter"),
index = this._getFilterElementIndex(filterEl),
filter = this.filters[index],
def = this._definition(filter.name);
let filterEl = e.target.closest(".filter");
let index = this._getFilterElementIndex(filterEl);
let filter = this.filters[index];
let def = this._definition(filter.name);
if (def.type !== "string") {
e.target.value = fixFloat(e.target.value);
@ -366,9 +375,9 @@ CSSFilterEditorWidget.prototype = {
this.el.classList.add("dragging");
// label-dragging
} else if (e.target.classList.contains("devtools-draglabel")) {
let label = e.target,
input = filterEl.querySelector("input"),
index = this._getFilterElementIndex(filterEl);
let label = e.target;
let input = filterEl.querySelector("input");
let index = this._getFilterElementIndex(filterEl);
this._dragging = {
index, label, input,
@ -386,19 +395,7 @@ CSSFilterEditorWidget.prototype = {
}
const key = select.value;
const def = this._definition(key);
// UNIT_MAPPING[string] is an empty string (falsy), so
// using || doesn't work here
const unitLabel = typeof UNIT_MAPPING[def.type] === "undefined" ?
UNIT_MAPPING[DEFAULT_FILTER_TYPE] :
UNIT_MAPPING[def.type];
// string-type filters have no default value but a placeholder instead
if (!unitLabel) {
this.add(key);
} else {
this.add(key, def.range[0] + unitLabel);
}
this.add(key, null);
this.render();
},
@ -423,9 +420,9 @@ CSSFilterEditorWidget.prototype = {
},
_dragFilterElement: function(e) {
const rect = this.filtersList.getBoundingClientRect(),
top = e.pageY - LIST_PADDING,
bottom = e.pageY + LIST_PADDING;
const rect = this.filtersList.getBoundingClientRect();
let top = e.pageY - LIST_PADDING;
let bottom = e.pageY + LIST_PADDING;
// don't allow dragging over top/bottom of list
if (top < rect.top || bottom > rect.bottom) {
return;
@ -439,8 +436,11 @@ CSSFilterEditorWidget.prototype = {
// change is the number of _steps_ taken from initial position
// i.e. how many elements we have passed
let change = delta / LIST_ITEM_HEIGHT;
change = change > 0 ? Math.floor(change) :
change < 0 ? Math.ceil(change) : change;
if (change > 0) {
change = Math.floor(change);
} else if (change < 0) {
change = Math.ceil(change);
}
const children = this.filtersList.children;
const index = [...children].indexOf(filterEl);
@ -489,8 +489,11 @@ CSSFilterEditorWidget.prototype = {
const filter = this.filters[dragging.index];
const [min, max] = this._definition(filter.name).range;
value = value < min ? min :
value > max ? max : value;
if (value < min) {
value = min;
} else if (value > max) {
value = max;
}
input.value = fixFloat(value);
@ -551,8 +554,8 @@ CSSFilterEditorWidget.prototype = {
_savePreset: function(e) {
e.preventDefault();
let name = this.addPresetInput.value,
value = this.getCssValue();
let name = this.addPresetInput.value;
let value = this.getCssValue();
if (!name || !value || value === "none") {
this.emit("preset-save-error");
@ -593,9 +596,9 @@ CSSFilterEditorWidget.prototype = {
let el = base.cloneNode(true);
let [name, value] = el.children,
label = name.children[1],
[input, unitPreview] = value.children;
let [name, value] = el.children;
let label = name.children[1];
let [input, unitPreview] = value.children;
let min, max;
if (def.range) {
@ -615,11 +618,11 @@ CSSFilterEditorWidget.prototype = {
input.max = max;
}
input.step = "0.1";
break;
break;
case "string":
input.type = "text";
input.placeholder = def.placeholder;
break;
break;
}
// use photoshop-style label-dragging
@ -637,7 +640,8 @@ CSSFilterEditorWidget.prototype = {
this.filtersList.appendChild(el);
}
let lastInput = this.filtersList.querySelector(`.filter:last-of-type input`);
let lastInput =
this.filtersList.querySelector(`.filter:last-of-type input`);
if (lastInput) {
lastInput.focus();
// move cursor to end of input
@ -685,6 +689,7 @@ CSSFilterEditorWidget.prototype = {
* filter's definition
*/
_definition: function(name) {
name = name.toLowerCase();
return filterList.find(a => a.name === name);
},
@ -708,6 +713,14 @@ CSSFilterEditorWidget.prototype = {
}
for (let {name, value} of tokenizeFilterValue(cssValue)) {
// If the specified value is invalid, replace it with the
// default.
if (name !== "url") {
if (!DOMUtils.cssPropertyIsValid("filter", name + "(" + value + ")")) {
value = null;
}
}
this.add(name, value);
}
@ -722,15 +735,31 @@ CSSFilterEditorWidget.prototype = {
* filter name (e.g. blur)
* @param {String} value
* value of the filter (e.g. 30px, 20%)
* If this is |null|, then a default value may be supplied.
* @return {Number}
* The index of the new filter in the current list of filters
*/
add: function(name, value = "") {
add: function(name, value) {
const def = this._definition(name);
if (!def) {
return false;
}
if (value === null) {
// UNIT_MAPPING[string] is an empty string (falsy), so
// using || doesn't work here
const unitLabel = typeof UNIT_MAPPING[def.type] === "undefined" ?
UNIT_MAPPING[DEFAULT_FILTER_TYPE] :
UNIT_MAPPING[def.type];
// string-type filters have no default value but a placeholder instead
if (!unitLabel) {
value = "";
} else {
value = def.range[0] + unitLabel;
}
}
let unit = def.type === "string"
? ""
: (/[a-zA-Z%]+/.exec(value) || [])[0];
@ -752,7 +781,7 @@ CSSFilterEditorWidget.prototype = {
}
}
const index = this.filters.push({value, unit, name: def.name}) - 1;
const index = this.filters.push({value, unit, name}) - 1;
this.emit("updated", this.getCssValue());
return index;
@ -940,8 +969,8 @@ function getNeighbourNumber(string, index) {
return null;
}
let left = /-?[0-9.]*$/.exec(string.slice(0, index)),
right = /-?[0-9.]*/.exec(string.slice(index));
let left = /-?[0-9.]*$/.exec(string.slice(0, index));
let right = /-?[0-9.]*/.exec(string.slice(index));
left = left ? left[0] : "";
right = right ? right[0] : "";

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

@ -19,9 +19,24 @@
--row-hover-background-color: rgba(76,158,217,0.2);
}
html, .theme-body, #app, #memory-tool, #memory-tool-container {
height: 100%;
}
.theme-body {
overflow: hidden;
background-color: var(--theme-body-background);
}
#memory-tool-container {
display: flex;
flex-direction: row;
--toolbar-height: 20px;
/**
* If --heap-tree-row-height changes, be sure to change HEAP_TREE_ROW_HEIGHT
* in `devtools/client/memory/components/heap.js`.
*/
--heap-tree-row-height: 14px;
}
/**
@ -63,7 +78,7 @@
display: flex;
flex-direction: row;
align-items: center;
height: 20px;
height: var(--toolbar-height);
}
/**
@ -91,13 +106,18 @@
width: 186px;
list-style-type: none;
font-size: 12px;
height: 100%;
overflow-y: scroll;
background-color: var(--theme-toolbar-background);
border-color: var(--theme-splitter-color);
color: var(--theme-body-color-alt);
border-left-width: 1px;
}
.list > li {
height: 40px;
color: var(--theme-body-color);
border-bottom: 1px solid transparent;
border-top: 1px solid rgba(128,128,128,0.15);
border-bottom: 1px solid rgba(128,128,128,0.15);
padding: 8px;
cursor: pointer;
}
@ -127,6 +147,9 @@
#heap-view {
flex: 1 1 auto;
border-color: var(--theme-splitter-color);
color: var(--theme-body-color)
border-left-width: 1px;
}
#heap-view .heap-view-panel {
@ -138,65 +161,86 @@
}
/**
* Heap View
* Heap Tree View
*/
.heap-view {
position: relative;
#heap-view .theme-twisty {
float: left;
}
.heap-view .theme-twisty {
text-align: end;
.tree {
height: 100%;
overflow-y: scroll;
}
.heap-tree-item {
.tree .header {
height: 17px;
overflow: hidden;
color: var(--theme-body-color);
background-color: var(--theme-tab-toolbar-background);
}
.tree span {
border-left-color: var(--cell-border-color);
border-left-width: 1px;
}
.tree-node {
height: var(--heap-tree-row-height);
}
.heap-tree-item, .header {
list-style-type: none;
/* display: none; */
height: var(--heap-tree-row-height);
}
.heap-tree-item[expanded] {
display: block;
.heap-tree-item span, .header span {
float: left;
}
.heap-tree-item:nth-child(2n) {
.tree-node:nth-child(2n) {
background-color: var(--row-alt-background-color);
}
.heap-tree-item:hover {
.tree-node:hover {
background-color: var(--row-hover-background-color);
}
.heap-tree-item:focus {
.tree-node:focus {
background-color: var(--theme-selection-background);
}
.heap-tree-item:focus description {
color: var(--theme-selection-color) !important;
.header {
background-color: var(--theme-tab-toolbar-background);
}
.heap-tree-item:focus .call-tree-cell {
-moz-border-end-color: var(--focus-cell-border-color);
}
.heap-tree-cell[type="bytes"], .heap-tree-cell[type="count"] {
position: absolute;
text-align: right;
width: 40px;
}
.heap-tree-cell[type="name"] {
width: 150px;
.header span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
text-align: center;
font-size: 90%;
}
.heap-tree-cell[type="count"] {
left: 300px;
.heap-tree-item-bytes,
.heap-tree-item-count,
.heap-tree-item-total-bytes,
.heap-tree-item-total-count {
text-align: right;
border-right: var(--cell-border-color) 1px solid;
padding-right: 5px;
}
.heap-tree-cell[type="bytes"] {
left: 250px;
.heap-tree-item-count,
.heap-tree-item-total-count {
width: 5vw;
}
.heap-tree-item-bytes,
.heap-tree-item-total-bytes {
width: 7vw;
}
.heap-tree-item-name {
padding-left: 10px;
}

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

@ -549,6 +549,15 @@
* Marker colors
*/
menuitem.marker-color-graphs-full-red:before,
.marker-color-graphs-full-red {
background-color: var(--theme-graphs-full-red);
}
menuitem.marker-color-graphs-full-blue:before,
.marker-color-graphs-full-blue {
background-color: var(--theme-graphs-full-blue);
}
menuitem.marker-color-graphs-green:before,
.marker-color-graphs-green {
background-color: var(--theme-graphs-green);

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

@ -51,6 +51,8 @@
--theme-graphs-orange: #d97e00;
--theme-graphs-red: #e57180;
--theme-graphs-grey: #cccccc;
--theme-graphs-full-red: #f00;
--theme-graphs-full-blue: #00f;
}
:root.theme-dark {
@ -90,4 +92,6 @@
--theme-graphs-orange: #d96629;
--theme-graphs-red: #eb5368;
--theme-graphs-grey: #757873;
--theme-graphs-full-red: #f00;
--theme-graphs-full-blue: #00f;
}

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

@ -77,7 +77,10 @@ OutputParser.prototype = {
safeCssPropertySupportsType(name, DOMUtils.TYPE_COLOR) ||
safeCssPropertySupportsType(name, DOMUtils.TYPE_GRADIENT);
if (this._cssPropertySupportsValue(name, value)) {
// The filter property is special in that we want to show the
// swatch even if the value is invalid, because this way the user
// can easily use the editor to fix it.
if (options.expectFilter || this._cssPropertySupportsValue(name, value)) {
return this._parse(value, options);
}
this._appendTextNode(value);

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

@ -60,8 +60,6 @@ NS_IMETHODIMP AudioChannelAgent::GetAudioChannelType(int32_t *aAudioChannelType)
return NS_OK;
}
/* boolean init (in nsIDOMWindow window, in long channelType,
* in nsIAudioChannelAgentCallback callback); */
NS_IMETHODIMP
AudioChannelAgent::Init(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback)
@ -70,8 +68,6 @@ AudioChannelAgent::Init(nsIDOMWindow* aWindow, int32_t aChannelType,
/* useWeakRef = */ false);
}
/* boolean initWithWeakCallback (in nsIDOMWindow window, in long channelType,
* in nsIAudioChannelAgentCallback callback); */
NS_IMETHODIMP
AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow,
int32_t aChannelType,

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

@ -323,13 +323,16 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
MOZ_ASSERT(aVolume && aMuted);
MOZ_ASSERT(aAudioChannel < NUMBER_OF_AUDIO_CHANNELS);
*aVolume = 1.0;
*aMuted = false;
if (!aWindow || !aWindow->IsOuterWindow()) {
*aVolume = 0.0;
*aMuted = true;
return;
}
*aVolume = 1.0;
*aMuted = false;
AudioChannelWindow* winData = nullptr;
nsCOMPtr<nsPIDOMWindow> window = aWindow;

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

@ -448,9 +448,6 @@ Exception::ToString(nsACString& _retval)
return NS_OK;
}
/* void initialize (in AUTF8String aMessage, in nsresult aResult,
* in AUTF8String aName, in nsIStackFrame aLocation,
* in nsISupports aData, in nsIException aInner); */
NS_IMETHODIMP
Exception::Initialize(const nsACString& aMessage, nsresult aResult,
const nsACString& aName, nsIStackFrame *aLocation,

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

@ -5109,6 +5109,14 @@ nsDocument::DispatchContentLoadedEvents()
NS_LITERAL_STRING("DOMContentLoaded"),
true, false);
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
nsIDocShell* docShell = this->GetDocShell();
if (timelines && timelines->HasConsumer(docShell)) {
timelines->AddMarkerForDocShell(
docShell, "document::DOMContentLoaded", MarkerTracingType::TIMESTAMP);
}
if (mTiming) {
mTiming->NotifyDOMContentLoadedEnd(nsIDocument::GetDocumentURI());
}
@ -7598,7 +7606,6 @@ nsIDocument::GetDocumentURIObject() const
}
// readonly attribute DOMString compatMode;
// Returns "BackCompat" if we are in quirks mode, "CSS1Compat" if we are
// in almost standards or full standards mode. See bug 105640. This was
// implemented to match MSIE's compatMode property.

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

@ -2856,8 +2856,7 @@ nsObjectLoadingContent::ScriptRequestPluginInstance(JSContext* aCx,
aCx == nsContentUtils::GetCurrentJSContext());
bool callerIsContentJS = (nsContentUtils::GetCurrentJSContext() &&
!nsContentUtils::IsCallerChrome() &&
!nsContentUtils::IsCallerContentXBL() &&
JS_IsRunning(aCx));
!nsContentUtils::IsCallerContentXBL());
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));

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

@ -23,7 +23,6 @@
#include "nsNetUtil.h"
#include "nsAutoPtr.h"
#include "nsStreamUtils.h"
#include "nsCORSListenerProxy.h"
#include <algorithm>
using mozilla::net::ReferrerPolicy;
@ -42,7 +41,7 @@ public:
NS_DECL_ISUPPORTS
nsresult LoadDocument(nsIChannel* aChannel, nsIPrincipal *aLoaderPrincipal,
nsresult LoadDocument(nsIChannel* aChannel,
bool aChannelIsSync, bool aForceToXML,
ReferrerPolicy aReferrerPolicy,
nsIDOMDocument** aResult);
@ -130,29 +129,29 @@ NS_IMPL_ISUPPORTS(nsSyncLoader,
nsresult
nsSyncLoader::LoadDocument(nsIChannel* aChannel,
nsIPrincipal *aLoaderPrincipal,
bool aChannelIsSync,
bool aForceToXML,
ReferrerPolicy aReferrerPolicy,
nsIDOMDocument **aResult)
{
NS_ENSURE_ARG(aChannel);
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
nsresult rv = NS_OK;
nsCOMPtr<nsIURI> loaderUri;
if (aLoaderPrincipal) {
aLoaderPrincipal->GetURI(getter_AddRefs(loaderUri));
}
mChannel = aChannel;
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
if (http) {
http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
false);
if (loaderUri) {
http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
if (loadInfo) {
nsCOMPtr<nsIURI> loaderUri;
loadInfo->TriggeringPrincipal()->GetURI(getter_AddRefs(loaderUri));
if (loaderUri) {
http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
}
}
}
@ -186,14 +185,6 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
listener.swap(forceListener);
}
if (aLoaderPrincipal) {
RefPtr<nsCORSListenerProxy> corsListener =
new nsCORSListenerProxy(listener, aLoaderPrincipal, false);
rv = corsListener->Init(mChannel, DataURIHandling::Disallow);
NS_ENSURE_SUCCESS(rv, rv);
listener = corsListener;
}
if (aChannelIsSync) {
rv = PushSyncStream(listener);
}
@ -226,7 +217,7 @@ nsSyncLoader::PushAsyncStream(nsIStreamListener* aListener)
mAsyncLoadStatus = NS_OK;
// Start reading from the channel
nsresult rv = mChannel->AsyncOpen(this, nullptr);
nsresult rv = mChannel->AsyncOpen2(this);
if (NS_SUCCEEDED(rv)) {
// process events until we're finished.
@ -254,7 +245,7 @@ nsresult
nsSyncLoader::PushSyncStream(nsIStreamListener* aListener)
{
nsCOMPtr<nsIInputStream> in;
nsresult rv = mChannel->Open(getter_AddRefs(in));
nsresult rv = mChannel->Open2(getter_AddRefs(in));
NS_ENSURE_SUCCESS(rv, rv);
mLoading = true;
@ -309,8 +300,12 @@ nsSyncLoader::GetInterface(const nsIID & aIID,
/* static */
nsresult
nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
nsILoadGroup *aLoadGroup, bool aForceToXML,
nsSyncLoadService::LoadDocument(nsIURI *aURI,
nsContentPolicyType aContentPolicyType,
nsIPrincipal *aLoaderPrincipal,
nsSecurityFlags aSecurityFlags,
nsILoadGroup *aLoadGroup,
bool aForceToXML,
ReferrerPolicy aReferrerPolicy,
nsIDOMDocument** aResult)
{
@ -318,8 +313,8 @@ nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
aURI,
aLoaderPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
aSecurityFlags,
aContentPolicyType,
aLoadGroup);
NS_ENSURE_SUCCESS(rv, rv);
@ -328,15 +323,12 @@ nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
}
bool isChrome = false, isResource = false;
bool isSync = (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) &&
isChrome) ||
(NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)) &&
isResource);
bool isSync =
(NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome) ||
(NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)) && isResource);
RefPtr<nsSyncLoader> loader = new nsSyncLoader();
return loader->LoadDocument(channel, aLoaderPrincipal, isSync,
aForceToXML, aReferrerPolicy, aResult);
return loader->LoadDocument(channel, isSync, aForceToXML,
aReferrerPolicy, aResult);
}
/* static */

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

@ -29,17 +29,22 @@ public:
* Synchronously load the document from the specified URI.
*
* @param aURI URI to load the document from.
* @param aContentPolicyType contentPolicyType to be set on the channel
* @param aLoaderPrincipal Principal of loading document. For security
* checks and referrer header. May be null if no
* security checks should be done.
* checks and referrer header.
* @param aSecurityFlags securityFlags to be set on the channel
* @param aLoadGroup The loadgroup to use for loading the document.
* @param aForceToXML Whether to parse the document as XML, regardless of
* content type.
* @param referrerPolicy Referrer policy.
* @param aResult [out] The document loaded from the URI.
*/
static nsresult LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
nsILoadGroup *aLoadGroup, bool aForceToXML,
static nsresult LoadDocument(nsIURI *aURI,
nsContentPolicyType aContentPolicyType,
nsIPrincipal *aLoaderPrincipal,
nsSecurityFlags aSecurityFlags,
nsILoadGroup *aLoadGroup,
bool aForceToXML,
mozilla::net::ReferrerPolicy aReferrerPolicy,
nsIDOMDocument** aResult);

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

@ -162,6 +162,9 @@ ThrowNoSetterArg(JSContext* aCx, prototypes::ID aProtoId)
} // namespace dom
struct ErrorResult::Message {
Message() { MOZ_COUNT_CTOR(ErrorResult::Message); }
~Message() { MOZ_COUNT_DTOR(ErrorResult::Message); }
nsTArray<nsString> mArgs;
dom::ErrNum mErrorNumber;

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

@ -3262,8 +3262,7 @@ class IDLValue(IDLObject):
elif self.type.isInteger() and type.isFloat():
# Convert an integer literal into float
if -2**24 <= self.value <= 2**24:
floatType = BuiltinTypes[IDLBuiltinType.Types.float]
return IDLValue(self.location, floatType, float(self.value))
return IDLValue(self.location, type, float(self.value))
else:
raise WebIDLError("Converting value %s to %s will lose precision." %
(self.value, type), [location])
@ -3281,7 +3280,7 @@ class IDLValue(IDLObject):
math.isnan(self.value))):
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
% self.value, [location])
return self
return IDLValue(self.location, type, self.value)
elif self.type.isString() and type.isUSVString():
# Allow USVStrings to use default value just like
# DOMString. No coercion is required in this case as Codegen.py

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

@ -1,5 +1,30 @@
import WebIDL
expected = [
("::TestConsts::zero", "zero", "Byte", 0),
("::TestConsts::b", "b", "Byte", -1),
("::TestConsts::o", "o", "Octet", 2),
("::TestConsts::s", "s", "Short", -3),
("::TestConsts::us", "us", "UnsignedShort", 4),
("::TestConsts::l", "l", "Long", -5),
("::TestConsts::ul", "ul", "UnsignedLong", 6),
("::TestConsts::ull", "ull", "UnsignedLongLong", 7),
("::TestConsts::ll", "ll", "LongLong", -8),
("::TestConsts::t", "t", "Boolean", True),
("::TestConsts::f", "f", "Boolean", False),
("::TestConsts::n", "n", "BooleanOrNull", None),
("::TestConsts::nt", "nt", "BooleanOrNull", True),
("::TestConsts::nf", "nf", "BooleanOrNull", False),
("::TestConsts::fl", "fl", "Float", 0.2),
("::TestConsts::db", "db", "Double", 0.2),
("::TestConsts::ufl", "ufl", "UnrestrictedFloat", 0.2),
("::TestConsts::udb", "udb", "UnrestrictedDouble", 0.2),
("::TestConsts::fli", "fli", "Float", 2),
("::TestConsts::dbi", "dbi", "Double", 2),
("::TestConsts::ufli", "ufli", "UnrestrictedFloat", 2),
("::TestConsts::udbi", "udbi", "UnrestrictedDouble", 2),
]
def WebIDLTest(parser, harness):
parser.parse("""
interface TestConsts {
@ -17,6 +42,14 @@ def WebIDLTest(parser, harness):
const boolean? n = null;
const boolean? nt = true;
const boolean? nf = false;
const float fl = 0.2;
const double db = 0.2;
const unrestricted float ufl = 0.2;
const unrestricted double udb = 0.2;
const float fli = 2;
const double dbi = 2;
const unrestricted float ufli = 2;
const unrestricted double udbi = 2;
};
""")
@ -29,11 +62,9 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName")
harness.check(iface.identifier.name, "TestConsts", "Interface has the right name")
harness.check(len(iface.members), 14, "Expect 14 members")
harness.check(len(iface.members), len(expected), "Expect %s members" % len(expected))
consts = iface.members
def checkConst(const, QName, name, type, value):
for (const, (QName, name, type, value)) in zip(iface.members, expected):
harness.ok(isinstance(const, WebIDL.IDLConst),
"Should be an IDLConst")
harness.ok(const.isConst(), "Const is a const")
@ -47,18 +78,3 @@ def WebIDLTest(parser, harness):
"Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.")
checkConst(consts[0], "::TestConsts::zero", "zero", "Byte", 0)
checkConst(consts[1], "::TestConsts::b", "b", "Byte", -1)
checkConst(consts[2], "::TestConsts::o", "o", "Octet", 2)
checkConst(consts[3], "::TestConsts::s", "s", "Short", -3)
checkConst(consts[4], "::TestConsts::us", "us", "UnsignedShort", 4)
checkConst(consts[5], "::TestConsts::l", "l", "Long", -5)
checkConst(consts[6], "::TestConsts::ul", "ul", "UnsignedLong", 6)
checkConst(consts[7], "::TestConsts::ull", "ull", "UnsignedLongLong", 7)
checkConst(consts[8], "::TestConsts::ll", "ll", "LongLong", -8)
checkConst(consts[9], "::TestConsts::t", "t", "Boolean", True)
checkConst(consts[10], "::TestConsts::f", "f", "Boolean", False)
checkConst(consts[11], "::TestConsts::n", "n", "BooleanOrNull", None)
checkConst(consts[12], "::TestConsts::nt", "nt", "BooleanOrNull", True)
checkConst(consts[13], "::TestConsts::nf", "nf", "BooleanOrNull", False)

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

@ -1414,7 +1414,7 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
mBufferProvider = new PersistentBufferProviderBasic(mTarget);
mIsSkiaGL = true;
} else {
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
gfxCriticalNote << "Failed to create a SkiaGL DrawTarget, falling back to software\n";
mode = RenderingMode::SoftwareBackendMode;
}
}
@ -1470,6 +1470,10 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
mTarget = sErrorTarget;
}
// Drop a note in the debug builds if we ever use accelerated Skia canvas.
if (mIsSkiaGL && mTarget && mTarget->GetType() == DrawTargetType::HARDWARE_RASTER) {
gfxWarningOnce() << "Using SkiaGL canvas.";
}
return mode;
}
@ -5329,9 +5333,6 @@ CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
JS::ToInt32(dirtyHeight));
}
// void putImageData (in ImageData d, in float x, in float y);
// void putImageData (in ImageData d, in double x, in double y, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);
nsresult
CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
dom::Uint8ClampedArray* aArray,

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

@ -59,8 +59,6 @@ NS_IMETHODIMP GamepadServiceTest::RemoveGamepad(uint32_t aIndex)
return NS_OK;
}
/* void newButtonEvent (in uint32_t index, in uint32_t button,
in boolean pressed); */
NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
uint32_t aButton,
bool aPressed)
@ -69,8 +67,6 @@ NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
return NS_OK;
}
/* void newButtonEvent (in uint32_t index, in uint32_t button,
in boolean pressed, double value); */
NS_IMETHODIMP GamepadServiceTest::NewButtonValueEvent(uint32_t aIndex,
uint32_t aButton,
bool aPressed,
@ -80,8 +76,6 @@ NS_IMETHODIMP GamepadServiceTest::NewButtonValueEvent(uint32_t aIndex,
return NS_OK;
}
/* void newAxisMoveEvent (in uint32_t index, in uint32_t axis,
in double value); */
NS_IMETHODIMP GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex,
uint32_t aAxis,
double aValue)

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

@ -3194,8 +3194,6 @@ ConvertToMidasInternalCommand(const nsAString & inCommandID,
}
/* TODO: don't let this call do anything if the page is not done loading */
/* boolean execCommand(in DOMString commandID, in boolean doShowUI,
in DOMString value); */
NS_IMETHODIMP
nsHTMLDocument::ExecCommand(const nsAString& commandID,
bool doShowUI,

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

@ -129,7 +129,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: 0,
code: expectedValues.code || '',
keyCode: expectedValues.keyCode || 0,
location: 0,
location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false,
value: gCurrentValue,
shift: false,
@ -145,7 +145,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: expectedValues.charCode,
code: expectedValues.code || '',
keyCode: expectedValues.charCode ? 0 : expectedValues.keyCode,
location: 0,
location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false,
value: gCurrentValue,
shift: false,
@ -156,9 +156,22 @@ function sendKeyAndAssertResult(testdata) {
}
if (testdata.expectedInput) {
switch (testdata.expectedInput) {
case 'Enter':
gCurrentValue += '\n';
break;
case 'Backspace':
gCurrentValue =
gCurrentValue.substr(0, gCurrentValue.length - 1);
break;
default:
gCurrentValue += testdata.expectedInput;
break;
}
expectedEventDetail.push({
type: 'input',
value: gCurrentValue += testdata.expectedInput
value: gCurrentValue
});
}
@ -169,7 +182,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: 0,
code: expectedValues.code || '',
keyCode: expectedValues.keyCode || 0,
location: 0,
location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false,
value: gCurrentValue,
shift: false,
@ -1052,6 +1065,117 @@ function runSendKeyEnterTests() {
return promiseQueue;
}
function runSendKeyNumpadTests() {
gTestDescription = 'runSendKeyNumpadTests(): ';
var promiseQueue = Promise.resolve();
var tests = [];
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
.forEach(function(key) {
let charCode = key.charCodeAt(0);
tests.push({
dict: {
key: key,
code: 'Numpad' + key
},
expectedKeypress: true,
expectedInput: key,
expectedValues: {
key: key, code: 'Numpad' + key,
keyCode: charCode, charCode: charCode,
location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD
}
});
});
[['+', 'NumpadAdd'],
[',', 'NumpadComma'],
['.', 'NumpadDecimal'],
['.', 'NumpadComma'], // Locale-specific NumpadComma
[',', 'NumpadDecimal'], // Locale-specific NumpadDecimal
['/', 'NumpadDivide'],
['=', 'NumpadEqual'],
// ['#', 'NumpadHash'], // Not supported yet.
['*', 'NumpadMultiply'],
['(', 'NumpadParenLeft'],
[')', 'NumpadParenRight'],
// ['*', 'NumpadStar'], // Not supported yet.
['-', 'NumpadSubtract']].forEach(function([key, code]) {
tests.push({
dict: {
key: key,
code: code
},
expectedKeypress: true,
expectedInput: key,
expectedValues: {
key: key, code: code, keyCode: 0, charCode: key.charCodeAt(0),
location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD
}
});
});
[
'NumpadComma', // Locale-specific NumpadComma -- outputs nothing
'NumpadClear',
'NumpadClearEntry',
'NumpadMemoryAdd',
'NumpadMemoryClear',
'NumpadMemoryRecall',
'NumpadMemoryStore',
'NumpadMemorySubtract'
].forEach(function(code) {
tests.push({
dict: {
key: 'Unidentified',
code: code
},
expectedKeypress: true,
expectedValues: {
key: 'Unidentified', code: code, keyCode: 0, charCode: 0,
location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD
}
});
});
tests.push({
dict: {
key: 'Enter',
code: 'NumpadEnter'
},
expectedKeypress: true,
expectedInput: '\n',
expectedValues: {
key: 'Enter', code: 'NumpadEnter',
keyCode: KeyboardEvent.DOM_VK_RETURN, charCode: 0,
location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD
}
});
tests.push({
dict: {
key: 'Backspace',
code: 'NumpadBackspace'
},
expectedKeypress: true,
expectedInput: 'Backspace', // Special value
expectedValues: {
key: 'Backspace', code: 'NumpadBackspace',
keyCode: KeyboardEvent.DOM_VK_BACK_SPACE, charCode: 0,
location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD
}
});
tests.forEach((test) => {
promiseQueue = promiseQueue.then(() => {
return sendKeyAndAssertResult(test);
});
});
return promiseQueue;
}
function runSendKeyRejectionTests() {
gTestDescription = 'runSendKeyRejectionTests(): ';
var promiseQueue = Promise.resolve();
@ -1636,6 +1760,7 @@ function runTest() {
.then(() => runSendKeyUSKeyboardSymbolsTests())
.then(() => runSendKeyGreekLettersTests())
.then(() => runSendKeyEnterTests())
.then(() => runSendKeyNumpadTests())
.then(() => runSendKeyRejectionTests())
.then(() => runCompositionWithKeyEventTests())
.then(() => runCompositionWithoutKeyEventTests())

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

@ -184,7 +184,7 @@ static char const *const gWebMCodecs[7] = {
#endif
/* static */ bool
DecoderTraits::IsWebMType(const nsACString& aType)
DecoderTraits::IsWebMTypeAndEnabled(const nsACString& aType)
{
#ifdef MOZ_WEBM
if (!MediaDecoder::IsWebMEnabled()) {
@ -200,7 +200,7 @@ DecoderTraits::IsWebMType(const nsACString& aType)
static bool
IsGStreamerSupportedType(const nsACString& aMimeType)
{
if (DecoderTraits::IsWebMType(aMimeType))
if (DecoderTraits::IsWebMTypeAndEnabled(aMimeType))
return false;
if (!MediaDecoder::IsGStreamerEnabled())
@ -352,7 +352,7 @@ IsMP4SupportedType(const nsACString& aType,
#endif
/* static */ bool
DecoderTraits::IsMP4Type(const nsACString& aType)
DecoderTraits::IsMP4TypeAndEnabled(const nsACString& aType)
{
#ifdef MOZ_FMP4
return IsMP4SupportedType(aType);
@ -364,6 +364,9 @@ static bool
IsMP3SupportedType(const nsACString& aType,
const nsAString& aCodecs = EmptyString())
{
#ifdef MOZ_OMX_DECODER
return false;
#endif
return MP3Decoder::CanHandleMediaType(aType, aCodecs);
}
@ -435,12 +438,12 @@ DecoderTraits::CanHandleCodecsType(const char* aMIMEType,
}
#endif
#if !defined(MOZ_OMX_WEBM_DECODER)
if (IsWebMType(nsDependentCString(aMIMEType))) {
if (IsWebMTypeAndEnabled(nsDependentCString(aMIMEType))) {
codecList = gWebMCodecs;
}
#endif
#ifdef MOZ_FMP4
if (IsMP4Type(nsDependentCString(aMIMEType))) {
if (IsMP4TypeAndEnabled(nsDependentCString(aMIMEType))) {
if (IsMP4SupportedType(nsDependentCString(aMIMEType), aRequestedCodecs)) {
return CANPLAY_YES;
} else {
@ -530,11 +533,11 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
return CANPLAY_MAYBE;
}
#endif
if (IsMP4Type(nsDependentCString(aMIMEType))) {
if (IsMP4TypeAndEnabled(nsDependentCString(aMIMEType))) {
return CANPLAY_MAYBE;
}
#if !defined(MOZ_OMX_WEBM_DECODER)
if (IsWebMType(nsDependentCString(aMIMEType))) {
if (IsWebMTypeAndEnabled(nsDependentCString(aMIMEType))) {
return CANPLAY_MAYBE;
}
#endif
@ -662,7 +665,7 @@ InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
return decoder.forget();
}
#endif
if (DecoderTraits::IsWebMType(aType)) {
if (DecoderTraits::IsWebMTypeAndEnabled(aType)) {
decoder = new WebMDecoder(aOwner);
return decoder.forget();
}
@ -744,7 +747,7 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
decoderReader = new AndroidMediaReader(aDecoder, aType);
} else
#endif
if (IsWebMType(aType)) {
if (IsWebMTypeAndEnabled(aType)) {
decoderReader = Preferences::GetBool("media.format-reader.webm", true) ?
static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()))) :
new WebMReader(aDecoder);
@ -784,7 +787,7 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
(IsOmxSupportedType(aType) &&
!IsB2GSupportOnlyType(aType)) ||
#endif
IsWebMType(aType) ||
IsWebMTypeAndEnabled(aType) ||
#ifdef MOZ_GSTREAMER
IsGStreamerSupportedType(aType) ||
#endif

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

@ -70,8 +70,8 @@ public:
// OnConnected signal. (currently RTSP only)
static bool DecoderWaitsForOnConnected(const nsACString& aType);
static bool IsWebMType(const nsACString& aType);
static bool IsMP4Type(const nsACString& aType);
static bool IsWebMTypeAndEnabled(const nsACString& aType);
static bool IsMP4TypeAndEnabled(const nsACString& aType);
};
} // namespace mozilla

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

@ -69,6 +69,21 @@ static const char* const gMediaSourceTypes[6] = {
nullptr
};
// Returns true if we should enable MSE webm regardless of preferences.
// 1. If MP4/H264 isn't supported:
// * Windows XP
// * Windows Vista and Server 2008 without the optional "Platform Update Supplement"
// * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
// optional "Windows Media Feature Pack"
static bool
IsWebMForced()
{
bool mp4supported =
DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"));
return !mp4supported;
}
static nsresult
IsTypeSupported(const nsAString& aType)
{
@ -88,7 +103,7 @@ IsTypeSupported(const nsAString& aType)
for (uint32_t i = 0; gMediaSourceTypes[i]; ++i) {
if (mimeType.EqualsASCII(gMediaSourceTypes[i])) {
if (DecoderTraits::IsMP4Type(mimeTypeUTF8)) {
if (DecoderTraits::IsMP4TypeAndEnabled(mimeTypeUTF8)) {
if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
@ -98,8 +113,9 @@ IsTypeSupported(const nsAString& aType)
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
return NS_OK;
} else if (DecoderTraits::IsWebMType(mimeTypeUTF8)) {
if (!Preferences::GetBool("media.mediasource.webm.enabled", false)) {
} else if (DecoderTraits::IsWebMTypeAndEnabled(mimeTypeUTF8)) {
if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
IsWebMForced())) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
if (hasCodecs &&

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

@ -376,7 +376,13 @@ TrackBuffersManager::CompleteResetParserState()
// to discard now.
track->mQueuedSamples.Clear();
}
// 6. Remove all bytes from the input buffer.
// 6. If the mode attribute equals "sequence", then set the group start timestamp to the group end timestamp
if (mSourceBufferAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence) {
mGroupStartTimestamp = Some(mGroupEndTimestamp);
}
// 7. Remove all bytes from the input buffer.
mIncomingBuffers.Clear();
mInputBuffer = nullptr;
if (mCurrentInputBuffer) {
@ -401,7 +407,7 @@ TrackBuffersManager::CompleteResetParserState()
}
RecreateParser(true);
// 7. Set append state to WAITING_FOR_SEGMENT.
// 8. Set append state to WAITING_FOR_SEGMENT.
SetAppendState(AppendState::WAITING_FOR_SEGMENT);
// Reject our promise immediately.

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

@ -100,7 +100,7 @@ nsresult
DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
nsCOMPtr<nsIStreamListener>& aInAndOutListener)
{
MOZ_ASSERT(aInAndOutListener, "can not perform CORS checks without a listener");
MOZ_RELEASE_ASSERT(aInAndOutListener, "can not perform CORS checks without a listener");
nsIPrincipal* loadingPrincipal = aLoadInfo->LoadingPrincipal();
RefPtr<nsCORSListenerProxy> corsListener =
new nsCORSListenerProxy(aInAndOutListener,

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

@ -156,7 +156,6 @@ DOMSVGPathSeg::IndexIsValid()
// Implementation of DOMSVGPathSeg sub-classes below this point
#define IMPL_PROP_WITH_TYPE(segName, propName, index, type) \
/* attribute type propName; */ \
type \
DOMSVGPathSeg##segName::propName() \
{ \

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

@ -338,7 +338,6 @@ StumblerInfo::DumpStumblerInfo()
target->Dispatch(event, NS_DISPATCH_NORMAL);
}
/* void notifyGetCellInfoList (in uint32_t count, [array, size_is (count)] in nsICellInfo result); */
NS_IMETHODIMP
StumblerInfo::NotifyGetCellInfoList(uint32_t count, nsICellInfo** aCellInfos)
{
@ -353,7 +352,6 @@ StumblerInfo::NotifyGetCellInfoList(uint32_t count, nsICellInfo** aCellInfos)
return NS_OK;
}
/* void notifyGetCellInfoListFailed (in DOMString error); */
NS_IMETHODIMP StumblerInfo::NotifyGetCellInfoListFailed(const nsAString& error)
{
MOZ_ASSERT(NS_IsMainThread());

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

@ -102,7 +102,9 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMDocument> xslDocument;
rv = nsSyncLoadService::LoadDocument(xslUri, nsContentUtils::GetSystemPrincipal(),
rv = nsSyncLoadService::LoadDocument(xslUri, nsIContentPolicy::TYPE_XSLT,
nsContentUtils::GetSystemPrincipal(),
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nullptr, true, mozilla::net::RP_Default,
getter_AddRefs(xslDocument));
NS_ENSURE_SUCCESS(rv, rv);

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

@ -15,8 +15,10 @@
#include "nsIPrincipal.h"
nsresult
txParseDocumentFromURI(const nsAString& aHref, const txXPathNode& aLoader,
nsAString& aErrMsg, txXPathNode** aResult)
txParseDocumentFromURI(const nsAString& aHref,
const txXPathNode& aLoader,
nsAString& aErrMsg,
txXPathNode** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
@ -36,7 +38,9 @@ txParseDocumentFromURI(const nsAString& aHref, const txXPathNode& aLoader,
nsIDOMDocument* theDocument = nullptr;
nsAutoSyncOperation sync(loaderDocument);
rv = nsSyncLoadService::LoadDocument(documentURI,
nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
loaderDocument->NodePrincipal(),
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
loadGroup, true,
loaderDocument->GetReferrerPolicy(),
&theDocument);

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

@ -629,20 +629,6 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
// Content Policy
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_STYLESHEET,
uri,
referrerPrincipal,
nullptr,
NS_LITERAL_CSTRING("application/xml"),
nullptr,
&shouldLoad);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_CP_REJECTED(shouldLoad)) {
return NS_ERROR_DOM_BAD_URI;
}
// This is probably called by js, a loadGroup for the channel doesn't
// make sense.
nsCOMPtr<nsINode> source;
@ -652,8 +638,12 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
}
nsAutoSyncOperation sync(source ? source->OwnerDoc() : nullptr);
nsCOMPtr<nsIDOMDocument> document;
rv = nsSyncLoadService::LoadDocument(uri, referrerPrincipal, nullptr,
false, aReferrerPolicy,
rv = nsSyncLoadService::LoadDocument(uri, nsIContentPolicy::TYPE_XSLT,
referrerPrincipal,
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
nullptr, false,
aReferrerPolicy,
getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);

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

@ -85,10 +85,6 @@ NS_IMETHODIMP nsTransactionList::ItemIsBatch(int32_t aIndex, bool *aIsBatch)
return item->GetIsBatch(aIsBatch);
}
/* void getData (in long aIndex,
[optional] out unsigned long aLength,
[array, size_is (aLength), retval]
out nsISupports aData); */
NS_IMETHODIMP nsTransactionList::GetData(int32_t aIndex,
uint32_t *aLength,
nsISupports ***aData)

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

@ -415,9 +415,6 @@ NS_IMETHODIMP nsWebBrowserPersist::SetProgressListener(
return NS_OK;
}
/* void saveURI (in nsIURI aURI, in nsISupports aCacheKey, in nsIURI aReferrer,
in nsIInputStream aPostData, in wstring aExtraHeaders,
in nsISupports aFile, in nsILoadContext aPrivayContext); */
NS_IMETHODIMP nsWebBrowserPersist::SaveURI(
nsIURI *aURI, nsISupports *aCacheKey,
nsIURI *aReferrer, uint32_t aReferrerPolicy,
@ -533,7 +530,6 @@ NS_IMETHODIMP nsWebBrowserPersist::SaveDocument(
return rv;
}
/* void cancel(nsresult aReason); */
NS_IMETHODIMP nsWebBrowserPersist::Cancel(nsresult aReason)
{
mCancel = true;
@ -1002,8 +998,6 @@ nsWebBrowserPersist::OnDataAvailable(
// nsWebBrowserPersist::nsIProgressEventSink
//*****************************************************************************
/* void onProgress (in nsIRequest request, in nsISupports ctxt,
in long long aProgress, in long long aProgressMax); */
NS_IMETHODIMP nsWebBrowserPersist::OnProgress(
nsIRequest *request, nsISupports *ctxt, int64_t aProgress,
int64_t aProgressMax)
@ -1055,8 +1049,6 @@ NS_IMETHODIMP nsWebBrowserPersist::OnProgress(
return NS_OK;
}
/* void onStatus (in nsIRequest request, in nsISupports ctxt,
in nsresult status, in wstring statusArg); */
NS_IMETHODIMP nsWebBrowserPersist::OnStatus(
nsIRequest *request, nsISupports *ctxt, nsresult status,
const char16_t *statusArg)

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

@ -546,20 +546,17 @@ typedef Log<LOG_CRITICAL, CriticalLogger> CriticalLog;
// firstTime = false;
// gfxCriticalError() << "This message only shows up once;
// }
#ifdef GFX_LOG_DEBUG
#if defined(DEBUG)
#define gfxDebug mozilla::gfx::DebugLog
#define gfxDebugOnce static gfxDebug GFX_LOGGING_GLUE(sOnceAtLine,__LINE__) = gfxDebug
#else
#define gfxDebug if (1) ; else mozilla::gfx::NoLog
#define gfxDebugOnce if (1) ; else mozilla::gfx::NoLog
#endif
#ifdef GFX_LOG_WARNING
// Have gfxWarning available (behind a runtime preference)
#define gfxWarning mozilla::gfx::WarningLog
#define gfxWarningOnce static gfxWarning GFX_LOGGING_GLUE(sOnceAtLine,__LINE__) = gfxWarning
#else
#define gfxWarning if (1) ; else mozilla::gfx::NoLog
#define gfxWarningOnce if (1) ; else mozilla::gfx::NoLog
#endif
// In the debug build, this is equivalent to the default gfxCriticalError.
// In the non-debug build, on nightly and dev edition, it will MOZ_CRASH.

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

@ -42,7 +42,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>USE_SSE2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
<PreprocessorDefinitions>USE_SSE2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@ -62,7 +62,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_WARNING</PreprocessorDefinitions>
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

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

@ -179,17 +179,6 @@ for var in ('USE_CAIRO', 'MOZ2D_HAS_MOZ_CAIRO'):
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'):
DEFINES['MOZ_ENABLE_FREETYPE'] = True
if CONFIG['MOZ_DEBUG']:
DEFINES['GFX_LOG_DEBUG'] = True
DEFINES['GFX_LOG_WARNING'] = True
# Define the GFX_LOG_WARNING in release builds (available, but controlled by a
# preference), though we may want to consider only doing it in the nightly
# build, if the size of gfxWarning() code ends up making a difference.
# See bug 1074952.
# if CONFIG['NIGHTLY_BUILD']:
DEFINES['GFX_LOG_WARNING'] = True
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'):

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

@ -11,6 +11,13 @@
#include "gfx2DGlue.h"
#include "nsAppRunner.h"
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include "libdisplay/GonkDisplay.h" // for GonkDisplay
#include <ui/Fence.h>
#include "nsWindow.h"
#include "nsScreenManagerGonk.h"
#endif
namespace mozilla {
namespace gfx {
class Matrix4x4;
@ -353,5 +360,49 @@ DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
return 4;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)
{
// OpenGL does not provide ReleaseFence for rendering.
// Instead use DispAcquireFence as layer buffer's ReleaseFence
// to prevent flickering and tearing.
// DispAcquireFence is DisplaySurface's AcquireFence.
// AcquireFence will be signaled when a buffer's content is available.
// See Bug 974152.
if (!aLayer || !aWidget) {
return;
}
nsWindow* window = static_cast<nsWindow*>(aWidget);
RefPtr<FenceHandle::FdObj> fence = new FenceHandle::FdObj(
window->GetScreen()->GetPrevDispAcquireFd());
mReleaseFenceHandle.Merge(FenceHandle(fence));
}
FenceHandle
Compositor::GetReleaseFence()
{
if (!mReleaseFenceHandle.IsValid()) {
return FenceHandle();
}
RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetDupFdObj();
return FenceHandle(fdObj);
}
#else
void
Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)
{
}
FenceHandle
Compositor::GetReleaseFence()
{
return FenceHandle();
}
#endif
} // namespace layers
} // namespace mozilla

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

@ -370,12 +370,9 @@ public:
*/
virtual void EndFrame() = 0;
virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) {}
virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget);
virtual FenceHandle GetReleaseFence()
{
return FenceHandle();
}
virtual FenceHandle GetReleaseFence();
/**
* Post-rendering stuff if the rendering is done outside of this Compositor
@ -541,6 +538,10 @@ protected:
RefPtr<gfx::DrawTarget> mTarget;
gfx::IntRect mTargetBounds;
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
FenceHandle mReleaseFenceHandle;
#endif
private:
static LayersBackend sBackend;

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

@ -397,18 +397,15 @@ ConvertOmxYUVFormatToRGB565(android::sp<GraphicBuffer>& aBuffer,
return OK;
}
already_AddRefed<gfx::SourceSurface>
GrallocImage::GetAsSourceSurface()
already_AddRefed<gfx::DataSourceSurface>
GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
gfx::IntSize aSize,
const layers::PlanarYCbCrData& aYcbcrData)
{
if (!mTextureClient) {
return nullptr;
}
android::sp<GraphicBuffer> graphicBuffer =
mTextureClient->GetGraphicBuffer();
MOZ_ASSERT(aGraphicBuffer.get());
RefPtr<gfx::DataSourceSurface> surface =
gfx::Factory::CreateDataSourceSurface(GetSize(), gfx::SurfaceFormat::R5G6B5);
gfx::Factory::CreateDataSourceSurface(aSize, gfx::SurfaceFormat::R5G6B5);
if (NS_WARN_IF(!surface)) {
return nullptr;
}
@ -420,13 +417,13 @@ GrallocImage::GetAsSourceSurface()
}
int32_t rv;
rv = ConvertOmxYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface, mData);
rv = ConvertOmxYUVFormatToRGB565(aGraphicBuffer, surface, &mappedSurface, aYcbcrData);
if (rv == OK) {
surface->Unmap();
return surface.forget();
}
rv = ConvertVendorYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface);
rv = ConvertVendorYUVFormatToRGB565(aGraphicBuffer, surface, &mappedSurface);
surface->Unmap();
if (rv != OK) {
NS_WARNING("Unknown color format");
@ -436,6 +433,22 @@ GrallocImage::GetAsSourceSurface()
return surface.forget();
}
already_AddRefed<gfx::SourceSurface>
GrallocImage::GetAsSourceSurface()
{
if (!mTextureClient) {
return nullptr;
}
android::sp<GraphicBuffer> graphicBuffer =
mTextureClient->GetGraphicBuffer();
RefPtr<gfx::DataSourceSurface> surface =
GetDataSourceSurfaceFrom(graphicBuffer, mSize, mData);
return surface.forget();
}
android::sp<android::GraphicBuffer>
GrallocImage::GetGraphicBuffer() const
{

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

@ -22,6 +22,11 @@ namespace layers {
class GrallocTextureClientOGL;
already_AddRefed<gfx::DataSourceSurface>
GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
gfx::IntSize aSize,
const layers::PlanarYCbCrData& aYcbcrData);
/**
* The YUV format supported by Android HAL
*

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

@ -0,0 +1,291 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#include "GrallocTextureHostBasic.h"
#include "GrallocImages.h" // for GetDataSourceSurfaceFrom()
#include "mozilla/layers/SharedBufferManagerParent.h"
#if ANDROID_VERSION >= 17
#include <ui/Fence.h>
#endif
namespace mozilla {
namespace layers {
static SurfaceFormat
HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
{
bool swapRB = bool(aFlags & TextureFlags::RB_SWAPPED);
switch (aHalFormat) {
case android::PIXEL_FORMAT_BGRA_8888:
return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8;
case android::PIXEL_FORMAT_RGBA_8888:
return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8;
case android::PIXEL_FORMAT_RGBX_8888:
return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8;
case android::PIXEL_FORMAT_RGB_565:
return gfx::SurfaceFormat::R5G6B5;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YV12:
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
#endif
// Needs convert to RGB565
return gfx::SurfaceFormat::R5G6B5;
default:
if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) {
// Reserved range for HAL specific formats.
// Needs convert to RGB565
return gfx::SurfaceFormat::R5G6B5;
} else {
MOZ_CRASH("Unhandled HAL pixel format");
return SurfaceFormat::UNKNOWN; // not reached
}
}
}
static bool
NeedsConvertFromYUVtoRGB565(int aHalFormat)
{
switch (aHalFormat) {
case android::PIXEL_FORMAT_BGRA_8888:
case android::PIXEL_FORMAT_RGBA_8888:
case android::PIXEL_FORMAT_RGBX_8888:
case android::PIXEL_FORMAT_RGB_565:
return false;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YV12:
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
#endif
return true;
default:
if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) {
// Reserved range for HAL specific formats.
return true;
} else {
MOZ_CRASH("Unhandled HAL pixel format");
return false; // not reached
}
}
}
GrallocTextureHostBasic::GrallocTextureHostBasic(
TextureFlags aFlags,
const NewSurfaceDescriptorGralloc& aDescriptor)
: TextureHost(aFlags)
, mGrallocHandle(aDescriptor)
, mSize(0, 0)
, mCropSize(0, 0)
, mFormat(gfx::SurfaceFormat::UNKNOWN)
, mIsOpaque(aDescriptor.isOpaque())
{
android::GraphicBuffer* grallocBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
MOZ_ASSERT(grallocBuffer);
if (grallocBuffer) {
mFormat =
HalFormatToSurfaceFormat(grallocBuffer->getPixelFormat(),
aFlags & TextureFlags::RB_SWAPPED);
mSize = gfx::IntSize(grallocBuffer->getWidth(), grallocBuffer->getHeight());
mCropSize = mSize;
} else {
printf_stderr("gralloc buffer is nullptr\n");
}
}
bool
GrallocTextureHostBasic::Lock()
{
if (!mCompositor || !IsValid()) {
return false;
}
if (mTextureSource) {
return true;
}
android::sp<android::GraphicBuffer> graphicBuffer =
GetGraphicBufferFromDesc(mGrallocHandle);
MOZ_ASSERT(graphicBuffer.get());
RefPtr<gfx::DataSourceSurface> surf;
if (NeedsConvertFromYUVtoRGB565(graphicBuffer->getPixelFormat())) {
PlanarYCbCrData ycbcrData;
surf = GetDataSourceSurfaceFrom(graphicBuffer,
mCropSize,
ycbcrData);
} else {
uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN;
int32_t rv = graphicBuffer->lock(usage,
reinterpret_cast<void**>(&mMappedBuffer));
if (rv) {
mMappedBuffer = nullptr;
NS_WARNING("Couldn't lock graphic buffer");
return false;
}
surf = Factory::CreateWrappingDataSourceSurface(
mMappedBuffer,
graphicBuffer->getStride() * gfx::BytesPerPixel(mFormat),
mCropSize,
mFormat);
}
mTextureSource = mCompositor->CreateDataTextureSource(mFlags);
mTextureSource->Update(surf, nullptr);
return true;
}
bool
GrallocTextureHostBasic::IsValid() const
{
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
return graphicBuffer != nullptr;
}
bool
GrallocTextureHostBasic::BindTextureSource(CompositableTextureSourceRef& aTexture)
{
aTexture = mTextureSource;
return !!aTexture;
}
void
GrallocTextureHostBasic::UnbindTextureSource()
{
ClearTextureSource();
}
void
GrallocTextureHostBasic::ClearTextureSource()
{
mTextureSource = nullptr;
if (mMappedBuffer) {
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
MOZ_ASSERT(graphicBuffer);
mMappedBuffer = nullptr;
graphicBuffer->unlock();
}
}
void
GrallocTextureHostBasic::SetCompositor(Compositor* aCompositor)
{
BasicCompositor* compositor = static_cast<BasicCompositor*>(aCompositor);
mCompositor = compositor;
if (mTextureSource) {
mTextureSource->SetCompositor(compositor);
}
}
gfx::SurfaceFormat
GrallocTextureHostBasic::GetFormat() const {
return mFormat;
}
void
GrallocTextureHostBasic::WaitAcquireFenceHandleSyncComplete()
{
if (!mAcquireFenceHandle.IsValid()) {
return;
}
#if ANDROID_VERSION >= 17
RefPtr<FenceHandle::FdObj> fdObj = mAcquireFenceHandle.GetAndResetFdObj();
android::sp<android::Fence> fence(
new android::Fence(fdObj->GetAndResetFd()));
// Wait fece complete with timeout.
// If a source of the fence becomes invalid because of error,
// fene complete is not signaled. See Bug 1061435.
int rv = fence->wait(400 /*400 msec*/);
if (rv != android::OK) {
NS_ERROR("failed to wait fence complete");
}
#endif
}
void
GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect)
{
MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0));
MOZ_ASSERT(!aCropRect.IsEmpty());
MOZ_ASSERT(aCropRect.width <= mSize.width);
MOZ_ASSERT(aCropRect.height <= mSize.height);
gfx::IntSize cropSize(aCropRect.width, aCropRect.height);
if (mCropSize == cropSize) {
return;
}
mCropSize = cropSize;
ClearTextureSource();
}
void
GrallocTextureHostBasic::DeallocateSharedData()
{
ClearTextureSource();
if (mGrallocHandle.buffer().type() != MaybeMagicGrallocBufferHandle::Tnull_t) {
MaybeMagicGrallocBufferHandle handle = mGrallocHandle.buffer();
base::ProcessId owner;
if (handle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
owner = handle.get_GrallocBufferRef().mOwner;
}
else {
owner = handle.get_MagicGrallocBufferHandle().mRef.mOwner;
}
SharedBufferManagerParent::DropGrallocBuffer(owner, mGrallocHandle);
}
}
void
GrallocTextureHostBasic::ForgetSharedData()
{
ClearTextureSource();
}
void
GrallocTextureHostBasic::DeallocateDeviceData()
{
ClearTextureSource();
}
LayerRenderState
GrallocTextureHostBasic::GetRenderState()
{
android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
if (graphicBuffer) {
LayerRenderStateFlags flags = LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT;
if (mIsOpaque) {
flags |= LayerRenderStateFlags::OPAQUE;
}
if (mFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) {
flags |= LayerRenderStateFlags::ORIGIN_BOTTOM_LEFT;
}
if (mFlags & TextureFlags::RB_SWAPPED) {
flags |= LayerRenderStateFlags::FORMAT_RB_SWAP;
}
return LayerRenderState(graphicBuffer,
mCropSize,
flags,
this);
}
return LayerRenderState();
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
#ifndef MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H
#define MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H
#include "mozilla/layers/BasicCompositor.h"
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include "mozilla/layers/TextureHostBasic.h"
namespace mozilla {
namespace layers {
class BasicCompositor;
/**
* A TextureHost for shared gralloc
*
* Most of the logic actually happens in GrallocTextureSourceBasic.
*/
class GrallocTextureHostBasic : public TextureHost
{
public:
GrallocTextureHostBasic(TextureFlags aFlags,
const NewSurfaceDescriptorGralloc& aDescriptor);
virtual void SetCompositor(Compositor* aCompositor) override;
virtual bool Lock() override;
virtual gfx::SurfaceFormat GetFormat() const override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
virtual void UnbindTextureSource() override;
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
{
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
virtual void WaitAcquireFenceHandleSyncComplete() override;
virtual gfx::IntSize GetSize() const override { return mCropSize; }
virtual void SetCropRect(nsIntRect aCropRect) override;
virtual void DeallocateSharedData() override;
virtual void ForgetSharedData() override;
virtual void DeallocateDeviceData() override;
virtual LayerRenderState GetRenderState() override;
bool IsValid() const;
void ClearTextureSource();
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() override { return "GrallocTextureHostBasic"; }
#endif
protected:
RefPtr<BasicCompositor> mCompositor;
RefPtr<DataTextureSource> mTextureSource;
NewSurfaceDescriptorGralloc mGrallocHandle;
// gralloc buffer size.
gfx::IntSize mSize;
// Size reported by TextureClient, can be different in some cases (video?),
// used by LayerRenderState.
gfx::IntSize mCropSize;
gfx::SurfaceFormat mFormat;
bool mIsOpaque;
/**
* Points to a mapped gralloc buffer when TextureSource is valid.
*/
uint8_t* mMappedBuffer;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H

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

@ -7,6 +7,9 @@
#ifdef XP_MACOSX
#include "MacIOSurfaceTextureHostBasic.h"
#endif
#ifdef MOZ_WIDGET_GONK
#include "GrallocTextureHostBasic.h"
#endif
using namespace mozilla::gl;
using namespace mozilla::gfx;
@ -25,6 +28,13 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
aDesc.get_SurfaceDescriptorMacIOSurface();
return MakeAndAddRef<MacIOSurfaceTextureHostBasic>(aFlags, desc);
}
#endif
#ifdef MOZ_WIDGET_GONK
if (aDesc.type() == SurfaceDescriptor::TNewSurfaceDescriptorGralloc) {
const NewSurfaceDescriptorGralloc& desc =
aDesc.get_NewSurfaceDescriptorGralloc();
return MakeAndAddRef<GrallocTextureHostBasic>(aFlags, desc);
}
#endif
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
}

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

@ -14,9 +14,12 @@
#include "SharedSurface.h"
#ifdef MOZ_WIDGET_GONK
#include "mozilla/layers/GrallocTextureClient.h"
#include "SharedSurfaceGralloc.h"
#endif
using namespace mozilla::gl;
namespace mozilla {
namespace layers {

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

@ -214,10 +214,10 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (aBackend == LayersBackend::LAYERS_OPENGL) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);

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

@ -670,6 +670,9 @@ SharedTextureClientD3D9::SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
SharedTextureClientD3D9::~SharedTextureClientD3D9()
{
MOZ_COUNT_DTOR(SharedTextureClientD3D9);
if (mTexture) {
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
}
}
void
@ -678,9 +681,6 @@ SharedTextureClientD3D9::FinalizeOnIPDLThread()
if (mTexture && mActor) {
KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
}
if (mTexture) {
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
}
}
// static

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

@ -217,9 +217,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
# has full system permissions there.
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXPORTS.mozilla.layers += [
'basic/GrallocTextureHostBasic.h',
'ipc/ShadowLayerUtilsGralloc.h',
]
UNIFIED_SOURCES += [
'basic/GrallocTextureHostBasic.cpp',
'GrallocImages.cpp',
'opengl/EGLImageHelpers.cpp',
'opengl/GrallocTextureClient.cpp',

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

@ -51,13 +51,6 @@
#include "GeckoProfiler.h"
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include "libdisplay/GonkDisplay.h" // for GonkDisplay
#include <ui/Fence.h>
#include "nsWindow.h"
#include "nsScreenManagerGonk.h"
#endif
namespace mozilla {
using namespace std;
@ -1458,50 +1451,6 @@ CompositorOGL::EndFrame()
}
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
CompositorOGL::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)
{
// OpenGL does not provide ReleaseFence for rendering.
// Instead use DispAcquireFence as layer buffer's ReleaseFence
// to prevent flickering and tearing.
// DispAcquireFence is DisplaySurface's AcquireFence.
// AcquireFence will be signaled when a buffer's content is available.
// See Bug 974152.
if (!aLayer || !aWidget) {
return;
}
nsWindow* window = static_cast<nsWindow*>(aWidget);
RefPtr<FenceHandle::FdObj> fence = new FenceHandle::FdObj(
window->GetScreen()->GetPrevDispAcquireFd());
mReleaseFenceHandle.Merge(FenceHandle(fence));
}
FenceHandle
CompositorOGL::GetReleaseFence()
{
if (!mReleaseFenceHandle.IsValid()) {
return FenceHandle();
}
RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetDupFdObj();
return FenceHandle(fdObj);
}
#else
void
CompositorOGL::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)
{
}
FenceHandle
CompositorOGL::GetReleaseFence()
{
return FenceHandle();
}
#endif
void
CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform)
{

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

@ -232,8 +232,6 @@ public:
const gfx::Rect& aVisibleRect) override;
virtual void EndFrame() override;
virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) override;
virtual FenceHandle GetReleaseFence() override;
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override;
virtual bool SupportsPartialTextureUpdate() override;
@ -452,7 +450,6 @@ private:
*/
gfx::IntSize mViewportSize;
FenceHandle mReleaseFenceHandle;
ShaderProgramOGL *mCurrentProgram;
gfx::Rect mRenderBound;

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

@ -118,7 +118,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight());
mCropSize = mSize;
} else {
printf_stderr("gralloc buffer is nullptr");
printf_stderr("gralloc buffer is nullptr\n");
}
}
@ -419,7 +419,7 @@ GrallocTextureHostOGL::WaitAcquireFenceHandleSyncComplete()
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(),
sync,
0,
400000000 /*400 usec*/);
400000000 /*400 msec*/);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
NS_ERROR("failed to wait native fence sync");
}

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

@ -0,0 +1,5 @@
<!DOCTYPE HTML>
<html style="font-size: 70368744177663%; -moz-background-size: 2199023255552em 809464690865px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4%2F58BAAT%2FAf9jgNErAAAAAElFTkSuQmCC);">
<body>
</body>
</html>

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

@ -0,0 +1,2 @@
<html><body style="font-size-adjust: -18446744073709552000; font-weight: bold;">&#x9385;</body></html>

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

@ -0,0 +1 @@
<html style="-moz-box-shadow: 0 0 0.2em blue; -moz-appearance: button;"><body style="padding: 113in;"></body></html>

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

@ -79,10 +79,12 @@ load 483120-2.xhtml
load 487549-1.html
load 487724-1.html
load 490777-1.html
load 516512-1.html
load 532726-1.html
load 538065-1.html
load 546870-1.html
load 557348-1.html
load 563740-1.html
load 580100-1.html
load 580212-1.html
load 580233-1.html
@ -90,6 +92,7 @@ load 580719-1.html
load 593526.html
load 593526.xul
load 594654-1.xhtml
load 595042-1.html
load 595727-1.html
load 624198.xhtml
load 633453-1.html

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

@ -163,7 +163,6 @@ RasterImage::Init(const char* aMimeType,
}
//******************************************************************************
// [notxpcom] void requestRefresh ([const] in TimeStamp aTime);
NS_IMETHODIMP_(void)
RasterImage::RequestRefresh(const TimeStamp& aTime)
{
@ -543,8 +542,6 @@ RasterImage::CopyFrame(uint32_t aWhichFrame, uint32_t aFlags)
}
//******************************************************************************
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
RasterImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
@ -972,7 +969,6 @@ RasterImage::ResetAnimation()
}
//******************************************************************************
// [notxpcom] void setAnimationStartTime ([const] in TimeStamp aTime);
NS_IMETHODIMP_(void)
RasterImage::SetAnimationStartTime(const TimeStamp& aTime)
{
@ -1478,15 +1474,6 @@ RasterImage::DrawInternal(DrawableFrameRef&& aFrameRef,
}
//******************************************************************************
/* [noscript] void draw(in gfxContext aContext,
* in Filter aFilter,
* [const] in gfxMatrix aUserSpaceToImageSpace,
* [const] in gfxRect aFill,
* [const] in IntRect aSubimage,
* [const] in IntSize aViewportSize,
* [const] in SVGImageContext aSVGContext,
* in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP_(DrawResult)
RasterImage::Draw(gfxContext* aContext,
const IntSize& aSize,

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

@ -200,9 +200,6 @@ SVGDocumentWrapper::TickRefreshDriver()
/** nsIStreamListener methods **/
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr, in unsigned long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP
SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
nsIInputStream* inStr,
@ -236,8 +233,6 @@ SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt,
in nsresult status); */
NS_IMETHODIMP
SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
nsresult status)

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

@ -683,8 +683,6 @@ VectorImage::IsOpaque()
}
//******************************************************************************
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags; */
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
VectorImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags)
{
@ -793,13 +791,6 @@ struct SVGDrawingParameters
};
//******************************************************************************
/* [noscript] void draw(in gfxContext aContext,
* [const] in nsIntSize aSize,
* [const] in ImageRegion aRegion,
* in uint32_t aWhichFrame,
* in Filter aFilter,
* [const] in MaybeSVGImageContext aSVGContext,
* in uint32_t aFlags); */
NS_IMETHODIMP_(DrawResult)
VectorImage::Draw(gfxContext* aContext,
const nsIntSize& aSize,
@ -1134,8 +1125,6 @@ VectorImage::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt)
}
//******************************************************************************
/* void onStopRequest(in nsIRequest request, in nsISupports ctxt,
in nsresult status); */
NS_IMETHODIMP
VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
nsresult aStatus)
@ -1241,9 +1230,6 @@ VectorImage::OnSVGDocumentError()
// nsIStreamListener method
//******************************************************************************
/* void onDataAvailable(in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr, in unsigned long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP
VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
nsIInputStream* aInStr, uint64_t aSourceOffset,

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

@ -60,6 +60,12 @@
// - It also added an optional color profile table after the pixel data (and
// another optional gap).
//
// WinBMPv3-ICO. This is a variant of WinBMPv3.
// - It's the BMP format used for BMP images within ICO files.
// - The only difference with WinBMPv3 is that if an image is 32bpp and has no
// compression, then instead of treating the pixel data as 0RGB it is treated
// as ARGB, but only if one or more of the A values are non-zero.
//
// OS/2 VERSIONS OF THE BMP FORMAT
// -------------------------------
// OS2-BMPv1.
@ -168,6 +174,9 @@ GetBMPLog()
nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
: Decoder(aImage)
, mLexer(Transition::To(State::FILE_HEADER, FileHeader::LENGTH))
, mIsWithinICO(false)
, mMayHaveTransparency(false)
, mDoesHaveTransparency(false)
, mNumColors(0)
, mColors(nullptr)
, mBytesPerColor(0)
@ -175,8 +184,6 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
, mCurrentRow(0)
, mCurrentPos(0)
, mAbsoluteModeNumPixels(0)
, mUseAlphaData(false)
, mHaveAlphaData(false)
{
memset(&mBFH, 0, sizeof(mBFH));
memset(&mBIH, 0, sizeof(mBIH));
@ -187,13 +194,6 @@ nsBMPDecoder::~nsBMPDecoder()
delete[] mColors;
}
// Sets whether or not the BMP will use alpha data.
void
nsBMPDecoder::SetUseAlphaData(bool useAlphaData)
{
mUseAlphaData = useAlphaData;
}
// Obtains the bits per pixel from the internal BIH header.
int32_t
nsBMPDecoder::GetBitsPerPixel() const
@ -250,7 +250,8 @@ nsBMPDecoder::FinishInternal()
nsIntRect r(0, 0, mBIH.width, GetHeight());
PostInvalidation(r);
if (mUseAlphaData && mHaveAlphaData) {
if (mDoesHaveTransparency) {
MOZ_ASSERT(mMayHaveTransparency);
PostFrameStop(Opacity::SOME_TRANSPARENCY);
} else {
PostFrameStop(Opacity::OPAQUE);
@ -268,21 +269,39 @@ BitFields::Value::Set(uint32_t aMask)
{
mMask = aMask;
// Handle this exceptional case first. The chosen values don't matter
// (because a mask of zero will always give a value of zero) except that
// mBitWidth:
// - shouldn't be zero, because that would cause an infinite loop in Get();
// - shouldn't be 5 or 8, because that could cause a false positive match in
// IsR5G5B5() or IsR8G8B8().
if (mMask == 0x0) {
mRightShift = 0;
mBitWidth = 1;
return;
}
// Find the rightmost 1.
bool started = false;
mRightShift = mBitWidth = 0;
for (uint8_t pos = 0; pos <= 31; pos++) {
if (!started && (aMask & (1 << pos))) {
mRightShift = pos;
started = true;
} else if (started && !(aMask & (1 << pos))) {
mBitWidth = pos - mRightShift;
uint8_t i;
for (i = 0; i < 32; i++) {
if (mMask & (1 << i)) {
break;
}
}
mRightShift = i;
// Now find the leftmost 1 in the same run of 1s. (If there are multiple runs
// of 1s -- which isn't valid -- we'll behave as if only the lowest run was
// present, which seems reasonable.)
for (i = i + 1; i < 32; i++) {
if (!(mMask & (1 << i))) {
break;
}
}
mBitWidth = i - mRightShift;
}
inline uint8_t
MOZ_ALWAYS_INLINE uint8_t
BitFields::Value::Get(uint32_t aValue) const
{
// Extract the unscaled value.
@ -314,6 +333,16 @@ BitFields::Value::Get(uint32_t aValue) const
return v2;
}
MOZ_ALWAYS_INLINE uint8_t
BitFields::Value::GetAlpha(uint32_t aValue, bool& aHasAlphaOut) const
{
if (mMask == 0x0) {
return 0xff;
}
aHasAlphaOut = true;
return Get(aValue);
}
MOZ_ALWAYS_INLINE uint8_t
BitFields::Value::Get5(uint32_t aValue) const
{
@ -322,6 +351,14 @@ BitFields::Value::Get5(uint32_t aValue) const
return (v << 3u) | (v >> 2u);
}
MOZ_ALWAYS_INLINE uint8_t
BitFields::Value::Get8(uint32_t aValue) const
{
MOZ_ASSERT(mBitWidth == 8);
uint32_t v = (aValue & mMask) >> mRightShift;
return v;
}
void
BitFields::SetR5G5B5()
{
@ -330,12 +367,30 @@ BitFields::SetR5G5B5()
mBlue.Set(0x001f);
}
void
BitFields::SetR8G8B8()
{
mRed.Set(0xff0000);
mGreen.Set(0xff00);
mBlue.Set(0x00ff);
}
bool
BitFields::IsR5G5B5() const
{
return mRed.mBitWidth == 5 &&
mGreen.mBitWidth == 5 &&
mBlue.mBitWidth == 5;
mBlue.mBitWidth == 5 &&
mAlpha.mMask == 0x0;
}
bool
BitFields::IsR8G8B8() const
{
return mRed.mBitWidth == 8 &&
mGreen.mBitWidth == 8 &&
mBlue.mBitWidth == 8 &&
mAlpha.mMask == 0x0;
}
uint32_t*
@ -458,6 +513,9 @@ nsBMPDecoder::ReadInfoHeaderSize(const char* aData, size_t aLength)
PostDataError();
return Transition::Terminate(State::FAILURE);
}
// ICO BMPs must have a WinVMPv3 header. nsICODecoder should have already
// terminated decoding if this isn't the case.
MOZ_ASSERT_IF(mIsWithinICO, mBIH.bihsize == InfoHeaderLength::WIN_V3);
return Transition::To(State::INFO_HEADER_REST,
mBIH.bihsize - BIHSIZE_FIELD_LENGTH);
@ -530,6 +588,7 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
// Post our size to the superclass.
uint32_t realHeight = GetHeight();
PostSize(mBIH.width, realHeight);
mCurrentRow = realHeight;
// Round it up to the nearest byte count, then pad to 4-byte boundary.
// Compute this even for a metadate decode because GetCompressedImageSize()
@ -540,24 +599,69 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
mPixelRowSize += 4 - surplus;
}
// We treat BMPs as transparent if they're 32bpp and alpha is enabled, but
// also if they use RLE encoding, because the 'delta' mode can skip pixels
// and cause implicit transparency.
bool hasTransparency = (mBIH.compression == Compression::RLE8) ||
(mBIH.compression == Compression::RLE4) ||
(mBIH.bpp == 32 && mUseAlphaData);
if (hasTransparency) {
size_t bitFieldsLengthStillToRead = 0;
if (mBIH.compression == Compression::BITFIELDS) {
// Need to read bitfields.
if (mBIH.bihsize >= InfoHeaderLength::WIN_V4) {
// Bitfields are present in the info header, so we can read them
// immediately.
mBitFields.ReadFromHeader(aData + 36, /* aReadAlpha = */ true);
} else {
// Bitfields are present after the info header, so we will read them in
// ReadBitfields().
bitFieldsLengthStillToRead = BitFields::LENGTH;
}
} else if (mBIH.bpp == 16) {
// No bitfields specified; use the default 5-5-5 values.
mBitFields.SetR5G5B5();
} else if (mBIH.bpp == 32) {
// No bitfields specified; use the default 8-8-8 values.
mBitFields.SetR8G8B8();
}
return Transition::To(State::BITFIELDS, bitFieldsLengthStillToRead);
}
void
BitFields::ReadFromHeader(const char* aData, bool aReadAlpha)
{
mRed.Set (LittleEndian::readUint32(aData + 0));
mGreen.Set(LittleEndian::readUint32(aData + 4));
mBlue.Set (LittleEndian::readUint32(aData + 8));
if (aReadAlpha) {
mAlpha.Set(LittleEndian::readUint32(aData + 12));
}
}
LexerTransition<nsBMPDecoder::State>
nsBMPDecoder::ReadBitfields(const char* aData, size_t aLength)
{
mPreGapLength += aLength;
// If aLength is zero there are no bitfields to read, or we already read them
// in ReadInfoHeader().
if (aLength != 0) {
mBitFields.ReadFromHeader(aData, /* aReadAlpha = */ false);
}
// Note that RLE-encoded BMPs might be transparent because the 'delta' mode
// can skip pixels and cause implicit transparency.
mMayHaveTransparency =
(mBIH.compression == Compression::RGB && mIsWithinICO && mBIH.bpp == 32) ||
mBIH.compression == Compression::RLE8 ||
mBIH.compression == Compression::RLE4 ||
(mBIH.compression == Compression::BITFIELDS &&
mBitFields.mAlpha.IsPresent());
if (mMayHaveTransparency) {
PostHasTransparency();
}
// If we're doing a metadata decode, we're done.
// We've now read all the headers. If we're doing a metadata decode, we're
// done.
if (IsMetadataDecode()) {
return Transition::Terminate(State::SUCCESS);
}
// We're doing a real decode.
mCurrentRow = realHeight;
// Set up the color table, if present; it'll be filled in by ReadColorTable().
if (mBIH.bpp <= 8) {
mNumColors = 1 << mBIH.bpp;
@ -588,52 +692,13 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
// BMPs store their rows in reverse order, so the downscaler needs to
// reverse them again when writing its output.
rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
mImageData, hasTransparency,
mImageData, mMayHaveTransparency,
/* aFlipVertically = */ true);
if (NS_FAILED(rv)) {
return Transition::Terminate(State::FAILURE);
}
}
size_t bitFieldsLengthStillToRead = 0;
if (mBIH.compression == Compression::BITFIELDS) {
// Need to read bitfields.
if (mBIH.bihsize >= InfoHeaderLength::WIN_V4) {
// Bitfields are present in the info header, so we can read them
// immediately.
mBitFields.ReadFromHeader(aData + 36);
} else {
// Bitfields are present after the info header, so we will read them in
// ReadBitfields().
bitFieldsLengthStillToRead = BitFields::LENGTH;
}
} else if (mBIH.bpp == 16) {
// No bitfields specified; use the default 5-5-5 values.
mBitFields.SetR5G5B5();
}
return Transition::To(State::BITFIELDS, bitFieldsLengthStillToRead);
}
void
BitFields::ReadFromHeader(const char* aData)
{
mRed.Set (LittleEndian::readUint32(aData + 0));
mGreen.Set(LittleEndian::readUint32(aData + 4));
mBlue.Set (LittleEndian::readUint32(aData + 8));
}
LexerTransition<nsBMPDecoder::State>
nsBMPDecoder::ReadBitfields(const char* aData, size_t aLength)
{
mPreGapLength += aLength;
// If aLength is zero there are no bitfields to read, or we already read them
// in ReadInfoHeader().
if (aLength != 0) {
mBitFields.ReadFromHeader(aData);
}
return Transition::To(State::COLOR_TABLE, mNumColors * mBytesPerColor);
}
@ -726,14 +791,20 @@ nsBMPDecoder::ReadPixelRow(const char* aData)
src += 2;
}
} else {
bool anyHasAlpha = false;
while (lpos > 0) {
uint16_t val = LittleEndian::readUint16(src);
SetPixel(dst, mBitFields.mRed.Get(val),
mBitFields.mGreen.Get(val),
mBitFields.mBlue.Get(val));
mBitFields.mBlue.Get(val),
mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
--lpos;
src += 2;
}
if (anyHasAlpha) {
MOZ_ASSERT(mMayHaveTransparency);
mDoesHaveTransparency = true;
}
}
break;
@ -746,18 +817,53 @@ nsBMPDecoder::ReadPixelRow(const char* aData)
break;
case 32:
while (lpos > 0) {
if (mUseAlphaData) {
if (MOZ_UNLIKELY(!mHaveAlphaData && src[3])) {
PostHasTransparency();
mHaveAlphaData = true;
if (mBIH.compression == Compression::RGB && mIsWithinICO &&
mBIH.bpp == 32) {
// This is a special case only used for 32bpp WinBMPv3-ICO files, which
// could be in either 0RGB or ARGB format.
while (lpos > 0) {
// If src[3] is zero, we can't tell at this point if the image is
// 0RGB or ARGB. So we just use 0 value as-is. If the image is 0RGB
// then mDoesHaveTransparency will be false at the end, we'll treat
// the image as opaque, and the 0 alpha values will be ignored. If
// the image is ARGB then mDoesHaveTransparency will be true at the
// end and we'll treat the image as non-opaque. (Note: a
// fully-transparent ARGB image is indistinguishable from a 0RGB
// image, and we will render such an image as a 0RGB image, i.e.
// opaquely. This is unlikely to be a problem in practice.)
if (src[3] != 0) {
MOZ_ASSERT(mMayHaveTransparency);
mDoesHaveTransparency = true;
}
SetPixel(dst, src[2], src[1], src[0], src[3]);
} else {
SetPixel(dst, src[2], src[1], src[0]);
src += 4;
--lpos;
}
} else if (mBitFields.IsR8G8B8()) {
// Specialize this common case.
while (lpos > 0) {
uint32_t val = LittleEndian::readUint32(src);
SetPixel(dst, mBitFields.mRed.Get8(val),
mBitFields.mGreen.Get8(val),
mBitFields.mBlue.Get8(val));
--lpos;
src += 4;
}
} else {
bool anyHasAlpha = false;
while (lpos > 0) {
uint32_t val = LittleEndian::readUint32(src);
SetPixel(dst, mBitFields.mRed.Get(val),
mBitFields.mGreen.Get(val),
mBitFields.mBlue.Get(val),
mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
--lpos;
src += 4;
}
if (anyHasAlpha) {
MOZ_ASSERT(mMayHaveTransparency);
mDoesHaveTransparency = true;
}
--lpos;
src += 4;
}
break;
@ -840,13 +946,10 @@ nsBMPDecoder::ReadRLESegment(const char* aData)
LexerTransition<nsBMPDecoder::State>
nsBMPDecoder::ReadRLEDelta(const char* aData)
{
// Delta encoding makes it possible to skip pixels making the image
// Delta encoding makes it possible to skip pixels making part of the image
// transparent.
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
PostHasTransparency();
mHaveAlphaData = true;
}
mUseAlphaData = mHaveAlphaData = true;
MOZ_ASSERT(mMayHaveTransparency);
mDoesHaveTransparency = true;
if (mDownscaler) {
// Clear the skipped pixels. (This clears to the end of the row,

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

@ -38,12 +38,26 @@ class BitFields {
void Set(uint32_t aMask);
public:
Value()
{
mMask = 0;
mRightShift = 0;
mBitWidth = 0;
}
/// Returns true if this channel is used. Only used for alpha.
bool IsPresent() const { return mMask != 0x0; }
/// Extracts the single color value from the multi-color value.
uint8_t Get(uint32_t aVal) const;
/// Specialized version of Get() for the case where the bit-width is 5.
/// (It will assert if called and the bit-width is not 5.)
/// Like Get(), but specially for alpha.
uint8_t GetAlpha(uint32_t aVal, bool& aHasAlphaOut) const;
/// Specialized versions of Get() for when the bit-width is 5 or 8.
/// (They will assert if called and the bit-width is not 5 or 8.)
uint8_t Get5(uint32_t aVal) const;
uint8_t Get8(uint32_t aVal) const;
};
public:
@ -51,15 +65,23 @@ public:
Value mRed;
Value mGreen;
Value mBlue;
Value mAlpha;
/// Set bitfields to the standard 5-5-5 16bpp values.
void SetR5G5B5();
/// Set bitfields to the standard 8-8-8 32bpp values.
void SetR8G8B8();
/// Test if bitfields have the standard 5-5-5 16bpp values.
bool IsR5G5B5() const;
/// Read the bitfields from a header.
void ReadFromHeader(const char* aData);
/// Test if bitfields have the standard 8-8-8 32bpp values.
bool IsR8G8B8() const;
/// Read the bitfields from a header. The reading of the alpha mask is
/// optional.
void ReadFromHeader(const char* aData, bool aReadAlpha);
/// Length of the bitfields structure in the BMP file.
static const size_t LENGTH = 12;
@ -76,11 +98,6 @@ class nsBMPDecoder : public Decoder
public:
~nsBMPDecoder();
/// Specifies whether or not the BMP file will contain alpha data. If set to
/// true and the BMP is 32BPP, the alpha data will be retrieved from the 4th
/// byte of image data per pixel.
void SetUseAlphaData(bool useAlphaData);
/// Obtains the bits per pixel from the internal BIH header.
int32_t GetBitsPerPixel() const;
@ -97,12 +114,19 @@ public:
/// Obtains the size of the compressed image resource.
int32_t GetCompressedImageSize() const;
/// Obtains whether or not a BMP file had alpha data in its 4th byte for 32BPP
/// bitmaps. Use only after the bitmap has been processed.
bool HasAlphaData() const { return mHaveAlphaData; }
/// Mark this BMP as being within an ICO file.
void SetIsWithinICO() { mIsWithinICO = true; }
/// Marks this BMP as having alpha data (due to e.g. an ICO alpha mask).
void SetHasAlphaData() { mHaveAlphaData = true; }
/// Did the BMP file have alpha data of any kind? (Only use this after the
/// bitmap has been fully decoded.)
bool HasTransparency() const { return mDoesHaveTransparency; }
/// Force transparency from outside. (Used by the ICO decoder.)
void SetHasTransparency()
{
mMayHaveTransparency = true;
mDoesHaveTransparency = true;
}
virtual void WriteInternal(const char* aBuffer,
uint32_t aCount) override;
@ -151,8 +175,19 @@ private:
bmp::FileHeader mBFH;
bmp::V5InfoHeader mBIH;
// If the BMP is within an ICO file our treatment of it differs slightly.
bool mIsWithinICO;
bmp::BitFields mBitFields;
// Might the image have transparency? Determined from the headers during
// metadata decode. (Does not guarantee the image actually has transparency.)
bool mMayHaveTransparency;
// Does the image have transparency? Determined during full decoding, so only
// use this after that has been completed.
bool mDoesHaveTransparency;
uint32_t mNumColors; // The number of used colors, i.e. the number of
// entries in mColors, if it's present.
bmp::ColorTableEntry* mColors; // The color table, if it's present.
@ -171,18 +206,6 @@ private:
// Only used in RLE_ABSOLUTE state: the number of pixels to read.
uint32_t mAbsoluteModeNumPixels;
// Stores whether the image data may store alpha data, or if the alpha data
// is unspecified and filled with a padding byte of 0. When a 32BPP bitmap
// is stored in an ICO or CUR file, its 4th byte is used for alpha
// transparency. When it is stored in a BMP, its 4th byte is reserved and
// is always 0. Reference:
// http://en.wikipedia.org/wiki/ICO_(file_format)#cite_note-9
// Bitmaps where the alpha bytes are all 0 should be fully visible.
bool mUseAlphaData;
// Whether the 4th byte alpha data was found to be non zero and hence used.
bool mHaveAlphaData;
};
} // namespace image

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

@ -393,7 +393,7 @@ nsICODecoder::SniffResource(const char* aData)
// is the AND mask, which isn't present in standalone BMPs.
nsBMPDecoder* bmpDecoder = new nsBMPDecoder(mImage);
mContainedDecoder = bmpDecoder;
bmpDecoder->SetUseAlphaData(true);
bmpDecoder->SetIsWithinICO();
mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
@ -525,9 +525,9 @@ nsICODecoder::PrepareForMask()
MOZ_ASSERT(bmpLengthWithHeader < mDirEntry.mBytesInRes);
uint32_t maskLength = mDirEntry.mBytesInRes - bmpLengthWithHeader;
// If we have a 32-bpp BMP with alpha data, we ignore the AND mask. We can
// If the BMP provides its own transparency, we ignore the AND mask. We can
// also obviously ignore it if the image has zero width or zero height.
if ((bmpDecoder->GetBitsPerPixel() == 32 && bmpDecoder->HasAlphaData()) ||
if (bmpDecoder->HasTransparency() ||
GetRealWidth() == 0 || GetRealHeight() == 0) {
return Transition::ToUnbuffered(ICOState::FINISHED_RESOURCE,
ICOState::SKIP_MASK,
@ -658,7 +658,7 @@ nsICODecoder::FinishMask()
RefPtr<nsBMPDecoder> bmpDecoder =
static_cast<nsBMPDecoder*>(mContainedDecoder.get());
bmpDecoder->SetHasAlphaData();
bmpDecoder->SetHasTransparency();
}
return Transition::To(ICOState::FINISHED_RESOURCE, 0);

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

@ -268,8 +268,6 @@ nsJPEGEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval)
return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
}
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter, in
voidPtr aClosure, in unsigned long aCount); */
NS_IMETHODIMP
nsJPEGEncoder::ReadSegments(nsWriteSegmentFun aWriter,
void* aClosure, uint32_t aCount, uint32_t* _retval)

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

@ -548,17 +548,12 @@ nsPNGEncoder::Available(uint64_t* _retval)
return NS_OK;
}
/* [noscript] unsigned long read (in charPtr aBuf,
in unsigned long aCount); */
NS_IMETHODIMP
nsPNGEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval)
{
return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
}
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter,
in voidPtr aClosure,
in unsigned long aCount); */
NS_IMETHODIMP
nsPNGEncoder::ReadSegments(nsWriteSegmentFun aWriter,
void* aClosure, uint32_t aCount,

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

@ -2008,15 +2008,6 @@ imgLoader::LoadImageXPCOM(nsIURI* aURI,
return rv;
}
// imgIRequest loadImage(in nsIURI aURI,
// in nsIURI aInitialDocumentURL,
// in nsIURI aReferrerURI,
// in nsIPrincipal aLoadingPrincipal,
// in nsILoadGroup aLoadGroup,
// in imgINotificationObserver aObserver,
// in nsISupports aCX,
// in nsLoadFlags aLoadFlags,
// in nsISupports cacheKey);
nsresult
imgLoader::LoadImage(nsIURI* aURI,
nsIURI* aInitialDocumentURI,
@ -2294,11 +2285,6 @@ imgLoader::LoadImage(nsIURI* aURI,
return NS_OK;
}
/* imgIRequest
loadImageWithChannelXPCOM(in nsIChannel channel,
in imgINotificationObserver aObserver,
in nsISupports cx,
out nsIStreamListener); */
NS_IMETHODIMP
imgLoader::LoadImageWithChannelXPCOM(nsIChannel* channel,
imgINotificationObserver* aObserver,
@ -2635,8 +2621,6 @@ ProxyListener::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
return mDestListener->OnStartRequest(aRequest, ctxt);
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt,
in nsresult status); */
NS_IMETHODIMP
ProxyListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* ctxt,
@ -2651,10 +2635,6 @@ ProxyListener::OnStopRequest(nsIRequest* aRequest,
/** nsIStreamListener methods **/
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr,
in unsigned long long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP
ProxyListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
nsIInputStream* inStr, uint64_t sourceOffset,
@ -2853,8 +2833,6 @@ imgCacheValidator::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
return mDestListener->OnStartRequest(aRequest, ctxt);
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt,
in nsresult status); */
NS_IMETHODIMP
imgCacheValidator::OnStopRequest(nsIRequest* aRequest,
nsISupports* ctxt,
@ -2873,10 +2851,6 @@ imgCacheValidator::OnStopRequest(nsIRequest* aRequest,
/** nsIStreamListener methods **/
/* void
onDataAvailable (in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr, in unsigned long long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP
imgCacheValidator::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
nsIInputStream* inStr,

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

@ -804,8 +804,6 @@ imgRequest::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
return NS_OK;
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt,
nsresult status); */
NS_IMETHODIMP
imgRequest::OnStopRequest(nsIRequest* aRequest,
nsISupports* ctxt, nsresult status)

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

@ -194,13 +194,13 @@ ImageTestCase FirstFramePaddingGIFTestCase()
TEST_CASE_IS_TRANSPARENT);
}
ImageTestCase TransparentBMPWhenBMPAlphaEnabledTestCase()
ImageTestCase TransparentIfWithinICOBMPTestCase(TestCaseFlags aFlags)
{
// Note that we only decode this test case as transparent when the BMP decoder
// is set to use alpha data. (That's not the default, which is why it's not marked
// TEST_CASE_IS_TRANSPARENT; tests that want to treat this testcase as
// transparent need to handle this case manually.)
return ImageTestCase("transparent.bmp", "image/bmp", IntSize(32, 32));
// This is a BMP that is only transparent when decoded as if it is within an
// ICO file. (Note: aFlags needs to be set to TEST_CASE_DEFAULT_FLAGS or
// TEST_CASE_IS_TRANSPARENT accordingly.)
return ImageTestCase("transparent-if-within-ico.bmp", "image/bmp",
IntSize(32, 32), aFlags);
}
ImageTestCase RLE4BMPTestCase()

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

@ -38,15 +38,15 @@ TEST(ImageMetadata, ImageModuleAvailable)
EXPECT_TRUE(imgTools != nullptr);
}
enum class BMPAlpha
enum class BMPWithinICO
{
DISABLED,
ENABLED
NO,
YES
};
static void
CheckMetadata(const ImageTestCase& aTestCase,
BMPAlpha aBMPAlpha = BMPAlpha::DISABLED)
BMPWithinICO aBMPWithinICO = BMPWithinICO::NO)
{
nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
ASSERT_TRUE(inputStream != nullptr);
@ -70,13 +70,13 @@ CheckMetadata(const ImageTestCase& aTestCase,
DecoderFactory::CreateAnonymousMetadataDecoder(decoderType, sourceBuffer);
ASSERT_TRUE(decoder != nullptr);
if (aBMPAlpha == BMPAlpha::ENABLED) {
static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true);
if (aBMPWithinICO == BMPWithinICO::YES) {
static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
}
// Run the metadata decoder synchronously.
decoder->Decode();
// Ensure that the metadata decoder didn't make progress it shouldn't have
// (which would indicate that it decoded past the header of the image).
Progress metadataProgress = decoder->TakeProgress();
@ -100,7 +100,7 @@ CheckMetadata(const ImageTestCase& aTestCase,
EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
EXPECT_EQ(aTestCase.mSize.height, metadataSize.height);
bool expectTransparency = aBMPAlpha == BMPAlpha::ENABLED
bool expectTransparency = aBMPWithinICO == BMPWithinICO::YES
? true
: bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT);
EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY));
@ -114,13 +114,13 @@ CheckMetadata(const ImageTestCase& aTestCase,
DefaultSurfaceFlags());
ASSERT_TRUE(decoder != nullptr);
if (aBMPAlpha == BMPAlpha::ENABLED) {
static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true);
if (aBMPWithinICO == BMPWithinICO::YES) {
static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
}
// Run the full decoder synchronously.
decoder->Decode();
EXPECT_TRUE(decoder->GetDecodeDone() && !decoder->HasError());
Progress fullProgress = decoder->TakeProgress();
@ -164,14 +164,16 @@ TEST(ImageMetadata, FirstFramePaddingGIF)
CheckMetadata(FirstFramePaddingGIFTestCase());
}
TEST(ImageMetadata, TransparentBMPWithBMPAlphaOff)
TEST(ImageMetadata, TransparentIfWithinICOBMPNotWithinICO)
{
CheckMetadata(TransparentBMPWhenBMPAlphaEnabledTestCase(), BMPAlpha::ENABLED);
CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_DEFAULT_FLAGS),
BMPWithinICO::NO);
}
TEST(ImageMetadata, TransparentBMPWithBMPAlphaOn)
TEST(ImageMetadata, TransparentIfWithinICOBMPWithinICO)
{
CheckMetadata(TransparentBMPWhenBMPAlphaEnabledTestCase(), BMPAlpha::ENABLED);
CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_IS_TRANSPARENT),
BMPWithinICO::YES);
}
TEST(ImageMetadata, RLE4BMP) { CheckMetadata(RLE4BMPTestCase()); }

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

@ -29,7 +29,7 @@ TEST_HARNESS_FILES.gtest += [
'no-frame-delay.gif',
'rle4.bmp',
'rle8.bmp',
'transparent.bmp',
'transparent-if-within-ico.bmp',
'transparent.gif',
'transparent.png',
]

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.1 KiB

После

Ширина:  |  Высота:  |  Размер: 4.1 KiB

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

@ -108,7 +108,5 @@ fuzzy(1,1516) == rgb16.bmp rgb16.png
# "A 32-bit image with a BITFIELDS segment. As usual, there are 8 bits per color
# channel, and 8 unused bits. But the color channels are in an unusual order,
# so the viewer must read the BITFIELDS, and not just guess."
# [XXX: we get this completely wrong because we don't handle BITFIELDS at all
# in 32bpp BMPs. Chromium gets this right.]
fails == rgb32bf.bmp rgb24.png
== rgb32bf.bmp rgb24.png

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

@ -71,9 +71,7 @@ fuzzy(1,899) == pal8os2v2-16.bmp pal8.png
# "A 16-bit image with an alpha channel. There are 4 bits for each color
# channel, and 4 bits for the alpha channel. Its not clear if this is valid,
# but I cant find anything that suggests it isnt."
# [XXX: we don't even try to do transparency for 16bpp. Chromium gets the
# transparency right.]
fails == rgba16-4444.bmp rgba16-4444.png
== rgba16-4444.bmp rgba16-4444.png
# BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=300
# "A 24-bit image, with a palette containing 300 colors. The fact that the
@ -114,18 +112,14 @@ fails == rgba16-4444.bmp rgba16-4444.png
# BMP: bihsize=40, 127 x 64, bpp=32, compression=3, colors=0
# "A 32 bits/pixel image, with all 32 bits used: 11 each for red and green, and
# 10 for blue. As far as I know, this is perfectly valid, but it is unusual."
# [XXX: we get this completely wrong because we don't handle BITFIELDS at all
# in 32bpp BMPs. Chromium gets this right.]
fails == rgb32-111110.bmp rgb24.png
fuzzy(1,1408) == rgb32-111110.bmp rgb24.png
# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
# "A BMP with an alpha channel. Transparency is barely documented, so its
# possible that this file is not correctly formed. The color channels are in an
# unusual order, to prevent viewers from passing this test by making a lucky
# guess."
# [XXX: we get this completely wrong because we don't handle BITFIELDS at all
# in 32bpp BMPs, especially not with alpha. Chromium gets this right.]
fails == rgba32.bmp rgba32.png
== rgba32.bmp rgba32.png
# BMP: bihsize=40, 127 x 64, bpp=32, compression=6, colors=0
# "An image of type BI_ALPHABITFIELDS. Supposedly, this was used on Windows CE.

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

@ -130,9 +130,6 @@ nsScriptableUnicodeConverter::ConvertToUnicode(const nsACString& aSrc, nsAString
_retval);
}
/* AString convertFromByteArray([const,array,size_is(aCount)] in octet aData,
in unsigned long aCount);
*/
NS_IMETHODIMP
nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData,
uint32_t aCount,
@ -168,10 +165,6 @@ nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData,
}
/* void convertToByteArray(in AString aString,
[optional] out unsigned long aLen,
[array, size_is(aLen),retval] out octet aData);
*/
NS_IMETHODIMP
nsScriptableUnicodeConverter::ConvertToByteArray(const nsAString& aString,
uint32_t* aLen,

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