Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-03-04 13:40:08 +01:00
commit 41362e0e1b
340 changed files with 6329 additions and 3358 deletions

View File

@ -16,6 +16,7 @@
#include "nsWhitespaceTokenizer.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
using namespace mozilla::a11y;
@ -861,12 +862,10 @@ struct RoleComparator
}
nsRoleMapEntry*
aria::GetRoleMap(nsINode* aNode)
aria::GetRoleMap(dom::Element* aEl)
{
nsIContent* content = nsCoreUtils::GetRoleContent(aNode);
nsAutoString roles;
if (!content ||
!content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roles) ||
if (!aEl || !aEl->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roles) ||
roles.IsEmpty()) {
// We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
return nullptr;

View File

@ -210,7 +210,7 @@ extern nsRoleMapEntry gEmptyRoleMap;
* @return a pointer to the role map entry for the ARIA role, or nullptr
* if none
*/
nsRoleMapEntry* GetRoleMap(nsINode* aNode);
nsRoleMapEntry* GetRoleMap(dom::Element* aEl);
/**
* Return accessible state from ARIA universal states applied to the given

View File

@ -131,11 +131,11 @@ nsAccUtils::GetLevelForXULContainerItem(nsIContent *aContent)
void
nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
nsIContent *aStartContent,
nsIContent *aTopContent)
nsIContent* aStartContent,
dom::Element* aTopEl)
{
nsAutoString live, relevant, busy;
nsIContent *ancestor = aStartContent;
nsIContent* ancestor = aStartContent;
while (ancestor) {
// container-relevant attribute
@ -146,10 +146,12 @@ nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
// container-live, and container-live-role attributes
if (live.IsEmpty()) {
nsRoleMapEntry* role = aria::GetRoleMap(ancestor);
nsRoleMapEntry* role = nullptr;
if (ancestor->IsElement()) {
role = aria::GetRoleMap(ancestor->AsElement());
}
if (HasDefinedARIAToken(ancestor, nsGkAtoms::aria_live)) {
ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live,
live);
ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live, live);
} else if (role) {
GetLiveAttrValue(role->liveAttRule, live);
}
@ -175,12 +177,12 @@ nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_busy, busy))
SetAccAttr(aAttributes, nsGkAtoms::containerBusy, busy);
if (ancestor == aTopContent)
if (ancestor == aTopEl)
break;
ancestor = ancestor->GetParent();
if (!ancestor)
ancestor = aTopContent; // Use <body>/<frameset>
ancestor = aTopEl; // Use <body>/<frameset>
}
}

View File

@ -85,8 +85,8 @@ public:
* @param aTopContent node to end at
*/
static void SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
nsIContent *aStartContent,
nsIContent *aTopContent);
nsIContent* aStartContent,
mozilla::dom::Element* aTopEl);
/**
* Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA

View File

@ -142,7 +142,7 @@ New_HTMLLink(nsIContent* aContent, Accessible* aContext)
{
// Only some roles truly enjoy life as HTMLLinkAccessibles, for details
// see closed bug 494807.
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent);
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent->AsElement());
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
roleMapEntry->role != roles::LINK) {
return new HyperTextAccessibleWrap(aContent, aContext->Document());
@ -1128,11 +1128,11 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
}
newAcc = new HyperTextAccessibleWrap(content, document);
document->BindToDocument(newAcc, aria::GetRoleMap(aNode));
document->BindToDocument(newAcc, aria::GetRoleMap(content->AsElement()));
return newAcc;
}
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aNode);
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(content->AsElement());
// If the element is focusable or global ARIA attribute is applied to it or
// it is referenced by ARIA relationship then treat role="presentation" on

View File

@ -223,7 +223,7 @@ nsCoreUtils::GetDOMNodeFromDOMPoint(nsINode *aNode, uint32_t aOffset)
return aNode;
}
nsIContent*
dom::Element*
nsCoreUtils::GetRoleContent(nsINode *aNode)
{
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
@ -242,7 +242,7 @@ nsCoreUtils::GetRoleContent(nsINode *aNode)
}
}
return content;
return (content && content->IsElement()) ? content->AsElement() : nullptr;
}
bool

View File

@ -117,7 +117,7 @@ public:
* @param aNode [in] DOM node for the accessible that may be affected by ARIA
* @return the nsIContent which may have ARIA markup
*/
static nsIContent* GetRoleContent(nsINode *aNode);
static mozilla::dom::Element* GetRoleContent(nsINode *aNode);
/**
* Is the first passed in node an ancestor of the second?

View File

@ -1463,10 +1463,10 @@ DocAccessible::DoInitialUpdate()
// The content element may be changed before the initial update and then we
// miss the notification (since content tree change notifications are ignored
// prior to initial update). Make sure the content element is valid.
nsIContent* contentElm = nsCoreUtils::GetRoleContent(mDocumentNode);
if (contentElm) {
mContent = contentElm;
SetRoleMapEntry(aria::GetRoleMap(mContent));
dom::Element* rootEl = nsCoreUtils::GetRoleContent(mDocumentNode);
if (rootEl) {
mContent = rootEl;
SetRoleMapEntry(aria::GetRoleMap(rootEl));
}
// Build initial tree. Since its the initial tree there's no group info to
@ -1700,10 +1700,10 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer,
if (container == this) {
// If new root content has been inserted then update it.
nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocumentNode);
if (rootContent != mContent) {
mContent = rootContent;
SetRoleMapEntry(aria::GetRoleMap(mContent));
dom::Element* rootEl = nsCoreUtils::GetRoleContent(mDocumentNode);
if (rootEl != mContent) {
mContent = rootEl;
SetRoleMapEntry(aria::GetRoleMap(rootEl));
}
// Continue to update the tree even if we don't have root content.

View File

@ -109,11 +109,10 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
uint32_t areaElmCount = imageMapObj->AreaCount();
for (uint32_t idx = 0; idx < areaElmCount; idx++) {
nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
Accessible* area = mChildren.SafeElementAt(idx);
if (!area || area->GetContent() != areaContent) {
RefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
mDoc->BindToDocument(area, aria::GetRoleMap(areaContent->AsElement()));
if (!InsertChildAt(idx, area)) {
mDoc->UnbindFromDocument(area);

View File

@ -19,6 +19,10 @@ function test() {
let notificationBox = window.gBrowser.getNotificationBox();
let notification = notificationBox.getNotificationWithValue(notificationValue);
ok(notification, "Notification box should be displayed");
if (notification == null) {
finish();
return;
}
is(notification.type, "info", "We expect this notification to have the type of 'info'.");
isnot(notification.image, null, "We expect this notification to have an icon.");
@ -33,7 +37,7 @@ function test() {
todo_isnot(button.accesskey, null, "We expect the add button to have a accesskey.");
finish();
}, 100);
}, "Still can not get notification after retry 100 times.", 100);
window.gBrowser.selectedBrowser.loadURI(testURI);
}

View File

@ -66,6 +66,7 @@ function* testSendReportAutomatically(testURL, suffix, errorURISuffix) {
// Load the page and wait for the error report submission.
let promiseStatus = createReportResponseStatusPromise(URL_REPORTS + suffix);
browser.loadURI(testURL);
yield promiseErrorPageLoaded(browser);
ok(!isErrorStatus(yield promiseStatus),
"SSL error report submitted successfully");

View File

@ -84,7 +84,7 @@ function* checkInput(inputStr) {
let expectedURL = "moz-action:" + type + "," + JSON.stringify(params);
Assert.equal(item.getAttribute("url"), expectedURL, "url");
Assert.equal(item.getAttribute("title"), inputStr, "title");
Assert.equal(item.getAttribute("title"), inputStr.replace("\\","/"), "title");
Assert.equal(item.getAttribute("text"), inputStr, "text");
let itemTypeStr = item.getAttribute("type");
@ -93,5 +93,5 @@ function* checkInput(inputStr) {
["action", "heuristic", "visiturl"].toString(),
"type");
Assert.equal(item._title.textContent, "Visit " + inputStr, "Visible title");
Assert.equal(item._title.textContent, "Visit " + inputStr.replace("\\","/"), "Visible title");
}

View File

@ -95,10 +95,11 @@ function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
aBrowserWin.gCustomizeMode.exit();
}
function waitForCondition(condition, nextTest, errorMsg) {
function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
retryTimes = typeof retryTimes !== 'undefined' ? retryTimes : 30;
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
if (tries >= retryTimes) {
ok(false, errorMsg);
moveOn();
}

View File

@ -342,12 +342,12 @@ add_task(function* () {
is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED,
"Test 26, plugin fallback type should be PLUGIN_BLOCKLISTED");
let result = ContentTask.spawn(gTestBrowser, {}, function* () {
let result = yield ContentTask.spawn(gTestBrowser, {}, function* () {
let plugin = content.document.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
return objLoadingContent.activated;
});
ok(result, "Plugin should be activated.");
ok(!result, "Plugin should not be activated.");
const testUrl = "http://test.url.com/";

View File

@ -360,7 +360,7 @@ add_task(function* () {
let overlayRect = mainBox.getBoundingClientRect();
return overlayRect.width == 200 && overlayRect.height == 200;
});
ok(result, "Test 20b, Waited too long for plugin to become visible");
ok(result, "Test 20c, plugin should have overlay dims of 200px");
pluginInfo = yield promiseForPluginInfo("test");
ok(!pluginInfo.activated, "Test 20b, plugin should not be activated");
@ -386,13 +386,13 @@ add_task(function* () {
pluginInfo = yield promiseForPluginInfo("test");
ok(pluginInfo.activated, "Test 20c, plugin should be activated");
result = ContentTask.spawn(gTestBrowser, {}, function* () {
result = yield ContentTask.spawn(gTestBrowser, {}, function* () {
let doc = content.document;
let plugin = doc.getElementById("test");
let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
return overlayRect.width == 0 && overlayRect.height == 0;
});
ok(result, "Test 20c, plugin should have overlay dims of 200px");
ok(result, "Test 20c, plugin should have overlay dims of 0px");
clearAllPluginPermissions();
});
@ -466,7 +466,7 @@ add_task(function* () {
ok(notification.options.pluginData.size == 2, "Test 21c, Should have one type of plugin in the notification");
let result = ContentTask.spawn(gTestBrowser, {}, function* () {
let result = yield ContentTask.spawn(gTestBrowser, {}, function* () {
let doc = content.document;
let plugin = doc.getElementById("test");
let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();

View File

@ -15,29 +15,33 @@ var {
// Map[Extension -> Map[ID -> MenuItem]]
// Note: we want to enumerate all the menu items so
// this cannot be a weak map.
var contextMenuMap = new Map();
var gContextMenuMap = new Map();
// Map[Extension -> MenuItem]
var rootItems = new Map();
var gRootItems = new Map();
// Not really used yet, will be used for event pages.
var onClickedCallbacksMap = new WeakMap();
var gOnClickedCallbacksMap = new WeakMap();
// If id is not specified for an item we use an integer.
var nextID = 0;
var gNextMenuItemID = 0;
// Used to assign unique names to radio groups.
var gNextRadioGroupID = 0;
// The max length of a menu item's label.
var gMaxLabelLength = 64;
// When a new contextMenu is opened, this function is called and
// we populate the |xulMenu| with all the items from extensions
// to be displayed. We always clear all the items again when
// popuphidden fires.
var menuBuilder = {
var gMenuBuilder = {
build: function(contextData) {
let xulMenu = contextData.menu;
xulMenu.addEventListener("popuphidden", this);
this.xulMenu = xulMenu;
for (let [, root] of rootItems) {
for (let [, root] of gRootItems) {
let rootElement = this.buildElementWithChildren(root, contextData);
if (!rootElement.childNodes.length) {
// If the root has no visible children, there is no reason to show
@ -46,6 +50,23 @@ var menuBuilder = {
}
rootElement.setAttribute("ext-type", "top-level-menu");
rootElement = this.removeTopLevelMenuIfNeeded(rootElement);
// Display the extension icon on the root element.
if (root.extension.manifest.icons) {
let parentWindow = contextData.menu.ownerDocument.defaultView;
let extension = root.extension;
let url = IconDetails.getURL(extension.manifest.icons, parentWindow, extension, 16 /* size */);
let resolvedURL = root.extension.baseURI.resolve(url);
if (rootElement.localName == "menu") {
rootElement.setAttribute("class", "menu-iconic");
} else if (rootElement.localName == "menuitem") {
rootElement.setAttribute("class", "menuitem-iconic");
}
rootElement.setAttribute("image", resolvedURL);
}
xulMenu.appendChild(rootElement);
this.itemsToCleanUp.add(rootElement);
}
@ -53,7 +74,17 @@ var menuBuilder = {
buildElementWithChildren(item, contextData) {
let element = this.buildSingleElement(item, contextData);
let groupName;
for (let child of item.children) {
if (child.type == "radio" && !child.groupName) {
if (!groupName) {
groupName = `webext-radio-group-${gNextRadioGroupID++}`;
}
child.groupName = groupName;
} else {
groupName = null;
}
if (child.enabledForContext(contextData)) {
let childElement = this.buildElementWithChildren(child, contextData);
// Here element must be a menu element and its first child
@ -95,8 +126,7 @@ var menuBuilder = {
createMenuElement(doc, item) {
let element = doc.createElement("menu");
// Menu elements need to have a menupopup child for
// its menu items.
// Menu elements need to have a menupopup child for its menu items.
let menupopup = doc.createElement("menupopup");
element.appendChild(menupopup);
return element;
@ -120,11 +150,37 @@ var menuBuilder = {
element.setAttribute("label", label);
}
if (item.type == "checkbox") {
element.setAttribute("type", "checkbox");
if (item.checked) {
element.setAttribute("checked", "true");
}
} else if (item.type == "radio") {
element.setAttribute("type", "radio");
element.setAttribute("name", item.groupName);
if (item.checked) {
element.setAttribute("checked", "true");
}
}
if (!item.enabled) {
element.setAttribute("disabled", true);
element.setAttribute("disabled", "true");
}
element.addEventListener("command", event => { // eslint-disable-line mozilla/balanced-listeners
if (item.type == "checkbox") {
item.checked = !item.checked;
} else if (item.type == "radio") {
// Deselect all radio items in the current radio group.
for (let child of item.parent.children) {
if (child.type == "radio" && child.groupName == item.groupName) {
child.checked = false;
}
}
// Select the clicked radio item.
item.checked = true;
}
item.tabManager.addActiveTabPermission();
if (item.onclick) {
let clickData = item.getClickData(contextData, event);
@ -154,7 +210,7 @@ var menuBuilder = {
function contextMenuObserver(subject, topic, data) {
subject = subject.wrappedJSObject;
menuBuilder.build(subject);
gMenuBuilder.build(subject);
}
function getContexts(contextData) {
@ -203,7 +259,7 @@ function MenuItem(extension, extContext, createProperties, isRoot = false) {
this.setDefaults();
this.setProps(createProperties);
if (!this.hasOwnProperty("_id")) {
this.id = nextID++;
this.id = gNextMenuItemID++;
}
// If the item is not the root and has no parent
// it must be a child of the root.
@ -234,9 +290,9 @@ MenuItem.prototype = {
setDefaults() {
this.setProps({
type: "normal",
checked: "false",
checked: false,
contexts: ["all"],
enabled: "true",
enabled: true,
});
},
@ -244,7 +300,7 @@ MenuItem.prototype = {
if (this.hasOwnProperty("_id")) {
throw new Error("Id of a MenuItem cannot be changed");
}
let isIdUsed = contextMenuMap.get(this.extension).has(id);
let isIdUsed = gContextMenuMap.get(this.extension).has(id);
if (isIdUsed) {
throw new Error("Id already exists");
}
@ -259,7 +315,7 @@ MenuItem.prototype = {
if (parentId === undefined) {
return;
}
let menuMap = contextMenuMap.get(this.extension);
let menuMap = gContextMenuMap.get(this.extension);
if (!menuMap.has(parentId)) {
throw new Error("Could not find any MenuItem with id: " + parentId);
}
@ -280,7 +336,7 @@ MenuItem.prototype = {
if (parentId === undefined) {
this.root.addChild(this);
} else {
let menuMap = contextMenuMap.get(this.extension);
let menuMap = gContextMenuMap.get(this.extension);
menuMap.get(parentId).addChild(this);
}
},
@ -308,14 +364,14 @@ MenuItem.prototype = {
get root() {
let extension = this.extension;
if (!rootItems.has(extension)) {
if (!gRootItems.has(extension)) {
let root = new MenuItem(extension, this.context,
{title: extension.name},
/* isRoot = */ true);
rootItems.set(extension, root);
gRootItems.set(extension, root);
}
return rootItems.get(extension);
return gRootItems.get(extension);
},
remove() {
@ -327,10 +383,10 @@ MenuItem.prototype = {
child.remove();
}
let menuMap = contextMenuMap.get(this.extension);
let menuMap = gContextMenuMap.get(this.extension);
menuMap.delete(this.id);
if (this.root == this) {
rootItems.delete(this.extension);
gRootItems.delete(this.extension);
}
},
@ -394,12 +450,12 @@ MenuItem.prototype = {
},
};
var extCount = 0;
var gExtensionCount = 0;
/* eslint-disable mozilla/balanced-listeners */
extensions.on("startup", (type, extension) => {
contextMenuMap.set(extension, new Map());
rootItems.delete(extension);
if (++extCount == 1) {
gContextMenuMap.set(extension, new Map());
gRootItems.delete(extension);
if (++gExtensionCount == 1) {
Services.obs.addObserver(contextMenuObserver,
"on-build-contextmenu",
false);
@ -407,8 +463,8 @@ extensions.on("startup", (type, extension) => {
});
extensions.on("shutdown", (type, extension) => {
contextMenuMap.delete(extension);
if (--extCount == 0) {
gContextMenuMap.delete(extension);
if (--gExtensionCount == 0) {
Services.obs.removeObserver(contextMenuObserver,
"on-build-contextmenu");
}
@ -420,7 +476,7 @@ extensions.registerSchemaAPI("contextMenus", "contextMenus", (extension, context
contextMenus: {
create: function(createProperties, callback) {
let menuItem = new MenuItem(extension, context, createProperties);
contextMenuMap.get(extension).set(menuItem.id, menuItem);
gContextMenuMap.get(extension).set(menuItem.id, menuItem);
if (callback) {
runSafe(context, callback);
}
@ -428,7 +484,7 @@ extensions.registerSchemaAPI("contextMenus", "contextMenus", (extension, context
},
update: function(id, updateProperties) {
let menuItem = contextMenuMap.get(extension).get(id);
let menuItem = gContextMenuMap.get(extension).get(id);
if (menuItem) {
menuItem.setProps(updateProperties);
}
@ -436,7 +492,7 @@ extensions.registerSchemaAPI("contextMenus", "contextMenus", (extension, context
},
remove: function(id) {
let menuItem = contextMenuMap.get(extension).get(id);
let menuItem = gContextMenuMap.get(extension).get(id);
if (menuItem) {
menuItem.remove();
}
@ -444,7 +500,7 @@ extensions.registerSchemaAPI("contextMenus", "contextMenus", (extension, context
},
removeAll: function() {
let root = rootItems.get(extension);
let root = gRootItems.get(extension);
if (root) {
root.remove();
}
@ -457,9 +513,9 @@ extensions.registerSchemaAPI("contextMenus", "contextMenus", (extension, context
fire(menuItem.data);
};
onClickedCallbacksMap.set(extension, callback);
gOnClickedCallbacksMap.set(extension, callback);
return () => {
onClickedCallbacksMap.delete(extension);
gOnClickedCallbacksMap.delete(extension);
};
}).api(),
},

View File

@ -102,10 +102,10 @@ global.IconDetails = {
// Returns the appropriate icon URL for the given icons object and the
// screen resolution of the given window.
getURL(icons, window, extension) {
getURL(icons, window, extension, size = 18) {
const DEFAULT = "chrome://browser/content/extension.svg";
return AddonManager.getPreferredIconURL({icons: icons}, 18, window) || DEFAULT;
return AddonManager.getPreferredIconURL({icons: icons}, size, window) || DEFAULT;
},
convertImageDataToPNG(imageData, context) {

View File

@ -4,7 +4,6 @@
/* globals content */
/* eslint-disable mozilla/no-cpows-in-tests */
add_task(function* () {
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
"http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
@ -19,17 +18,24 @@ add_task(function* () {
background: function() {
// A generic onclick callback function.
function genericOnClick(info) {
browser.test.sendMessage("menuItemClick", JSON.stringify(info));
browser.test.sendMessage("menuItemClick", info);
}
browser.contextMenus.create({contexts: ["all"], type: "separator"});
browser.contextMenus.create({
contexts: ["all"],
type: "separator",
});
let contexts = ["page", "selection", "image"];
for (let i = 0; i < contexts.length; i++) {
let context = contexts[i];
let title = context;
browser.contextMenus.create({title: title, contexts: [context], id: "ext-" + context,
onclick: genericOnClick});
browser.contextMenus.create({
title: title,
contexts: [context],
id: "ext-" + context,
onclick: genericOnClick,
});
if (context == "selection") {
browser.contextMenus.update("ext-selection", {
title: "selection is: '%s'",
@ -41,58 +47,171 @@ add_task(function* () {
}
}
let parent = browser.contextMenus.create({title: "parent"});
browser.contextMenus.create(
{title: "child1", parentId: parent, onclick: genericOnClick});
let child2 = browser.contextMenus.create(
{title: "child2", parentId: parent, onclick: genericOnClick});
let parent = browser.contextMenus.create({
title: "parent",
});
browser.contextMenus.create({
title: "child1",
parentId: parent,
onclick: genericOnClick,
});
let child2 = browser.contextMenus.create({
title: "child2",
parentId: parent,
onclick: genericOnClick,
});
let parentToDel = browser.contextMenus.create({title: "parentToDel"});
browser.contextMenus.create(
{title: "child1", parentId: parentToDel, onclick: genericOnClick});
browser.contextMenus.create(
{title: "child2", parentId: parentToDel, onclick: genericOnClick});
let parentToDel = browser.contextMenus.create({
title: "parentToDel",
});
browser.contextMenus.create({
title: "child1",
parentId: parentToDel,
onclick: genericOnClick,
});
browser.contextMenus.create({
title: "child2",
parentId: parentToDel,
onclick: genericOnClick,
});
browser.contextMenus.remove(parentToDel);
browser.contextMenus.create({
title: "radio-group-1",
type: "radio",
checked: true,
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.create({
title: "Checkbox",
type: "checkbox",
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.create({
title: "radio-group-2",
type: "radio",
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.create({
title: "radio-group-2",
type: "radio",
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.create({
type: "separator",
});
browser.contextMenus.create({
title: "Checkbox",
type: "checkbox",
checked: true,
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.create({
title: "Checkbox",
type: "checkbox",
contexts: ["page"],
onclick: genericOnClick,
});
browser.contextMenus.update(parent, {parentId: child2}).then(
() => {
browser.test.notifyFail();
},
() => {
browser.test.notifyPass();
});
}
);
},
});
let expectedClickInfo;
function checkClickInfo(info) {
info = JSON.parse(info);
for (let i in expectedClickInfo) {
is(info[i], expectedClickInfo[i],
"click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + info[i]);
}
is(expectedClickInfo.pageSrc, info.tab.url);
}
yield extension.startup();
yield extension.awaitFinish();
// Bring up context menu
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
yield BrowserTestUtils.synthesizeMouseAtCenter("#img1",
{type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
yield popupShownPromise;
let contentAreaContextMenu;
function getTop() {
contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
is(items.length, 1, "top level item was found (context=selection)");
let topItem = items[0];
return topItem.childNodes[0];
}
function* openExtensionMenu() {
contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
yield BrowserTestUtils.synthesizeMouseAtCenter("#img1", {
type: "contextmenu",
button: 2,
}, gBrowser.selectedBrowser);
yield popupShownPromise;
popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(getTop(), {});
yield popupShownPromise;
}
function* closeContextMenu(itemToSelect, expectedClickInfo) {
function checkClickInfo(info) {
for (let i of Object.keys(expectedClickInfo)) {
is(info[i], expectedClickInfo[i],
"click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + info[i]);
}
is(expectedClickInfo.pageSrc, info.tab.url);
}
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
EventUtils.synthesizeMouseAtCenter(itemToSelect, {});
let clickInfo = yield extension.awaitMessage("menuItemClick");
if (expectedClickInfo) {
checkClickInfo(clickInfo);
}
yield popupHiddenPromise;
}
function confirmRadioGroupStates(expectedStates) {
let top = getTop();
let radioItems = top.getElementsByAttribute("type", "radio");
let radioGroup1 = top.getElementsByAttribute("label", "radio-group-1");
let radioGroup2 = top.getElementsByAttribute("label", "radio-group-2");
is(radioItems.length, 3, "there should be 3 radio items in the context menu");
is(radioGroup1.length, 1, "the first radio group should only have 1 radio item");
is(radioGroup2.length, 2, "the second radio group should only have 2 radio items");
is(radioGroup1[0].hasAttribute("checked"), expectedStates[0], `radio item 1 has state (checked=${expectedStates[0]})`);
is(radioGroup2[0].hasAttribute("checked"), expectedStates[1], `radio item 2 has state (checked=${expectedStates[1]})`);
is(radioGroup2[1].hasAttribute("checked"), expectedStates[2], `radio item 3 has state (checked=${expectedStates[2]})`);
}
function confirmCheckboxStates(expectedStates) {
let checkboxItems = getTop().getElementsByAttribute("type", "checkbox");
is(checkboxItems.length, 3, "there should be 3 checkbox items in the context menu");
is(checkboxItems[0].hasAttribute("checked"), expectedStates[0], `checkbox item 1 has state (checked=${expectedStates[0]})`);
is(checkboxItems[1].hasAttribute("checked"), expectedStates[1], `checkbox item 2 has state (checked=${expectedStates[1]})`);
is(checkboxItems[2].hasAttribute("checked"), expectedStates[2], `checkbox item 3 has state (checked=${expectedStates[2]})`);
}
yield openExtensionMenu();
// Check some menu items
let items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
is(items.length, 1, "top level item was found (context=image)");
let topItem = items.item(0);
let top = topItem.childNodes[0];
items = top.getElementsByAttribute("label", "image");
let top = getTop();
let items = top.getElementsByAttribute("label", "image");
is(items.length, 1, "contextMenu item for image was found (context=image)");
let image = items.item(0);
let image = items[0];
items = top.getElementsByAttribute("label", "selection-edited");
is(items.length, 0, "contextMenu item for selection was not found (context=image)");
@ -103,21 +222,54 @@ add_task(function* () {
items = top.getElementsByAttribute("label", "parent");
is(items.length, 1, "contextMenu item for parent was found (context=image)");
is(items.item(0).childNodes[0].childNodes.length, 2, "child items for parent were found (context=image)");
is(items[0].childNodes[0].childNodes.length, 2, "child items for parent were found (context=image)");
// Click on ext-image item and check the results
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
expectedClickInfo = {
// Click on ext-image item and check the click results
yield closeContextMenu(image, {
menuItemId: "ext-image",
mediaType: "image",
srcUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/ctxmenu-image.png",
pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
};
top.openPopup(topItem, "end_before", 0, 0, true, false);
EventUtils.synthesizeMouseAtCenter(image, {});
let clickInfo = yield extension.awaitMessage("menuItemClick");
checkClickInfo(clickInfo);
yield popupHiddenPromise;
});
// Test radio groups
yield openExtensionMenu();
confirmRadioGroupStates([true, false, false]);
items = getTop().getElementsByAttribute("type", "radio");
yield closeContextMenu(items[1]);
yield openExtensionMenu();
confirmRadioGroupStates([true, true, false]);
items = getTop().getElementsByAttribute("type", "radio");
yield closeContextMenu(items[2]);
yield openExtensionMenu();
confirmRadioGroupStates([true, false, true]);
items = getTop().getElementsByAttribute("type", "radio");
yield closeContextMenu(items[0]);
yield openExtensionMenu();
confirmRadioGroupStates([true, false, true]);
// Test checkboxes
items = getTop().getElementsByAttribute("type", "checkbox");
confirmCheckboxStates([false, true, false]);
yield closeContextMenu(items[0]);
yield openExtensionMenu();
confirmCheckboxStates([true, true, false]);
items = getTop().getElementsByAttribute("type", "checkbox");
yield closeContextMenu(items[2]);
yield openExtensionMenu();
confirmCheckboxStates([true, true, true]);
items = getTop().getElementsByAttribute("type", "checkbox");
yield closeContextMenu(items[0]);
yield openExtensionMenu();
confirmCheckboxStates([false, true, true]);
items = getTop().getElementsByAttribute("type", "checkbox");
yield closeContextMenu(items[2]);
// Select some text
yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
@ -132,39 +284,22 @@ add_task(function* () {
});
// Bring up context menu again
popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
yield BrowserTestUtils.synthesizeMouse(null, 1, 1,
{type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
yield popupShownPromise;
items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
is(items.length, 1, "top level item was found (context=selection)");
top = items.item(0).childNodes[0];
yield openExtensionMenu();
// Check some menu items
top = getTop();
items = top.getElementsByAttribute("label", "selection is: 'just some text 123456789012345678901234567890...'");
is(items.length, 1, "contextMenu item for selection was found (context=selection)");
let selectionItem = items.item(0);
let selectionItem = items[0];
items = top.getElementsByAttribute("label", "selection");
is(items.length, 0, "contextMenu item label update worked (context=selection)");
popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
expectedClickInfo = {
yield closeContextMenu(selectionItem, {
menuItemId: "ext-selection",
pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
selectionText: "just some text 1234567890123456789012345678901234567890123456789012345678901234567890123456789012",
};
top.openPopup(topItem, "end_before", 0, 0, true, false);
EventUtils.synthesizeMouseAtCenter(selectionItem, {});
clickInfo = yield extension.awaitMessage("menuItemClick");
checkClickInfo(clickInfo);
yield popupHiddenPromise;
popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
yield BrowserTestUtils.synthesizeMouseAtCenter("#img1",
{type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
yield popupShownPromise;
});
items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
is(items.length, 0, "top level item was not found (after removeAll()");

View File

@ -264,7 +264,9 @@ var SessionHistoryInternal = {
let history = webNavigation.sessionHistory;
if ("userContextId" in tabData) {
docShell.setUserContextId(tabData.userContextId);
let attrs = docShell.getOriginAttributes();
attrs.userContextId = tabData.userContextId;
docShell.setOriginAttributes(attrs);
}
if (history.count > 0) {

View File

@ -13,6 +13,4 @@ mk_add_options MOZ_PGO=1
ac_add_options --enable-official-branding
ac_add_options --enable-verify-mar
. "$topsrcdir/build/mozconfig.rust"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -6,7 +6,5 @@ ac_add_options --enable-verify-mar
ac_add_options --with-branding=browser/branding/nightly
. "$topsrcdir/build/mozconfig.rust"
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.cache"

View File

@ -19,6 +19,4 @@ ac_add_options --enable-verify-mar
# defines.sh during the beta cycle
export BUILDING_RELEASE=1
. "$topsrcdir/build/mozconfig.rust"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -0,0 +1,107 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
// The amount of people to be part of e10s, in %
const TEST_THRESHOLD = {
"beta" : 50,
"release" : 0,
};
const PREF_COHORT_SAMPLE = "e10s.rollout.cohortSample";
const PREF_COHORT_NAME = "e10s.rollout.cohort";
const PREF_E10S_OPTED_IN = "browser.tabs.remote.autostart";
const PREF_E10S_FORCE_ENABLED = "browser.tabs.remote.force-enable";
const PREF_E10S_FORCE_DISABLED = "browser.tabs.remote.force-disable";
const PREF_TOGGLE_E10S = "browser.tabs.remote.autostart.2";
function startup() {
// In theory we only need to run this once (on install()), but
// it's better to also run it on every startup. If the user has
// made manual changes to the prefs, this will keep the data
// reported more accurate.
// It's also fine (and preferred) to just do it here on startup
// (instead of observing prefs), because e10s takes a restart
// to take effect, so we keep the data based on how it was when
// the session started.
defineCohort();
}
function install() {
defineCohort();
}
let cohortDefinedOnThisSession = false;
function defineCohort() {
// Avoid running twice when it was called by install() first
if (cohortDefinedOnThisSession) {
return;
}
cohortDefinedOnThisSession = true;
let updateChannel = UpdateUtils.getUpdateChannel(false);
if (!(updateChannel in TEST_THRESHOLD)) {
setCohort("unsupportedChannel");
return;
}
let userOptedOut = optedOut();
let userOptedIn = optedIn();
let testGroup = (getUserSample() < TEST_THRESHOLD[updateChannel]);
if (userOptedOut) {
setCohort("optedOut");
} else if (userOptedIn) {
setCohort("optedIn");
} else if (testGroup) {
setCohort("test");
Preferences.set(PREF_TOGGLE_E10S, true);
} else {
setCohort("control");
Preferences.reset(PREF_TOGGLE_E10S);
}
}
function shutdown(data, reason) {
}
function uninstall() {
}
function getUserSample() {
let existingVal = Preferences.get(PREF_COHORT_SAMPLE, undefined);
if (typeof(existingVal) == "number") {
return existingVal;
}
let val = Math.floor(Math.random() * 100);
Preferences.set(PREF_COHORT_SAMPLE, val);
return val;
}
function setCohort(cohortName) {
Preferences.set(PREF_COHORT_NAME, cohortName);
}
function optedIn() {
return Preferences.get(PREF_E10S_OPTED_IN, false) ||
Preferences.get(PREF_E10S_FORCE_ENABLED, false);
}
function optedOut() {
// Users can also opt-out by toggling back the pref to false.
// If they reset the pref instead they might be re-enabled if
// they are still part of the threshold.
return Preferences.get(PREF_E10S_FORCE_DISABLED, false) ||
(Preferences.isSet(PREF_TOGGLE_E10S) &&
Preferences.get(PREF_TOGGLE_E10S) == false);
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>e10srollout@mozilla.org</em:id>
<em:version>1.0</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<!-- Target Application this theme can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>@FIREFOX_VERSION@</em:minVersion>
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Multi-process staged rollout</em:name>
<em:description>Staged rollout of Firefox multi-process feature.</em:description>
</Description>
</RDF>

View File

@ -0,0 +1,13 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
FINAL_TARGET_FILES.features['e10srollout@mozilla.org'] += [
'bootstrap.js'
]
FINAL_TARGET_PP_FILES.features['e10srollout@mozilla.org'] += [
'install.rdf.in'
]

View File

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += [
'e10srollout',
'loop',
'pdfjs',
'pocket',

View File

@ -6,8 +6,8 @@
struct MOZ_HEAP_CLASS Heap {
int i;
Heap() {}
MOZ_IMPLICIT Heap(int i) {}
Heap(int i, int j) {}
MOZ_IMPLICIT Heap(int a) {}
Heap(int a, int b) {}
void *operator new(size_t x) throw() { return 0; }
void *operator new(size_t blah, char *buffer) { return buffer; }
};

View File

@ -6,8 +6,8 @@
struct MOZ_NON_TEMPORARY_CLASS NonTemporary {
int i;
NonTemporary() {}
MOZ_IMPLICIT NonTemporary(int i) {}
NonTemporary(int i, int j) {}
MOZ_IMPLICIT NonTemporary(int a) {}
NonTemporary(int a, int b) {}
void *operator new(size_t x) throw() { return 0; }
void *operator new(size_t blah, char *buffer) { return buffer; }
};

View File

@ -1,6 +1,8 @@
#!/usr/bin/python
import subprocess
import json
import re
import subprocess
import sys
def count_ctors(filename):
@ -47,6 +49,15 @@ def count_ctors(filename):
if __name__ == '__main__':
for f in sys.argv[1:]:
output = {"framework": {"name": "build_metrics"}, "suites": [{"name": "compiler_metrics", "subtests": [{"name": "num_constructors", "value": count_ctors(f)}] } ]}
print "PERFHERDER_DATA: %s" % output
perfherder_data = {
"framework": {"name": "build_metrics"},
"suites": [{
"name": "compiler_metrics",
"subtests": [{
"name": "num_constructors",
"value": count_ctors(f)
}]}
]
}
print "PERFHERDER_DATA: %s" % json.dumps(perfherder_data)

View File

@ -38,6 +38,16 @@
comma := ,
ifdef MACH
ifndef NO_BUILDSTATUS_MESSAGES
define BUILDSTATUS
@echo 'BUILDSTATUS $1'
endef
endif
endif
CWD := $(CURDIR)
ifneq (1,$(words $(CWD)))
$(error The mozilla directory cannot be located in a path with spaces.)
@ -225,12 +235,23 @@ everything: clean build
# is usable in multi-pass builds, where you might not have a runnable
# application until all the build passes and postflight scripts have run.
profiledbuild::
$(call BUILDSTATUS,TIERS pgo_profile_generate pgo_package pgo_profile pgo_clobber pgo_profile_use)
$(call BUILDSTATUS,TIER_START pgo_profile_generate)
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1 CREATE_MOZCONFIG_JSON=
$(call BUILDSTATUS,TIER_FINISH pgo_profile_generate)
$(call BUILDSTATUS,TIER_START pgo_package)
$(MAKE) -C $(OBJDIR) package MOZ_PGO_INSTRUMENTED=1 MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
rm -f $(OBJDIR)/jarlog/en-US.log
$(call BUILDSTATUS,TIER_FINISH pgo_package)
$(call BUILDSTATUS,TIER_START pgo_profile)
MOZ_PGO_INSTRUMENTED=1 JARLOG_FILE=jarlog/en-US.log EXTRA_TEST_ARGS=10 $(MAKE) -C $(OBJDIR) pgo-profile-run
$(call BUILDSTATUS,TIER_FINISH pgo_profile)
$(call BUILDSTATUS,TIER_START pgo_clobber)
$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild CREATE_MOZCONFIG_JSON=
$(call BUILDSTATUS,TIER_FINISH pgo_clobber)
$(call BUILDSTATUS,TIER_START pgo_profile_use)
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1 CREATE_MOZCONFIG_JSON=
$(call BUILDSTATUS,TIER_FINISH pgo_profile_use)
#####################################################
# Build date unification

View File

@ -60,6 +60,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'uikit':
DEFINES['SQLITE_ENABLE_LOCKING_STYLE'] = 0
# Thunderbird needs the 2-argument version of fts3_tokenizer()
if CONFIG['MOZ_THUNDERBIRD'] or CONFIG['MOZ_SUITE']:
DEFINES['SQLITE_ENABLE_FTS3_TOKENIZER'] = 1
# Turn on SQLite's assertions in debug builds.
if CONFIG['MOZ_DEBUG']:
DEFINES['SQLITE_DEBUG'] = 1

View File

@ -7,9 +7,9 @@ support-files =
[browser_responsive_cmd.js]
[browser_responsivecomputedview.js]
skip-if = e10s && debug && os == 'win' # Bug 1252201 - Docshell leak on win 7 debug e10s
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
[browser_responsiveruleview.js]
skip-if = e10s && debug && os == 'win' # Bug 1252201 - Docshell leak on win 7 debug e10s
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
[browser_responsiveui.js]
[browser_responsiveui_touch.js]
[browser_responsiveuiaddcustompreset.js]

View File

@ -68,7 +68,7 @@ support-files =
[browser_styleeditor_loading.js]
[browser_styleeditor_media_sidebar.js]
[browser_styleeditor_media_sidebar_links.js]
skip-if = e10s && debug && os == 'win' # Bug 1252201 - Docshell leak on win 7 debug e10s
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
[browser_styleeditor_media_sidebar_sourcemaps.js]
[browser_styleeditor_missing_stylesheet.js]
[browser_styleeditor_navigate.js]

View File

@ -350,7 +350,6 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
[browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js]
[browser_console_history_persist.js]
[browser_webconsole_output_01.js]
skip-if = e10s # Bug 1042253 - webconsole e10s tests
[browser_webconsole_output_02.js]
[browser_webconsole_output_03.js]
[browser_webconsole_output_04.js]

View File

@ -17,11 +17,6 @@ const TEST_URI = "data:text/html;charset=utf8,test for console output - 01";
var {DebuggerServer} = require("devtools/server/main");
var LONG_STRING_LENGTH = DebuggerServer.LONG_STRING_LENGTH;
var LONG_STRING_INITIAL_LENGTH = DebuggerServer.LONG_STRING_INITIAL_LENGTH;
DebuggerServer.LONG_STRING_LENGTH = 100;
DebuggerServer.LONG_STRING_INITIAL_LENGTH = 50;
var longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 4)).join("a");
var initialString = longString.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH);
@ -114,11 +109,6 @@ longString = initialString = null;
function test() {
requestLongerTimeout(2);
registerCleanupFunction(() => {
DebuggerServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH;
DebuggerServer.LONG_STRING_INITIAL_LENGTH = LONG_STRING_INITIAL_LENGTH;
});
Task.spawn(function*() {
let {tab} = yield loadTab(TEST_URI);
let hud = yield openConsole(tab);

View File

@ -9,17 +9,6 @@
const TEST_URI = "data:text/html;charset=utf8,test for console and promises";
var {DebuggerServer} = require("devtools/server/main");
var LONG_STRING_LENGTH = DebuggerServer.LONG_STRING_LENGTH;
var LONG_STRING_INITIAL_LENGTH = DebuggerServer.LONG_STRING_INITIAL_LENGTH;
DebuggerServer.LONG_STRING_LENGTH = 100;
DebuggerServer.LONG_STRING_INITIAL_LENGTH = 50;
var longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 4)).join("a");
var initialString = longString.substring(0,
DebuggerServer.LONG_STRING_INITIAL_LENGTH);
var inputTests = [
// 0
{
@ -31,16 +20,9 @@ var inputTests = [
},
];
longString = initialString = null;
function test() {
requestLongerTimeout(2);
registerCleanupFunction(() => {
DebuggerServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH;
DebuggerServer.LONG_STRING_INITIAL_LENGTH = LONG_STRING_INITIAL_LENGTH;
});
Task.spawn(function*() {
let {tab} = yield loadTab(TEST_URI);
let hud = yield openConsole(tab);
@ -49,6 +31,5 @@ function test() {
}
function finishUp() {
longString = initialString = inputTests = null;
finishTest();
}

View File

@ -1477,7 +1477,7 @@ function checkOutputForInputs(hud, inputTests) {
}
function* checkConsoleLog(entry) {
info("Logging: " + entry.input);
info("Logging");
hud.jsterm.clearOutput();
hud.jsterm.execute("console.log(" + entry.input + ")");
@ -1501,13 +1501,13 @@ function checkOutputForInputs(hud, inputTests) {
}
if (typeof entry.inspectorIcon == "boolean") {
info("Checking Inspector Link: " + entry.input);
info("Checking Inspector Link");
yield checkLinkToInspector(entry.inspectorIcon, msg);
}
}
function checkPrintOutput(entry) {
info("Printing: " + entry.input);
info("Printing");
hud.jsterm.clearOutput();
hud.jsterm.execute("print(" + entry.input + ")");
@ -1524,7 +1524,7 @@ function checkOutputForInputs(hud, inputTests) {
}
function* checkJSEval(entry) {
info("Evaluating: " + entry.input);
info("Evaluating");
hud.jsterm.clearOutput();
hud.jsterm.execute(entry.input);
@ -1550,7 +1550,7 @@ function checkOutputForInputs(hud, inputTests) {
}
function* checkObjectClick(entry, msg) {
info("Clicking: " + entry.input);
info("Clicking");
let body;
if (entry.getClickableNode) {
body = entry.getClickableNode(msg);
@ -1595,7 +1595,7 @@ function checkOutputForInputs(hud, inputTests) {
}
function onVariablesViewOpen(entry, {resolve, reject}, event, view, options) {
info("Variables view opened: " + entry.input);
info("Variables view opened");
let label = entry.variablesViewLabel || entry.output;
if (typeof label == "string" && options.label != label) {
return;

View File

@ -222,45 +222,6 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
info->mFixupChangedProtocol = true;
return NS_OK;
}
#if defined(XP_WIN)
// Not a file URL, so translate '\' to '/' for convenience in the common
// protocols. E.g. catch
//
// http:\\broken.com\address
// http:\\broken.com/blah
// broken.com\blah
//
// Code will also do partial fix up the following urls
//
// http:\\broken.com\address/somewhere\image.jpg (stops at first forward slash)
// http:\\broken.com\blah?arg=somearg\foo.jpg (stops at question mark)
// http:\\broken.com#odd\ref (stops at hash)
//
if (scheme.IsEmpty() ||
scheme.LowerCaseEqualsLiteral("http") ||
scheme.LowerCaseEqualsLiteral("https") ||
scheme.LowerCaseEqualsLiteral("ftp")) {
// Walk the string replacing backslashes with forward slashes until
// the end is reached, or a question mark, or a hash, or a forward
// slash. The forward slash test is to stop before trampling over
// URIs which legitimately contain a mix of both forward and
// backward slashes.
nsAutoCString::iterator start;
nsAutoCString::iterator end;
uriString.BeginWriting(start);
uriString.EndWriting(end);
while (start != end) {
if (*start == '?' || *start == '#' || *start == '/') {
break;
}
if (*start == '\\') {
*start = '/';
}
++start;
}
}
#endif
}
if (!sInitializedPrefCaches) {

View File

@ -805,10 +805,8 @@ nsDocShell::nsDocShell()
, mHasLoadedNonBlankURI(false)
, mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
, mBlankTiming(false)
, mFrameType(eFrameTypeRegular)
, mFrameType(FRAME_TYPE_REGULAR)
, mIsInIsolatedMozBrowser(false)
, mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
, mUserContextId(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)
, mParentCharsetSource(0)
, mJSRunToCompletionDepth(0)
{
@ -4009,7 +4007,6 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild)
}
aChild->SetTreeOwner(mTreeOwner);
childDocShell->SetUserContextId(mUserContextId);
childDocShell->SetIsInIsolatedMozBrowserElement(mIsInIsolatedMozBrowser);
nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
@ -9551,7 +9548,7 @@ nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
nsIPrincipal** aResult)
{
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aReferrer);
attrs.InheritFromDocShellToDoc(mOriginAttributes, aReferrer);
nsCOMPtr<nsIPrincipal> prin =
BasePrincipal::CreateCodebasePrincipal(aReferrer, attrs);
prin.forget(aResult);
@ -13850,80 +13847,38 @@ nsDocShell::GetCanExecuteScripts(bool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsApp(uint32_t aOwnAppId)
/* [infallible] */ NS_IMETHODIMP
nsDocShell::SetFrameType(uint32_t aFrameType)
{
mOwnOrContainingAppId = aOwnAppId;
if (aOwnAppId != nsIScriptSecurityManager::NO_APP_ID &&
aOwnAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
mFrameType = eFrameTypeApp;
} else {
mFrameType = eFrameTypeRegular;
}
mFrameType = aFrameType;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsBrowserInsideApp(uint32_t aContainingAppId)
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetFrameType(uint32_t* aFrameType)
{
mOwnOrContainingAppId = aContainingAppId;
mFrameType = eFrameTypeBrowser;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsSignedPackage(const nsAString& aSignedPkg)
{
mSignedPkg = aSignedPkg;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetUserContextId(uint32_t aUserContextId)
{
mUserContextId = aUserContextId;
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
while (iter.HasMore()) {
nsCOMPtr<nsIDocShell> docshell = do_QueryObject(iter.GetNext());
if (!docshell || docshell->ItemType() != ItemType()) {
continue;
}
docshell->SetUserContextId(aUserContextId);
}
*aFrameType = mFrameType;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
*aIsApp = (mFrameType == eFrameTypeApp);
*aIsApp = (mFrameType == FRAME_TYPE_APP);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsMozBrowserOrApp(bool* aIsMozBrowserOrApp)
{
switch (mFrameType) {
case eFrameTypeRegular:
*aIsMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsMozBrowserOrApp = true;
break;
}
*aIsMozBrowserOrApp = (mFrameType != FRAME_TYPE_REGULAR);
return NS_OK;
}
nsDocShell::FrameType
uint32_t
nsDocShell::GetInheritedFrameType()
{
if (mFrameType != eFrameTypeRegular) {
if (mFrameType != FRAME_TYPE_REGULAR) {
return mFrameType;
}
@ -13932,7 +13887,7 @@ nsDocShell::GetInheritedFrameType()
nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
if (!parent) {
return eFrameTypeRegular;
return FRAME_TYPE_REGULAR;
}
return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
@ -13941,7 +13896,7 @@ nsDocShell::GetInheritedFrameType()
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
{
bool result = mFrameType == eFrameTypeBrowser && mIsInIsolatedMozBrowser;
bool result = mFrameType == FRAME_TYPE_BROWSER && mIsInIsolatedMozBrowser;
*aIsIsolatedMozBrowserElement = result;
return NS_OK;
}
@ -13950,9 +13905,9 @@ nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
nsDocShell::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
{
MOZ_ASSERT(!mIsInIsolatedMozBrowser ||
(GetInheritedFrameType() == eFrameTypeBrowser),
(GetInheritedFrameType() == FRAME_TYPE_BROWSER),
"Isolated mozbrowser should only be true inside browser frames");
bool result = (GetInheritedFrameType() == eFrameTypeBrowser) &&
bool result = (GetInheritedFrameType() == FRAME_TYPE_BROWSER) &&
mIsInIsolatedMozBrowser;
*aIsInIsolatedMozBrowserElement = result;
return NS_OK;
@ -13968,24 +13923,15 @@ nsDocShell::SetIsInIsolatedMozBrowserElement(bool aIsInIsolatedMozBrowserElement
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInMozBrowserOrApp(bool* aIsInMozBrowserOrApp)
{
switch (GetInheritedFrameType()) {
case eFrameTypeRegular:
*aIsInMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsInMozBrowserOrApp = true;
break;
}
*aIsInMozBrowserOrApp = (GetInheritedFrameType() != FRAME_TYPE_REGULAR);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetAppId(uint32_t* aAppId)
{
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOwnOrContainingAppId;
if (mOriginAttributes.mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOriginAttributes.mAppId;
return NS_OK;
}
@ -14000,42 +13946,45 @@ nsDocShell::GetAppId(uint32_t* aAppId)
return parent->GetAppId(aAppId);
}
DocShellOriginAttributes
nsDocShell::GetOriginAttributes()
{
DocShellOriginAttributes attrs;
RefPtr<nsDocShell> parent = GetParentDocshell();
if (parent) {
nsCOMPtr<nsIPrincipal> parentPrin = parent->GetDocument()->NodePrincipal();
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
attrs.InheritFromDocToChildDocShell(poa);
} else {
// This is the topmost docshell, so we get the mSignedPkg attribute if it is
// set before.
attrs.mSignedPkg = mSignedPkg;
}
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
attrs.mAppId = mOwnOrContainingAppId;
}
attrs.mUserContextId = mUserContextId;
attrs.mInIsolatedMozBrowser = mIsInIsolatedMozBrowser;
return attrs;
}
// Implements nsILoadContext.originAttributes
NS_IMETHODIMP
nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
{
JSContext* cx = nsContentUtils::GetCurrentJSContext();
MOZ_ASSERT(cx);
bool ok = ToJSValue(cx, GetOriginAttributes(), aVal);
return GetOriginAttributes(cx, aVal);
}
// Implements nsIDocShell.GetOriginAttributes()
NS_IMETHODIMP
nsDocShell::GetOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal)
{
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}
void
nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
{
mOriginAttributes = aAttrs;
}
NS_IMETHODIMP
nsDocShell::SetOriginAttributes(JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx)
{
DocShellOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
SetOriginAttributes(attrs);
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAppManifestURL(nsAString& aAppManifestURL)
{
@ -14226,7 +14175,7 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
if (aIsNonSubresourceRequest) {
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aURI);
attrs.InheritFromDocShellToDoc(mOriginAttributes, aURI);
*aShouldIntercept = swm->IsAvailable(attrs, aURI);
return NS_OK;
}
@ -14280,7 +14229,7 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
NS_ENSURE_SUCCESS(rv, rv);
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), uri);
attrs.InheritFromDocShellToDoc(mOriginAttributes, uri);
ErrorResult error;
swm->DispatchFetchEvent(attrs, doc, mInterceptedDocumentId, aChannel,

View File

@ -270,7 +270,13 @@ public:
}
bool InFrameSwap();
mozilla::DocShellOriginAttributes GetOriginAttributes();
const mozilla::DocShellOriginAttributes&
GetOriginAttributes()
{
return mOriginAttributes;
}
void SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
void GetInterceptedDocumentId(nsAString& aId)
{
@ -764,21 +770,14 @@ protected:
nsresult CreatePrincipalFromReferrer(nsIURI* aReferrer,
nsIPrincipal** aResult);
enum FrameType
{
eFrameTypeRegular,
eFrameTypeBrowser,
eFrameTypeApp
};
static const nsCString FrameTypeToString(FrameType aFrameType)
static const nsCString FrameTypeToString(uint32_t aFrameType)
{
switch (aFrameType) {
case FrameType::eFrameTypeApp:
case FRAME_TYPE_APP:
return NS_LITERAL_CSTRING("app");
case FrameType::eFrameTypeBrowser:
case FRAME_TYPE_BROWSER:
return NS_LITERAL_CSTRING("browser");
case FrameType::eFrameTypeRegular:
case FRAME_TYPE_REGULAR:
return NS_LITERAL_CSTRING("regular");
default:
NS_ERROR("Unknown frame type");
@ -786,7 +785,7 @@ protected:
}
}
FrameType GetInheritedFrameType();
uint32_t GetInheritedFrameType();
bool HasUnloadedParent();
@ -999,32 +998,15 @@ protected:
bool mBlankTiming;
// Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType;
uint32_t mFrameType;
// Whether we are in an isolated mozbrowser frame.
bool mIsInIsolatedMozBrowser;
// We only expect mOwnOrContainingAppId to be something other than
// UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes
// inside an app, we'll retrieve the containing app-id by walking up the
// docshell hierarchy.
//
// (This needs to be the docshell's own /or containing/ app id because the
// containing app frame might be in another process, in which case we won't
// find it by walking up the docshell hierarchy.)
uint32_t mOwnOrContainingAppId;
// userContextId signifying which container we are in
uint32_t mUserContextId;
nsString mPaymentRequestId;
nsString GetInheritedPaymentRequestId();
// The packageId for a signed packaged iff this docShell is created
// for a signed package.
nsString mSignedPkg;
nsString mInterceptedDocumentId;
private:
@ -1037,6 +1019,7 @@ private:
nsTObserverArray<nsWeakPtr> mScrollObservers;
nsCString mOriginalUriString;
nsWeakPtr mOpener;
mozilla::DocShellOriginAttributes mOriginAttributes;
// A depth count of how many times NotifyRunToCompletionStart
// has been called without a matching NotifyRunToCompletionStop.

View File

@ -768,6 +768,15 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean isApp;
/**
* The type of iframe that this docshell lives.
*/
const unsigned long FRAME_TYPE_REGULAR = 0;
const unsigned long FRAME_TYPE_BROWSER = 1;
const unsigned long FRAME_TYPE_APP = 2;
[infallible] attribute unsigned long frameType;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozapp>. <xul:browser> returns false here.
@ -813,48 +822,14 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean isInMozBrowserOrApp;
/**
* Indicate that this docshell corresponds to an app with the given app id.
*
* You may pass NO_APP_ID or UNKNOWN_APP_ID for containingAppId. If you
* pass NO_APP_ID, then this docshell will return NO_APP_ID for appId. If
* you pass UNKNOWN_APP_ID, then this docshell will search its hiearchy for
* an app frame and use that frame's appId.
*
* You can call this method more than once, but there's no guarantee that
* other components will update their view of the world if you change a
* docshell's app id, so tread lightly.
*
* If you call this method after calling setIsBrowserInsideApp, this
* docshell will forget the fact that it was a browser.
*/
void setIsApp(in unsigned long ownAppId);
/**
* Indicate that this docshell corresponds to a browser inside an app with
* the given ID. As with setIsApp, you may pass NO_APP_ID or
* UNKNOWN_APP_ID.
*
* As with setIsApp, you may call this more than once, but it's kind of a
* hack, so be careful.
*/
void setIsBrowserInsideApp(in unsigned long containingAppId);
/**
* Indicate that this docshell corresponds to a signed package with
* the given packageId.
*/
void setIsSignedPackage(in AString packageId);
/**
* Returns the id of the app associated with this docshell. If this docshell
* is an <iframe mozbrowser> inside an <iframe mozapp>, we return the app's
* appId.
*
* We compute this value by walking up the docshell hierarchy until we find a
* docshell on which setIsApp(x) or setIsBrowserInsideApp(x) was called
* (ignoring those docshells where x == UNKNOWN_APP_ID). We return the app
* id x.
* docshell on which origin attributes was set. (ignoring those docshells
* where x == UNKNOWN_APP_ID). We return the app id x.
*
* If we don't find a docshell with an associated app id in our hierarchy, we
* return NO_APP_ID. We never return UNKNOWN_APP_ID.
@ -1105,11 +1080,15 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Sets/gets the current scroll restoration mode.
* @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
*/
*/
attribute boolean currentScrollRestorationIsManual;
/*
* Sets the user context ID for this docshell.
/**
* Setter and getter for the origin attributes living on this docshell.
*/
void setUserContextId(in unsigned long aUserContextId);
[implicit_jscontext]
jsval getOriginAttributes();
[implicit_jscontext]
void setOriginAttributes(in jsval aAttrs);
};

View File

@ -471,6 +471,13 @@ var testcases = [ {
fixedURI: "http://mozilla/foo",
alternateURI: "http://www.mozilla.com/foo",
protocolChange: true,
}, {
input: "mozilla\\",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}];
if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
@ -485,12 +492,6 @@ if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
alternateURI: "http://www.mozilla.com/",
protocolChange: true,
});
testcases.push({
input: "mozilla\\",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
protocolChange: true,
});
} else {
testcases.push({
input: "/some/file.txt",
@ -502,15 +503,6 @@ if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
fixedURI: "file:////mozilla",
protocolChange: true,
});
// \ is an invalid character in the hostname until bug 652186 is implemented
testcases.push({
input: "mozilla\\",
// fixedURI: "http://mozilla\\/",
// alternateURI: "http://www.mozilla/",
keywordLookup: true,
protocolChange: true,
// affectedByDNSForSingleHosts: true,
});
}
function sanitize(input) {

View File

@ -8130,7 +8130,8 @@ nsContentUtils::IsPreloadType(nsContentPolicyType aType)
nsresult
nsContentUtils::SetFetchReferrerURIWithPolicy(nsIPrincipal* aPrincipal,
nsIDocument* aDoc,
nsIHttpChannel* aChannel)
nsIHttpChannel* aChannel,
mozilla::net::ReferrerPolicy aReferrerPolicy)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aChannel);
@ -8144,7 +8145,7 @@ nsContentUtils::SetFetchReferrerURIWithPolicy(nsIPrincipal* aPrincipal,
aPrincipal->GetURI(getter_AddRefs(principalURI));
if (!aDoc) {
return aChannel->SetReferrerWithPolicy(principalURI, net::RP_Default);
return aChannel->SetReferrerWithPolicy(principalURI, aReferrerPolicy);
}
// If it weren't for history.push/replaceState, we could just use the
@ -8173,7 +8174,10 @@ nsContentUtils::SetFetchReferrerURIWithPolicy(nsIPrincipal* aPrincipal,
referrerURI = principalURI;
}
net::ReferrerPolicy referrerPolicy = aDoc->GetReferrerPolicy();
net::ReferrerPolicy referrerPolicy = aReferrerPolicy;
if (referrerPolicy == net::RP_Default) {
referrerPolicy = aDoc->GetReferrerPolicy();
}
return aChannel->SetReferrerWithPolicy(referrerURI, referrerPolicy);
}

View File

@ -2523,7 +2523,8 @@ public:
*/
static nsresult SetFetchReferrerURIWithPolicy(nsIPrincipal* aPrincipal,
nsIDocument* aDoc,
nsIHttpChannel* aChannel);
nsIHttpChannel* aChannel,
mozilla::net::ReferrerPolicy aReferrerPolicy);
static bool PushEnabled(JSContext* aCx, JSObject* aObj);

View File

@ -1848,26 +1848,6 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetName(frameName);
}
//Grab the userContextId from owner if XUL
nsAutoString userContextIdStr;
if (namespaceID == kNameSpaceID_XUL) {
if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usercontextid)) {
mOwnerContent->GetAttr(kNameSpaceID_None,
nsGkAtoms::usercontextid,
userContextIdStr);
}
}
if (!userContextIdStr.IsEmpty()) {
nsresult rv;
uint32_t userContextId =
static_cast<uint32_t>(userContextIdStr.ToInteger(&rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDocShell->SetUserContextId(userContextId);
NS_ENSURE_SUCCESS(rv, rv);
}
// Inform our docShell that it has a new child.
// Note: This logic duplicates a lot of logic in
// nsSubDocumentFrame::AttributeChanged. We should fix that.
@ -1938,6 +1918,14 @@ nsFrameLoader::MaybeCreateDocShell()
webNav->SetSessionHistory(sessionHistory);
}
DocShellOriginAttributes attrs;
if (!mOwnerContent->IsXULElement(nsGkAtoms::browser)) {
nsCOMPtr<nsIPrincipal> parentPrin = doc->NodePrincipal();
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
attrs.InheritFromDocToChildDocShell(poa);
}
if (OwnerIsAppFrame()) {
// You can't be both an app and a browser frame.
MOZ_ASSERT(!OwnerIsMozBrowserFrame());
@ -1949,7 +1937,8 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ENSURE_SUCCESS(ownApp->GetLocalId(&ownAppId), NS_ERROR_FAILURE);
}
mDocShell->SetIsApp(ownAppId);
attrs.mAppId = ownAppId;
mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_APP);
}
if (OwnerIsMozBrowserFrame()) {
@ -1962,10 +1951,25 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
NS_ERROR_FAILURE);
}
mDocShell->SetIsBrowserInsideApp(containingAppId);
attrs.mAppId = containingAppId;
attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
mDocShell->SetIsInIsolatedMozBrowserElement(OwnerIsIsolatedMozBrowserFrame());
}
// Grab the userContextId from owner if XUL
nsAutoString userContextIdStr;
if ((namespaceID == kNameSpaceID_XUL) &&
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usercontextid, userContextIdStr) &&
!userContextIdStr.IsEmpty()) {
nsresult rv;
attrs.mUserContextId = userContextIdStr.ToInteger(&rv);
NS_ENSURE_SUCCESS(rv, rv);
}
nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
if (OwnerIsMozBrowserOrAppFrame()) {
// For inproc frames, set the docshell properties.
nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/File.h"
#include "mozilla/dom/MediaSource.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/Preferences.h"
#include "nsClassHashtable.h"
#include "nsError.h"
@ -743,3 +744,53 @@ NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
source.forget(aSource);
return NS_OK;
}
#define NS_BLOBPROTOCOLHANDLER_CID \
{ 0xb43964aa, 0xa078, 0x44b2, \
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
{ 0x27d1fa24, 0x2b73, 0x4db3, \
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
#define NS_MEDIASOURCEPROTOCOLHANDLER_CID \
{ 0x12ef31fc, 0xa8fb, 0x4661, \
{ 0x9a, 0x63, 0xfb, 0x61, 0x04,0x5d, 0xb8, 0x61 } }
#define NS_FONTTABLEPROTOCOLHANDLER_CID \
{ 0x3fc8f04e, 0xd719, 0x43ca, \
{ 0x9a, 0xd0, 0x18, 0xee, 0x32, 0x02, 0x11, 0xf2 } }
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaSourceProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontTableProtocolHandler)
NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID);
NS_DEFINE_NAMED_CID(NS_MEDIASOURCEPROTOCOLHANDLER_CID);
NS_DEFINE_NAMED_CID(NS_FONTTABLEPROTOCOLHANDLER_CID);
static const mozilla::Module::CIDEntry kHostObjectProtocolHandlerCIDs[] = {
{ &kNS_BLOBPROTOCOLHANDLER_CID, false, nullptr, nsBlobProtocolHandlerConstructor },
{ &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, nullptr, nsMediaStreamProtocolHandlerConstructor },
{ &kNS_MEDIASOURCEPROTOCOLHANDLER_CID, false, nullptr, nsMediaSourceProtocolHandlerConstructor },
{ &kNS_FONTTABLEPROTOCOLHANDLER_CID, false, nullptr, nsFontTableProtocolHandlerConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kHostObjectProtocolHandlerContracts[] = {
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASOURCEURI_SCHEME, &kNS_MEDIASOURCEPROTOCOLHANDLER_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID },
{ nullptr }
};
static const mozilla::Module kHostObjectProtocolHandlerModule = {
mozilla::Module::kVersion,
kHostObjectProtocolHandlerCIDs,
kHostObjectProtocolHandlerContracts
};
NSMODULE_DEFN(HostObjectProtocolHandler) = &kHostObjectProtocolHandlerModule;

View File

@ -136,20 +136,4 @@ NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream);
extern nsresult
NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource);
#define NS_BLOBPROTOCOLHANDLER_CID \
{ 0xb43964aa, 0xa078, 0x44b2, \
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
{ 0x27d1fa24, 0x2b73, 0x4db3, \
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
#define NS_MEDIASOURCEPROTOCOLHANDLER_CID \
{ 0x12ef31fc, 0xa8fb, 0x4661, \
{ 0x9a, 0x63, 0xfb, 0x61, 0x04,0x5d, 0xb8, 0x61 } }
#define NS_FONTTABLEPROTOCOLHANDLER_CID \
{ 0x3fc8f04e, 0xd719, 0x43ca, \
{ 0x9a, 0xd0, 0x18, 0xee, 0x32, 0x02, 0x11, 0xf2 } }
#endif /* nsHostObjectProtocolHandler_h */

View File

@ -2564,7 +2564,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
nsCOMPtr<nsIDocument> doc = owner ? owner->GetExtantDoc() : nullptr;
nsContentUtils::SetFetchReferrerURIWithPolicy(mPrincipal, doc,
httpChannel);
httpChannel, mozilla::net::RP_Default);
}
// Some extensions override the http protocol handler and provide their own

View File

@ -19,25 +19,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=466409
/** Test for Bug 466409 **/
function setUniversalDetector(detector)
{
var olddetector = SpecialPowers.getCharPref("intl.charset.detector");
SpecialPowers.setCharPref("intl.charset.detector", detector);
return olddetector;
}
SimpleTest.waitForExplicitFinish();
var testframe = document.getElementById('testframe');
testframe.onload = function ()
{
setUniversalDetector(olddetector);
ok(true, "page loaded successfully");
SimpleTest.finish();
};
var olddetector = setUniversalDetector("universal_charset_detector");
testframe.src = "bug466409-page.html";
SpecialPowers.pushPrefEnv({"set": [['intl.charset.detector', 'universal_charset_detector']]}, function() {
testframe.onload = function () {
ok(true, "page loaded successfully");
SimpleTest.finish();
};
testframe.src = "bug466409-page.html";
});
</script>
</pre>

View File

@ -22,22 +22,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
SimpleTest.waitForExplicitFinish();
/** Test for NavigatorLanguage **/
var prefValue = null;
var actualLanguageChangesFromHandler = 0;
var actualLanguageChangesFromAVL = 0;
var expectedLanguageChanges = 0;
function setUp() {
try {
prefValue = SpecialPowers.getCharPref('intl.accept_languages');
} catch (e) {
}
}
function tearDown() {
SpecialPowers.setCharPref('intl.accept_languages', prefValue);
}
var testValues = [
{ accept_languages: 'foo', language: 'foo', languages: ['foo'] },
{ accept_languages: '', language: '', languages: [] },
@ -58,7 +46,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
function nextTest() {
currentTestIdx++;
if (currentTestIdx >= tests.length) {
tearDown();
SimpleTest.finish();
return;
}
@ -90,7 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
}
setTimeout(function() {
SpecialPowers.setCharPref('intl.accept_languages', 'testArrayCached');
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testArrayCached']]});
}, 0);
});
@ -103,7 +90,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
"nextTest();");
setTimeout(function() {
SpecialPowers.setCharPref('intl.accept_languages', 'testEventProperties');
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testEventProperties']]}, function() {});
}, 0);
});
@ -133,7 +120,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
for (var i = 0; i < testValues.length; ++i) {
var data = testValues[i];
setTimeout(function(data) {
SpecialPowers.setCharPref('intl.accept_languages', data.accept_languages);
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', data.accept_languages]]});
}, 0, data);
expectedLanguageChanges++;
yield undefined;
@ -156,22 +143,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
genEvents.next();
});
// Check that the orientationchange event isn't sent twice if the preference
// Check that the languagechange event isn't sent twice if the preference
// is set to the same value.
tests.push(function testOnlyFireIfRealChange() {
function* changeLanguage() {
setTimeout(function() {
SpecialPowers.setCharPref('intl.accept_languages', 'fr-CA');
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]});
});
yield undefined;
setTimeout(function() {
// Twice the same change, should fire only one event.
SpecialPowers.setCharPref('intl.accept_languages', 'fr-CA');
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]});
setTimeout(function() {
// A real change to tell the test it should now count how many changes were
// received until now.
SpecialPowers.setCharPref('intl.accept_languages', 'fr-FR');
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-FR']]});
});
});
yield undefined;
@ -210,16 +197,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=889335
SpecialPowers.exactGC(window, function() {
// This should not crash.
SpecialPowers.setCharPref('intl.accept_languages', 'en-GB');
nextTest();
SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'en-GB']]}, nextTest);
});
}
});
// There is one test using document.body.
addLoadEvent(function() {
setUp();
tests[0]();
});

View File

@ -361,5 +361,31 @@
URL.revokeObjectURL('blob:something');
ok(true, "This should not throw.");
</script>
<script>
var base = new URL("http:\\\\test.com\\path/to\\file?query\\backslash#hash\\");
is(base.href, "http://test.com/path/to/file?query\\backslash#hash\\");
var url = new URL("..\\", base);
is(url.href, "http://test.com/path/");
url = new URL("\\test", base);
is(url.href, "http://test.com/test");
url = new URL("\\test\\", base);
is(url.href, "http://test.com/test/");
url = new URL("http://example.org/test", base);
is(url.href, "http://example.org/test");
url = new URL("ftp://tmp/test", base);
is(url.href, "ftp://tmp/test");
url = new URL("ftp:\\\\tmp\\test", base);
is(url.href, "ftp://tmp/test");
url = new URL("scheme://tmp\\test", base);
is(url.href, "scheme://tmp\\test");
</script>
</body>
</html>

View File

@ -980,7 +980,10 @@ DOMInterfaces = {
},
'Request': {
'binaryNames': { 'headers': 'headers_' },
'binaryNames': {
'headers': 'headers_',
'referrerPolicy': 'referrerPolicy_'
},
},
'Response': {

View File

@ -20,7 +20,7 @@ BluetoothHandsfreeNotificationHandler*
#if ANDROID_VERSION < 21
BluetoothAddress BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress(
BluetoothAddress::ANY);
BluetoothAddress::ANY());
#endif
void
@ -760,7 +760,7 @@ public:
if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) {
sConnectedDeviceAddress = aArg2;
} else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) {
sConnectedDeviceAddress = BluetoothAddress::ANY;
sConnectedDeviceAddress = BluetoothAddress::ANY();
}
#endif
WarnAboutTrailingData();

View File

@ -898,7 +898,7 @@ BluetoothGattManager::StartLeScan(const nsTArray<BluetoothUuid>& aServiceUuids,
index = sClients->Length();
sClients->AppendElement(new BluetoothGattClient(appUuid,
BluetoothAddress::ANY));
BluetoothAddress::ANY()));
RefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mStartLeScanRunnable = aRunnable;
@ -1036,7 +1036,7 @@ BluetoothGattManager::StartAdvertising(
index = sClients->Length();
sClients->AppendElement(new BluetoothGattClient(aAppUuid,
BluetoothAddress::ANY));
BluetoothAddress::ANY()));
RefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mStartAdvertisingRunnable = aRunnable;
client->mAdvertisingData = aData;

View File

@ -16,23 +16,36 @@ BEGIN_BLUETOOTH_NAMESPACE
// |BluetoothAddress|
//
const BluetoothAddress BluetoothAddress::ANY(0x00, 0x00, 0x00,
0x00, 0x00, 0x00);
const BluetoothAddress& BluetoothAddress::ANY()
{
static const BluetoothAddress sAddress(0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
return sAddress;
}
const BluetoothAddress BluetoothAddress::ALL(0xff, 0xff, 0xff,
0xff, 0xff, 0xff);
const BluetoothAddress& BluetoothAddress::ALL()
{
static const BluetoothAddress sAddress(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
return sAddress;
}
const BluetoothAddress BluetoothAddress::LOCAL(0x00, 0x00, 0x00,
0xff, 0xff, 0xff);
const BluetoothAddress& BluetoothAddress::LOCAL()
{
static const BluetoothAddress sAddress(0x00, 0x00, 0x00, 0xff, 0xff, 0xff);
return sAddress;
}
//
// |BluetoothUuid|
//
const BluetoothUuid BluetoothUuid::ZERO(0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00);
const BluetoothUuid& BluetoothUuid::ZERO()
{
static const BluetoothUuid sUuid(0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00);
return sUuid;
}
/*
* [Bluetooth Specification Version 4.2, Volume 3, Part B, Section 2.5.1]
@ -43,9 +56,13 @@ const BluetoothUuid BluetoothUuid::ZERO(0x00, 0x00, 0x00, 0x00,
* the Bluetooth Base UUID and has the value 00000000-0000-1000-8000-
* 00805F9B34FB, from the Bluetooth Assigned Numbers document.
*/
const BluetoothUuid BluetoothUuid::BASE(0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80,
0x5f, 0x9b, 0x34, 0xfb);
const BluetoothUuid& BluetoothUuid::BASE()
{
static const BluetoothUuid sUuid(0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80,
0x5f, 0x9b, 0x34, 0xfb);
return sUuid;
}
END_BLUETOOTH_NAMESPACE

View File

@ -408,20 +408,19 @@ struct BluetoothActivityEnergyInfo {
/**
* |BluetoothAddress| stores the 6-byte MAC address of a Bluetooth
* device. The constants ANY, ALL and LOCAL represent addresses with
* special meaning.
* device. The constants returned from ANY(), ALL() and LOCAL()
* represent addresses with special meaning.
*/
struct BluetoothAddress {
static const BluetoothAddress ANY;
static const BluetoothAddress ALL;
static const BluetoothAddress LOCAL;
static const BluetoothAddress& ANY();
static const BluetoothAddress& ALL();
static const BluetoothAddress& LOCAL();
uint8_t mAddr[6];
BluetoothAddress()
{
Clear(); // assign ANY
Clear(); // assign ANY()
}
MOZ_IMPLICIT BluetoothAddress(const BluetoothAddress&) = default;
@ -451,20 +450,20 @@ struct BluetoothAddress {
}
/**
* |Clear| assigns an invalid value (i.e., ANY) to the address.
* |Clear| assigns an invalid value (i.e., ANY()) to the address.
*/
void Clear()
{
operator=(ANY);
operator=(ANY());
}
/**
* |IsCleared| returns true if the address doesn not contain a
* specific value (i.e., it contains ANY).
* |IsCleared| returns true if the address does not contain a
* specific value (i.e., it contains ANY()).
*/
bool IsCleared() const
{
return operator==(ANY);
return operator==(ANY());
}
/*
@ -550,13 +549,13 @@ enum BluetoothServiceClass {
};
struct BluetoothUuid {
static const BluetoothUuid ZERO;
static const BluetoothUuid BASE;
static const BluetoothUuid& ZERO();
static const BluetoothUuid& BASE();
uint8_t mUuid[16]; // store 128-bit UUID value in big-endian order
BluetoothUuid()
: BluetoothUuid(ZERO)
: BluetoothUuid(ZERO())
{ }
MOZ_IMPLICIT BluetoothUuid(const BluetoothUuid&) = default;
@ -610,7 +609,7 @@ struct BluetoothUuid {
*/
void Clear()
{
operator=(ZERO);
operator=(ZERO());
}
/**
@ -619,7 +618,7 @@ struct BluetoothUuid {
*/
bool IsCleared() const
{
return operator==(ZERO);
return operator==(ZERO());
}
bool operator==(const BluetoothUuid& aRhs) const
@ -650,7 +649,7 @@ struct BluetoothUuid {
void SetUuid32(uint32_t aUuid32)
{
operator=(BASE);
operator=(BASE());
BigEndian::writeUint32(&mUuid[0], aUuid32);
}
@ -661,7 +660,7 @@ struct BluetoothUuid {
void SetUuid16(uint16_t aUuid16)
{
operator=(BASE);
operator=(BASE());
BigEndian::writeUint16(&mUuid[2], aUuid16);
}

View File

@ -304,7 +304,7 @@ BytesToUuid(const nsTArray<uint8_t>& aArray,
return NS_ERROR_ILLEGAL_VALUE;
}
aUuid = BluetoothUuid::BASE;
aUuid = BluetoothUuid::BASE();
if (aEndian == ENDIAN_BIG) {
for (size_t i = 0; i < length; ++i) {

View File

@ -10,6 +10,7 @@ include ChannelInfo;
include PBackgroundSharedTypes;
using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
using ReferrerPolicy from "mozilla/dom/cache/IPCUtils.h";
using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
using RequestMode from "mozilla/dom/cache/IPCUtils.h";
using RequestCache from "mozilla/dom/cache/IPCUtils.h";
@ -60,6 +61,7 @@ struct CacheRequest
HeadersEntry[] headers;
HeadersGuardEnum headersGuard;
nsString referrer;
ReferrerPolicy referrerPolicy;
RequestMode mode;
RequestCredentials credentials;
CacheReadStreamOrVoid body;

186
dom/cache/DBSchema.cpp vendored
View File

@ -37,7 +37,7 @@ const int32_t kFirstShippedSchemaVersion = 15;
namespace {
// Update this whenever the DB schema is changed.
const int32_t kLatestSchemaVersion = 19;
const int32_t kLatestSchemaVersion = 20;
// ---------
// The following constants define the SQL schema. These are defined in the
@ -104,9 +104,10 @@ const char* const kTableEntries =
"response_principal_info TEXT NOT NULL, "
"cache_id INTEGER NOT NULL REFERENCES caches(id) ON DELETE CASCADE, "
"request_redirect INTEGER NOT NULL, "
"request_referrer_policy INTEGER NOT NULL"
// New columns must be added at the end of table to migrate and
// validate properly.
"request_redirect INTEGER NOT NULL"
")";
// Create an index to support the QueryCache() matching algorithm. This
@ -189,6 +190,14 @@ static_assert(int(HeadersGuardEnum::None) == 0 &&
int(HeadersGuardEnum::Immutable) == 4 &&
int(HeadersGuardEnum::EndGuard_) == 5,
"HeadersGuardEnum values are as expected");
static_assert(int(ReferrerPolicy::_empty) == 0 &&
int(ReferrerPolicy::No_referrer) == 1 &&
int(ReferrerPolicy::No_referrer_when_downgrade) == 2 &&
int(ReferrerPolicy::Origin_only) == 3 &&
int(ReferrerPolicy::Origin_when_cross_origin) == 4 &&
int(ReferrerPolicy::Unsafe_url) == 5 &&
int(ReferrerPolicy::EndGuard_) == 6,
"ReferrerPolicy values are as expected");
static_assert(int(RequestMode::Same_origin) == 0 &&
int(RequestMode::No_cors) == 1 &&
int(RequestMode::Cors) == 2 &&
@ -1635,6 +1644,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"request_url_query, "
"request_url_query_hash, "
"request_referrer, "
"request_referrer_policy, "
"request_headers_guard, "
"request_mode, "
"request_credentials, "
@ -1658,6 +1668,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
":request_url_query, "
":request_url_query_hash, "
":request_referrer, "
":request_referrer_policy, "
":request_headers_guard, "
":request_mode, "
":request_credentials, "
@ -1710,6 +1721,10 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
aRequest.referrer());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_referrer_policy"),
static_cast<int32_t>(aRequest.referrerPolicy()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_headers_guard"),
static_cast<int32_t>(aRequest.headersGuard()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@ -1988,6 +2003,7 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"request_url_no_query, "
"request_url_query, "
"request_referrer, "
"request_referrer_policy, "
"request_headers_guard, "
"request_mode, "
"request_credentials, "
@ -2019,48 +2035,54 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
rv = state->GetString(3, aSavedRequestOut->mValue.referrer());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
int32_t referrerPolicy;
rv = state->GetInt32(4, &referrerPolicy);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.referrerPolicy() =
static_cast<ReferrerPolicy>(referrerPolicy);
int32_t guard;
rv = state->GetInt32(4, &guard);
rv = state->GetInt32(5, &guard);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.headersGuard() =
static_cast<HeadersGuardEnum>(guard);
int32_t mode;
rv = state->GetInt32(5, &mode);
rv = state->GetInt32(6, &mode);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.mode() = static_cast<RequestMode>(mode);
int32_t credentials;
rv = state->GetInt32(6, &credentials);
rv = state->GetInt32(7, &credentials);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.credentials() =
static_cast<RequestCredentials>(credentials);
int32_t requestContentPolicyType;
rv = state->GetInt32(7, &requestContentPolicyType);
rv = state->GetInt32(8, &requestContentPolicyType);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.contentPolicyType() =
static_cast<nsContentPolicyType>(requestContentPolicyType);
int32_t requestCache;
rv = state->GetInt32(8, &requestCache);
rv = state->GetInt32(9, &requestCache);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.requestCache() =
static_cast<RequestCache>(requestCache);
int32_t requestRedirect;
rv = state->GetInt32(9, &requestRedirect);
rv = state->GetInt32(10, &requestRedirect);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mValue.requestRedirect() =
static_cast<RequestRedirect>(requestRedirect);
bool nullBody = false;
rv = state->GetIsNull(10, &nullBody);
rv = state->GetIsNull(11, &nullBody);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aSavedRequestOut->mHasBodyId = !nullBody;
if (aSavedRequestOut->mHasBodyId) {
rv = ExtractId(state, 10, &aSavedRequestOut->mBodyId);
rv = ExtractId(state, 11, &aSavedRequestOut->mBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
}
@ -2396,7 +2418,7 @@ Validate(mozIStorageConnection* aConn)
// Schema migration code
// -----
typedef nsresult (*MigrationFunc)(mozIStorageConnection*);
typedef nsresult (*MigrationFunc)(mozIStorageConnection*, bool&);
struct Migration
{
MOZ_CONSTEXPR Migration(int32_t aFromVersion, MigrationFunc aFunc)
@ -2409,10 +2431,11 @@ struct Migration
// Declare migration functions here. Each function should upgrade
// the version by a single increment. Don't skip versions.
nsresult MigrateFrom15To16(mozIStorageConnection* aConn);
nsresult MigrateFrom16To17(mozIStorageConnection* aConn);
nsresult MigrateFrom17To18(mozIStorageConnection* aConn);
nsresult MigrateFrom18To19(mozIStorageConnection* aConn);
nsresult MigrateFrom15To16(mozIStorageConnection* aConn, bool& aRewriteSchema);
nsresult MigrateFrom16To17(mozIStorageConnection* aConn, bool& aRewriteSchema);
nsresult MigrateFrom17To18(mozIStorageConnection* aConn, bool& aRewriteSchema);
nsresult MigrateFrom18To19(mozIStorageConnection* aConn, bool& aRewriteSchema);
nsresult MigrateFrom19To20(mozIStorageConnection* aConn, bool& aRewriteSchema);
// Configure migration functions to run for the given starting version.
Migration sMigrationList[] = {
@ -2420,45 +2443,11 @@ Migration sMigrationList[] = {
Migration(16, MigrateFrom16To17),
Migration(17, MigrateFrom17To18),
Migration(18, MigrateFrom18To19),
Migration(19, MigrateFrom19To20),
};
uint32_t sMigrationListLength = sizeof(sMigrationList) / sizeof(Migration);
nsresult
Migrate(mozIStorageConnection* aConn)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
int32_t currentVersion = 0;
nsresult rv = aConn->GetSchemaVersion(&currentVersion);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
while (currentVersion < kLatestSchemaVersion) {
// Wiping old databases is handled in DBAction because it requires
// making a whole new mozIStorageConnection. Make sure we don't
// accidentally get here for one of those old databases.
MOZ_ASSERT(currentVersion >= kFirstShippedSchemaVersion);
for (uint32_t i = 0; i < sMigrationListLength; ++i) {
if (sMigrationList[i].mFromVersion == currentVersion) {
rv = sMigrationList[i].mFunc(aConn);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
break;
}
}
DebugOnly<int32_t> lastVersion = currentVersion;
rv = aConn->GetSchemaVersion(&currentVersion);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
MOZ_ASSERT(currentVersion > lastVersion);
}
MOZ_ASSERT(currentVersion == kLatestSchemaVersion);
return rv;
}
nsresult
RewriteEntriesSchema(mozIStorageConnection* aConn)
{
@ -2488,7 +2477,55 @@ RewriteEntriesSchema(mozIStorageConnection* aConn)
return rv;
}
nsresult MigrateFrom15To16(mozIStorageConnection* aConn)
nsresult
Migrate(mozIStorageConnection* aConn)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
int32_t currentVersion = 0;
nsresult rv = aConn->GetSchemaVersion(&currentVersion);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool rewriteSchema = false;
while (currentVersion < kLatestSchemaVersion) {
// Wiping old databases is handled in DBAction because it requires
// making a whole new mozIStorageConnection. Make sure we don't
// accidentally get here for one of those old databases.
MOZ_ASSERT(currentVersion >= kFirstShippedSchemaVersion);
for (uint32_t i = 0; i < sMigrationListLength; ++i) {
if (sMigrationList[i].mFromVersion == currentVersion) {
bool shouldRewrite = false;
rv = sMigrationList[i].mFunc(aConn, shouldRewrite);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
if (shouldRewrite) {
rewriteSchema = true;
}
break;
}
}
DebugOnly<int32_t> lastVersion = currentVersion;
rv = aConn->GetSchemaVersion(&currentVersion);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
MOZ_ASSERT(currentVersion > lastVersion);
}
MOZ_ASSERT(currentVersion == kLatestSchemaVersion);
if (rewriteSchema) {
// Now overwrite the master SQL for the entries table to remove the column
// default value. This is also necessary for our Validate() method to
// pass on this database.
rv = RewriteEntriesSchema(aConn);
}
return rv;
}
nsresult MigrateFrom15To16(mozIStorageConnection* aConn, bool& aRewriteSchema)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
@ -2507,20 +2544,16 @@ nsresult MigrateFrom15To16(mozIStorageConnection* aConn)
));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
// Now overwrite the master SQL for the entries table to remove the column
// default value. This is also necessary for our Validate() method to
// pass on this database.
rv = RewriteEntriesSchema(aConn);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = aConn->SetSchemaVersion(16);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aRewriteSchema = true;
return rv;
}
nsresult
MigrateFrom16To17(mozIStorageConnection* aConn)
MigrateFrom16To17(mozIStorageConnection* aConn, bool& aRewriteSchema)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
@ -2645,12 +2678,6 @@ MigrateFrom16To17(mozIStorageConnection* aConn)
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
if (NS_WARN_IF(hasMoreData)) { return NS_ERROR_FAILURE; }
// Finally, rewrite the schema for the entries database, otherwise the
// returned SQL string from sqlite will wrap the name of the table in quotes,
// breaking the checks in Validate().
rv = RewriteEntriesSchema(aConn);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = aConn->SetSchemaVersion(17);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@ -2658,7 +2685,7 @@ MigrateFrom16To17(mozIStorageConnection* aConn)
}
nsresult
MigrateFrom17To18(mozIStorageConnection* aConn)
MigrateFrom17To18(mozIStorageConnection* aConn, bool& aRewriteSchema)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
@ -2688,7 +2715,7 @@ MigrateFrom17To18(mozIStorageConnection* aConn)
}
nsresult
MigrateFrom18To19(mozIStorageConnection* aConn)
MigrateFrom18To19(mozIStorageConnection* aConn, bool& aRewriteSchema)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
@ -2719,6 +2746,33 @@ MigrateFrom18To19(mozIStorageConnection* aConn)
return rv;
}
nsresult MigrateFrom19To20(mozIStorageConnection* aConn, bool& aRewriteSchema)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
mozStorageTransaction trans(aConn, true,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
// Add the request_referrer_policy column with a default value of
// "no-referrer-when-downgrade". Note, we only use a default value here
// because its required by ALTER TABLE and we need to apply the default
// "no-referrer-when-downgrade" to existing records in the table. We don't
// actually want to keep the default in the schema for future INSERTs.
nsresult rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE entries "
"ADD COLUMN request_referrer_policy INTEGER NOT NULL DEFAULT 2"
));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = aConn->SetSchemaVersion(20);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
aRewriteSchema = true;
return rv;
}
} // anonymous namespace

View File

@ -24,6 +24,11 @@ namespace IPC {
mozilla::dom::HeadersGuardEnum::None,
mozilla::dom::HeadersGuardEnum::EndGuard_> {};
template<>
struct ParamTraits<mozilla::dom::ReferrerPolicy> :
public ContiguousEnumSerializer<mozilla::dom::ReferrerPolicy,
mozilla::dom::ReferrerPolicy::_empty,
mozilla::dom::ReferrerPolicy::EndGuard_> {};
template<>
struct ParamTraits<mozilla::dom::RequestMode> :
public ContiguousEnumSerializer<mozilla::dom::RequestMode,
mozilla::dom::RequestMode::Same_origin,

View File

@ -170,6 +170,7 @@ TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
}
aIn->GetReferrer(aOut.referrer());
aOut.referrerPolicy() = aIn->ReferrerPolicy_();
RefPtr<InternalHeaders> headers = aIn->Headers();
MOZ_ASSERT(headers);
@ -340,6 +341,7 @@ TypeUtils::ToInternalRequest(const CacheRequest& aIn)
internalRequest->SetURL(url);
internalRequest->SetReferrer(aIn.referrer());
internalRequest->SetReferrerPolicy(aIn.referrerPolicy());
internalRequest->SetMode(aIn.mode());
internalRequest->SetCredentialsMode(aIn.credentials());
internalRequest->SetContentPolicyType(aIn.contentPolicyType());

View File

@ -22,6 +22,7 @@ function run_test() {
ok(request.redirect === 'follow', 'request.redirect should default to "follow"');
ok(request.cache === 'default', 'request.cache should have been updated to "default"' + request.cache);
ok(request.mode === 'navigate', 'request.mode should have been updated to "navigate"');
ok(request.referrerPolicy === 'no-referrer-when-downgrade', 'request.referrerPolicy should have been updated to "no-referrer-when-downgrade"');
});
return Promise.all(requestList.map(function(request) {
return cache.match(request);

View File

@ -389,11 +389,13 @@ HasRasterImage(HTMLImageElement& aImageEl)
return false;
}
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData)
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
bool aIsPremultipliedAlpha /* = true */)
: mParent(aGlobal)
, mData(aData)
, mSurface(nullptr)
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
, mIsPremultipliedAlpha(aIsPremultipliedAlpha)
{
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
}
@ -433,10 +435,10 @@ ImageBitmap::PrepareForDrawTarget(gfx::DrawTarget* aTarget)
if (!mSurface) {
mSurface = mData->GetAsSourceSurface();
}
if (!mSurface) {
return nullptr;
if (!mSurface) {
return nullptr;
}
}
RefPtr<DrawTarget> target = aTarget;
@ -496,6 +498,63 @@ ImageBitmap::PrepareForDrawTarget(gfx::DrawTarget* aTarget)
mPictureRect.MoveTo(0, 0);
}
// Pre-multiply alpha here.
// Apply pre-multiply alpha only if mIsPremultipliedAlpha is false.
if (!mIsPremultipliedAlpha) {
MOZ_ASSERT(mSurface->GetFormat() == SurfaceFormat::R8G8B8A8 ||
mSurface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
mSurface->GetFormat() == SurfaceFormat::A8R8G8B8);
RefPtr<DataSourceSurface> dataSourceSurface = mSurface->GetDataSurface();
MOZ_ASSERT(dataSourceSurface);
DataSourceSurface::ScopedMap map(dataSourceSurface, DataSourceSurface::READ_WRITE);
if (NS_WARN_IF(!map.IsMapped())) {
return nullptr;
}
uint8_t rIndex = 0;
uint8_t gIndex = 0;
uint8_t bIndex = 0;
uint8_t aIndex = 0;
if (mSurface->GetFormat() == SurfaceFormat::R8G8B8A8) {
rIndex = 0;
gIndex = 1;
bIndex = 2;
aIndex = 3;
} else if (mSurface->GetFormat() == SurfaceFormat::B8G8R8A8) {
rIndex = 2;
gIndex = 1;
bIndex = 0;
aIndex = 3;
} else if (mSurface->GetFormat() == SurfaceFormat::A8R8G8B8) {
rIndex = 1;
gIndex = 2;
bIndex = 3;
aIndex = 0;
}
for (int i = 0; i < dataSourceSurface->GetSize().height; ++i) {
uint8_t* bufferPtr = map.GetData() + map.GetStride() * i;
for (int i = 0; i < dataSourceSurface->GetSize().width; ++i) {
uint8_t r = *(bufferPtr+rIndex);
uint8_t g = *(bufferPtr+gIndex);
uint8_t b = *(bufferPtr+bIndex);
uint8_t a = *(bufferPtr+aIndex);
*(bufferPtr+rIndex) = gfxUtils::sPremultiplyTable[a * 256 + r];
*(bufferPtr+gIndex) = gfxUtils::sPremultiplyTable[a * 256 + g];
*(bufferPtr+bIndex) = gfxUtils::sPremultiplyTable[a * 256 + b];
*(bufferPtr+aIndex) = a;
bufferPtr += 4;
}
}
mSurface = dataSourceSurface;
}
// Replace our surface with one optimized for the target we're about to draw
// to, under the assumption it'll likely be drawn again to that target.
// This call should be a no-op for already-optimized surfaces
@ -518,6 +577,7 @@ ImageBitmap::ToCloneData()
{
ImageBitmapCloneData* result = new ImageBitmapCloneData();
result->mPictureRect = mPictureRect;
result->mIsPremultipliedAlpha = mIsPremultipliedAlpha;
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
result->mSurface = surface->GetDataSurface();
MOZ_ASSERT(result->mSurface);
@ -532,7 +592,8 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
RefPtr<layers::Image> data =
CreateImageFromSurface(aData->mSurface);
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
aData->mIsPremultipliedAlpha);
ErrorResult rv;
ret->SetPictureRect(aData->mPictureRect, rv);
return ret.forget();
@ -763,7 +824,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
}
// Create an ImageBimtap.
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
// ImageData's underlying data is not alpha-premultiplied.
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, false);
// The cropping information has been handled in the CreateImageFromRawData()
// function.
@ -1239,9 +1301,12 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
uint32_t picRectY_;
uint32_t picRectWidth_;
uint32_t picRectHeight_;
uint32_t isPremultipliedAlpha_;
uint32_t dummy_;
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_)) {
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
!JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_, &dummy_)) {
return nullptr;
}
@ -1263,7 +1328,7 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
{
RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
RefPtr<ImageBitmap> imageBitmap =
new ImageBitmap(aParent, img);
new ImageBitmap(aParent, img, isPremultipliedAlpha_);
ErrorResult error;
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
@ -1293,13 +1358,15 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
const uint32_t picRectY = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.y);
const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0;
// Indexing the cloned surfaces and send the index to the receiver.
uint32_t index = aClonedSurfaces.Length();
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight))) {
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha, 0))) {
return false;
}

View File

@ -57,6 +57,7 @@ struct ImageBitmapCloneData final
{
RefPtr<gfx::DataSourceSurface> mSurface;
gfx::IntRect mPictureRect;
bool mIsPremultipliedAlpha;
};
/*
@ -141,7 +142,27 @@ public:
protected:
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData);
/*
* The default value of aIsPremultipliedAlpha is TRUE because that the
* data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement,
* CanvasRenderingContext2D are alpha-premultiplied in default.
*
* Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it
* is possible to get un-premultipliedAlpha data out. But, we do not do it in
* the CreateInternal(from HTMLCanvasElement) method.
*
* It is also possible to decode an image which is encoded with alpha channel
* to be non-premultipliedAlpha. This could be applied in
* 1) the CreateInternal(from HTMLImageElement) method (which might trigger
* re-decoding if the original decoded data is alpha-premultiplied) and
* 2) while decoding a blob. But we do not do it in both code path too.
*
* ImageData's underlying data is triggered as non-premultipliedAlpha, so set
* the aIsPremultipliedAlpha to be false in the
* CreateInternal(from ImageData) method.
*/
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
bool aIsPremultipliedAlpha = true);
virtual ~ImageBitmap();
@ -202,6 +223,8 @@ protected:
* to draw this ImageBitmap into a HTMLCanvasElement.
*/
gfx::IntRect mPictureRect;
const bool mIsPremultipliedAlpha;
};
} // namespace dom

View File

@ -0,0 +1,85 @@
var RGBAValues = [[42,142,23,148],
[234,165,177,91],
[74,228,75,195],
[140,108,73,65],
[25,177,3,201],
[127,104,12,199],
[196,93,240,131],
[250,121,231,189],
[175,131,215,190],
[145,122,166,70],
[18,196,210,162],
[225,1,90,188],
[223,216,182,233],
[115,48,168,56],
[50,206,198,199],
[152,28,70,130],
[176,134,133,51],
[148,46,43,144],
[78,171,141,95],
[24,177,102,110],
[0,27,127,91],
[31,221,41,170],
[85,7,218,146],
[65,30,198,238],
[121,56,123,88],
[246,39,140,146],
[174,195,254,149],
[29,153,92,116],
[17,240,5,111],
[38,162,84,143],
[237,159,201,244],
[93,68,14,246],
[143,142,82,221],
[187,215,243,154],
[24,121,220,53],
[80,153,151,219],
[202,241,250,191]];
function createOneTest(rgbaValue) {
return new Promise(function(resolve, reject) {
var tolerance = 5;
var r = rgbaValue[0];
var g = rgbaValue[1];
var b = rgbaValue[2];
var a = rgbaValue[3];
var imageData = new ImageData(new Uint8ClampedArray([r, g, b, a]), 1, 1);
var newImageData;
createImageBitmap(imageData).then(
function(imageBitmap) {
var context = document.createElement("canvas").getContext("2d");
context.drawImage(imageBitmap, 0, 0);
newImageData = context.getImageData(0, 0, 1, 1);
var newR = newImageData.data[0];
var newG = newImageData.data[1];
var newB = newImageData.data[2];
var newA = newImageData.data[3];
var isTheSame = Math.abs(r - newR) <= tolerance &&
Math.abs(g - newG) <= tolerance &&
Math.abs(b - newB) <= tolerance &&
Math.abs(a - newA) <= tolerance;
ok(isTheSame, "newImageData(" + newR + "," + newG + "," + newB + "," + newA +
") should equal to imageData(" + r + "," + g + "," + b + "," + a + ")." +
"Premultiplied Alpha is handled while creating ImageBitmap from ImageData.");
if (isTheSame) {
resolve();
} else {
reject();
}
},
function() {
reject();
}
);
});
}
function testBug1239752() {
var tests = [];
for (var i = 0; i < RGBAValues.length; ++i) {
tests.push(createOneTest(RGBAValues[i]));
}
return Promise.all(tests);
}

View File

@ -4,7 +4,8 @@ function ok(expect, msg) {
onmessage = function(event) {
ok(!!event.data.bitmap1, "Get the 1st ImageBitmap from the main script.");
ok(!!event.data.bitmap2, "Get the 2st ImageBitmap from the main script.");
ok(!!event.data.bitmap2, "Get the 2nd ImageBitmap from the main script.");
ok(!!event.data.bitmap3, "Get the 3rd ImageBitmap from the main script.");
// send the first original ImageBitmap back to the main-thread
postMessage({"type":"bitmap1",
@ -27,4 +28,8 @@ onmessage = function(event) {
ok(false, "Cannot create a new bitmap from the original bitmap in worker.");
}
);
// send the third original ImageBitmap back to the main-thread
postMessage({"type":"bitmap3",
"bitmap":event.data.bitmap3});
}

View File

@ -0,0 +1,157 @@
var gImage1;
var gImage2;
var gImageBitmap1;
var gImageBitmap2;
// Bug 1239752.
var gImageData;
var gImageBitmap3;
function comparePixelColor(testImgageData, groundTruthImageData, x, y, tolerance, info) {
ok(testImgageData.width == groundTruthImageData.width && testImgageData.height == groundTruthImageData.height,
"testImgageData and groundTruthImageData should have the same dimension.");
var index = (groundTruthImageData.width * y + x) * 4;
var r = groundTruthImageData.data[index + 0];
var g = groundTruthImageData.data[index + 1];
var b = groundTruthImageData.data[index + 2];
var a = groundTruthImageData.data[index + 3];
var newR = testImgageData.data[index + 0];
var newG = testImgageData.data[index + 1];
var newB = testImgageData.data[index + 2];
var newA = testImgageData.data[index + 3];
var isTheSame = Math.abs(r - newR) <= tolerance &&
Math.abs(g - newG) <= tolerance &&
Math.abs(b - newB) <= tolerance &&
Math.abs(a - newA) <= tolerance;
ok(isTheSame, "[" + info + "] " +
"newImageData(" + newR + "," + newG + "," + newB + "," + newA +
") should equal to imageData(" + r + "," + g + "," + b + "," + a + ").");
}
function compareImageBitmapWithImageElement(imageBitmap, imageElement) {
var canvas1 = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
canvas1.width = imageElement.naturalWidth;
canvas1.height = imageElement.naturalHeight;
canvas2.width = imageElement.naturalWidth;
canvas2.height = imageElement.naturalHeight;
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
ctx1.drawImage(imageElement, 0, 0);
ctx2.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
document.body.appendChild(canvas2);
var imageData1 = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
var imageData2 = ctx2.getImageData(0, 0, canvas2.width, canvas2.height);
// Create an array of pixels that is going to be tested.
var pixels = [];
var xGap = imageElement.naturalWidth / 4;
var yGap = imageElement.naturalHeight / 4;
for (var y = 0; y < imageElement.naturalHeight; y += yGap) {
for (var x = 0; x < imageElement.naturalWidth; x += xGap) {
pixels.push({"x":x, "y":y});
}
}
// Also, put the button-right pixel into pixels.
pixels.push({"x":imageElement.naturalWidth-1, "y":imageElement.naturalHeight-1});
// Do the test.
for (var pixel of pixels) {
comparePixelColor(imageData2, imageData1, pixel.x, pixel.y, 0);
}
}
function compareImageBitmapWithImageData(imageBitmap, imageData, info) {
var canvas1 = document.createElement('canvas');
canvas1.width = imageBitmap.width;
canvas1.height = imageBitmap.height;
var ctx1 = canvas1.getContext('2d');
ctx1.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
var imageData1 = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
// Create an array of pixels that is going to be tested.
var pixels = [];
var xGap = imageBitmap.width / 4;
var yGap = imageBitmap.height / 4;
for (var y = 0; y < imageBitmap.height; y += yGap) {
for (var x = 0; x < imageBitmap.width; x += xGap) {
pixels.push({"x":x, "y":y});
}
}
// Also, put the button-right pixel into pixels.
pixels.push({"x":imageBitmap.width-1, "y":imageBitmap.height-1});
// Do the test.
for (var pixel of pixels) {
comparePixelColor(imageData1, imageData, pixel.x, pixel.y, 5, info);
}
}
function prepareImageBitmaps() {
gImage1 = document.createElement('img');
gImage2 = document.createElement('img');
gImage1.src = "image_rgrg-256x256.png";
gImage2.src = "image_yellow.png";
var p1 = new Promise(function(resolve, reject) {
gImage1.onload = function() {
var promise = createImageBitmap(gImage1);
promise.then(function(bitmap) {
gImageBitmap1 = bitmap;
resolve(true);
});
}
});
var p2 = new Promise(function(resolve, reject) {
gImage2.onload = function() {
var promise = createImageBitmap(gImage2);
promise.then(function(bitmap) {
gImageBitmap2 = bitmap;
resolve(true);
});
}
});
var p3 = new Promise(function(resolve, reject) {
// Create an ImageData with random colors.
var width = 5;
var height = 10;
var data = [43,143,24,148, 235,165,179,91, 74,228,75,195, 141,109,74,65, 25,177,3,201,
128,105,12,199, 196,93,241,131, 250,121,232,189, 175,131,216,190, 145,123,167,70,
18,196,210,162, 225,1,90,188, 223,216,182,233, 118,50,168,56, 51,206,198,199,
153,29,70,130, 180,135,135,51, 148,46,44,144, 80,171,142,95, 25,178,102,110,
0,28,128,91, 31,222,42,170, 85,8,218,146, 65,30,198,238, 121,57,124,88,
246,40,141,146, 174,195,255,149, 30,153,92,116, 18,241,6,111, 39,162,85,143,
237,159,201,244, 93,68,14,246, 143,143,83,221, 187,215,243,154, 24,125,221,53,
80,153,151,219, 202,241,250,191, 153,129,181,57, 94,18,136,231, 41,252,168,207,
213,103,118,172, 53,213,184,204, 25,29,249,199, 101,55,49,167, 25,23,173,78,
19,234,205,155, 250,175,44,201, 215,92,25,59, 25,29,249,199, 153,129,181,57];
gImageData = new ImageData(new Uint8ClampedArray(data), width, height);
// Create an ImageBitmap from the above ImageData.
createImageBitmap(gImageData).then(
(bitmap) => { gImageBitmap3 = bitmap; resolve(true); },
() => { reject(); }
);
});
return Promise.all([p1, p2, p3]);
}

View File

@ -26,9 +26,11 @@ support-files =
image_yellow.png
image_yellow75.png
imagebitmap_bug1239300.js
imagebitmap_bug1239752.js
imagebitmap_on_worker.js
imagebitmap_structuredclone.js
imagebitmap_structuredclone_iframe.html
imagebitmap_structuredclone_utils.js
offscreencanvas.js
offscreencanvas_mask.svg
offscreencanvas_neuter.js

View File

@ -12,6 +12,7 @@
<canvas id="c2" width="128" height="128"></canvas>
<script src="imagebitmap_bug1239300.js"></script>
<script src="imagebitmap_bug1239752.js"></script>
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
@ -335,6 +336,7 @@ function runTests() {
.then(testExceptions)
.then(testSecurityErrors)
.then(testBug1239300)
.then(testBug1239752)
.then(SimpleTest.finish, function(ev) { failed(ev); SimpleTest.finish(); });
}

View File

@ -4,49 +4,9 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<script src="imagebitmap_structuredclone_utils.js"></script>
<script type="text/javascript">
var gImage1;
var gImage2;
var gImageBitmap1;
var gImageBitmap2;
function isPixel(ctx1, ctx2, x, y) {
var pixel1 = ctx1.getImageData(x, y, 1, 1);
var pixel2 = ctx2.getImageData(x, y, 1, 1);
ok(pixel1.data[0] == pixel2.data[0] &&
pixel1.data[1] == pixel2.data[1] &&
pixel1.data[2] == pixel2.data[2] &&
pixel1.data[3] == pixel2.data[3],
"Color(" + pixel1.data[0] + ", " + pixel1.data[1] + ", " + pixel1.data[2] + ", " + pixel1.data[3] + ") should qual to Color(" + pixel2.data[0] + ", " + pixel2.data[1] + ", " + pixel2.data[2] + ", " + pixel2.data[3] + ")");
}
function compareImageBitmapWithImageElement(imageBitmap, imageElement) {
var canvas1 = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
canvas1.width = imageElement.naturalWidth;
canvas1.height = imageElement.naturalHeight;
canvas2.width = imageElement.naturalWidth;
canvas2.height = imageElement.naturalHeight;
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
ctx1.drawImage(imageElement, 0, 0);
ctx2.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
document.body.appendChild(canvas2);
for (var t = 0; t < 20; ++t) {
// check one random pixel
var randomX = Math.floor(Math.random() * imageElement.naturalWidth);
var randomY = Math.floor(Math.random() * imageElement.naturalHeight);
isPixel(ctx1, ctx2, randomX, randomY);
}
}
var worker = new Worker("imagebitmap_structuredclone.js");
worker.onmessage = function(event) {
@ -58,43 +18,16 @@ worker.onmessage = function(event) {
compareImageBitmapWithImageElement(event.data.bitmap, gImage1);
} else if (event.data.type == "bitmap2") {
compareImageBitmapWithImageElement(event.data.bitmap, gImage2);
} else if (event.data.type == "bitmap3") {
compareImageBitmapWithImageData(event.data.bitmap, gImageData, "Check preserving alpha");
}
}
function prepareTwoImageBitmap() {
gImage1 = document.createElement('img');
gImage2 = document.createElement('img');
gImage1.src = "image_rgrg-256x256.png";
gImage2.src = "image_yellow.png";
var p1 = new Promise(function(resolve, reject) {
gImage1.onload = function() {
var promise = createImageBitmap(gImage1);
promise.then(function(bitmap) {
gImageBitmap1 = bitmap;
resolve(true);
});
}
});
var p2 = new Promise(function(resolve, reject) {
gImage2.onload = function() {
var promise = createImageBitmap(gImage2);
promise.then(function(bitmap) {
gImageBitmap2 = bitmap;
resolve(true);
});
}
});
return Promise.all([p1, p2]);
}
function runTests() {
ok(worker, "Worker created successfully.");
prepareTwoImageBitmap().then(function(){
worker.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2});
prepareImageBitmaps().then(function(){
worker.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2, "bitmap3":gImageBitmap3});
});
}

View File

@ -5,78 +5,9 @@
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<div id="content"></div>
<script src="imagebitmap_structuredclone_utils.js"></script>
<script type="text/javascript">
var gImage1;
var gImage2;
var gImageBitmap1;
var gImageBitmap2;
function isPixel(ctx1, ctx2, x, y) {
var pixel1 = ctx1.getImageData(x, y, 1, 1);
var pixel2 = ctx2.getImageData(x, y, 1, 1);
ok(pixel1.data[0] == pixel2.data[0] &&
pixel1.data[1] == pixel2.data[1] &&
pixel1.data[2] == pixel2.data[2] &&
pixel1.data[3] == pixel2.data[3],
"Color(" + pixel1.data[0] + ", " + pixel1.data[1] + ", " + pixel1.data[2] + ", " + pixel1.data[3] + ") should qual to Color(" + pixel2.data[0] + ", " + pixel2.data[1] + ", " + pixel2.data[2] + ", " + pixel2.data[3] + ")");
}
function compareImageBitmapWithImageElement(imageBitmap, imageElement) {
var canvas1 = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
canvas1.width = imageElement.naturalWidth;
canvas1.height = imageElement.naturalHeight;
canvas2.width = imageElement.naturalWidth;
canvas2.height = imageElement.naturalHeight;
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
ctx1.drawImage(imageElement, 0, 0);
ctx2.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
document.body.appendChild(canvas2);
for (var t = 0; t < 20; ++t) {
// check one random pixel
var randomX = Math.floor(Math.random() * imageElement.naturalWidth);
var randomY = Math.floor(Math.random() * imageElement.naturalHeight);
isPixel(ctx1, ctx2, randomX, randomY);
}
}
function prepareTwoImageBitmap() {
gImage1 = document.createElement('img');
gImage2 = document.createElement('img');
gImage1.src = "image_rgrg-256x256.png";
gImage2.src = "image_yellow.png";
var p1 = new Promise(function(resolve, reject) {
gImage1.onload = function() {
var promise = createImageBitmap(gImage1);
promise.then(function(bitmap) {
gImageBitmap1 = bitmap;
resolve(true);
});
}
});
var p2 = new Promise(function(resolve, reject) {
gImage2.onload = function() {
var promise = createImageBitmap(gImage2);
promise.then(function(bitmap) {
gImageBitmap2 = bitmap;
resolve(true);
});
}
});
return Promise.all([p1, p2]);
}
function runTests() {
window.onmessage = function(event) {
if (event.data.type == "status") {
@ -87,6 +18,8 @@ function runTests() {
compareImageBitmapWithImageElement(event.data.bitmap, gImage1);
} else if (event.data.type == "bitmap2") {
compareImageBitmapWithImageElement(event.data.bitmap, gImage2);
} else if (event.data.type == "bitmap3") {
compareImageBitmapWithImageData(event.data.bitmap, gImageData, "Check preserving alpha");
}
}
@ -99,8 +32,8 @@ function runTests() {
div.appendChild(ifr);
function iframeLoaded() {
prepareTwoImageBitmap().then(function(){
ifr.contentWindow.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2}, "*");
prepareImageBitmaps().then(function(){
ifr.contentWindow.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2, "bitmap3":gImageBitmap3}, "*");
});
}
}

View File

@ -4,87 +4,19 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<script src="imagebitmap_structuredclone_utils.js"></script>
<script type="text/javascript">
var gImage1;
var gImage2;
var gImageBitmap1;
var gImageBitmap2;
function isPixel(ctx1, ctx2, x, y) {
var pixel1 = ctx1.getImageData(x, y, 1, 1);
var pixel2 = ctx2.getImageData(x, y, 1, 1);
ok(pixel1.data[0] == pixel2.data[0] &&
pixel1.data[1] == pixel2.data[1] &&
pixel1.data[2] == pixel2.data[2] &&
pixel1.data[3] == pixel2.data[3],
"Color(" + pixel1.data[0] + ", " + pixel1.data[1] + ", " + pixel1.data[2] + ", " + pixel1.data[3] + ") should qual to Color(" + pixel2.data[0] + ", " + pixel2.data[1] + ", " + pixel2.data[2] + ", " + pixel2.data[3] + ")");
}
function compareImageBitmapWithImageElement(imageBitmap, imageElement) {
var canvas1 = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
canvas1.width = imageElement.naturalWidth;
canvas1.height = imageElement.naturalHeight;
canvas2.width = imageElement.naturalWidth;
canvas2.height = imageElement.naturalHeight;
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
ctx1.drawImage(imageElement, 0, 0);
ctx2.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
document.body.appendChild(canvas2);
for (var t = 0; t < 20; ++t) {
// check one random pixel
var randomX = Math.floor(Math.random() * imageElement.naturalWidth);
var randomY = Math.floor(Math.random() * imageElement.naturalHeight);
isPixel(ctx1, ctx2, randomX, randomY);
}
}
window.onmessage = function(event) {
compareImageBitmapWithImageElement(event.data.bitmap1, gImage1);
compareImageBitmapWithImageElement(event.data.bitmap2, gImage2);
compareImageBitmapWithImageData(event.data.bitmap3, gImageData, "Check preserving alpha");
SimpleTest.finish();
}
function prepareTwoImageBitmap() {
gImage1 = document.createElement('img');
gImage2 = document.createElement('img');
gImage1.src = "image_rgrg-256x256.png";
gImage2.src = "image_yellow.png";
var p1 = new Promise(function(resolve, reject) {
gImage1.onload = function() {
var promise = createImageBitmap(gImage1);
promise.then(function(bitmap) {
gImageBitmap1 = bitmap;
resolve(true);
});
}
});
var p2 = new Promise(function(resolve, reject) {
gImage2.onload = function() {
var promise = createImageBitmap(gImage2);
promise.then(function(bitmap) {
gImageBitmap2 = bitmap;
resolve(true);
});
}
});
return Promise.all([p1, p2]);
}
function runTests() {
prepareTwoImageBitmap().then(function(){
window.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2}, "*");
prepareImageBitmaps().then(function(){
window.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2, "bitmap3":gImageBitmap3}, "*");
});
}

View File

@ -4,49 +4,9 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<script src="imagebitmap_structuredclone_utils.js"></script>
<script type="text/javascript">
var gImage1;
var gImage2;
var gImageBitmap1;
var gImageBitmap2;
function isPixel(ctx1, ctx2, x, y) {
var pixel1 = ctx1.getImageData(x, y, 1, 1);
var pixel2 = ctx2.getImageData(x, y, 1, 1);
ok(pixel1.data[0] == pixel2.data[0] &&
pixel1.data[1] == pixel2.data[1] &&
pixel1.data[2] == pixel2.data[2] &&
pixel1.data[3] == pixel2.data[3],
"Color(" + pixel1.data[0] + ", " + pixel1.data[1] + ", " + pixel1.data[2] + ", " + pixel1.data[3] + ") should qual to Color(" + pixel2.data[0] + ", " + pixel2.data[1] + ", " + pixel2.data[2] + ", " + pixel2.data[3] + ")");
}
function compareImageBitmapWithImageElement(imageBitmap, imageElement) {
var canvas1 = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
canvas1.width = imageElement.naturalWidth;
canvas1.height = imageElement.naturalHeight;
canvas2.width = imageElement.naturalWidth;
canvas2.height = imageElement.naturalHeight;
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
ctx1.drawImage(imageElement, 0, 0);
ctx2.drawImage(imageBitmap, 0, 0);
document.body.appendChild(canvas1);
document.body.appendChild(canvas2);
for (var t = 0; t < 20; ++t) {
// check one random pixel
var randomX = Math.floor(Math.random() * imageElement.naturalWidth);
var randomY = Math.floor(Math.random() * imageElement.naturalHeight);
isPixel(ctx1, ctx2, randomX, randomY);
}
}
var worker = new Worker("imagebitmap_structuredclone.js");
worker.onmessage = function(event) {
@ -58,49 +18,24 @@ worker.onmessage = function(event) {
compareImageBitmapWithImageElement(event.data.bitmap, gImage1);
} else if (event.data.type == "bitmap2") {
compareImageBitmapWithImageElement(event.data.bitmap, gImage2);
} else if (event.data.type == "bitmap3") {
compareImageBitmapWithImageData(event.data.bitmap, gImageData, "Check preserving alpha");
}
}
function prepareTwoImageBitmap() {
gImage1 = document.createElement('img');
gImage2 = document.createElement('img');
gImage1.src = "image_rgrg-256x256.png";
gImage2.src = "image_yellow.png";
var p1 = new Promise(function(resolve, reject) {
gImage1.onload = function() {
var promise = createImageBitmap(gImage1);
promise.then(function(bitmap) {
gImageBitmap1 = bitmap;
resolve(true);
});
}
});
var p2 = new Promise(function(resolve, reject) {
gImage2.onload = function() {
var promise = createImageBitmap(gImage2);
promise.then(function(bitmap) {
gImageBitmap2 = bitmap;
resolve(true);
});
}
});
return Promise.all([p1, p2]);
}
function runTests() {
ok(worker, "Worker created successfully.");
prepareTwoImageBitmap().then(function(){
worker.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2},
[gImageBitmap1, gImageBitmap2]);
prepareImageBitmaps().then(function(){
worker.postMessage({"bitmap1":gImageBitmap1, "bitmap2":gImageBitmap2, "bitmap3":gImageBitmap3},
[gImageBitmap1, gImageBitmap2, gImageBitmap3]);
ok(gImageBitmap1.width == 0 && gImageBitmap1.height == 0,
"After transfer, ImageBitmap become neutered");
ok(gImageBitmap2.width == 0 && gImageBitmap2.height == 0,
"After transfer, ImageBitmap become neutered");
ok(gImageBitmap3.width == 0 && gImageBitmap3.height == 0,
"After transfer, ImageBitmap become neutered");
});
}

View File

@ -54,22 +54,6 @@ function deleteDB() {
backend.sendAsyncMessage("deleteDB");
}
function setSubstringMatching(value) {
info("Setting substring matching to " + value);
if (value) {
SpecialPowers.setIntPref("dom.phonenumber.substringmatching.BR", value);
// this is the Mcc for Brazil, so that we trigger the previous pref
SpecialPowers.setCharPref("ril.lastKnownSimMcc", "724");
} else {
SpecialPowers.clearUserPref("dom.phonenumber.substringmatching.BR");
SpecialPowers.clearUserPref("ril.lastKnownSimMcc");
}
next();
}
var steps = [
function setupChromeScript() {
loadChromeScript();
@ -79,7 +63,6 @@ var steps = [
deleteDB, // let's be sure the DB does not exist yet
createDB.bind(null, 12),
setSubstringMatching.bind(null, 7),
function testAccessMozContacts() {
info("Checking we have the right number of contacts: " + contactsCount);
@ -194,7 +177,6 @@ var steps = [
},
deleteDB,
setSubstringMatching.bind(null, null),
function finish() {
backend.destroy();
@ -203,7 +185,9 @@ var steps = [
}
];
start_tests();
// this is the Mcc for Brazil, so that we trigger the previous pref
SpecialPowers.pushPrefEnv({"set": [["dom.phonenumber.substringmatching.BR", 7],
["ril.lastKnownSimMcc", "724"]]}, start_tests);
</script>
</pre>
</body>

View File

@ -1123,6 +1123,15 @@ ContentEventHandler::OnQuerySelectedText(WidgetQueryContentEvent* aEvent)
return rv;
}
nsINode* const startNode = mFirstSelectedRange->GetStartParent();
nsINode* const endNode = mFirstSelectedRange->GetEndParent();
// Make sure the selection is within the root content range.
if (!nsContentUtils::ContentIsDescendantOf(startNode, mRootContent) ||
!nsContentUtils::ContentIsDescendantOf(endNode, mRootContent)) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ASSERTION(aEvent->mReply.mString.IsEmpty(),
"The reply string must be empty");

View File

@ -49,6 +49,7 @@
#include "nsSandboxFlags.h"
#include "xpcpublic.h"
#include "nsIFrame.h"
#include "nsDisplayList.h"
namespace mozilla {
@ -457,7 +458,7 @@ EventListenerManager::ProcessApzAwareEventListenerAdd()
}
}
if (doc) {
if (doc && nsDisplayListBuilder::LayerEventRegionsEnabled()) {
nsIPresShell* ps = doc->GetShell();
if (ps) {
nsIFrame* f = ps->GetRootFrame();

View File

@ -145,6 +145,7 @@ support-files = bug1017086_inner.html
[test_bug1079236.html]
[test_bug1145910.html]
[test_bug1150308.html]
[test_bug1248459.html]
[test_clickevent_on_input.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_continuous_wheel_events.html]

View File

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1248459
-->
<head>
<title>Test for Bug 1248459</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<input id="input" value="foo">
<div id="div">bar</div>
<script type="application/javascript">
/** Test for Bug 1248459 **/
/**
* The bug occurs when a piece of text outside of the editor's root element is
* somehow selected when the editor is focused. In the bug's case, it's the
* placeholder anonymous div that's selected. In this test's case, it's a
* document div that's selected.
*/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
var div = document.getElementById("div");
var input = document.getElementById("input");
input.appendChild(div);
input.focus();
var editor = SpecialPowers.wrap(input).editor;
var sel = editor.selection;
sel.selectAllChildren(editor.rootElement);
var result = synthesizeQuerySelectedText();
ok(result.succeeded, "Query selected text should succeed");
is(result.offset, 0, "Selected text should be at offset 0");
is(result.text, "foo", "Selected text should match");
var range = document.createRange();
range.selectNode(div);
sel.removeAllRanges();
sel.addRange(range);
result = synthesizeQuerySelectedText();
ok(!result.succeeded, "Query out-of-bounds selection should fail");
SimpleTest.finish();
});
</script>
</body>
</html>

View File

@ -265,10 +265,36 @@ FetchDriver::HttpFetch()
// Step 2. Set the referrer.
nsAutoString referrer;
mRequest->GetReferrer(referrer);
ReferrerPolicy referrerPolicy = mRequest->ReferrerPolicy_();
net::ReferrerPolicy net_referrerPolicy = net::RP_Unset;
switch (referrerPolicy) {
case ReferrerPolicy::_empty:
net_referrerPolicy = net::RP_Default;
break;
case ReferrerPolicy::No_referrer:
net_referrerPolicy = net::RP_No_Referrer;
break;
case ReferrerPolicy::No_referrer_when_downgrade:
net_referrerPolicy = net::RP_No_Referrer_When_Downgrade;
break;
case ReferrerPolicy::Origin_only:
net_referrerPolicy = net::RP_Origin;
break;
case ReferrerPolicy::Origin_when_cross_origin:
net_referrerPolicy = net::RP_Origin_When_Crossorigin;
break;
case ReferrerPolicy::Unsafe_url:
net_referrerPolicy = net::RP_Unsafe_URL;
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy enum value?");
break;
}
if (referrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
rv = nsContentUtils::SetFetchReferrerURIWithPolicy(mPrincipal,
mDocument,
httpChan);
httpChan,
net_referrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
} else if (referrer.IsEmpty()) {
rv = httpChan->SetReferrerWithPolicy(nullptr, net::RP_No_Referrer);
@ -277,19 +303,17 @@ FetchDriver::HttpFetch()
// From "Determine request's Referrer" step 3
// "If request's referrer is a URL, let referrerSource be request's
// referrer."
//
// XXXnsm - We never actually hit this from a fetch() call since both
// fetch and Request() create a new internal request whose referrer is
// always set to about:client. Should we just crash here instead until
// someone tries to use FetchDriver for non-fetch() APIs?
nsCOMPtr<nsIURI> referrerURI;
rv = NS_NewURI(getter_AddRefs(referrerURI), referrer, nullptr, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t documentReferrerPolicy = mDocument ? mDocument->GetReferrerPolicy() :
net::RP_Default;
rv =
httpChan->SetReferrerWithPolicy(referrerURI,
mDocument ? mDocument->GetReferrerPolicy() :
net::RP_Default);
referrerPolicy == ReferrerPolicy::_empty ?
documentReferrerPolicy :
net_referrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -37,6 +37,7 @@ InternalRequest::GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult
copy->mSameOriginDataURL = true;
copy->mPreserveContentCodings = true;
// The default referrer is already about:client.
copy->mReferrerPolicy = mReferrerPolicy;
copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH;
copy->mMode = mMode;
@ -77,6 +78,7 @@ InternalRequest::InternalRequest(const InternalRequest& aOther)
, mHeaders(new InternalHeaders(*aOther.mHeaders))
, mContentPolicyType(aOther.mContentPolicyType)
, mReferrer(aOther.mReferrer)
, mReferrerPolicy(aOther.mReferrerPolicy)
, mMode(aOther.mMode)
, mCredentialsMode(aOther.mCredentialsMode)
, mResponseTainting(aOther.mResponseTainting)

View File

@ -93,6 +93,7 @@ public:
, mHeaders(new InternalHeaders(HeadersGuardEnum::None))
, mContentPolicyType(nsIContentPolicy::TYPE_FETCH)
, mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR))
, mReferrerPolicy(ReferrerPolicy::_empty)
, mMode(RequestMode::No_cors)
, mCredentialsMode(RequestCredentials::Omit)
, mResponseTainting(LoadTainting::Basic)
@ -120,12 +121,14 @@ public:
RequestRedirect aRequestRedirect,
RequestCredentials aRequestCredentials,
const nsAString& aReferrer,
ReferrerPolicy aReferrerPolicy,
nsContentPolicyType aContentPolicyType)
: mMethod(aMethod)
, mURL(aURL)
, mHeaders(aHeaders)
, mContentPolicyType(aContentPolicyType)
, mReferrer(aReferrer)
, mReferrerPolicy(aReferrerPolicy)
, mMode(aMode)
, mCredentialsMode(aRequestCredentials)
, mResponseTainting(LoadTainting::Basic)
@ -230,6 +233,18 @@ public:
mReferrer.Assign(aReferrer);
}
ReferrerPolicy
ReferrerPolicy_() const
{
return mReferrerPolicy;
}
void
SetReferrerPolicy(ReferrerPolicy aReferrerPolicy)
{
mReferrerPolicy = aReferrerPolicy;
}
bool
SkipServiceWorker() const
{
@ -442,6 +457,7 @@ private:
// "about:client": client (default)
// URL: an URL
nsString mReferrer;
ReferrerPolicy mReferrerPolicy;
RequestMode mMode;
RequestCredentials mCredentialsMode;

View File

@ -353,6 +353,7 @@ Request::Constructor(const GlobalObject& aGlobal,
if (aInit.IsAnyMemberPresent()) {
request->SetReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR));
request->SetReferrerPolicy(ReferrerPolicy::_empty);
}
if (aInit.mReferrer.WasPassed()) {
const nsString& referrer = aInit.mReferrer.Value();
@ -419,6 +420,10 @@ Request::Constructor(const GlobalObject& aGlobal,
}
}
if (aInit.mReferrerPolicy.WasPassed()) {
request->SetReferrerPolicy(aInit.mReferrerPolicy.Value());
}
if (mode != RequestMode::EndGuard_) {
request->ClearCreatedByFetchEvent();
request->SetMode(mode);

View File

@ -99,6 +99,12 @@ public:
mRequest->GetReferrer(aReferrer);
}
ReferrerPolicy
ReferrerPolicy_() const
{
return mRequest->ReferrerPolicy_();
}
InternalHeaders*
GetInternalHeaders() const
{

View File

@ -354,19 +354,21 @@ HTMLOptionElement::IntrinsicState() const
HTMLSelectElement*
HTMLOptionElement::GetSelect()
{
nsIContent* parent = this;
while ((parent = parent->GetParent()) &&
parent->IsHTMLElement()) {
HTMLSelectElement* select = HTMLSelectElement::FromContent(parent);
if (select) {
return select;
}
if (!parent->IsHTMLElement(nsGkAtoms::optgroup)) {
break;
}
nsIContent* parent = GetParent();
if (!parent) {
return nullptr;
}
return nullptr;
HTMLSelectElement* select = HTMLSelectElement::FromContent(parent);
if (select) {
return select;
}
if (!parent->IsHTMLElement(nsGkAtoms::optgroup)) {
return nullptr;
}
return HTMLSelectElement::FromContentOrNull(parent->GetParent());
}
already_AddRefed<HTMLOptionElement>

View File

@ -605,3 +605,4 @@ skip-if = buildapp == 'b2g' || (e10s && debug && os == 'win') # bug 1129014
[test_filepicker_default_directory.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
[test_bug1233598.html]
[test_bug1250401.html]

View File

@ -0,0 +1,97 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1250401
-->
<head>
<title>Test for Bug 1250401</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1250401">Bug 1250401</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 1250401 **/
function test_add() {
var select = document.createElement("select");
var g1 = document.createElement("optgroup");
var o1 = document.createElement("option");
g1.appendChild(o1);
select.appendChild(g1);
var g2 = document.createElement("optgroup");
var o2 = document.createElement("option");
g2.appendChild(o2);
select.add(g2, 0);
is(select.children.length, 1, "Select has 1 item");
is(select.firstChild, g1, "First item is g1");
is(select.firstChild.children.length, 2, "g2 has 2 children");
is(select.firstChild.children[0], g2, "g1 has 2 children: g2");
is(select.firstChild.children[1], o1, "g1 has 2 children: o1");
is(o1.index, 0, "o1.index should be 0");
is(o2.index, 0, "o2.index should be 0");
}
function test_append() {
var select = document.createElement("select");
var g1 = document.createElement("optgroup");
var o1 = document.createElement("option");
g1.appendChild(o1);
select.appendChild(g1);
var g2 = document.createElement("optgroup");
var o2 = document.createElement("option");
g2.appendChild(o2);
g1.appendChild(g2);
is(select.children.length, 1, "Select has 1 item");
is(select.firstChild, g1, "First item is g1");
is(select.firstChild.children.length, 2, "g2 has 2 children");
is(select.firstChild.children[0], o1, "g1 has 2 children: o1");
is(select.firstChild.children[1], g2, "g1 has 2 children: g1");
is(o1.index, 0, "o1.index should be 0");
is(o2.index, 0, "o2.index should be 0");
}
function test_no_select() {
var g1 = document.createElement("optgroup");
var o1 = document.createElement("option");
g1.appendChild(o1);
var g2 = document.createElement("optgroup");
var o2 = document.createElement("option");
g2.appendChild(o2);
g1.appendChild(g2);
is(g1.children.length, 2, "g2 has 2 children");
is(g1.children[0], o1, "g1 has 2 children: o1");
is(g1.children[1], g2, "g1 has 2 children: g1");
is(o1.index, 0, "o1.index should be 0");
is(o2.index, 0, "o2.index should be 0");
}
function test_no_parent() {
var o1 = document.createElement("option");
var o2 = document.createElement("option");
is(o1.index, 0, "o1.index should be 0");
is(o2.index, 0, "o2.index should be 0");
}
test_add();
test_append();
test_no_select();
test_no_parent();
</script>
</pre>
</body>
</html>

View File

@ -859,23 +859,22 @@ TabChild::Init()
void
TabChild::NotifyTabContextUpdated()
{
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
MOZ_ASSERT(docShell);
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
MOZ_ASSERT(docShell);
if (docShell) {
// nsDocShell will do the right thing if we pass NO_APP_ID or
// UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (IsMozBrowserElement()) {
docShell->SetIsBrowserInsideApp(BrowserOwnerAppId());
docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
} else {
docShell->SetIsApp(OwnAppId());
}
if (!docShell) {
return;
}
OriginAttributes attrs = OriginAttributesRef();
docShell->SetIsSignedPackage(attrs.mSignedPkg);
docShell->SetUserContextId(attrs.mUserContextId);
}
if (IsMozBrowserElement()) {
docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
}
docShell->SetFrameType(IsMozBrowserElement() ?
nsIDocShell::FRAME_TYPE_BROWSER :
HasOwnApp() ?
nsIDocShell::FRAME_TYPE_APP :
nsIDocShell::FRAME_TYPE_REGULAR);
nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef());
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)

View File

@ -231,7 +231,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mDecodeThreadWaiting(false),
mDropAudioUntilNextDiscontinuity(false),
mDropVideoUntilNextDiscontinuity(false),
mDecodeToSeekTarget(false),
mCurrentTimeBeforeSeek(0),
mCorruptFrames(60),
mDecodingFirstFrame(true),
@ -486,13 +485,11 @@ bool
MediaDecoderStateMachine::NeedToDecodeVideo()
{
MOZ_ASSERT(OnTaskQueue());
SAMPLE_LOG("NeedToDecodeVideo() isDec=%d decToTar=%d minPrl=%d seek=%d enufVid=%d",
IsVideoDecoding(), mDecodeToSeekTarget, mMinimizePreroll,
mState == DECODER_STATE_SEEKING,
HaveEnoughDecodedVideo());
SAMPLE_LOG("NeedToDecodeVideo() isDec=%d minPrl=%d enufVid=%d",
IsVideoDecoding(), mMinimizePreroll, HaveEnoughDecodedVideo());
return IsVideoDecoding() &&
((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) ||
(IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
mState != DECODER_STATE_SEEKING &&
((IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
(!mMinimizePreroll && !HaveEnoughDecodedVideo()));
}
@ -556,17 +553,15 @@ bool
MediaDecoderStateMachine::NeedToDecodeAudio()
{
MOZ_ASSERT(OnTaskQueue());
SAMPLE_LOG("NeedToDecodeAudio() isDec=%d decToTar=%d minPrl=%d seek=%d enufAud=%d",
IsAudioDecoding(), mDecodeToSeekTarget, mMinimizePreroll,
mState == DECODER_STATE_SEEKING,
SAMPLE_LOG("NeedToDecodeAudio() isDec=%d minPrl=%d enufAud=%d",
IsAudioDecoding(), mMinimizePreroll,
HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate));
return IsAudioDecoding() &&
((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) ||
(IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
mState != DECODER_STATE_SEEKING &&
((IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
(!mMinimizePreroll &&
!HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate) &&
(mState != DECODER_STATE_SEEKING || mDecodeToSeekTarget)));
!HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate)));
}
bool
@ -1026,7 +1021,8 @@ MediaDecoderStateMachine::CheckIfSeekComplete()
audioSeekComplete, videoSeekComplete);
if (audioSeekComplete && videoSeekComplete) {
mDecodeToSeekTarget = false;
NS_ASSERTION(AudioQueue().GetSize() <= 1, "Should decode at most one sample");
NS_ASSERTION(VideoQueue().GetSize() <= 1, "Should decode at most one sample");
SeekCompleted();
}
}
@ -1648,8 +1644,8 @@ MediaDecoderStateMachine::InitiateSeek()
self->mSeekRequest.Complete();
// We must decode the first samples of active streams, so we can determine
// the new stream time. So dispatch tasks to do that.
self->mDecodeToSeekTarget = true;
self->DispatchDecodeTasksIfNeeded();
self->EnsureAudioDecodeTaskQueued();
self->EnsureVideoDecodeTaskQueued();
}, [self] (nsresult aResult) -> void {
self->mSeekRequest.Complete();
MOZ_ASSERT(NS_FAILED(aResult), "Cancels should also disconnect mSeekRequest");
@ -2406,7 +2402,6 @@ MediaDecoderStateMachine::Reset()
mFirstVideoFrameAfterSeek = nullptr;
mDropAudioUntilNextDiscontinuity = true;
mDropVideoUntilNextDiscontinuity = true;
mDecodeToSeekTarget = false;
mMetadataRequest.DisconnectIfExists();
mAudioDataRequest.DisconnectIfExists();

View File

@ -1121,10 +1121,6 @@ private:
bool mDropAudioUntilNextDiscontinuity;
bool mDropVideoUntilNextDiscontinuity;
// True if we need to decode forwards to the seek target inside
// mCurrentSeekTarget.
bool mDecodeToSeekTarget;
// Track the current seek promise made by the reader.
MozPromiseRequestHolder<MediaDecoderReader::SeekPromise> mSeekRequest;

View File

@ -169,7 +169,7 @@ VP8TrackEncoder::GetMetadata()
return meta.forget();
}
nsresult
bool
VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
{
vpx_codec_iter_t iter = nullptr;
@ -197,21 +197,18 @@ VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
}
}
if (!frameData.IsEmpty() &&
(pkt->data.frame.pts == mEncodedTimestamp)) {
if (!frameData.IsEmpty()) {
// Copy the encoded data to aData.
EncodedFrame* videoData = new EncodedFrame();
videoData->SetFrameType(frameType);
// Convert the timestamp and duration to Usecs.
CheckedInt64 timestamp = FramesToUsecs(mEncodedTimestamp, mTrackRate);
CheckedInt64 timestamp = FramesToUsecs(pkt->data.frame.pts, mTrackRate);
if (timestamp.isValid()) {
videoData->SetTimeStamp(
(uint64_t)FramesToUsecs(mEncodedTimestamp, mTrackRate).value());
videoData->SetTimeStamp((uint64_t)timestamp.value());
}
CheckedInt64 duration = FramesToUsecs(pkt->data.frame.duration, mTrackRate);
if (duration.isValid()) {
videoData->SetDuration(
(uint64_t)FramesToUsecs(pkt->data.frame.duration, mTrackRate).value());
videoData->SetDuration((uint64_t)duration.value());
}
videoData->SwapInFrameData(frameData);
VP8LOG("GetEncodedPartitions TimeStamp %lld Duration %lld\n",
@ -220,7 +217,7 @@ VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData)
aData.AppendEncodedFrame(videoData);
}
return NS_OK;
return !!pkt;
}
static bool isYUV420(const PlanarYCbCrImage::Data *aData)
@ -365,7 +362,7 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
return NS_ERROR_FAILURE;
}
VP8LOG("Converted an %s frame to I420\n");
VP8LOG("Converted an %s frame to I420\n", yuvFormat.c_str());
} else {
// Not YCbCr at all. Try to get access to the raw data and convert.
@ -631,11 +628,15 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
if (EOS) {
VP8LOG("mEndOfStream is true\n");
mEncodingComplete = true;
if (vpx_codec_encode(mVPXContext, nullptr, mEncodedTimestamp,
mEncodedFrameDuration, 0, VPX_DL_REALTIME)) {
return NS_ERROR_FAILURE;
}
GetEncodedPartitions(aData);
// Bug 1243611, keep calling vpx_codec_encode and vpx_codec_get_cx_data
// until vpx_codec_get_cx_data return null.
do {
if (vpx_codec_encode(mVPXContext, nullptr, mEncodedTimestamp,
mEncodedFrameDuration, 0, VPX_DL_REALTIME)) {
return NS_ERROR_FAILURE;
}
} while(GetEncodedPartitions(aData));
}
return NS_OK ;

View File

@ -54,7 +54,9 @@ private:
StreamTime aProcessedDuration);
// Get the encoded data from encoder to aData.
nsresult GetEncodedPartitions(EncodedFrameContainer& aData);
// Return value: false if the vpx_codec_get_cx_data returns null
// for EOS detection.
bool GetEncodedPartitions(EncodedFrameContainer& aData);
// Prepare the input data to the mVPXImageWrapper for encoding.
nsresult PrepareRawFrame(VideoChunk &aChunk);

View File

@ -1,5 +1,6 @@
[DEFAULT]
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
subsuite = media
support-files =
mediasource.js
seek.webm seek.webm^headers^

View File

@ -66,5 +66,5 @@ class MachCommands(MachCommandBase):
parser=setup_argument_parser,
)
def run_external_media_test(self, tests, **kwargs):
kwargs['binary'] = self.get_binary_path('app')
kwargs['binary'] = kwargs['binary'] or self.get_binary_path('app')
return run_external_media_test(tests, topsrcdir=self.topsrcdir, **kwargs)

View File

@ -23,6 +23,7 @@
[DEFAULT]
skip-if = buildapp == 'mulet' || (os == 'win' && strictContentSandbox) || android_version == '18' # strictContentSandbox (Bug 1042735)
subsuite = media
support-files =
16bit_wave_extrametadata.wav
16bit_wave_extrametadata.wav^headers^

View File

@ -3,6 +3,7 @@
# won't run on b2g desktop tests - bug 1119993
# broken HTTPS on b2g emulator - bug 1135339
skip-if = (os == 'win' && strictContentSandbox) || android_version == '10' || android_version == '18' || (buildapp == 'b2g' && toolkit != 'gonk') || (buildapp == 'b2g' && toolkit == 'gonk') || buildapp == 'mulet'
subsuite = media
support-files =
/.well-known/idp-proxy/idp.js
identityPcTest.js

View File

@ -1,5 +1,6 @@
[DEFAULT]
tags=msg
subsuite=media
support-files =
ipc.json

View File

@ -1,6 +1,7 @@
[DEFAULT]
# strictContentSandbox - bug 1042735, Android 2.3 - bug 981881
tags = msg webrtc
subsuite = media
skip-if = (os == 'win' && strictContentSandbox) || android_version == '10' || (buildapp == 'mulet') || (toolkit == 'gonk' && debug) # b2g(Either bug 1171118 or bug 1169838, take your pick)
support-files =
head.js

View File

@ -1,6 +1,7 @@
[DEFAULT]
tags=msg
tags = webaudio
subsuite = media
skip-if = ((buildapp == 'b2g') && (toolkit != 'gonk' || debug)) || (os == 'win' && strictContentSandbox) #b2g-debug,b2g-desktop(bug 916135); strictContentSandbox(Bug 1042735)
support-files =
audio-expected.wav

View File

@ -1,6 +1,7 @@
[DEFAULT]
tags=msg
skip-if = buildapp == 'b2g' || (e10s && debug && os == 'win') # Bug 1191270, bug 1037287, bug 967606, bug 1096400, bug 1238542 etc
subsuite = media
support-files =
head.js
hello.ogg

View File

@ -1,5 +1,6 @@
[DEFAULT]
tags=msg
subsuite = media
support-files =
common.js
file_bfcache_frame.html

Some files were not shown because too many files have changed in this diff Show More