Merge m-c to b2g-i

This commit is contained in:
Carsten "Tomcat" Book 2014-04-16 15:20:23 +02:00
commit 0e443a27d3
240 changed files with 14782 additions and 11870 deletions

View File

@ -37,7 +37,7 @@ let gGrid = {
get sites() [cell.site for each (cell in this.cells)],
// Tells whether the grid has already been initialized.
get ready() !!this._node,
get ready() !!this._ready,
/**
* Initializes the grid.
@ -46,7 +46,11 @@ let gGrid = {
init: function Grid_init() {
this._node = document.getElementById("newtab-grid");
this._createSiteFragment();
this._render();
this._renderGrid();
gLinks.populateCache(() => {
this._renderSites();
this._ready = true;
});
addEventListener("load", this);
addEventListener("resize", this);
},
@ -69,14 +73,6 @@ let gGrid = {
handleEvent: function Grid_handleEvent(aEvent) {
switch (aEvent.type) {
case "load":
// Save the cell's computed height/width including margin and border
let refCell = document.querySelector(".newtab-cell");
this._cellMargin = parseFloat(getComputedStyle(refCell).marginTop) * 2;
this._cellHeight = refCell.offsetHeight + this._cellMargin;
this._cellWidth = refCell.offsetWidth + this._cellMargin;
this._resizeGrid();
break;
case "resize":
this._resizeGrid();
break;
@ -97,8 +93,11 @@ let gGrid = {
}, this);
// Render the grid again.
this._render();
this._resizeGrid();
if (this._shouldRenderGrid()) {
this._renderGrid();
this._resizeGrid();
}
this._renderSites();
},
/**
@ -185,21 +184,18 @@ let gGrid = {
}
},
/**
* Renders the grid.
*/
_render: function Grid_render() {
if (this._shouldRenderGrid()) {
this._renderGrid();
}
this._renderSites();
},
/**
* Make sure the correct number of rows and columns are visible
*/
_resizeGrid: function Grid_resizeGrid() {
// Save the cell's computed height/width including margin and border
if (this._cellMargin === undefined) {
let refCell = document.querySelector(".newtab-cell");
this._cellMargin = parseFloat(getComputedStyle(refCell).marginTop) * 2;
this._cellHeight = refCell.offsetHeight + this._cellMargin;
this._cellWidth = refCell.offsetWidth + this._cellMargin;
}
let availSpace = document.documentElement.clientHeight - this._cellMargin -
document.querySelector("#newtab-margin-top").offsetHeight;
let visibleRows = Math.floor(availSpace / this._cellHeight);

View File

@ -144,19 +144,17 @@ let gPage = {
attributeFilter: ["allow-background-captures"],
});
gLinks.populateCache(function () {
// Initialize and render the grid.
gGrid.init();
// Initialize and render the grid.
gGrid.init();
// Initialize the drop target shim.
gDropTargetShim.init();
// Initialize the drop target shim.
gDropTargetShim.init();
#ifdef XP_MACOSX
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
document.addEventListener("dragover", this, false);
document.addEventListener("drop", this, false);
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
document.addEventListener("dragover", this, false);
document.addEventListener("drop", this, false);
#endif
}.bind(this));
},
/**

View File

@ -169,7 +169,10 @@ Site.prototype = {
this._node.addEventListener("dragstart", this, false);
this._node.addEventListener("dragend", this, false);
this._node.addEventListener("mouseover", this, false);
this._node.addEventListener("click", this, false);
// XXX bug 991111 - Not all click events are correctly triggered when
// listening from the xhtml node, so listen from the xul window and filter
addEventListener("click", this, false);
// Specially treat the sponsored icon to prevent regular hover effects
let sponsored = this._querySelector(".newtab-control-sponsored");
@ -240,7 +243,11 @@ Site.prototype = {
handleEvent: function Site_handleEvent(aEvent) {
switch (aEvent.type) {
case "click":
this._onClick(aEvent);
// Check the bitmask if the click event is for the site's descendants
if (this._node.compareDocumentPosition(aEvent.target) &
this._node.DOCUMENT_POSITION_CONTAINED_BY) {
this._onClick(aEvent);
}
break;
case "mouseover":
this._node.removeEventListener("mouseover", this, false);

View File

@ -771,7 +771,7 @@ function test() {
}, true);
let rootDir = getRootDirectory(gTestPath)
rootDir = rootDir.replace("chrome://mochitests/content/",
"http://127.0.0.1:8888/");
"https://example.com/");
content.location = rootDir + "get_user_media.html";
}

View File

@ -15,6 +15,8 @@ skip-if = os == "mac" # Intermittent failures, bug 898317
[browser_newtab_bug752841.js]
[browser_newtab_bug765628.js]
[browser_newtab_bug876313.js]
[browser_newtab_bug991111.js]
[browser_newtab_bug991210.js]
[browser_newtab_disable.js]
[browser_newtab_drag_drop.js]
[browser_newtab_drag_drop_ext.js]

View File

@ -0,0 +1,19 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function runTests() {
yield setLinks("0");
yield addNewTabPageTab();
// Remember if the click handler was triggered
let cell = getCell(0);
let clicked = false;
cell.site._onClick = e => {
clicked = true;
executeSoon(TestRunner.next);
};
// Send a middle-click and make sure it happened
yield EventUtils.synthesizeMouseAtCenter(cell.node, {button: 1}, getContentWindow());
ok(clicked, "middle click triggered click listener");
}

View File

@ -0,0 +1,41 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PRELOAD_PREF = "browser.newtab.preload";
function runTests() {
// turn off preload to ensure that a newtab page loads
Services.prefs.setBoolPref(PRELOAD_PREF, false);
// add a test provider that waits for load
let afterLoadProvider = {
getLinks: function(callback) {
this.callback = callback;
},
addObserver: function() {},
};
NewTabUtils.links.addProvider(afterLoadProvider);
// wait until about:newtab loads before calling provider callback
addNewTabPageTab();
let browser = gWindow.gBrowser.selectedTab.linkedBrowser;
yield browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
// afterLoadProvider.callback has to be called asynchronously to make grid
// initilize after "load" event was handled
executeSoon(() => afterLoadProvider.callback([]));
}, true);
let {_cellMargin, _cellHeight, _cellWidth, node} = getGrid();
isnot(_cellMargin, null, "grid has a computed cell margin");
isnot(_cellHeight, null, "grid has a computed cell height");
isnot(_cellWidth, null, "grid has a computed cell width");
let {height, maxHeight, maxWidth} = node.style;
isnot(height, "", "grid has a computed grid height");
isnot(maxHeight, "", "grid has a computed grid max-height");
isnot(maxWidth, "", "grid has a computed grid max-width");
// restore original state
NewTabUtils.links.removeProvider(afterLoadProvider);
Services.prefs.clearUserPref(PRELOAD_PREF);
}

View File

@ -6,11 +6,6 @@
*/
function runTests() {
if (NewTabUtils.allPages.updateScheduledForHiddenPages) {
// Wait for dynamic updates triggered by the previous test to finish.
yield whenPagesUpdated(null, true);
}
// First, start with an empty page. setLinks will trigger a hidden page
// update because it calls clearHistory. We need to wait for that update to
// happen so that the next time we wait for a page update below, we catch the

View File

@ -14,7 +14,8 @@ Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp);
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://browser/content/sanitize.js", tmp);
let {Promise, NewTabUtils, Sanitizer} = tmp;
Cu.import("resource://gre/modules/Timer.jsm", tmp);
let {Promise, NewTabUtils, Sanitizer, clearTimeout} = tmp;
let uri = Services.io.newURI("about:newtab", null, null);
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
@ -30,6 +31,13 @@ registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
// Stop any update timers to prevent unexpected updates in later tests
let timer = NewTabUtils.allPages._scheduleUpdateTimeout;
if (timer) {
clearTimeout(timer);
delete NewTabUtils.allPages._scheduleUpdateTimeout;
}
});
/**

View File

@ -36,14 +36,12 @@ function test()
// Make sure the body element is selected initially.
node = doc.querySelector("body");
inspector.once("inspector-updated", () => {
is(inspector.selection.node, node, "Body should be selected initially.");
node = doc.querySelector("h1")
inspector.once("inspector-updated", highlightHeaderNode);
let bc = inspector.breadcrumbs;
bc.nodeHierarchy[bc.currentIndex].button.focus();
EventUtils.synthesizeKey("VK_RIGHT", { });
});
is(inspector.selection.node, node, "Body should be selected initially.");
node = doc.querySelector("h1")
inspector.once("inspector-updated", highlightHeaderNode);
let bc = inspector.breadcrumbs;
bc.nodeHierarchy[bc.currentIndex].button.focus();
EventUtils.synthesizeKey("VK_RIGHT", {});
}
function highlightHeaderNode()

View File

@ -25,7 +25,7 @@ function test() {
openInspector((aInspector, aToolbox) => {
inspector = aInspector;
markupView = inspector.markup;
inspector.once("inspector-updated", startTests);
startTests();
});
}, content);
}, true);

View File

@ -35,9 +35,7 @@ function createDocument() {
// Open the inspector, start the picker mode, and start the tests
openInspector(aInspector => {
inspector = aInspector;
inspector.once("inspector-updated", () => {
inspector.toolbox.highlighterUtils.startPicker().then(runTests);
});
inspector.toolbox.highlighterUtils.startPicker().then(runTests);
});
}, false);

View File

@ -13,9 +13,7 @@ function test() {
openInspector(aInspector => {
inspector = aInspector;
inspector.once("inspector-updated", () => {
inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
});
inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
});
}

View File

@ -1,189 +1,142 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that locking the pseudoclass displays correctly in the ruleview
let DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
const PSEUDO = ":hover";
const TEST_URL = 'data:text/html,' +
'<head>' +
' <style>div {color:red;} div:hover {color:blue;}</style>' +
'</head>' +
'<body>' +
' <div id="parent-div">' +
' <div id="div-1">test div</div>' +
' <div id="div-2">test div2</div>' +
' </div>' +
'</body>';
let doc;
let parentDiv, div, div2;
let inspector;
let ruleview;
waitForExplicitFinish();
let pseudo = ":hover";
function test()
{
waitForExplicitFinish();
function test() {
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
doc = content.document;
waitForFocus(createDocument, content);
waitForFocus(startTests, content);
}, true);
content.location = "data:text/html,pseudo-class lock tests";
content.location = TEST_URL;
}
function createDocument()
{
parentDiv = doc.createElement("div");
parentDiv.textContent = "parent div";
let startTests = Task.async(function*() {
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode("#div-1", inspector);
div = doc.createElement("div");
div.textContent = "test div";
yield performTests(inspector, view);
div2 = doc.createElement("div");
div2.textContent = "test div2";
yield finishUp(toolbox);
finish();
});
let head = doc.getElementsByTagName('head')[0];
let style = doc.createElement('style');
let rules = doc.createTextNode('div { color: red; } div:hover { color: blue; }');
function* performTests(inspector, ruleview) {
yield togglePseudoClass(inspector);
yield testAdded(inspector, ruleview);
style.appendChild(rules);
head.appendChild(style);
parentDiv.appendChild(div);
parentDiv.appendChild(div2);
doc.body.appendChild(parentDiv);
yield togglePseudoClass(inspector);
yield testRemoved();
yield testRemovedFromUI(inspector, ruleview);
openInspector(selectNode);
yield togglePseudoClass(inspector);
yield testNavigate(inspector, ruleview);
}
function selectNode(aInspector)
{
inspector = aInspector;
function* togglePseudoClass(inspector) {
info("Toggle the pseudoclass, wait for the pseudoclass event and wait for the refresh of the rule view");
waitForView("ruleview", () => {
ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view;
inspector.sidebar.select("ruleview");
inspector.selection.setNode(div, "test");
inspector.once("inspector-updated", performTests);
});
let onPseudo = inspector.selection.once("pseudoclass");
let onRefresh = inspector.once("rule-view-refreshed");
inspector.togglePseudoClass(PSEUDO);
yield onPseudo;
yield onRefresh;
}
function performTests()
{
// toggle the class
inspector.togglePseudoClass(pseudo);
function* testNavigate(inspector, ruleview) {
yield selectNode("#parent-div", inspector);
// Wait for the "pseudoclass" event so we know the
// inspector has been told of the pseudoclass lock change.
inspector.selection.once("pseudoclass", () => {
inspector.once("rule-view-refreshed", () => {
testAdded(() => {
// Change the pseudo class and give the rule view time to update.
inspector.togglePseudoClass(pseudo);
inspector.selection.once("pseudoclass", () => {
inspector.once("rule-view-refreshed", () => {
testRemoved();
testRemovedFromUI(() => {
// toggle it back on
inspector.togglePseudoClass(pseudo);
inspector.selection.once("pseudoclass", () => {
inspector.once("rule-view-refreshed", () => {
testNavigate(() => {
// close the inspector
finishUp();
});
});
});
});
});
});
});
});
});
info("Make sure the pseudoclass is still on after navigating to a parent");
is(DOMUtils.hasPseudoClassLock(getNode("#div-1"), PSEUDO), true,
"pseudo-class lock is still applied after inspecting ancestor");
let onPseudo = inspector.selection.once("pseudoclass");
yield selectNode("#div-2", inspector);
yield onPseudo;
info("Make sure the pseudoclass is removed after navigating to a non-hierarchy node");
is(DOMUtils.hasPseudoClassLock(getNode("#div-1"), PSEUDO), false,
"pseudo-class lock is removed after inspecting sibling node");
yield selectNode("#div-1", inspector);
yield togglePseudoClass(inspector);
yield inspector.once("computed-view-refreshed");
}
function testNavigate(callback)
{
inspector.selection.setNode(parentDiv, "test");
inspector.once("inspector-updated", () => {
// make sure it's still on after naving to parent
is(DOMUtils.hasPseudoClassLock(div, pseudo), true,
"pseudo-class lock is still applied after inspecting ancestor");
inspector.selection.setNode(div2, "test");
inspector.selection.once("pseudoclass", () => {
// make sure it's removed after naving to a non-hierarchy node
is(DOMUtils.hasPseudoClassLock(div, pseudo), false,
"pseudo-class lock is removed after inspecting sibling node");
// toggle it back on
inspector.selection.setNode(div, "test");
inspector.once("inspector-updated", () => {
inspector.togglePseudoClass(pseudo);
inspector.once("computed-view-refreshed", callback);
});
});
});
}
function showPickerOn(node, cb)
{
function showPickerOn(node, inspector) {
let highlighter = inspector.toolbox.highlighter;
highlighter.showBoxModel(getNodeFront(node)).then(cb);
return highlighter.showBoxModel(getNodeFront(node));
}
function testAdded(cb)
{
// lock is applied to it and ancestors
let node = div;
function* testAdded(inspector, ruleview) {
info("Make sure the pseudoclass lock is applied to #div-1 and its ancestors");
let node = getNode("#div-1");
do {
is(DOMUtils.hasPseudoClassLock(node, pseudo), true,
is(DOMUtils.hasPseudoClassLock(node, PSEUDO), true,
"pseudo-class lock has been applied");
node = node.parentNode;
} while (node.parentNode)
// ruleview contains pseudo-class rule
info("Check that the ruleview contains the pseudo-class rule");
let rules = ruleview.element.querySelectorAll(".ruleview-rule.theme-separator");
is(rules.length, 3, "rule view is showing 3 rules for pseudo-class locked div");
is(rules[1]._ruleEditor.rule.selectorText, "div:hover", "rule view is showing " + pseudo + " rule");
is(rules[1]._ruleEditor.rule.selectorText, "div:hover", "rule view is showing " + PSEUDO + " rule");
// Show the highlighter by starting the pick mode and hovering over the div
showPickerOn(div, () => {
// infobar selector contains pseudo-class
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
is(pseudoClassesBox.textContent, pseudo, "pseudo-class in infobar selector");
inspector.toolbox.highlighter.hideBoxModel().then(cb);
});
info("Show the highlighter on #div-1");
yield showPickerOn(getNode("#div-1"), inspector);
info("Check that the infobar selector contains the pseudo-class");
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
is(pseudoClassesBox.textContent, PSEUDO, "pseudo-class in infobar selector");
yield inspector.toolbox.highlighter.hideBoxModel();
}
function testRemoved()
{
// lock removed from node and ancestors
let node = div;
function* testRemoved() {
info("Make sure the pseudoclass lock is removed from #div-1 and its ancestors");
let node = getNode("#div-1");
do {
is(DOMUtils.hasPseudoClassLock(node, pseudo), false,
is(DOMUtils.hasPseudoClassLock(node, PSEUDO), false,
"pseudo-class lock has been removed");
node = node.parentNode;
} while (node.parentNode)
}
function testRemovedFromUI(cb)
{
// ruleview no longer contains pseudo-class rule
function* testRemovedFromUI(inspector, ruleview) {
info("Check that the ruleview no longer contains the pseudo-class rule");
let rules = ruleview.element.querySelectorAll(".ruleview-rule.theme-separator");
is(rules.length, 2, "rule view is showing 2 rules after removing lock");
showPickerOn(div, () => {
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
inspector.toolbox.highlighter.hideBoxModel().then(cb);
});
yield showPickerOn(getNode("#div-1"), inspector);
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
yield inspector.toolbox.highlighter.hideBoxModel();
}
function finishUp()
{
gDevTools.once("toolbox-destroyed", function() {
testRemoved();
inspector = ruleview = null;
doc = div = null;
gBrowser.removeCurrentTab();
finish();
});
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = gDevTools.getToolbox(target);
function* finishUp(toolbox) {
let onDestroy = gDevTools.once("toolbox-destroyed");
toolbox.destroy();
yield onDestroy;
yield testRemoved(getNode("#div-1"));
gBrowser.removeCurrentTab();
}

View File

@ -41,12 +41,152 @@ SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
});
function openInspector(callback)
{
/**
* Simple DOM node accesor function that takes either a node or a string css
* selector as argument and returns the corresponding node
* @param {String|DOMNode} nodeOrSelector
* @return {DOMNode}
*/
function getNode(nodeOrSelector) {
return typeof nodeOrSelector === "string" ?
content.document.querySelector(nodeOrSelector) :
nodeOrSelector;
}
/**
* Set the inspector's current selection to a node or to the first match of the
* given css selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @param {String} reason Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @param {String} reason Defaults to "test" which instructs the inspector not to highlight the node upon selection
* @return a promise that resolves when the inspector is updated with the new
* node
*/
function selectNode(nodeOrSelector, inspector, reason="test") {
info("Selecting the node " + nodeOrSelector);
let node = getNode(nodeOrSelector);
let updated = inspector.once("inspector-updated");
inspector.selection.setNode(node, reason);
return updated;
}
/**
* Open the toolbox, with the inspector tool visible.
* @param {Function} cb Optional callback, if you don't want to use the returned
* promise
* @return a promise that resolves when the inspector is ready
*/
let openInspector = Task.async(function*(cb) {
info("Opening the inspector");
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
callback(toolbox.getCurrentPanel(), toolbox);
}).then(null, console.error);
let inspector, toolbox;
// Checking if the toolbox and the inspector are already loaded
// The inspector-updated event should only be waited for if the inspector
// isn't loaded yet
toolbox = gDevTools.getToolbox(target);
if (toolbox) {
inspector = toolbox.getPanel("inspector");
if (inspector) {
info("Toolbox and inspector already open");
if (cb) {
return cb(inspector, toolbox);
} else {
return {
toolbox: toolbox,
inspector: inspector
};
}
}
}
info("Opening the toolbox");
toolbox = yield gDevTools.showToolbox(target, "inspector");
yield waitForToolboxFrameFocus(toolbox);
inspector = toolbox.getPanel("inspector");
info("Waiting for the inspector to update");
yield inspector.once("inspector-updated");
if (cb) {
return cb(inspector, toolbox);
} else {
return {
toolbox: toolbox,
inspector: inspector
};
}
});
/**
* Wait for the toolbox frame to receive focus after it loads
* @param {Toolbox} toolbox
* @return a promise that resolves when focus has been received
*/
function waitForToolboxFrameFocus(toolbox) {
info("Making sure that the toolbox's frame is focused");
let def = promise.defer();
let win = toolbox.frame.contentWindow;
waitForFocus(def.resolve, win);
return def.promise;
}
/**
* Open the toolbox, with the inspector tool visible, and the sidebar that
* corresponds to the given id selected
* @return a promise that resolves when the inspector is ready and the sidebar
* view is visible and ready
*/
let openInspectorSideBar = Task.async(function*(id) {
let {toolbox, inspector} = yield openInspector();
if (!hasSideBarTab(inspector, id)) {
info("Waiting for the " + id + " sidebar to be ready");
yield inspector.sidebar.once(id + "-ready");
}
info("Selecting the " + id + " sidebar");
inspector.sidebar.select(id);
return {
toolbox: toolbox,
inspector: inspector,
view: inspector.sidebar.getWindowForTab(id)[id].view
};
});
/**
* Open the toolbox, with the inspector tool visible, and the computed-view
* sidebar tab selected.
* @return a promise that resolves when the inspector is ready and the computed
* view is visible and ready
*/
function openComputedView() {
return openInspectorSideBar("computedview");
}
/**
* Open the toolbox, with the inspector tool visible, and the rule-view
* sidebar tab selected.
* @return a promise that resolves when the inspector is ready and the rule
* view is visible and ready
*/
function openRuleView() {
return openInspectorSideBar("ruleview");
}
/**
* Checks whether the inspector's sidebar corresponding to the given id already
* exists
* @param {InspectorPanel}
* @param {String}
* @return {Boolean}
*/
function hasSideBarTab(inspector, id) {
return !!inspector.sidebar.getWindowForTab(id);
}
function getActiveInspector()

File diff suppressed because it is too large Load Diff

View File

@ -4010,7 +4010,7 @@ for (var i = 0; i < 288; ++i)
bitLengths[i] = i < 144 || i > 279 ? 8 : i < 256 ? 9 : 7;
var fixedLiteralTable = makeHuffmanTable(bitLengths);
function makeHuffmanTable(bitLengths) {
var maxBits = max.apply(null, bitLengths);
var maxBits = Math.max.apply(null, bitLengths);
var numLengths = bitLengths.length;
var size = 1 << maxBits;
var codes = new Uint32Array(size);
@ -4042,7 +4042,14 @@ function createInflatedStream(bytes, outputLength) {
available: 0,
completed: false
};
var state = {};
var state = {
header: null,
distanceTable: null,
literalTable: null,
sym: null,
len: null,
sym2: null
};
do {
inflateBlock(stream, output, state);
} while (!output.completed && stream.pos < stream.end);
@ -4050,7 +4057,7 @@ function createInflatedStream(bytes, outputLength) {
}
var InflateNoDataError = {};
function inflateBlock(stream, output, state) {
var header = state.header !== undefined ? state.header : state.header = readBits(stream.bytes, stream, 3);
var header = state.header !== null ? state.header : state.header = readBits(stream.bytes, stream, 3);
switch (header >> 1) {
case 0:
stream.align();
@ -4066,10 +4073,7 @@ function inflateBlock(stream, output, state) {
var begin = pos + 4;
var end = stream.pos = begin + len;
var sbytes = stream.bytes, dbytes = output.data;
splice.apply(dbytes, [
output.available,
len
].concat(slice.call(sbytes, begin, end)));
dbytes.set(sbytes.subarray(begin, end), output.available);
output.available += len;
break;
case 1:
@ -4077,7 +4081,7 @@ function inflateBlock(stream, output, state) {
break;
case 2:
var distanceTable, literalTable;
if (state.distanceTable !== undefined) {
if (state.distanceTable !== null) {
distanceTable = state.distanceTable;
literalTable = state.literalTable;
} else {
@ -4130,13 +4134,13 @@ function inflateBlock(stream, output, state) {
literalTable = state.literalTable = makeHuffmanTable(bitLengths);
}
inflate(stream, output, literalTable, distanceTable, state);
delete state.distanceTable;
delete state.literalTable;
state.distanceTable = null;
state.literalTable = null;
break;
default:
fail('unknown block type', 'inflate');
}
delete state.header;
state.header = null;
output.completed = !(!(header & 1));
}
function readBits(bytes, stream, size) {
@ -4165,22 +4169,22 @@ function inflate(stream, output, literalTable, distanceTable, state) {
var pos = output.available;
var dbytes = output.data;
var sbytes = stream.bytes;
var sym = state.sym !== undefined ? state.sym : readCode(sbytes, stream, literalTable);
var sym = state.sym !== null ? state.sym : readCode(sbytes, stream, literalTable);
while (sym !== 256) {
if (sym < 256) {
dbytes[pos++] = sym;
} else {
state.sym = sym;
sym -= 257;
var len = state.len !== undefined ? state.len : state.len = lengthCodes[sym] + readBits(sbytes, stream, lengthExtraBits[sym]);
var sym2 = state.sym2 !== undefined ? state.sym2 : state.sym2 = readCode(sbytes, stream, distanceTable);
var len = state.len !== null ? state.len : state.len = lengthCodes[sym] + readBits(sbytes, stream, lengthExtraBits[sym]);
var sym2 = state.sym2 !== null ? state.sym2 : state.sym2 = readCode(sbytes, stream, distanceTable);
var distance = distanceCodes[sym2] + readBits(sbytes, stream, distanceExtraBits[sym2]);
var i = pos - distance;
while (len--)
dbytes[pos++] = dbytes[i++];
delete state.sym2;
delete state.len;
delete state.sym;
state.sym2 = null;
state.len = null;
state.sym = null;
}
output.available = pos;
sym = readCode(sbytes, stream, literalTable);
@ -5827,7 +5831,7 @@ function readTags(context, stream, swfVersion, final, onprogress, onexception) {
var tag = null;
if (context._readTag) {
tag = context._readTag;
delete context._readTag;
context._readTag = null;
}
try {
while (stream.pos < stream.end) {
@ -5951,7 +5955,14 @@ function CompressedPipe(target, length) {
this.state = {
bitBuffer: 0,
bitLength: 0,
compression: {}
compression: {
header: null,
distanceTable: null,
literalTable: null,
sym: null,
len: null,
sym2: null
}
};
this.output = {
data: new Uint8Array(length),

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
0.8.6
4728574
0.8.271
2717b0c

View File

@ -80,6 +80,11 @@ function fallback() {
FirefoxCom.requestSync('fallback', null)
}
var playerglobalInfo = {
abcs: SHUMWAY_ROOT + "playerglobal/playerglobal.abcs",
catalog: SHUMWAY_ROOT + "playerglobal/playerglobal.json"
};
function runViewer() {
var flashParams = JSON.parse(FirefoxCom.requestSync('getPluginParams', null));
FileLoadingService.setBaseUrl(flashParams.baseUrl);
@ -222,7 +227,7 @@ var FileLoadingService = {
case "open": this.onopen(); break;
case "close":
this.onclose();
delete FileLoadingService.sessions[sessionId];
FileLoadingService.sessions[sessionId] = null;
console.log('Session #' + sessionId +': closed');
break;
case "error":
@ -258,6 +263,9 @@ var FileLoadingService = {
};
function parseSwf(url, movieParams, objectParams) {
var enableVerifier = Shumway.AVM2.Runtime.enableVerifier;
var EXECUTION_MODE = Shumway.AVM2.Runtime.EXECUTION_MODE;
var compilerSettings = JSON.parse(
FirefoxCom.requestSync('getCompilerSettings', null));
enableVerifier.value = compilerSettings.verifier;
@ -274,7 +282,7 @@ function parseSwf(url, movieParams, objectParams) {
FirefoxCom.request('endActivation', null);
}
createAVM2(builtinPath, playerGlobalPath, avm1Path,
createAVM2(builtinPath, playerglobalInfo, avm1Path,
compilerSettings.sysCompiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET,
compilerSettings.appCompiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET,
function (avm2) {

View File

@ -66,13 +66,14 @@ function getBrowserForWindow(aContentWindow) {
function handleRequest(aSubject, aTopic, aData) {
let constraints = aSubject.getConstraints();
let secure = aSubject.isSecure;
let contentWindow = Services.wm.getOuterWindowWithId(aSubject.windowID);
contentWindow.navigator.mozGetUserMediaDevices(
constraints,
function (devices) {
prompt(contentWindow, aSubject.callID, constraints.audio,
constraints.video || constraints.picture, devices);
constraints.video || constraints.picture, devices, secure);
},
function (error) {
// bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND
@ -91,7 +92,7 @@ function denyRequest(aCallID, aError) {
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
}
function prompt(aContentWindow, aCallID, aAudioRequested, aVideoRequested, aDevices) {
function prompt(aContentWindow, aCallID, aAudioRequested, aVideoRequested, aDevices, aSecure) {
let audioDevices = [];
let videoDevices = [];
for (let device of aDevices) {
@ -143,7 +144,8 @@ function prompt(aContentWindow, aCallID, aAudioRequested, aVideoRequested, aDevi
label: stringBundle.getString("getUserMedia.always.label"),
accessKey: stringBundle.getString("getUserMedia.always.accesskey"),
callback: function () {
mainAction.callback(true);
// don't save unless secure load!
mainAction.callback(aSecure);
}
},
{
@ -158,6 +160,8 @@ function prompt(aContentWindow, aCallID, aAudioRequested, aVideoRequested, aDevi
accessKey: stringBundle.getString("getUserMedia.never.accesskey"),
callback: function () {
denyRequest(aCallID);
// Let someone save "Never" for http sites so that they can be stopped from
// bothering you with doorhangers
let perms = Services.perms;
if (audioDevices.length)
perms.add(uri, "microphone", perms.DENY_ACTION);

View File

@ -142,6 +142,8 @@ toolbarseparator {
#PersonalToolbar {
padding: 0 4px 4px;
/* 4px padding ^ plus 19px personal-bookmarks (see below) */
min-height: 23px;
}
#navigator-toolbox > toolbar:not(#TabsToolbar):-moz-lwtheme {
@ -157,7 +159,7 @@ toolbarseparator {
/* ----- BOOKMARK TOOLBAR ----- */
#personal-bookmarks {
min-height: 17px; /* 16px button height + 1px margin-bottom */
min-height: 19px; /* 16px button height + 2px padding + 1px margin-bottom */
}
toolbarbutton.chevron {

View File

@ -23,6 +23,7 @@
#include "mozilla/dom/NodeListBinding.h"
#include "mozilla/Likely.h"
#include "nsGenericHTMLElement.h"
#include "jsfriendapi.h"
#include <algorithm>
// Form related includes
@ -553,8 +554,12 @@ nsContentList::NamedItem(const nsAString& aName, bool aDoFlush)
}
void
nsContentList::GetSupportedNames(nsTArray<nsString>& aNames)
nsContentList::GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames)
{
if (!(aFlags & JSITER_HIDDEN)) {
return;
}
BringSelfUpToDate(true);
nsAutoTArray<nsIAtom*, 8> atoms;

View File

@ -280,7 +280,8 @@ public:
aFound = !!item;
return item;
}
virtual void GetSupportedNames(nsTArray<nsString>& aNames) MOZ_OVERRIDE;
virtual void GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames) MOZ_OVERRIDE;
// nsContentList public methods
NS_HIDDEN_(uint32_t) Length(bool aDoFlush);

View File

@ -217,6 +217,12 @@ nsDOMAttributeMap::NamedGetter(const nsAString& aAttrName, bool& aFound)
return GetAttribute(ni, false);
}
bool
nsDOMAttributeMap::NameIsEnumerable(const nsAString& aName)
{
return true;
}
Attr*
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName)
{

View File

@ -146,6 +146,7 @@ public:
// WebIDL
Attr* GetNamedItem(const nsAString& aAttrName);
Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
bool NameIsEnumerable(const nsAString& aName);
already_AddRefed<Attr>
SetNamedItem(Attr& aAttr, ErrorResult& aError)
{
@ -170,7 +171,7 @@ public:
RemoveNamedItemNS(const nsAString& aNamespaceURI, const nsAString& aLocalName,
ErrorResult& aError);
void GetSupportedNames(nsTArray<nsString>& aNames)
void GetSupportedNames(unsigned, nsTArray<nsString>& aNames)
{
// No supported names we want to show up in iteration.
}

View File

@ -7,8 +7,6 @@
#include "nsIImageLoadingContent.h"
#include "nsExpirationTracker.h"
#include "imgIRequest.h"
#include "gfxASurface.h"
#include "gfxPoint.h"
#include "mozilla/dom/Element.h"
#include "nsTHashtable.h"
#include "mozilla/dom/HTMLCanvasElement.h"

View File

@ -6,6 +6,8 @@
#ifndef CANVASIMAGECACHE_H_
#define CANVASIMAGECACHE_H_
#include "nsSize.h"
namespace mozilla {
namespace dom {
class Element;
@ -16,9 +18,6 @@ class SourceSurface;
} // namespace gfx
} // namespace mozilla
class imgIRequest;
class gfxASurface;
#include "gfxPoint.h"
namespace mozilla {

View File

@ -23,7 +23,6 @@
#include "nsLayoutUtils.h"
#include "GLContextProvider.h"
#include "gfxImageSurface.h"
#include "mozilla/LinkedList.h"
#include "mozilla/CheckedInt.h"

View File

@ -20,7 +20,6 @@
#include "nsString.h"
#include "nsDebug.h"
#include "gfxImageSurface.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "GLContext.h"

View File

@ -929,6 +929,19 @@ WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
{
MOZ_ASSERT(level >= 0, "level should already be validated");
/* Bug 966630: maxTextureSize >> level runs into "undefined"
* behaviour depending on ISA. For example, on Intel shifts
* amounts are mod 64 (in 64-bit mode on 64-bit dest) and mod 32
* otherwise. This means 16384 >> 0x10000001 == 8192 which isn't
* what would be expected. Make the required behaviour explicit by
* clamping to a shift of 31 bits if level is greater than that
* ammount. This will give 0 that if (!maxAllowedSize) is
* expecting.
*/
if (level > 31)
level = 31;
const GLuint maxTexImageSize = MaxTextureSizeForTarget(target) >> level;
const bool isCubemapTarget = IsTexImageCubemapTarget(target);

View File

@ -69,10 +69,15 @@ public:
{
return GetFirstNamedElement(aName, aFound);
}
bool NameIsEnumerable(const nsAString& aName)
{
return false;
}
virtual mozilla::dom::Element*
GetFirstNamedElement(const nsAString& aName, bool& aFound) = 0;
virtual void GetSupportedNames(nsTArray<nsString>& aNames) = 0;
virtual void GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames) = 0;
JSObject* GetWrapperPreserveColor()
{

View File

@ -8,7 +8,6 @@
#include "ImageEncoder.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "gfxImageSurface.h"
#include "Layers.h"
#include "mozilla/Base64.h"
#include "mozilla/CheckedInt.h"

View File

@ -17,6 +17,7 @@
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIFormControl.h"
#include "jsfriendapi.h"
namespace mozilla {
namespace dom {
@ -395,8 +396,13 @@ CollectNames(const nsAString& aName,
}
void
HTMLFormControlsCollection::GetSupportedNames(nsTArray<nsString>& aNames)
HTMLFormControlsCollection::GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames)
{
if (!(aFlags & JSITER_HIDDEN)) {
return;
}
FlushPendingNotifications();
// Just enumerate mNameLookupTable. This won't guarantee order, but
// that's OK, because the HTML5 spec doesn't define an order for

View File

@ -54,7 +54,8 @@ public:
bool dummy;
NamedGetter(aName, dummy, aResult);
}
virtual void GetSupportedNames(nsTArray<nsString>& aNames);
virtual void GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames) MOZ_OVERRIDE;
nsresult AddElementToTable(nsGenericHTMLFormElement* aChild,
const nsAString& aName);

View File

@ -1434,8 +1434,14 @@ HTMLFormElement::NamedGetter(const nsAString& aName, bool &aFound)
return nullptr;
}
bool
HTMLFormElement::NameIsEnumerable(const nsAString& aName)
{
return true;
}
void
HTMLFormElement::GetSupportedNames(nsTArray<nsString >& aRetval)
HTMLFormElement::GetSupportedNames(unsigned, nsTArray<nsString >& aRetval)
{
// TODO https://www.w3.org/Bugs/Public/show_bug.cgi?id=22320
}

View File

@ -395,7 +395,9 @@ public:
already_AddRefed<nsISupports>
NamedGetter(const nsAString& aName, bool &aFound);
void GetSupportedNames(nsTArray<nsString >& aRetval);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(unsigned, nsTArray<nsString >& aRetval);
static int32_t
CompareFormControlPosition(Element* aElement1, Element* aElement2,

View File

@ -28,6 +28,7 @@
#include "nsRuleData.h"
#include "nsServiceManagerUtils.h"
#include "nsStyleConsts.h"
#include "jsfriendapi.h"
namespace mozilla {
namespace dom {
@ -280,8 +281,13 @@ HTMLOptionsCollection::NamedItem(const nsAString& aName,
}
void
HTMLOptionsCollection::GetSupportedNames(nsTArray<nsString>& aNames)
HTMLOptionsCollection::GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames)
{
if (!(aFlags & JSITER_HIDDEN)) {
return;
}
nsAutoTArray<nsIAtom*, 8> atoms;
for (uint32_t i = 0; i < mElements.Length(); ++i) {
HTMLOptionElement* content = mElements.ElementAt(i);

View File

@ -150,7 +150,8 @@ public:
{
aError = SetOption(aIndex, aOption);
}
virtual void GetSupportedNames(nsTArray<nsString>& aNames) MOZ_OVERRIDE;
virtual void GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames) MOZ_OVERRIDE;
private:
/** The list of options (holds strong references). This is infallible, so

View File

@ -297,7 +297,7 @@ HTMLPropertiesCollection::CrawlSubtree(Element* aElement)
}
void
HTMLPropertiesCollection::GetSupportedNames(nsTArray<nsString>& aNames)
HTMLPropertiesCollection::GetSupportedNames(unsigned, nsTArray<nsString>& aNames)
{
EnsureFresh();
mNames->CopyList(aNames);

View File

@ -86,12 +86,17 @@ public:
aFound = IsSupportedNamedProperty(aName);
return aFound ? NamedItem(aName) : nullptr;
}
bool NameIsEnumerable(const nsAString& aName)
{
return true;
}
DOMStringList* Names()
{
EnsureFresh();
return mNames;
}
virtual void GetSupportedNames(nsTArray<nsString>& aNames) MOZ_OVERRIDE;
virtual void GetSupportedNames(unsigned,
nsTArray<nsString>& aNames) MOZ_OVERRIDE;
NS_DECL_NSIDOMHTMLCOLLECTION

View File

@ -12,6 +12,7 @@
#include "mozilla/dom/HTMLCollectionBinding.h"
#include "mozilla/dom/HTMLTableElementBinding.h"
#include "nsContentUtils.h"
#include "jsfriendapi.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
@ -41,7 +42,8 @@ public:
virtual Element*
GetFirstNamedElement(const nsAString& aName, bool& aFound) MOZ_OVERRIDE;
virtual void GetSupportedNames(nsTArray<nsString>& aNames);
virtual void GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames) MOZ_OVERRIDE;
NS_IMETHOD ParentDestroyed();
@ -234,13 +236,18 @@ TableRowsCollection::GetFirstNamedElement(const nsAString& aName, bool& aFound)
}
void
TableRowsCollection::GetSupportedNames(nsTArray<nsString>& aNames)
TableRowsCollection::GetSupportedNames(unsigned aFlags,
nsTArray<nsString>& aNames)
{
if (!(aFlags & JSITER_HIDDEN)) {
return;
}
DO_FOR_EACH_ROWGROUP(
nsTArray<nsString> names;
nsCOMPtr<nsIHTMLCollection> coll = do_QueryInterface(rows);
if (coll) {
coll->GetSupportedNames(names);
coll->GetSupportedNames(aFlags, names);
for (uint32_t i = 0; i < names.Length(); ++i) {
if (!aNames.Contains(names[i])) {
aNames.AppendElement(names[i]);

View File

@ -91,6 +91,12 @@ nsDOMStringMap::NamedGetter(const nsAString& aProp, bool& found,
found = mElement->GetAttr(attr, aResult);
}
bool
nsDOMStringMap::NameIsEnumerable(const nsAString& aName)
{
return true;
}
void
nsDOMStringMap::NamedSetter(const nsAString& aProp,
const nsAString& aValue,
@ -143,7 +149,7 @@ nsDOMStringMap::NamedDeleter(const nsAString& aProp, bool& found)
}
void
nsDOMStringMap::GetSupportedNames(nsTArray<nsString>& aNames)
nsDOMStringMap::GetSupportedNames(unsigned, nsTArray<nsString>& aNames)
{
uint32_t attrCount = mElement->GetAttrCount();

View File

@ -42,7 +42,8 @@ public:
void NamedSetter(const nsAString& aProp, const nsAString& aValue,
mozilla::ErrorResult& rv);
void NamedDeleter(const nsAString& aProp, bool &found);
void GetSupportedNames(nsTArray<nsString>& aNames);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(unsigned, nsTArray<nsString>& aNames);
js::ExpandoAndGeneration mExpandoAndGeneration;

View File

@ -32,14 +32,27 @@ names = [];
for (var name in x) {
names.push(name);
}
is(names.length, 14, "Should have 14 items");
is(names.length, 10, "Should have 10 enumerated names");
is(names[0], "0", "Enum entry 1");
is(names[1], "1", "Enum entry 2");
is(names[2], "2", "Enum entry 3");
is(names[3], "3", "Enum entry 4");
is(names[4], "4", "Enum entry 5");
is(names[5], "something", "Enum entry 6");
is(names[6], "namedItem", "Enum entry 7");
is(names[7], "item", "Enum entry 8");
is(names[8], "@@iterator", "Enum entry 9");
is(names[9], "length", "Enum entry 10");
names = Object.getOwnPropertyNames(x);
is(names.length, 10, "Should have 10 items");
// Now sort entries 5 through 8, for comparison purposes. We don't sort the
// whole array, because we want to make sure the ordering between the parts
// is correct
temp = names.slice(5, 9);
temp.sort();
names.splice.bind(names, 5, 4).apply(null, temp);
is(names.length, 14, "Should have still have 14 items");
is(names.length, 10, "Should still have 10 items");
is(names[0], "0", "Entry 1")
is(names[1], "1", "Entry 2")
is(names[2], "2", "Entry 3")
@ -50,10 +63,6 @@ is(names[6], "x", "Entry 7")
is(names[7], "y", "Entry 8")
is(names[8], "z", "Entry 9")
is(names[9], "something", "Entry 10")
is(names[10], "namedItem", "Entry 11")
is(names[11], "item", "Entry 12")
is(names[12], "@@iterator", "Entry 13")
is(names[13], "length", "Entry 14")
</script>
</pre>
</body>

View File

@ -24,11 +24,23 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=772869
/** Test for Bug 772869 **/
var x = document.getElementsByClassName("foo");
x.something = "another";
names = [];
var names = [];
for (var name in x) {
names.push(name);
}
is(names.length, 13, "Should have 13 items");
is(names.length, 9, "Should have 9 enumerated names");
is(names[0], "0", "Enum entry 1")
is(names[1], "1", "Enum entry 2")
is(names[2], "2", "Enum entry 3")
is(names[3], "3", "Enum entry 4")
is(names[4], "something", "Enum entry 5")
is(names[5], "item", "Enum entry 6")
is(names[6], "namedItem", "Enum entry 7")
is(names[7], "@@iterator", "Enum entry 8")
is(names[8], "length", "Enum entry 9")
names = Object.getOwnPropertyNames(x);
is(names.length, 9, "Should have 9 items");
is(names[0], "0", "Entry 1")
is(names[1], "1", "Entry 2")
is(names[2], "2", "Entry 3")
@ -38,10 +50,6 @@ is(names[5], "y", "Entry 6")
is(names[6], "z", "Entry 7")
is(names[7], "w", "Entry 8")
is(names[8], "something", "Entry 9")
is(names[9], "item", "Entry 10")
is(names[10], "namedItem", "Entry 11")
is(names[11], "@@iterator", "Entry 12")
is(names[12], "length", "Entry 13")
</script>
</pre>
</body>

View File

@ -27,7 +27,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=772869
var opt = $("s").options;
opt.loopy = "something"
var names = Object.getOwnPropertyNames(opt);
is(names.length, 9, "Should have eight entries");
is(names.length, 9, "Should have nine entries");
is(names[0], "0", "Entry 1")
is(names[1], "1", "Entry 2")
is(names[2], "2", "Entry 3")
@ -42,9 +42,19 @@ var names2 = [];
for (var name in opt) {
names2.push(name);
}
for (var i = 0; i < names.length; ++i) {
is(names2[i], names[i], "Correct entry at " + i);
}
is(names2.length, 12, "Should have twelve enumerated names");
is(names2[0], "0", "Enum entry 1")
is(names2[1], "1", "Enum entry 2")
is(names2[2], "2", "Enum entry 3")
is(names2[3], "3", "Enum entry 4")
is(names2[4], "loopy", "Enum entry 5")
is(names2[5], "add", "Enum entrry 6")
is(names2[6], "remove", "Enum entry 7")
is(names2[7], "length", "Enum entry 8")
is(names2[8], "selectedIndex", "Enum entry 9")
is(names2[9], "item", "Enum entry 10")
is(names2[10], "namedItem", "Enum entry 11")
is(names2[11], "@@iterator", "Enum entry 12")
</script>
</pre>

View File

@ -34,11 +34,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=772869
/** Test for Bug 772869 **/
var x = $("f").rows;
x.something = "another";
names = [];
var names = [];
for (var name in x) {
names.push(name);
}
is(names.length, 15, "Should have 15 items");
is(names.length, 11, "Should have 11 enumerated names");
is(names[0], "0", "Enum entry 1")
is(names[1], "1", "Enum entry 2")
is(names[2], "2", "Enum entry 3")
is(names[3], "3", "Enum entry 4")
is(names[4], "4", "Enum entry 5")
is(names[5], "5", "Enum entry 6")
is(names[6], "something", "Enum entry 7")
is(names[7], "item", "Enum entry 8")
is(names[8], "namedItem", "Enum entry 9")
is(names[9], "@@iterator", "Enum entry 10")
is(names[10], "length", "Enum entry 11")
names = Object.getOwnPropertyNames(x);
is(names.length, 11, "Should have 11 items");
is(names[0], "0", "Entry 1")
is(names[1], "1", "Entry 2")
is(names[2], "2", "Entry 3")
@ -50,10 +64,6 @@ is(names[7], "y", "Entry 8")
is(names[8], "z", "Entry 9")
is(names[9], "w", "Entry 10")
is(names[10], "something", "Entry 11")
is(names[11], "item", "Entry 12")
is(names[12], "namedItem", "Entry 13")
is(names[13], "@@iterator", "Entry 14")
is(names[14], "length", "Entry 15")
</script>
</pre>
</body>

View File

@ -2264,6 +2264,12 @@ nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
return &val.toObject();
}
bool
nsHTMLDocument::NameIsEnumerable(const nsAString& aName)
{
return true;
}
static PLDHashOperator
IdentifierMapEntryAddNames(nsIdentifierMapEntry* aEntry, void* aArg)
{
@ -2276,7 +2282,7 @@ IdentifierMapEntryAddNames(nsIdentifierMapEntry* aEntry, void* aArg)
}
void
nsHTMLDocument::GetSupportedNames(nsTArray<nsString>& aNames)
nsHTMLDocument::GetSupportedNames(unsigned, nsTArray<nsString>& aNames)
{
mIdentifierMap.EnumerateEntries(IdentifierMapEntryAddNames, &aNames);
}

View File

@ -174,7 +174,8 @@ public:
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
JSObject* NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
mozilla::ErrorResult& rv);
void GetSupportedNames(nsTArray<nsString>& aNames);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(unsigned, nsTArray<nsString>& aNames);
nsGenericHTMLElement *GetBody();
void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv);
mozilla::dom::HTMLSharedElement *GetHead() {

View File

@ -507,9 +507,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Console)
}
for (uint32_t i = 0; i < data->mArguments.Length(); ++i) {
if (JSVAL_IS_TRACEABLE(data->mArguments[i])) {
aCallbacks.Trace(&data->mArguments[i], "data->mArguments[i]", aClosure);
}
aCallbacks.Trace(&data->mArguments[i], "data->mArguments[i]", aClosure);
}
}

View File

@ -39,11 +39,6 @@ public:
URL(nsIURI* aURI);
// WebIDL methods
nsISupports* GetParentObject() const
{
return nullptr;
}
JSObject*
WrapObject(JSContext* aCx);

View File

@ -168,9 +168,10 @@ WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
}
bool
WindowNamedPropertiesHandler::getOwnPropertyNames(JSContext* aCx,
JS::Handle<JSObject*> aProxy,
JS::AutoIdVector& aProps)
WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
JS::Handle<JSObject*> aProxy,
unsigned flags,
JS::AutoIdVector& aProps)
{
// Grab the DOM window.
nsGlobalWindow* win = GetWindowFromGlobal(JS_GetGlobalForObject(aCx, aProxy));
@ -186,7 +187,7 @@ WindowNamedPropertiesHandler::getOwnPropertyNames(JSContext* aCx,
return true;
}
nsHTMLDocument* document = static_cast<nsHTMLDocument*>(htmlDoc.get());
document->GetSupportedNames(names);
document->GetSupportedNames(flags, names);
JS::AutoIdVector docProps(aCx);
if (!AppendNamedPropertyIds(aCx, aProxy, names, false, docProps)) {

View File

@ -37,8 +37,8 @@ public:
JS::Handle<jsid> aId,
JS::MutableHandle<JSPropertyDescriptor> aDesc) MOZ_OVERRIDE;
virtual bool
getOwnPropertyNames(JSContext* aCx, JS::Handle<JSObject*> aProxy,
JS::AutoIdVector& aProps) MOZ_OVERRIDE;
ownPropNames(JSContext* aCx, JS::Handle<JSObject*> aProxy, unsigned flags,
JS::AutoIdVector& aProps) MOZ_OVERRIDE;
virtual bool
delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
bool* aBp) MOZ_OVERRIDE;

View File

@ -42,7 +42,6 @@
#include "nsViewManager.h"
#include "nsIDOMHTMLCanvasElement.h"
#include "gfxImageSurface.h"
#include "nsLayoutUtils.h"
#include "nsComputedDOMStyle.h"
#include "nsIPresShell.h"

View File

@ -173,6 +173,12 @@ nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound)
return mt;
}
bool
nsMimeTypeArray::NameIsEnumerable(const nsAString& aName)
{
return true;
}
uint32_t
nsMimeTypeArray::Length()
{
@ -182,7 +188,7 @@ nsMimeTypeArray::Length()
}
void
nsMimeTypeArray::GetSupportedNames(nsTArray< nsString >& aRetval)
nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray< nsString >& aRetval)
{
EnsurePluginMimeTypes();

View File

@ -36,8 +36,9 @@ public:
nsMimeType* NamedItem(const nsAString& name);
nsMimeType* IndexedGetter(uint32_t index, bool &found);
nsMimeType* NamedGetter(const nsAString& name, bool &found);
bool NameIsEnumerable(const nsAString& name);
uint32_t Length();
void GetSupportedNames(nsTArray< nsString >& retval);
void GetSupportedNames(unsigned, nsTArray< nsString >& retval);
protected:
void EnsurePluginMimeTypes();

View File

@ -222,6 +222,12 @@ nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
return plugin;
}
bool
nsPluginArray::NameIsEnumerable(const nsAString& aName)
{
return true;
}
uint32_t
nsPluginArray::Length()
{
@ -235,7 +241,7 @@ nsPluginArray::Length()
}
void
nsPluginArray::GetSupportedNames(nsTArray< nsString >& aRetval)
nsPluginArray::GetSupportedNames(unsigned, nsTArray<nsString>& aRetval)
{
aRetval.Clear();
@ -440,6 +446,12 @@ nsPluginElement::NamedGetter(const nsAString& aName, bool &aFound)
return nullptr;
}
bool
nsPluginElement::NameIsEnumerable(const nsAString& aName)
{
return true;
}
uint32_t
nsPluginElement::Length()
{
@ -449,7 +461,7 @@ nsPluginElement::Length()
}
void
nsPluginElement::GetSupportedNames(nsTArray< nsString >& retval)
nsPluginElement::GetSupportedNames(unsigned, nsTArray<nsString>& retval)
{
EnsurePluginMimeTypes();

View File

@ -52,8 +52,9 @@ public:
void Refresh(bool aReloadDocuments);
nsPluginElement* IndexedGetter(uint32_t aIndex, bool &aFound);
nsPluginElement* NamedGetter(const nsAString& aName, bool &aFound);
bool NameIsEnumerable(const nsAString& aName);
uint32_t Length();
void GetSupportedNames(nsTArray< nsString >& aRetval);
void GetSupportedNames(unsigned, nsTArray<nsString>& aRetval);
private:
bool AllowPlugins() const;
@ -101,8 +102,9 @@ public:
nsMimeType* NamedItem(const nsAString& name);
nsMimeType* IndexedGetter(uint32_t index, bool &found);
nsMimeType* NamedGetter(const nsAString& name, bool &found);
bool NameIsEnumerable(const nsAString& aName);
uint32_t Length();
void GetSupportedNames(nsTArray< nsString >& retval);
void GetSupportedNames(unsigned, nsTArray<nsString>& retval);
nsTArray<nsRefPtr<nsMimeType> >& MimeTypes();

View File

@ -779,7 +779,7 @@ class CGTemplatedType(CGWrapper):
const = "const " if isConst else ""
pre = "%s%s<" % (const, templateName)
ref = "&" if isReference else ""
post = " >%s" % ref
post = ">%s" % ref
CGWrapper.__init__(self, child, pre=pre, post=post)
@ -8768,7 +8768,8 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
Argument('unsigned', 'flags')]
ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args)
ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -8847,8 +8848,17 @@ MOZ_ASSERT_IF(desc.object(), desc.object() == ${holder});"""
setOrIndexedGet += getUnforgeable
if self.descriptor.supportsNamedProperties():
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
operations = self.descriptor.operations
readonly = toStringBool(operations['NamedSetter'] is None)
enumerable = (
"self->NameIsEnumerable(Constify(%s))" %
# First [0] means first (and only) signature, [1] means
# "arguments" as opposed to return type, [0] means first (and
# only) argument.
operations['NamedGetter'].signatures()[0][1][0].identifier.name)
fillDescriptor = (
"FillPropertyDescriptor(desc, proxy, %s, %s);\n"
"return true;" % (readonly, enumerable))
templateValues = {'jsvalRef': 'desc.value()', 'jsvalHandle': 'desc.value()',
'obj': 'proxy', 'successCode': fillDescriptor}
condition = "!HasPropertyOnPrototype(cx, proxy, id)"
@ -8946,7 +8956,8 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('bool*', 'bp')]
ClassMethod.__init__(self, "delete_", "bool", args)
ClassMethod.__init__(self, "delete_", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9025,12 +9036,14 @@ return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);"""
return delete
class CGDOMJSProxyHandler_getOwnPropertyNames(ClassMethod):
def __init__(self, descriptor):
class CGDOMJSProxyHandler_ownPropNames(ClassMethod):
def __init__(self, descriptor, ):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('unsigned', 'flags'),
Argument('JS::AutoIdVector&', 'props')]
ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args)
ClassMethod.__init__(self, "ownPropNames", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9055,7 +9068,7 @@ for (int32_t i = 0; i < int32_t(length); ++i) {
shadow = "false"
addNames = """
nsTArray<nsString> names;
UnwrapProxy(proxy)->GetSupportedNames(names);
UnwrapProxy(proxy)->GetSupportedNames(flags, names);
if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
return false;
}
@ -9065,7 +9078,7 @@ if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
if UseHolderForUnforgeable(self.descriptor):
addUnforgeable = (
"if (!js::GetPropertyNames(cx, ${holder}, JSITER_OWNONLY | JSITER_HIDDEN, &props)) {\n"
"if (!js::GetPropertyNames(cx, ${holder}, flags, &props)) {\n"
" return false;\n"
"}")
addUnforgeable = CallOnUnforgeableHolder(self.descriptor,
@ -9077,7 +9090,7 @@ if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
""" + addIndices + addUnforgeable + addNames + """
JS::Rooted<JSObject*> expando(cx);
if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
!js::GetPropertyNames(cx, expando, JSITER_OWNONLY | JSITER_HIDDEN, &props)) {
!js::GetPropertyNames(cx, expando, flags, &props)) {
return false;
}
@ -9090,7 +9103,8 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod):
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('bool*', 'bp')]
ClassMethod.__init__(self, "hasOwn", "bool", args)
ClassMethod.__init__(self, "hasOwn", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9153,7 +9167,8 @@ class CGDOMJSProxyHandler_get(ClassMethod):
Argument('JS::Handle<JSObject*>', 'receiver'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::MutableHandle<JS::Value>', 'vp')]
ClassMethod.__init__(self, "get", "bool", args)
ClassMethod.__init__(self, "get", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9248,7 +9263,8 @@ class CGDOMJSProxyHandler_className(ClassMethod):
class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod):
def __init__(self, descriptor):
args = [Argument('JS::Value', 'priv')]
ClassMethod.__init__(self, "finalizeInBackground", "bool", args)
ClassMethod.__init__(self, "finalizeInBackground", "bool", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9258,7 +9274,8 @@ class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod):
class CGDOMJSProxyHandler_finalize(ClassMethod):
def __init__(self, descriptor):
args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
ClassMethod.__init__(self, "finalize", "void", args)
ClassMethod.__init__(self, "finalize", "void", args,
virtual=True, override=True)
self.descriptor = descriptor
def getBody(self):
@ -9334,7 +9351,7 @@ class CGDOMJSProxyHandler(CGClass):
CGDOMJSProxyHandler_defineProperty(descriptor),
ClassUsingDeclaration("mozilla::dom::DOMProxyHandler",
"defineProperty"),
CGDOMJSProxyHandler_getOwnPropertyNames(descriptor),
CGDOMJSProxyHandler_ownPropNames(descriptor),
CGDOMJSProxyHandler_hasOwn(descriptor),
CGDOMJSProxyHandler_get(descriptor),
CGDOMJSProxyHandler_className(descriptor),
@ -11121,7 +11138,7 @@ class CGBindingImplClass(CGClass):
[]),
{"infallible": True}))
# And if we support named properties we need to be able to
# enumerate the supported names.
# enumerate the supported names and test whether they're enumerable.
if descriptor.supportsNamedProperties():
self.methodDecls.append(
CGNativeMember(
@ -11129,8 +11146,21 @@ class CGBindingImplClass(CGClass):
"GetSupportedNames",
(IDLSequenceType(None,
BuiltinTypes[IDLBuiltinType.Types.domstring]),
[]),
# Let's use unsigned long for the type here, though really
# it's just a C++ "unsigned"...
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
FakeMember(),
name="aFlags")]),
{"infallible": True}))
self.methodDecls.append(
CGNativeMember(
descriptor, FakeMember(),
"NameIsEnumerable",
(BuiltinTypes[IDLBuiltinType.Types.boolean],
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.domstring],
FakeMember(),
name="aName")]),
{ "infallible": True }))
wrapArgs = [Argument('JSContext*', 'aCx')]
self.methodDecls.insert(0,
@ -11168,7 +11198,9 @@ class CGExampleClass(CGBindingImplClass):
Codegen for the actual example class implementation for this descriptor
"""
def __init__(self, descriptor):
CGBindingImplClass.__init__(self, descriptor, CGExampleMethod, CGExampleGetter, CGExampleSetter)
CGBindingImplClass.__init__(self, descriptor,
CGExampleMethod, CGExampleGetter, CGExampleSetter,
wantGetParent=descriptor.wrapperCache)
self.refcounted = descriptor.nativeOwnership == "refcounted"

View File

@ -234,7 +234,7 @@ BaseDOMProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
if (!JS_GetPrototype(cx, proxy, &proto)) {
return false;
}
return getOwnPropertyNames(cx, proxy, props) &&
return keys(cx, proxy, props) &&
(!proto || js::GetPropertyNames(cx, proto, 0, &props));
}
@ -251,6 +251,22 @@ BaseDOMProxyHandler::unwatch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Han
return js::UnwatchGuts(cx, proxy, id);
}
bool
BaseDOMProxyHandler::getOwnPropertyNames(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props)
{
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props);
}
bool
BaseDOMProxyHandler::keys(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props)
{
return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
}
bool
DOMProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp)
{

View File

@ -57,6 +57,22 @@ public:
JS::Handle<JSObject*> callable) MOZ_OVERRIDE;
bool unwatch(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) MOZ_OVERRIDE;
virtual bool getOwnPropertyNames(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) MOZ_OVERRIDE;
// We override keys() and implement it directly instead of using the
// default implementation, which would getOwnPropertyNames and then
// filter out the non-enumerable ones. This avoids doing
// unnecessary work during enumeration.
virtual bool keys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) MOZ_OVERRIDE;
protected:
// Hook for subclasses to implement shared getOwnPropertyNames()/keys()
// functionality. The "flags" argument is either JSITER_OWNONLY (for keys())
// or JSITER_OWNONLY | JSITER_HIDDEN (for getOwnPropertyNames()).
virtual bool ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy,
unsigned flags,
JS::AutoIdVector& props) = 0;
};
class DOMProxyHandler : public BaseDOMProxyHandler
@ -139,20 +155,23 @@ IsArrayIndex(int32_t index)
}
inline void
FillPropertyDescriptor(JS::MutableHandle<JSPropertyDescriptor> desc, JSObject* obj, bool readonly)
FillPropertyDescriptor(JS::MutableHandle<JSPropertyDescriptor> desc,
JSObject* obj, bool readonly, bool enumerable = true)
{
desc.object().set(obj);
desc.setAttributes((readonly ? JSPROP_READONLY : 0) | JSPROP_ENUMERATE);
desc.setAttributes((readonly ? JSPROP_READONLY : 0) |
(enumerable ? JSPROP_ENUMERATE : 0));
desc.setGetter(nullptr);
desc.setSetter(nullptr);
}
inline void
FillPropertyDescriptor(JS::MutableHandle<JSPropertyDescriptor> desc, JSObject* obj, JS::Value v,
bool readonly)
FillPropertyDescriptor(JS::MutableHandle<JSPropertyDescriptor> desc,
JSObject* obj, JS::Value v,
bool readonly, bool enumerable = true)
{
desc.value().set(v);
FillPropertyDescriptor(desc, obj, readonly);
FillPropertyDescriptor(desc, obj, readonly, enumerable);
}
inline void

View File

@ -989,7 +989,8 @@ public:
virtual nsISupports* GetParentObject();
void NamedGetter(const nsAString&, bool&, nsAString&);
void GetSupportedNames(nsTArray<nsString>&);
bool NameIsEnumerable(const nsAString&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestIndexedGetterAndSetterAndNamedGetterInterface : public nsISupports,
@ -1002,7 +1003,8 @@ public:
virtual nsISupports* GetParentObject();
void NamedGetter(const nsAString&, bool&, nsAString&);
void GetSupportedNames(nsTArray<nsString>&);
bool NameIsEnumerable(const nsAString&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
int32_t IndexedGetter(uint32_t, bool&);
void IndexedSetter(uint32_t, int32_t);
uint32_t Length();
@ -1019,9 +1021,10 @@ public:
uint32_t IndexedGetter(uint32_t, bool&);
void NamedGetter(const nsAString&, bool&, nsAString&);
bool NameIsEnumerable(const nsAString&);
void NamedItem(const nsAString&, nsAString&);
uint32_t Length();
void GetSupportedNames(nsTArray<nsString>&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestIndexedSetterInterface : public nsISupports,
@ -1050,7 +1053,8 @@ public:
void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
TestIndexedSetterInterface* NamedGetter(const nsAString&, bool&);
void GetSupportedNames(nsTArray<nsString>&);
bool NameIsEnumerable(const nsAString&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestIndexedAndNamedSetterInterface : public nsISupports,
@ -1067,8 +1071,9 @@ public:
uint32_t Length();
void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
TestIndexedSetterInterface* NamedGetter(const nsAString&, bool&);
bool NameIsEnumerable(const nsAString&);
void SetNamedItem(const nsAString&, TestIndexedSetterInterface&);
void GetSupportedNames(nsTArray<nsString>&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestIndexedAndNamedGetterAndSetterInterface : public TestIndexedSetterInterface
@ -1077,13 +1082,14 @@ public:
uint32_t IndexedGetter(uint32_t, bool&);
uint32_t Item(uint32_t);
void NamedGetter(const nsAString&, bool&, nsAString&);
bool NameIsEnumerable(const nsAString&);
void NamedItem(const nsAString&, nsAString&);
void IndexedSetter(uint32_t, int32_t&);
void IndexedSetter(uint32_t, const nsAString&) MOZ_DELETE;
void NamedSetter(const nsAString&, const nsAString&);
void Stringify(nsAString&);
uint32_t Length();
void GetSupportedNames(nsTArray<nsString>&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestCppKeywordNamedMethodsInterface : public nsISupports,
@ -1145,7 +1151,8 @@ public:
void NamedDeleter(const nsAString&, bool&);
long NamedGetter(const nsAString&, bool&);
void GetSupportedNames(nsTArray<nsString>&);
bool NameIsEnumerable(const nsAString&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestNamedDeleterWithRetvalInterface : public nsISupports,
@ -1160,9 +1167,10 @@ public:
bool NamedDeleter(const nsAString&, bool&);
bool NamedDeleter(const nsAString&) MOZ_DELETE;
long NamedGetter(const nsAString&, bool&);
bool NameIsEnumerable(const nsAString&);
bool DelNamedItem(const nsAString&);
bool DelNamedItem(const nsAString&, bool&) MOZ_DELETE;
void GetSupportedNames(nsTArray<nsString>&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestIndexedAndNamedDeleterInterface : public nsISupports,
@ -1181,9 +1189,10 @@ public:
void NamedDeleter(const nsAString&, bool&);
void NamedDeleter(const nsAString&) MOZ_DELETE;
long NamedGetter(const nsAString&, bool&);
bool NameIsEnumerable(const nsAString&);
void DelNamedItem(const nsAString&);
void DelNamedItem(const nsAString&, bool&) MOZ_DELETE;
void GetSupportedNames(nsTArray<nsString>&);
void GetSupportedNames(unsigned, nsTArray<nsString>&);
};
class TestParentInterface : public nsISupports,

View File

@ -35,6 +35,7 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure; bug 926547
[test_lenientThis.html]
[test_lookupGetter.html]
[test_namedNoIndexed.html]
[test_named_getter_enumerability.html]
[test_Object.prototype_props.html]
[test_queryInterface.html]
[test_sequence_wrapping.html]

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for named getter enumerability</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var list = document.getElementsByTagName("div");
var desc = Object.getOwnPropertyDescriptor(list, "0");
assert_equals(typeof desc, "object", "Should have a '0' property");
assert_true(desc.enumerable, "'0' property should be enumerable");
desc = Object.getOwnPropertyDescriptor(list, "log");
assert_equals(typeof desc, "object", "Should have a 'log' property");
assert_false(desc.enumerable, "'log' property should not be enumerable");
}, "Correct getOwnPropertyDescriptor behavior");
test(function() {
var list = document.getElementsByTagName("div");
props = [];
for (var prop in list) {
props.push(prop);
}
assert_not_equals(props.indexOf("0"), -1, "Should enumerate '0'");
assert_equals(props.indexOf("log"), -1, "Should not enumerate 'log'");
}, "Correct enumeration behavior");
test(function() {
var list = document.getElementsByTagName("div");
props = Object.keys(list)
assert_not_equals(props.indexOf("0"), -1, "Keys should contain '0'");
assert_equals(props.indexOf("log"), -1, "Keys should not contain 'log'");
}, "Correct keys() behavior");
test(function() {
var list = document.getElementsByTagName("div");
props = Object.getOwnPropertyNames(list)
assert_not_equals(props.indexOf("0"), -1,
"own prop names should contain '0'");
assert_not_equals(props.indexOf("log"), -1,
"own prop names should contain 'log'");
}, "Correct getOwnPropertyNames() behavior");
</script>

View File

@ -84,7 +84,6 @@ function getErrorClass(errorCode) {
switch (NSPRCode) {
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:

View File

@ -51,12 +51,6 @@ public:
return TextDecoderBinding::Wrap(aCx, this, aTookOwnership);
}
nsISupports*
GetParentObject()
{
return nullptr;
}
/**
* Validates provided label and throws an exception if invalid label.
*

View File

@ -46,12 +46,6 @@ public:
return TextEncoderBinding::Wrap(aCx, this, aTookOwnership);
}
nsISupports*
GetParentObject()
{
return nullptr;
}
JSObject* Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,

View File

@ -21,11 +21,6 @@ public:
DeviceRotationRate(DeviceMotionEvent* aOwner,
Nullable<double> aAlpha, Nullable<double> aBeta,
Nullable<double> aGamma);
DeviceRotationRate(double aAlpha, double aBeta, double aGamma)
{
DeviceRotationRate(nullptr, Nullable<double>(aAlpha),
Nullable<double>(aBeta), Nullable<double>(aGamma));
}
DeviceMotionEvent* GetParentObject() const
{
@ -58,11 +53,6 @@ public:
DeviceAcceleration(DeviceMotionEvent* aOwner,
Nullable<double> aX, Nullable<double> aY,
Nullable<double> aZ);
DeviceAcceleration(double aX, double aY, double aZ)
{
DeviceAcceleration(nullptr, Nullable<double>(aX),
Nullable<double>(aY), Nullable<double>(aZ));
}
DeviceMotionEvent* GetParentObject() const
{

View File

@ -64,10 +64,15 @@ test(function() {
assert_array_equals(Object.getOwnPropertyNames(list).sort(), ["0", "x"]);
var desc = Object.getOwnPropertyDescriptor(list, 'x');
var desc = Object.getOwnPropertyDescriptor(list, '0');
assert_equals(typeof desc, "object", "descriptor should be an object");
assert_true(desc.enumerable, "desc.enumerable");
assert_true(desc.configurable, "desc.configurable");
desc = Object.getOwnPropertyDescriptor(list, 'x');
assert_equals(typeof desc, "object", "descriptor should be an object");
assert_false(desc.enumerable, "desc.enumerable");
assert_true(desc.configurable, "desc.configurable");
}, "hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames")
test(function() {

View File

@ -20,6 +20,8 @@ test(function() {
result.push(p);
}
}
assert_array_equals(result, ['0', '1', '2']);
result = Object.getOwnPropertyNames(list);
assert_array_equals(result, ['0', '1', '2', 'foo']);
});
</script>

View File

@ -36,7 +36,6 @@ interface nsIDOMWindow;
interface nsIDOMBlob;
interface nsIDOMFile;
interface nsIFile;
interface nsIDOMTouch;
interface nsIDOMClientRect;
interface nsIURI;
interface nsIDOMEventTarget;

View File

@ -10,26 +10,6 @@
%}
interface nsIVariant;
/**
* @see http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
*/
[scriptable, builtinclass, uuid(2311671f-ff7e-43d2-adfb-d9e07006955e)]
interface nsIDOMTouch : nsISupports {
readonly attribute long identifier;
readonly attribute nsIDOMEventTarget target;
readonly attribute long pageX;
readonly attribute long pageY;
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute long radiusX;
readonly attribute long radiusY;
readonly attribute float rotationAngle;
readonly attribute float force;
};
[scriptable, uuid(6d5484f7-92ac-45f8-9388-39b5bad055ce)]
interface nsITouchEventReceiver : nsISupports {
[implicit_jscontext] attribute jsval ontouchstart;

View File

@ -16,11 +16,13 @@ namespace dom {
GetUserMediaRequest::GetUserMediaRequest(
nsPIDOMWindow* aInnerWindow,
const nsAString& aCallID,
const MediaStreamConstraintsInternal& aConstraints)
const MediaStreamConstraintsInternal& aConstraints,
bool aIsSecure)
: mInnerWindowID(aInnerWindow->WindowID())
, mOuterWindowID(aInnerWindow->GetOuterWindow()->WindowID())
, mCallID(aCallID)
, mConstraints(new MediaStreamConstraintsInternal(aConstraints))
, mIsSecure(aIsSecure)
{
SetIsDOMBinding();
}
@ -59,6 +61,11 @@ uint64_t GetUserMediaRequest::InnerWindowID()
return mInnerWindowID;
}
bool GetUserMediaRequest::IsSecure()
{
return mIsSecure;
}
void
GetUserMediaRequest::GetConstraints(MediaStreamConstraintsInternal &result)
{

View File

@ -21,7 +21,8 @@ class GetUserMediaRequest : public nsISupports, public nsWrapperCache
public:
GetUserMediaRequest(nsPIDOMWindow* aInnerWindow,
const nsAString& aCallID,
const MediaStreamConstraintsInternal& aConstraints);
const MediaStreamConstraintsInternal& aConstraints,
bool aIsSecure);
virtual ~GetUserMediaRequest() {};
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -33,6 +34,7 @@ public:
uint64_t WindowID();
uint64_t InnerWindowID();
bool IsSecure();
void GetCallID(nsString& retval);
void GetConstraints(MediaStreamConstraintsInternal &result);
@ -40,6 +42,7 @@ private:
uint64_t mInnerWindowID, mOuterWindowID;
const nsString mCallID;
nsAutoPtr<MediaStreamConstraintsInternal> mConstraints;
bool mIsSecure;
};
} // namespace dom

View File

@ -1459,6 +1459,12 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
(c.mFake && !Preferences::GetBool("media.navigator.permission.fake"))) {
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} else {
bool isHTTPS = false;
nsIURI* docURI = aWindow->GetDocumentURI();
if (docURI) {
docURI->SchemeIs("https", &isHTTPS);
}
// Check if this site has persistent permissions.
nsresult rv;
nsCOMPtr<nsIPermissionManager> permManager =
@ -1473,6 +1479,11 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
if (audioPerm == nsIPermissionManager::PROMPT_ACTION) {
audioPerm = nsIPermissionManager::UNKNOWN_ACTION;
}
if (audioPerm == nsIPermissionManager::ALLOW_ACTION) {
if (!isHTTPS) {
audioPerm = nsIPermissionManager::UNKNOWN_ACTION;
}
}
}
uint32_t videoPerm = nsIPermissionManager::UNKNOWN_ACTION;
@ -1483,9 +1494,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
if (videoPerm == nsIPermissionManager::PROMPT_ACTION) {
videoPerm = nsIPermissionManager::UNKNOWN_ACTION;
}
if (videoPerm == nsIPermissionManager::ALLOW_ACTION) {
if (!isHTTPS) {
videoPerm = nsIPermissionManager::UNKNOWN_ACTION;
}
}
}
if ((!IsOn(c.mAudio) || audioPerm) && (!IsOn(c.mVideo) || videoPerm)) {
if ((!IsOn(c.mAudio) || audioPerm != nsIPermissionManager::UNKNOWN_ACTION) &&
(!IsOn(c.mVideo) || videoPerm != nsIPermissionManager::UNKNOWN_ACTION)) {
// All permissions we were about to request already have a saved value.
if (IsOn(c.mAudio) && audioPerm == nsIPermissionManager::DENY_ACTION) {
c.mAudio.SetAsBoolean() = false;
@ -1533,7 +1550,7 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
nsRefPtr<GetUserMediaRequest> req = new GetUserMediaRequest(aWindow,
callID, c);
callID, c, isHTTPS);
obs->NotifyObservers(req, "getUserMedia:request", nullptr);
}

View File

@ -15,7 +15,6 @@
#include "nsError.h"
#include "mozilla/EventForwards.h"
class gfxASurface;
class gfxContext;
class nsCString;
struct nsIntRect;

View File

@ -12,4 +12,5 @@ interface GetUserMediaRequest {
readonly attribute unsigned long long innerWindowID;
readonly attribute DOMString callID;
MediaStreamConstraintsInternal getConstraints();
readonly attribute boolean isSecure;
};

View File

@ -322,6 +322,8 @@ GfxPatternToCairoPattern(const Pattern& aPattern, Float aAlpha)
{
const SurfacePattern& pattern = static_cast<const SurfacePattern&>(aPattern);
cairo_surface_t* surf = GetCairoSurfaceForSourceSurface(pattern.mSurface);
if (!surf)
return nullptr;
pat = cairo_pattern_create_for_surface(surf);
@ -331,7 +333,6 @@ GfxPatternToCairoPattern(const Pattern& aPattern, Float aAlpha)
cairo_pattern_set_extend(pat, GfxExtendToCairoExtend(pattern.mExtendMode));
cairo_surface_destroy(surf);
break;
}
case PatternType::LINEAR_GRADIENT:
@ -578,7 +579,7 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
if (aSurface->GetType() != SurfaceType::CAIRO) {
return;
}
AutoClearDeviceOffset clear(aSurface);
Float width = Float(aSurface->GetSize().width);
@ -650,10 +651,13 @@ DrawTargetCairo::DrawPattern(const Pattern& aPattern,
if (!PatternIsCompatible(aPattern)) {
return;
}
AutoClearDeviceOffset clear(aPattern);
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
if (!pat)
return;
cairo_set_source(mContext, pat);
cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
@ -883,6 +887,9 @@ DrawTargetCairo::FillGlyphs(ScaledFont *aFont,
cairo_set_scaled_font(mContext, scaledFont->GetCairoScaledFont());
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
if (!pat)
return;
cairo_set_source(mContext, pat);
cairo_pattern_destroy(pat);
@ -911,9 +918,16 @@ DrawTargetCairo::Mask(const Pattern &aSource,
cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
cairo_pattern_t* source = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
cairo_set_source(mContext, source);
if (!source)
return;
cairo_pattern_t* mask = GfxPatternToCairoPattern(aMask, aOptions.mAlpha);
if (!mask) {
cairo_pattern_destroy(source);
return;
}
cairo_set_source(mContext, source);
cairo_mask(mContext, mask);
cairo_pattern_destroy(mask);
@ -937,6 +951,9 @@ DrawTargetCairo::MaskSurface(const Pattern &aSource,
cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
cairo_pattern_t* pat = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
if (!pat)
return;
cairo_set_source(mContext, pat);
if (NeedIntermediateSurface(aSource, aOptions)) {
@ -1011,7 +1028,7 @@ DrawTargetCairo::PopClip()
cairo_set_matrix(mContext, &mat);
MOZ_ASSERT(GetTransform() == Matrix(mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0),
MOZ_ASSERT(cairo_status(mContext) || GetTransform() == Matrix(mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0),
"Transforms are out of sync");
}

View File

@ -6,6 +6,9 @@
#include <initguid.h>
#include "DrawTargetD2D.h"
#include "SourceSurfaceD2D.h"
#ifdef USE_D2D1_1
#include "SourceSurfaceD2D1.h"
#endif
#include "SourceSurfaceD2DTarget.h"
#include "ShadersD2D.h"
#include "PathD2D.h"
@ -318,6 +321,24 @@ DrawTargetD2D::GetBitmapForSurface(SourceSurface *aSurface,
return bitmap;
}
#ifdef USE_D2D1_1
TemporaryRef<ID2D1Image>
DrawTargetD2D::GetImageForSurface(SourceSurface *aSurface)
{
RefPtr<ID2D1Image> image;
if (aSurface->GetType() == SurfaceType::D2D1_1_IMAGE) {
image = static_cast<SourceSurfaceD2D1*>(aSurface)->GetImage();
static_cast<SourceSurfaceD2D1*>(aSurface)->EnsureIndependent();
} else {
Rect r(Point(), Size(aSurface->GetSize()));
image = GetBitmapForSurface(aSurface, r);
}
return image;
}
#endif
void
DrawTargetD2D::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,

View File

@ -139,6 +139,10 @@ public:
TemporaryRef<ID2D1Layer> GetCachedLayer();
void PopCachedLayer(ID2D1RenderTarget *aRT);
#ifdef USE_D2D1_1
TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface);
#endif
static ID2D1Factory *factory();
static void CleanupD2D();
static IDWriteFactory *GetDWriteFactory();

View File

@ -128,29 +128,15 @@ D2D1_CHANNEL_SELECTOR D2DChannelSelector(uint32_t aMode)
TemporaryRef<ID2D1Image> GetImageForSourceSurface(DrawTarget *aDT, SourceSurface *aSurface)
{
if (aDT->GetType() == BackendType::DIRECT2D1_1) {
return static_cast<DrawTargetD2D1*>(aDT)->GetImageForSurface(aSurface, ExtendMode::CLAMP);
switch (aDT->GetType()) {
case BackendType::DIRECT2D1_1:
return static_cast<DrawTargetD2D1*>(aDT)->GetImageForSurface(aSurface, ExtendMode::CLAMP);
case BackendType::DIRECT2D:
return static_cast<DrawTargetD2D*>(aDT)->GetImageForSurface(aSurface);
default:
MOZ_CRASH("Unknown draw target type!");
return nullptr;
}
RefPtr<ID2D1Image> image;
switch (aSurface->GetType()) {
case SurfaceType::D2D1_1_IMAGE:
image = static_cast<SourceSurfaceD2D1*>(aSurface)->GetImage();
static_cast<SourceSurfaceD2D1*>(aSurface)->EnsureIndependent();
break;
case SurfaceType::D2D1_BITMAP:
image = static_cast<SourceSurfaceD2D*>(aSurface)->GetBitmap();
break;
case SurfaceType::D2D1_DRAWTARGET: {
SourceSurfaceD2DTarget *surf = static_cast<SourceSurfaceD2DTarget*>(aSurface);
image = surf->GetBitmap(static_cast<DrawTargetD2D*>(aDT)->GetRT());
}
break;
default:
gfxWarning() << "Unknown input SourceSurface set on effect.";
MOZ_ASSERT(0);
}
return image;
}
uint32_t ConvertValue(FilterType aType, uint32_t aAttribute, uint32_t aValue)

View File

@ -43,7 +43,6 @@ typedef IOSurfacePtr (*IOSurfaceContextGetSurfaceFunc)(CGContextRef ref);
#include "2D.h"
#include "mozilla/RefPtr.h"
class gfxASurface;
struct _CGLContextObject;
typedef _CGLContextObject* CGLContextObj;

View File

@ -27,7 +27,6 @@
#include "GLDefs.h"
#include "GLLibraryLoader.h"
#include "gfxImageSurface.h"
#include "gfx3DMatrix.h"
#include "nsISupportsImpl.h"
#include "plstr.h"
@ -2524,6 +2523,8 @@ public:
return MakeCurrentImpl(aForce);
}
virtual bool Init() = 0;
virtual bool SetupLookupFunction() = 0;
virtual void ReleaseSurface() {}

View File

@ -42,7 +42,7 @@ public:
return static_cast<GLContextCGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
NSOpenGLContext* GetNSOpenGLContext() const { return mContext; }
CGLContextObj GetCGLContext() const;

View File

@ -46,7 +46,7 @@ public:
return static_cast<GLContextEGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool IsDoubleBuffered() const MOZ_OVERRIDE {
return mIsDoubleBuffered;
@ -117,6 +117,7 @@ protected:
#ifdef MOZ_WIDGET_GONK
nsRefPtr<HwcComposer2D> mHwc;
#endif
bool mOwnsContext;
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
EGLenum bindToTextureFormat,

View File

@ -36,7 +36,7 @@ public:
return static_cast<GLContextGLX*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool MakeCurrentImpl(bool aForce) MOZ_OVERRIDE;
@ -72,6 +72,7 @@ private:
GLXLibrary* mGLX;
nsRefPtr<gfxXlibSurface> mPixmap;
bool mOwnsContext;
};
}

View File

@ -7,13 +7,12 @@
#define GLCONTEXTPROVIDER_H_
#include "GLContextTypes.h"
#include "gfxTypes.h"
#include "gfxPoint.h"
#include "nsAutoPtr.h"
#include "SurfaceTypes.h"
#include "nsSize.h" // for gfxIntSize (needed by GLContextProviderImpl.h below)
class nsIWidget;
class gfxASurface;
namespace mozilla {
namespace gl {

View File

@ -9,9 +9,6 @@
#include "nsDebug.h"
#include "nsIWidget.h"
#include <OpenGL/gl.h>
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "gfxQuartzSurface.h"
#include "gfxPrefs.h"
#include "gfxFailure.h"
#include "prenv.h"
@ -189,13 +186,15 @@ GetGlobalContextCGL()
return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
GLContextCGL *shareContext = GetGlobalContextCGL();
NSOpenGLContext *context = [[NSOpenGLContext alloc]

View File

@ -100,7 +100,6 @@ public:
#include "gfxUtils.h"
#include "gfxFailure.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "GLContextProvider.h"
#include "GLLibraryEGL.h"
@ -234,6 +233,7 @@ GLContextEGL::GLContextEGL(
, mIsDoubleBuffered(false)
, mCanBindToTexture(false)
, mShareWithEGLImage(false)
, mOwnsContext(true)
{
// any EGL contexts will always be GLESv2
SetProfileVersion(ContextProfile::OpenGLES, 200);
@ -258,6 +258,11 @@ GLContextEGL::~GLContextEGL()
{
MarkDestroyed();
// Wrapped context should not destroy eglContext/Surface
if (!mOwnsContext) {
return;
}
#ifdef DEBUG
printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
@ -410,6 +415,9 @@ GLContextEGL::IsCurrent() {
bool
GLContextEGL::RenewSurface() {
if (!mOwnsContext) {
return false;
}
#ifndef MOZ_WIDGET_ANDROID
MOZ_CRASH("unimplemented");
// to support this on non-Android platforms, need to keep track of the nsIWidget that
@ -430,7 +438,9 @@ GLContextEGL::RenewSurface() {
void
GLContextEGL::ReleaseSurface() {
DestroySurface(mSurface);
if (mOwnsContext) {
DestroySurface(mSurface);
}
mSurface = EGL_NO_SURFACE;
}
@ -682,6 +692,31 @@ CreateConfig(EGLConfig* aConfig)
}
}
already_AddRefed<GLContext>
GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
{
if (!sEGLLibrary.EnsureInitialized()) {
MOZ_CRASH("Failed to load EGL library!\n");
return nullptr;
}
if (aContext && aSurface) {
SurfaceCaps caps = SurfaceCaps::Any();
EGLConfig config = EGL_NO_CONFIG;
nsRefPtr<GLContextEGL> glContext =
new GLContextEGL(caps,
nullptr, false,
config, (EGLSurface)aSurface, (EGLContext)aContext);
glContext->SetIsDoubleBuffered(true);
glContext->mOwnsContext = false;
return glContext.forget();
}
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
{

View File

@ -26,7 +26,6 @@
#include "GLXLibrary.h"
#include "gfxXlibSurface.h"
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "GLContextGLX.h"
#include "gfxUtils.h"
@ -825,6 +824,11 @@ GLContextGLX::~GLContextGLX()
{
MarkDestroyed();
// Wrapped context should not destroy glxContext/Surface
if (!mOwnsContext) {
return;
}
// see bug 659842 comment 76
#ifdef DEBUG
bool success =
@ -924,7 +928,8 @@ GLContextGLX::GLContextGLX(
mDeleteDrawable(aDeleteDrawable),
mDoubleBuffered(aDoubleBuffered),
mGLX(&sGLXLibrary),
mPixmap(aPixmap)
mPixmap(aPixmap),
mOwnsContext(true)
{
MOZ_ASSERT(mGLX);
// See 899855
@ -958,6 +963,36 @@ AreCompatibleVisuals(Visual *one, Visual *two)
return true;
}
static StaticRefPtr<GLContext> gGlobalContext;
already_AddRefed<GLContext>
GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface)
{
if (!sGLXLibrary.EnsureInitialized()) {
return nullptr;
}
if (aContext && aSurface) {
SurfaceCaps caps = SurfaceCaps::Any();
nsRefPtr<GLContextGLX> glContext =
new GLContextGLX(caps,
nullptr, // SharedContext
false, // Offscreen
(Display*)DefaultXDisplay(), // Display
(GLXDrawable)aSurface, (GLXContext)aContext,
false, // aDeleteDrawable,
true,
(gfxXlibSurface*)nullptr);
glContext->mOwnsContext = false;
gGlobalContext = glContext;
return glContext.forget();
}
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
{
@ -973,6 +1008,11 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
// is a relatively safe intermediate step.
Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY);
if (!display) {
NS_ERROR("X Display required for GLX Context provider");
return nullptr;
}
int xscreen = DefaultScreen(display);
Window window = GET_NATIVE_WINDOW(aWidget);
@ -1189,8 +1229,6 @@ GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
return glContext.forget();
}
static StaticRefPtr<GLContext> gGlobalContext;
GLContext*
GLContextProviderGLX::GetGlobalContext()
{

View File

@ -61,6 +61,17 @@ public:
CreateOffscreen(const gfxIntSize& size,
const SurfaceCaps& caps);
/**
* Create wrapping Gecko GLContext for external gl context.
*
* @param aContext External context which will be wrapped by Gecko GLContext.
* @param aSurface External surface which is used for external context.
*
* @return Wrapping Context to use for rendering
*/
static already_AddRefed<GLContext>
CreateWrappingExisting(void* aContext, void* aSurface);
/**
* Get a pointer to the global context, creating it if it doesn't exist.
*/

View File

@ -14,6 +14,12 @@ GLContextProviderNull::CreateForWindow(nsIWidget*)
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderNull::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
const SurfaceCaps&,

View File

@ -8,8 +8,6 @@
#include "GLLibraryLoader.h"
#include "nsDebug.h"
#include "nsIWidget.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "gfxWindowsSurface.h"
@ -400,6 +398,12 @@ GetGlobalContextWGL()
return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
}
already_AddRefed<GLContext>
GLContextProviderWGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
{

View File

@ -43,7 +43,7 @@ public:
return static_cast<GLContextWGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool MakeCurrentImpl(bool aForce) MOZ_OVERRIDE;

View File

@ -9,6 +9,7 @@
#include "OGLShaderProgram.h"
#include "gfxTypes.h"
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "ScopedGLHelpers.h"
#include "mozilla/gfx/2D.h"
#include "gfx2DGlue.h"

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