mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Merge mozilla-central to fx-team
This commit is contained in:
commit
6e681479dc
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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?
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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/";
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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(),
|
||||
},
|
||||
|
@ -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) {
|
||||
|
@ -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()");
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
107
browser/extensions/e10srollout/bootstrap.js
vendored
Normal file
107
browser/extensions/e10srollout/bootstrap.js
vendored
Normal 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);
|
||||
}
|
||||
|
31
browser/extensions/e10srollout/install.rdf.in
Normal file
31
browser/extensions/e10srollout/install.rdf.in
Normal 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>
|
13
browser/extensions/e10srollout/moz.build
Normal file
13
browser/extensions/e10srollout/moz.build
Normal 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'
|
||||
]
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'e10srollout',
|
||||
'loop',
|
||||
'pdfjs',
|
||||
'pocket',
|
||||
|
@ -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; }
|
||||
};
|
||||
|
@ -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; }
|
||||
};
|
||||
|
@ -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)
|
||||
|
||||
|
21
client.mk
21
client.mk
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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]();
|
||||
});
|
||||
|
||||
|
@ -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>
|
||||
|
@ -980,7 +980,10 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'Request': {
|
||||
'binaryNames': { 'headers': 'headers_' },
|
||||
'binaryNames': {
|
||||
'headers': 'headers_',
|
||||
'referrerPolicy': 'referrerPolicy_'
|
||||
},
|
||||
},
|
||||
|
||||
'Response': {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
2
dom/cache/CacheTypes.ipdlh
vendored
2
dom/cache/CacheTypes.ipdlh
vendored
@ -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
186
dom/cache/DBSchema.cpp
vendored
@ -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(¤tVersion);
|
||||
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(¤tVersion);
|
||||
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(¤tVersion);
|
||||
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(¤tVersion);
|
||||
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
|
||||
|
||||
|
5
dom/cache/IPCUtils.h
vendored
5
dom/cache/IPCUtils.h
vendored
@ -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,
|
||||
|
2
dom/cache/TypeUtils.cpp
vendored
2
dom/cache/TypeUtils.cpp
vendored
@ -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());
|
||||
|
1
dom/cache/test/xpcshell/test_migration.js
vendored
1
dom/cache/test/xpcshell/test_migration.js
vendored
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
85
dom/canvas/test/imagebitmap_bug1239752.js
Normal file
85
dom/canvas/test/imagebitmap_bug1239752.js
Normal 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);
|
||||
}
|
@ -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});
|
||||
}
|
||||
|
157
dom/canvas/test/imagebitmap_structuredclone_utils.js
Normal file
157
dom/canvas/test/imagebitmap_structuredclone_utils.js
Normal 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]);
|
||||
}
|
@ -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
|
||||
|
@ -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(); });
|
||||
}
|
||||
|
||||
|
@ -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});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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}, "*");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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}, "*");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
|
58
dom/events/test/test_bug1248459.html
Normal file
58
dom/events/test/test_bug1248459.html
Normal 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>
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -99,6 +99,12 @@ public:
|
||||
mRequest->GetReferrer(aReferrer);
|
||||
}
|
||||
|
||||
ReferrerPolicy
|
||||
ReferrerPolicy_() const
|
||||
{
|
||||
return mRequest->ReferrerPolicy_();
|
||||
}
|
||||
|
||||
InternalHeaders*
|
||||
GetInternalHeaders() const
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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]
|
||||
|
97
dom/html/test/test_bug1250401.html
Normal file
97
dom/html/test/test_bug1250401.html
Normal 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>
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 ;
|
||||
|
@ -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);
|
||||
|
@ -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^
|
||||
|
2
dom/media/test/external/mach_commands.py
vendored
2
dom/media/test/external/mach_commands.py
vendored
@ -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)
|
||||
|
@ -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^
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,6 @@
|
||||
[DEFAULT]
|
||||
tags=msg
|
||||
subsuite=media
|
||||
support-files =
|
||||
ipc.json
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user