--HG--
rename : xpcom/ds/CheckedInt.h => mfbt/CheckedInt.h
This commit is contained in:
David Anderson 2012-05-16 15:39:10 -07:00
Родитель 697d029d7f 32b77ac8c5
Коммит 693dcc5c78
180 изменённых файлов: 6084 добавлений и 2516 удалений

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

@ -177,7 +177,7 @@ EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
endif
SYMBOL_INDEX_NAME = \
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
buildsymbols:
ifdef MOZ_CRASHREPORTER

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

@ -88,9 +88,6 @@ nsHTMLSelectListAccessible::NativeState()
role
nsHTMLSelectListAccessible::NativeRole()
{
if (mParent && mParent->Role() == roles::COMBOBOX)
return roles::COMBOBOX_LIST;
return roles::LISTBOX;
}
@ -710,6 +707,12 @@ nsHTMLComboboxListAccessible::IsPrimaryForNode() const
////////////////////////////////////////////////////////////////////////////////
// nsHTMLComboboxAccessible: nsAccessible
role
nsHTMLComboboxListAccessible::NativeRole()
{
return roles::COMBOBOX_LIST;
}
PRUint64
nsHTMLComboboxListAccessible::NativeState()
{

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

@ -258,6 +258,7 @@ public:
virtual bool IsPrimaryForNode() const;
// nsAccessible
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);

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

@ -199,6 +199,21 @@ var AccessFu = {
QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
let event = aEvent.
QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent);
let position = pivot.position;
let doc = aEvent.DOMNode;
if (doc instanceof Ci.nsIDOMDocument && position.DOMNode) {
// Set the caret to the start of the pivot position, and move
// the focus in the same manner as browse with caret mode.
// This blurs the focus on the previous pivot position (if it
// was activated), and keeps us in a predictable spot for tab
// focus.
let sel = doc.getSelection();
sel.collapse(position.DOMNode, 0);
Cc["@mozilla.org/focus-manager;1"]
.getService(Ci.nsIFocusManager).moveFocus(
doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
}
let newContext = this.getNewContext(event.oldAccessible,
pivot.position);

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

@ -18,14 +18,17 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
getService(Ci.nsIAccessibleRetrieval);
var VirtualCursorController = {
NOT_EDITABLE: 0,
SINGLE_LINE_EDITABLE: 1,
MULTI_LINE_EDITABLE: 2,
attach: function attach(aWindow) {
this.chromeWin = aWindow;
this.chromeWin.document.addEventListener('keypress', this._onkeypress, true);
this.chromeWin.document.addEventListener('keypress', this, true);
},
detach: function detach() {
this.chromeWin.document.removeEventListener('keypress', this._onkeypress,
true);
this.chromeWin.document.removeEventListener('keypress', this, true);
},
_getBrowserApp: function _getBrowserApp() {
@ -37,26 +40,38 @@ var VirtualCursorController = {
}
},
_onkeypress: function _onkeypress(aEvent) {
let document = VirtualCursorController._getBrowserApp().
selectedBrowser.contentDocument;
dump('keypress ' + aEvent.keyCode + '\n');
handleEvent: function handleEvent(aEvent) {
let document = this._getBrowserApp().selectedBrowser.contentDocument;
let target = aEvent.target;
switch (aEvent.keyCode) {
case aEvent.DOM_VK_END:
VirtualCursorController.moveForward(document, true);
this.moveForward(document, true);
break;
case aEvent.DOM_VK_HOME:
VirtualCursorController.moveBackward(document, true);
this.moveBackward(document, true);
break;
case aEvent.DOM_VK_RIGHT:
VirtualCursorController.moveForward(document, aEvent.shiftKey);
if (this._isEditableText(target) &&
target.selectionEnd != target.textLength)
// Don't move forward if caret is not at end of entry.
// XXX: Fix for rtl
return;
this.moveForward(document, aEvent.shiftKey);
break;
case aEvent.DOM_VK_LEFT:
VirtualCursorController.moveBackward(document, aEvent.shiftKey);
if (this._isEditableText(target) &&
target.selectionEnd != 0)
// Don't move backward if caret is not at start of entry.
// XXX: Fix for rtl
return;
this.moveBackward(document, aEvent.shiftKey);
break;
case aEvent.DOM_VK_UP:
if (this._isEditableText(target) == this.MULTI_LINE_EDITABLE &&
target.selectionEnd != 0)
// Don't blur content if caret is not at start of text area.
return;
if (Services.appinfo.OS == 'Android')
// Return focus to native Android browser chrome.
Cc['@mozilla.org/android/bridge;1'].
@ -64,12 +79,10 @@ var VirtualCursorController = {
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
break;
case aEvent.DOM_VK_RETURN:
// XXX: It is true that desktop does not map the keypad enter key to
// DOM_VK_ENTER. So for desktop we require a ctrl+return instead.
if (Services.appinfo.OS == 'Android' || !aEvent.ctrlKey)
return;
case aEvent.DOM_VK_ENTER:
VirtualCursorController.activateCurrent(document);
if (this._isEditableText(target))
return;
this.activateCurrent(document);
break;
default:
return;
@ -79,6 +92,18 @@ var VirtualCursorController = {
aEvent.stopPropagation();
},
_isEditableText: function _isEditableText(aElement) {
// XXX: Support contentEditable and design mode
if (aElement instanceof Ci.nsIDOMHTMLInputElement &&
aElement.mozIsTextField(false))
return this.SINGLE_LINE_EDITABLE;
if (aElement instanceof Ci.nsIDOMHTMLTextAreaElement)
return this.MULTI_LINE_EDITABLE;
return this.NOT_EDITABLE;
},
moveForward: function moveForward(document, last) {
let virtualCursor = this.getVirtualCursor(document);
if (last) {

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

@ -198,7 +198,7 @@
<menuitem id="appmenu_debugger"
hidden="true"
type="checkbox"
label="&debuggerMenu.label;"
label="&debuggerMenu.label2;"
key="key_debugger"
command="Tools:Debugger"/>
<menuitem id="appmenu_remoteDebugger"

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

@ -574,7 +574,7 @@
<menuitem id="menu_debugger"
hidden="true"
type="checkbox"
label="&debuggerMenu.label;"
label="&debuggerMenu.label2;"
key="key_debugger"
command="Tools:Debugger"/>
<menuitem id="menu_remoteDebugger"

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

@ -8,8 +8,18 @@
* Keeps thumbnails of open web pages up-to-date.
*/
let gBrowserThumbnails = {
/**
* Pref that controls whether we can store SSL content on disk
*/
PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
_captureDelayMS: 1000,
/**
* Used to keep track of disk_cache_ssl preference
*/
_sslDiskCacheEnabled: null,
/**
* Map of capture() timeouts assigned to their browsers.
*/
@ -32,6 +42,10 @@ let gBrowserThumbnails = {
} catch (e) {}
gBrowser.addTabsProgressListener(this);
Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
this._sslDiskCacheEnabled =
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
this._tabEvents.forEach(function (aEvent) {
gBrowser.tabContainer.addEventListener(aEvent, this, false);
@ -45,6 +59,7 @@ let gBrowserThumbnails = {
uninit: function Thumbnails_uninit() {
gBrowser.removeTabsProgressListener(this);
Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
this._tabEvents.forEach(function (aEvent) {
gBrowser.tabContainer.removeEventListener(aEvent, this, false);
@ -68,6 +83,11 @@ let gBrowserThumbnails = {
}
},
observe: function Thumbnails_observe() {
this._sslDiskCacheEnabled =
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
},
/**
* State change progress listener for all tabs.
*/
@ -129,19 +149,30 @@ let gBrowserThumbnails = {
// Don't take screenshots of internally redirecting about: pages.
// This includes error pages.
if (channel.originalURI.schemeIs("about"))
let uri = channel.originalURI;
if (uri.schemeIs("about"))
return false;
let httpChannel;
try {
// If the channel is a nsIHttpChannel get its http status code.
let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
} catch (e) { /* Not an HTTP channel. */ }
if (httpChannel) {
// Continue only if we have a 2xx status code.
return Math.floor(httpChannel.responseStatus / 100) == 2;
} catch (e) {
// Not a http channel, we just assume a success status code.
return true;
if (Math.floor(httpChannel.responseStatus / 100) != 2)
return false;
// Cache-Control: no-store.
if (httpChannel.isNoStoreResponse())
return false;
// Don't capture HTTPS pages unless the user explicitly enabled it.
if (uri.schemeIs("https") && !this._sslDiskCacheEnabled)
return false;
}
return true;
},
_clearTimeout: function Thumbnails_clearTimeout(aBrowser) {

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

@ -1078,6 +1078,7 @@
hidden="true">
#ifdef XP_MACOSX
<toolbarbutton id="developer-toolbar-closebutton"
class="devtools-closebutton"
oncommand="DeveloperToolbar.hide();"
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
#endif
@ -1102,6 +1103,7 @@
command="Tools:Debugger"/>
#ifndef XP_MACOSX
<toolbarbutton id="developer-toolbar-closebutton"
class="devtools-closebutton"
oncommand="DeveloperToolbar.hide();"
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
#endif

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

@ -111,12 +111,15 @@ html|*#highlighter-nodeinfobar-tagname {
}
#inspector-layoutview-container > iframe {
-moz-transition-property: height;
-moz-transition-duration: 0.1s;
/* header size */
height: 22px;
}
#inspector-layoutview-container:not([disable-transitions]) > iframe {
-moz-transition-property: height;
-moz-transition-duration: 0.2s;
}
#inspector-layoutview-container > iframe[open] {
/* header size + layout view size: 22px + 155px */
height: 177px;

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

@ -3806,7 +3806,6 @@
role="presentation"/>
<xul:toolbarbutton anonid="close-button"
xbl:inherits="fadein,pinned,selected"
clickthrough="never"
class="tab-close-button"/>
</xul:hbox>
</xul:stack>

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

@ -13,6 +13,7 @@ include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
browser_thumbnails_capture.js \
browser_thumbnails_privacy.js \
browser_thumbnails_redirect.js \
browser_thumbnails_storage.js \
browser_thumbnails_bug726727.js \
@ -20,6 +21,7 @@ _BROWSER_FILES = \
head.js \
background_red.html \
background_red_redirect.sjs \
privacy_cache_control.sjs \
$(NULL)
libs:: $(_BROWSER_FILES)

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

@ -0,0 +1,66 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_DISK_CACHE_SSL = "browser.cache.disk_cache_ssl";
const URL = "://example.com/browser/browser/components/thumbnails/" +
"test/privacy_cache_control.sjs";
function runTests() {
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_DISK_CACHE_SSL);
});
let positive = [
// A normal HTTP page without any Cache-Control header.
{scheme: "http", cacheControl: null, diskCacheSSL: false},
// A normal HTTP page with 'Cache-Control: private'.
{scheme: "http", cacheControl: "private", diskCacheSSL: false},
// Capture HTTPS pages if browser.cache.disk_cache_ssl == true.
{scheme: "https", cacheControl: null, diskCacheSSL: true},
{scheme: "https", cacheControl: "public", diskCacheSSL: true},
{scheme: "https", cacheControl: "private", diskCacheSSL: true}
];
let negative = [
// Never capture pages with 'Cache-Control: no-store'.
{scheme: "http", cacheControl: "no-store", diskCacheSSL: false},
{scheme: "http", cacheControl: "no-store", diskCacheSSL: true},
{scheme: "https", cacheControl: "no-store", diskCacheSSL: false},
{scheme: "https", cacheControl: "no-store", diskCacheSSL: true},
// Don't capture HTTPS pages by default.
{scheme: "https", cacheControl: null, diskCacheSSL: false},
{scheme: "https", cacheControl: "public", diskCacheSSL: false},
{scheme: "https", cacheControl: "private", diskCacheSSL: false}
];
yield checkCombinations(positive, true);
yield checkCombinations(negative, false);
}
function checkCombinations(aCombinations, aResult) {
let combi = aCombinations.shift();
if (!combi) {
next();
return;
}
let url = combi.scheme + URL;
if (combi.cacheControl)
url += "?" + combi.cacheControl;
Services.prefs.setBoolPref(PREF_DISK_CACHE_SSL, combi.diskCacheSSL);
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
let browser = gBrowser.selectedBrowser;
whenLoaded(browser, function () {
let msg = JSON.stringify(combi) + " == " + aResult;
is(gBrowserThumbnails._shouldCapture(browser), aResult, msg);
gBrowser.removeTab(tab);
// Continue with the next combination.
checkCombinations(aCombinations, aResult);
});
}

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

@ -117,52 +117,24 @@ function checkThumbnailColor(aURL, aRed, aGreen, aBlue, aMessage) {
let width = 100, height = 100;
let thumb = PageThumbs.getThumbnailURL(aURL, width, height);
getXULDocument(function (aDocument) {
let htmlns = "http://www.w3.org/1999/xhtml";
let img = aDocument.createElementNS(htmlns, "img");
img.setAttribute("src", thumb);
let htmlns = "http://www.w3.org/1999/xhtml";
let img = document.createElementNS(htmlns, "img");
img.setAttribute("src", thumb);
whenLoaded(img, function () {
let canvas = aDocument.createElementNS(htmlns, "canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
whenLoaded(img, function () {
let canvas = document.createElementNS(htmlns, "canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
// Draw the image to a canvas and compare the pixel color values.
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
checkCanvasColor(ctx, aRed, aGreen, aBlue, aMessage);
// Draw the image to a canvas and compare the pixel color values.
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
checkCanvasColor(ctx, aRed, aGreen, aBlue, aMessage);
next();
});
next();
});
}
/**
* Passes a XUL document (created if necessary) to the given callback.
* @param aCallback The function to be called when the XUL document has been
* created. The first argument will be the document.
*/
function getXULDocument(aCallback) {
let hiddenWindow = Services.appShell.hiddenDOMWindow;
let doc = cachedXULDocument || hiddenWindow.document;
if (doc instanceof XULDocument) {
aCallback(cachedXULDocument = doc);
return;
}
let iframe = doc.createElement("iframe");
iframe.setAttribute("src", "chrome://global/content/mozilla.xhtml");
iframe.addEventListener("DOMContentLoaded", function onLoad() {
iframe.removeEventListener("DOMContentLoaded", onLoad, false);
aCallback(cachedXULDocument = iframe.contentDocument);
}, false);
doc.body.appendChild(iframe);
registerCleanupFunction(function () { doc.body.removeChild(iframe); });
}
/**
* Checks the top-left pixel of a given canvas' 2d context for a given color.
* @param aContext The 2D context of a canvas.

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

@ -0,0 +1,16 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function handleRequest(aRequest, aResponse) {
// Set HTTP Status
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
// Set Cache-Control header.
let value = aRequest.queryString;
if (value)
aResponse.setHeader("Cache-Control", value);
// Set the response body.
aResponse.write("<!DOCTYPE html><html><body></body></html>");
}

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

@ -0,0 +1,18 @@
# Use at least -O1 for optimization to avoid stack space
# exhaustions caused by Clang function inlining.
ac_add_options --enable-debug
ac_add_options --enable-optimize="-O1"
# ASan specific options on Linux
ac_add_options --enable-valgrind
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

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

@ -0,0 +1,20 @@
# We still need to build with debug symbols
ac_add_options --disable-debug
ac_add_options --enable-optimize="-O2 -g"
# ASan specific options on Linux
ac_add_options --enable-valgrind
# Other options
ac_add_options --enable-codesighs
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

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

@ -0,0 +1,18 @@
# Use at least -O1 for optimization to avoid stack space
# exhaustions caused by Clang function inlining.
ac_add_options --enable-debug
ac_add_options --enable-optimize="-O1"
# ASan specific options on Linux
ac_add_options --enable-valgrind
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

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

@ -0,0 +1,20 @@
# We still need to build with debug symbols
ac_add_options --disable-debug
ac_add_options --enable-optimize="-O2 -g"
# ASan specific options on Linux
ac_add_options --enable-valgrind
# Other options
ac_add_options --enable-codesighs
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

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

@ -1505,6 +1505,10 @@ InspectorStyleSidebar.prototype = {
let frame = this._chromeDoc.createElement("iframe");
frame.setAttribute("flex", "1");
frame._toolID = aRegObj.id;
// This is needed to enable tooltips inside the iframe document.
frame.setAttribute("tooltip", "aHTMLTooltip");
this._deck.appendChild(frame);
// wire up button to show the iframe

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

@ -97,6 +97,9 @@ LayoutView.prototype = {
// Build the layout view in the sidebar.
this.buildView();
this.bound_handleKeypress = this.handleKeypress.bind(this);
this.iframe.addEventListener("keypress", this.bound_handleKeypress, true);
// Get messages from the iframe.
this.inspector.chromeWindow.addEventListener("message", this.onMessage, true);
@ -151,6 +154,7 @@ LayoutView.prototype = {
this.inspector.removeListener("locked", this.onLock);
this.inspector.removeListener("unlocked", this.onUnlock);
this.browser.removeEventListener("MozAfterPaint", this.update, true);
this.iframe.removeEventListener("keypress", this.bound_handleKeypress, true);
this.inspector.chromeWindow.removeEventListener("message", this.onMessage, true);
this.close();
this.iframe = null;
@ -215,6 +219,28 @@ LayoutView.prototype = {
}
},
/**
* Handle keypress.
*/
handleKeypress: function LV_handleKeypress(event) {
let win = this.inspector.chromeWindow;
// avoid scroll
if (event.keyCode == win.KeyEvent.DOM_VK_LEFT ||
event.keyCode == win.KeyEvent.DOM_VK_RIGHT ||
event.keyCode == win.KeyEvent.DOM_VK_UP ||
event.keyCode == win.KeyEvent.DOM_VK_DOWN ||
event.keyCode == win.KeyEvent.DOM_VK_PAGE_UP ||
event.keyCode == win.KeyEvent.DOM_VK_PAGE_DOWN) {
event.preventDefault();
}
if (event.charCode == win.KeyEvent.DOM_VK_SPACE) {
this.toggle(true);
}
},
/**
* Open the view container.
*
@ -228,6 +254,9 @@ LayoutView.prototype = {
if (aUserAction) {
this.inspector._layoutViewIsOpen = true;
Services.prefs.setBoolPref("devtools.layoutview.open", true);
this.view.removeAttribute("disable-transitions");
} else {
this.view.setAttribute("disable-transitions", "true");
}
this.iframe.setAttribute("open", "true");
this.update();
@ -246,6 +275,9 @@ LayoutView.prototype = {
if (aUserAction) {
this.inspector._layoutViewIsOpen = false;
Services.prefs.setBoolPref("devtools.layoutview.open", false);
this.view.removeAttribute("disable-transitions");
} else {
this.view.setAttribute("disable-transitions", "true");
}
this.iframe.removeAttribute("open");
},

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -3,6 +3,12 @@
// Tests that the developer toolbar works properly
let imported = {};
Components.utils.import("resource:///modules/HUDService.jsm", imported);
registerCleanupFunction(function() {
imported = {};
});
const URL = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_basic.html";
function test() {
@ -13,24 +19,106 @@ function test() {
}
function runTest() {
Services.obs.addObserver(checkOpen, DeveloperToolbar.NOTIFICATIONS.SHOW, false);
// TODO: reopen the window so the pref has a chance to take effect
// EventUtils.synthesizeKey("v", { ctrlKey: true, shiftKey: true });
DeveloperToolbarTest.show();
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible in runTest");
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.SHOW, catchFail(checkOpen));
document.getElementById("Tools:DevToolbar").doCommand();
}
function checkOpen() {
Services.obs.removeObserver(checkOpen, DeveloperToolbar.NOTIFICATIONS.SHOW, false);
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible");
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible in checkOpen");
Services.obs.addObserver(checkClosed, DeveloperToolbar.NOTIFICATIONS.HIDE, false);
// EventUtils.synthesizeKey("v", { ctrlKey: true, shiftKey: true });
DeveloperToolbarTest.hide();
let close = document.getElementById("developer-toolbar-closebutton");
let webconsole = document.getElementById("developer-toolbar-webconsole");
let inspector = document.getElementById("developer-toolbar-inspector");
let debuggr = document.getElementById("developer-toolbar-debugger");
ok(close, "Close button exists");
ok(!webconsole.checked, "web console button state 1");
ok(!inspector.checked, "inspector button state 1");
ok(!debuggr.checked, "debugger button state 1");
document.getElementById("Tools:WebConsole").doCommand();
ok(webconsole.checked, "web console button state 2");
ok(!inspector.checked, "inspector button state 2");
ok(!debuggr.checked, "debugger button state 2");
document.getElementById("Tools:Inspect").doCommand();
ok(webconsole.checked, "web console button state 3");
ok(inspector.checked, "inspector button state 3");
ok(!debuggr.checked, "debugger button state 3");
// Christmas tree!
// The web console opens synchronously, but closes asynchronously.
let hud = imported.HUDService.getHudByWindow(content);
imported.HUDService.disableAnimation(hud.hudId);
document.getElementById("Tools:WebConsole").doCommand();
ok(!webconsole.checked, "web console button state 6");
ok(inspector.checked, "inspector button state 6");
ok(!debuggr.checked, "debugger button state 6");
document.getElementById("Tools:Inspect").doCommand();
ok(!webconsole.checked, "web console button state 7");
ok(!inspector.checked, "inspector button state 7");
ok(!debuggr.checked, "debugger button state 7");
// All closed
// Check we can open and close and retain button state
document.getElementById("Tools:Inspect").doCommand();
ok(!webconsole.checked, "web console button state 8");
ok(inspector.checked, "inspector button state 8");
ok(!debuggr.checked, "debugger button state 8");
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkClosed));
document.getElementById("Tools:DevToolbar").doCommand();
}
function checkClosed() {
Services.obs.removeObserver(checkClosed, DeveloperToolbar.NOTIFICATIONS.HIDE, false);
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible");
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible in checkClosed");
// Check we grok state even when closed
document.getElementById("Tools:WebConsole").doCommand();
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.SHOW, catchFail(checkReOpen));
document.getElementById("Tools:DevToolbar").doCommand();
}
function checkReOpen() {
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible in checkReOpen");
let webconsole = document.getElementById("developer-toolbar-webconsole");
let inspector = document.getElementById("developer-toolbar-inspector");
let debuggr = document.getElementById("developer-toolbar-debugger");
ok(webconsole.checked, "web console button state 9");
ok(inspector.checked, "inspector button state 9");
ok(!debuggr.checked, "debugger button state 9");
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkReClosed));
document.getElementById("developer-toolbar-closebutton").doCommand();
}
function checkReClosed() {
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible in checkReClosed");
finish();
}
//------------------------------------------------------------------------------
function oneTimeObserve(name, callback) {
var func = function() {
Services.obs.removeObserver(func, name);
callback();
};
Services.obs.addObserver(func, name, false);
}

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

@ -310,12 +310,24 @@ let DeveloperToolbarTest = {
testFunc(browser, tab);
}
catch (ex) {
ok(false, "" + ex);
ok(false, ex);
console.error(ex);
finish();
throw ex;
}
});
});
},
};
function catchFail(func) {
return function() {
try {
return func.apply(null, arguments);
}
catch (ex) {
ok(false, ex);
console.error(ex);
finish();
}
};
}

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

@ -768,17 +768,6 @@ var types = require('gcli/types');
var Status = require('gcli/types').Status;
var BooleanType = require('gcli/types/basic').BooleanType;
/**
* A lookup hash of our registered commands
*/
var commands = {};
/**
* A sorted list of command names, we regularly want them in order, so pre-sort
*/
var commandNames = [];
/**
* Implement the localization algorithm for any documentation objects (i.e.
* description and manual) in a command.
@ -1030,6 +1019,21 @@ Object.defineProperty(Parameter.prototype, 'isPositionalAllowed', {
canon.Parameter = Parameter;
/**
* A lookup hash of our registered commands
*/
var commands = {};
/**
* A sorted list of command names, we regularly want them in order, so pre-sort
*/
var commandNames = [];
/**
* A lookup of the original commandSpecs by command name
*/
var commandSpecs = {};
/**
* Add a command to the canon of known commands.
* This function is exposed to the outside world (via gcli/index). It is
@ -1038,11 +1042,21 @@ canon.Parameter = Parameter;
* @return The new command
*/
canon.addCommand = function addCommand(commandSpec) {
if (commands[commandSpec.name] != null) {
// Roughly canon.removeCommand() without the event call, which we do later
delete commands[commandSpec.name];
commandNames = commandNames.filter(function(test) {
return test !== commandSpec.name;
});
}
var command = new Command(commandSpec);
commands[commandSpec.name] = command;
commandNames.push(commandSpec.name);
commandNames.sort();
commandSpecs[commandSpec.name] = commandSpec;
canon.onCanonChange();
return command;
};
@ -1055,7 +1069,10 @@ canon.removeCommand = function removeCommand(commandOrName) {
var name = typeof commandOrName === 'string' ?
commandOrName :
commandOrName.name;
// See start of canon.addCommand if changing this code
delete commands[name];
delete commandSpecs[name];
commandNames = commandNames.filter(function(test) {
return test !== name;
});
@ -1089,6 +1106,14 @@ canon.getCommandNames = function getCommandNames() {
return commandNames.slice(0);
};
/**
* Get access to the stored commandMetaDatas (i.e. before they were made into
* instances of Command/Parameters) so we can remote them.
*/
canon.getCommandSpecs = function getCommandSpecs() {
return commandSpecs;
};
/**
* Enable people to be notified of changes to the list of commands
*/
@ -1226,9 +1251,17 @@ exports.createEvent = function(name) {
* @param scope Optional 'this' object for the function call
*/
event.remove = function(func, scope) {
var found = false;
handlers = handlers.filter(function(test) {
return test.func !== func && test.scope !== scope;
var noMatch = (test.func !== func && test.scope !== scope);
if (!noMatch) {
found = true;
}
return noMatch;
});
if (!found) {
console.warn('Failed to remove handler from ' + name);
}
};
/**
@ -1590,6 +1623,13 @@ exports.createUrlLookup = function(callingModule) {
return require('text!gcli/ui/' + path);
}
catch (ex) {
// Under node/unamd callingModule is provided by node. This code isn't
// the right answer but it's enough to pass all the unit tests and get
// test coverage information, which is all we actually care about here.
if (callingModule.filename) {
return callingModule.filename + path;
}
var filename = callingModule.id.split('/').pop() + '.js';
if (callingModule.uri.substr(-filename.length) !== filename) {
@ -5000,7 +5040,8 @@ define('gcli/ui/intro', ['require', 'exports', 'module' , 'gcli/settings', 'gcli
var hideIntroSettingSpec = {
name: 'hideIntro',
type: 'boolean',
description: l10n.lookup('hideIntroDesc')
description: l10n.lookup('hideIntroDesc'),
defaultValue: false
};
var hideIntro;
@ -5713,6 +5754,9 @@ Requisition.prototype.cloneAssignments = function() {
*/
Requisition.prototype.getStatus = function() {
var status = Status.VALID;
if (!this._unassigned.arg.isBlank()) {
return Status.ERROR;
}
this.getAssignments(true).forEach(function(assignment) {
var assignStatus = assignment.getStatus();
if (assignStatus > status) {
@ -6669,9 +6713,21 @@ Output.prototype.toDom = function(element) {
}
else {
if (this.command.returnType === 'terminal') {
node = util.createElement(document, 'textarea');
node.classList.add('gcli-row-terminal');
node.readOnly = true;
if (Array.isArray(output)) {
node = util.createElement(document, 'div');
output.forEach(function() {
var child = util.createElement(document, 'textarea');
child.classList.add('gcli-row-subterminal');
child.readOnly = true;
node.appendChild(child);
});
}
else {
node = util.createElement(document, 'textarea');
node.classList.add('gcli-row-terminal');
node.readOnly = true;
}
}
else {
node = util.createElement(document, 'p');
@ -6812,7 +6868,6 @@ exports.shutdown = function() {
* something else takes focus.
* @param options Object containing user customization properties, including:
* - blurDelay (default=150ms)
* - slowTypingDelay (default=3000ms)
* - debug (default=false)
* - commandOutputManager (default=canon.commandOutputManager)
* @param components Object that links to other UI components. GCLI provided:
@ -6838,12 +6893,6 @@ function FocusManager(options, components) {
this._helpRequested = false;
this._recentOutput = false;
// Be more helpful if the user pauses
// this._slowTyping = false;
// this._keyPressTimeout = null;
// this._onSlowTyping = this._onSlowTyping.bind(this);
// this._slowTypingDelay = options.slowTypingDelay || 3000;
this.onVisibilityChange = util.createEvent('FocusManager.onVisibilityChange');
this._focused = this._focused.bind(this);
@ -6878,7 +6927,6 @@ FocusManager.prototype.destroy = function() {
this._blurDelayTimeout = null;
}
// delete this._onSlowTyping;
delete this._focused;
delete this._document;
delete this._window;
@ -6969,8 +7017,6 @@ FocusManager.prototype._reportFocus = function(where) {
console.log('FocusManager._reportFocus(' + (where || 'unknown') + ')');
}
// this._resetSlowTypingAlarm();
if (this._blurDelayTimeout) {
if (this._debug) {
console.log('FocusManager.cancelBlur');
@ -6996,8 +7042,6 @@ FocusManager.prototype._reportBlur = function(where) {
console.log('FocusManager._reportBlur(' + where + ')');
}
// this._cancelSlowTypingAlarm();
if (this._hasFocus) {
if (this._blurDelayTimeout) {
if (this._debug) {
@ -7017,35 +7061,6 @@ FocusManager.prototype._reportBlur = function(where) {
}
};
/**
* Called on keypress or new focus. Sets off a timer to explode if the user
* stops typing.
*/
FocusManager.prototype._resetSlowTypingAlarm = function() {
// this._cancelSlowTypingAlarm();
// this._keyPressTimeout = this._window.setTimeout(this._onSlowTyping,
// this._slowTypingDelay);
};
/**
* Don't kick off a slow typing alarm
*/
FocusManager.prototype._cancelSlowTypingAlarm = function() {
// if (this._keyPressTimeout) {
// this._window.clearTimeout(this._keyPressTimeout);
// this._keyPressTimeout = null;
// }
// this._slowTyping = false;
};
/**
* Called from the key-press timeout
*/
FocusManager.prototype._onSlowTyping = function() {
// this._slowTyping = true;
// this._checkShow();
};
/**
* The setting has changed
*/
@ -7058,8 +7073,6 @@ FocusManager.prototype._eagerHelperChanged = function() {
* showing the tooltip element, (or if the keypress is F1, show it now)
*/
FocusManager.prototype.onInputChange = function(ev) {
// this._resetSlowTypingAlarm();
// this._slowTyping = false;
this._recentOutput = false;
this._checkShow();
};
@ -7073,8 +7086,6 @@ FocusManager.prototype.helpRequest = function() {
console.log('FocusManager.helpRequest');
}
// this._cancelSlowTypingAlarm();
// this._slowTyping = true;
this._helpRequested = true;
this._recentOutput = false;
this._checkShow();
@ -7089,8 +7100,6 @@ FocusManager.prototype.removeHelp = function() {
console.log('FocusManager.removeHelp');
}
// this._cancelSlowTypingAlarm();
// this._slowTyping = false;
this._importantFieldFlag = false;
this._isError = false;
this._helpRequested = false;
@ -7176,10 +7185,6 @@ FocusManager.prototype._shouldShowTooltip = function() {
return { visible: true, reason: 'importantFieldFlag' };
}
// if (this._slowTyping) {
// return { visible: true, reason: 'slowTyping' };
// }
return { visible: false, reason: 'default' };
};
@ -8007,8 +8012,8 @@ function Menu(options) {
*/
Menu.prototype.destroy = function() {
delete this.element;
delete this.items;
delete this.template;
delete this.document;
};
/**
@ -8388,7 +8393,7 @@ var helpCommandSpec = {
name: 'search',
type: 'string',
description: l10n.lookup('helpSearchDesc'),
manual: l10n.lookup('helpSearchManual'),
manual: l10n.lookup('helpSearchManual2'),
defaultValue: null
}
],
@ -9463,7 +9468,8 @@ History.prototype.backward = function() {
exports.History = History;
});define("text!gcli/ui/inputter.css", [], "");
});
define("text!gcli/ui/inputter.css", [], "");
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
@ -9829,8 +9835,6 @@ Tooltip.prototype.destroy = function() {
delete this.descriptionEle;
delete this.highlightEle;
delete this.field;
delete this.focusManager;
delete this.document;
delete this.element;
delete this.panelElement;

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

@ -1,4 +1,4 @@
<!-- LOCALIZATION NOTE : FILE This file contains the Script Debugger strings -->
<!-- LOCALIZATION NOTE : FILE This file contains the Debugger strings -->
<!-- LOCALIZATION NOTE : FILE Do not translate commandkey -->
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
@ -9,7 +9,7 @@
<!-- LOCALIZATION NOTE (debuggerMenu.label): This is the label for the
- application menu item that opens the debugger UI. -->
<!ENTITY debuggerMenu.label "Script Debugger">
<!ENTITY debuggerMenu.label2 "Debugger">
<!-- LOCALIZATION NOTE (remoteDebuggerMenu.label): This is the label for the
- application menu item that opens the remote debugger UI. -->

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

@ -1,5 +1,5 @@
# LOCALIZATION NOTE These strings are used inside the Script Debugger
# which is available from the Web Developer sub-menu -> 'Script Debugger'.
# LOCALIZATION NOTE These strings are used inside the Debugger
# which is available from the Web Developer sub-menu -> 'Debugger'.
# The correct localization of this file might be to keep it in
# English, or another language commonly spoken among web developers.
# You want to make that choice consistent across the developer tools.

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

@ -105,15 +105,16 @@ helpDesc=Get help on the available commands
helpManual=Provide help either on a specific command (if a search string is provided and an exact match is found) or on the available commands (if a search string is not provided, or if no exact match is found).
# LOCALIZATION NOTE (helpSearchDesc): A very short description of the 'search'
# parameter to the 'help' command. See helpSearchManual for a fuller
# parameter to the 'help' command. See helpSearchManual2 for a fuller
# description of what it does. This string is designed to be shown in a dialog
# with restricted space, which is why it should be as short as possible.
helpSearchDesc=Search string
# LOCALIZATION NOTE (helpSearchManual): A fuller description of the 'search'
# LOCALIZATION NOTE (helpSearchManual2): A fuller description of the 'search'
# parameter to the 'help' command. Displayed when the user asks for help on
# what it does.
helpSearchManual=<strong>search string</strong> to use in narrowing down the displayed commands. Regular expressions not supported.
# what it does. Inline HTML (e.g. <strong>) can be used to emphasize the core
# concept.
helpSearchManual2=<strong>search string</strong> to use in narrowing down the displayed commands. Regular expressions not supported.
# LOCALIZATION NOTE (helpManSynopsis): A heading shown at the top of a help
# page for a command in the console It labels a summary of the parameters to
@ -220,6 +221,28 @@ prefSetCheckBody=Changing these advanced settings can be harmful to the stabilit
# prefSetCheckBody
prefSetCheckGo=I'll be careful, I promise!
# LOCALIZATION NOTE (prefResetDesc): A very short description of the 'pref
# reset' command. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible. See
# prefResetManual for a fuller description of what it does.
prefResetDesc=Reset a setting
# LOCALIZATION NOTE (prefResetManual): A fuller description of the 'pref
# reset' command. Displayed when the user asks for help on what it does.
prefResetManual=Reset the value of a setting to the system defaults
# LOCALIZATION NOTE (prefResetSettingDesc): A short description of the
# 'setting' parameter to the 'pref reset' command. See prefResetSettingManual
# for a fuller description of what it does. This string is designed to be
# shown in a dialog with restricted space, which is why it should be as short
# as possible.
prefResetSettingDesc=Setting to reset
# LOCALIZATION NOTE (prefResetSettingManual): A fuller description of the
# 'setting' parameter to the 'pref reset' command. Displayed when the user
# asks for help on what it does.
prefResetSettingManual=The name of the setting to reset to the system default value
# LOCALIZATION NOTE (prefOutputFilter): Displayed in the output from the 'pref
# list' command as a label to an input element that allows the user to filter
# the results
@ -235,6 +258,16 @@ prefOutputName=Name
# available preferences
prefOutputValue=Value
# LOCALIZATION NOTE (introDesc): A very short description of the 'intro'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See introManual for a
# fuller description of what it does.
introDesc=Show the opening message
# LOCALIZATION NOTE (introManual): A fuller description of the 'intro'
# command. Displayed when the user asks for help on what it does.
introManual=Redisplay the message that is shown to new users until they click the 'Got it!' button
# LOCALIZATION NOTE (hideIntroDesc): Short description of the 'hideIntro'
# setting. Displayed when the user asks for help on the settings.
hideIntroDesc=Show the initial welcome message

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

@ -277,5 +277,13 @@ build_one_stage({"PATH" : stage1_tool_inst_dir + "/bin:/bin:/usr/bin",
"RANLIB" : "true" },
stage2_dir, False)
stage2_tool_inst_dir = stage2_dir + '/inst'
stage3_dir = build_dir + '/stage3'
build_one_stage({"PATH" : stage2_tool_inst_dir + "/bin:/bin:/usr/bin",
"CC" : "gcc -fgnu89-inline",
"CXX" : "g++",
"RANLIB" : "true" },
stage3_dir, False)
build_tar_package(aux_inst_dir + "/bin/tar",
"toolchain.tar", stage2_dir, "inst")
"toolchain.tar", stage3_dir, "inst")

20
build/unix/mozconfig.asan Normal file
Просмотреть файл

@ -0,0 +1,20 @@
# Use Clang r155417
export CC="/tools/clang-3.0/bin/clang -fgnu89-inline"
export CXX="/tools/clang-3.0/bin/clang++"
# Mandatory flags for ASan
export ASANFLAGS="-faddress-sanitizer -Dxmalloc=myxmalloc -fPIC"
export CFLAGS="$ASANFLAGS"
export CXXFLAGS="$ASANFLAGS"
export LDFLAGS="-faddress-sanitizer"
# Enable ASan specific code and build workarounds
ac_add_options --enable-address-sanitizer
# Mandatory options required for ASan builds (both on Linux and Mac)
export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols
ac_add_options --disable-install-strip
ac_add_options --disable-jemalloc
ac_add_options --disable-crashreporter
ac_add_options --disable-elf-hack

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

@ -1,12 +1,13 @@
export INCLUDE=/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/v7.0/include:/c/tools/sdks/v7.0/include/atl:/c/tools/sdks/dx10/include
export LIBPATH=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib
export LIB=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib:/c/tools/sdks/v7.0/lib:/c/tools/sdks/dx10/lib
export PATH="/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:${PATH}"
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x86/Microsoft.VC100.CRT
export MOZ_TOOLS=C:/mozilla-build/moztools
export PATH="/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:/c/mozilla-build/moztools:/c/Tools/sdks/v7.0/bin:${PATH}"
mk_add_options "export LIB=$LIB"
mk_add_options "export LIBPATH=$LIBPATH"
mk_add_options "export PATH=$PATH"
mk_add_options "export INCLUDE=$INCLUDE"
mk_add_options "export WIN32_REDIST_DIR=$WIN32_REDIST_DIR"
mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"

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

@ -22,8 +22,8 @@ ifndef INCLUDED_VERSION_MK
include $(topsrcdir)/config/version.mk
endif
USE_AUTOTARGETS_MK = 1
include $(topsrcdir)/config/makefiles/makeutils.mk
include $(topsrcdir)/config/makefiles/autotargets.mk
ifdef SDK_XPIDLSRCS
XPIDLSRCS += $(SDK_XPIDLSRCS)
@ -1596,8 +1596,7 @@ chrome::
$(LOOP_OVER_DIRS)
$(LOOP_OVER_TOOL_DIRS)
$(FINAL_TARGET)/chrome:
$(NSINSTALL) -D $@
$(FINAL_TARGET)/chrome: $(call mkdir_deps,$(FINAL_TARGET)/chrome)
ifneq (,$(wildcard $(JAR_MANIFEST)))
ifndef NO_DIST_INSTALL

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

@ -70,7 +70,7 @@ nsDOMMultipartFile::GetSize(PRUint64* aLength)
length += l;
}
NS_ENSURE_TRUE(length.valid(), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(length.isValid(), NS_ERROR_FAILURE);
mLength = length.value();
}

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

@ -39,9 +39,8 @@
#define nsDOMBlobBuilder_h
#include "nsDOMFile.h"
#include "CheckedInt.h"
#include "mozilla/StandardInteger.h"
#include "mozilla/CheckedInt.h"
using namespace mozilla;
@ -128,10 +127,10 @@ protected:
// Start at 1 or we'll loop forever.
CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
while (bufferLen.valid() && bufferLen.value() < mDataLen + aSize)
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
bufferLen *= 2;
if (!bufferLen.valid())
if (!bufferLen.isValid())
return false;
// PR_ memory functions are still fallible

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

@ -61,8 +61,8 @@
#include "nsIUUIDGenerator.h"
#include "nsBlobProtocolHandler.h"
#include "nsStringStream.h"
#include "CheckedInt.h"
#include "nsJSUtils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Preferences.h"
#include "plbase64.h"
@ -227,7 +227,7 @@ ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
newEndOffset = aSize;
}
if (!newStartOffset.valid() || !newEndOffset.valid() ||
if (!newStartOffset.isValid() || !newEndOffset.isValid() ||
newStartOffset.value() >= newEndOffset.value()) {
aStart = aEnd = 0;
}

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

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -109,6 +110,7 @@
#include "nsIDOMFormData.h"
#include "nsWrapperCacheInlines.h"
#include "nsStreamListenerWrapper.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -3046,9 +3048,6 @@ nsXMLHttpRequest::Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<Requ
if (mState & XML_HTTP_REQUEST_MULTIPART) {
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 1);
listener = new nsMultipartProxyListener(listener);
if (!listener) {
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 0);
}
@ -3062,9 +3061,18 @@ nsXMLHttpRequest::Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<Requ
// a same-origin request right now, since it could be redirected.
listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
withCredentials, true, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
// Because of bug 682305, we can't let listener be the XHR object itself
// because JS wouldn't be able to use it. So if we haven't otherwise
// created a listener around 'this', do so now.
listener = new nsStreamListenerWrapper(listener);
}
NS_ASSERTION(listener != this,
"Using an object as a listener that can't be exposed to JS");
// Bypass the network cache in cases where it makes no sense:
// 1) Multipart responses are very large and would likely be doomed by the

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

@ -75,6 +75,7 @@ _CHROME_FILES = \
test_bug650784.html \
test_bug752226-3.xul \
test_bug752226-4.xul \
test_bug682305.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,159 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=682305
-->
<head>
<title>XMLHttpRequest send and channel implemented in JS</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=682305">Mozilla Bug 682305</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();
/*
* Register a custom nsIProtocolHandler service
* in order to be able to implement *and use* an
* nsIChannel component written in Javascript.
*/
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var SimpleURI = Cc["@mozilla.org/network/simple-uri;1"];
var ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var PROTOCOL_SCHEME = "jsproto";
function CustomChannel(uri) {
this.URI = this.originalURI = uri;
}
CustomChannel.prototype = {
URI: null,
originalURI: null,
contentCharset: "utf-8",
contentLength: 0,
contentType: "text/plain",
owner: Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal),
securityInfo: null,
notificationCallbacks: null,
loadFlags: 0,
loadGroup: null,
name: null,
status: Cr.NS_OK,
asyncOpen: function(listener, context) {
let stream = this.open();
try {
listener.onStartRequest(this, context);
} catch(e) {}
try {
listener.onDataAvailable(this, context, stream, 0, stream.available());
} catch(e) {}
try {
listener.onStopRequest(this, context, Cr.NS_OK);
} catch(e) {}
},
open: function() {
let data = "bar";
let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
stream.setData(data, data.length);
return stream;
},
isPending: function() {
return false;
},
cancel: function() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
suspend: function() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
resume: function() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
};
function CustomProtocol() {}
CustomProtocol.prototype = {
get scheme() {
return PROTOCOL_SCHEME;
},
get protocolFlags() {
return (Ci.nsIProtocolHandler.URI_NORELATIVE |
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD);
},
get defaultPort() {
return -1;
},
allowPort: function allowPort() {
return false;
},
newURI: function newURI(spec, charset, baseURI) {
var uri = SimpleURI.createInstance(Ci.nsIURI)
uri.spec = spec;
return uri.QueryInterface(Ci.nsIURI);
},
newChannel: function newChannel(URI) {
return new CustomChannel(URI);
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsISupportsWeakReference,
Ci.nsIProtocolHandler])
};
var gFactory = {
register: function() {
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
var classID = Components.ID("{ed064287-1e76-49ba-a28d-dc74394a8334}");
var description = PROTOCOL_SCHEME + ": protocol";
var contractID = "@mozilla.org/network/protocol;1?name=" + PROTOCOL_SCHEME;
var factory = XPCOMUtils._getFactory(CustomProtocol);
registrar.registerFactory(classID, description, contractID, factory);
this.unregister = function() {
registrar.unregisterFactory(classID, factory);
delete this.unregister;
};
}
};
// Register the custom procotol handler
gFactory.register();
// Then, checks if XHR works with it
var xhr = new XMLHttpRequest();
xhr.open("GET", PROTOCOL_SCHEME + ":foo", true);
xhr.onload = function () {
is(xhr.responseText, "bar", "protocol doesn't work");
gFactory.unregister();
SimpleTest.finish();
}
try {
xhr.send(null);
} catch(e) {
ok(false, e);
}
</script>
</pre>
</body>
</html>

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

@ -40,7 +40,7 @@
#include "prtypes.h"
#include "CheckedInt.h"
#include "mozilla/CheckedInt.h"
class nsHTMLCanvasElement;
class nsIPrincipal;
@ -63,9 +63,9 @@ inline bool CheckSaneSubrectSize(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h,
CheckedInt32 checked_ymost = CheckedInt32(y) + h;
return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
checked_xmost.valid() &&
checked_xmost.isValid() &&
checked_xmost.value() <= realWidth &&
checked_ymost.valid() &&
checked_ymost.isValid() &&
checked_ymost.value() <= realHeight;
}

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

@ -40,7 +40,7 @@
#include "nsDOMError.h"
#include "nsIDOMCanvasRenderingContext2D.h"
#include "CheckedInt.h"
#include "mozilla/CheckedInt.h"
#include "nsMathUtils.h"
#include "CustomQS_Canvas.h"
@ -169,7 +169,7 @@ CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
h = 1;
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
if (!len.valid()) {
if (!len.isValid()) {
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
}

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

@ -425,7 +425,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
// If incrementing the generation would cause overflow,
// don't allow it. Allowing this would allow us to use
// resource handles created from older context generations.
if (!(mGeneration+1).valid())
if (!(mGeneration + 1).isValid())
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);

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

@ -64,9 +64,9 @@
#include "GLContextProvider.h"
#include "Layers.h"
#include "CheckedInt.h"
#include "nsDataHashtable.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/ImageData.h"
#ifdef XP_MACOSX
@ -481,7 +481,7 @@ public:
private:
WebGLMonotonicHandle NextMonotonicHandle() {
++mCurrentMonotonicHandle;
if (!mCurrentMonotonicHandle.valid())
if (!mCurrentMonotonicHandle.isValid())
NS_RUNTIMEABORT("ran out of monotonic ids!");
return mCurrentMonotonicHandle.value();
}
@ -1748,7 +1748,7 @@ public:
bool HasImageInfoAt(size_t level, size_t face) const {
CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
return checked_index.valid() &&
return checked_index.isValid() &&
checked_index.value() < mImageInfos.Length() &&
ImageInfoAt(level, face).mIsDefined;
}
@ -2328,7 +2328,7 @@ public:
bool NextGeneration()
{
if (!(mGeneration+1).valid())
if (!(mGeneration + 1).isValid())
return false; // must exit without changing mGeneration
++mGeneration;
return true;

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

@ -687,7 +687,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
return ErrorInvalidOperation("BufferData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
@ -726,7 +726,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
return ErrorInvalidOperation("BufferSubData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
@ -941,7 +941,7 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
CheckedUint32 checked_neededByteLength =
GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
PRUint32 bytesNeeded = checked_neededByteLength.value();
@ -1562,7 +1562,7 @@ WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount)
CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
if (!checked_dataSize.valid()) {
if (!checked_dataSize.isValid()) {
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
"with %d vertices. Try reducing the number of vertices.", vertexCount);
return false;
@ -1779,7 +1779,7 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
if (!checked_firstPlusCount.valid())
if (!checked_firstPlusCount.isValid())
return ErrorInvalidOperation("drawArrays: overflow in first+count");
if (checked_firstPlusCount.value() > maxAllowedCount)
@ -1847,7 +1847,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
}
if (!checked_byteCount.valid())
if (!checked_byteCount.isValid())
return ErrorInvalidValue("DrawElements: overflow in byteCount");
// If there is no current program, this is silently ignored.
@ -1863,7 +1863,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
CheckedUint32 checked_neededByteCount = checked_byteCount + byteOffset;
if (!checked_neededByteCount.valid())
if (!checked_neededByteCount.isValid())
return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
if (checked_neededByteCount.value() > mBoundElementArrayBuffer->ByteLength())
@ -1880,7 +1880,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
CheckedInt32 checked_maxIndexPlusOne = CheckedInt32(maxIndex) + 1;
if (!checked_maxIndexPlusOne.valid() ||
if (!checked_maxIndexPlusOne.isValid() ||
checked_maxIndexPlusOne.value() > maxAllowedCount)
{
// the index array contains invalid indices for the current drawing state, but they
@ -1893,7 +1893,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
CheckedInt32 checked_maxIndexInSubArrayPlusOne = CheckedInt32(maxIndexInSubArray) + 1;
if (!checked_maxIndexInSubArrayPlusOne.valid() ||
if (!checked_maxIndexInSubArrayPlusOne.isValid() ||
checked_maxIndexInSubArrayPlusOne.value() > maxAllowedCount)
{
return ErrorInvalidOperation(
@ -3883,7 +3883,7 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
CheckedUint32 checked_alignedRowSize =
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
if (checked_neededByteLength.value() > dataByteLen)
@ -5601,7 +5601,7 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
CheckedUint32 checked_alignedRowSize =
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("texImage2D: integer overflow computing the needed buffer size");
PRUint32 bytesNeeded = checked_neededByteLength.value();
@ -5842,7 +5842,7 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
CheckedUint32 checked_alignedRowSize =
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
if (!checked_neededByteLength.valid())
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
PRUint32 bytesNeeded = checked_neededByteLength.value();

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

@ -40,8 +40,7 @@
#include "WebGLContext.h"
#include "mozilla/Preferences.h"
#include "CheckedInt.h"
#include "mozilla/CheckedInt.h"
#include "jsfriendapi.h"
@ -143,8 +142,8 @@ WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
CheckedInt32 checked_sizeOfLastElement
= CheckedInt32(vd.componentSize()) * vd.size;
if (!checked_byteLength.valid() ||
!checked_sizeOfLastElement.valid())
if (!checked_byteLength.isValid() ||
!checked_sizeOfLastElement.isValid())
{
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
return false;
@ -156,7 +155,7 @@ WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
CheckedInt32 checked_maxAllowedCount
= ((checked_byteLength - checked_sizeOfLastElement) / vd.actualStride()) + 1;
if (!checked_maxAllowedCount.valid()) {
if (!checked_maxAllowedCount.isValid()) {
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
return false;
}
@ -401,7 +400,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
{
CheckedUint32 calculated_byteLength = 0;
CheckedUint32 checked_byteLength = byteLength;
if (!checked_byteLength.valid()) {
if (!checked_byteLength.isValid()) {
ErrorInvalidValue("%s: data length out of bounds", info);
return false;
}
@ -411,7 +410,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
{
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 8;
if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
ErrorInvalidValue("%s: data size does not match dimensions", info);
return false;
}
@ -421,7 +420,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
{
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 16;
if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
ErrorInvalidValue("%s: data size does not match dimensions", info);
return false;
}

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

@ -108,7 +108,6 @@
#include "nsIMemoryReporter.h"
#include "nsStyleUtil.h"
#include "CanvasImageCache.h"
#include "CheckedInt.h"
#include <algorithm>
@ -116,6 +115,7 @@
#include "jsfriendapi.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/PBrowserParent.h"
@ -3926,14 +3926,14 @@ nsCanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
MOZ_ASSERT(aWidth && aHeight);
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.valid()) {
if (!len.isValid()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
if (!rightMost.valid() || !bottomMost.valid()) {
if (!rightMost.isValid() || !bottomMost.isValid()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
@ -4066,7 +4066,7 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
if (!checkedDirtyX.valid())
if (!checkedDirtyX.isValid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyX = checkedDirtyX.value();
@ -4078,7 +4078,7 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
if (!checkedDirtyY.valid())
if (!checkedDirtyY.isValid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyY = checkedDirtyY.value();

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

@ -104,7 +104,6 @@
#include "nsIMemoryReporter.h"
#include "nsStyleUtil.h"
#include "CanvasImageCache.h"
#include "CheckedInt.h"
#include <algorithm>
@ -112,6 +111,7 @@
#include "jsfriendapi.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/PBrowserParent.h"
@ -4095,14 +4095,14 @@ nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
MOZ_ASSERT(aWidth && aHeight);
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.valid()) {
if (!len.isValid()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
if (!rightMost.valid() || !bottomMost.valid()) {
if (!rightMost.isValid() || !bottomMost.isValid()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
@ -4233,7 +4233,7 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(PRInt32 x, PRInt32 y, PRU
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
if (!checkedDirtyX.valid())
if (!checkedDirtyX.isValid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyX = checkedDirtyX.value();
@ -4245,7 +4245,7 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(PRInt32 x, PRInt32 y, PRU
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
if (!checkedDirtyY.valid())
if (!checkedDirtyY.isValid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyY = checkedDirtyY.value();

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

@ -38,10 +38,10 @@
#include "nsHTMLCanvasElement.h"
#include "mozilla/Base64.h"
#include "mozilla/CheckedInt.h"
#include "nsNetUtil.h"
#include "prmem.h"
#include "nsDOMFile.h"
#include "CheckedInt.h"
#include "nsIScriptSecurityManager.h"
#include "nsIXPConnect.h"

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

@ -98,6 +98,9 @@
#include "nsDOMMediaStream.h"
#include "nsIScriptError.h"
#include "nsCSSParser.h"
#include "nsIMediaList.h"
#ifdef MOZ_OGG
#include "nsOggDecoder.h"
#endif
@ -850,6 +853,12 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
"Should delay load event (if in document) during load");
NS_ASSERTION(mIsLoadingFromSourceChildren,
"Must remember we're loading from source children");
nsIDocument* parentDoc = OwnerDoc()->GetParentDocument();
if (parentDoc) {
parentDoc->FlushPendingNotifications(Flush_Layout);
}
while (true) {
nsIContent* child = GetNextSource();
if (!child) {
@ -876,11 +885,25 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
GetCanPlay(type) == CANPLAY_NO) {
DispatchAsyncSourceError(child);
const PRUnichar* params[] = { type.get(), src.get() };
ReportLoadError("MediaLoadUnsupportedType", params, ArrayLength(params));
ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
continue;
}
LOG(PR_LOG_DEBUG, ("%p Trying load from <source>=%s type=%s", this,
NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get()));
nsAutoString media;
if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::media, media) && !media.IsEmpty()) {
nsCSSParser cssParser;
nsRefPtr<nsMediaList> mediaList(new nsMediaList());
cssParser.ParseMediaList(media, NULL, 0, mediaList, false);
nsIPresShell* presShell = OwnerDoc()->GetShell();
if (presShell && !mediaList->Matches(presShell->GetPresContext(), NULL)) {
DispatchAsyncSourceError(child);
const PRUnichar* params[] = { media.get(), src.get() };
ReportLoadError("MediaLoadSourceMediaNotMatched", params, ArrayLength(params));
continue;
}
}
LOG(PR_LOG_DEBUG, ("%p Trying load from <source>=%s type=%s media=%s", this,
NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get(),
NS_ConvertUTF16toUTF8(media).get()));
nsCOMPtr<nsIURI> uri;
NewURIFromString(src, getter_AddRefs(uri));

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

@ -114,6 +114,7 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLSourceElement)
NS_IMPL_URI_ATTR(nsHTMLSourceElement, Src, src)
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Type, type)
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Media, media)
nsresult
nsHTMLSourceElement::BindToTree(nsIDocument *aDocument,

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

@ -243,32 +243,88 @@ nsMathMLElement::GetAttributeMappingFunction() const
return &MapMathMLAttributesInto;
}
// ================
// Utilities for parsing and retrieving numeric values
/*
The REC says:
An explicit plus sign ('+') is not allowed as part of a numeric value
except when it is specifically listed in the syntax (as a quoted '+'
or "+"),
Units allowed
ID Description
em ems (font-relative unit traditionally used for horizontal lengths)
ex exs (font-relative unit traditionally used for vertical lengths)
px pixels, or pixel size of a "typical computer display"
in inches (1 inch = 2.54 centimeters)
cm centimeters
mm millimeters
pt points (1 point = 1/72 inch)
pc picas (1 pica = 12 points)
% percentage of default value
Implementation here:
The numeric value is valid only if it is of the form [-] nnn.nnn
[h/v-unit]
*/
/* static */ bool
nsMathMLElement::ParseNamedSpaceValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags)
{
PRInt32 i = 0;
// See if it is one of the 'namedspace' (ranging -7/18em, -6/18, ... 7/18em)
if (aString.EqualsLiteral("veryverythinmathspace")) {
i = 1;
} else if (aString.EqualsLiteral("verythinmathspace")) {
i = 2;
} else if (aString.EqualsLiteral("thinmathspace")) {
i = 3;
} else if (aString.EqualsLiteral("mediummathspace")) {
i = 4;
} else if (aString.EqualsLiteral("thickmathspace")) {
i = 5;
} else if (aString.EqualsLiteral("verythickmathspace")) {
i = 6;
} else if (aString.EqualsLiteral("veryverythickmathspace")) {
i = 7;
} else if (aFlags & PARSE_ALLOW_NEGATIVE) {
if (aString.EqualsLiteral("negativeveryverythinmathspace")) {
i = -1;
} else if (aString.EqualsLiteral("negativeverythinmathspace")) {
i = -2;
} else if (aString.EqualsLiteral("negativethinmathspace")) {
i = -3;
} else if (aString.EqualsLiteral("negativemediummathspace")) {
i = -4;
} else if (aString.EqualsLiteral("negativethickmathspace")) {
i = -5;
} else if (aString.EqualsLiteral("negativeverythickmathspace")) {
i = -6;
} else if (aString.EqualsLiteral("negativeveryverythickmathspace")) {
i = -7;
}
}
if (0 != i) {
aCSSValue.SetFloatValue(float(i)/float(18), eCSSUnit_EM);
return true;
}
return false;
}
// The REC says:
//
// "Most presentation elements have attributes that accept values representing
// lengths to be used for size, spacing or similar properties. The syntax of a
// length is specified as
//
// number | number unit | namedspace
//
// There should be no space between the number and the unit of a length."
//
// "A trailing '%' represents a percent of the default value. The default
// value, or how it is obtained, is listed in the table of attributes for each
// element. [...] A number without a unit is intepreted as a multiple of the
// default value."
//
// "The possible units in MathML are:
//
// Unit Description
// em an em (font-relative unit traditionally used for horizontal lengths)
// ex an ex (font-relative unit traditionally used for vertical lengths)
// px pixels, or size of a pixel in the current display
// in inches (1 inch = 2.54 centimeters)
// cm centimeters
// mm millimeters
// pt points (1 point = 1/72 inch)
// pc picas (1 pica = 12 points)
// % percentage of default value"
//
// The numbers are defined that way:
// - unsigned-number: "a string of decimal digits with up to one decimal point
// (U+002E), representing a non-negative terminating decimal number (a type of
// rational number)"
// - number: "an optional prefix of '-' (U+002D), followed by an unsigned
// number, representing a terminating decimal number (a type of rational
// number)"
//
/* static */ bool
nsMathMLElement::ParseNumericValue(const nsString& aString,
nsCSSValue& aCSSValue,
@ -281,6 +337,10 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
if (!stringLength)
return false;
if (ParseNamedSpaceValue(aString, aCSSValue, aFlags)) {
return true;
}
nsAutoString number, unit;
// see if the negative sign is there
@ -289,10 +349,6 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
if (c == '-') {
number.Append(c);
i++;
// skip any space after the negative sign
if (i < stringLength && nsCRT::IsAsciiSpace(str[i]))
i++;
}
// Gather up characters that make up the number
@ -358,6 +414,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
// scriptsizemultiplier
//
// "Specifies the multiplier to be used to adjust font size due to changes
// in scriptlevel.
//
// values: number
// default: 0.71
//
const nsAttrValue* value =
aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_);
nsCSSValue* scriptSizeMultiplier =
@ -377,6 +441,18 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// scriptminsize
//
// "Specifies the minimum font size allowed due to changes in scriptlevel.
// Note that this does not limit the font size due to changes to mathsize."
//
// values: length
// default: 8pt
//
// We don't allow negative values.
// XXXfredw Should we allow unitless values? (bug 411227)
// XXXfredw Does a relative unit give a multiple of the default value?
//
value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_);
nsCSSValue* scriptMinSize = aData->ValueForScriptMinSize();
if (value && value->Type() == nsAttrValue::eString &&
@ -384,6 +460,17 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
ParseNumericValue(value->GetStringValue(), *scriptMinSize, 0);
}
// scriptlevel
//
// "Changes the scriptlevel in effect for the children. When the value is
// given without a sign, it sets scriptlevel to the specified value; when a
// sign is given, it increments ("+") or decrements ("-") the current
// value. (Note that large decrements can result in negative values of
// scriptlevel, but these values are considered legal.)"
//
// values: ( "+" | "-" )? unsigned-integer
// default: inherited
//
value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
nsCSSValue* scriptLevel = aData->ValueForScriptLevel();
if (value && value->Type() == nsAttrValue::eString &&
@ -408,6 +495,28 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathsize
//
// "Specifies the size to display the token content. The values 'small' and
// 'big' choose a size smaller or larger than the current font size, but
// leave the exact proportions unspecified; 'normal' is allowed for
// completeness, but since it is equivalent to '100%' or '1em', it has no
// effect."
//
// values: "small" | "normal" | "big" | length
// default: inherited
//
// fontsize
//
// "Specified the size for the token. Deprecated in favor of mathsize."
//
// values: length
// default: inherited
//
// In both cases, we don't allow negative values.
// XXXfredw Should we allow unitless values? (bug 411227)
// XXXfredw Does a relative unit give a multiple of the default value?
//
bool parseSizeKeywords = true;
value = aAttributes->GetAttr(nsGkAtoms::mathsize_);
if (!value) {
@ -435,6 +544,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// fontfamily
//
// "Should be the name of a font that may be available to a MathML renderer,
// or a CSS font specification; See Section 6.5 Using CSS with MathML and
// CSS for more information. Deprecated in favor of mathvariant."
//
// values: string
//
value = aAttributes->GetAttr(nsGkAtoms::fontfamily_);
nsCSSValue* fontFamily = aData->ValueForFontFamily();
if (value && value->Type() == nsAttrValue::eString &&
@ -443,6 +560,24 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathbackground
//
// "Specifies the background color to be used to fill in the bounding box of
// the element and its children. The default, 'transparent', lets the
// background color, if any, used in the current rendering context to show
// through."
//
// values: color | "transparent"
// default: "transparent"
//
// background
//
// "Specified the background color to be used to fill in the bounding box of
// the element and its children. Deprecated in favor of mathbackground."
//
// values: color | "transparent"
// default: "transparent"
//
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
const nsAttrValue* value =
aAttributes->GetAttr(nsGkAtoms::mathbackground_);
@ -458,6 +593,23 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
}
}
// mathcolor
//
// "Specifies the foreground color to use when drawing the components of this
// element, such as the content for token elements or any lines, surds, or
// other decorations. It also establishes the default mathcolor used for
// child elements when used on a layout element."
//
// values: color
// default: inherited
//
// color
//
// "Specified the color for the token. Deprecated in favor of mathcolor."
//
// values: color
// default: inherited
//
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
if (!value) {

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

@ -89,6 +89,10 @@ public:
PARSE_ALLOW_UNITLESS = 0x01, // unitless 0 will be turned into 0px
PARSE_ALLOW_NEGATIVE = 0x02
};
static bool ParseNamedSpaceValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags);
static bool ParseNumericValue(const nsString& aString,
nsCSSValue& aCSSValue,
PRUint32 aFlags);

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

@ -40,13 +40,12 @@
#define VideoUtils_h
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/CheckedInt.h"
#include "nsRect.h"
#include "nsIThreadManager.h"
#include "nsThreadUtils.h"
#include "CheckedInt.h"
using mozilla::CheckedInt64;
using mozilla::CheckedUint64;
using mozilla::CheckedInt32;

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

@ -164,8 +164,8 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
// the frame we've been supplied without indexing out of bounds.
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
if (!xLimit.valid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
!yLimit.valid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
!yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
{
// The specified picture dimensions can't be contained inside the video
// frame, we'll stomp memory if we try to copy it. Fail.
@ -346,7 +346,7 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
break;
CheckedInt64 startFrame = UsecsToFrames(audio->mTime, mInfo.mAudioRate);
CheckedInt64 targetFrame = UsecsToFrames(aTarget, mInfo.mAudioRate);
if (!startFrame.valid() || !targetFrame.valid()) {
if (!startFrame.isValid() || !targetFrame.isValid()) {
return NS_ERROR_FAILURE;
}
if (startFrame.value() + audio->mFrames <= targetFrame.value()) {
@ -390,7 +390,7 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
audio->mAudioData.get() + (framesToPrune * channels),
frames * channels * sizeof(AudioDataValue));
CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudioRate);
if (!duration.valid()) {
if (!duration.isValid()) {
return NS_ERROR_FAILURE;
}
nsAutoPtr<AudioData> data(new AudioData(audio->mOffset,

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

@ -547,7 +547,7 @@ void nsBuiltinDecoderStateMachine::SendOutputStreamAudio(AudioData* aAudio,
CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
aStream->mAudioFramesWrittenBaseTime + mStartTime) + aStream->mAudioFramesWritten;
CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudioRate, aAudio->mTime);
if (!audioWrittenOffset.valid() || !frameOffset.valid())
if (!audioWrittenOffset.isValid() || !frameOffset.isValid())
return;
if (audioWrittenOffset.value() < frameOffset.value()) {
// Write silence to catch up
@ -1115,7 +1115,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
// samples.
CheckedInt64 sampleTime = UsecsToFrames(s->mTime, rate);
CheckedInt64 missingFrames = sampleTime - playedFrames;
if (!missingFrames.valid() || !sampleTime.valid()) {
if (!missingFrames.isValid() || !sampleTime.isValid()) {
NS_WARNING("Int overflow adding in AudioLoop()");
break;
}
@ -1139,7 +1139,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
if (!playedUsecs.valid()) {
if (!playedUsecs.isValid()) {
NS_WARNING("Int overflow calculating audio end time");
break;
}

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

@ -353,10 +353,10 @@ PRInt64 nsTheoraState::Time(th_info* aInfo, PRInt64 aGranulepos)
ogg_int64_t pframe = aGranulepos - (iframe << shift);
PRInt64 frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
if (!t.valid())
if (!t.isValid())
return -1;
t /= aInfo->fps_numerator;
return t.valid() ? t.value() : -1;
return t.isValid() ? t.value() : -1;
}
PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
@ -364,7 +364,7 @@ PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
return -1;
}
CheckedInt64 t = (CheckedInt64(th_granule_frame(mCtx, granulepos)) * USECS_PER_S) * mInfo.fps_denominator;
if (!t.valid())
if (!t.isValid())
return -1;
return t.value() / mInfo.fps_numerator;
}
@ -622,7 +622,7 @@ PRInt64 nsVorbisState::Time(vorbis_info* aInfo, PRInt64 aGranulepos)
return -1;
}
CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
if (!t.valid())
if (!t.isValid())
t = 0;
return t.value() / aInfo->rate;
}
@ -884,7 +884,7 @@ PRInt64 nsOpusState::Time(PRInt64 granulepos)
// Ogg Opus always runs at a granule rate of 48 kHz.
CheckedInt64 t = CheckedInt64(granulepos - mPreSkip) * USECS_PER_S;
return t.valid() ? t.value() / mRate : -1;
return t.isValid() ? t.value() / mRate : -1;
}
bool nsOpusState::IsHeader(ogg_packet* aPacket)
@ -1048,7 +1048,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
// Extract the start time.
CheckedInt64 t = CheckedInt64(LEInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
if (!t.valid()) {
if (!t.isValid()) {
return (mActive = false);
} else {
startTime = t.value() / timeDenom;
@ -1056,7 +1056,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
// Extract the end time.
t = LEInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
if (!t.valid()) {
if (!t.isValid()) {
return (mActive = false);
} else {
endTime = t.value() / timeDenom;
@ -1065,7 +1065,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
// Check the numKeyPoints value read, ensure we're not going to run out of
// memory while trying to decode the index packet.
CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
if (!minPacketSize.valid())
if (!minPacketSize.isValid())
{
return (mActive = false);
}
@ -1103,7 +1103,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
p = ReadVariableLengthInt(p, limit, delta);
offset += delta;
if (p == limit ||
!offset.valid() ||
!offset.isValid() ||
offset.value() > mLength ||
offset.value() < 0)
{
@ -1111,14 +1111,14 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
}
p = ReadVariableLengthInt(p, limit, delta);
time += delta;
if (!time.valid() ||
if (!time.isValid() ||
time.value() > endTime ||
time.value() < startTime)
{
return (mActive = false);
}
CheckedInt64 timeUsecs = time * USECS_PER_S;
if (!timeUsecs.valid())
if (!timeUsecs.isValid())
return mActive = false;
timeUsecs /= timeDenom;
keyPoints->Add(offset.value(), timeUsecs.value());
@ -1228,8 +1228,8 @@ nsresult nsSkeletonState::GetDuration(const nsTArray<PRUint32>& aTracks,
}
NS_ASSERTION(endTime > startTime, "Duration must be positive");
CheckedInt64 duration = CheckedInt64(endTime) - startTime;
aDuration = duration.valid() ? duration.value() : 0;
return duration.valid() ? NS_OK : NS_ERROR_FAILURE;
aDuration = duration.isValid() ? duration.value() : 0;
return duration.isValid() ? NS_OK : NS_ERROR_FAILURE;
}
bool nsSkeletonState::DecodeHeader(ogg_packet* aPacket)

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

@ -87,7 +87,7 @@ nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
CheckedUint32 dummy = CheckedUint32(static_cast<PRUint32>(mMetadata.frameWidth)) *
static_cast<PRUint32>(mMetadata.frameHeight);
NS_ENSURE_TRUE(dummy.valid(), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(dummy.isValid(), NS_ERROR_FAILURE);
if (mMetadata.aspectDenominator == 0 ||
mMetadata.framerateDenominator == 0)
@ -268,7 +268,7 @@ nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime,
CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
offset += sizeof(nsRawVideoHeader);
NS_ENSURE_TRUE(offset.valid(), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(offset.isValid(), NS_ERROR_FAILURE);
nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
NS_ENSURE_SUCCESS(rv, rv);

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

@ -161,6 +161,7 @@ _TEST_FILES = \
use_large_cache.js \
test_audiowrite.html \
test_mozHasAudio.html \
test_source_media.html \
$(NULL)
# Don't run in suite

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

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Media test: media attribute for the source element.</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
<script type="text/javascript" src="../../html/content/test/reflect.js"></script>
</head>
<body>
<pre id="test">
<script type="text/javascript">
var testCount = 0;
function notifyFinished() {
testCount++;
if (testCount == 2) {
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
reflectString({
element: document.createElement("source"),
attribute: "media",
});
var media = getPlayableVideo(gSmallTests);
if (media == null) {
todo(false, "No media supported.");
SimpleTest.finish();
} else {
var v = document.createElement('video');
v.innerHTML = "<source src=\"" + media.name + "?fail\" media=\"not all\">" +
"<source src=\""+ media.name + "?pass\" media=\"all\">";
var v2 = document.createElement("video");
v2.innerHTML = "<source src=\""+ media.name +"?pass\">" +
"<source src=\""+ media.name + "?fail\" media=\"all\">";
document.body.appendChild(v);
document.body.appendChild(v2);
v.addEventListener("loadedmetadata", function(e) {
ok(/pass/.test(e.target.currentSrc),
"The source has been chosen according to the media attribute.");
notifyFinished();
});
v2.addEventListener("loadedmetadata", function(e) {
ok(/pass/.test(e.target.currentSrc),
"If no media attribute is specified, it defaults to \'all\'.")
notifyFinished();
});
}
</script>
</pre>
</body>
</html>

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

@ -209,10 +209,8 @@ void nsWebMBufferedParser::Append(const unsigned char* aBuffer, PRUint32 aLength
mCurrentOffset += aLength;
}
void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
PRInt64 aStartOffset, PRInt64 aEndOffset,
PRUint64 aTimecodeScale,
PRInt64 aStartTimeOffsetNS)
bool nsWebMBufferedState::CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset,
PRUint64* aStartTime, PRUint64* aEndTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
@ -220,7 +218,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
PRUint32 start;
mTimeMapping.GreatestIndexLtEq(aStartOffset, start);
if (start == mTimeMapping.Length()) {
return;
return false;
}
// Find the first nsWebMTimeDataOffset at or before aEndOffset.
@ -233,7 +231,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
// Range is empty.
if (end <= start) {
return;
return false;
}
NS_ASSERTION(mTimeMapping[start].mOffset >= aStartOffset &&
@ -252,9 +250,9 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
// from the ranges' start and end timestamps, so that those timestamps are
// normalized in the range [0,duration].
double startTime = (mTimeMapping[start].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S;
double endTime = (mTimeMapping[end].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S;
aBuffered->Add(startTime, endTime);
*aStartTime = mTimeMapping[start].mTimecode;
*aEndTime = mTimeMapping[end].mTimecode;
return true;
}
void nsWebMBufferedState::NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset)

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

@ -225,10 +225,8 @@ public:
}
void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset);
void CalculateBufferedForRange(nsTimeRanges* aBuffered,
PRInt64 aStartOffset, PRInt64 aEndOffset,
PRUint64 aTimecodeScale,
PRInt64 aStartTimeOffsetNS);
bool CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset,
PRUint64* aStartTime, PRUint64* aEndTime);
private:
// Synchronizes access to the mTimeMapping array.

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

@ -448,12 +448,12 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
// from after the gap.
CheckedInt64 tstamp_frames = UsecsToFrames(tstamp_usecs, rate);
CheckedInt64 decoded_frames = UsecsToFrames(mAudioStartUsec, rate);
if (!tstamp_frames.valid() || !decoded_frames.valid()) {
if (!tstamp_frames.isValid() || !decoded_frames.isValid()) {
NS_WARNING("Int overflow converting WebM times to frames");
return false;
}
decoded_frames += mAudioFrames;
if (!decoded_frames.valid()) {
if (!decoded_frames.isValid()) {
NS_WARNING("Int overflow adding decoded_frames");
return false;
}
@ -461,7 +461,7 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
#ifdef DEBUG
CheckedInt64 usecs = FramesToUsecs(tstamp_frames.value() - decoded_frames.value(), rate);
LOG(PR_LOG_DEBUG, ("WebMReader detected gap of %lld, %lld frames, in audio stream\n",
usecs.valid() ? usecs.value(): -1,
usecs.isValid() ? usecs.value() : -1,
tstamp_frames.value() - decoded_frames.value()));
#endif
mPacketCount++;
@ -501,18 +501,18 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
}
CheckedInt64 duration = FramesToUsecs(frames, rate);
if (!duration.valid()) {
if (!duration.isValid()) {
NS_WARNING("Int overflow converting WebM audio duration");
return false;
}
CheckedInt64 total_duration = FramesToUsecs(total_frames, rate);
if (!total_duration.valid()) {
if (!total_duration.isValid()) {
NS_WARNING("Int overflow converting WebM audio total_duration");
return false;
}
CheckedInt64 time = total_duration + tstamp_usecs;
if (!time.valid()) {
if (!time.isValid()) {
NS_WARNING("Int overflow adding total_duration and tstamp_usecs");
nestegg_free_packet(aPacket);
return false;
@ -791,24 +791,45 @@ nsresult nsWebMReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime)
}
// Special case completely cached files. This also handles local files.
if (resource->IsDataCachedToEndOfResource(0)) {
bool isFullyCached = resource->IsDataCachedToEndOfResource(0);
if (isFullyCached) {
uint64_t duration = 0;
if (nestegg_duration(mContext, &duration) == 0) {
aBuffered->Add(0, duration / NS_PER_S);
}
} else {
}
PRUint32 bufferedLength = 0;
aBuffered->GetLength(&bufferedLength);
// Either we the file is not fully cached, or we couldn't find a duration in
// the WebM bitstream.
if (!isFullyCached || !bufferedLength) {
MediaResource* resource = mDecoder->GetResource();
nsTArray<MediaByteRange> ranges;
nsresult res = resource->GetCachedRanges(ranges);
NS_ENSURE_SUCCESS(res, res);
PRInt64 startTimeOffsetNS = aStartTime * NS_PER_USEC;
for (PRUint32 index = 0; index < ranges.Length(); index++) {
mBufferedState->CalculateBufferedForRange(aBuffered,
ranges[index].mStart,
ranges[index].mEnd,
timecodeScale,
startTimeOffsetNS);
PRUint64 start, end;
bool rv = mBufferedState->CalculateBufferedForRange(ranges[index].mStart,
ranges[index].mEnd,
&start, &end);
if (rv) {
double startTime = start * timecodeScale / NS_PER_S - aStartTime;
double endTime = end * timecodeScale / NS_PER_S - aStartTime;
// If this range extends to the end of the file, the true end time
// is the file's duration.
if (resource->IsDataCachedToEndOfResource(ranges[index].mStart)) {
uint64_t duration = 0;
if (nestegg_duration(mContext, &duration) == 0) {
endTime = duration / NS_PER_S;
}
}
aBuffered->Add(startTime, endTime);
}
}
}

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

@ -67,17 +67,17 @@ BrowserElementParent.prototype = {
}
},
_observeInProcessBrowserFrameShown: function(frameLoader, data) {
_observeInProcessBrowserFrameShown: function(frameLoader) {
debug("In-process browser frame shown " + frameLoader);
this._setUpMessageManagerListeners(frameLoader, data);
this._setUpMessageManagerListeners(frameLoader);
},
_observeRemoteBrowserFrameShown: function(frameLoader, data) {
_observeRemoteBrowserFrameShown: function(frameLoader) {
debug("Remote browser frame shown " + frameLoader);
this._setUpMessageManagerListeners(frameLoader, data);
this._setUpMessageManagerListeners(frameLoader);
},
_setUpMessageManagerListeners: function(frameLoader, data) {
_setUpMessageManagerListeners: function(frameLoader) {
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
if (!frameElement) {
debug("No frame element?");
@ -150,10 +150,10 @@ BrowserElementParent.prototype = {
}
break;
case 'remote-browser-frame-shown':
this._observeRemoteBrowserFrameShown(subject, data);
this._observeRemoteBrowserFrameShown(subject);
break;
case 'in-process-browser-frame-shown':
this._observeInProcessBrowserFrameShown(subject, data);
this._observeInProcessBrowserFrameShown(subject);
break;
case 'content-document-global-created':
this._observeContentGlobalCreated(subject);

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

@ -138,18 +138,25 @@ inline bool
IsArrayLike(JSContext* cx, JSObject* obj)
{
MOZ_ASSERT(obj);
// For simplicity, check for security wrappers up front
// For simplicity, check for security wrappers up front. In case we
// have a security wrapper, don't forget to enter the compartment of
// the underlying object after unwrapping.
JSAutoEnterCompartment ac;
if (js::IsWrapper(obj)) {
obj = XPCWrapper::Unwrap(cx, obj, false);
if (!obj) {
// Let's say it's not
return false;
}
if (!ac.enter(cx, obj)) {
return false;
}
}
// XXXbz need to detect platform objects (including listbinding
// ones) with indexGetters here!
return JS_IsArrayObject(cx, obj);
return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx);
}
inline bool
@ -582,6 +589,84 @@ ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
JSBool
ThrowingConstructorWorkers(JSContext* cx, unsigned argc, JS::Value* vp);
template<class T>
class NonNull
{
public:
NonNull()
#ifdef DEBUG
: inited(false)
#endif
{}
operator T&() {
MOZ_ASSERT(inited);
MOZ_ASSERT(ptr, "NonNull<T> was set to null");
return *ptr;
}
void operator=(T* t) {
ptr = t;
MOZ_ASSERT(ptr);
#ifdef DEBUG
inited = true;
#endif
}
T** Slot() {
#ifdef DEBUG
inited = true;
#endif
return &ptr;
}
protected:
T* ptr;
#ifdef DEBUG
bool inited;
#endif
};
template<class T>
class OwningNonNull
{
public:
OwningNonNull()
#ifdef DEBUG
: inited(false)
#endif
{}
operator T&() {
MOZ_ASSERT(inited);
MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
return *ptr;
}
void operator=(T* t) {
init(t);
}
void operator=(const already_AddRefed<T>& t) {
init(t);
}
protected:
template<typename U>
void init(U t) {
ptr = t;
MOZ_ASSERT(ptr);
#ifdef DEBUG
inited = true;
#endif
}
nsRefPtr<T> ptr;
#ifdef DEBUG
bool inited;
#endif
};
} // namespace dom
} // namespace mozilla

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

@ -1115,12 +1115,12 @@ class CastableObjectUnwrapper():
def __str__(self):
return string.Template(
""" {
nsresult rv = UnwrapObject<${protoID}>(cx, ${source}, &${target});
if (NS_FAILED(rv)) {
${codeOnFailure}
}
}""").substitute(self.substitution)
"""{
nsresult rv = UnwrapObject<${protoID}>(cx, ${source}, ${target});
if (NS_FAILED(rv)) {
${codeOnFailure}
}
}""").substitute(self.substitution)
class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
"""
@ -1150,128 +1150,300 @@ class CallbackObjectUnwrapper:
def __str__(self):
if self.descriptor.workers:
return string.Template("""
${target} = ${source};""").substitute(self.substitution)
return string.Template(
"${target} = ${source};"
).substitute(self.substitution)
return string.Template("""
nsresult rv;
XPCCallContext ccx(JS_CALLER, cx);
if (!ccx.IsValid()) {
rv = NS_ERROR_XPC_BAD_CONVERT_JS;
${codeOnFailure}
}
return string.Template(
"""nsresult rv;
XPCCallContext ccx(JS_CALLER, cx);
if (!ccx.IsValid()) {
rv = NS_ERROR_XPC_BAD_CONVERT_JS;
${codeOnFailure}
}
const nsIID& iid = NS_GET_IID(${nativeType});
nsRefPtr<nsXPCWrappedJS> wrappedJS;
rv = nsXPCWrappedJS::GetNewOrUsed(ccx, ${source}, iid,
NULL, getter_AddRefs(wrappedJS));
if (NS_FAILED(rv) || !wrappedJS) {
${codeOnFailure}
}
const nsIID& iid = NS_GET_IID(${nativeType});
nsRefPtr<nsXPCWrappedJS> wrappedJS;
rv = nsXPCWrappedJS::GetNewOrUsed(ccx, ${source}, iid,
NULL, getter_AddRefs(wrappedJS));
if (NS_FAILED(rv) || !wrappedJS) {
${codeOnFailure}
}
${target} = do_QueryObject(wrappedJS.get());
if (!${target}) {
${codeOnFailure}
}""").substitute(self.substitution)
// Use a temp nsCOMPtr for the null-check, because ${target} might be
// OwningNonNull, not an nsCOMPtr.
nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
if (!tmp) {
${codeOnFailure}
}
${target} = tmp.forget();""").substitute(self.substitution)
def getArgumentConversionTemplate(type, descriptor):
if type.isSequence() or type.isArray():
raise TypeError("Can't handle sequence or array arguments yet")
def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
isDefinitelyObject=False,
isSequenceMember=False):
"""
Get a template for converting a JS value to a native object based on the
given type and descriptor. If failureCode is given, then we're actually
testing whether we can convert the argument to the desired type. That
means that failures to convert due to the JS value being the wrong type of
value need to use failureCode instead of throwing exceptions. Failures to
convert that are due to JS exceptions (from toString or valueOf methods) or
out of memory conditions need to throw exceptions no matter what
failureCode is.
if descriptor is not None:
assert(type.isInterface())
If isDefinitelyObject is True, that means we know the value
isObject() and we have no need to recheck that.
The return value from this function is a tuple consisting of three things:
1) A string representing the conversion code. This will have template
substitution performed on it as follows:
${val} replaced by an expression for the JS::Value in question
${valPtr} is a pointer to the JS::Value in question
${holderName} replaced by the holder's name, if any
${declName} replaced by the declaration's name
2) A CGThing representing the native C++ type we're converting to
(declType). This is allowed to be None if the conversion code is
supposed to be used as-is.
3) A CGThing representing the type of a "holder" (holderType) which will
hold a possible reference to the C++ thing whose type we returned in #1,
or None if no such holder is needed.
${declName} must be in scope before the generated code is entered.
If holderType is not None then ${holderName} must be in scope
before the generated code is entered.
"""
# A helper function for wrapping up the template body for
# possibly-nullable objecty stuff
def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
codeToSetNull, isWorker):
if not isDefinitelyObject:
# Handle the non-object cases by wrapping up the whole
# thing in an if cascade.
templateBody = (
"if (${val}.isObject()) {\n" +
CGIndenter(CGGeneric(templateBody)).define() + "\n")
if type.nullable():
templateBody += (
"} else if (${val}.isNullOrUndefined()) {\n"
" %s;\n" % codeToSetNull)
templateBody += (
"} else {\n"
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
"}" % toStringBool(not isWorker))
return templateBody
if type.isArray():
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
if isSequenceMember:
raise TypeError("Can't handle sequences of sequences")
if failureCode is not None:
raise TypeError("Can't handle sequences when failureCode is not None")
nullable = type.nullable();
if nullable:
type = type.inner;
elementType = type.inner;
# We don't know anything about the object-ness of the things
# we wrap, so don't pass through isDefinitelyObject
(elementTemplate, elementDeclType,
elementHolderType) = getJSToNativeConversionTemplate(
elementType, descriptorProvider, isSequenceMember=True)
if elementHolderType is not None:
raise TypeError("Shouldn't need holders for sequences")
# Have to make sure to use a fallible array, because it's trivial for
# page JS to create things with very large lengths.
typeName = CGWrapper(elementDeclType, pre="nsTArray< ", post=" >")
if nullable:
typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
templateBody = ("""JSObject* seq = &${val}.toObject();\n
if (!IsArrayLike(cx, seq)) {
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
uint32_t length;
// JS_GetArrayLength actually works on all objects
if (!JS_GetArrayLength(cx, seq, &length)) {
return false;
}
// Jump through a hoop to do a fallible allocation but later end up with
// an infallible array.
FallibleTArray< %s > arr;
if (!arr.SetCapacity(length)) {
return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY);
}
for (uint32_t i = 0; i < length; ++i) {
jsval temp;
if (!JS_GetElement(cx, seq, i, &temp)) {
return false;
}
""" % (toStringBool(descriptorProvider.workers),
elementDeclType.define(),
toStringBool(descriptorProvider.workers)))
templateBody += CGIndenter(CGGeneric(
string.Template(elementTemplate).substitute(
{
"val" : "temp",
"declName" : "*arr.AppendElement()"
}
))).define()
templateBody += """
}
// And the other half of the hoop-jump"""
if nullable:
templateBody += """
${declName}.SetValue().SwapElements(arr);
"""
else:
templateBody += """
${declName}.SwapElements(arr);
"""
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
type, "${declName}.SetNull()",
descriptorProvider.workers)
return (templateBody, typeName, None)
if type.isInterface() and not type.isArrayBuffer():
descriptor = descriptorProvider.getDescriptor(
type.unroll().inner.identifier.name)
# This is an interface that we implement as a concrete class
# or an XPCOM interface.
# Allow null pointers for nullable types and old-binding classes
argIsPointer = type.nullable() or type.unroll().inner.isExternal()
# Sequences and non-worker callbacks have to hold a strong ref to the
# thing being passed down.
forceOwningType = (descriptor.interface.isCallback() and
not descriptor.workers) or isSequenceMember
typeName = descriptor.nativeType
typePtr = typeName + "*"
# Compute a few things:
# - declType is the type we want to return as the first element of our
# tuple.
# - holderType is the type we want to return as the third element
# of our tuple.
# - declInit is the initializer expression for our decl, if any.
# - target is where a pointer to the object is being stored
# Set up some sensible defaults for these things insofar as we can.
holderType = None
if argIsPointer:
nameSuffix = ""
if forceOwningType:
declType = "nsRefPtr<" + typeName + ">"
else:
declType = typePtr
target = "&${declName}"
else:
nameSuffix = "_ptr"
if forceOwningType:
declType = "OwningNonNull<" + typeName + ">"
else:
declType = "NonNull<" + typeName + ">"
target = "${declName}.Slot()"
# If we're going to QI, we want an nsCOMPtr. But note that XPConnect
# unwrapping may or may not QI, and we don't know whether it will. So
# we use a raw pointer for the isExternal() case, and if a ref is needed
# it'll be handled by the xpc_qsSelfRef we put on the stack later.
if descriptor.castable or type.unroll().inner.isExternal() or descriptor.workers:
declType = " ${typeName}*"
else:
declType = " nsCOMPtr<${typeName}>"
template = declType + " ${name}%s;\n" % nameSuffix
# We have to be very careful here to put anything that might need to
# hold references across the C++ call in |template| and not
# |templateBody|, since things in |templateBody| will go out of scope
# before the call happens.
templateBody = " if (${argVal}.isObject()) {"
templateBody = ""
if descriptor.castable:
templateBody += str(FailureFatalCastableObjectUnwrapper(
descriptor,
"&${argVal}.toObject()",
"${name}"+nameSuffix)).replace("\n", "\n ") + "\n"
if failureCode is not None:
templateBody += str(CastableObjectUnwrapper(
descriptor,
"&${val}.toObject()",
target,
failureCode))
else:
templateBody += str(FailureFatalCastableObjectUnwrapper(
descriptor,
"&${val}.toObject()",
target))
elif descriptor.interface.isCallback():
templateBody += str(CallbackObjectUnwrapper(
descriptor,
"&${argVal}.toObject()",
"${name}"+nameSuffix)) + "\n"
"&${val}.toObject()",
"${declName}",
codeOnFailure=failureCode))
elif descriptor.workers:
templateBody += """
${name}%s = &${argVal}.toObject();
MOZ_ASSERT(${name}%s);
""" % (nameSuffix, nameSuffix)
templateBody += "${declName} = &${val}.toObject();"
else:
template += " xpc_qsSelfRef tmpRef_${name};\n"
template += " jsval tmpVal_${name} = ${argVal};\n"
templateBody += """
${typeName}* tmp;
if (NS_FAILED(xpc_qsUnwrapArg<${typeName}>(cx, ${argVal}, &tmp, &tmpRef_${name}.ptr,
&tmpVal_${name}))) {
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
MOZ_ASSERT(tmp);
${name}%s = tmp;
""" % (toStringBool(not descriptor.workers), nameSuffix)
if type.nullable():
# Either external, or new-binding non-castable. We always have a
# holder for these, because we don't actually know whether we have
# to addref when unwrapping or not. So we just pass an
# getter_AddRefs(nsCOMPtr) to XPConnect and if we'll need a release
# it'll put a non-null pointer in there.
if forceOwningType:
# Don't return a holderType in this case; our declName
# will just own stuff.
templateBody += "nsCOMPtr<" + typeName + "> ${holderName};"
else:
holderType = "nsCOMPtr<" + typeName + ">"
templateBody += (
" } else if (${argVal}.isNullOrUndefined()) {\n"
" ${name}%s = NULL;\n" % nameSuffix)
"jsval tmpVal = ${val};\n" +
typePtr + " tmp;\n"
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, getter_AddRefs(${holderName}), &tmpVal))) {\n")
if failureCode is not None:
templateBody += " " + failureCode + "\n"
else:
templateBody += (
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
% toStringBool(not descriptor.workers))
templateBody += ("}\n"
"MOZ_ASSERT(tmp);\n")
templateBody += (
" } else {\n"
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }\n" % toStringBool(not descriptor.workers))
if not isDefinitelyObject:
# Our tmpVal will go out of scope, so we can't rely on it
# for rooting
templateBody += (
"if (tmpVal != ${val} && !${holderName}) {\n"
" // We have to have a strong ref, because we got this off\n"
" // some random object that might get GCed\n"
" ${holderName} = tmp;\n"
"}\n")
template += templateBody
# And store our tmp, before it goes out of scope.
templateBody += "${declName} = tmp;"
if not argIsPointer:
template += " ${typeName} &${name} = *${name}_ptr;\n"
return template
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
type, "${declName} = NULL",
descriptor.workers)
declType = CGGeneric(declType)
if holderType is not None:
holderType = CGGeneric(holderType)
return (templateBody, declType, holderType)
if type.isArrayBuffer():
if isSequenceMember:
raise TypeError("Can't handle sequences of arraybuffers")
declType = "JSObject*"
template = (
" JSObject* ${name};\n"
" if (${argVal}.isObject() && JS_IsArrayBufferObject(&${argVal}.toObject(), cx)) {\n"
" ${name} = &${argVal}.toObject();\n"
" }")
"if (${val}.isObject() && JS_IsArrayBufferObject(&${val}.toObject(), cx)) {\n"
" ${declName} = &${val}.toObject();\n"
"}")
if type.nullable():
template += (
" else if (${argVal}.isNullOrUndefined()) {\n"
" ${name} = NULL;\n"
" }")
" else if (${val}.isNullOrUndefined()) {\n"
" ${declName} = NULL;\n"
"}")
template += (
# XXXbz We don't know whether we're on workers, so play it safe
" else {\n"
" return Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }")
" return Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
"}")
return template
if type.isInterface():
raise TypeError("Interface type with no descriptor: " + type)
return (template, CGGeneric(declType), None)
if type.isString():
if isSequenceMember:
raise TypeError("Can't handle sequences of strings")
# XXXbz Need to figure out string behavior based on extended args? Also, how to
# detect them?
@ -1285,12 +1457,12 @@ def getArgumentConversionTemplate(type, descriptor):
undefinedBehavior = "eStringify"
return (
" const xpc_qsDOMString ${name}(cx, ${argVal}, ${argPtr},\n"
" xpc_qsDOMString::%s,\n"
" xpc_qsDOMString::%s);\n"
" if (!${name}.IsValid()) {\n"
" return false;\n"
" }\n" % (nullBehavior, undefinedBehavior))
"const xpc_qsDOMString ${declName}(cx, ${val}, ${valPtr},\n"
" xpc_qsDOMString::%s,\n"
" xpc_qsDOMString::%s);\n"
"if (!${declName}.IsValid()) {\n"
" return false;\n"
"}" % (nullBehavior, undefinedBehavior), None, None)
if type.isEnum():
if type.nullable():
@ -1298,46 +1470,74 @@ def getArgumentConversionTemplate(type, descriptor):
"yet")
enum = type.inner.identifier.name
return (
" %(enumtype)s ${name};\n"
" {\n"
" bool ok;\n"
" ${name} = static_cast<%(enumtype)s>(FindEnumStringIndex(cx, ${argVal}, %(values)s, &ok));\n"
" if (!ok) {\n"
" return false;\n"
" }\n"
" }" % { "enumtype" : enum,
"values" : enum + "Values::strings" })
"{\n"
" bool ok;\n"
" ${declName} = static_cast<%(enumtype)s>(FindEnumStringIndex(cx, ${val}, %(values)s, &ok));\n"
" if (!ok) {\n"
" return false;\n"
" }\n"
"}" % { "enumtype" : enum,
"values" : enum + "Values::strings" },
CGGeneric(enum), None)
if type.isCallback():
if isSequenceMember:
raise TypeError("Can't handle sequences of callbacks")
# XXXbz we're going to assume that callback types are always
# nullable and always have [TreatNonCallableAsNull] for now.
return (
" JSObject* ${name};\n"
" if (${argVal}.isObject() && JS_ObjectIsCallable(cx, &${argVal}.toObject())) {\n"
" ${name} = &${argVal}.toObject();\n"
" } else {\n"
" ${name} = NULL;\n"
" }\n")
"if (${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())) {\n"
" ${declName} = &${val}.toObject();\n"
"} else {\n"
" ${declName} = NULL;\n"
"}", CGGeneric("JSObject*"), None)
if type.isAny():
return " JS::Value ${name} = ${argVal};\n"
if isSequenceMember:
raise TypeError("Can't handle sequences of 'any'")
return ("${declName} = ${val};", CGGeneric("JS::Value"), None)
if not type.isPrimitive():
raise TypeError("Need conversion for argument type '%s'" % type)
# XXXbz need to add support for [EnforceRange] and [Clamp]
typeName = builtinNames[type.tag()]
if type.nullable():
return (" Nullable<${typeName}> ${name};\n"
" if (${argVal}.isNullOrUndefined()) {\n"
" ${name}.SetNull();\n"
" } else if (!ValueToPrimitive<${typeName}>(cx, ${argVal}, &${name}.SetValue())) {\n"
" return false;\n"
" }\n")
return ("if (${val}.isNullOrUndefined()) {\n"
" ${declName}.SetNull();\n"
"} else if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName}.SetValue())) {\n"
" return false;\n"
"}", CGGeneric("Nullable<" + typeName + ">"), None)
else:
return (" ${typeName} ${name};\n"
" if (!ValueToPrimitive<${typeName}>(cx, ${argVal}, &${name})) {\n"
" return false;\n"
" }\n")
return ("if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName})) {\n"
" return false;\n"
"}", CGGeneric(typeName), None)
def instantiateJSToNativeConversionTemplate(templateTuple, replacements):
"""
Take a tuple as returned by getJSToNativeConversionTemplate and a set of
replacements as required by the strings in such a tuple, and generate code
to convert into stack C++ types.
"""
(templateBody, declType, holderType) = templateTuple
result = CGList([], "\n")
if holderType is not None:
result.append(
CGList([holderType, CGGeneric(" "),
CGGeneric(replacements["holderName"]),
CGGeneric(";")]))
if declType is not None:
result.append(
CGList([declType, CGGeneric(" "),
CGGeneric(replacements["declName"]),
CGGeneric(";")]))
result.append(CGGeneric(
string.Template(templateBody).substitute(replacements)
))
# Add an empty CGGeneric to get an extra newline after the argument
# conversion.
result.append(CGGeneric(""))
return result;
def convertConstIDLValueToJSVal(value):
if isinstance(value, IDLNullValue):
@ -1363,7 +1563,6 @@ def convertIDLDefaultValueToJSVal(value):
assert False # Not implemented!
return convertConstIDLValueToJSVal(value)
unindenter = re.compile("^ ", re.MULTILINE)
class CGArgumentConverter(CGThing):
"""
A class that takes an IDL argument object, its index in the
@ -1375,44 +1574,38 @@ class CGArgumentConverter(CGThing):
self.argument = argument
# XXXbz should optional jsval args get JSVAL_VOID? What about
# others?
self.replacementVariables = {
replacer = {
"index" : index,
"argc" : argc,
"argv" : argv,
"defaultValue" : "JSVAL_VOID",
"name" : "arg%d" % index
"defaultValue" : "JSVAL_VOID"
}
self.replacementVariables = {
"declName" : "arg%d" % index,
"holderName" : ("arg%d" % index) + "_holder"
}
if argument.optional:
if argument.defaultValue:
self.replacementVariables["defaultValue"] = convertIDLDefaultValueToJSVal(argument.defaultValue)
self.replacementVariables["argVal"] = string.Template(
replacer["defaultValue"] = convertIDLDefaultValueToJSVal(argument.defaultValue)
self.replacementVariables["val"] = string.Template(
"(${index} < ${argc} ? ${argv}[${index}] : ${defaultValue})"
).substitute(self.replacementVariables)
self.replacementVariables["argPtr"] = string.Template(
).substitute(replacer)
self.replacementVariables["valPtr"] = string.Template(
"(${index} < ${argc} ? &${argv}[${index}] : NULL)"
).substitute(self.replacementVariables)
).substitute(replacer)
else:
self.replacementVariables["argVal"] = string.Template(
self.replacementVariables["val"] = string.Template(
"${argv}[${index}]"
).substitute(self.replacementVariables)
self.replacementVariables["argPtr"] = (
"&" + self.replacementVariables["argVal"])
self.descriptor = None
if argument.type.isPrimitive():
self.replacementVariables["typeName"] = builtinNames[argument.type.tag()]
elif argument.type.isInterface() and not argument.type.isArrayBuffer():
descriptor = descriptorProvider.getDescriptor(
argument.type.unroll().inner.identifier.name)
self.descriptor = descriptor
self.replacementVariables["typeName"] = descriptor.nativeType
).substitute(replacer)
self.replacementVariables["valPtr"] = (
"&" + self.replacementVariables["val"])
self.descriptorProvider = descriptorProvider
def define(self):
return string.Template(
re.sub(unindenter,
"",
getArgumentConversionTemplate(self.argument.type,
self.descriptor))
).substitute(self.replacementVariables)
return instantiateJSToNativeConversionTemplate(
getJSToNativeConversionTemplate(self.argument.type,
self.descriptorProvider),
self.replacementVariables).define()
def getWrapTemplateForType(type, descriptorProvider, result, successCode):
"""
@ -1460,8 +1653,45 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode):
if type is None or type.isVoid():
return setValue("JSVAL_VOID")
if type.isSequence() or type.isArray():
raise TypeError("Can't handle sequence or array return values yet")
if type.isArray():
raise TypeError("Can't handle array return values yet")
if type.isSequence():
if type.nullable():
# Nullable sequences are Nullable< nsTArray<T> >
return """
if (%s.IsNull()) {
%s
}
%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(),
getWrapTemplateForType(type.inner, descriptorProvider,
"%s.Value()" % result, successCode))
# Now do non-nullable sequences. We use setting the element
# in the array as our succcess code because when we succeed in
# wrapping that's what we should do.
innerTemplate = wrapForType(
type.inner, descriptorProvider,
{
'result' : "%s[i]" % result,
'successCode': ("if (!JS_SetElement(cx, returnArray, i, &tmp)) {\n"
" return false;\n"
"}"),
'jsvalRef': "tmp",
'jsvalPtr': "&tmp"
}
)
innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
return ("""
uint32_t length = %s.Length();
JSObject *returnArray = JS_NewArrayObject(cx, length, NULL);
if (!returnArray) {
return false;
}
jsval tmp;
for (uint32_t i = 0; i < length; ++i) {
%s
}\n""" % (result, innerTemplate)) + setValue("JS::ObjectValue(*returnArray)")
if type.isInterface() and not type.isArrayBuffer():
descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
@ -1582,6 +1812,51 @@ def wrapForType(type, descriptorProvider, templateValues):
defaultValues = {'obj': 'obj'}
return string.Template(wrap).substitute(defaultValues, **templateValues)
def getRetvalDeclarationForType(returnType, descriptorProvider,
resultAlreadyAddRefed):
if returnType is None or returnType.isVoid():
# Nothing to declare
result = None
elif returnType.isPrimitive() and returnType.tag() in builtinNames:
result = CGGeneric(builtinNames[returnType.tag()])
if returnType.nullable():
result = CGWrapper(result, pre="Nullable<", post=">")
elif returnType.isString():
result = CGGeneric("nsString")
elif returnType.isEnum():
if returnType.nullable():
raise TypeError("We don't support nullable enum return values")
result = CGGeneric(returnType.inner.identifier.name)
elif returnType.isInterface() and not returnType.isArrayBuffer():
result = CGGeneric(descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name).nativeType)
if resultAlreadyAddRefed:
result = CGWrapper(result, pre="nsRefPtr<", post=">")
else:
result = CGWrapper(result, post="*")
elif returnType.isCallback():
# XXXbz we're going to assume that callback types are always
# nullable for now.
result = CGGeneric("JSObject*")
elif returnType.tag() is IDLType.Tags.any:
result = CGGeneric("JS::Value")
elif returnType.isSequence():
nullable = returnType.nullable()
if nullable:
returnType = returnType.inner
# Assume no need to addref for now
result = CGWrapper(getRetvalDeclarationForType(returnType.inner,
descriptorProvider,
False),
pre="nsTArray< ", post=" >")
if nullable:
result = CGWrapper(result, pre="Nullable< ", post=" >")
else:
raise TypeError("Don't know how to declare return value for %s" %
returnType)
return result
class CGCallGenerator(CGThing):
"""
A class to generate an actual call to a C++ object. Assumes that the C++
@ -1594,42 +1869,16 @@ class CGCallGenerator(CGThing):
isFallible = errorReport is not None
args = CGList([CGGeneric("arg" + str(i)) for i in range(argCount)], ", ")
resultOutParam = returnType is not None and returnType.isString()
resultOutParam = (returnType is not None and
(returnType.isString() or returnType.isSequence()))
# Return values that go in outparams go here
if resultOutParam:
args.append(CGGeneric("result"))
if isFallible:
args.append(CGGeneric("rv"))
if returnType is None or returnType.isVoid():
# Nothing to declare
result = None
elif returnType.isPrimitive() and returnType.tag() in builtinNames:
result = CGGeneric(builtinNames[returnType.tag()])
if returnType.nullable():
result = CGWrapper(result, pre="Nullable<", post=">")
elif returnType.isString():
result = CGGeneric("nsString")
elif returnType.isEnum():
if returnType.nullable():
raise TypeError("We don't support nullable enum return values")
result = CGGeneric(returnType.inner.identifier.name)
elif returnType.isInterface() and not returnType.isArrayBuffer():
result = CGGeneric(descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name).nativeType)
if resultAlreadyAddRefed:
result = CGWrapper(result, pre="nsRefPtr<", post=">")
else:
result = CGWrapper(result, post="*")
elif returnType.isCallback():
# XXXbz we're going to assume that callback types are always
# nullable for now.
result = CGGeneric("JSObject*")
elif returnType.tag() is IDLType.Tags.any:
result = CGGeneric("JS::Value")
else:
raise TypeError("Don't know how to declare return value for %s" %
returnType)
result = getRetvalDeclarationForType(returnType, descriptorProvider,
resultAlreadyAddRefed)
# Build up our actual call
self.cgRoot = CGList([], "\n")
@ -1958,63 +2207,24 @@ class CGMethodCall(CGThing):
caseBody.append(CGIndenter(CGGeneric("do {")));
type = sig[1][distinguishingIndex].type
# XXXbz this duplicates some argument-unwrapping code!
interfaceDesc = descriptor.getDescriptor(
type.unroll().inner.identifier.name)
argIsPointer = (type.nullable() or
type.unroll().inner.isExternal())
if argIsPointer:
nameSuffix = ""
else:
nameSuffix = "_ptr"
if (interfaceDesc.castable or
type.unroll().inner.isExternal() or
interfaceDesc.workers):
declType = " ${typeName}*"
else:
declType = " nsCOMPtr<${typeName}>"
template = declType + " ${name}%s;\n" % nameSuffix
if interfaceDesc.castable:
template += str(CastableObjectUnwrapper(
interfaceDesc,
"&${argVal}.toObject()",
"${name}"+nameSuffix,
"break;")) + "\n"
elif interfaceDesc.workers:
template += """
${name}%s = &${argVal}.toObject();
MOZ_ASSERT(${name}%s);
""" % (nameSuffix, nameSuffix)
else:
template += " xpc_qsSelfRef tmpRef_${name};\n"
template += " jsval tmpVal_${name} = ${argVal};\n"
template += """
${typeName}* tmp;
if (NS_FAILED(xpc_qsUnwrapArg<${typeName}>(cx, ${argVal}, &tmp, &tmpRef_${name}.ptr,
&tmpVal_${name}))) {
break;
}
MOZ_ASSERT(tmp);
${name}%s = tmp;
""" % nameSuffix
if not argIsPointer:
template += " ${typeName} &${name} = *${name}_ptr;\n"
testCode = string.Template(template).substitute(
testCode = instantiateJSToNativeConversionTemplate(
getJSToNativeConversionTemplate(type, descriptor,
failureCode="break;",
isDefinitelyObject=True),
{
"typeName": interfaceDesc.nativeType,
"name" : "arg%d" % distinguishingIndex,
"argVal" : distinguishingArg
}
)
caseBody.append(CGIndenter(CGGeneric(testCode)));
"declName" : "arg%d" % distinguishingIndex,
"holderName" : ("arg%d" % distinguishingIndex) + "_holder",
"val" : distinguishingArg
})
# Indent by 4, since we need to indent further than our "do" statement
caseBody.append(CGIndenter(testCode, 4));
# If we got this far, we know we unwrapped to the right
# interface, so just do the call. Start conversion with
# distinguishingIndex + 1, since we already converted
# distinguishingIndex.
caseBody.append(CGIndenter(CGIndenter(
getPerSignatureCall(sig, distinguishingIndex + 1))))
caseBody.append(CGIndenter(
getPerSignatureCall(sig, distinguishingIndex + 1), 4))
caseBody.append(CGIndenter(CGGeneric("} while (0);")))
caseBody.append(CGGeneric("}"))
@ -2022,7 +2232,7 @@ class CGMethodCall(CGThing):
# XXXbz Now we're supposed to check for distinguishingArg being
# an array or a platform object that supports indexed
# properties... skip that last for now. It's a bit of a pain.
pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject()" %
pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
(distinguishingArg, distinguishingArg),
lambda s:
(s[1][distinguishingIndex].type.isArray() or
@ -2168,8 +2378,9 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
def definition_body(self):
unwrapThis = CGGeneric(
str(FailureFatalCastableObjectUnwrapper(self.descriptor, "obj", "self")))
unwrapThis = CGIndenter(CGGeneric(
str(FailureFatalCastableObjectUnwrapper(self.descriptor,
"obj", "&self"))))
return CGList([ self.getThis(), unwrapThis,
self.generate_code() ], "\n").define()

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

@ -47,6 +47,10 @@ public:
private:
nsresult mResult;
// Not to be implemented, to make sure people always pass this by
// reference, not by value.
ErrorResult(const ErrorResult&) MOZ_DELETE;
};
} // namespace mozilla

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

@ -52,6 +52,11 @@ public:
return mValue;
}
T& Value() {
MOZ_ASSERT(!mIsNull);
return mValue;
}
bool IsNull() const {
return mIsNull;
}

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

@ -814,10 +814,10 @@ class IDLSequenceType(IDLType):
return False
def isPrimitive(self):
return self.inner.isPrimitive()
return False;
def isString(self):
return self.inner.isString()
return False;
def isVoid(self):
return False

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

@ -104,16 +104,16 @@ class ToggleBtTask : public nsRunnable
}
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
int isEnabled = sBluedroidFunctions.bt_is_enabled();
int isEnabled = IsBluetoothEnabled();
if ((isEnabled == 1 && mEnabled) || (isEnabled == 0 && !mEnabled)) {
result = true;
} else if (isEnabled < 0) {
result = false;
} else if (mEnabled) {
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
result = (EnableBluetooth() == 0) ? true : false;
} else {
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
result = (DisableBluetooth() == 0) ? true : false;
}
#else
result = true;

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

@ -14,6 +14,21 @@ namespace mozilla {
namespace dom {
namespace bluetooth {
static struct BluedroidFunctions {
bool initialized;
bool tried_initialization;
BluedroidFunctions() :
initialized(false),
tried_initialization(false)
{
}
int (* bt_enable)();
int (* bt_disable)();
int (* bt_is_enabled)();
} sBluedroidFunctions;
bool EnsureBluetoothInit() {
if (sBluedroidFunctions.tried_initialization)
{
@ -49,6 +64,22 @@ bool EnsureBluetoothInit() {
return true;
}
int IsBluetoothEnabled()
{
return sBluedroidFunctions.bt_is_enabled();
}
int EnableBluetooth()
{
return sBluedroidFunctions.bt_enable();
}
int DisableBluetooth()
{
return sBluedroidFunctions.bt_disable();
}
}
}
}

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

@ -11,22 +11,11 @@ namespace mozilla {
namespace dom {
namespace bluetooth {
static struct BluedroidFunctions {
bool initialized;
bool tried_initialization;
BluedroidFunctions() :
initialized(false),
tried_initialization(false)
{
}
int (* bt_enable)();
int (* bt_disable)();
int (* bt_is_enabled)();
} sBluedroidFunctions;
bool EnsureBluetoothInit();
int IsBluetoothEnabled();
int EnableBluetooth();
int DisableBluetooth();
}
}
}

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

@ -222,7 +222,10 @@ IDBDatabase::Invalidate()
// When the IndexedDatabaseManager needs to invalidate databases, all it has
// is an origin, so we call back into the manager to cancel any prompts for
// our owner.
IndexedDatabaseManager::CancelPromptsForWindow(GetOwner());
nsPIDOMWindow* owner = GetOwner();
if (owner) {
IndexedDatabaseManager::CancelPromptsForWindow(owner);
}
mInvalidated = true;
}
@ -284,8 +287,6 @@ void
IDBDatabase::OnUnlink()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!GetOwner() && !GetScriptOwner(),
"Should have been cleared already!");
// We've been unlinked, at the very least we should be able to prevent further
// transactions from starting and unblock any other SetVersion callers.
@ -680,7 +681,8 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
{
NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
if (!GetOwner()) {
nsPIDOMWindow* owner = GetOwner();
if (!owner) {
return NS_OK;
}
@ -694,7 +696,7 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
CreateGenericEvent(type, eDoesNotBubble, eNotCancelable);
NS_ENSURE_STATE(duplicateEvent);
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(GetOwner()));
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(owner));
NS_ASSERTION(target, "How can this happen?!");
bool dummy;

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

@ -48,9 +48,10 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(4BF58085-9986-47B5-BB03-62BAA0451497)]
[scriptable, uuid(af4b7ca2-2694-4672-a182-8a63be79c826)]
interface nsIDOMHTMLSourceElement : nsIDOMHTMLElement
{
attribute DOMString src;
attribute DOMString type;
attribute DOMString media;
};

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

@ -144,7 +144,9 @@ MediaLoadHttpError=HTTP load failed with status %1$S. Load of media resource %2$
# LOCALIZATION NOTE: %S is the URL of the media resource which failed to load.
MediaLoadInvalidURI=Invalid URI. Load of media resource %S failed.
# LOCALIZATION NOTE: %1$S is the media resource's format/codec type (basically equivalent to the file type, e.g. MP4,AVI,WMV,MOV etc), %2$S is the URL of the media resource which failed to load.
MediaLoadUnsupportedType=Specified "type" of "%1$S" is not supported. Load of media resource %2$S failed.
MediaLoadUnsupportedTypeAttribute=Specified "type" attribute of "%1$S" is not supported. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %1$S is the "media" attribute value of the <source> element. It is a media query. %2$S is the URL of the media resource which failed to load.
MediaLoadSourceMediaNotMatched=Specified "media" attribute of "%1$S" does not match the environment. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %1$S is the MIME type HTTP header being sent by the web server, %2$S is the URL of the media resource which failed to load.
MediaLoadUnsupportedMimeType=HTTP "Content-Type" of "%1$S" is not supported. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %S is the URL of the media resource which failed to load because of error in decoding.

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

@ -226,7 +226,7 @@ static dom::ConstantSpec gWinProperties[] =
INT_CONSTANT(FILE_ATTRIBUTE_TEMPORARY),
// SetFilePointer error constant
{ "INVALID_HANDLE_VALUE", INT_TO_JSVAL((int)INVALID_HANDLE_VALUE) },
{ "INVALID_HANDLE_VALUE", INT_TO_JSVAL(INT_PTR(INVALID_HANDLE_VALUE)) },
// CreateFile flags

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

@ -521,7 +521,7 @@ protected:
class DrawTarget : public RefCounted<DrawTarget>
{
public:
DrawTarget() : mTransformDirty(false) {}
DrawTarget() : mTransformDirty(false), mPermitSubpixelAA(false) {}
virtual ~DrawTarget() {}
virtual BackendType GetType() const = 0;
@ -792,11 +792,21 @@ public:
const IntRect &GetOpaqueRect() const {
return mOpaqueRect;
}
void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
mPermitSubpixelAA = aPermitSubpixelAA;
}
bool GetPermitSubpixelAA() {
return mPermitSubpixelAA;
}
protected:
UserData mUserData;
Matrix mTransform;
IntRect mOpaqueRect;
bool mTransformDirty : 1;
bool mPermitSubpixelAA : 1;
SurfaceFormat mFormat;
};

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

@ -39,7 +39,7 @@
#include <math.h>
#include <string.h>
#include "CheckedInt.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Util.h"
#ifndef M_PI
@ -81,7 +81,7 @@ BoxBlurHorizontal(unsigned char* aInput,
memcpy(aOutput, aInput, aWidth*aRows);
return;
}
PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
uint32_t reciprocal = (uint64_t(1) << 32) / boxSize;
for (int32_t y = 0; y < aRows; y++) {
// Check whether the skip rect intersects this row. If the skip
@ -128,7 +128,7 @@ BoxBlurHorizontal(unsigned char* aInput,
int32_t last = max(tmp, 0);
int32_t next = min(tmp + boxSize, aWidth - 1);
aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
aOutput[aWidth * y + x] = (uint64_t(alphaSum) * reciprocal) >> 32;
alphaSum += aInput[aWidth * y + next] -
aInput[aWidth * y + last];
@ -159,7 +159,7 @@ BoxBlurVertical(unsigned char* aInput,
memcpy(aOutput, aInput, aWidth*aRows);
return;
}
PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
uint32_t reciprocal = (uint64_t(1) << 32) / boxSize;
for (int32_t x = 0; x < aWidth; x++) {
bool inSkipRectX = x >= aSkipRect.x &&
@ -199,7 +199,7 @@ BoxBlurVertical(unsigned char* aInput,
int32_t last = max(tmp, 0);
int32_t next = min(tmp + boxSize, aRows - 1);
aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
aOutput[aWidth * y + x] = (uint64_t(alphaSum) * reciprocal) >> 32;
alphaSum += aInput[aWidth * next + x] -
aInput[aWidth * last + x];
@ -409,12 +409,12 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
mRect = IntRect(rect.x, rect.y, rect.width, rect.height);
CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.width);
if (stride.valid()) {
if (stride.isValid()) {
mStride = stride.value();
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
sizeof(unsigned char);
if (size.valid()) {
if (size.isValid()) {
mData = static_cast<unsigned char*>(malloc(size.value()));
memset(mData, 0, size.value());
}

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

@ -47,6 +47,8 @@
#include "Tools.h"
#include <algorithm>
#include <dwrite.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
@ -67,6 +69,12 @@ typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)(
ID3D10Effect **ppEffect
);
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
DWRITE_FACTORY_TYPE factoryType,
REFIID iid,
IUnknown **factory
);
using namespace std;
namespace mozilla {
@ -78,6 +86,7 @@ struct Vertex {
};
ID2D1Factory *DrawTargetD2D::mFactory;
IDWriteFactory *DrawTargetD2D::mDWriteFactory;
// Helper class to restore surface contents that was clipped out but may have
// been altered by a drawing call.
@ -363,29 +372,9 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
RefPtr<ID3D10Texture2D> maskTexture;
RefPtr<ID3D10ShaderResourceView> maskSRView;
if (mPushedClips.size()) {
// Here we render a mask of the clipped out area for use as an input to the
// shadow drawing.
EnsureClipMaskTexture();
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
mSize.width, mSize.height,
1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
hr = mDevice->CreateTexture2D(&desc, NULL, byRef(maskTexture));
RefPtr<ID2D1RenderTarget> rt = CreateRTForTexture(maskTexture);
RefPtr<ID2D1SolidColorBrush> brush;
rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
rt->BeginDraw();
rt->Clear(D2D1::ColorF(0, 0));
rt->FillGeometry(geometry, brush);
rt->EndDraw();
mDevice->CreateShaderResourceView(maskTexture, NULL, byRef(maskSRView));
mDevice->CreateShaderResourceView(mCurrentClipMaskTexture, NULL, byRef(maskSRView));
}
IntSize srcSurfSize;
@ -891,10 +880,6 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
ScaledFontDWrite *font = static_cast<ScaledFontDWrite*>(aFont);
ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
PrepareForDrawing(rt);
IDWriteRenderingParams *params = NULL;
if (aRenderOptions) {
if (aRenderOptions->GetType() != FONT_DWRITE) {
@ -906,38 +891,28 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
}
}
if (mFormat == FORMAT_B8G8R8A8 && mPermitSubpixelAA &&
aOptions.mCompositionOp == OP_OVER && aPattern.GetType() == PATTERN_COLOR) {
if (FillGlyphsManual(font, aBuffer,
static_cast<const ColorPattern*>(&aPattern)->mColor,
params, aOptions)) {
return;
}
}
ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aPattern);
PrepareForDrawing(rt);
rt->SetTextRenderingParams(params);
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
DWRITE_GLYPH_RUN glyphRun;
glyphRun.bidiLevel = 0;
glyphRun.fontEmSize = font->mSize;
glyphRun.isSideways = FALSE;
glyphRun.fontFace = font->mFontFace;
glyphRun.glyphCount = aBuffer.mNumGlyphs;
std::vector<UINT16> indices;
std::vector<FLOAT> advances;
std::vector<DWRITE_GLYPH_OFFSET> offsets;
indices.resize(aBuffer.mNumGlyphs);
advances.resize(aBuffer.mNumGlyphs);
offsets.resize(aBuffer.mNumGlyphs);
memset(&advances.front(), 0, sizeof(FLOAT) * aBuffer.mNumGlyphs);
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
indices[i] = aBuffer.mGlyphs[i].mIndex;
offsets[i].advanceOffset = aBuffer.mGlyphs[i].mPosition.x;
offsets[i].ascenderOffset = -aBuffer.mGlyphs[i].mPosition.y;
}
glyphRun.glyphAdvances = &advances.front();
glyphRun.glyphIndices = &indices.front();
glyphRun.glyphOffsets = &offsets.front();
AutoDWriteGlyphRun autoRun;
DWriteGlyphRunFromGlyphs(aBuffer, font, &autoRun);
if (brush) {
rt->DrawGlyphRun(D2D1::Point2F(), &glyphRun, brush);
rt->DrawGlyphRun(D2D1::Point2F(), &autoRun, brush);
}
FinalizeRTForOperation(aOptions.mCompositionOp, aPattern, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
@ -981,6 +956,9 @@ DrawTargetD2D::PushClip(const Path *aPath)
return;
}
mCurrentClipMaskTexture = NULL;
mCurrentClippedGeometry = NULL;
RefPtr<PathD2D> pathD2D = static_cast<PathD2D*>(const_cast<Path*>(aPath));
PushedClip clip;
@ -1017,6 +995,8 @@ DrawTargetD2D::PushClip(const Path *aPath)
void
DrawTargetD2D::PushClipRect(const Rect &aRect)
{
mCurrentClipMaskTexture = NULL;
mCurrentClippedGeometry = NULL;
if (!mTransform.IsRectilinear()) {
// Whoops, this isn't a rectangle in device space, Direct2D will not deal
// with this transform the way we want it to.
@ -1048,6 +1028,8 @@ DrawTargetD2D::PushClipRect(const Rect &aRect)
void
DrawTargetD2D::PopClip()
{
mCurrentClipMaskTexture = NULL;
mCurrentClippedGeometry = NULL;
if (mClipsArePushed) {
if (mPushedClips.back().mLayer) {
mRT->PopLayer();
@ -1322,7 +1304,7 @@ DrawTargetD2D::InitD2DRenderTarget()
return false;
}
mRT = CreateRTForTexture(mTexture);
mRT = CreateRTForTexture(mTexture, mFormat);
if (!mRT) {
return false;
@ -1349,24 +1331,7 @@ DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT)
mTransformDirty = true;
mClipsArePushed = true;
}
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
iter != mPushedClips.end(); iter++) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (iter->mLayer) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (mFormat == FORMAT_B8G8R8X8) {
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
}
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
iter->mTransform, 1.0f, NULL,
options), iter->mLayer);
} else {
aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
}
PushClipsToRT(aRT);
}
}
FlushTransformToRT();
@ -1493,7 +1458,7 @@ DrawTargetD2D::GetRTForOperation(CompositionOp aOperator, const Pattern &aPatter
return mRT;
}
mTempRT = CreateRTForTexture(mTempTexture);
mTempRT = CreateRTForTexture(mTempTexture, FORMAT_B8G8R8A8);
if (!mTempRT) {
return mRT;
@ -1524,13 +1489,7 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
return;
}
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
mTempRT->PopLayer();
} else {
mTempRT->PopAxisAlignedClip();
}
}
PopClipsFromRT(mTempRT);
mRT->Flush();
mTempRT->Flush();
@ -1593,16 +1552,26 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
TemporaryRef<ID2D1Geometry>
DrawTargetD2D::GetClippedGeometry()
{
RefPtr<ID2D1GeometrySink> currentSink;
RefPtr<ID2D1PathGeometry> clippedGeometry;
if (mCurrentClippedGeometry) {
return mCurrentClippedGeometry;
}
factory()->CreatePathGeometry(byRef(clippedGeometry));
clippedGeometry->Open(byRef(currentSink));
RefPtr<ID2D1GeometrySink> currentSink;
factory()->CreatePathGeometry(byRef(mCurrentClippedGeometry));
mCurrentClippedGeometry->Open(byRef(currentSink));
std::vector<DrawTargetD2D::PushedClip>::iterator iter = mPushedClips.begin();
iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
iter->mTransform, currentSink);
if (iter->mPath) {
iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
iter->mTransform, currentSink);
} else {
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(iter->mBounds, byRef(rectGeom));
rectGeom->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
D2D1::IdentityMatrix(), currentSink);
}
currentSink->Close();
iter++;
@ -1611,19 +1580,27 @@ DrawTargetD2D::GetClippedGeometry()
factory()->CreatePathGeometry(byRef(newGeom));
newGeom->Open(byRef(currentSink));
clippedGeometry->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
iter->mTransform, currentSink);
if (iter->mPath) {
mCurrentClippedGeometry->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
iter->mTransform, currentSink);
} else {
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(iter->mBounds, byRef(rectGeom));
mCurrentClippedGeometry->CombineWithGeometry(rectGeom, D2D1_COMBINE_MODE_INTERSECT,
D2D1::IdentityMatrix(), currentSink);
}
currentSink->Close();
clippedGeometry = newGeom;
mCurrentClippedGeometry = newGeom;
}
return clippedGeometry;
return mCurrentClippedGeometry;
}
TemporaryRef<ID2D1RenderTarget>
DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
{
HRESULT hr;
@ -1642,7 +1619,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
if (mFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
if (aFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
alphaMode = D2D1_ALPHA_MODE_IGNORE;
}
@ -1699,18 +1676,252 @@ void
DrawTargetD2D::PopAllClips()
{
if (mClipsArePushed) {
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
mRT->PopLayer();
} else {
mRT->PopAxisAlignedClip();
}
}
PopClipsFromRT(mRT);
mClipsArePushed = false;
}
}
void
DrawTargetD2D::PushClipsToRT(ID2D1RenderTarget *aRT)
{
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
iter != mPushedClips.end(); iter++) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (iter->mLayer) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (mFormat == FORMAT_B8G8R8X8) {
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
}
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
iter->mTransform, 1.0f, NULL,
options), iter->mLayer);
} else {
aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
}
}
void
DrawTargetD2D::PopClipsFromRT(ID2D1RenderTarget *aRT)
{
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
aRT->PopLayer();
} else {
aRT->PopAxisAlignedClip();
}
}
}
void
DrawTargetD2D::EnsureClipMaskTexture()
{
if (mCurrentClipMaskTexture || mPushedClips.empty()) {
return;
}
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
mSize.width,
mSize.height,
1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
HRESULT hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mCurrentClipMaskTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create texture for ClipMask!";
return;
}
RefPtr<ID2D1RenderTarget> rt = CreateRTForTexture(mCurrentClipMaskTexture, FORMAT_A8);
if (!rt) {
gfxWarning() << "Failed to create RT for ClipMask!";
return;
}
RefPtr<ID2D1SolidColorBrush> brush;
rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
rt->BeginDraw();
rt->Clear(D2D1::ColorF(0, 0));
rt->FillGeometry(geometry, brush);
rt->EndDraw();
}
bool
DrawTargetD2D::FillGlyphsManual(ScaledFontDWrite *aFont,
const GlyphBuffer &aBuffer,
const Color &aColor,
IDWriteRenderingParams *aParams,
const DrawOptions &aOptions)
{
HRESULT hr;
RefPtr<IDWriteRenderingParams> params;
if (aParams) {
params = aParams;
} else {
mRT->GetTextRenderingParams(byRef(params));
}
DWRITE_RENDERING_MODE renderMode = DWRITE_RENDERING_MODE_DEFAULT;
if (params) {
hr = aFont->mFontFace->GetRecommendedRenderingMode(
(FLOAT)aFont->mSize,
1.0f,
DWRITE_MEASURING_MODE_NATURAL,
params,
&renderMode);
if (FAILED(hr)) {
// this probably never happens, but let's play it safe
renderMode = DWRITE_RENDERING_MODE_DEFAULT;
}
}
// Deal with rendering modes CreateGlyphRunAnalysis doesn't accept.
switch (renderMode) {
case DWRITE_RENDERING_MODE_ALIASED:
// ClearType texture creation will fail in this mode, so bail out
return false;
case DWRITE_RENDERING_MODE_DEFAULT:
// As per DWRITE_RENDERING_MODE documentation, pick Natural for font
// sizes under 16 ppem
if (aFont->mSize < 16.0f) {
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
} else {
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
}
break;
case DWRITE_RENDERING_MODE_OUTLINE:
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
break;
default:
break;
}
DWRITE_MEASURING_MODE measureMode =
renderMode <= DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ? DWRITE_MEASURING_MODE_GDI_CLASSIC :
renderMode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ? DWRITE_MEASURING_MODE_GDI_NATURAL :
DWRITE_MEASURING_MODE_NATURAL;
DWRITE_MATRIX mat = DWriteMatrixFromMatrix(mTransform);
AutoDWriteGlyphRun autoRun;
DWriteGlyphRunFromGlyphs(aBuffer, aFont, &autoRun);
RefPtr<IDWriteGlyphRunAnalysis> analysis;
hr = GetDWriteFactory()->CreateGlyphRunAnalysis(&autoRun, 1.0f, &mat,
renderMode, measureMode, 0, 0, byRef(analysis));
if (FAILED(hr)) {
return false;
}
RECT bounds;
hr = analysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &bounds);
IntRect rectBounds(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top);
IntRect surfBounds(IntPoint(0, 0), mSize);
rectBounds.IntersectRect(rectBounds, surfBounds);
if (rectBounds.IsEmpty()) {
// Nothing to do.
return true;
}
RefPtr<ID3D10Texture2D> tex = CreateTextureForAnalysis(analysis, rectBounds);
if (!tex) {
return false;
}
RefPtr<ID3D10ShaderResourceView> srView;
hr = mDevice->CreateShaderResourceView(tex, NULL, byRef(srView));
if (FAILED(hr)) {
return false;
}
MarkChanged();
// Prepare our background texture for drawing.
PopAllClips();
mRT->Flush();
SetupStateForRendering();
ID3D10EffectTechnique *technique = mPrivateData->mEffect->GetTechniqueByName("SampleTextTexture");
mPrivateData->mEffect->GetVariableByName("QuadDesc")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(-1.0f + ((Float(rectBounds.x) / mSize.width) * 2.0f),
1.0f - (Float(rectBounds.y) / mSize.height * 2.0f),
(Float(rectBounds.width) / mSize.width) * 2.0f,
(-Float(rectBounds.height) / mSize.height) * 2.0f));
mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
FLOAT color[4] = { aColor.r, aColor.g, aColor.b, aColor.a };
mPrivateData->mEffect->GetVariableByName("TextColor")->AsVector()->
SetFloatVector(color);
mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(srView);
bool isMasking = false;
if (!mPushedClips.empty()) {
RefPtr<ID2D1Geometry> geom = GetClippedGeometry();
RefPtr<ID2D1RectangleGeometry> rectGeom;
factory()->CreateRectangleGeometry(D2D1::RectF(rectBounds.x, rectBounds.y,
rectBounds.width + rectBounds.x,
rectBounds.height + rectBounds.y),
byRef(rectGeom));
D2D1_GEOMETRY_RELATION relation;
if (FAILED(geom->CompareWithGeometry(rectGeom, D2D1::IdentityMatrix(), &relation)) ||
relation != D2D1_GEOMETRY_RELATION_CONTAINS) {
isMasking = true;
}
}
if (isMasking) {
EnsureClipMaskTexture();
RefPtr<ID3D10ShaderResourceView> srViewMask;
hr = mDevice->CreateShaderResourceView(mCurrentClipMaskTexture, NULL, byRef(srViewMask));
if (FAILED(hr)) {
return false;
}
mPrivateData->mEffect->GetVariableByName("mask")->AsShaderResource()->SetResource(srViewMask);
mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(Float(rectBounds.x) / mSize.width, Float(rectBounds.y) / mSize.height,
Float(rectBounds.width) / mSize.width, Float(rectBounds.height) / mSize.height));
technique->GetPassByIndex(1)->Apply(0);
} else {
technique->GetPassByIndex(0)->Apply(0);
}
RefPtr<ID3D10RenderTargetView> rtView;
ID3D10RenderTargetView *rtViews;
mDevice->CreateRenderTargetView(mTexture, NULL, byRef(rtView));
rtViews = rtView;
mDevice->OMSetRenderTargets(1, &rtViews, NULL);
mDevice->Draw(4, 0);
}
TemporaryRef<ID2D1Brush>
DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
{
@ -1972,6 +2183,70 @@ DrawTargetD2D::CreateGradientTexture(const GradientStopsD2D *aStops)
return tex;
}
TemporaryRef<ID3D10Texture2D>
DrawTargetD2D::CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds)
{
HRESULT hr;
uint32_t bufferSize = aBounds.width * aBounds.height * 3;
RECT bounds;
bounds.left = aBounds.x;
bounds.top = aBounds.y;
bounds.right = aBounds.x + aBounds.width;
bounds.bottom = aBounds.y + aBounds.height;
// Add one byte so we can safely read a 32-bit int when copying the last
// 3 bytes.
BYTE *texture = new BYTE[bufferSize + 1];
hr = aAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1, &bounds, texture, bufferSize);
if (FAILED(hr)) {
delete [] texture;
return NULL;
}
int alignedBufferSize = aBounds.width * aBounds.height * 4;
// Create a one-off immutable texture from system memory.
BYTE *alignedTextureData = new BYTE[alignedBufferSize];
for (int y = 0; y < aBounds.height; y++) {
for (int x = 0; x < aBounds.width; x++) {
// Copy 3 Bpp source to 4 Bpp destination memory used for
// texture creation. D3D10 has no 3 Bpp texture format we can
// use.
//
// Since we don't care what ends up in the alpha pixel of the
// destination, therefor we can simply copy a normal 32 bit
// integer each time, filling the alpha pixel of the destination
// with the first subpixel of the next pixel from the source.
*((int*)(alignedTextureData + (y * aBounds.width + x) * 4)) =
*((int*)(texture + (y * aBounds.width + x) * 3));
}
}
D3D10_SUBRESOURCE_DATA data;
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
aBounds.width, aBounds.height,
1, 1);
desc.Usage = D3D10_USAGE_IMMUTABLE;
data.SysMemPitch = aBounds.width * 4;
data.pSysMem = alignedTextureData;
RefPtr<ID3D10Texture2D> tex;
hr = mDevice->CreateTexture2D(&desc, &data, byRef(tex));
delete [] alignedTextureData;
delete [] texture;
if (FAILED(hr)) {
return NULL;
}
return tex;
}
TemporaryRef<ID2D1Bitmap>
DrawTargetD2D::CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix)
{
@ -2146,6 +2421,28 @@ DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPatter
}
}
void
DrawTargetD2D::SetupStateForRendering()
{
UINT stride = sizeof(Vertex);
UINT offset = 0;
ID3D10Buffer *buff = mPrivateData->mVB;
mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
mDevice->IASetVertexBuffers(0, 1, &buff, &stride, &offset);
mDevice->IASetInputLayout(mPrivateData->mInputLayout);
D3D10_VIEWPORT viewport;
viewport.MaxDepth = 1;
viewport.MinDepth = 0;
viewport.Height = mSize.height;
viewport.Width = mSize.width;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
mDevice->RSSetViewports(1, &viewport);
}
ID2D1Factory*
DrawTargetD2D::factory()
{
@ -2182,5 +2479,32 @@ DrawTargetD2D::factory()
return mFactory;
}
IDWriteFactory*
DrawTargetD2D::GetDWriteFactory()
{
if (mDWriteFactory) {
return mDWriteFactory;
}
DWriteCreateFactoryFunc createDWriteFactory;
HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll");
createDWriteFactory = (DWriteCreateFactoryFunc)
GetProcAddress(dwriteModule, "DWriteCreateFactory");
if (!createDWriteFactory) {
gfxWarning() << "Failed to locate DWriteCreateFactory function.";
return NULL;
}
HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&mDWriteFactory));
if (FAILED(hr)) {
gfxWarning() << "Failed to create DWrite Factory.";
}
return mDWriteFactory;
}
}
}

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

@ -52,12 +52,15 @@
#include <unordered_set>
#endif
struct IDWriteFactory;
namespace mozilla {
namespace gfx {
class SourceSurfaceD2DTarget;
class SourceSurfaceD2D;
class GradientStopsD2D;
class ScaledFontDWrite;
struct PrivateD3D10DataD2D
{
@ -153,6 +156,7 @@ public:
static ID2D1Factory *factory();
static TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
static IDWriteFactory *GetDWriteFactory();
operator std::string() const {
std::stringstream stream;
@ -187,13 +191,26 @@ private:
ID2D1RenderTarget *GetRTForOperation(CompositionOp aOperator, const Pattern &aPattern);
void FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aPattern, const Rect &aBounds); void EnsureViews();
void PopAllClips();
void PushClipsToRT(ID2D1RenderTarget *aRT);
void PopClipsFromRT(ID2D1RenderTarget *aRT);
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
// This function ensures mCurrentClipMaskTexture contains a texture containing
// a mask corresponding with the current DrawTarget clip.
void EnsureClipMaskTexture();
bool FillGlyphsManual(ScaledFontDWrite *aFont,
const GlyphBuffer &aBuffer,
const Color &aColor,
IDWriteRenderingParams *aParams,
const DrawOptions &aOptions = DrawOptions());
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
TemporaryRef<ID2D1Geometry> GetClippedGeometry();
TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
TemporaryRef<ID3D10Texture1D> CreateGradientTexture(const GradientStopsD2D *aStops);
TemporaryRef<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds);
// This creates a partially uploaded bitmap for a SourceSurfaceD2D that is
// too big to fit in a bitmap. It adjusts the passed Matrix to accomodate the
@ -201,6 +218,7 @@ private:
TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix);
void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
void SetupStateForRendering();
static const uint32_t test = 4;
@ -208,6 +226,8 @@ private:
RefPtr<ID3D10Device1> mDevice;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
RefPtr<ID2D1PathGeometry> mCurrentClippedGeometry;
mutable RefPtr<ID2D1RenderTarget> mRT;
// Temporary texture and render target used for supporting alternative operators.
@ -239,6 +259,7 @@ private:
bool mClipsArePushed;
PrivateD3D10DataD2D *mPrivateData;
static ID2D1Factory *mFactory;
static IDWriteFactory *mDWriteFactory;
};
}

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

@ -39,8 +39,11 @@
#define MOZILLA_GFX_HELPERSD2D_H_
#include <d2d1.h>
#include <dwrite.h>
#include "2D.h"
#include "ScaledFontDWrite.h"
namespace mozilla {
namespace gfx {
@ -212,6 +215,78 @@ struct ShaderConstantRectD3D10
operator float* () { return &mX; }
};
static DWRITE_MATRIX
DWriteMatrixFromMatrix(Matrix &aMatrix)
{
DWRITE_MATRIX mat;
mat.m11 = aMatrix._11;
mat.m12 = aMatrix._12;
mat.m21 = aMatrix._21;
mat.m22 = aMatrix._22;
mat.dx = aMatrix._31;
mat.dy = aMatrix._32;
return mat;
}
class AutoDWriteGlyphRun : public DWRITE_GLYPH_RUN
{
static const int kNumAutoGlyphs = 256;
public:
AutoDWriteGlyphRun() {
glyphCount = 0;
}
~AutoDWriteGlyphRun() {
if (glyphCount > kNumAutoGlyphs) {
delete[] glyphIndices;
delete[] glyphAdvances;
delete[] glyphOffsets;
}
}
void allocate(int aNumGlyphs) {
glyphCount = aNumGlyphs;
if (aNumGlyphs <= kNumAutoGlyphs) {
glyphIndices = &mAutoIndices[0];
glyphAdvances = &mAutoAdvances[0];
glyphOffsets = &mAutoOffsets[0];
} else {
glyphIndices = new UINT16[aNumGlyphs];
glyphAdvances = new FLOAT[aNumGlyphs];
glyphOffsets = new DWRITE_GLYPH_OFFSET[aNumGlyphs];
}
}
private:
DWRITE_GLYPH_OFFSET mAutoOffsets[kNumAutoGlyphs];
FLOAT mAutoAdvances[kNumAutoGlyphs];
UINT16 mAutoIndices[kNumAutoGlyphs];
};
static void
DWriteGlyphRunFromGlyphs(const GlyphBuffer &aGlyphs, ScaledFontDWrite *aFont, AutoDWriteGlyphRun *run)
{
run->allocate(aGlyphs.mNumGlyphs);
FLOAT *advances = const_cast<FLOAT*>(run->glyphAdvances);
UINT16 *indices = const_cast<UINT16*>(run->glyphIndices);
DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run->glyphOffsets);
memset(advances, 0, sizeof(FLOAT) * aGlyphs.mNumGlyphs);
for (unsigned int i = 0; i < aGlyphs.mNumGlyphs; i++) {
indices[i] = aGlyphs.mGlyphs[i].mIndex;
offsets[i].advanceOffset = aGlyphs.mGlyphs[i].mPosition.x;
offsets[i].ascenderOffset = -aGlyphs.mGlyphs[i].mPosition.y;
}
run->bidiLevel = 0;
run->fontFace = aFont->mFontFace;
run->fontEmSize = aFont->mSize;
run->glyphCount = aGlyphs.mNumGlyphs;
run->isSideways = FALSE;
}
}
}

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

@ -39,6 +39,7 @@
#include "mozilla/Attributes.h"
#include <xmmintrin.h>
#include <emmintrin.h>
/* The functions below use the following system for averaging 4 pixels:
*

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

@ -59,9 +59,6 @@ public:
virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder);
private:
friend class DrawTargetD2D;
void CopyGlyphsToSink(const GlyphBuffer &aBuffer, ID2D1GeometrySink *aSink);
RefPtr<IDWriteFontFace> mFontFace;

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

@ -14,6 +14,7 @@ cbuffer cb0
float4 QuadDesc;
float4 TexCoords;
float4 MaskTexCoords;
float4 TextColor;
}
cbuffer cb1
@ -50,6 +51,12 @@ struct VS_RADIAL_OUTPUT
float2 PixelCoord : TEXCOORD1;
};
struct PS_TEXT_OUTPUT
{
float4 color;
float4 alpha;
};
Texture2D tex;
Texture2D mask;
@ -113,6 +120,19 @@ BlendState ShadowBlendV
RenderTargetWriteMask[0] = 0xF;
};
BlendState bTextBlend
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = TRUE;
SrcBlend = Src1_Color;
DestBlend = Inv_Src1_Color;
BlendOp = Add;
SrcBlendAlpha = Src1_Alpha;
DestBlendAlpha = Inv_Src1_Alpha;
BlendOpAlpha = Add;
RenderTargetWriteMask[0] = 0x0F; // All
};
VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
{
VS_OUTPUT Output;
@ -278,6 +298,26 @@ float4 SampleMaskShadowVPS( VS_OUTPUT In) : SV_Target
return outputColor * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
};
PS_TEXT_OUTPUT SampleTextTexturePS( VS_OUTPUT In) : SV_Target
{
PS_TEXT_OUTPUT output;
output.color = TextColor;
output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a;
return output;
};
PS_TEXT_OUTPUT SampleTextTexturePSMasked( VS_OUTPUT In) : SV_Target
{
PS_TEXT_OUTPUT output;
float maskValue = mask.Sample(sMaskSampler, In.MaskTexCoord).a;
output.color = TextColor * maskValue;
output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a * maskValue;
return output;
};
technique10 SampleTexture
{
pass P0
@ -375,4 +415,23 @@ technique10 SampleTextureWithShadow
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskShadowVPS()));
}
}
}
technique10 SampleTextTexture
{
pass Unmasked
{
SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePS()));
}
pass Masked
{
SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePSMasked()));
}
}

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

@ -39,6 +39,9 @@
#define MOZILLA_GFX_TOOLS_H_
#include "Types.h"
#if defined(_MSC_VER) && (_MSC_VER < 1600)
#define hypotf _hypotf
#endif
namespace mozilla {
namespace gfx {

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

@ -129,8 +129,6 @@ public:
#endif
#include "mozilla/Preferences.h"
#include "nsIScreen.h"
#include "nsIScreenManager.h"
#include "gfxUtils.h"
#include "gfxFailure.h"
#include "gfxASurface.h"
@ -1401,17 +1399,6 @@ CreateConfig(EGLConfig* aConfig, PRInt32 depth)
return false;
}
static int
GetScreenDepth()
{
nsCOMPtr<nsIScreenManager> screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
nsCOMPtr<nsIScreen> screen;
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
PRInt32 depth = 24;
screen->GetColorDepth(&depth);
return depth;
}
// Return true if a suitable EGLConfig was found and pass it out
// through aConfig. Return false otherwise.
//
@ -1420,7 +1407,7 @@ GetScreenDepth()
static bool
CreateConfig(EGLConfig* aConfig)
{
PRInt32 depth = GetScreenDepth();
PRInt32 depth = gfxPlatform::GetPlatform()->GetScreenDepth();
if (!CreateConfig(aConfig, depth)) {
#ifdef MOZ_WIDGET_ANDROID
// Bug 736005
@ -1492,7 +1479,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
void* currentContext = sEGLLibrary.fGetCurrentContext();
if (aWidget->HasGLContext() && currentContext) {
PRInt32 depth = GetScreenDepth();
PRInt32 depth = gfxPlatform::GetPlatform()->GetScreenDepth();
void* platformContext = currentContext;
#ifdef MOZ_WIDGET_QT
QGLContext* context = const_cast<QGLContext*>(QGLContext::currentContext());

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

@ -599,21 +599,33 @@ static void
SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget)
{
if (!aTarget->IsCairo()) {
// Azure targets don't contain antialiasing flags at this point.
return;
}
RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
nsRefPtr<gfxASurface> surface = aTarget->CurrentSurface();
if (surface->GetContentType() != gfxASurface::CONTENT_COLOR_ALPHA) {
// Destination doesn't have alpha channel; no need to set any special flags
return;
}
if (dt->GetFormat() != FORMAT_B8G8R8A8) {
return;
}
const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
surface->SetSubpixelAntialiasingEnabled(
!(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
surface->GetOpaqueRect().Contains(
aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height))));
const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
Rect transformedBounds = dt->GetTransform().TransformBounds(Rect(Float(bounds.x), Float(bounds.y),
Float(bounds.width), Float(bounds.height)));
transformedBounds.RoundOut();
IntRect intTransformedBounds;
transformedBounds.ToIntRect(&intTransformedBounds);
dt->SetPermitSubpixelAA(!(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
dt->GetOpaqueRect().Contains(intTransformedBounds));
} else {
nsRefPtr<gfxASurface> surface = aTarget->CurrentSurface();
if (surface->GetContentType() != gfxASurface::CONTENT_COLOR_ALPHA) {
// Destination doesn't have alpha channel; no need to set any special flags
return;
}
const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
surface->SetSubpixelAntialiasingEnabled(
!(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
surface->GetOpaqueRect().Contains(
aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height))));
}
}
already_AddRefed<gfxContext>

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

@ -484,6 +484,8 @@ ThebesLayerD3D10::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode)
if (mD2DSurface) {
mD2DSurface->SetSubpixelAntialiasingEnabled(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
} else if (mDrawTarget) {
mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
}
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();

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

@ -882,6 +882,9 @@ ShadowImageLayerOGL::LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize)
void
ShadowImageLayerOGL::CleanupResources()
{
mYUVTexture[0].Release();
mYUVTexture[1].Release();
mYUVTexture[2].Release();
mTexImage = nsnull;
}

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

@ -82,8 +82,8 @@ public:
GLuint GetTextureID() { return mTexture; }
GLContext *GetGLContext() { return mContext; }
private:
void Release();
private:
nsRefPtr<GLContext> mContext;
GLuint mTexture;

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

@ -38,7 +38,7 @@
#include "nsIMemoryReporter.h"
#include "nsMemory.h"
#include "CheckedInt.h"
#include "mozilla/CheckedInt.h"
#include "gfxASurface.h"
#include "gfxContext.h"
@ -378,7 +378,7 @@ gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, PRInt32 limit)
// make sure the surface area doesn't overflow a PRInt32
CheckedInt<PRInt32> tmp = sz.width;
tmp *= sz.height;
if (!tmp.valid()) {
if (!tmp.isValid()) {
NS_WARNING("Surface size too large (would overflow)!");
return false;
}
@ -386,7 +386,7 @@ gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, PRInt32 limit)
// assuming 4-byte stride, make sure the allocation size
// doesn't overflow a PRInt32 either
tmp *= 4;
if (!tmp.valid()) {
if (!tmp.isValid()) {
NS_WARNING("Allocation too large (would overflow)!");
return false;
}

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

@ -63,11 +63,12 @@ gfxAndroidPlatform::gfxAndroidPlatform()
nsCOMPtr<nsIScreenManager> screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
nsCOMPtr<nsIScreen> screen;
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
PRInt32 depth = 24;
screen->GetColorDepth(&depth);
mScreenDepth = 24;
screen->GetColorDepth(&mScreenDepth);
mOffscreenFormat = depth == 16 ? gfxASurface::ImageFormatRGB16_565 :
gfxASurface::ImageFormatARGB32;
mOffscreenFormat = mScreenDepth == 16
? gfxASurface::ImageFormatRGB16_565
: gfxASurface::ImageFormatARGB32;
}
gfxAndroidPlatform::~gfxAndroidPlatform()
@ -232,3 +233,9 @@ gfxAndroidPlatform::FontHintingEnabled()
return (XRE_GetProcessType() != GeckoProcessType_Content);
#endif // MOZ_USING_ANDROID_JAVA_WIDGETS
}
int
gfxAndroidPlatform::GetScreenDepth() const
{
return mScreenDepth;
}

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

@ -103,7 +103,10 @@ public:
FT_Library GetFTLibrary();
virtual int GetScreenDepth() const;
private:
int mScreenDepth;
gfxImageFormat mOffscreenFormat;
};

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

@ -930,23 +930,33 @@ public:
gfxContextAutoDisableSubpixelAntialiasing(gfxContext *aContext, bool aDisable)
{
if (aDisable) {
mSurface = aContext->CurrentSurface();
if (!mSurface) {
return;
if (aContext->IsCairo()) {
mSurface = aContext->CurrentSurface();
if (!mSurface) {
return;
}
mSubpixelAntialiasingEnabled = mSurface->GetSubpixelAntialiasingEnabled();
mSurface->SetSubpixelAntialiasingEnabled(false);
} else {
mDT = aContext->GetDrawTarget();
mSubpixelAntialiasingEnabled = mDT->GetPermitSubpixelAA();
mDT->SetPermitSubpixelAA(false);
}
mSubpixelAntialiasingEnabled = mSurface->GetSubpixelAntialiasingEnabled();
mSurface->SetSubpixelAntialiasingEnabled(false);
}
}
~gfxContextAutoDisableSubpixelAntialiasing()
{
if (mSurface) {
mSurface->SetSubpixelAntialiasingEnabled(mSubpixelAntialiasingEnabled);
} else if (mDT) {
mDT->SetPermitSubpixelAA(mSubpixelAntialiasingEnabled);
}
}
private:
nsRefPtr<gfxASurface> mSurface;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDT;
bool mSubpixelAntialiasingEnabled;
};

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

@ -86,6 +86,7 @@
#include "mozilla/FunctionTimer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Assertions.h"
#include "nsIGfxInfo.h"
@ -1437,3 +1438,10 @@ gfxPlatform::GetLog(eGfxLog aWhichLog)
return nsnull;
#endif
}
int
gfxPlatform::GetScreenDepth() const
{
MOZ_ASSERT(false, "Not implemented on this platform");
return 0;
}

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

@ -457,6 +457,8 @@ public:
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
virtual int GetScreenDepth() const;
protected:
gfxPlatform();
virtual ~gfxPlatform();

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

@ -11,4 +11,6 @@ body > :first-child {
right: 0;
bottom: 0;
left: 0;
background-color: #fff;
color: #222;
}

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

@ -11,4 +11,6 @@ img {
right: 0;
bottom: 0;
left: 0;
background-color: #fff;
color: #222;
}

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

@ -11,4 +11,6 @@ body > :first-child {
right: 0;
bottom: 0;
left: 0;
background-color: #fff;
color: #222;
}

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

@ -11,4 +11,6 @@ body > :first-child {
right: 0;
bottom: 0;
left: 0;
background-color: #fff;
color: #222;
}

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

@ -17,5 +17,5 @@ function handleRequest(request, response)
response.setHeader("Content-Type", "text/html");
response.setHeader("Cache-Control", "no-cache");
response.write("<link rel=\"stylesheet\" href=\"ImageDocument.css\">");
response.write("<img src=\"moz-icon:" + uri + "\">");
response.write("<img src=\"moz-icon:" + uri + "\" width=\"32\" height=\"32\">");
}

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

@ -55,6 +55,7 @@
#include "jsdebug.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "nsCycleCollectionParticipant.h"
/* XXX DOM dependency */
#include "nsIScriptContext.h"
@ -2450,7 +2451,42 @@ jsdValue::GetScript(jsdIScript **_rval)
/******************************************************************************
* debugger service implementation
******************************************************************************/
NS_IMPL_THREADSAFE_ISUPPORTS1(jsdService, jsdIDebuggerService)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(jsdService)
NS_INTERFACE_MAP_ENTRY(jsdIDebuggerService)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, jsdIDebuggerService)
NS_INTERFACE_MAP_END
/* NS_IMPL_CYCLE_COLLECTION_10(jsdService, ...) */
NS_IMPL_CYCLE_COLLECTION_CLASS(jsdService)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(jsdService)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mErrorHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBreakpointHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDebugHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDebuggerHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInterruptHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mThrowHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTopLevelHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFunctionHook)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mActivationCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(jsdService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mErrorHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBreakpointHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDebugHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDebuggerHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInterruptHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mThrowHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTopLevelHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFunctionHook)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mActivationCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(jsdService)
NS_IMPL_CYCLE_COLLECTING_RELEASE(jsdService)
NS_IMETHODIMP
jsdService::GetJSDContext(JSDContext **_rval)

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