зеркало из https://github.com/mozilla/gecko-dev.git
Merge from mozilla-central.
--HG-- rename : xpcom/ds/CheckedInt.h => mfbt/CheckedInt.h
This commit is contained in:
Коммит
693dcc5c78
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
12
gfx/2d/2D.h
12
gfx/2d/2D.h
|
@ -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)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче