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

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

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

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

@ -2,6 +2,7 @@
support-files = support-files =
file_dom_notifications.html file_dom_notifications.html
[browser_notification_close.js]
[browser_notification_do_not_disturb.js] [browser_notification_do_not_disturb.js]
[browser_notification_open_settings.js] [browser_notification_open_settings.js]
[browser_notification_remove_permission.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"); is(doNotDisturbMenuItem.localName, "menuitem", "menuitem found");
alertWindow.addEventListener("beforeunload", onAlertClosing); alertWindow.addEventListener("beforeunload", onAlertClosing);
doNotDisturbMenuItem.click(); doNotDisturbMenuItem.click();
info("Clicked on do-not-disturb menuitem") info("Clicked on do-not-disturb menuitem");
} }
function onAlertClosing(event) { function onAlertClosing(event) {

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

@ -199,10 +199,16 @@ extensions.registerAPI((extension, context) => {
}, },
onLocationChange(browser, webProgress, request, locationURI, flags) { onLocationChange(browser, webProgress, request, locationURI, flags) {
if (!webProgress.isTopLevel) {
return;
}
let gBrowser = browser.ownerDocument.defaultView.gBrowser; let gBrowser = browser.ownerDocument.defaultView.gBrowser;
let tab = gBrowser.getTabForBrowser(browser); let tab = gBrowser.getTabForBrowser(browser);
let tabId = TabManager.getId(tab); 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) { if (needed) {
fire(tabId, changeInfo, TabManager.convert(extension, tab)); fire(tabId, changeInfo, TabManager.convert(extension, tab));
} }
@ -213,11 +219,12 @@ extensions.registerAPI((extension, context) => {
AllWindowEvents.addListener("TabAttrModified", listener); AllWindowEvents.addListener("TabAttrModified", listener);
AllWindowEvents.addListener("TabPinned", listener); AllWindowEvents.addListener("TabPinned", listener);
AllWindowEvents.addListener("TabUnpinned", listener); AllWindowEvents.addListener("TabUnpinned", listener);
return () => { return () => {
AllWindowEvents.removeListener("progress", progressListener); AllWindowEvents.removeListener("progress", progressListener);
AllWindowEvents.addListener("TabAttrModified", listener); AllWindowEvents.removeListener("TabAttrModified", listener);
AllWindowEvents.addListener("TabPinned", listener); AllWindowEvents.removeListener("TabPinned", listener);
AllWindowEvents.addListener("TabUnpinned", listener); AllWindowEvents.removeListener("TabUnpinned", listener);
}; };
}).api(), }).api(),

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

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

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

@ -3,6 +3,8 @@ support-files =
head.js head.js
context.html context.html
ctxmenu-image.png ctxmenu-image.png
context_tabs_onUpdated_page.html
context_tabs_onUpdated_iframe.html
[browser_ext_simple.js] [browser_ext_simple.js]
[browser_ext_currentWindow.js] [browser_ext_currentWindow.js]
@ -16,6 +18,7 @@ support-files =
[browser_ext_tabs_executeScript.js] [browser_ext_tabs_executeScript.js]
[browser_ext_tabs_query.js] [browser_ext_tabs_query.js]
[browser_ext_tabs_update.js] [browser_ext_tabs_update.js]
[browser_ext_tabs_onUpdated.js]
[browser_ext_tabs_sendMessage.js] [browser_ext_tabs_sendMessage.js]
[browser_ext_windows_update.js] [browser_ext_windows_update.js]
[browser_ext_contentscript_connect.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() function genericChecker()
{ {
var kind = "background"; 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(); id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_"); 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 { .context-url-view-wrapper {
padding: 12px; padding: 14px 15px;
margin-bottom: 0.5em;
background-color: #dbf7ff; background-color: #dbf7ff;
} }
.showing-room-name > .text-chat-entries > .text-chat-scroller > .context-url-view-wrapper { .showing-room-name > .text-chat-entries > .text-chat-scroller > .context-url-view-wrapper {
padding-top: 0; padding-top: 0;
margin-bottom: 0;
} }
.room-context { .room-context {
@ -755,7 +755,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.media-wrapper > .focus-stream { .media-wrapper > .focus-stream {
width: 100%; width: 100%;
/* A reasonable height */ /* A reasonable height */
height: 70%; height: 55%;
} }
.media-wrapper.receiving-screen-share > .focus-stream { .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 { .desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
/* This is temp, to echo the .media-wrapper > .text-chat-view above */ /* This is temp, to echo the .media-wrapper > .text-chat-view above */
height: 30%; height: 45%;
} }
.media-wrapper.receiving-screen-share > .screen { .media-wrapper.receiving-screen-share > .screen {
@ -930,7 +930,12 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.media-wrapper > .focus-stream { .media-wrapper > .focus-stream {
flex: 1 1 auto; 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-align: start;
} }
.text-chat-scroller div:nth-child(2) {
margin-top: .5em;
}
/* Sent text chat entries should be on the right */ /* Sent text chat entries should be on the right */
.text-chat-entry.sent { .text-chat-entry.sent {
/* aligns paragraph to right side */ /* aligns paragraph to right side */
@ -1208,8 +1217,6 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
.text-chat-view { .text-chat-view {
display: flex; display: flex;
flex-flow: column nowrap; 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 */ /* 60px min-height of .text-chat-entries plus 40px of .text-chat-box */
min-height: 100px; min-height: 100px;
height: auto; height: auto;
@ -1220,7 +1227,6 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
.text-chat-entries { .text-chat-entries {
flex: 1 1 auto; flex: 1 1 auto;
max-height: 120px;
min-height: 60px; min-height: 60px;
} }

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

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

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

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

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

@ -96,6 +96,7 @@ describe("loop.store.TextChatStore", function() {
}); });
it("should dispatch a LoopChatMessageAppended event", function() { it("should dispatch a LoopChatMessageAppended event", function() {
store.setStoreState({ textChatEnabled: true });
store.receivedTextChatMessage({ store.receivedTextChatMessage({
contentType: CHAT_CONTENT_TYPES.TEXT, contentType: CHAT_CONTENT_TYPES.TEXT,
message: "Hello!" message: "Hello!"
@ -141,6 +142,7 @@ describe("loop.store.TextChatStore", function() {
}); });
it("should dipatch a LoopChatMessageAppended event", function() { it("should dipatch a LoopChatMessageAppended event", function() {
store.setStoreState({ textChatEnabled: true });
store.sendTextChatMessage({ store.sendTextChatMessage({
contentType: CHAT_CONTENT_TYPES.TEXT, contentType: CHAT_CONTENT_TYPES.TEXT,
message: "Hello!" 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() { it("should not dispatch a LoopChatMessageAppended event", function() {
store.updateRoomInfo(new sharedActions.UpdateRoomInfo({ store.updateRoomInfo(new sharedActions.UpdateRoomInfo({
roomName: "Let's share!", roomName: "Let's share!",

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

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

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

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

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

@ -2669,7 +2669,22 @@ ContentPermissionPrompt.prototype = {
_promptWebNotifications : function(aRequest) { _promptWebNotifications : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite"); var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
var actions = [ 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", stringId: "webNotifications.alwaysReceive",
action: Ci.nsIPermissionManager.ALLOW_ACTION, action: Ci.nsIPermissionManager.ALLOW_ACTION,
@ -2683,6 +2698,7 @@ ContentPermissionPrompt.prototype = {
callback: function() {}, callback: function() {},
}, },
]; ];
}
var options = { var options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"), 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.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file? 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=Always Receive Notifications
webNotifications.alwaysReceive.accesskey=A webNotifications.alwaysReceive.accesskey=A
webNotifications.neverShow=Always Block Notifications webNotifications.neverShow=Always Block Notifications

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

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

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

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

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

@ -9,7 +9,9 @@ const { getSnapshotStatusText } = require("../utils");
const { snapshotState: states } = require("../constants"); const { snapshotState: states } = require("../constants");
const { snapshot: snapshotModel } = require("../models"); const { snapshot: snapshotModel } = require("../models");
const TAKE_SNAPSHOT_TEXT = "Take snapshot"; 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. * 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 }), renderItem: (item, depth, focused, arrow) => new TreeItem({ item, depth, focused, arrow }),
getRoots: () => census.children, getRoots: () => census.children,
getKey: node => node.id, getKey: node => node.id,
itemHeight: TREE_ROW_HEIGHT, itemHeight: HEAP_TREE_ROW_HEIGHT,
}; };
} }
@ -85,6 +87,13 @@ const Heap = module.exports = createClass({
break; break;
case states.SAVED_CENSUS: case states.SAVED_CENSUS:
pane = dom.div({ className: "heap-view-panel", "data-state": "loaded" }, 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)) Tree(createTreeProperties(snapshot.census))
); );
break; break;

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

@ -15,13 +15,15 @@ const TreeItem = module.exports = createClass({
render() { render() {
let { item, depth, arrow, focused } = this.props; let { item, depth, arrow, focused } = this.props;
return dom.div({ className: "heap-tree-item", style: { marginLeft: depth * INDENT }}, return dom.div({ className: "heap-tree-item" },
arrow,
dom.span({ className: "heap-tree-item-name" }, item.name),
dom.span({ className: "heap-tree-item-bytes" }, item.bytes), dom.span({ className: "heap-tree-item-bytes" }, item.bytes),
dom.span({ className: "heap-tree-item-count" }, item.count), 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-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)` * DOMString causeName - the label passed into `console.timeStamp(label)`
if passed in. 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 HTML
## Parse XML ## Parse XML

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

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

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

@ -56,6 +56,7 @@ skip-if = true # Bug 1161817
[browser_perf-loading-02.js] [browser_perf-loading-02.js]
[browser_perf-marker-details-01.js] [browser_perf-marker-details-01.js]
skip-if = os == 'linux' # Bug 1172120 skip-if = os == 'linux' # Bug 1172120
[browser_perf-markers-docload.js]
[browser_perf-options-01.js] [browser_perf-options-01.js]
[browser_perf-options-02.js] [browser_perf-options-02.js]
[browser_perf-options-03.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(), is(widget.getCssValue(),
"drop-shadow(2px 1px 5px black) url(example.svg#filter)", "drop-shadow(2px 1px 5px black) url(example.svg#filter)",
"setCssValue should work for string-typed values"); "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); testParseCssProperty(doc, parser);
testParseCssVar(doc, parser); testParseCssVar(doc, parser);
testParseURL(doc, parser); testParseURL(doc, parser);
testParseFilter(doc, parser);
host.destroy(); host.destroy();
} }
@ -249,3 +250,13 @@ function testParseURL(doc, parser) {
target.innerHTML = ""; 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 EventEmitter = require("devtools/shared/event-emitter");
const { Cu } = require("chrome"); const { Cu, Cc, Ci } = require("chrome");
const { ViewHelpers } = Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm", {}); const { ViewHelpers } =
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm",
{});
const STRINGS_URI = "chrome://browser/locale/devtools/filterwidget.properties"; const STRINGS_URI = "chrome://browser/locale/devtools/filterwidget.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI); const L10N = new ViewHelpers.L10N(STRINGS_URI);
const {cssTokenizer} = require("devtools/client/shared/css-parsing-utils"); 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", loader.lazyGetter(this, "asyncStorage",
() => require("devtools/shared/async-storage")); () => 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 DEFAULT_FILTER_TYPE = "length";
const UNIT_MAPPING = { const UNIT_MAPPING = {
percentage: "%", percentage: "%",
@ -307,8 +313,11 @@ CSSFilterEditorWidget.prototype = {
let value = startValue + direction * multiplier; let value = startValue + direction * multiplier;
const [min, max] = this._definition(filter.name).range; const [min, max] = this._definition(filter.name).range;
value = value < min ? min : if (value < min) {
value > max ? max : value; value = min;
} else if (value > max) {
value = max;
}
input.value = fixFloat(value); input.value = fixFloat(value);
@ -323,8 +332,8 @@ CSSFilterEditorWidget.prototype = {
let {start, end, value} = num; let {start, end, value} = num;
let split = input.value.split(""); let split = input.value.split("");
let computed = fixFloat(value + direction * multiplier), let computed = fixFloat(value + direction * multiplier);
dotIndex = computed.indexOf(".0"); let dotIndex = computed.indexOf(".0");
if (dotIndex > -1) { if (dotIndex > -1) {
computed = computed.slice(0, -2); computed = computed.slice(0, -2);
@ -343,10 +352,10 @@ CSSFilterEditorWidget.prototype = {
}, },
_input: function(e) { _input: function(e) {
let filterEl = e.target.closest(".filter"), let filterEl = e.target.closest(".filter");
index = this._getFilterElementIndex(filterEl), let index = this._getFilterElementIndex(filterEl);
filter = this.filters[index], let filter = this.filters[index];
def = this._definition(filter.name); let def = this._definition(filter.name);
if (def.type !== "string") { if (def.type !== "string") {
e.target.value = fixFloat(e.target.value); e.target.value = fixFloat(e.target.value);
@ -366,9 +375,9 @@ CSSFilterEditorWidget.prototype = {
this.el.classList.add("dragging"); this.el.classList.add("dragging");
// label-dragging // label-dragging
} else if (e.target.classList.contains("devtools-draglabel")) { } else if (e.target.classList.contains("devtools-draglabel")) {
let label = e.target, let label = e.target;
input = filterEl.querySelector("input"), let input = filterEl.querySelector("input");
index = this._getFilterElementIndex(filterEl); let index = this._getFilterElementIndex(filterEl);
this._dragging = { this._dragging = {
index, label, input, index, label, input,
@ -386,19 +395,7 @@ CSSFilterEditorWidget.prototype = {
} }
const key = select.value; const key = select.value;
const def = this._definition(key); this.add(key, 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) {
this.add(key);
} else {
this.add(key, def.range[0] + unitLabel);
}
this.render(); this.render();
}, },
@ -423,9 +420,9 @@ CSSFilterEditorWidget.prototype = {
}, },
_dragFilterElement: function(e) { _dragFilterElement: function(e) {
const rect = this.filtersList.getBoundingClientRect(), const rect = this.filtersList.getBoundingClientRect();
top = e.pageY - LIST_PADDING, let top = e.pageY - LIST_PADDING;
bottom = e.pageY + LIST_PADDING; let bottom = e.pageY + LIST_PADDING;
// don't allow dragging over top/bottom of list // don't allow dragging over top/bottom of list
if (top < rect.top || bottom > rect.bottom) { if (top < rect.top || bottom > rect.bottom) {
return; return;
@ -439,8 +436,11 @@ CSSFilterEditorWidget.prototype = {
// change is the number of _steps_ taken from initial position // change is the number of _steps_ taken from initial position
// i.e. how many elements we have passed // i.e. how many elements we have passed
let change = delta / LIST_ITEM_HEIGHT; let change = delta / LIST_ITEM_HEIGHT;
change = change > 0 ? Math.floor(change) : if (change > 0) {
change < 0 ? Math.ceil(change) : change; change = Math.floor(change);
} else if (change < 0) {
change = Math.ceil(change);
}
const children = this.filtersList.children; const children = this.filtersList.children;
const index = [...children].indexOf(filterEl); const index = [...children].indexOf(filterEl);
@ -489,8 +489,11 @@ CSSFilterEditorWidget.prototype = {
const filter = this.filters[dragging.index]; const filter = this.filters[dragging.index];
const [min, max] = this._definition(filter.name).range; const [min, max] = this._definition(filter.name).range;
value = value < min ? min : if (value < min) {
value > max ? max : value; value = min;
} else if (value > max) {
value = max;
}
input.value = fixFloat(value); input.value = fixFloat(value);
@ -551,8 +554,8 @@ CSSFilterEditorWidget.prototype = {
_savePreset: function(e) { _savePreset: function(e) {
e.preventDefault(); e.preventDefault();
let name = this.addPresetInput.value, let name = this.addPresetInput.value;
value = this.getCssValue(); let value = this.getCssValue();
if (!name || !value || value === "none") { if (!name || !value || value === "none") {
this.emit("preset-save-error"); this.emit("preset-save-error");
@ -593,9 +596,9 @@ CSSFilterEditorWidget.prototype = {
let el = base.cloneNode(true); let el = base.cloneNode(true);
let [name, value] = el.children, let [name, value] = el.children;
label = name.children[1], let label = name.children[1];
[input, unitPreview] = value.children; let [input, unitPreview] = value.children;
let min, max; let min, max;
if (def.range) { if (def.range) {
@ -637,7 +640,8 @@ CSSFilterEditorWidget.prototype = {
this.filtersList.appendChild(el); 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) { if (lastInput) {
lastInput.focus(); lastInput.focus();
// move cursor to end of input // move cursor to end of input
@ -685,6 +689,7 @@ CSSFilterEditorWidget.prototype = {
* filter's definition * filter's definition
*/ */
_definition: function(name) { _definition: function(name) {
name = name.toLowerCase();
return filterList.find(a => a.name === name); return filterList.find(a => a.name === name);
}, },
@ -708,6 +713,14 @@ CSSFilterEditorWidget.prototype = {
} }
for (let {name, value} of tokenizeFilterValue(cssValue)) { 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); this.add(name, value);
} }
@ -722,15 +735,31 @@ CSSFilterEditorWidget.prototype = {
* filter name (e.g. blur) * filter name (e.g. blur)
* @param {String} value * @param {String} value
* value of the filter (e.g. 30px, 20%) * value of the filter (e.g. 30px, 20%)
* If this is |null|, then a default value may be supplied.
* @return {Number} * @return {Number}
* The index of the new filter in the current list of filters * 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); const def = this._definition(name);
if (!def) { if (!def) {
return false; 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" let unit = def.type === "string"
? "" ? ""
: (/[a-zA-Z%]+/.exec(value) || [])[0]; : (/[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()); this.emit("updated", this.getCssValue());
return index; return index;
@ -940,8 +969,8 @@ function getNeighbourNumber(string, index) {
return null; return null;
} }
let left = /-?[0-9.]*$/.exec(string.slice(0, index)), let left = /-?[0-9.]*$/.exec(string.slice(0, index));
right = /-?[0-9.]*/.exec(string.slice(index)); let right = /-?[0-9.]*/.exec(string.slice(index));
left = left ? left[0] : ""; left = left ? left[0] : "";
right = right ? right[0] : ""; right = right ? right[0] : "";

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

@ -19,9 +19,24 @@
--row-hover-background-color: rgba(76,158,217,0.2); --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 { #memory-tool-container {
display: flex; display: flex;
flex-direction: row; 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; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
height: 20px; height: var(--toolbar-height);
} }
/** /**
@ -91,13 +106,18 @@
width: 186px; width: 186px;
list-style-type: none; list-style-type: none;
font-size: 12px; 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 { .list > li {
height: 40px; height: 40px;
color: var(--theme-body-color); color: var(--theme-body-color);
border-bottom: 1px solid transparent; border-bottom: 1px solid rgba(128,128,128,0.15);
border-top: 1px solid rgba(128,128,128,0.15);
padding: 8px; padding: 8px;
cursor: pointer; cursor: pointer;
} }
@ -127,6 +147,9 @@
#heap-view { #heap-view {
flex: 1 1 auto; flex: 1 1 auto;
border-color: var(--theme-splitter-color);
color: var(--theme-body-color)
border-left-width: 1px;
} }
#heap-view .heap-view-panel { #heap-view .heap-view-panel {
@ -138,65 +161,86 @@
} }
/** /**
* Heap View * Heap Tree View
*/ */
.heap-view { #heap-view .theme-twisty {
position: relative; float: left;
} }
.heap-view .theme-twisty { .tree {
text-align: end; 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; list-style-type: none;
/* display: none; */ height: var(--heap-tree-row-height);
} }
.heap-tree-item[expanded] { .heap-tree-item span, .header span {
display: block; float: left;
} }
.heap-tree-item:nth-child(2n) { .tree-node:nth-child(2n) {
background-color: var(--row-alt-background-color); background-color: var(--row-alt-background-color);
} }
.heap-tree-item:hover { .tree-node:hover {
background-color: var(--row-hover-background-color); background-color: var(--row-hover-background-color);
} }
.heap-tree-item:focus { .tree-node:focus {
background-color: var(--theme-selection-background); background-color: var(--theme-selection-background);
} }
.heap-tree-item:focus description { .header {
color: var(--theme-selection-color) !important; background-color: var(--theme-tab-toolbar-background);
} }
.heap-tree-item:focus .call-tree-cell { .header span {
-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;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
display: block; text-align: center;
font-size: 90%;
} }
.heap-tree-cell[type="count"] { .heap-tree-item-bytes,
left: 300px; .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"] { .heap-tree-item-count,
left: 250px; .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 * 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, menuitem.marker-color-graphs-green:before,
.marker-color-graphs-green { .marker-color-graphs-green {
background-color: var(--theme-graphs-green); background-color: var(--theme-graphs-green);

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

@ -51,6 +51,8 @@
--theme-graphs-orange: #d97e00; --theme-graphs-orange: #d97e00;
--theme-graphs-red: #e57180; --theme-graphs-red: #e57180;
--theme-graphs-grey: #cccccc; --theme-graphs-grey: #cccccc;
--theme-graphs-full-red: #f00;
--theme-graphs-full-blue: #00f;
} }
:root.theme-dark { :root.theme-dark {
@ -90,4 +92,6 @@
--theme-graphs-orange: #d96629; --theme-graphs-orange: #d96629;
--theme-graphs-red: #eb5368; --theme-graphs-red: #eb5368;
--theme-graphs-grey: #757873; --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_COLOR) ||
safeCssPropertySupportsType(name, DOMUtils.TYPE_GRADIENT); 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); return this._parse(value, options);
} }
this._appendTextNode(value); this._appendTextNode(value);

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

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

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

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

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

@ -448,9 +448,6 @@ Exception::ToString(nsACString& _retval)
return NS_OK; 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 NS_IMETHODIMP
Exception::Initialize(const nsACString& aMessage, nsresult aResult, Exception::Initialize(const nsACString& aMessage, nsresult aResult,
const nsACString& aName, nsIStackFrame *aLocation, const nsACString& aName, nsIStackFrame *aLocation,

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

@ -5109,6 +5109,14 @@ nsDocument::DispatchContentLoadedEvents()
NS_LITERAL_STRING("DOMContentLoaded"), NS_LITERAL_STRING("DOMContentLoaded"),
true, false); 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) { if (mTiming) {
mTiming->NotifyDOMContentLoadedEnd(nsIDocument::GetDocumentURI()); 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 // Returns "BackCompat" if we are in quirks mode, "CSS1Compat" if we are
// in almost standards or full standards mode. See bug 105640. This was // in almost standards or full standards mode. See bug 105640. This was
// implemented to match MSIE's compatMode property. // implemented to match MSIE's compatMode property.

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

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

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

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

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

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

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

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

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

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

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

@ -1,5 +1,30 @@
import WebIDL 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): def WebIDLTest(parser, harness):
parser.parse(""" parser.parse("""
interface TestConsts { interface TestConsts {
@ -17,6 +42,14 @@ def WebIDLTest(parser, harness):
const boolean? n = null; const boolean? n = null;
const boolean? nt = true; const boolean? nt = true;
const boolean? nf = false; 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") "Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName") harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName")
harness.check(iface.identifier.name, "TestConsts", "Interface has the right name") 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 for (const, (QName, name, type, value)) in zip(iface.members, expected):
def checkConst(const, QName, name, type, value):
harness.ok(isinstance(const, WebIDL.IDLConst), harness.ok(isinstance(const, WebIDL.IDLConst),
"Should be an IDLConst") "Should be an IDLConst")
harness.ok(const.isConst(), "Const is a const") 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") "Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.") 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); mBufferProvider = new PersistentBufferProviderBasic(mTarget);
mIsSkiaGL = true; mIsSkiaGL = true;
} else { } 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; mode = RenderingMode::SoftwareBackendMode;
} }
} }
@ -1470,6 +1470,10 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
mTarget = sErrorTarget; 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; return mode;
} }
@ -5329,9 +5333,6 @@ CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
JS::ToInt32(dirtyHeight)); 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 nsresult
CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h, CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
dom::Uint8ClampedArray* aArray, dom::Uint8ClampedArray* aArray,

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

@ -59,8 +59,6 @@ NS_IMETHODIMP GamepadServiceTest::RemoveGamepad(uint32_t aIndex)
return NS_OK; return NS_OK;
} }
/* void newButtonEvent (in uint32_t index, in uint32_t button,
in boolean pressed); */
NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex, NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
uint32_t aButton, uint32_t aButton,
bool aPressed) bool aPressed)
@ -69,8 +67,6 @@ NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
return NS_OK; 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, NS_IMETHODIMP GamepadServiceTest::NewButtonValueEvent(uint32_t aIndex,
uint32_t aButton, uint32_t aButton,
bool aPressed, bool aPressed,
@ -80,8 +76,6 @@ NS_IMETHODIMP GamepadServiceTest::NewButtonValueEvent(uint32_t aIndex,
return NS_OK; return NS_OK;
} }
/* void newAxisMoveEvent (in uint32_t index, in uint32_t axis,
in double value); */
NS_IMETHODIMP GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex, NS_IMETHODIMP GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex,
uint32_t aAxis, uint32_t aAxis,
double aValue) 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 */ /* 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 NS_IMETHODIMP
nsHTMLDocument::ExecCommand(const nsAString& commandID, nsHTMLDocument::ExecCommand(const nsAString& commandID,
bool doShowUI, bool doShowUI,

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

@ -129,7 +129,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: 0, charCode: 0,
code: expectedValues.code || '', code: expectedValues.code || '',
keyCode: expectedValues.keyCode || 0, keyCode: expectedValues.keyCode || 0,
location: 0, location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false, repeat: expectedValues.repeat || false,
value: gCurrentValue, value: gCurrentValue,
shift: false, shift: false,
@ -145,7 +145,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: expectedValues.charCode, charCode: expectedValues.charCode,
code: expectedValues.code || '', code: expectedValues.code || '',
keyCode: expectedValues.charCode ? 0 : expectedValues.keyCode, keyCode: expectedValues.charCode ? 0 : expectedValues.keyCode,
location: 0, location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false, repeat: expectedValues.repeat || false,
value: gCurrentValue, value: gCurrentValue,
shift: false, shift: false,
@ -156,9 +156,22 @@ function sendKeyAndAssertResult(testdata) {
} }
if (testdata.expectedInput) { 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({ expectedEventDetail.push({
type: 'input', type: 'input',
value: gCurrentValue += testdata.expectedInput value: gCurrentValue
}); });
} }
@ -169,7 +182,7 @@ function sendKeyAndAssertResult(testdata) {
charCode: 0, charCode: 0,
code: expectedValues.code || '', code: expectedValues.code || '',
keyCode: expectedValues.keyCode || 0, keyCode: expectedValues.keyCode || 0,
location: 0, location: expectedValues.location ? expectedValues.location : 0,
repeat: expectedValues.repeat || false, repeat: expectedValues.repeat || false,
value: gCurrentValue, value: gCurrentValue,
shift: false, shift: false,
@ -1052,6 +1065,117 @@ function runSendKeyEnterTests() {
return promiseQueue; 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() { function runSendKeyRejectionTests() {
gTestDescription = 'runSendKeyRejectionTests(): '; gTestDescription = 'runSendKeyRejectionTests(): ';
var promiseQueue = Promise.resolve(); var promiseQueue = Promise.resolve();
@ -1636,6 +1760,7 @@ function runTest() {
.then(() => runSendKeyUSKeyboardSymbolsTests()) .then(() => runSendKeyUSKeyboardSymbolsTests())
.then(() => runSendKeyGreekLettersTests()) .then(() => runSendKeyGreekLettersTests())
.then(() => runSendKeyEnterTests()) .then(() => runSendKeyEnterTests())
.then(() => runSendKeyNumpadTests())
.then(() => runSendKeyRejectionTests()) .then(() => runSendKeyRejectionTests())
.then(() => runCompositionWithKeyEventTests()) .then(() => runCompositionWithKeyEventTests())
.then(() => runCompositionWithoutKeyEventTests()) .then(() => runCompositionWithoutKeyEventTests())

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

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

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

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

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

@ -69,6 +69,21 @@ static const char* const gMediaSourceTypes[6] = {
nullptr 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 static nsresult
IsTypeSupported(const nsAString& aType) IsTypeSupported(const nsAString& aType)
{ {
@ -88,7 +103,7 @@ IsTypeSupported(const nsAString& aType)
for (uint32_t i = 0; gMediaSourceTypes[i]; ++i) { for (uint32_t i = 0; gMediaSourceTypes[i]; ++i) {
if (mimeType.EqualsASCII(gMediaSourceTypes[i])) { if (mimeType.EqualsASCII(gMediaSourceTypes[i])) {
if (DecoderTraits::IsMP4Type(mimeTypeUTF8)) { if (DecoderTraits::IsMP4TypeAndEnabled(mimeTypeUTF8)) {
if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) { if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
} }
@ -98,8 +113,9 @@ IsTypeSupported(const nsAString& aType)
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
} }
return NS_OK; return NS_OK;
} else if (DecoderTraits::IsWebMType(mimeTypeUTF8)) { } else if (DecoderTraits::IsWebMTypeAndEnabled(mimeTypeUTF8)) {
if (!Preferences::GetBool("media.mediasource.webm.enabled", false)) { if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
IsWebMForced())) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
} }
if (hasCodecs && if (hasCodecs &&

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

@ -376,7 +376,13 @@ TrackBuffersManager::CompleteResetParserState()
// to discard now. // to discard now.
track->mQueuedSamples.Clear(); 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(); mIncomingBuffers.Clear();
mInputBuffer = nullptr; mInputBuffer = nullptr;
if (mCurrentInputBuffer) { if (mCurrentInputBuffer) {
@ -401,7 +407,7 @@ TrackBuffersManager::CompleteResetParserState()
} }
RecreateParser(true); RecreateParser(true);
// 7. Set append state to WAITING_FOR_SEGMENT. // 8. Set append state to WAITING_FOR_SEGMENT.
SetAppendState(AppendState::WAITING_FOR_SEGMENT); SetAppendState(AppendState::WAITING_FOR_SEGMENT);
// Reject our promise immediately. // Reject our promise immediately.

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

@ -100,7 +100,7 @@ nsresult
DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo, DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
nsCOMPtr<nsIStreamListener>& aInAndOutListener) 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(); nsIPrincipal* loadingPrincipal = aLoadInfo->LoadingPrincipal();
RefPtr<nsCORSListenerProxy> corsListener = RefPtr<nsCORSListenerProxy> corsListener =
new nsCORSListenerProxy(aInAndOutListener, new nsCORSListenerProxy(aInAndOutListener,

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

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

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

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

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

@ -102,7 +102,9 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMDocument> xslDocument; 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, nullptr, true, mozilla::net::RP_Default,
getter_AddRefs(xslDocument)); getter_AddRefs(xslDocument));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

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

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

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

@ -629,20 +629,6 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
getter_AddRefs(referrerPrincipal)); getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv); 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 // This is probably called by js, a loadGroup for the channel doesn't
// make sense. // make sense.
nsCOMPtr<nsINode> source; nsCOMPtr<nsINode> source;
@ -652,8 +638,12 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
} }
nsAutoSyncOperation sync(source ? source->OwnerDoc() : nullptr); nsAutoSyncOperation sync(source ? source->OwnerDoc() : nullptr);
nsCOMPtr<nsIDOMDocument> document; 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)); getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

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

@ -85,10 +85,6 @@ NS_IMETHODIMP nsTransactionList::ItemIsBatch(int32_t aIndex, bool *aIsBatch)
return item->GetIsBatch(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, NS_IMETHODIMP nsTransactionList::GetData(int32_t aIndex,
uint32_t *aLength, uint32_t *aLength,
nsISupports ***aData) nsISupports ***aData)

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

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

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

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

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

@ -42,7 +42,7 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <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> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@ -62,7 +62,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_WARNING</PreprocessorDefinitions> <PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <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'): if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'):
DEFINES['MOZ_ENABLE_FREETYPE'] = True 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'] CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'): if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'):

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

@ -11,6 +11,13 @@
#include "gfx2DGlue.h" #include "gfx2DGlue.h"
#include "nsAppRunner.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 mozilla {
namespace gfx { namespace gfx {
class Matrix4x4; class Matrix4x4;
@ -353,5 +360,49 @@ DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
return 4; 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 layers
} // namespace mozilla } // namespace mozilla

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

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

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

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

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

@ -22,6 +22,11 @@ namespace layers {
class GrallocTextureClientOGL; 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 * 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 #ifdef XP_MACOSX
#include "MacIOSurfaceTextureHostBasic.h" #include "MacIOSurfaceTextureHostBasic.h"
#endif #endif
#ifdef MOZ_WIDGET_GONK
#include "GrallocTextureHostBasic.h"
#endif
using namespace mozilla::gl; using namespace mozilla::gl;
using namespace mozilla::gfx; using namespace mozilla::gfx;
@ -25,6 +28,13 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
aDesc.get_SurfaceDescriptorMacIOSurface(); aDesc.get_SurfaceDescriptorMacIOSurface();
return MakeAndAddRef<MacIOSurfaceTextureHostBasic>(aFlags, desc); 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 #endif
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
} }

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

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

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

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

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

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

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

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

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

@ -51,13 +51,6 @@
#include "GeckoProfiler.h" #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 { namespace mozilla {
using namespace std; 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 void
CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform) CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform)
{ {

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

@ -232,8 +232,6 @@ public:
const gfx::Rect& aVisibleRect) override; const gfx::Rect& aVisibleRect) override;
virtual void EndFrame() 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 void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override;
virtual bool SupportsPartialTextureUpdate() override; virtual bool SupportsPartialTextureUpdate() override;
@ -452,7 +450,6 @@ private:
*/ */
gfx::IntSize mViewportSize; gfx::IntSize mViewportSize;
FenceHandle mReleaseFenceHandle;
ShaderProgramOGL *mCurrentProgram; ShaderProgramOGL *mCurrentProgram;
gfx::Rect mRenderBound; gfx::Rect mRenderBound;

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

@ -118,7 +118,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight()); mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight());
mCropSize = mSize; mCropSize = mSize;
} else { } 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(), EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(),
sync, sync,
0, 0,
400000000 /*400 usec*/); 400000000 /*400 msec*/);
if (status != LOCAL_EGL_CONDITION_SATISFIED) { if (status != LOCAL_EGL_CONDITION_SATISFIED) {
NS_ERROR("failed to wait native fence sync"); 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 487549-1.html
load 487724-1.html load 487724-1.html
load 490777-1.html load 490777-1.html
load 516512-1.html
load 532726-1.html load 532726-1.html
load 538065-1.html load 538065-1.html
load 546870-1.html load 546870-1.html
load 557348-1.html load 557348-1.html
load 563740-1.html
load 580100-1.html load 580100-1.html
load 580212-1.html load 580212-1.html
load 580233-1.html load 580233-1.html
@ -90,6 +92,7 @@ load 580719-1.html
load 593526.html load 593526.html
load 593526.xul load 593526.xul
load 594654-1.xhtml load 594654-1.xhtml
load 595042-1.html
load 595727-1.html load 595727-1.html
load 624198.xhtml load 624198.xhtml
load 633453-1.html load 633453-1.html

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

@ -163,7 +163,6 @@ RasterImage::Init(const char* aMimeType,
} }
//****************************************************************************** //******************************************************************************
// [notxpcom] void requestRefresh ([const] in TimeStamp aTime);
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
RasterImage::RequestRefresh(const TimeStamp& aTime) 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>) NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
RasterImage::GetFrame(uint32_t aWhichFrame, RasterImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags) uint32_t aFlags)
@ -972,7 +969,6 @@ RasterImage::ResetAnimation()
} }
//****************************************************************************** //******************************************************************************
// [notxpcom] void setAnimationStartTime ([const] in TimeStamp aTime);
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
RasterImage::SetAnimationStartTime(const TimeStamp& aTime) 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) NS_IMETHODIMP_(DrawResult)
RasterImage::Draw(gfxContext* aContext, RasterImage::Draw(gfxContext* aContext,
const IntSize& aSize, const IntSize& aSize,

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

@ -200,9 +200,6 @@ SVGDocumentWrapper::TickRefreshDriver()
/** nsIStreamListener methods **/ /** nsIStreamListener methods **/
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr, in unsigned long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP NS_IMETHODIMP
SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt, SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
nsIInputStream* inStr, 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 NS_IMETHODIMP
SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt, SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
nsresult status) nsresult status)

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

@ -683,8 +683,6 @@ VectorImage::IsOpaque()
} }
//****************************************************************************** //******************************************************************************
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
* in uint32_t aFlags; */
NS_IMETHODIMP_(already_AddRefed<SourceSurface>) NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
VectorImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) 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) NS_IMETHODIMP_(DrawResult)
VectorImage::Draw(gfxContext* aContext, VectorImage::Draw(gfxContext* aContext,
const nsIntSize& aSize, 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 NS_IMETHODIMP
VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt, VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
nsresult aStatus) nsresult aStatus)
@ -1241,9 +1230,6 @@ VectorImage::OnSVGDocumentError()
// nsIStreamListener method // nsIStreamListener method
//****************************************************************************** //******************************************************************************
/* void onDataAvailable(in nsIRequest request, in nsISupports ctxt,
in nsIInputStream inStr, in unsigned long sourceOffset,
in unsigned long count); */
NS_IMETHODIMP NS_IMETHODIMP
VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt, VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
nsIInputStream* aInStr, uint64_t aSourceOffset, nsIInputStream* aInStr, uint64_t aSourceOffset,

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

@ -60,6 +60,12 @@
// - It also added an optional color profile table after the pixel data (and // - It also added an optional color profile table after the pixel data (and
// another optional gap). // 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 // OS/2 VERSIONS OF THE BMP FORMAT
// ------------------------------- // -------------------------------
// OS2-BMPv1. // OS2-BMPv1.
@ -168,6 +174,9 @@ GetBMPLog()
nsBMPDecoder::nsBMPDecoder(RasterImage* aImage) nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
: Decoder(aImage) : Decoder(aImage)
, mLexer(Transition::To(State::FILE_HEADER, FileHeader::LENGTH)) , mLexer(Transition::To(State::FILE_HEADER, FileHeader::LENGTH))
, mIsWithinICO(false)
, mMayHaveTransparency(false)
, mDoesHaveTransparency(false)
, mNumColors(0) , mNumColors(0)
, mColors(nullptr) , mColors(nullptr)
, mBytesPerColor(0) , mBytesPerColor(0)
@ -175,8 +184,6 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
, mCurrentRow(0) , mCurrentRow(0)
, mCurrentPos(0) , mCurrentPos(0)
, mAbsoluteModeNumPixels(0) , mAbsoluteModeNumPixels(0)
, mUseAlphaData(false)
, mHaveAlphaData(false)
{ {
memset(&mBFH, 0, sizeof(mBFH)); memset(&mBFH, 0, sizeof(mBFH));
memset(&mBIH, 0, sizeof(mBIH)); memset(&mBIH, 0, sizeof(mBIH));
@ -187,13 +194,6 @@ nsBMPDecoder::~nsBMPDecoder()
delete[] mColors; 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. // Obtains the bits per pixel from the internal BIH header.
int32_t int32_t
nsBMPDecoder::GetBitsPerPixel() const nsBMPDecoder::GetBitsPerPixel() const
@ -250,7 +250,8 @@ nsBMPDecoder::FinishInternal()
nsIntRect r(0, 0, mBIH.width, GetHeight()); nsIntRect r(0, 0, mBIH.width, GetHeight());
PostInvalidation(r); PostInvalidation(r);
if (mUseAlphaData && mHaveAlphaData) { if (mDoesHaveTransparency) {
MOZ_ASSERT(mMayHaveTransparency);
PostFrameStop(Opacity::SOME_TRANSPARENCY); PostFrameStop(Opacity::SOME_TRANSPARENCY);
} else { } else {
PostFrameStop(Opacity::OPAQUE); PostFrameStop(Opacity::OPAQUE);
@ -268,21 +269,39 @@ BitFields::Value::Set(uint32_t aMask)
{ {
mMask = 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. // Find the rightmost 1.
bool started = false; uint8_t i;
mRightShift = mBitWidth = 0; for (i = 0; i < 32; i++) {
for (uint8_t pos = 0; pos <= 31; pos++) { if (mMask & (1 << i)) {
if (!started && (aMask & (1 << pos))) {
mRightShift = pos;
started = true;
} else if (started && !(aMask & (1 << pos))) {
mBitWidth = pos - mRightShift;
break; 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 BitFields::Value::Get(uint32_t aValue) const
{ {
// Extract the unscaled value. // Extract the unscaled value.
@ -314,6 +333,16 @@ BitFields::Value::Get(uint32_t aValue) const
return v2; 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 MOZ_ALWAYS_INLINE uint8_t
BitFields::Value::Get5(uint32_t aValue) const BitFields::Value::Get5(uint32_t aValue) const
{ {
@ -322,6 +351,14 @@ BitFields::Value::Get5(uint32_t aValue) const
return (v << 3u) | (v >> 2u); 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 void
BitFields::SetR5G5B5() BitFields::SetR5G5B5()
{ {
@ -330,12 +367,30 @@ BitFields::SetR5G5B5()
mBlue.Set(0x001f); mBlue.Set(0x001f);
} }
void
BitFields::SetR8G8B8()
{
mRed.Set(0xff0000);
mGreen.Set(0xff00);
mBlue.Set(0x00ff);
}
bool bool
BitFields::IsR5G5B5() const BitFields::IsR5G5B5() const
{ {
return mRed.mBitWidth == 5 && return mRed.mBitWidth == 5 &&
mGreen.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* uint32_t*
@ -458,6 +513,9 @@ nsBMPDecoder::ReadInfoHeaderSize(const char* aData, size_t aLength)
PostDataError(); PostDataError();
return Transition::Terminate(State::FAILURE); 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, return Transition::To(State::INFO_HEADER_REST,
mBIH.bihsize - BIHSIZE_FIELD_LENGTH); mBIH.bihsize - BIHSIZE_FIELD_LENGTH);
@ -530,6 +588,7 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
// Post our size to the superclass. // Post our size to the superclass.
uint32_t realHeight = GetHeight(); uint32_t realHeight = GetHeight();
PostSize(mBIH.width, realHeight); PostSize(mBIH.width, realHeight);
mCurrentRow = realHeight;
// Round it up to the nearest byte count, then pad to 4-byte boundary. // Round it up to the nearest byte count, then pad to 4-byte boundary.
// Compute this even for a metadate decode because GetCompressedImageSize() // Compute this even for a metadate decode because GetCompressedImageSize()
@ -540,24 +599,69 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
mPixelRowSize += 4 - surplus; mPixelRowSize += 4 - surplus;
} }
// We treat BMPs as transparent if they're 32bpp and alpha is enabled, but size_t bitFieldsLengthStillToRead = 0;
// also if they use RLE encoding, because the 'delta' mode can skip pixels if (mBIH.compression == Compression::BITFIELDS) {
// and cause implicit transparency. // Need to read bitfields.
bool hasTransparency = (mBIH.compression == Compression::RLE8) || if (mBIH.bihsize >= InfoHeaderLength::WIN_V4) {
(mBIH.compression == Compression::RLE4) || // Bitfields are present in the info header, so we can read them
(mBIH.bpp == 32 && mUseAlphaData); // immediately.
if (hasTransparency) { 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(); 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()) { if (IsMetadataDecode()) {
return Transition::Terminate(State::SUCCESS); 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(). // Set up the color table, if present; it'll be filled in by ReadColorTable().
if (mBIH.bpp <= 8) { if (mBIH.bpp <= 8) {
mNumColors = 1 << mBIH.bpp; 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 // BMPs store their rows in reverse order, so the downscaler needs to
// reverse them again when writing its output. // reverse them again when writing its output.
rv = mDownscaler->BeginFrame(GetSize(), Nothing(), rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
mImageData, hasTransparency, mImageData, mMayHaveTransparency,
/* aFlipVertically = */ true); /* aFlipVertically = */ true);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return Transition::Terminate(State::FAILURE); 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); return Transition::To(State::COLOR_TABLE, mNumColors * mBytesPerColor);
} }
@ -726,14 +791,20 @@ nsBMPDecoder::ReadPixelRow(const char* aData)
src += 2; src += 2;
} }
} else { } else {
bool anyHasAlpha = false;
while (lpos > 0) { while (lpos > 0) {
uint16_t val = LittleEndian::readUint16(src); uint16_t val = LittleEndian::readUint16(src);
SetPixel(dst, mBitFields.mRed.Get(val), SetPixel(dst, mBitFields.mRed.Get(val),
mBitFields.mGreen.Get(val), mBitFields.mGreen.Get(val),
mBitFields.mBlue.Get(val)); mBitFields.mBlue.Get(val),
mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
--lpos; --lpos;
src += 2; src += 2;
} }
if (anyHasAlpha) {
MOZ_ASSERT(mMayHaveTransparency);
mDoesHaveTransparency = true;
}
} }
break; break;
@ -746,19 +817,54 @@ nsBMPDecoder::ReadPixelRow(const char* aData)
break; break;
case 32: case 32:
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) { while (lpos > 0) {
if (mUseAlphaData) { // If src[3] is zero, we can't tell at this point if the image is
if (MOZ_UNLIKELY(!mHaveAlphaData && src[3])) { // 0RGB or ARGB. So we just use 0 value as-is. If the image is 0RGB
PostHasTransparency(); // then mDoesHaveTransparency will be false at the end, we'll treat
mHaveAlphaData = true; // 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]); SetPixel(dst, src[2], src[1], src[0], src[3]);
} else { src += 4;
SetPixel(dst, src[2], src[1], src[0]); --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; --lpos;
src += 4; 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;
}
}
break; break;
default: default:
@ -840,13 +946,10 @@ nsBMPDecoder::ReadRLESegment(const char* aData)
LexerTransition<nsBMPDecoder::State> LexerTransition<nsBMPDecoder::State>
nsBMPDecoder::ReadRLEDelta(const char* aData) 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. // transparent.
if (MOZ_UNLIKELY(!mHaveAlphaData)) { MOZ_ASSERT(mMayHaveTransparency);
PostHasTransparency(); mDoesHaveTransparency = true;
mHaveAlphaData = true;
}
mUseAlphaData = mHaveAlphaData = true;
if (mDownscaler) { if (mDownscaler) {
// Clear the skipped pixels. (This clears to the end of the row, // Clear the skipped pixels. (This clears to the end of the row,

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

@ -38,12 +38,26 @@ class BitFields {
void Set(uint32_t aMask); void Set(uint32_t aMask);
public: 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. /// Extracts the single color value from the multi-color value.
uint8_t Get(uint32_t aVal) const; uint8_t Get(uint32_t aVal) const;
/// Specialized version of Get() for the case where the bit-width is 5. /// Like Get(), but specially for alpha.
/// (It will assert if called and the bit-width is not 5.) 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 Get5(uint32_t aVal) const;
uint8_t Get8(uint32_t aVal) const;
}; };
public: public:
@ -51,15 +65,23 @@ public:
Value mRed; Value mRed;
Value mGreen; Value mGreen;
Value mBlue; Value mBlue;
Value mAlpha;
/// Set bitfields to the standard 5-5-5 16bpp values. /// Set bitfields to the standard 5-5-5 16bpp values.
void SetR5G5B5(); 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. /// Test if bitfields have the standard 5-5-5 16bpp values.
bool IsR5G5B5() const; bool IsR5G5B5() const;
/// Read the bitfields from a header. /// Test if bitfields have the standard 8-8-8 32bpp values.
void ReadFromHeader(const char* aData); 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. /// Length of the bitfields structure in the BMP file.
static const size_t LENGTH = 12; static const size_t LENGTH = 12;
@ -76,11 +98,6 @@ class nsBMPDecoder : public Decoder
public: public:
~nsBMPDecoder(); ~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. /// Obtains the bits per pixel from the internal BIH header.
int32_t GetBitsPerPixel() const; int32_t GetBitsPerPixel() const;
@ -97,12 +114,19 @@ public:
/// Obtains the size of the compressed image resource. /// Obtains the size of the compressed image resource.
int32_t GetCompressedImageSize() const; int32_t GetCompressedImageSize() const;
/// Obtains whether or not a BMP file had alpha data in its 4th byte for 32BPP /// Mark this BMP as being within an ICO file.
/// bitmaps. Use only after the bitmap has been processed. void SetIsWithinICO() { mIsWithinICO = true; }
bool HasAlphaData() const { return mHaveAlphaData; }
/// Marks this BMP as having alpha data (due to e.g. an ICO alpha mask). /// Did the BMP file have alpha data of any kind? (Only use this after the
void SetHasAlphaData() { mHaveAlphaData = true; } /// 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, virtual void WriteInternal(const char* aBuffer,
uint32_t aCount) override; uint32_t aCount) override;
@ -151,8 +175,19 @@ private:
bmp::FileHeader mBFH; bmp::FileHeader mBFH;
bmp::V5InfoHeader mBIH; bmp::V5InfoHeader mBIH;
// If the BMP is within an ICO file our treatment of it differs slightly.
bool mIsWithinICO;
bmp::BitFields mBitFields; 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 uint32_t mNumColors; // The number of used colors, i.e. the number of
// entries in mColors, if it's present. // entries in mColors, if it's present.
bmp::ColorTableEntry* mColors; // The color table, 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. // Only used in RLE_ABSOLUTE state: the number of pixels to read.
uint32_t mAbsoluteModeNumPixels; 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 } // namespace image

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

@ -393,7 +393,7 @@ nsICODecoder::SniffResource(const char* aData)
// is the AND mask, which isn't present in standalone BMPs. // is the AND mask, which isn't present in standalone BMPs.
nsBMPDecoder* bmpDecoder = new nsBMPDecoder(mImage); nsBMPDecoder* bmpDecoder = new nsBMPDecoder(mImage);
mContainedDecoder = bmpDecoder; mContainedDecoder = bmpDecoder;
bmpDecoder->SetUseAlphaData(true); bmpDecoder->SetIsWithinICO();
mContainedDecoder->SetMetadataDecode(IsMetadataDecode()); mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
mContainedDecoder->SetDecoderFlags(GetDecoderFlags()); mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags()); mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
@ -525,9 +525,9 @@ nsICODecoder::PrepareForMask()
MOZ_ASSERT(bmpLengthWithHeader < mDirEntry.mBytesInRes); MOZ_ASSERT(bmpLengthWithHeader < mDirEntry.mBytesInRes);
uint32_t maskLength = mDirEntry.mBytesInRes - bmpLengthWithHeader; 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. // 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) { GetRealWidth() == 0 || GetRealHeight() == 0) {
return Transition::ToUnbuffered(ICOState::FINISHED_RESOURCE, return Transition::ToUnbuffered(ICOState::FINISHED_RESOURCE,
ICOState::SKIP_MASK, ICOState::SKIP_MASK,
@ -658,7 +658,7 @@ nsICODecoder::FinishMask()
RefPtr<nsBMPDecoder> bmpDecoder = RefPtr<nsBMPDecoder> bmpDecoder =
static_cast<nsBMPDecoder*>(mContainedDecoder.get()); static_cast<nsBMPDecoder*>(mContainedDecoder.get());
bmpDecoder->SetHasAlphaData(); bmpDecoder->SetHasTransparency();
} }
return Transition::To(ICOState::FINISHED_RESOURCE, 0); 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); return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
} }
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter, in
voidPtr aClosure, in unsigned long aCount); */
NS_IMETHODIMP NS_IMETHODIMP
nsJPEGEncoder::ReadSegments(nsWriteSegmentFun aWriter, nsJPEGEncoder::ReadSegments(nsWriteSegmentFun aWriter,
void* aClosure, uint32_t aCount, uint32_t* _retval) void* aClosure, uint32_t aCount, uint32_t* _retval)

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

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

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

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

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

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

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

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

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

@ -38,15 +38,15 @@ TEST(ImageMetadata, ImageModuleAvailable)
EXPECT_TRUE(imgTools != nullptr); EXPECT_TRUE(imgTools != nullptr);
} }
enum class BMPAlpha enum class BMPWithinICO
{ {
DISABLED, NO,
ENABLED YES
}; };
static void static void
CheckMetadata(const ImageTestCase& aTestCase, CheckMetadata(const ImageTestCase& aTestCase,
BMPAlpha aBMPAlpha = BMPAlpha::DISABLED) BMPWithinICO aBMPWithinICO = BMPWithinICO::NO)
{ {
nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath); nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
ASSERT_TRUE(inputStream != nullptr); ASSERT_TRUE(inputStream != nullptr);
@ -70,8 +70,8 @@ CheckMetadata(const ImageTestCase& aTestCase,
DecoderFactory::CreateAnonymousMetadataDecoder(decoderType, sourceBuffer); DecoderFactory::CreateAnonymousMetadataDecoder(decoderType, sourceBuffer);
ASSERT_TRUE(decoder != nullptr); ASSERT_TRUE(decoder != nullptr);
if (aBMPAlpha == BMPAlpha::ENABLED) { if (aBMPWithinICO == BMPWithinICO::YES) {
static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true); static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
} }
// Run the metadata decoder synchronously. // Run the metadata decoder synchronously.
@ -100,7 +100,7 @@ CheckMetadata(const ImageTestCase& aTestCase,
EXPECT_EQ(aTestCase.mSize.width, metadataSize.width); EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
EXPECT_EQ(aTestCase.mSize.height, metadataSize.height); EXPECT_EQ(aTestCase.mSize.height, metadataSize.height);
bool expectTransparency = aBMPAlpha == BMPAlpha::ENABLED bool expectTransparency = aBMPWithinICO == BMPWithinICO::YES
? true ? true
: bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT); : bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT);
EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY)); EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY));
@ -114,8 +114,8 @@ CheckMetadata(const ImageTestCase& aTestCase,
DefaultSurfaceFlags()); DefaultSurfaceFlags());
ASSERT_TRUE(decoder != nullptr); ASSERT_TRUE(decoder != nullptr);
if (aBMPAlpha == BMPAlpha::ENABLED) { if (aBMPWithinICO == BMPWithinICO::YES) {
static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true); static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
} }
// Run the full decoder synchronously. // Run the full decoder synchronously.
@ -164,14 +164,16 @@ TEST(ImageMetadata, FirstFramePaddingGIF)
CheckMetadata(FirstFramePaddingGIFTestCase()); 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()); } TEST(ImageMetadata, RLE4BMP) { CheckMetadata(RLE4BMPTestCase()); }

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

@ -29,7 +29,7 @@ TEST_HARNESS_FILES.gtest += [
'no-frame-delay.gif', 'no-frame-delay.gif',
'rle4.bmp', 'rle4.bmp',
'rle8.bmp', 'rle8.bmp',
'transparent.bmp', 'transparent-if-within-ico.bmp',
'transparent.gif', 'transparent.gif',
'transparent.png', '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 # "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, # 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." # 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 == rgb32bf.bmp rgb24.png
# in 32bpp BMPs. Chromium gets this right.]
fails == 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 # "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, # channel, and 4 bits for the alpha channel. Its not clear if this is valid,
# but I cant find anything that suggests it isnt." # but I cant find anything that suggests it isnt."
# [XXX: we don't even try to do transparency for 16bpp. Chromium gets the == rgba16-4444.bmp rgba16-4444.png
# transparency right.]
fails == rgba16-4444.bmp rgba16-4444.png
# BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=300 # 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 # "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 # 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 # "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." # 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 fuzzy(1,1408) == rgb32-111110.bmp rgb24.png
# in 32bpp BMPs. Chromium gets this right.]
fails == rgb32-111110.bmp rgb24.png
# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0 # BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
# "A BMP with an alpha channel. Transparency is barely documented, so its # "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 # 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 # unusual order, to prevent viewers from passing this test by making a lucky
# guess." # guess."
# [XXX: we get this completely wrong because we don't handle BITFIELDS at all == rgba32.bmp rgba32.png
# in 32bpp BMPs, especially not with alpha. Chromium gets this right.]
fails == rgba32.bmp rgba32.png
# BMP: bihsize=40, 127 x 64, bpp=32, compression=6, colors=0 # 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. # "An image of type BI_ALPHABITFIELDS. Supposedly, this was used on Windows CE.

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

@ -130,9 +130,6 @@ nsScriptableUnicodeConverter::ConvertToUnicode(const nsACString& aSrc, nsAString
_retval); _retval);
} }
/* AString convertFromByteArray([const,array,size_is(aCount)] in octet aData,
in unsigned long aCount);
*/
NS_IMETHODIMP NS_IMETHODIMP
nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData, nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData,
uint32_t aCount, 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 NS_IMETHODIMP
nsScriptableUnicodeConverter::ConvertToByteArray(const nsAString& aString, nsScriptableUnicodeConverter::ConvertToByteArray(const nsAString& aString,
uint32_t* aLen, uint32_t* aLen,

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