--- a/accessible/src/base/AccTypes.h
+++ b/accessible/src/base/AccTypes.h
@@ -8,37 +8,37 @@
namespace mozilla {
namespace a11y {
/**
* Accessible object types used when creating an accessible based on the frame.
*/
enum AccType {
- eNoAccessible,
- eHTMLBRAccessible,
- eHTMLButtonAccessible,
- eHTMLCanvasAccessible,
- eHTMLCaptionAccessible,
- eHTMLCheckboxAccessible,
- eHTMLComboboxAccessible,
- eHTMLFileInputAccessible,
- eHTMLGroupboxAccessible,
- eHTMLHRAccessible,
- eHTMLImageMapAccessible,
- eHTMLLabelAccessible,
- eHTMLLiAccessible,
- eHTMLSelectListAccessible,
- eHTMLMediaAccessible,
- eHTMLObjectFrameAccessible,
- eHTMLRadioButtonAccessible,
- eHTMLTableAccessible,
- eHTMLTableCellAccessible,
- eHTMLTableRowAccessible,
- eHTMLTextFieldAccessible,
- eHyperTextAccessible,
- eImageAccessible,
- eOuterDocAccessible,
- eTextLeafAccessible
+ eNoType,
+ eHTMLBR,
+ eHTMLButton,
+ eHTMLCanvas,
+ eHTMLCaption,
+ eHTMLCheckbox,
+ eHTMLCombobox,
+ eHTMLFileInput,
+ eHTMLGroupbox,
+ eHTMLHR,
+ eHTMLImageMap,
+ eHTMLLabel,
+ eHTMLLi,
+ eHTMLSelectList,
+ eHTMLMedia,
+ eHTMLRadioButton,
+ eHTMLTable,
+ eHTMLTableCell,
+ eHTMLTableRow,
+ eHTMLTextField,
+ eHyperText,
+ eImage,
+ eOuterDoc,
+ ePlugin,
+ eTextLeaf
};
}
}
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -202,19 +202,19 @@ nsAccessibilityService::GetRootDocumentA
return aCanCreate ?
GetDocAccessible(documentNode) : GetDocAccessibleFromCache(documentNode);
}
}
return nullptr;
}
already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
- nsIContent* aContent,
- Accessible* aContext)
+nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
+ nsIContent* aContent,
+ Accessible* aContext)
{
// nsObjectFrame means a plugin, so we need to use the accessibility support
// of the plugin.
if (aFrame->GetRect().IsEmpty())
return nullptr;
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
@@ -794,53 +794,53 @@ nsAccessibilityService::GetOrCreateAcces
}
if (!newAcc && isHTML) { // HTML accessibles
if (roleMapEntry) {
// Create pure ARIA grid/treegrid related accessibles if they weren't used
// on accessible HTML table elements.
if ((roleMapEntry->accTypes & Accessible::eTableCellAccessible)) {
if (aContext->IsOfType(Accessible::eTableRowAccessible) &&
- (frame->AccessibleType() != eHTMLTableCellAccessible ||
+ (frame->AccessibleType() != eHTMLTableCell ||
aContext->GetContent() != content->GetParent())) {
newAcc = new ARIAGridCellAccessibleWrap(content, document);
}
} else if ((roleMapEntry->accTypes & Accessible::eTableAccessible) &&
- frame->AccessibleType() != eHTMLTableAccessible) {
+ frame->AccessibleType() != eHTMLTable) {
newAcc = new ARIAGridAccessibleWrap(content, document);
}
}
if (!newAcc) {
// Prefer to use markup (mostly tag name, perhaps attributes) to decide if
// and what kind of accessible to create.
newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext);
// Try using frame to do it.
if (!newAcc)
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
// If table has strong ARIA role then all table descendants shouldn't
// expose their native roles.
if (!roleMapEntry && newAcc) {
- if (frame->AccessibleType() == eHTMLTableRowAccessible) {
+ if (frame->AccessibleType() == eHTMLTableRow) {
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
if (contextRoleMap &&
!(contextRoleMap->accTypes & Accessible::eTableAccessible))
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
- } else if (frame->AccessibleType() == eHTMLTableCellAccessible &&
+ } else if (frame->AccessibleType() == eHTMLTableCell &&
aContext->ARIARoleMap() == &nsARIAMap::gEmptyRoleMap) {
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
} else if (content->Tag() == nsGkAtoms::dt ||
content->Tag() == nsGkAtoms::li ||
content->Tag() == nsGkAtoms::dd ||
- frame->AccessibleType() == eHTMLLiAccessible) {
+ frame->AccessibleType() == eHTMLLi) {
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
if (contextRoleMap &&
!(contextRoleMap->accTypes & Accessible::eListAccessible))
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
}
}
}
}
@@ -1301,85 +1301,79 @@ already_AddRefed<Accessible>
nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
nsIContent* aContent,
Accessible* aContext)
{
DocAccessible* document = aContext->Document();
nsRefPtr<Accessible> newAcc;
switch (aFrame->AccessibleType()) {
- case eNoAccessible:
+ case eNoType:
return nullptr;
- case eHTMLBRAccessible:
+ case eHTMLBR:
newAcc = new HTMLBRAccessible(aContent, document);
break;
- case eHTMLButtonAccessible:
+ case eHTMLButton:
newAcc = new HTMLButtonAccessible(aContent, document);
break;
- case eHTMLCanvasAccessible:
+ case eHTMLCanvas:
newAcc = new HTMLCanvasAccessible(aContent, document);
break;
- case eHTMLCaptionAccessible:
+ case eHTMLCaption:
if (aContext->IsOfType(Accessible::eTableAccessible) &&
aContext->GetContent() == aContent->GetParent()) {
newAcc = new HTMLCaptionAccessible(aContent, document);
}
break;
- case eHTMLCheckboxAccessible:
+ case eHTMLCheckbox:
newAcc = new HTMLCheckboxAccessible(aContent, document);
break;
- case eHTMLComboboxAccessible:
+ case eHTMLCombobox:
newAcc = new HTMLComboboxAccessible(aContent, document);
break;
- case eHTMLFileInputAccessible:
+ case eHTMLFileInput:
newAcc = new HTMLFileInputAccessible(aContent, document);
break;
- case eHTMLGroupboxAccessible:
+ case eHTMLGroupbox:
newAcc = new HTMLGroupboxAccessible(aContent, document);
break;
- case eHTMLHRAccessible:
+ case eHTMLHR:
newAcc = new HTMLHRAccessible(aContent, document);
break;
- case eHTMLImageMapAccessible:
+ case eHTMLImageMap:
newAcc = new HTMLImageMapAccessible(aContent, document);
break;
- case eHTMLLabelAccessible:
+ case eHTMLLabel:
newAcc = new HTMLLabelAccessible(aContent, document);
break;
- case eHTMLLiAccessible:
+ case eHTMLLi:
if (aContext->IsOfType(Accessible::eListAccessible) &&
aContext->GetContent() == aContent->GetParent()) {
newAcc = new HTMLLIAccessible(aContent, document);
}
break;
- case eHTMLSelectListAccessible:
+ case eHTMLSelectList:
newAcc = new HTMLSelectListAccessible(aContent, document);
break;
- case eHTMLMediaAccessible:
+ case eHTMLMedia:
newAcc = new EnumRoleAccessible(aContent, document, roles::GROUPING);
break;
- case eHTMLObjectFrameAccessible: {
- nsObjectFrame* objectFrame = do_QueryFrame(aFrame);
- newAcc = CreateHTMLObjectFrameAccessible(objectFrame, aContent, aContext);
- break;
- }
-
- case eHTMLRadioButtonAccessible:
+ case eHTMLRadioButton:
newAcc = new HTMLRadioButtonAccessible(aContent, document);
break;
- case eHTMLTableAccessible:
+ case eHTMLTable:
newAcc = new HTMLTableAccessibleWrap(aContent, document);
break;
- case eHTMLTableCellAccessible:
+ case eHTMLTableCell:
// Accessible HTML table cell must be a child of accessible HTML table row.
if (aContext->IsOfType(Accessible::eHTMLTableRowAccessible))
newAcc = new HTMLTableCellAccessibleWrap(aContent, document);
break;
- case eHTMLTableRowAccessible: {
+ case eHTMLTableRow: {
// Accessible HTML table row must be a child of tbody/tfoot/thead of
// accessible HTML table or must be a child of accessible of HTML table.
if (aContext->IsOfType(Accessible::eTableAccessible)) {
nsIContent* parentContent = aContent->GetParent();
nsIFrame* parentFrame = parentContent->GetPrimaryFrame();
if (parentFrame->GetType() == nsGkAtoms::tableRowGroupFrame) {
parentContent = parentContent->GetParent();
parentFrame = parentContent->GetPrimaryFrame();
@@ -1387,31 +1381,36 @@ nsAccessibilityService::CreateAccessible
if (parentFrame->GetType() == nsGkAtoms::tableOuterFrame &&
aContext->GetContent() == parentContent) {
newAcc = new HTMLTableRowAccessible(aContent, document);
}
}
break;
}
- case eHTMLTextFieldAccessible:
+ case eHTMLTextField:
newAcc = new HTMLTextFieldAccessible(aContent, document);
break;
- case eHyperTextAccessible:
+ case eHyperText:
if (aContent->Tag() != nsGkAtoms::dt && aContent->Tag() != nsGkAtoms::dd)
newAcc = new HyperTextAccessibleWrap(aContent, document);
break;
- case eImageAccessible:
+ case eImage:
newAcc = new ImageAccessibleWrap(aContent, document);
break;
- case eOuterDocAccessible:
+ case eOuterDoc:
newAcc = new OuterDocAccessible(aContent, document);
break;
- case eTextLeafAccessible:
+ case ePlugin: {
+ nsObjectFrame* objectFrame = do_QueryFrame(aFrame);
+ newAcc = CreatePluginAccessible(objectFrame, aContent, aContext);
+ break;
+ }
+ case eTextLeaf:
newAcc = new TextLeafAccessibleWrap(aContent, document);
break;
}
return newAcc.forget();
}
////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -49,18 +49,18 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLERETRIEVAL
NS_DECL_NSIOBSERVER
// nsIAccessibilityService
virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
bool aCanCreate);
already_AddRefed<Accessible>
- CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
- Accessible* aContext);
+ CreatePluginAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
+ Accessible* aContext);
/**
* Adds/remove ATK root accessible for gtk+ native window to/from children
* of the application accessible.
*/
virtual Accessible* AddNativeRootAccessible(void* aAtkAccessible);
virtual void RemoveNativeRootAccessible(Accessible* aRootAccessible);
--- a/b2g/config/otoro/config.json
+++ b/b2g/config/otoro/config.json
@@ -1,18 +1,16 @@
{
"config_version": 1,
"tooltool_manifest": "releng-otoro.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": [],
"upload_files": [
- "{objdir}/dist/b2g-update/*.mar",
- "{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{workdir}/sources.xml"
],
"zip_files": [
["{workdir}/out/target/product/otoro/*.img", "out/target/product/otoro/"],
"{workdir}/boot.img",
"{workdir}/flash.sh",
"{workdir}/load-config.sh",
--- a/b2g/config/panda-gaia-central/config.json
+++ b/b2g/config/panda-gaia-central/config.json
@@ -3,18 +3,16 @@
"tooltool_manifest": "releng-pandaboard.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": ["boottarball", "systemtarball", "userdatatarball", "package-tests"],
"upload_files": [
"{workdir}/out/target/product/panda/*.tar.bz2",
"{workdir}/out/target/product/panda/tests/*.zip",
- "{objdir}/dist/b2g-update/*.mar",
- "{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{srcdir}/b2g/config/panda/README",
"{workdir}/sources.xml"
],
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
"gaia": {
"vcs": "hgtool",
"repo": "http://hg.mozilla.org/integration/gaia-central",
--- a/b2g/config/panda/config.json
+++ b/b2g/config/panda/config.json
@@ -3,18 +3,16 @@
"tooltool_manifest": "releng-pandaboard.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": ["boottarball", "systemtarball", "userdatatarball", "package-tests"],
"upload_files": [
"{workdir}/out/target/product/panda/*.tar.bz2",
"{workdir}/out/target/product/panda/tests/*.zip",
- "{objdir}/dist/b2g-update/*.mar",
- "{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{srcdir}/b2g/config/panda/README",
"{workdir}/sources.xml"
],
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
"gaia": {
"vcs": "hgtool",
"repo": "http://hg.mozilla.org/integration/gaia-nightly",
--- a/b2g/config/tooltool-manifests/macosx64/releng.manifest
+++ b/b2g/config/tooltool-manifests/macosx64/releng.manifest
@@ -1,17 +1,17 @@
[
{
-"clang_version": "r169139"
+"clang_version": "r169730"
},
{
"size": 47,
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
-"size": 56158651,
-"digest": "38d718f20a8fa9218e22ade312e724e6c9cdd7c6650e023cfdc21b5505fe7aa3743ae41c0abd717a1bbccec4c4271be2fa82d0e2f96c91e693d70e33b4dc00d6",
+"size": 56115091,
+"digest": "d7188264f28d6f6a84fab9737520cad22fe3d575917a87fc110d0b9a2033617c35da83530ea20553f5c55a996459f750fa2d0c49288c1fb9671f6252a92cf4c9",
"algorithm": "sha512",
"filename": "clang.tar.bz2"
}
]
--- a/b2g/config/unagi/config.json
+++ b/b2g/config/unagi/config.json
@@ -2,17 +2,16 @@
"config_version": 1,
"tooltool_manifest": "releng-unagi.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": [],
"upload_files": [
"{objdir}/dist/b2g-update/*.mar",
- "{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{workdir}/sources.xml"
],
"zip_files": [
["{workdir}/out/target/product/unagi/*.img", "out/target/product/unagi/"],
"{workdir}/boot.img",
"{workdir}/flash.sh",
"{workdir}/load-config.sh",
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -246,16 +246,17 @@ var gPluginHandler = {
// Hide the in-content UI if it's too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed") {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
if (overlay != null && self.isTooSmall(plugin, overlay))
overlay.style.visibility = "hidden";
}
},
+ _notificationDisplayedOnce: false,
handlePluginScripted: function PH_handlePluginScripted(aBrowser) {
let contentWindow = aBrowser.contentWindow;
if (!contentWindow)
return;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let haveVisibleCTPPlugin = cwu.plugins.some(function(plugin) {
@@ -273,19 +274,20 @@ var gPluginHandler = {
let isInvisible = ((computedStyle.width == "240px" &&
computedStyle.height == "200px") ||
gPluginHandler.isTooSmall(plugin, overlay));
return (!isInvisible &&
gPluginHandler.canActivatePlugin(objLoadingContent));
});
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
- if (notification && !haveVisibleCTPPlugin) {
+ if (notification && !haveVisibleCTPPlugin && !this._notificationDisplayedOnce) {
notification.dismissed = false;
PopupNotifications._update(notification.anchorElement);
+ this._notificationDisplayedOnce = true;
}
aBrowser._pluginScriptedState = PLUGIN_SCRIPTED_STATE_DONE;
},
isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
@@ -638,18 +640,19 @@ var gPluginHandler = {
if (notification)
notification.remove();
gPluginHandler._removeClickToPlayOverlays(contentWindow);
}
}];
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let dismissed = notification ? notification.dismissed : true;
let options = { dismissed: dismissed, centerActions: centerActions };
+ let icon = haveVulnerablePlugin ? "blocked-plugins-notification-icon" : "plugins-notification-icon"
PopupNotifications.show(aBrowser, "click-to-play-plugins",
- messageString, "plugins-notification-icon",
+ messageString, icon,
mainAction, secondaryActions, options);
},
_removeClickToPlayOverlays: function PH_removeClickToPlayOverlays(aContentWindow) {
let doc = aContentWindow.document;
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
for (let plugin of cwu.plugins) {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -552,16 +552,17 @@
<image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
+ <image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
</box>
<!-- Use onclick instead of normal popup= syntax since the popup
code fires onmousedown, and hence eats our favicon drag events.
We only add the identity-box button to the tab order when the location bar
has focus, otherwise pressing F6 focuses it instead of the location bar -->
<box id="identity-box" role="button"
align="center"
onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -5,16 +5,17 @@
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
DIRS += \
newtab \
+ social \
$(NULL)
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
head.js \
test_feed_discovery.html \
feed_discovery.html \
@@ -281,32 +282,16 @@ endif
browser_bug734076.js \
browser_bug812562.js \
browser_bug818009.js \
browser_bug818118.js \
blockPluginVulnerableUpdatable.xml \
blockPluginVulnerableNoUpdate.xml \
blockNoPlugins.xml \
browser_utilityOverlay.js \
- browser_social.js \
- browser_social_toolbar.js \
- browser_social_shareButton.js \
- browser_social_sidebar.js \
- browser_social_flyout.js \
- browser_social_mozSocial_API.js \
- browser_social_isVisible.js \
- browser_social_chatwindow.js \
- browser_social_multiprovider.js \
- social_panel.html \
- social_share_image.png \
- social_sidebar.html \
- social_chat.html \
- social_flyout.html \
- social_window.html \
- social_worker.js \
browser_bug676619.js \
download_page.html \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
_BROWSER_FILES += \
browser_bug462289.js \
$(NULL)
--- a/browser/base/content/test/browser_clickToPlayPluginScriptAccessPopup.js
+++ b/browser/base/content/test/browser_clickToPlayPluginScriptAccessPopup.js
@@ -18,21 +18,25 @@ function test() {
});
Services.prefs.setBoolPref("plugins.click_to_play", true);
gBrowser.selectedTab = gBrowser.addTab();
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.addEventListener("PluginScripted", pluginScripted, true);
+ // This list is iterated in reverse order, since it uses Array.pop to get the next test.
gNextTestList = [
- { func: testExpectPopupPart1,
+ // Doesn't show a popup since not the first instance of a small plugin
+ { func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup1.html" },
- { func: testExpectPopupPart1,
+ // Doesn't show a popup since not the first instance of a small plugin
+ { func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup2.html" },
+ // Shows a popup since it is the first instance of a small plugin
{ func: testExpectPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup3.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup1.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup2.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup3.html" }
deleted file mode 100644
--- a/browser/base/content/test/browser_social_multiprovider.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- runSocialTestWithProvider(gProviders, function (finishcb) {
- runSocialTests(tests, undefined, undefined, finishcb);
- });
-}
-
-let gProviders = [
- {
- name: "provider 1",
- origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html?provider1",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
- iconURL: "chrome://branding/content/icon48.png"
- },
- {
- name: "provider 2",
- origin: "https://test1.example.com",
- sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social_sidebar.html?provider2",
- workerURL: "https://test1.example.com/browser/browser/base/content/test/social_worker.js",
- iconURL: "chrome://branding/content/icon48.png"
- }
-];
-
-var tests = {
- testProviderSwitch: function(next) {
- function checkProviderMenu(selectedProvider) {
- let menu = document.getElementById("social-statusarea-popup");
- let menuProviders = menu.querySelectorAll(".social-provider-menuitem");
- is(menuProviders.length, gProviders.length, "correct number of providers listed in the menu");
- // Find the selectedProvider's menu item
- let el = menu.getElementsByAttribute("origin", selectedProvider.origin);
- is(el.length, 1, "selected provider menu item exists");
- is(el[0].getAttribute("checked"), "true", "selected provider menu item is checked");
- }
-
- checkProviderMenu(gProviders[0]);
-
- // Now wait for the initial provider profile to be set
- waitForProviderLoad(function() {
- checkUIStateMatchesProvider(gProviders[0]);
-
- // Now activate "provider 2"
- observeProviderSet(function () {
- waitForProviderLoad(function() {
- checkUIStateMatchesProvider(gProviders[1]);
- next();
- });
- });
- Social.activateFromOrigin("https://test1.example.com");
- });
- }
-}
-
-function checkUIStateMatchesProvider(provider) {
- let profileData = getExpectedProfileData(provider);
- // Bug 789863 - share button uses 'displayName', toolbar uses 'userName'
- // Check the "share button"
- let displayNameEl = document.getElementById("socialUserDisplayName");
- is(displayNameEl.getAttribute("label"), profileData.displayName, "display name matches provider profile");
- // The toolbar
- let loginStatus = document.getElementsByClassName("social-statusarea-loggedInStatus");
- for (let label of loginStatus) {
- is(label.value, profileData.userName, "username name matches provider profile");
- }
- // Sidebar
- is(document.getElementById("social-sidebar-browser").getAttribute("src"), provider.sidebarURL, "side bar URL is set");
-}
-
-function getExpectedProfileData(provider) {
- // This data is defined in social_worker.js
- if (provider.origin == "https://test1.example.com") {
- return {
- displayName: "Test1 User",
- userName: "tester"
- };
- }
-
- return {
- displayName: "Kuma Lisa",
- userName: "trickster"
- };
-}
-
-function observeProviderSet(cb) {
- Services.obs.addObserver(function providerSet(subject, topic, data) {
- Services.obs.removeObserver(providerSet, "social:provider-set");
- info("social:provider-set observer was notified");
- // executeSoon to let the browser UI observers run first
- executeSoon(cb);
- }, "social:provider-set", false);
-}
-
-function waitForProviderLoad(cb) {
- waitForCondition(function() {
- return Social.provider.profile &&
- Social.provider.profile.displayName;
- }, cb, "waitForProviderLoad: provider profile was not set");
-}
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -83,141 +83,29 @@ function waitForCondition(condition, nex
if (condition()) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}
-// Check that a specified (string) URL hasn't been "remembered" (ie, is not
-// in history, will not appear in about:newtab or auto-complete, etc.)
-function ensureSocialUrlNotRemembered(url) {
- let gh = Cc["@mozilla.org/browser/global-history;2"]
- .getService(Ci.nsIGlobalHistory2);
- let uri = Services.io.newURI(url, null, null);
- ok(!gh.isVisited(uri), "social URL " + url + " should not be in global history");
-}
-
function getTestPlugin() {
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
var tags = ph.getPluginTags();
// Find the test plugin
for (var i = 0; i < tags.length; i++) {
if (tags[i].name == "Test Plug-in")
return tags[i];
}
ok(false, "Unable to find plugin");
return null;
}
-function runSocialTestWithProvider(manifest, callback) {
- let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
-
- let manifests = Array.isArray(manifest) ? manifest : [manifest];
-
- // Check that none of the provider's content ends up in history.
- registerCleanupFunction(function () {
- manifests.forEach(function (m) {
- for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
- if (m[what]) {
- ensureSocialUrlNotRemembered(m[what]);
- }
- }
- });
- });
-
- info("runSocialTestWithProvider: " + manifests.toSource());
-
- let providersAdded = 0;
- let firstProvider;
- manifests.forEach(function (m) {
- SocialService.addProvider(m, function(provider) {
- provider.active = true;
-
- providersAdded++;
- info("runSocialTestWithProvider: provider added");
-
- // we want to set the first specified provider as the UI's provider
- if (provider.origin == manifests[0].origin) {
- firstProvider = provider;
- }
-
- // If we've added all the providers we need, call the callback to start
- // the tests (and give it a callback it can call to finish them)
- if (providersAdded == manifests.length) {
- // Set the UI's provider and enable the feature
- Social.provider = firstProvider;
- Social.enabled = true;
-
- registerCleanupFunction(function () {
- // disable social before removing the providers to avoid providers
- // being activated immediately before we get around to removing it.
- Services.prefs.clearUserPref("social.enabled");
- // if one test happens to fail, it is likely finishSocialTest will not
- // be called, causing most future social tests to also fail as they
- // attempt to add a provider which already exists - so work
- // around that by also attempting to remove the test provider.
- manifests.forEach(function (m) {
- try {
- SocialService.removeProvider(m.origin, finish);
- } catch (ex) {}
- });
- });
- function finishSocialTest() {
- SocialService.removeProvider(provider.origin, finish);
- }
- callback(finishSocialTest);
- }
- });
- });
-}
-
-
-function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
- let testIter = Iterator(tests);
-
- if (cbPreTest === undefined) {
- cbPreTest = function(cb) {cb()};
- }
- if (cbPostTest === undefined) {
- cbPostTest = function(cb) {cb()};
- }
-
- function runNextTest() {
- let name, func;
- try {
- [name, func] = testIter.next();
- } catch (err if err instanceof StopIteration) {
- // out of items:
- (cbFinish || finish)();
- return;
- }
- // We run on a timeout as the frameworker also makes use of timeouts, so
- // this helps keep the debug messages sane.
- executeSoon(function() {
- function cleanupAndRunNextTest() {
- info("sub-test " + name + " complete");
- cbPostTest(runNextTest);
- }
- cbPreTest(function() {
- info("sub-test " + name + " starting");
- try {
- func.call(tests, cleanupAndRunNextTest);
- } catch (ex) {
- ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
- cleanupAndRunNextTest();
- }
- })
- });
- }
- runNextTest();
-}
-
function updateBlocklist(aCallback) {
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);
var observer = function() {
aCallback();
Services.obs.removeObserver(observer, "blocklist-updated");
};
Services.obs.addObserver(observer, "blocklist-updated", false);
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/Makefile.in
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+_BROWSER_FILES = \
+ head.js \
+ browser_social.js \
+ browser_social_toolbar.js \
+ browser_social_shareButton.js \
+ browser_social_sidebar.js \
+ browser_social_flyout.js \
+ browser_social_mozSocial_API.js \
+ browser_social_isVisible.js \
+ browser_social_chatwindow.js \
+ browser_social_multiprovider.js \
+ social_panel.html \
+ social_share_image.png \
+ social_sidebar.html \
+ social_chat.html \
+ social_flyout.html \
+ social_window.html \
+ social_worker.js \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+libs:: $(_BROWSER_FILES)
+ $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
rename from browser/base/content/test/browser_social.js
rename to browser/base/content/test/social/browser_social.js
--- a/browser/base/content/test/browser_social.js
+++ b/browser/base/content/test/social/browser_social.js
@@ -25,18 +25,18 @@ function portClosed(port) {
}
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, finishcb);
});
}
var tests = {
@@ -48,29 +48,31 @@ var tests = {
let topic = e.data.topic;
switch (topic) {
case "got-sidebar-message":
ok(true, "got sidebar message");
port.close();
togglePrivateBrowsing(function () {
ok(!Social.enabled, "Social shuts down during private browsing");
togglePrivateBrowsing(function () {
+ ok(Social.provider.getWorkerPort(), "port still obtainable after PB")
ok(Social.enabled, "Social enabled after private browsing");
next();
});
});
break;
}
};
},
testPrivateBrowsingSocialDisabled: function(next) {
// test PB from the perspective of entering PB without social enabled
// we expect social to be enabled at the start of the test, we need
// to disable it before testing PB transitions.
+ ok(Social.enabled, "social is still enabled");
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-sidebar-message":
ok(true, "got sidebar message");
rename from browser/base/content/test/browser_social_chatwindow.js
rename to browser/base/content/test/social/browser_social_chatwindow.js
--- a/browser/base/content/test/browser_social_chatwindow.js
+++ b/browser/base/content/test/social/browser_social_chatwindow.js
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
let oldwidth = window.outerWidth; // we futz with this, so we restore it
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, function () {
let chats = document.getElementById("pinnedchats");
ok(chats.children.length == 0, "no chatty children left behind");
window.resizeTo(oldwidth, window.outerHeight);
@@ -97,17 +97,17 @@ var tests = {
}
}
port.postMessage({topic: "test-init", data: { id: 1 }});
},
// In this case the *worker* opens a chat (so minimized is specified).
// The worker then makes the same call again - as that second call also
// specifies "minimized" the chat should *not* be restored.
testWorkerChatWindowMinimized: function(next) {
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let port = Social.provider.getWorkerPort();
let seen_opened = false;
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-chatbox-message":
@@ -170,17 +170,17 @@ var tests = {
}
}
let num = numToOpen;
while (num-- > 0) {
port.postMessage({topic: "test-chatbox-open", data: { id: num }});
}
},
testWorkerChatWindow: function(next) {
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-chatbox-message":
ok(true, "got a chat window opened");
@@ -409,17 +409,17 @@ var tests = {
});
}
}
port.postMessage({topic: "test-init", data: { id: 1 }});
},
testSecondTopLevelWindow: function(next) {
// Bug 817782 - check chats work in new top-level windows.
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let port = Social.provider.getWorkerPort();
let secondWindow;
port.onmessage = function(e) {
if (e.data.topic == "test-init-done") {
secondWindow = OpenBrowserWindow();
secondWindow.addEventListener("load", function loadListener() {
secondWindow.removeEventListener("load", loadListener);
port.postMessage({topic: "test-worker-chat", data: chatUrl});
@@ -432,17 +432,17 @@ var tests = {
}
}
port.postMessage({topic: "test-init"});
},
testChatWindowChooser: function(next) {
// Tests that when a worker creates a chat, it is opened in the correct
// window.
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let chatId = 1;
let port = Social.provider.getWorkerPort();
port.postMessage({topic: "test-init"});
function openChat(callback) {
port.onmessage = function(e) {
if (e.data.topic == "got-chatbox-message")
callback();
@@ -476,17 +476,17 @@ var tests = {
});
})
});
},
// XXX - note this must be the last test until we restore the login state
// between tests...
testCloseOnLogout: function(next) {
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-chatbox-message":
ok(true, "got a chat window opened");
@@ -547,17 +547,17 @@ function get3ChatsForCollapsing(mode, cb
cb(first, second, third);
}, mode);
}, mode);
});
}, mode);
}
function makeChat(mode, uniqueid, cb) {
- const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
+ const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let provider = Social.provider;
window.SocialChatBar.openChat(provider, chatUrl + "?id=" + uniqueid, function(chat) {
// we can't callback immediately or we might close the chat during
// this event which upsets the implementation - it is only 1/2 way through
// handling the load event.
chat.document.title = uniqueid;
executeSoon(cb);
}, mode);
rename from browser/base/content/test/browser_social_flyout.js
rename to browser/base/content/test/social/browser_social_flyout.js
--- a/browser/base/content/test/browser_social_flyout.js
+++ b/browser/base/content/test/social/browser_social_flyout.js
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, finishcb);
});
}
var tests = {
rename from browser/base/content/test/browser_social_isVisible.js
rename to browser/base/content/test/social/browser_social_isVisible.js
--- a/browser/base/content/test/browser_social_isVisible.js
+++ b/browser/base/content/test/social/browser_social_isVisible.js
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, finishcb);
});
}
var tests = {
rename from browser/base/content/test/browser_social_mozSocial_API.js
rename to browser/base/content/test/social/browser_social_mozSocial_API.js
--- a/browser/base/content/test/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/social/browser_social_mozSocial_API.js
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, finishcb);
});
}
var tests = {
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/browser_social_multiprovider.js
@@ -0,0 +1,104 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function test() {
+ waitForExplicitFinish();
+
+ runSocialTestWithProvider(gProviders, function (finishcb) {
+ runSocialTests(tests, undefined, undefined, finishcb);
+ });
+}
+
+let gProviders = [
+ {
+ name: "provider 1",
+ origin: "https://example.com",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html?provider1",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
+ iconURL: "chrome://branding/content/icon48.png"
+ },
+ {
+ name: "provider 2",
+ origin: "https://test1.example.com",
+ sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?provider2",
+ workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
+ iconURL: "chrome://branding/content/icon48.png"
+ }
+];
+
+var tests = {
+ testProviderSwitch: function(next) {
+ function checkProviderMenu(selectedProvider) {
+ let menu = document.getElementById("social-statusarea-popup");
+ let menuProviders = menu.querySelectorAll(".social-provider-menuitem");
+ is(menuProviders.length, gProviders.length, "correct number of providers listed in the menu");
+ // Find the selectedProvider's menu item
+ let el = menu.getElementsByAttribute("origin", selectedProvider.origin);
+ is(el.length, 1, "selected provider menu item exists");
+ is(el[0].getAttribute("checked"), "true", "selected provider menu item is checked");
+ }
+
+ checkProviderMenu(gProviders[0]);
+
+ // Now wait for the initial provider profile to be set
+ waitForProviderLoad(function() {
+ checkUIStateMatchesProvider(gProviders[0]);
+
+ // Now activate "provider 2"
+ observeProviderSet(function () {
+ waitForProviderLoad(function() {
+ checkUIStateMatchesProvider(gProviders[1]);
+ next();
+ });
+ });
+ Social.activateFromOrigin("https://test1.example.com");
+ });
+ }
+}
+
+function checkUIStateMatchesProvider(provider) {
+ let profileData = getExpectedProfileData(provider);
+ // Bug 789863 - share button uses 'displayName', toolbar uses 'userName'
+ // Check the "share button"
+ let displayNameEl = document.getElementById("socialUserDisplayName");
+ is(displayNameEl.getAttribute("label"), profileData.displayName, "display name matches provider profile");
+ // The toolbar
+ let loginStatus = document.getElementsByClassName("social-statusarea-loggedInStatus");
+ for (let label of loginStatus) {
+ is(label.value, profileData.userName, "username name matches provider profile");
+ }
+ // Sidebar
+ is(document.getElementById("social-sidebar-browser").getAttribute("src"), provider.sidebarURL, "side bar URL is set");
+}
+
+function getExpectedProfileData(provider) {
+ // This data is defined in social_worker.js
+ if (provider.origin == "https://test1.example.com") {
+ return {
+ displayName: "Test1 User",
+ userName: "tester"
+ };
+ }
+
+ return {
+ displayName: "Kuma Lisa",
+ userName: "trickster"
+ };
+}
+
+function observeProviderSet(cb) {
+ Services.obs.addObserver(function providerSet(subject, topic, data) {
+ Services.obs.removeObserver(providerSet, "social:provider-set");
+ info("social:provider-set observer was notified");
+ // executeSoon to let the browser UI observers run first
+ executeSoon(cb);
+ }, "social:provider-set", false);
+}
+
+function waitForProviderLoad(cb) {
+ waitForCondition(function() {
+ return Social.provider.profile &&
+ Social.provider.profile.displayName;
+ }, cb, "waitForProviderLoad: provider profile was not set");
+}
rename from browser/base/content/test/browser_social_shareButton.js
rename to browser/base/content/test/social/browser_social_shareButton.js
--- a/browser/base/content/test/browser_social_shareButton.js
+++ b/browser/base/content/test/social/browser_social_shareButton.js
@@ -22,18 +22,18 @@ function test() {
}
function tabLoaded() {
ok(Social, "Social module loaded");
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
gFinishCB = finishcb;
testInitial();
});
}
@@ -63,26 +63,26 @@ function testInitial(finishcb) {
let displayName = document.getElementById("socialUserDisplayName");
is(displayName.label, profile.displayName, "display name is set");
ok(!document.getElementById("unsharePopupHeader").hidden, "user profile is visible");
// Check the strings from our worker actually ended up on the button.
is(shareButton.getAttribute("tooltiptext"), "Share this page", "check tooltip text is correct");
is(shareStatusLabel.getAttribute("value"), "", "check status label text is blank");
// Check the relative URL was resolved correctly (note this image has offsets of zero...)
- is(shareButton.src, 'https://example.com/browser/browser/base/content/test/social_share_image.png', "check image url is correct");
+ is(shareButton.src, 'https://example.com/browser/browser/base/content/test/social/social_share_image.png', "check image url is correct");
// Test clicking the share button
shareButton.addEventListener("click", function listener() {
shareButton.removeEventListener("click", listener);
is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked");
is(shareButton.getAttribute("tooltiptext"), "Unshare this page", "check tooltip text is correct");
is(shareStatusLabel.getAttribute("value"), "This page has been shared", "check status label text is correct");
// Check the URL and offsets were applied correctly
- is(shareButton.src, 'https://example.com/browser/browser/base/content/test/social_share_image.png', "check image url is correct");
+ is(shareButton.src, 'https://example.com/browser/browser/base/content/test/social/social_share_image.png', "check image url is correct");
executeSoon(testSecondClick.bind(window, testPopupOKButton));
});
shareButton.click();
}, "provider didn't provide user-recommend-prompt response");
}
function testSecondClick(nextTest) {
let {shareButton, unsharePopup} = SocialShareButton;
rename from browser/base/content/test/browser_social_sidebar.js
rename to browser/base/content/test/social/browser_social_sidebar.js
--- a/browser/base/content/test/browser_social_sidebar.js
+++ b/browser/base/content/test/social/browser_social_sidebar.js
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, doTest);
}
function doTest(finishcb) {
ok(SocialSidebar.canShow, "social sidebar should be able to be shown");
ok(SocialSidebar.opened, "social sidebar should be open by default");
rename from browser/base/content/test/browser_social_toolbar.js
rename to browser/base/content/test/social/browser_social_toolbar.js
--- a/browser/base/content/test/browser_social_toolbar.js
+++ b/browser/base/content/test/social/browser_social_toolbar.js
@@ -3,17 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
- workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+ workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, undefined, finishcb);
});
}
var tests = {
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/head.js
@@ -0,0 +1,129 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function waitForCondition(condition, nextTest, errorMsg) {
+ var tries = 0;
+ var interval = setInterval(function() {
+ if (tries >= 30) {
+ ok(false, errorMsg);
+ moveOn();
+ }
+ if (condition()) {
+ moveOn();
+ }
+ tries++;
+ }, 100);
+ var moveOn = function() { clearInterval(interval); nextTest(); };
+}
+
+// Check that a specified (string) URL hasn't been "remembered" (ie, is not
+// in history, will not appear in about:newtab or auto-complete, etc.)
+function ensureSocialUrlNotRemembered(url) {
+ let gh = Cc["@mozilla.org/browser/global-history;2"]
+ .getService(Ci.nsIGlobalHistory2);
+ let uri = Services.io.newURI(url, null, null);
+ ok(!gh.isVisited(uri), "social URL " + url + " should not be in global history");
+}
+
+function runSocialTestWithProvider(manifest, callback) {
+ let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+
+ let manifests = Array.isArray(manifest) ? manifest : [manifest];
+
+ // Check that none of the provider's content ends up in history.
+ registerCleanupFunction(function () {
+ manifests.forEach(function (m) {
+ for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
+ if (m[what]) {
+ ensureSocialUrlNotRemembered(m[what]);
+ }
+ }
+ });
+ });
+
+ info("runSocialTestWithProvider: " + manifests.toSource());
+
+ let providersAdded = 0;
+ let firstProvider;
+ manifests.forEach(function (m) {
+ SocialService.addProvider(m, function(provider) {
+ provider.active = true;
+
+ providersAdded++;
+ info("runSocialTestWithProvider: provider added");
+
+ // we want to set the first specified provider as the UI's provider
+ if (provider.origin == manifests[0].origin) {
+ firstProvider = provider;
+ }
+
+ // If we've added all the providers we need, call the callback to start
+ // the tests (and give it a callback it can call to finish them)
+ if (providersAdded == manifests.length) {
+ // Set the UI's provider and enable the feature
+ Social.provider = firstProvider;
+ Social.enabled = true;
+
+ registerCleanupFunction(function () {
+ // disable social before removing the providers to avoid providers
+ // being activated immediately before we get around to removing it.
+ Services.prefs.clearUserPref("social.enabled");
+ // if one test happens to fail, it is likely finishSocialTest will not
+ // be called, causing most future social tests to also fail as they
+ // attempt to add a provider which already exists - so work
+ // around that by also attempting to remove the test provider.
+ manifests.forEach(function (m) {
+ try {
+ SocialService.removeProvider(m.origin, finish);
+ } catch (ex) {}
+ });
+ });
+ function finishSocialTest() {
+ SocialService.removeProvider(provider.origin, finish);
+ }
+ callback(finishSocialTest);
+ }
+ });
+ });
+}
+
+function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
+ let testIter = Iterator(tests);
+
+ if (cbPreTest === undefined) {
+ cbPreTest = function(cb) {cb()};
+ }
+ if (cbPostTest === undefined) {
+ cbPostTest = function(cb) {cb()};
+ }
+
+ function runNextTest() {
+ let name, func;
+ try {
+ [name, func] = testIter.next();
+ } catch (err if err instanceof StopIteration) {
+ // out of items:
+ (cbFinish || finish)();
+ return;
+ }
+ // We run on a timeout as the frameworker also makes use of timeouts, so
+ // this helps keep the debug messages sane.
+ executeSoon(function() {
+ function cleanupAndRunNextTest() {
+ info("sub-test " + name + " complete");
+ cbPostTest(runNextTest);
+ }
+ cbPreTest(function() {
+ info("sub-test " + name + " starting");
+ try {
+ func.call(tests, cleanupAndRunNextTest);
+ } catch (ex) {
+ ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
+ cleanupAndRunNextTest();
+ }
+ })
+ });
+ }
+ runNextTest();
+}
rename from browser/base/content/test/social_chat.html
rename to browser/base/content/test/social/social_chat.html
rename from browser/base/content/test/social_flyout.html
rename to browser/base/content/test/social/social_flyout.html
rename from browser/base/content/test/social_panel.html
rename to browser/base/content/test/social/social_panel.html
rename from browser/base/content/test/social_share_image.png
rename to browser/base/content/test/social/social_share_image.png
rename from browser/base/content/test/social_sidebar.html
rename to browser/base/content/test/social/social_sidebar.html
rename from browser/base/content/test/social_window.html
rename to browser/base/content/test/social/social_window.html
rename from browser/base/content/test/social_worker.js
rename to browser/base/content/test/social/social_worker.js
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social/social_worker.js
@@ -100,36 +100,36 @@ onconnect = function(e) {
};
}
port.postMessage({topic: "social.user-profile", data: profile});
break;
case "test-ambient-notification":
let icon = {
name: "testIcon",
iconURL: "chrome://browser/skin/Info.png",
- contentPanel: "https://example.com/browser/browser/base/content/test/social_panel.html",
+ contentPanel: "https://example.com/browser/browser/base/content/test/social/social_panel.html",
counter: 1
};
apiPort.postMessage({topic: "social.ambient-notification", data: icon});
break;
case "test-isVisible":
sidebarPort.postMessage({topic: "test-isVisible"});
break;
case "test-isVisible-response":
testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
break;
case "social.user-recommend-prompt":
port.postMessage({
topic: "social.user-recommend-prompt-response",
data: {
images: {
// this one is relative to test we handle relative ones.
- share: "browser/browser/base/content/test/social_share_image.png",
+ share: "browser/browser/base/content/test/social/social_share_image.png",
// absolute to check we handle them too.
- unshare: "https://example.com/browser/browser/base/content/test/social_share_image.png"
+ unshare: "https://example.com/browser/browser/base/content/test/social/social_share_image.png"
},
messages: {
shareTooltip: "Share this page",
unshareTooltip: "Unshare this page",
sharedLabel: "This page has been shared",
unsharedLabel: "This page is no longer shared",
unshareLabel: "You have already shared this page",
portraitLabel: "Your pretty face",
--- a/browser/components/places/tests/unit/test_browserGlue_prefs.js
+++ b/browser/components/places/tests/unit/test_browserGlue_prefs.js
@@ -22,17 +22,17 @@ function waitForImportAndSmartBookmarks(
Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
// Delay to test eventual smart bookmarks creation.
do_execute_soon(function () {
promiseAsyncUpdates().then(aCallback);
});
}, "bookmarks-restore-success", false);
}
-let gTests = [
+[
// This test must be the first one.
function test_checkPreferences() {
// Initialize Places through the History Service and check that a new
// database has been created.
do_check_eq(PlacesUtils.history.databaseStatus,
PlacesUtils.history.DATABASE_STATUS_CREATE);
@@ -258,17 +258,17 @@ let gTests = [
});
// Force nsBrowserGlue::_initPlaces()
do_log_info("Simulate Places init");
bg.QueryInterface(Ci.nsIObserver).observe(null,
TOPIC_BROWSERGLUE_TEST,
TOPICDATA_FORCE_PLACES_INIT);
}
-];
+].forEach(add_test);
do_register_cleanup(function () {
remove_all_bookmarks();
remove_bookmarks_html();
remove_all_JSON_backups();
});
function run_test()
--- a/browser/config/tooltool-manifests/linux32/clang.manifest
+++ b/browser/config/tooltool-manifests/linux32/clang.manifest
@@ -1,17 +1,17 @@
[
{
-"clang_version": "r169139"
+"clang_version": "r169730"
},
{
"size": 47,
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
-"size": 62513298,
-"digest": "1c9dfc75d4a06438da4d079282178274054e07d814ec6bc8e45c9e62589293df11858c74ce301c53b5bd758c56dc1c593a97cd5034b47ea753c518fd9af69ea4",
+"size": 61875575,
+"digest": "7098e1cc85a8ae45672333320c7673c284023366fbe6d4fab3e9276960b7f92fd74ee63d0ad6c43a86fd96a1b886408993479260ac897fa6fe101c4a9fb807b1",
"algorithm": "sha512",
"filename": "clang.tar.bz2"
}
]
--- a/browser/config/tooltool-manifests/linux64/clang.manifest
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest
@@ -1,17 +1,17 @@
[
{
-"clang_version": "r169139"
+"clang_version": "r169730"
},
{
"size": 47,
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
-"size": 62856551,
-"digest": "3542a25815f89555f2e2b4c67fbffa432c341d824395b452698d8d90ee0216e045531adcad14bf7071be1a41c016b4652cf955270b652bcdbd7b04a02cc3c9f9",
+"size": 62279267,
+"digest": "0c9f87e3d7675feaa79b6d5d0997c8f370785901b8668f51da3339ae674291b3946e9d76629adb1c4ccd15aa851d84e4cd39ddd9032c916cc75233fe73c68f2e",
"algorithm": "sha512",
"filename": "clang.tar.bz2"
}
]
--- a/browser/config/tooltool-manifests/macosx32/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx32/releng.manifest
@@ -1,17 +1,17 @@
[
{
-"clang_version": "r169139"
+"clang_version": "r169730"
},
{
"size": 47,
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
-"size": 56158651,
-"digest": "38d718f20a8fa9218e22ade312e724e6c9cdd7c6650e023cfdc21b5505fe7aa3743ae41c0abd717a1bbccec4c4271be2fa82d0e2f96c91e693d70e33b4dc00d6",
+"size": 56115091,
+"digest": "d7188264f28d6f6a84fab9737520cad22fe3d575917a87fc110d0b9a2033617c35da83530ea20553f5c55a996459f750fa2d0c49288c1fb9671f6252a92cf4c9",
"algorithm": "sha512",
"filename": "clang.tar.bz2"
}
]
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -1,17 +1,17 @@
[
{
-"clang_version": "r169139"
+"clang_version": "r169730"
},
{
"size": 47,
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
-"size": 56158651,
-"digest": "38d718f20a8fa9218e22ade312e724e6c9cdd7c6650e023cfdc21b5505fe7aa3743ae41c0abd717a1bbccec4c4271be2fa82d0e2f96c91e693d70e33b4dc00d6",
+"size": 56115091,
+"digest": "d7188264f28d6f6a84fab9737520cad22fe3d575917a87fc110d0b9a2033617c35da83530ea20553f5c55a996459f750fa2d0c49288c1fb9671f6252a92cf4c9",
"algorithm": "sha512",
"filename": "clang.tar.bz2"
}
]
--- a/browser/devtools/inspector/test/Makefile.in
+++ b/browser/devtools/inspector/test/Makefile.in
@@ -23,17 +23,17 @@ include $(topsrcdir)/config/rules.mk
browser_inspector_invalidate.js \
browser_inspector_menu.js \
browser_inspector_pseudoClass_menu.js \
browser_inspector_destroyselection.html \
browser_inspector_destroyselection.js \
browser_inspector_bug_699308_iframe_navigation.js \
browser_inspector_bug_672902_keyboard_shortcuts.js \
browser_inspector_bug_566084_location_changed.js \
- browser_inspector_sidebarstate.js \
+ $(filter disabled-temporarily--bug-816990, browser_inspector_sidebarstate.js) \
browser_inspector_pseudoclass_lock.js \
browser_inspector_cmd_inspect.js \
browser_inspector_cmd_inspect.html \
browser_inspector_highlighter_autohide.js \
browser_inspector_changes.js \
browser_inspector_bug_674871.js \
head.js \
helpers.js \
--- a/browser/makefiles.sh
+++ b/browser/makefiles.sh
@@ -94,16 +94,17 @@ else
browser/themes/winstripe/communicator/Makefile
"
fi
if [ "$ENABLE_TESTS" ]; then
add_makefiles "
browser/base/content/test/Makefile
browser/base/content/test/newtab/Makefile
+ browser/base/content/test/social/Makefile
browser/components/certerror/test/Makefile
browser/components/dirprovider/tests/Makefile
browser/components/downloads/test/Makefile
browser/components/downloads/test/browser/Makefile
browser/components/preferences/tests/Makefile
browser/components/search/test/Makefile
browser/components/sessionstore/test/Makefile
browser/components/shell/test/Makefile
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1266,16 +1266,33 @@ toolbar[iconsize="small"] #feed-button {
#webapps-notification-icon {
list-style-image: url(chrome://browser/skin/webapps-16.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-16.png);
}
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/plugins/notifyPluginBlocked.png);
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
#webRTC-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
#treecolAutoCompleteImage {
max-width : 36px;
}
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -3044,16 +3044,40 @@ toolbarbutton.chevron > .toolbarbutton-m
#webapps-notification-icon {
list-style-image: url(chrome://browser/skin/webapps-16@2x.png);
}
}
#plugins-notification-icon {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-16.png);
}
+
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/plugins/notifyPluginBlocked.png);
+}
+
+@media (min-resolution: 2dppx) {
+ #blocked-plugins-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked.png);
+ }
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
@media (min-resolution: 2dppx) {
#plugins-notification-icon {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
}
}
#webRTC-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -2395,16 +2395,33 @@ toolbarbutton.bookmark-item[dragover="tr
#webapps-notification-icon {
list-style-image: url(chrome://browser/skin/webapps-16.png);
}
#plugins-notification-icon {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-16.png);
}
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/plugins/notifyPluginBlocked.png);
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
#webRTC-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
#identity-popup-container {
min-width: 280px;
}
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -170,18 +170,16 @@ libs:: $(topsrcdir)/tools/rb/fix_stack_u
$(INSTALL) $< $(DIST)/bin
# Unit tests for ManifestParser
check::
$(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(srcdir) \
$(srcdir)/tests/test.py
ifeq ($(OS_ARCH),Darwin)
-libs:: $(topsrcdir)/tools/rb/fix-macosx-stack.pl
- $(INSTALL) $< $(DIST)/bin
libs:: $(topsrcdir)/tools/rb/fix_macosx_stack.py
$(INSTALL) $< $(DIST)/bin
# Basic unit tests for some stuff in the unify script
check::
# build x64/i386 binaries, and unify them
rm -f unify-test-x64 unify-test-i386 unify-test-universal
$(HOST_CC) -arch x86_64 $(srcdir)/unify-test.c -o unify-test-x64
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -1,14 +1,14 @@
#!/usr/bin/python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-llvm_revision = "169139"
+llvm_revision = "169730"
moz_version = "moz0"
##############################################
import os
import os.path
import shutil
import tarfile
@@ -27,22 +27,23 @@ def run_in(path, args):
check_run(args)
os.chdir(d)
def patch(patch, plevel, srcdir):
patch = os.path.realpath(patch)
check_run(['patch', '-d', srcdir, '-p%s' % plevel, '-i', patch, '--fuzz=0',
'-s'])
-def build_package(package_source_dir, package_build_dir, configure_args):
+def build_package(package_source_dir, package_build_dir, configure_args,
+ make_args):
if not os.path.exists(package_build_dir):
os.mkdir(package_build_dir)
run_in(package_build_dir,
["%s/configure" % package_source_dir] + configure_args)
- run_in(package_build_dir, ["make", "-j8"])
+ run_in(package_build_dir, ["make", "-j8"] + make_args)
run_in(package_build_dir, ["make", "install"])
def with_env(env, f):
old_env = os.environ.copy()
os.environ.update(env)
f()
os.environ.clear()
os.environ.update(old_env)
@@ -106,17 +107,18 @@ def build_one_stage_aux(stage_dir, is_st
build_dir = stage_dir + "/build"
inst_dir = stage_dir + "/clang"
configure_opts = ["--enable-optimized",
"--enable-targets=x86,x86_64,arm",
"--disable-assertions",
"--prefix=%s" % inst_dir,
"--with-gcc-toolchain=/tools/gcc-4.5-0moz3"]
- build_package(llvm_source_dir, build_dir, configure_opts)
+ build_package(llvm_source_dir, build_dir, configure_opts,
+ ["CLANG_IS_PRODUCTION=1"])
if isDarwin:
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
if not os.path.exists(source_dir):
os.makedirs(source_dir)
svn_co("http://llvm.org/svn/llvm-project/llvm/branches/release_32",
llvm_source_dir, llvm_revision)
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -582,16 +582,23 @@ protected:
*/
void ProcessMediaFragmentURI();
/**
* Mute or unmute the audio, without changing the value that |muted| reports.
*/
void SetMutedInternal(bool aMuted);
+ /**
+ * Suspend (if aPauseForInactiveDocument) or resume element playback and
+ * resource download. If aSuspendEvents is true, event delivery is
+ * suspended (and events queued) until the element is resumed.
+ */
+ void SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents);
+
// Get the nsHTMLMediaElement object if the decoder is being used from an
// HTML media element, and null otherwise.
virtual nsHTMLMediaElement* GetMediaElement() MOZ_FINAL MOZ_OVERRIDE
{
return this;
}
// Return true if decoding should be paused
@@ -806,18 +813,22 @@ protected:
bool mAudioCaptured;
// If TRUE then the media element was actively playing before the currently
// in progress seeking. If FALSE then the media element is either not seeking
// or was not actively playing before the current seek. Used to decide whether
// to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
bool mPlayingBeforeSeek;
- // True iff this element is paused because the document is inactive
- bool mPausedForInactiveDocument;
+ // True iff this element is paused because the document is inactive or has
+ // been suspended by the audio channel service.
+ bool mPausedForInactiveDocumentOrChannel;
+
+ // True iff event delivery is suspended (mPausedForInactiveDocumentOrChannel must also be true).
+ bool mEventDeliveryPaused;
// True if we've reported a "waiting" event since the last
// readyState change to HAVE_CURRENT_DATA.
bool mWaitingFired;
// True if we're running the "load()" method.
bool mIsRunningLoadMethod;
@@ -881,18 +892,18 @@ protected:
// information to give it as a hint to the channel for it to bypass the
// sniffing phase, that would fail because sniffing only works when applied to
// the first bytes of the stream.
nsCString mMimeType;
// Audio Channel Type.
mozilla::dom::AudioChannelType mAudioChannelType;
- // The audiochannel has been muted
- bool mChannelMuted;
+ // The audiochannel has been suspended.
+ bool mChannelSuspended;
// Is this media element playing?
bool mPlayingThroughTheAudioChannel;
// An agent used to join audio channel service.
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
};
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -1551,17 +1551,17 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMut
{
*aMuted = mMuted;
return NS_OK;
}
void nsHTMLMediaElement::SetMutedInternal(bool aMuted)
{
- float effectiveVolume = aMuted || mChannelMuted ? 0.0f : float(mVolume);
+ float effectiveVolume = aMuted ? 0.0f : float(mVolume);
if (mDecoder) {
mDecoder->SetVolume(effectiveVolume);
} else if (mAudioStream) {
mAudioStream->SetVolume(effectiveVolume);
} else if (mSrcStream) {
GetSrcMediaStream()->SetAudioOutputVolume(this, effectiveVolume);
}
@@ -1748,17 +1748,18 @@ nsHTMLMediaElement::nsHTMLMediaElement(a
mBegun(false),
mLoadedFirstFrame(false),
mAutoplaying(true),
mAutoplayEnabled(true),
mPaused(true),
mMuted(false),
mAudioCaptured(false),
mPlayingBeforeSeek(false),
- mPausedForInactiveDocument(false),
+ mPausedForInactiveDocumentOrChannel(false),
+ mEventDeliveryPaused(false),
mWaitingFired(false),
mIsRunningLoadMethod(false),
mIsLoadingFromSourceChildren(false),
mDelayingLoadEvent(false),
mIsRunningSelectResource(false),
mHaveQueuedSelectResource(false),
mSuspendedAfterFirstFrame(false),
mAllowSuspendAfterFirstFrame(true),
@@ -1766,17 +1767,17 @@ nsHTMLMediaElement::nsHTMLMediaElement(a
mHasSelfReference(false),
mShuttingDown(false),
mSuspendedForPreloadNone(false),
mMediaSecurityVerified(false),
mCORSMode(CORS_NONE),
mHasAudio(false),
mDownloadSuspendedByCache(false),
mAudioChannelType(AUDIO_CHANNEL_NORMAL),
- mChannelMuted(false),
+ mChannelSuspended(false),
mPlayingThroughTheAudioChannel(false)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
gMediaElementLog = PR_NewLogModule("nsMediaElement");
}
if (!gMediaElementEventsLog) {
gMediaElementEventsLog = PR_NewLogModule("nsMediaElementEvents");
@@ -1872,17 +1873,17 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
ResumeLoad(PRELOAD_ENOUGH);
}
// Even if we just did Load() or ResumeLoad(), we could already have a decoder
// here if we managed to clone an existing decoder.
if (mDecoder) {
if (mDecoder->IsEnded()) {
SetCurrentTime(0);
}
- if (!mPausedForInactiveDocument) {
+ if (!mPausedForInactiveDocumentOrChannel) {
nsresult rv = mDecoder->Play();
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (mCurrentPlayRangeStart == -1.0) {
GetCurrentTime(&mCurrentPlayRangeStart);
}
@@ -2298,17 +2299,19 @@ nsresult nsHTMLMediaElement::FinishDecod
MediaDecoder* aCloneDonor)
{
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
// Force a same-origin check before allowing events for this media resource.
mMediaSecurityVerified = false;
// The new stream has not been suspended by us.
- mPausedForInactiveDocument = false;
+ mPausedForInactiveDocumentOrChannel = false;
+ mPendingEvents.Clear();
+ mEventDeliveryPaused = false;
aDecoder->SetAudioChannelType(mAudioChannelType);
aDecoder->SetAudioCaptured(mAudioCaptured);
aDecoder->SetVolume(mMuted ? 0.0 : mVolume);
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
OutputMediaStream* ms = &mOutputStreams[i];
aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
ms->mFinishWhenEnded);
@@ -2329,17 +2332,17 @@ nsresult nsHTMLMediaElement::FinishDecod
NotifyDecoderPrincipalChanged();
// We may want to suspend the new stream now.
// This will also do an AddRemoveSelfReference.
NotifyOwnerDocumentActivityChanged();
if (!mPaused) {
SetPlayedOrSeeked(true);
- if (!mPausedForInactiveDocument) {
+ if (!mPausedForInactiveDocumentOrChannel) {
rv = mDecoder->Play();
}
}
if (OwnerDoc()->HasAudioAvailableListeners()) {
NotifyAudioAvailableListener();
}
@@ -2475,17 +2478,17 @@ void nsHTMLMediaElement::SetupSrcMediaSt
mSrcStream = aStream;
// XXX if we ever support capturing the output of a media element which is
// playing a stream, we'll need to add a CombineWithPrincipal call here.
mSrcStreamListener = new StreamListener(this);
GetSrcMediaStream()->AddListener(mSrcStreamListener);
if (mPaused) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
}
- if (mPausedForInactiveDocument) {
+ if (mPausedForInactiveDocumentOrChannel) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
}
ChangeDelayLoadStatus(false);
GetSrcMediaStream()->AddAudioOutput(this);
GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume));
VideoFrameContainer* container = GetVideoFrameContainer();
if (container) {
GetSrcMediaStream()->AddVideoOutput(container);
@@ -2510,17 +2513,17 @@ void nsHTMLMediaElement::EndSrcMediaStre
VideoFrameContainer* container = GetVideoFrameContainer();
if (container) {
GetSrcMediaStream()->RemoveVideoOutput(container);
container->ClearCurrentFrame();
}
if (mPaused) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
}
- if (mPausedForInactiveDocument) {
+ if (mPausedForInactiveDocumentOrChannel) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
}
mSrcStream = nullptr;
}
nsresult nsHTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
@@ -2850,25 +2853,25 @@ static const char* gReadyStateToString[]
};
#endif
void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
{
nsMediaReadyState oldState = mReadyState;
mReadyState = aState;
- UpdateAudioChannelPlayingState();
-
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY ||
oldState == mReadyState) {
return;
}
LOG(PR_LOG_DEBUG, ("%p Ready state changed to %s", this, gReadyStateToString[aState]));
+ UpdateAudioChannelPlayingState();
+
// Handle raising of "waiting" event during seek (see 4.8.10.9)
if (mPlayingBeforeSeek &&
oldState < nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) {
DispatchAsyncEvent(NS_LITERAL_STRING("waiting"));
}
if (oldState < nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
@@ -2985,17 +2988,17 @@ nsresult nsHTMLMediaElement::DispatchAud
nsresult nsHTMLMediaElement::DispatchEvent(const nsAString& aName)
{
LOG_EVENT(PR_LOG_DEBUG, ("%p Dispatching event %s", this,
NS_ConvertUTF16toUTF8(aName).get()));
// Save events that occur while in the bfcache. These will be dispatched
// if the page comes out of the bfcache.
- if (mPausedForInactiveDocument) {
+ if (mEventDeliveryPaused) {
mPendingEvents.AppendElement(aName);
return NS_OK;
}
return nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIContent*>(this),
aName,
false,
@@ -3009,17 +3012,17 @@ nsresult nsHTMLMediaElement::DispatchAsy
nsCOMPtr<nsIRunnable> event = new nsAsyncEventRunner(aName, this);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
return NS_OK;
}
nsresult nsHTMLMediaElement::DispatchPendingMediaEvents()
{
- NS_ASSERTION(!mPausedForInactiveDocument,
+ NS_ASSERTION(!mEventDeliveryPaused,
"Must not be in bfcache when dispatching pending media events");
uint32_t count = mPendingEvents.Length();
for (uint32_t i = 0; i < count; ++i) {
DispatchAsyncEvent(mPendingEvents[i]);
}
mPendingEvents.Clear();
@@ -3068,52 +3071,63 @@ void nsHTMLMediaElement::NotifyDecoderPr
}
}
void nsHTMLMediaElement::UpdateMediaSize(nsIntSize size)
{
mMediaSize = size;
}
-void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
+void nsHTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
{
- nsIDocument* ownerDoc = OwnerDoc();
- bool pauseForInactiveDocument =
- !ownerDoc->IsActive() || !ownerDoc->IsVisible();
-
- if (pauseForInactiveDocument != mPausedForInactiveDocument) {
- mPausedForInactiveDocument = pauseForInactiveDocument;
- if (pauseForInactiveDocument) {
+ if (aPauseElement != mPausedForInactiveDocumentOrChannel) {
+ mPausedForInactiveDocumentOrChannel = aPauseElement;
+ if (aPauseElement) {
if (mDecoder) {
mDecoder->Pause();
mDecoder->Suspend();
} else if (mSrcStream) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
}
+ mEventDeliveryPaused = aSuspendEvents;
} else {
if (mDecoder) {
mDecoder->Resume(false);
if (!mPaused && !mDecoder->IsEnded()) {
mDecoder->Play();
}
} else if (mSrcStream) {
GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
}
- DispatchPendingMediaEvents();
+ if (mEventDeliveryPaused) {
+ DispatchPendingMediaEvents();
+ mEventDeliveryPaused = false;
+ }
}
}
-
- if (mPlayingThroughTheAudioChannel && mAudioChannelAgent) {
+}
+
+void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
+{
+ nsIDocument* ownerDoc = OwnerDoc();
+#ifdef MOZ_B2G
+ nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc());
+ if (domDoc) {
bool hidden = false;
- nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(ownerDoc);
- if (domDoc) {
- domDoc->GetHidden(&hidden);
+ domDoc->GetHidden(&hidden);
+ // SetVisibilityState will update mChannelSuspended via the CanPlayChanged callback.
+ if (mPlayingThroughTheAudioChannel && mAudioChannelAgent) {
mAudioChannelAgent->SetVisibilityState(!hidden);
}
}
+#endif
+ bool suspendEvents = !ownerDoc->IsActive() || !ownerDoc->IsVisible();
+ bool pauseElement = suspendEvents || mChannelSuspended;
+
+ SuspendOrResumeElement(pauseElement, suspendEvents);
AddRemoveSelfReference();
}
void nsHTMLMediaElement::AddRemoveSelfReference()
{
// XXX we could release earlier here in many situations if we examined
// which event listeners are attached. Right now we assume there is a
@@ -3517,25 +3531,25 @@ ImageContainer* nsHTMLMediaElement::GetI
}
nsresult nsHTMLMediaElement::UpdateChannelMuteState(bool aCanPlay)
{
// Only on B2G we mute the nsHTMLMediaElement following the rules of
// AudioChannelService.
#ifdef MOZ_B2G
// We have to mute this channel:
- if (!aCanPlay && !mChannelMuted) {
- mChannelMuted = true;
+ if (!aCanPlay && !mChannelSuspended) {
+ mChannelSuspended = true;
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
- } else if (aCanPlay && mChannelMuted) {
- mChannelMuted = false;
+ } else if (aCanPlay && mChannelSuspended) {
+ mChannelSuspended = false;
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
}
- SetMutedInternal(mMuted);
+ SuspendOrResumeElement(mChannelSuspended, false);
#endif
return NS_OK;
}
void nsHTMLMediaElement::UpdateAudioChannelPlayingState()
{
// The nsHTMLMediaElement is registered to the AudioChannelService only on B2G.
@@ -3547,17 +3561,17 @@ void nsHTMLMediaElement::UpdateAudioChan
mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
if (!mAudioChannelAgent) {
nsresult rv;
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
if (!mAudioChannelAgent) {
return;
}
- mAudioChannelAgent->Init( mAudioChannelType, this);
+ mAudioChannelAgent->Init(mAudioChannelType, this);
}
if (mPlayingThroughTheAudioChannel) {
bool canPlay;
mAudioChannelAgent->StartPlaying(&canPlay);
} else {
mAudioChannelAgent->StopPlaying();
mAudioChannelAgent = nullptr;
@@ -3567,9 +3581,8 @@ void nsHTMLMediaElement::UpdateAudioChan
}
/* void canPlayChanged (in boolean canPlay); */
NS_IMETHODIMP nsHTMLMediaElement::CanPlayChanged(bool canPlay)
{
UpdateChannelMuteState(canPlay);
return NS_OK;
}
-
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8498,16 +8498,22 @@ nsGlobalWindow::GetIndexedDB(nsIIDBFacto
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIIDBFactory> request(mIndexedDB);
request.forget(_retval);
return NS_OK;
}
+NS_IMETHODIMP
+nsGlobalWindow::GetMozIndexedDB(nsIIDBFactory** _retval)
+{
+ return GetIndexedDB(_retval);
+}
+
//*****************************************************************************
// nsGlobalWindow::nsIInterfaceRequestor
//*****************************************************************************
NS_IMETHODIMP
nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
{
NS_ENSURE_ARG_POINTER(aSink);
--- a/dom/bluetooth/BluetoothOppManager.cpp
+++ b/dom/bluetooth/BluetoothOppManager.cpp
@@ -41,19 +41,19 @@ public:
BluetoothOppManagerObserver()
{
}
bool Init()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (NS_FAILED(obs->AddObserver(this,
- NS_XPCOM_SHUTDOWN_OBSERVER_ID,
- false))) {
+ if (!obs || NS_FAILED(obs->AddObserver(this,
+ NS_XPCOM_SHUTDOWN_OBSERVER_ID,
+ false))) {
NS_WARNING("Failed to add shutdown observer!");
return false;
}
return true;
}
bool Shutdown()
@@ -477,16 +477,36 @@ BluetoothOppManager::CreateFile()
/*
* The function CreateUnique() may create a file with a different file
* name from the original sFileName. Therefore we have to retrieve
* the file name again.
*/
f->GetLeafName(sFileName);
+ mDsFile = nullptr;
+
+ nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
+ if (mimeSvc) {
+ nsCString mimeType;
+ nsresult rv = mimeSvc->GetTypeFromFile(f, mimeType);
+
+ if (NS_SUCCEEDED(rv)) {
+ if (StringBeginsWith(mimeType, NS_LITERAL_CSTRING("image/"))) {
+ mDsFile = new DeviceStorageFile(NS_LITERAL_STRING("pictures"), f);
+ } else if (StringBeginsWith(mimeType, NS_LITERAL_CSTRING("video/"))) {
+ mDsFile = new DeviceStorageFile(NS_LITERAL_STRING("movies"), f);
+ } else if (StringBeginsWith(mimeType, NS_LITERAL_CSTRING("audio/"))) {
+ mDsFile = new DeviceStorageFile(NS_LITERAL_STRING("music"), f);
+ } else {
+ NS_WARNING("Couldn't recognize the mimetype of received file.");
+ }
+ }
+ }
+
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
if (!mOutputStream) {
NS_WARNING("Couldn't new an output stream");
return false;
}
return true;
}
@@ -1235,22 +1255,34 @@ BluetoothOppManager::OnDisconnect()
/**
* It is valid for a bluetooth device which is transfering file via OPP
* closing socket without sending OBEX disconnect request first. So we
* delete the broken file when we failed to receive a file from the remote,
* and notify the transfer has been completed (but failed). We also call
* AfterOppDisconnected here to ensure all variables will be cleaned.
*/
if (mSocketStatus == SocketConnectionStatus::SOCKET_CONNECTED) {
+ if (mTransferMode) {
+ if (!mSuccessFlag) {
+ DeleteReceivedFile();
+ } else if (mDsFile) {
+ nsString data;
+ CopyASCIItoUTF16("modified", data);
+
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (obs) {
+ obs->NotifyObservers(mDsFile, "file-watcher-update", data.get());
+ }
+ }
+ }
+
if (!mSuccessFlag) {
- if (mTransferMode) {
- DeleteReceivedFile();
- }
FileTransferComplete();
}
+
Listen();
} else if (mSocketStatus == SocketConnectionStatus::SOCKET_CONNECTING) {
NS_WARNING("BluetoothOppManager got unexpected socket status!");
}
AfterOppDisconnected();
mConnectedDeviceAddress.AssignLiteral("00:00:00:00:00:00");
mSuccessFlag = false;
--- a/dom/bluetooth/BluetoothOppManager.h
+++ b/dom/bluetooth/BluetoothOppManager.h
@@ -5,16 +5,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothoppmanager_h__
#define mozilla_dom_bluetooth_bluetoothoppmanager_h__
#include "BluetoothCommon.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/ipc/UnixSocket.h"
+#include "DeviceStorage.h"
class nsIOutputStream;
class nsIInputStream;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class ObexHeaderSet;
@@ -160,13 +161,14 @@ private:
nsAutoPtr<uint8_t> mReceivedDataBuffer;
nsCOMPtr<nsIDOMBlob> mBlob;
nsCOMPtr<nsIThread> mReadFileThread;
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCOMPtr<nsIInputStream> mInputStream;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
+ nsRefPtr<DeviceStorageFile> mDsFile;
};
END_BLUETOOTH_NAMESPACE
#endif
--- a/dom/browser-element/BrowserElementScrolling.js
+++ b/dom/browser-element/BrowserElementScrolling.js
@@ -1,117 +1,207 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const ContentPanning = {
init: function cp_init() {
- ['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
+ ['mousedown', 'mouseup', 'mousemove', 'touchstart', 'touchend', 'touchmove'].forEach(function(type) {
addEventListener(type, ContentPanning, false);
});
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
},
+ evtFilter: '',
+ _filterEvent: function cp_filterEvent(evt) {
+ switch (this.evtFilter) {
+ case 'mouse':
+ if (evt.type == 'touchstart' || evt.type == 'touchend' || evt.type == 'touchmove') {
+ return false;
+ }
+ break;
+ case 'touch':
+ if (evt.type == 'mousedown' || evt.type == 'mouseup' || evt.type == 'mousemove') {
+ return false;
+ }
+ break;
+ }
+ return true;
+ },
handleEvent: function cp_handleEvent(evt) {
+ // determine scrolling detection is based on touch or mouse event at runtime
+ if (!this.evtFilter) {
+ if (evt.type == 'touchstart') this.evtFilter = 'touch';
+ else if (evt.type == 'mousedown') this.evtFilter = 'mouse';
+ }
+ if (evt.defaultPrevented || !this._filterEvent(evt)) return;
+
switch (evt.type) {
case 'mousedown':
+ case 'touchstart':
this.onTouchStart(evt);
break;
case 'mousemove':
+ case 'touchmove':
this.onTouchMove(evt);
break;
case 'mouseup':
+ case 'touchend':
this.onTouchEnd(evt);
break;
case 'click':
evt.stopPropagation();
evt.preventDefault();
let target = evt.target;
let view = target.ownerDocument ? target.ownerDocument.defaultView
: target;
view.removeEventListener('click', this, true, true);
break;
}
},
position: new Point(0 , 0),
+ findFirstTouch: function cp_findFirstTouch(touches) {
+ if (!('trackingId' in this)) return undefined;
+
+ for (let i = 0; i < touches.length; i++) {
+ if (touches[i].identifier === this.trackingId)
+ return touches[i];
+ }
+ return undefined;
+ },
+
onTouchStart: function cp_onTouchStart(evt) {
+ let target, screenX, screenY;
+ if (this.evtFilter == 'touch') {
+ if ('trackingId' in this) {
+ return;
+ }
+
+ let firstTouch = evt.changedTouches[0];
+ this.trackingId = firstTouch.identifier;
+ target = firstTouch.target;
+ screenX = firstTouch.screenX;
+ screenY = firstTouch.screenY;
+ } else {
+ target = evt.target;
+ screenX = evt.screenX;
+ screenY = evt.screenY;
+ }
+
this.dragging = true;
this.panning = false;
let oldTarget = this.target;
- [this.target, this.scrollCallback] = this.getPannable(evt.target);
+ [this.target, this.scrollCallback] = this.getPannable(target);
// If we found a target, that means we have found a scrollable subframe. In
// this case, and if we are using async panning and zooming on the parent
// frame, inform the pan/zoom controller that it should not attempt to
// handle any touch events it gets until the next batch (meaning the next
// time we get a touch end).
if (this.target != null && ContentPanning._asyncPanZoomForViewportFrame) {
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- os.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
+ os.notifyObservers(docShell, 'detect-scrollable-subframe', null);
}
// If there is a pan animation running (from a previous pan gesture) and
// the user touch back the screen, stop this animation immediatly and
// prevent the possible click action if the touch happens on the same
// target.
this.preventNextClick = false;
if (KineticPanning.active) {
KineticPanning.stop();
if (oldTarget && oldTarget == this.target)
this.preventNextClick = true;
}
- this.position.set(evt.screenX, evt.screenY);
+ this.position.set(screenX, screenY);
KineticPanning.record(new Point(0, 0), evt.timeStamp);
},
onTouchEnd: function cp_onTouchEnd(evt) {
+ if (this.evtFilter == 'touch' && !this.findFirstTouch(evt.changedTouches))
+ return;
+
if (!this.dragging)
return;
this.dragging = false;
+ this.isScrolling = false;
this.onTouchMove(evt);
- let click = evt.detail;
+ delete this.trackingId;
+
+ let click = (this.evtFilter == 'touch') ? true : evt.detail;
if (this.target && click && (this.panning || this.preventNextClick)) {
let target = this.target;
let view = target.ownerDocument ? target.ownerDocument.defaultView
: target;
view.addEventListener('click', this, true, true);
}
if (this.panning)
KineticPanning.start(this);
},
+ isScrolling: false, // Scrolling gesture is executed in BrowserElementScrolling
onTouchMove: function cp_onTouchMove(evt) {
if (!this.dragging || !this.scrollCallback)
return;
+ let screenX, screenY;
+ if (this.evtFilter == 'touch') {
+ let firstTouch = this.findFirstTouch(evt.changedTouches);
+ if (evt.touches.length > 1 || !firstTouch)
+ return;
+ screenX = firstTouch.screenX;
+ screenY = firstTouch.screenY;
+ } else {
+ screenX = evt.screenX;
+ screenY = evt.screenY;
+ }
+
let current = this.position;
- let delta = new Point(evt.screenX - current.x, evt.screenY - current.y);
- current.set(evt.screenX, evt.screenY);
+ let delta = new Point(screenX - current.x, screenY - current.y);
+ current.set(screenX, screenY);
KineticPanning.record(delta, evt.timeStamp);
- this.scrollCallback(delta.scale(-1));
+ let success = this.scrollCallback(delta.scale(-1));
+ // Stop async-pan-zooming if the subframe is really scrolled.
+ if (!this.isScrolling && ContentPanning._asyncPanZoomForViewportFrame) {
+ if (success) {
+ var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ os.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
+ } else {
+ // Let AsyncPanZoomController handle the scrolling gesture.
+ delete this.trackingId;
+ return;
+ }
+ }
+
+ // Successfully scroll the inner scrollable region.
+ if (success && !this.isScrolling) {
+ this.isScrolling = true;
+ }
+
// If a pan action happens, cancel the active state of the
// current target.
if (!this.panning && KineticPanning.isPan()) {
this.panning = true;
this._resetActive();
}
+
evt.stopPropagation();
evt.preventDefault();
},
onKineticBegin: function cp_onKineticBegin(evt) {
},
--- a/dom/interfaces/storage/nsIDOMStorageIndexedDB.idl
+++ b/dom/interfaces/storage/nsIDOMStorageIndexedDB.idl
@@ -10,16 +10,17 @@
* http://www.whatwg.org/specs/web-apps/current-work/#scs-client-side and
* http://www.w3.org/TR/IndexedDB/ for more information.
*
* Allows access to contextual storage areas.
*/
interface nsIIDBFactory;
-[scriptable, uuid(c5982775-3f65-4d3e-b5f0-2400c987a900)]
+[scriptable, uuid(94ca74e8-9cff-456e-a7a4-a4071a32ff58)]
interface nsIDOMStorageIndexedDB : nsISupports
{
/**
* Indexed Databases for the current browsing context.
*/
readonly attribute nsIIDBFactory indexedDB;
+ readonly attribute nsIIDBFactory mozIndexedDB;
};
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -91,16 +91,17 @@ using namespace mozilla::widget;
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
static const nsIntSize kDefaultViewportSize(980, 480);
static const char CANCEL_DEFAULT_PAN_ZOOM[] = "cancel-default-pan-zoom";
static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect";
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
+static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe";
NS_IMETHODIMP
ContentListener::HandleEvent(nsIDOMEvent* aEvent)
{
RemoteDOMEvent remoteEvent;
remoteEvent.mEvent = do_QueryInterface(aEvent);
NS_ENSURE_STATE(remoteEvent.mEvent);
mTabChild->SendEvent(remoteEvent);
@@ -236,16 +237,22 @@ TabChild::Observe(nsISupports *aSubject,
AsyncPanZoomController::CalculateResolution(mLastMetrics);
mLastMetrics.mScrollOffset = gfx::Point(0, 0);
utils->SetResolution(mLastMetrics.mResolution.width,
mLastMetrics.mResolution.height);
HandlePossibleViewportChange();
}
}
+ } else if (!strcmp(aTopic, DETECT_SCROLLABLE_SUBFRAME)) {
+ nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
+ nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
+ if (tabChild == this) {
+ mRemoteFrame->DetectScrollableSubframe();
+ }
}
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
@@ -1671,16 +1678,17 @@ TabChild::RecvDestroy()
}
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
observerService->RemoveObserver(this, CANCEL_DEFAULT_PAN_ZOOM);
observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT);
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
+ observerService->RemoveObserver(this, DETECT_SCROLLABLE_SUBFRAME);
const InfallibleTArray<PIndexedDBChild*>& idbActors =
ManagedPIndexedDBChild();
for (uint32_t i = 0; i < idbActors.Length(); ++i) {
static_cast<IndexedDBChild*>(idbActors[i])->Disconnect();
}
// XXX what other code in ~TabChild() should we be running here?
@@ -1798,16 +1806,19 @@ TabChild::InitRenderingState()
CANCEL_DEFAULT_PAN_ZOOM,
false);
observerService->AddObserver(this,
BROWSER_ZOOM_TO_RECT,
false);
observerService->AddObserver(this,
BEFORE_FIRST_PAINT,
false);
+ observerService->AddObserver(this,
+ DETECT_SCROLLABLE_SUBFRAME,
+ false);
}
return true;
}
void
TabChild::SetBackgroundColor(const nscolor& aColor)
{
--- a/dom/wifi/wifi_worker.js
+++ b/dom/wifi/wifi_worker.js
@@ -40,21 +40,32 @@ self.onmessage = function(e) {
var cmd = data.cmd;
switch (cmd) {
case "command":
len.value = 4096;
var ret = libhardware_legacy.command(data.request, cbuf, len.address());
var reply = "";
if (!ret) {
+ // The return value from libhardware_legacy.command is not guaranteed to
+ // be null-terminated. At the same time we want to make sure that we
+ // don't return a response with a trailing newline, so handle both cases
+ // here. Note that if we wrote 4096 characters to cbuf, we don't have to
+ // null-terminate the buffer, as ctypes has the maximum size already.
var reply_len = len.value;
- var str = cbuf.readString();
- if (str[reply_len-1] == "\n")
- --reply_len;
- reply = str.substr(0, reply_len);
+ if (reply_len !== 0) {
+ if (cbuf[reply_len - 1] === 10)
+ cbuf[--reply_len] = 0;
+ else if (reply_len !== 4096)
+ cbuf[reply_len] = 0;
+
+ reply = cbuf.readString();
+ }
+
+ // Else if reply_len was 0, use the empty reply, set above.
}
postMessage({ id: id, status: ret, reply: reply });
break;
case "wait_for_event":
var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
var event = cbuf.readString().substr(0, ret.value);
postMessage({ id: id, event: event });
break;
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -589,16 +589,36 @@ Layer::SnapTransform(const gfx3DMatrix&
*aResidualTransform = matrix2D * snappedMatrixInverse;
}
} else {
result = aTransform;
}
return result;
}
+static bool
+AncestorLayerMayChangeTransform(Layer* aLayer)
+{
+ for (Layer* l = aLayer; l; l = l->GetParent()) {
+ if (l->GetContentFlags() & Layer::CONTENT_MAY_CHANGE_TRANSFORM) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+Layer::MayResample()
+{
+ gfxMatrix transform2d;
+ return !GetEffectiveTransform().Is2D(&transform2d) ||
+ transform2d.HasNonIntegerTranslation() ||
+ AncestorLayerMayChangeTransform(this);
+}
+
nsIntRect
Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
const gfxMatrix* aWorldTransform)
{
ContainerLayer* container = GetParent();
NS_ASSERTION(container, "This can't be called on the root!");
// Establish initial clip rect: it's either the one passed in, or
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -571,17 +571,23 @@ public:
* This should never be set at the same time as CONTENT_OPAQUE.
*/
CONTENT_COMPONENT_ALPHA = 0x02,
/**
* If this is set then this layer is part of a preserve-3d group, and should
* be sorted with sibling layers that are also part of the same group.
*/
- CONTENT_PRESERVE_3D = 0x04
+ CONTENT_PRESERVE_3D = 0x04,
+ /**
+ * This indicates that the transform may be changed on during an empty
+ * transaction where there is no possibility of redrawing the content, so the
+ * implementation should be ready for that.
+ */
+ CONTENT_MAY_CHANGE_TRANSFORM = 0x08
};
/**
* CONSTRUCTION PHASE ONLY
* This lets layout make some promises about what will be drawn into the
* visible region of the ThebesLayer. This enables internal quality
* and performance optimizations.
*/
void SetContentFlags(uint32_t aFlags)
@@ -1078,16 +1084,24 @@ protected:
* transform matrix
* @param aResidualTransform a transform to apply before mEffectiveTransform
* in order to get the results to completely match aTransform
*/
gfx3DMatrix SnapTransform(const gfx3DMatrix& aTransform,
const gfxRect& aSnapRect,
gfxMatrix* aResidualTransform);
+ /**
+ * Returns true if this layer's effective transform is not just
+ * a translation by integers, or if this layer or some ancestor layer
+ * is marked as having a transform that may change without a full layer
+ * transaction.
+ */
+ bool MayResample();
+
LayerManager* mManager;
ContainerLayer* mParent;
Layer* mNextSibling;
Layer* mPrevSibling;
void* mImplData;
nsRefPtr<Layer> mMaskLayer;
gfx::UserData mUserData;
nsIntRegion mVisibleRegion;
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -155,19 +155,17 @@ BasicThebesLayer::PaintThebes(gfxContext
{
uint32_t flags = 0;
#ifndef MOZ_WIDGET_ANDROID
if (BasicManager()->CompositorMightResample()) {
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
}
if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
- gfxMatrix transform;
- if (!GetEffectiveTransform().CanDraw2D(&transform) ||
- transform.HasNonIntegerTranslation()) {
+ if (MayResample()) {
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
}
}
#endif
if (mDrawAtomically) {
flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
}
Buffer::PaintState state =
--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
@@ -160,19 +160,17 @@ ThebesLayerD3D10::Validate(ReadbackProce
// If we have a transform that requires resampling of our texture, then
// we need to make sure we don't sample pixels that haven't been drawn.
// We clamp sample coordinates to the texture rect, but when the visible region
// doesn't fill the entire texture rect we need to make sure we draw all the
// pixels in the texture rect anyway in case they get sampled.
nsIntRegion neededRegion = mVisibleRegion;
if (!neededRegion.GetBounds().IsEqualInterior(newTextureRect) ||
neededRegion.GetNumRects() > 1) {
- gfxMatrix transform2d;
- if (!GetEffectiveTransform().Is2D(&transform2d) ||
- transform2d.HasNonIntegerTranslation()) {
+ if (MayResample()) {
neededRegion = newTextureRect;
if (mode == SURFACE_OPAQUE) {
// We're going to paint outside the visible region, but layout hasn't
// promised that it will paint opaquely there, so we'll have to
// treat this layer as transparent.
mode = SURFACE_SINGLE_CHANNEL_ALPHA;
}
}
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -187,19 +187,17 @@ ThebesLayerD3D9::RenderThebesLayer(Readb
// If we have a transform that requires resampling of our texture, then
// we need to make sure we don't sample pixels that haven't been drawn.
// We clamp sample coordinates to the texture rect, but when the visible region
// doesn't fill the entire texture rect we need to make sure we draw all the
// pixels in the texture rect anyway in case they get sampled.
nsIntRegion neededRegion = mVisibleRegion;
if (!neededRegion.GetBounds().IsEqualInterior(newTextureRect) ||
neededRegion.GetNumRects() > 1) {
- gfxMatrix transform2d;
- if (!GetEffectiveTransform().Is2D(&transform2d) ||
- transform2d.HasNonIntegerTranslation()) {
+ if (MayResample()) {
neededRegion = newTextureRect;
if (mode == SURFACE_OPAQUE) {
// We're going to paint outside the visible region, but layout hasn't
// promised that it will paint opaquely there, so we'll have to
// treat this layer as transparent.
mode = SURFACE_SINGLE_CHANNEL_ALPHA;
}
}
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -232,16 +232,36 @@ nsEventStatus AsyncPanZoomController::Ha
nsEventStatus rv = nsEventStatus_eIgnore;
if (mGestureEventListener && !mDisableNextTouchBatch) {
rv = mGestureEventListener->HandleInputEvent(aEvent);
if (rv == nsEventStatus_eConsumeNoDefault)
return rv;
}
+ if (mDelayPanning && aEvent.mInputType == MULTITOUCH_INPUT) {
+ const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
+ if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_MOVE) {
+ // Let BrowserElementScrolling perform panning gesture first.
+ SetState(WAITING_LISTENERS);
+ mTouchQueue.AppendElement(multiTouchInput);
+
+ if (!mTouchListenerTimeoutTask) {
+ mTouchListenerTimeoutTask =
+ NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ mTouchListenerTimeoutTask,
+ TOUCH_LISTENER_TIMEOUT);
+ }
+ return nsEventStatus_eConsumeNoDefault;
+ }
+ }
+
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
switch (multiTouchInput.mType) {
case MultiTouchInput::MULTITOUCH_START: rv = OnTouchStart(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_MOVE: rv = OnTouchMove(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_END: rv = OnTouchEnd(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_CANCEL: rv = OnTouchCancel(multiTouchInput); break;
@@ -1084,16 +1104,17 @@ bool AsyncPanZoomController::SampleConte
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFrame, bool aIsFirstPaint) {
MonitorAutoLock monitor(mMonitor);
mPaintThrottler.TaskComplete();
mLastContentPaintMetrics = aViewportFrame;
+ mFrameMetrics.mMayHaveTouchListeners = aViewportFrame.mMayHaveTouchListeners;
if (mWaitingForContentToPaint) {
// Remove the oldest sample we have if adding a new sample takes us over our
// desired number of samples.
if (mPreviousPaintDurations.Length() >= NUM_PAINT_DURATION_SAMPLES) {
mPreviousPaintDurations.RemoveElementAt(0);
}
mPreviousPaintDurations.AppendElement(
@@ -1177,16 +1198,20 @@ void AsyncPanZoomController::UpdateCompo
void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true;
if (mGestureEventListener) {
mGestureEventListener->CancelGesture();
}
}
+void AsyncPanZoomController::DetectScrollableSubframe() {
+ mDelayPanning = true;
+}
+
void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height));
SetState(ANIMATING_ZOOM);
{
MonitorAutoLock mon(mMonitor);
@@ -1263,34 +1288,43 @@ void AsyncPanZoomController::ZoomToRect(
mAnimationStartTime = TimeStamp::Now();
ScheduleComposite();
}
}
void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
- if (!mFrameMetrics.mMayHaveTouchListeners) {
+ if (!mFrameMetrics.mMayHaveTouchListeners && !mDelayPanning) {
mTouchQueue.Clear();
return;
}
if (mTouchListenerTimeoutTask) {
mTouchListenerTimeoutTask->Cancel();
mTouchListenerTimeoutTask = nullptr;
}
if (mState == WAITING_LISTENERS) {
if (!aPreventDefault) {
- SetState(NOTHING);
+ // Delayed scrolling gesture is pending at TOUCHING state.
+ if (mDelayPanning) {
+ SetState(TOUCHING);
+ } else {
+ SetState(NOTHING);
+ }
}
mHandlingTouchQueue = true;
while (!mTouchQueue.IsEmpty()) {
+ // we need to reset mDelayPanning before handling scrolling gesture.
+ if (mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_MOVE) {
+ mDelayPanning = false;
+ }
if (!aPreventDefault) {
HandleInputEvent(mTouchQueue[0]);
}
if (mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_END ||
mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_CANCEL) {
mTouchQueue.RemoveElementAt(0);
break;
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -103,26 +103,32 @@ public:
* the frame this is tied to during composition onto, in device pixels. In
* general, this will just be:
* { x = 0, y = 0, width = surface.width, height = surface.height }, however
* there is no hard requirement for this.
*/
void UpdateCompositionBounds(const nsIntRect& aCompositionBounds);
/**
- * We have found a scrollable subframe, so disable our machinery until we hit
+ * We are scrolling a subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally
* panning both the subframe and the parent frame.
*
* XXX/bug 775452: We should eventually be supporting async scrollable
* subframes.
*/
void CancelDefaultPanZoom();
/**
+ * We have found a scrollable subframe, so we need to delay the scrolling
+ * gesture executed and let subframe do the scrolling first.
+ */
+ void DetectScrollableSubframe();
+
+ /**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
* in. The actual animation is done on the compositor thread after being set
* up. |aRect| must be given in CSS pixels, relative to the document.
*/
void ZoomToRect(const gfxRect& aRect);
/**
* If we have touch listeners, this should always be called when we know
@@ -544,15 +550,21 @@ private:
bool mDisableNextTouchBatch;
// Flag used to determine whether or not we should try to enter the
// WAITING_LISTENERS state. This is used in the case that we are processing a
// queued up event block. If set, this means that we are handling this queue
// and we don't want to queue the events back up again.
bool mHandlingTouchQueue;
+ // Flag used to determine whether or not we should try scrolling by
+ // BrowserElementScrolling first. If set, this means we should pend touch move
+ // event, which not be cosumed by GestureListener. This flag will be reset
+ // after touch move event has been handled by content process.
+ bool mDelayPanning;
+
friend class Axis;
};
}
}
#endif // mozilla_layers_PanZoomController_h
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -852,22 +852,17 @@ ThebesLayerOGL::RenderLayer(int aPreviou
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
TextureImage::ContentType contentType =
CanUseOpaqueSurface() ? gfxASurface::CONTENT_COLOR :
gfxASurface::CONTENT_COLOR_ALPHA;
uint32_t flags = 0;
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
- gfxMatrix transform2d;
- if (GetEffectiveTransform().Is2D(&transform2d)) {
- if (transform2d.HasNonIntegerTranslation()) {
- flags |= ThebesLayerBufferOGL::PAINT_WILL_RESAMPLE;
- }
- } else {
+ if (MayResample()) {
flags |= ThebesLayerBufferOGL::PAINT_WILL_RESAMPLE;
}
#endif
Buffer::PaintState state = mBuffer->BeginPaint(contentType, flags);
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
if (state.mContext) {
--- a/image/test/mochitest/test_bug733553.html
+++ b/image/test/mochitest/test_bug733553.html
@@ -64,17 +64,20 @@ function readyForNext() {
function imageLoad(aEvent) {
var [width, fileName] = testParts[testIndex];
is(aEvent.target.width, width,
"Test " + testIndex + " " + fileName + " width correct");
// Always call readyForNext here, as it's the closest we have to a cleanup
readyForNext();
- if ((testParts.length - 1) == testIndex) {
+ if (testParts.length == testIndex) {
+ var firstimg = document.getElementsByTagName('img')[0];
+ firstimg.removeEventListener("load", imageLoad, false);
+ firstimg.removeEventListener("error", imageLoad, false);
SimpleTest.finish();
}
}
</script>
</pre>
<div id="content"> <!-- style="display: none" -->
<iframe id="loader"></iframe>
--- a/intl/lwbrk/public/nsILineBreaker.h
+++ b/intl/lwbrk/public/nsILineBreaker.h
@@ -50,21 +50,23 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsILineBreaker, NS_ILINEBREAKER_IID)
static inline bool
NS_IsSpace(PRUnichar u)
{
return u == 0x0020 || // SPACE
u == 0x0009 || // CHARACTER TABULATION
u == 0x000D || // CARRIAGE RETURN
+ u == 0x1680 || // OGHAM SPACE MARK
(0x2000 <= u && u <= 0x2006) || // EN QUAD, EM QUAD, EN SPACE,
// EM SPACE, THREE-PER-EM SPACE,
// FOUR-PER-SPACE, SIX-PER-EM SPACE,
- (0x2008 <= u && u <= 0x200B); // PUNCTUATION SPACE, THIN SPACE,
+ (0x2008 <= u && u <= 0x200B) || // PUNCTUATION SPACE, THIN SPACE,
// HAIR SPACE, ZERO WIDTH SPACE
+ u == 0x205F; // MEDIUM MATHEMATICAL SPACE
}
static inline bool
NS_NeedsPlatformNativeHandling(PRUnichar aChar)
{
return (0x0e01 <= aChar && aChar <= 0x0fff); // Thai, Lao, Tibetan
}
--- a/intl/lwbrk/src/jisx4501class.h
+++ b/intl/lwbrk/src/jisx4501class.h
@@ -48,17 +48,17 @@ 0x777277B7, // U+2010 - U+2017
0x77A777A7, // U+2018 - U+201F
0xAAAA7777, // U+2020 - U+2027
0xB7777777, // U+2028 - U+202F
0x77744444, // U+2030 - U+2037
0x7A115107, // U+2038 - U+203F
0x11017777, // U+2040 - U+2047
0x77777711, // U+2048 - U+204F
0x77777777, // U+2050 - U+2057
-0x77777777, // U+2058 - U+205F
+0x57777777, // U+2058 - U+205F
0x77777777, // U+2060 - U+2067
0x77777777, // U+2068 - U+206F
0x77777777, // U+2070 - U+2077
0x77777777, // U+2078 - U+207F
0x77777777, // U+2080 - U+2087
0x77777777, // U+2088 - U+208F
0x77777777, // U+2090 - U+2097
0x77777777, // U+2098 - U+209F
--- a/intl/lwbrk/src/nsJISx4501LineBreaker.cpp
+++ b/intl/lwbrk/src/nsJISx4501LineBreaker.cpp
@@ -486,16 +486,22 @@ GetClass(PRUnichar u)
c = CLASS_NON_BREAKABLE;
else
c = CLASS_CHARACTER;
} else if (0x1800 == h) {
if (0x0E == l)
c = CLASS_NON_BREAKABLE;
else
c = CLASS_CHARACTER;
+ } else if (0x1600 == h) {
+ if (0x80 == l) { // U+1680 OGHAM SPACE MARK
+ c = CLASS_BREAKABLE;
+ } else {
+ c = CLASS_CHARACTER;
+ }
} else {
c = CLASS_CHARACTER; // others
}
return c;
}
static bool
GetPair(int8_t c1, int8_t c2)
--- a/intl/lwbrk/tools/anzx4501.html
+++ b/intl/lwbrk/tools/anzx4501.html
@@ -249,18 +249,18 @@ Analysis of JIS X 4051 to Unicode Genera
</TR>
<TR><TH>05_[b]<TH>
<TD>33</TD>
<TD>153</TD>
<TD></TD>
<TD>33</TD>
<TD>2</TD>
<TD>5</TD>
-<TD>12</TD>
-<TD BGCOLOR=white>238</TD>
+<TD>13</TD>
+<TD BGCOLOR=white>239</TD>
<TD>32</TD>
<TD>1</TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD>153</TD>
<TD></TD>
@@ -279,17 +279,17 @@ Analysis of JIS X 4051 to Unicode Genera
<TD>2</TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD>5</TD>
<TD></TD>
<TD></TD>
-<TD>12</TD>
+<TD>13</TD>
</TR>
<TR><TH>06_15<TH>
<TD></TD>
<TD></TD>
<TD></TD>
<TD>30</TD>
<TD></TD>
<TD></TD>
@@ -322,52 +322,52 @@ Analysis of JIS X 4051 to Unicode Genera
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
</TR>
<TR><TH>07_18<TH>
<TD>19</TD>
-<TD>156</TD>
+<TD>157</TD>
<TD></TD>
<TD>33</TD>
<TD>56</TD>
-<TD>126</TD>
-<TD>3</TD>
-<TD BGCOLOR=white>393</TD>
+<TD>125</TD>
+<TD>2</TD>
+<TD BGCOLOR=white>392</TD>
<TD></TD>
<TD>19</TD>
<TD></TD>
<TD></TD>
-<TD>67</TD>
+<TD>64</TD>
+<TD>7</TD>
<TD>5</TD>
-<TD>4</TD>
<TD></TD>
-<TD>80</TD>
+<TD>81</TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD>3</TD>
<TD>30</TD>
<TD>4</TD>
<TD>5</TD>
<TD>2</TD>
<TD></TD>
<TD>5</TD>
<TD>36</TD>
<TD>4</TD>
<TD></TD>
<TD>3</TD>
-<TD>23</TD>
-<TD>100</TD>
+<TD>24</TD>
+<TD>98</TD>
<TD>1</TD>
<TD>1</TD>
-<TD>1</TD>
+<TD></TD>
</TR>
<TR><TH>08_COMPLEX<TH>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
@@ -442,46 +442,46 @@ Analysis of JIS X 4051 to Unicode Genera
<TD></TD>
<TD></TD>
</TR>
<TR><TH>0A_[d]<TH>
<TD>1</TD>
<TD>2</TD>
<TD></TD>
<TD>6</TD>
-<TD>26</TD>
-<TD>16</TD>
+<TD>28</TD>
+<TD>14</TD>
<TD></TD>
<TD BGCOLOR=white>51</TD>
<TD></TD>
<TD>1</TD>
<TD></TD>
<TD></TD>
-<TD>2</TD>
+<TD>1</TD>
<TD></TD>
-<TD></TD>
+<TD>1</TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD>6</TD>
<TD></TD>
<TD></TD>
<TD>3</TD>
<TD>3</TD>
<TD></TD>
-<TD>20</TD>
+<TD>22</TD>
<TD></TD>
<TD>2</TD>
<TD>3</TD>
<TD>7</TD>
-<TD>4</TD>
+<TD>2</TD>
<TD></TD>
<TD></TD>
<TD></TD>
</TR>
<TR><TH>0B_[e]<TH>
<TD></TD>
<TD></TD>
<TD></TD>
@@ -607,19 +607,19 @@ Analysis of JIS X 4051 to Unicode Genera
<TD></TD>
</TR>
<TR><TH>20<TH>
<TD>2</TD>
<TD>8</TD>
<TD>1</TD>
<TD></TD>
<TD>5</TD>
-<TD>12</TD>
+<TD>13</TD>
<TD></TD>
-<TD>102</TD>
+<TD>101</TD>
<TD></TD>
<TD></TD>
<TD>7</TD>
<TD>3</TD>
<TD></TD>
</TR>
<TR><TH>21<TH>
<TD></TD>
--- a/intl/lwbrk/tools/anzx4501.pl
+++ b/intl/lwbrk/tools/anzx4501.pl
@@ -54,16 +54,20 @@ open ( HEADER , "> ../src/jisx4501class.
|| die "cannot open output ../src/jisx4501class.h file";
######################################################################
#
# Generate license and header
#
######################################################################
$hthmlheader = <<END_OF_HTML;
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
<HTML>
<HEAD>
<TITLE>
Analysis of JIS X 4051 to Unicode General Category Mapping
</TITLE>
</HEAD>
<BODY>
<H1>
--- a/intl/lwbrk/tools/jisx4501class.txt
+++ b/intl/lwbrk/tools/jisx4501class.txt
@@ -65,17 +65,19 @@ 203A;;2
203B;;12
203C;203D;3
203E;;23
203F;2043;18
2044;;3
2045;;1
2046;;2
2047;2049;3
-204A;2063;18
+204A;205E;18
+205F;;17
+2060;2063;18
206A;206F;18
2070;2071;18
2074;208E;18
2090;2094;18
2116;;8
2160;217F;12
2190;21EA;a12
2126;;18
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -591,19 +591,20 @@ ion::CachedShapeGuardFailure()
}
uint32_t
ion::ThunkToInterpreter(Value *vp)
{
JSContext *cx = GetIonContext()->cx;
IonActivation *activation = cx->runtime->ionActivation;
BailoutClosure *br = activation->takeBailout();
+ InterpMode resumeMode = JSINTERP_BAILOUT;
if (!EnsureHasScopeObjects(cx, cx->fp()))
- return Interpret_Error;
+ resumeMode = JSINTERP_RETHROW;
// By default we set the forbidOsr flag on the ion script, but if a GC
// happens just after we re-enter the interpreter, the ion script get
// invalidated and we do not see the forbidOsr flag. This may cause a loop
// which apear with eager compilation and gc zeal enabled. This code is a
// workaround to avoid recompiling with OSR just after a bailout followed by
// a GC. (see Bug 746691 & Bug 751383)
jsbytecode *pc = cx->regs().pc;
@@ -626,18 +627,20 @@ ion::ThunkToInterpreter(Value *vp)
fp = iter.interpFrame();
script = iter.script();
if (script->needsArgsObj()) {
// Currently IonMonkey does not compile if the script needs an
// arguments object, so the frame should not have any argument
// object yet.
JS_ASSERT(!fp->hasArgsObj());
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, fp);
- if (!argsobj)
- return Interpret_Error;
+ if (!argsobj) {
+ resumeMode = JSINTERP_RETHROW;
+ break;
+ }
InternalBindingsHandle bindings(script, &script->bindings);
const unsigned var = Bindings::argumentsVarIndex(cx, bindings);
// The arguments is a local binding and needsArgsObj does not
// check if it is clobbered. Ensure that the local binding
// restored during bailout before storing the arguments object
// to the slot.
if (fp->unaliasedLocal(var).isMagic(JS_OPTIMIZED_ARGUMENTS))
fp->unaliasedLocal(var) = ObjectValue(*argsobj);
@@ -648,20 +651,21 @@ ion::ThunkToInterpreter(Value *vp)
if (activation->entryfp() == br->entryfp()) {
// If the bailout entry fp is the same as the activation entryfp, then
// there are no scripted frames below us. In this case, just shortcut
// out with a special return code, and resume interpreting in the
// original Interpret activation.
vp->setMagic(JS_ION_BAILOUT);
js_delete(br);
- return Interpret_Ok;
+ return resumeMode == JSINTERP_RETHROW ? Interpret_Error : Interpret_Ok;
}
- InterpretStatus status = Interpret(cx, br->entryfp(), JSINTERP_BAILOUT);
+ InterpretStatus status = Interpret(cx, br->entryfp(), resumeMode);
+ JS_ASSERT_IF(resumeMode == JSINTERP_RETHROW, status == Interpret_Error);
if (status == Interpret_OSR) {
// The interpreter currently does not ask to perform inline OSR, so
// this path is unreachable.
JS_NOT_REACHED("invalid");
IonSpew(IonSpew_Bailouts, "Performing inline OSR %s:%d",
cx->fp()->script()->filename,
--- a/js/src/ion/MCallOptimize.cpp
+++ b/js/src/ion/MCallOptimize.cpp
@@ -708,17 +708,18 @@ IonBuilder::inlineStrCharCodeAt(uint32_t
{
if (argc != 1 || constructing)
return InliningStatus_NotInlined;
if (getInlineReturnType() != MIRType_Int32)
return InliningStatus_NotInlined;
if (getInlineArgType(argc, 0) != MIRType_String)
return InliningStatus_NotInlined;
- if (getInlineArgType(argc, 1) != MIRType_Int32)
+ MIRType argType = getInlineArgType(argc, 1);
+ if (argType != MIRType_Int32 && argType != MIRType_Double)
return InliningStatus_NotInlined;
MDefinitionVector argv;
if (!discardCall(argc, argv, current))
return InliningStatus_Error;
MInstruction *index = MToInt32::New(argv[1]);
current->add(index);
@@ -763,17 +764,18 @@ IonBuilder::inlineStrCharAt(uint32_t arg
{
if (argc != 1 || constructing)
return InliningStatus_NotInlined;
if (getInlineReturnType() != MIRType_String)
return InliningStatus_NotInlined;
if (getInlineArgType(argc, 0) != MIRType_String)
return InliningStatus_NotInlined;
- if (getInlineArgType(argc, 1) != MIRType_Int32)
+ MIRType argType = getInlineArgType(argc, 1);
+ if (argType != MIRType_Int32 && argType != MIRType_Double)
return InliningStatus_NotInlined;
MDefinitionVector argv;
if (!discardCall(argc, argv, current))
return InliningStatus_Error;
MInstruction *index = MToInt32::New(argv[1]);
current->add(index);
--- a/js/src/ion/TypeOracle.cpp
+++ b/js/src/ion/TypeOracle.cpp
@@ -343,24 +343,25 @@ TypeInferenceOracle::elementReadIsTypedA
}
return true;
}
bool
TypeInferenceOracle::elementReadIsString(JSScript *script, jsbytecode *pc)
{
- // Check for string[int32].
+ // Check for string[index].
StackTypeSet *value = script->analysis()->poppedTypes(pc, 1);
StackTypeSet *id = script->analysis()->poppedTypes(pc, 0);
if (value->getKnownTypeTag() != JSVAL_TYPE_STRING)
return false;
- if (id->getKnownTypeTag() != JSVAL_TYPE_INT32)
+ JSValueType idType = id->getKnownTypeTag();
+ if (idType != JSVAL_TYPE_INT32 && idType != JSVAL_TYPE_DOUBLE)
return false;
// This function is used for jsop_getelem_string which should return
// undefined if this is out-side the string bounds. Currently we just
// fallback to a CallGetElement.
StackTypeSet *pushed = script->analysis()->pushedTypes(pc, 0);
if (pushed->getKnownTypeTag() != JSVAL_TYPE_STRING)
return false;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -802,16 +802,19 @@ JSRuntime::JSRuntime(JSUseHelperThreads
gcSweepingCompartments(NULL),
gcCompartmentGroupIndex(0),
gcCompartmentGroups(NULL),
gcCurrentCompartmentGroup(NULL),
gcSweepPhase(0),
gcSweepCompartment(NULL),
gcSweepKindIndex(0),
gcArenasAllocatedDuringSweep(NULL),
+#ifdef DEBUG
+ gcMarkingValidator(NULL),
+#endif
gcInterFrameGC(0),
gcSliceBudget(SliceBudget::Unlimited),
gcIncrementalEnabled(true),
gcExactScanningEnabled(true),
gcManipulatingDeadCompartments(false),
gcObjectsMarkedInDeadCompartments(0),
gcPoke(false),
heapState(Idle),
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -445,16 +445,20 @@ class PerThreadData : public js::PerThre
*/
int32_t suppressGC;
PerThreadData(JSRuntime *runtime);
bool associatedWith(const JSRuntime *rt) { return runtime_ == rt; }
};
+namespace gc {
+class MarkingValidator;
+} // namespace gc
+
} // namespace js
struct JSRuntime : js::RuntimeFriendFields
{
/* Per-thread data for the main thread that is associated with
* this JSRuntime, as opposed to any worker threads used in
* parallel sections. See definition of |PerThreadData| struct
* above for more details.
@@ -724,16 +728,20 @@ struct JSRuntime : js::RuntimeFriendFiel
JSCompartment *gcSweepCompartment;
int gcSweepKindIndex;
/*
* List head of arenas allocated during the sweep phase.
*/
js::gc::ArenaHeader *gcArenasAllocatedDuringSweep;
+#ifdef DEBUG
+ js::gc::MarkingValidator *gcMarkingValidator;
+#endif
+
/*
* Indicates that a GC slice has taken place in the middle of an animation
* frame, rather than at the beginning. In this case, the next slice will be
* delayed so that we don't get back-to-back slices.
*/
volatile uintptr_t gcInterFrameGC;
/* Default budget for incremental GC slice. See SliceBudget in jsgc.h. */
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2693,43 +2693,58 @@ BeginMarkPhase(JSRuntime *rt)
if (!c->maybeAlive)
c->scheduledForDestruction = true;
}
rt->gcFoundBlackGrayEdges = false;
return true;
}
-void
+template <class CompartmentIter>
+static void
MarkWeakReferences(JSRuntime *rt, gcstats::Phase phase)
{
GCMarker *gcmarker = &rt->gcMarker;
JS_ASSERT(gcmarker->isDrained());
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_MARK);
gcstats::AutoPhase ap1(rt->gcStats, phase);
for (;;) {
bool markedAny = false;
- for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
+ for (CompartmentIter c(rt); !c.done(); c.next()) {
markedAny |= WatchpointMap::markCompartmentIteratively(c, gcmarker);
markedAny |= WeakMapBase::markCompartmentIteratively(c, gcmarker);
}
markedAny |= Debugger::markAllIteratively(gcmarker);
if (!markedAny)
break;
SliceBudget budget;
gcmarker->drainMarkStack(budget);
}
JS_ASSERT(gcmarker->isDrained());
}
static void
+MarkWeakReferencesInCurrentGroup(JSRuntime *rt, gcstats::Phase phase)
+{
+ MarkWeakReferences<GCCompartmentGroupIter>(rt, phase);
+}
+
+#ifdef DEBUG
+static void
+MarkAllWeakReferences(JSRuntime *rt, gcstats::Phase phase)
+{
+ MarkWeakReferences<GCCompartmentsIter>(rt, phase);
+}
+#endif
+
+static void
MarkGrayReferences(JSRuntime *rt)
{
GCMarker *gcmarker = &rt->gcMarker;
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_MARK);
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_SWEEP_MARK_GRAY);
gcmarker->setMarkColorGray();
@@ -2738,135 +2753,235 @@ MarkGrayReferences(JSRuntime *rt)
} else {
if (JSTraceDataOp op = rt->gcGrayRootsTraceOp)
(*op)(gcmarker, rt->gcGrayRootsData);
}
SliceBudget budget;
gcmarker->drainMarkStack(budget);
}
- MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
+ MarkWeakReferencesInCurrentGroup(rt, gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
JS_ASSERT(gcmarker->isDrained());
gcmarker->setMarkColorBlack();
}
-#if 0
#ifdef DEBUG
-static void
-ValidateIncrementalMarking(JSRuntime *rt)
+
+class js::gc::MarkingValidator
{
- typedef HashMap<Chunk *, uintptr_t *, GCChunkHasher, SystemAllocPolicy> BitmapMap;
+ public:
+ MarkingValidator(JSRuntime *rt);
+ ~MarkingValidator();
+ void nonIncrementalMark();
+ void validate();
+
+ private:
+ JSRuntime *runtime;
+ bool initialized;
+
+ typedef HashMap<Chunk *, ChunkBitmap *, GCChunkHasher, SystemAllocPolicy> BitmapMap;
BitmapMap map;
+};
+
+js::gc::MarkingValidator::MarkingValidator(JSRuntime *rt)
+ : runtime(rt),
+ initialized(false)
+{}
+
+js::gc::MarkingValidator::~MarkingValidator()
+{
+ if (!map.initialized())
+ return;
+
+ for (BitmapMap::Range r(map.all()); !r.empty(); r.popFront())
+ js_delete(r.front().value);
+}
+
+void
+js::gc::MarkingValidator::nonIncrementalMark()
+{
+ /*
+ * Perform a non-incremental mark for all collecting compartments and record
+ * the results for later comparison.
+ *
+ * Currently this does not validate gray marking.
+ */
+
if (!map.init())
return;
- GCMarker *gcmarker = &rt->gcMarker;
+ GCMarker *gcmarker = &runtime->gcMarker;
/* Save existing mark bits. */
- for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
+ for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
ChunkBitmap *bitmap = &r.front()->bitmap;
- uintptr_t *entry = (uintptr_t *)js_malloc(sizeof(bitmap->bitmap));
+ ChunkBitmap *entry = js_new<ChunkBitmap>();
if (!entry)
return;
- memcpy(entry, bitmap->bitmap, sizeof(bitmap->bitmap));
+ memcpy(entry->bitmap, bitmap->bitmap, sizeof(bitmap->bitmap));
if (!map.putNew(r.front(), entry))
return;
}
- /* Save and reset the lists of live weakmaps for the compartments we are collecting. */
+ /*
+ * Save the lists of live weakmaps and array buffers for the compartments we
+ * are collecting.
+ */
WeakMapVector weakmaps;
- for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
- if (!WeakMapBase::saveCompartmentWeakMapList(c, weakmaps))
+ ArrayBufferVector arrayBuffers;
+ for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
+ if (!WeakMapBase::saveCompartmentWeakMapList(c, weakmaps) ||
+ !ArrayBufferObject::saveArrayBufferList(c, arrayBuffers))
+ {
return;
+ }
}
- for (GCCompartmentsIter c(rt); !c.done(); c.next())
- WeakMapBase::resetCompartmentWeakMapList(c);
/*
* After this point, the function should run to completion, so we shouldn't
* do anything fallible.
*/
+ initialized = true;
+
+ /*
+ * Reset the lists of live weakmaps and array buffers for the compartments we
+ * are collecting.
+ */
+ for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
+ WeakMapBase::resetCompartmentWeakMapList(c);
+ ArrayBufferObject::resetArrayBufferList(c);
+ }
/* Re-do all the marking, but non-incrementally. */
- js::gc::State state = rt->gcIncrementalState;
- rt->gcIncrementalState = MARK_ROOTS;
+ js::gc::State state = runtime->gcIncrementalState;
+ runtime->gcIncrementalState = MARK_ROOTS;
JS_ASSERT(gcmarker->isDrained());
gcmarker->reset();
- for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront())
+ for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront())
r.front()->bitmap.clear();
- MarkRuntime(gcmarker, true);
+ {
+ gcstats::AutoPhase ap1(runtime->gcStats, gcstats::PHASE_MARK);
+ gcstats::AutoPhase ap2(runtime->gcStats, gcstats::PHASE_MARK_ROOTS);
+ MarkRuntime(gcmarker, true);
+ }
SliceBudget budget;
- rt->gcIncrementalState = MARK;
- rt->gcMarker.drainMarkStack(budget);
- MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_WEAK);
- MarkGrayReferences(rt);
-
- /* Now verify that we have the same mark bits as before. */
- for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
+ runtime->gcIncrementalState = MARK;
+ runtime->gcMarker.drainMarkStack(budget);
+
+ {
+ gcstats::AutoPhase ap(runtime->gcStats, gcstats::PHASE_SWEEP);
+ MarkAllWeakReferences(runtime, gcstats::PHASE_SWEEP_MARK_WEAK);
+ }
+
+ /* Take a copy of the non-incremental mark state and restore the original. */
+ for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
Chunk *chunk = r.front();
ChunkBitmap *bitmap = &chunk->bitmap;
- uintptr_t *entry = map.lookup(r.front())->value;
- ChunkBitmap incBitmap;
-
- memcpy(incBitmap.bitmap, entry, sizeof(incBitmap.bitmap));
- js_free(entry);
+ ChunkBitmap *entry = map.lookup(chunk)->value;
+ js::Swap(*entry, *bitmap);
+ }
+
+ /* Restore the weak map and array buffer lists. */
+ for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
+ WeakMapBase::resetCompartmentWeakMapList(c);
+ ArrayBufferObject::resetArrayBufferList(c);
+ }
+ WeakMapBase::restoreCompartmentWeakMapLists(weakmaps);
+ ArrayBufferObject::restoreArrayBufferLists(arrayBuffers);
+
+ runtime->gcIncrementalState = state;
+}
+
+void
+js::gc::MarkingValidator::validate()
+{
+ /*
+ * Validates the incremental marking for a single compartment by comparing
+ * the mark bits to those previously recorded for a non-incremental mark.
+ */
+
+ if (!initialized)
+ return;
+
+ for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
+ Chunk *chunk = r.front();
+ BitmapMap::Ptr ptr = map.lookup(chunk);
+ if (!ptr)
+ continue; /* Allocated after we did the non-incremental mark. */
+
+ ChunkBitmap *bitmap = ptr->value;
+ ChunkBitmap *incBitmap = &chunk->bitmap;
for (size_t i = 0; i < ArenasPerChunk; i++) {
if (chunk->decommittedArenas.get(i))
continue;
Arena *arena = &chunk->arenas[i];
if (!arena->aheader.allocated())
continue;
- if (!arena->aheader.compartment->isCollecting())
+ if (!arena->aheader.compartment->isGCSweeping())
continue;
if (arena->aheader.allocatedDuringIncremental)
continue;
AllocKind kind = arena->aheader.getAllocKind();
uintptr_t thing = arena->thingsStart(kind);
uintptr_t end = arena->thingsEnd();
while (thing < end) {
Cell *cell = (Cell *)thing;
/*
* If a non-incremental GC wouldn't have collected a cell, then
* an incremental GC won't collect it.
*/
- JS_ASSERT_IF(bitmap->isMarked(cell, BLACK), incBitmap.isMarked(cell, BLACK));
-
- /*
- * If the cycle collector isn't allowed to collect an object
- * after a non-incremental GC has run, then it isn't allowed to
- * collected it after an incremental GC.
- */
- JS_ASSERT_IF(!bitmap->isMarked(cell, GRAY), !incBitmap.isMarked(cell, GRAY));
+ JS_ASSERT_IF(bitmap->isMarked(cell, BLACK), incBitmap->isMarked(cell, BLACK));
thing += Arena::thingSize(kind);
}
}
-
- memcpy(bitmap->bitmap, incBitmap.bitmap, sizeof(incBitmap.bitmap));
}
-
- /* Restore the weak map lists. */
- for (GCCompartmentsIter c(rt); !c.done(); c.next())
- WeakMapBase::resetCompartmentWeakMapList(c);
- WeakMapBase::restoreCompartmentWeakMapLists(weakmaps);
-
- rt->gcIncrementalState = state;
+}
+
+#endif
+
+static void
+ComputeNonIncrementalMarkingForValidation(JSRuntime *rt)
+{
+#ifdef DEBUG
+ JS_ASSERT(!rt->gcMarkingValidator);
+ if (rt->gcIsIncremental && rt->gcValidate)
+ rt->gcMarkingValidator = js_new<MarkingValidator>(rt);
+ if (rt->gcMarkingValidator)
+ rt->gcMarkingValidator->nonIncrementalMark();
+#endif
}
+
+static void
+ValidateIncrementalMarking(JSRuntime *rt)
+{
+#ifdef DEBUG
+ if (rt->gcMarkingValidator)
+ rt->gcMarkingValidator->validate();
#endif
+}
+
+static void
+FinishMarkingValidation(JSRuntime *rt)
+{
+#ifdef DEBUG
+ js_delete(rt->gcMarkingValidator);
+ rt->gcMarkingValidator = NULL;
#endif
+}
static void
DropStringWrappers(JSRuntime *rt)
{
/*
* String "wrappers" are dropped on GC because their presence would require
* us to sweep the wrappers in all compartments every time we sweep a
* compartment group.
@@ -3201,17 +3316,17 @@ EndMarkingCompartmentGroup(JSRuntime *rt
{
/*
* Mark any incoming black pointers from previously swept compartments
* whose referents are not marked. This can occur when gray cells become
* black by the action of UnmarkGray.
*/
MarkIncomingCrossCompartmentPointers(rt, BLACK);
- MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_WEAK);
+ MarkWeakReferencesInCurrentGroup(rt, gcstats::PHASE_SWEEP_MARK_WEAK);
/*
* Change state of current group to MarkGray to restrict marking to this
* group. Note that there may be pointers to the atoms compartment, and
* these will be marked through, as they are not marked with
* MarkCrossCompartmentXXX.
*/
for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
@@ -3252,16 +3367,18 @@ BeginSweepingCompartmentGroup(JSRuntime
/* Purge the ArenaLists before sweeping. */
c->arenas.purge();
if (c == rt->atomsCompartment)
sweepingAtoms = true;
}
+ ValidateIncrementalMarking(rt);
+
FreeOp fop(rt, rt->gcSweepOnBackgroundThread);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_FINALIZE_START);
if (rt->gcFinalizeCallback)
rt->gcFinalizeCallback(&fop, JSFINALIZE_GROUP_START, !rt->gcIsFull /* unused */);
}
@@ -3353,16 +3470,19 @@ BeginSweepPhase(JSRuntime *rt)
{
/*
* Sweep phase.
*
* Finalize as we sweep, outside of rt->gcLock but with rt->isHeapBusy()
* true so that any attempt to allocate a GC-thing from a finalizer will
* fail, rather than nest badly and leave the unmarked newborn to be swept.
*/
+
+ ComputeNonIncrementalMarkingForValidation(rt);
+
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
#ifdef JS_THREADSAFE
rt->gcSweepOnBackgroundThread = rt->hasContexts() && rt->useHelperThreads();
#endif
#ifdef DEBUG
for (CompartmentsIter c(rt); !c.done(); c.next()) {
@@ -3562,16 +3682,18 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocat
for (unsigned i = 0 ; i < FINALIZE_LIMIT ; ++i) {
JS_ASSERT_IF(!IsBackgroundFinalized(AllocKind(i)) ||
!rt->gcSweepOnBackgroundThread,
!c->arenas.arenaListsToSweep[i]);
}
#endif
}
+ FinishMarkingValidation(rt);
+
rt->gcLastGCTime = PRMJ_Now();
}
/* ...while this class is to be used only for garbage collection. */
class AutoGCSession : AutoTraceSession {
public:
explicit AutoGCSession(JSRuntime *rt);
~AutoGCSession();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1224,16 +1224,23 @@ js::Interpret(JSContext *cx, StackFrame
}
}
/* The REJOIN mode acts like the normal mode, except the prologue is skipped. */
if (interpMode == JSINTERP_REJOIN)
interpMode = JSINTERP_NORMAL;
/*
+ * The RETHROW mode acts like a bailout mode, except that it resume an
+ * exception instead of resuming the script.
+ */
+ if (interpMode == JSINTERP_RETHROW)
+ goto error;
+
+ /*
* It is important that "op" be initialized before calling DO_OP because
* it is possible for "op" to be specially assigned during the normal
* processing of an opcode while looping. We rely on DO_NEXT_OP to manage
* "op" correctly in all other cases.
*/
JSOp op;
int32_t len;
len = 0;
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -167,17 +167,18 @@ extern bool
Execute(JSContext *cx, HandleScript script, JSObject &scopeChain, Value *rval);
/* Flags to toggle js::Interpret() execution. */
enum InterpMode
{
JSINTERP_NORMAL = 0, /* interpreter is running normally */
JSINTERP_REJOIN = 1, /* as normal, but the frame has already started */
JSINTERP_SKIP_TRAP = 2, /* as REJOIN, but skip trap at first opcode */
- JSINTERP_BAILOUT = 3 /* interpreter is running from an Ion bailout */
+ JSINTERP_BAILOUT = 3, /* interpreter is running from an Ion bailout */
+ JSINTERP_RETHROW = 4 /* as BAILOUT, but unwind all frames */
};
enum InterpretStatus
{
Interpret_Error = 0, /* interpreter had an error */
Interpret_Ok = 1, /* interpreter executed successfully */
Interpret_OSR = 2 /* when mode=BAILOUT and we should OSR into Ion */
};
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -785,21 +785,21 @@ GetObjectElementOperation(JSContext *cx,
static JS_ALWAYS_INLINE bool
GetElementOperation(JSContext *cx, JSOp op, HandleValue lref, HandleValue rref,
MutableHandleValue res)
{
AssertCanGC();
JS_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM);
- if (lref.isString() && rref.isInt32()) {
+ uint32_t index;
+ if (lref.isString() && IsDefinitelyIndex(rref, &index)) {
JSString *str = lref.toString();
- int32_t i = rref.toInt32();
- if (size_t(i) < str->length()) {
- str = cx->runtime->staticStrings.getUnitStringForElement(cx, str, size_t(i));
+ if (index < str->length()) {
+ str = cx->runtime->staticStrings.getUnitStringForElement(cx, str, index);
if (!str)
return false;
res.setString(str);
return true;
}
}
StackFrame *fp = cx->fp();
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -374,16 +374,18 @@ struct JSScript : public js::gc::Cell
/* Persistent type information retained across GCs. */
js::types::TypeScript *types;
private:
js::ScriptSource *scriptSource_; /* source code */
#ifdef JS_METHODJIT
JITScriptSet *mJITInfo;
+#else
+ void *mJITInfoPad;
#endif
js::HeapPtrFunction function_;
js::HeapPtrObject enclosingScope_;
// 32-bit fields.
public:
uint32_t length; /* length of code vector */
@@ -474,19 +476,24 @@ struct JSScript : public js::gc::Cell
script */
bool hasSingletons:1; /* script has singleton objects */
bool isActiveEval:1; /* script came from eval(), and is still active */
bool isCachedEval:1; /* script came from eval(), and is in eval cache */
bool uninlineable:1; /* script is considered uninlineable by analysis */
#ifdef JS_METHODJIT
bool debugMode:1; /* script was compiled in debug mode */
bool failedBoundsCheck:1; /* script has had hoisted bounds checks fail */
+#else
+ bool debugModePad:1;
+ bool failedBoundsCheckPad:1;
#endif
#ifdef JS_ION
bool failedShapeGuard:1; /* script has had hoisted shape guard fail */
+#else
+ bool failedShapeGuardPad:1;
#endif
bool invalidatedIdempotentCache:1; /* idempotent cache has triggered invalidation */
bool isGenerator:1; /* is a generator */
bool isGeneratorExp:1; /* is a generator expression */
bool hasScriptCounts:1;/* script has an entry in
JSCompartment::scriptCountsMap */
bool hasDebugScript:1; /* script has an entry in
JSCompartment::debugScriptMap */
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -589,34 +589,66 @@ ArrayBufferObject::sweep(JSCompartment *
}
*views = prevLiveView;
buffer = nextBuffer;
}
}
void
-ArrayBufferObject::resetArrayBufferList(JSCompartment *compartment)
+ArrayBufferObject::resetArrayBufferList(JSCompartment *comp)
{
- JSObject *buffer = compartment->gcLiveArrayBuffers;
+ JSObject *buffer = comp->gcLiveArrayBuffers;
JS_ASSERT(buffer != UNSET_BUFFER_LINK);
- compartment->gcLiveArrayBuffers = NULL;
+ comp->gcLiveArrayBuffers = NULL;
while (buffer) {
JSObject *view = *GetViewList(&buffer->asArrayBuffer());
JS_ASSERT(view);
JSObject *nextBuffer = BufferLink(view);
JS_ASSERT(nextBuffer != UNSET_BUFFER_LINK);
SetBufferLink(view, UNSET_BUFFER_LINK);
buffer = nextBuffer;
}
}
+/* static */ bool
+ArrayBufferObject::saveArrayBufferList(JSCompartment *comp, ArrayBufferVector &vector)
+{
+ JSObject *obj = comp->gcLiveArrayBuffers;
+ while (obj) {
+ JS_ASSERT(obj != UNSET_BUFFER_LINK);
+ ArrayBufferObject *buffer = &obj->asArrayBuffer();
+ if (!vector.append(buffer))
+ return false;
+
+ JSObject *view = *GetViewList(buffer);
+ JS_ASSERT(view);
+ obj = BufferLink(view);
+ }
+ return true;
+}
+
+/* static */ void
+ArrayBufferObject::restoreArrayBufferLists(ArrayBufferVector &vector)
+{
+ for (ArrayBufferObject **p = vector.begin(); p != vector.end(); p++) {
+ ArrayBufferObject *buffer = *p;
+ JSCompartment *comp = buffer->compartment();
+ JSObject *firstView = *GetViewList(&buffer->asArrayBuffer());
+ JS_ASSERT(firstView);
+ JS_ASSERT(firstView->compartment() == comp);
+ JS_ASSERT(BufferLink(firstView) == UNSET_BUFFER_LINK);
+ SetBufferLink(firstView, comp->gcLiveArrayBuffers);
+ comp->gcLiveArrayBuffers = buffer;
+ }
+}
+
JSBool
ArrayBufferObject::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
MutableHandleObject objp, MutableHandleShape propp)
{
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
--- a/js/src/jstypedarray.h
+++ b/js/src/jstypedarray.h
@@ -12,16 +12,18 @@
#include "jsobj.h"
#include "gc/Barrier.h"
typedef struct JSProperty JSProperty;
namespace js {
+typedef Vector<ArrayBufferObject *, 0, SystemAllocPolicy> ArrayBufferVector;
+
/*
* ArrayBufferObject
*
* This class holds the underlying raw buffer that the various ArrayBufferView
* subclasses (DataView and the TypedArrays) access. It can be created
* explicitly and passed to an ArrayBufferView subclass, or can be created
* implicitly by constructing a TypedArray with a size.
*/
@@ -128,16 +130,18 @@ class ArrayBufferObject : public JSObjec
JSBool strict);
static JSBool obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
MutableHandleValue statep, MutableHandleId idp);
static void sweep(JSCompartment *rt);
static void resetArrayBufferList(JSCompartment *rt);
+ static bool saveArrayBufferList(JSCompartment *c, ArrayBufferVector &vector);
+ static void restoreArrayBufferLists(ArrayBufferVector &vector);
static bool stealContents(JSContext *cx, JSObject *obj, void **contents,
uint8_t **data);
static inline void setElementsHeader(js::ObjectElements *header, uint32_t bytes);
void addView(RawObject view);
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2778,20 +2778,21 @@ ChooseScaleAndSetTransform(FrameLayerBui
gfxMatrix frameTransform;
if (aContainerFrame->AreLayersMarkedActive(nsChangeHint_UpdateTransformLayer) &&
aTransform &&
(!aTransform->Is2D(&frameTransform) || frameTransform.HasNonTranslationOrFlip())) {
// Don't clamp the scale factor when the new desired scale factor matches the old one
// or it was previously unscaled.
bool clamp = true;
gfxMatrix oldFrameTransform2d;
- if (aLayer->GetTransform().Is2D(&oldFrameTransform2d)) {
+ if (aLayer->GetBaseTransform().Is2D(&oldFrameTransform2d)) {
gfxSize oldScale = oldFrameTransform2d.ScaleFactors(true);
- if (oldScale == scale || oldScale == gfxSize(1.0, 1.0))
+ if (oldScale == scale || oldScale == gfxSize(1.0, 1.0)) {
clamp = false;
+ }
}
if (clamp) {
scale.width = gfxUtils::ClampToScaleFactor(scale.width);
scale.height = gfxUtils::ClampToScaleFactor(scale.height);
}
} else {
// XXX Do we need to move nearly-integer values to integers here?
}
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3917,25 +3917,29 @@ already_AddRefed<Layer> nsDisplayTransfo
nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetChildren(),
aContainerParameters, &newTransformMatrix);
// Add the preserve-3d flag for this layer, BuildContainerLayerFor clears all flags,
// so we never need to explicitely unset this flag.
if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
+ } else {
+ container->SetContentFlags(container->GetContentFlags() & ~Layer::CONTENT_PRESERVE_3D);
}
AddAnimationsAndTransitionsToLayer(container, aBuilder,
this, eCSSProperty_transform);
if (ShouldPrerenderTransformedContent(aBuilder, mFrame, false)) {
container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(),
/*the value is irrelevant*/nullptr);
+ container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM);
} else {
container->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey());
+ container->SetContentFlags(container->GetContentFlags() & ~Layer::CONTENT_MAY_CHANGE_TRANSFORM);
}
return container.forget();
}
nsDisplayItem::LayerState
nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aParameters) {
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -307,17 +307,17 @@ NS_QUERYFRAME_HEAD(nsComboboxControlFram
NS_QUERYFRAME_ENTRY(nsISelectControlFrame)
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsComboboxControlFrame::AccessibleType()
{
- return a11y::eHTMLComboboxAccessible;
+ return a11y::eHTMLCombobox;
}
#endif
void
nsComboboxControlFrame::SetFocus(bool aOn, bool aRepaint)
{
nsWeakFrame weakFrame(this);
if (aOn) {
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -620,17 +620,17 @@ nsFieldSetFrame::RemoveFrame(ChildListID
NS_ASSERTION(aOldFrame != mLegendFrame, "Cannot remove mLegendFrame here");
return mContentFrame->RemoveFrame(aListID, aOldFrame);
}
#ifdef ACCESSIBILITY
a11y::AccType
nsFieldSetFrame::AccessibleType()
{
- return a11y::eHTMLGroupboxAccessible;
+ return a11y::eHTMLGroupbox;
}
#endif
void
nsFieldSetFrame::ReparentFrameList(const nsFrameList& aFrameList)
{
nsFrameManager* frameManager = PresContext()->FrameManager();
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -626,17 +626,17 @@ nsFileControlFrame::BuildDisplayList(nsD
return DisplaySelectionOverlay(aBuilder, aLists.Content());
}
#ifdef ACCESSIBILITY
a11y::AccType
nsFileControlFrame::AccessibleType()
{
- return a11y::eHTMLFileInputAccessible;
+ return a11y::eHTMLFileInput;
}
#endif
uint32_t
nsFileControlFrame::GetCaptureMode(const CaptureCallbackData& aData)
{
int32_t filters = nsHTMLInputElement::FromContent(mContent)->GetFilterFromAccept();
nsresult rv;
--- a/layout/forms/nsGfxCheckboxControlFrame.cpp
+++ b/layout/forms/nsGfxCheckboxControlFrame.cpp
@@ -85,17 +85,17 @@ nsGfxCheckboxControlFrame::nsGfxCheckbox
nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame()
{
}
#ifdef ACCESSIBILITY
a11y::AccType
nsGfxCheckboxControlFrame::AccessibleType()
{
- return a11y::eHTMLCheckboxAccessible;
+ return a11y::eHTMLCheckbox;
}
#endif
//------------------------------------------------------------
NS_IMETHODIMP
nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
--- a/layout/forms/nsGfxRadioControlFrame.cpp
+++ b/layout/forms/nsGfxRadioControlFrame.cpp
@@ -31,17 +31,17 @@ nsGfxRadioControlFrame::nsGfxRadioContro
nsGfxRadioControlFrame::~nsGfxRadioControlFrame()
{
}
#ifdef ACCESSIBILITY
a11y::AccType
nsGfxRadioControlFrame::AccessibleType()
{
- return a11y::eHTMLRadioButtonAccessible;
+ return a11y::eHTMLRadioButton;
}
#endif
//--------------------------------------------------------------
// Draw the dot for a non-native radio button in the checked state.
static void
PaintCheckedRadioButton(nsIFrame* aFrame,
nsRenderingContext* aCtx,
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -73,17 +73,17 @@ nsHTMLButtonControlFrame::Init(
NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame)
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsHTMLButtonControlFrame::AccessibleType()
{
- return a11y::eHTMLButtonAccessible;
+ return a11y::eHTMLButton;
}
#endif
nsIAtom*
nsHTMLButtonControlFrame::GetType() const
{
return nsGkAtoms::HTMLButtonControlFrame;
}
--- a/layout/forms/nsImageControlFrame.cpp
+++ b/layout/forms/nsImageControlFrame.cpp
@@ -128,20 +128,20 @@ NS_QUERYFRAME_HEAD(nsImageControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsImageControlFrameSuper)
#ifdef ACCESSIBILITY
a11y::AccType
nsImageControlFrame::AccessibleType()
{
if (mContent->Tag() == nsGkAtoms::button ||
mContent->Tag() == nsGkAtoms::input) {
- return a11y::eHTMLButtonAccessible;
+ return a11y::eHTMLButton;
}
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
#endif
nsIAtom*
nsImageControlFrame::GetType() const
{
return nsGkAtoms::imageControlFrame;
}
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -262,17 +262,17 @@ NS_QUERYFRAME_HEAD(nsListControlFrame)
NS_QUERYFRAME_ENTRY(nsIListControlFrame)
NS_QUERYFRAME_ENTRY(nsISelectControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsHTMLScrollFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsListControlFrame::AccessibleType()
{
- return a11y::eHTMLSelectListAccessible;
+ return a11y::eHTMLSelectList;
}
#endif
static nscoord
GetMaxOptionHeight(nsIFrame* aContainer)
{
nscoord result = 0;
for (nsIFrame* option = aContainer->GetFirstPrincipalChild();
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -90,17 +90,17 @@ NS_QUERYFRAME_HEAD(nsTextControlFrame)
NS_QUERYFRAME_ENTRY(nsITextControlFrame)
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsTextControlFrame::AccessibleType()
{
- return a11y::eHTMLTextFieldAccessible;
+ return a11y::eHTMLTextField;
}
#endif
#ifdef DEBUG
class EditorInitializerEntryTracker {
public:
explicit EditorInitializerEntryTracker(nsTextControlFrame &frame)
: mFrame(frame)
--- a/layout/generic/nsBRFrame.cpp
+++ b/layout/generic/nsBRFrame.cpp
@@ -249,15 +249,15 @@ BRFrame::PeekOffsetWord(bool aForward, b
a11y::AccType
BRFrame::AccessibleType()
{
nsIContent *parent = mContent->GetParent();
if (parent && parent->IsRootOfNativeAnonymousSubtree() &&
parent->GetChildCount() == 1) {
// This <br> is the only node in a text control, therefore it is the hacky
// "bogus node" used when there is no text in the control
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
- return a11y::eHTMLBRAccessible;
+ return a11y::eHTMLBR;
}
#endif
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6245,44 +6245,44 @@ nsBlockFrame::BuildDisplayList(nsDisplay
}
#ifdef ACCESSIBILITY
a11y::AccType
nsBlockFrame::AccessibleType()
{
// block frame may be for <hr>
if (mContent->Tag() == nsGkAtoms::hr) {
- return a11y::eHTMLHRAccessible;
+ return a11y::eHTMLHR;
}
if (!HasBullet() || !PresContext()) {
if (!mContent->GetParent()) {
// Don't create accessible objects for the root content node, they are redundant with
// the nsDocAccessible object created with the document node
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc =
do_QueryInterface(mContent->GetDocument());
if (htmlDoc) {
nsCOMPtr<nsIDOMHTMLElement> body;
htmlDoc->GetBody(getter_AddRefs(body));
if (SameCOMIdentity(body, mContent)) {
// Don't create accessible objects for the body, they are redundant with
// the nsDocAccessible object created with the document node
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
}
// Not a bullet, treat as normal HTML container
- return a11y::eHyperTextAccessible;
+ return a11y::eHyperText;
}
// Create special list bullet accessible
- return a11y::eHTMLLiAccessible;
+ return a11y::eHTMLLi;
}
#endif
void nsBlockFrame::ClearLineCursor()
{
if (!(GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR)) {
return;
}
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3027,16 +3027,24 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPres
nsRefPtr<nsFrameSelection> frameselection = GetFrameSelection();
bool mouseDown = frameselection->GetMouseDownState();
if (!mouseDown)
return NS_OK;
frameselection->StopAutoScrollTimer();
+#ifdef MOZ_B2G
+ // We only check touch move event since mouse move event is not cancelable.
+ if (aEvent->message == NS_TOUCH_MOVE &&
+ nsEventStatus_eConsumeNoDefault == *aEventStatus) {
+ return NS_OK;
+ }
+#endif // MOZ_B2G
+
// Check if we are dragging in a table cell
nsCOMPtr<nsIContent> parentContent;
int32_t contentOffset;
int32_t target;
nsMouseEvent *me = (nsMouseEvent *)aEvent;
nsresult result;
result = GetDataForTableSelection(frameselection, presShell, me,
getter_AddRefs(parentContent),
@@ -6770,17 +6778,17 @@ nsFrame::ChildIsDirty(nsIFrame* aChild)
"nsContainerFrame");
}
#ifdef ACCESSIBILITY
a11y::AccType
nsFrame::AccessibleType()
{
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
#endif
NS_DECLARE_FRAME_PROPERTY(OverflowAreasProperty,
nsIFrame::DestroyOverflowAreas)
bool
nsIFrame::ClearOverflowRects()
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -856,20 +856,20 @@ nsHTMLScrollFrame::GetFrameName(nsAStrin
a11y::AccType
nsHTMLScrollFrame::AccessibleType()
{
// Create an accessible regardless of focusable state because the state can be
// changed during frame life cycle without any notifications to accessibility.
if (mContent->IsRootOfNativeAnonymousSubtree() ||
GetScrollbarStyles() == nsIScrollableFrame::
ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN) ) {
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
- return a11y::eHyperTextAccessible;
+ return a11y::eHyperText;
}
#endif
NS_QUERYFRAME_HEAD(nsHTMLScrollFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_ENTRY(nsIScrollableFrame)
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -331,17 +331,17 @@ nsHTMLCanvasFrame::GetContinuationOffset
}
return offset;
}
#ifdef ACCESSIBILITY
a11y::AccType
nsHTMLCanvasFrame::AccessibleType()
{
- return a11y::eHTMLCanvasAccessible;
+ return a11y::eHTMLCanvas;
}
#endif
#ifdef DEBUG
NS_IMETHODIMP
nsHTMLCanvasFrame::GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("HTMLCanvas"), aResult);
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -158,20 +158,20 @@ NS_QUERYFRAME_HEAD(nsImageFrame)
NS_QUERYFRAME_TAIL_INHERITING(ImageFrameSuper)
#ifdef ACCESSIBILITY
a11y::AccType
nsImageFrame::AccessibleType()
{
// Don't use GetImageMap() to avoid reentrancy into accessibility.
if (HasImageMap()) {
- return a11y::eHTMLImageMapAccessible;
+ return a11y::eHTMLImageMap;
}
- return a11y::eImageAccessible;
+ return a11y::eImage;
}
#endif
void
nsImageFrame::DisconnectMap()
{
if (mImageMap) {
mImageMap->Destroy();
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -890,23 +890,23 @@ nsInlineFrame::GetBaseline() const
#ifdef ACCESSIBILITY
a11y::AccType
nsInlineFrame::AccessibleType()
{
// Broken image accessibles are created here, because layout
// replaces the image or image control frame with an inline frame
nsIAtom *tagAtom = mContent->Tag();
if (tagAtom == nsGkAtoms::input) // Broken <input type=image ... />
- return a11y::eHTMLButtonAccessible;
+ return a11y::eHTMLButton;
if (tagAtom == nsGkAtoms::img) // Create accessible for broken <img>
- return a11y::eImageAccessible;
+ return a11y::eImage;
if (tagAtom == nsGkAtoms::label) // Creat accessible for <label>
- return a11y::eHTMLLabelAccessible;
+ return a11y::eHTMLLabel;
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
#endif
//////////////////////////////////////////////////////////////////////
// nsLineFrame implementation
nsIFrame*
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -270,17 +270,17 @@ NS_QUERYFRAME_HEAD(nsObjectFrame)
NS_QUERYFRAME_ENTRY(nsObjectFrame)
NS_QUERYFRAME_ENTRY(nsIObjectFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsObjectFrameSuper)
#ifdef ACCESSIBILITY
a11y::AccType
nsObjectFrame::AccessibleType()
{
- return a11y::eHTMLObjectFrameAccessible;
+ return a11y::ePlugin;
}
#ifdef XP_WIN
NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort)
{
*aPort = (HWND) mInstanceOwner->GetPluginPortFromWidget();
return NS_OK;
}
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -80,17 +80,17 @@ nsSubDocumentFrame::nsSubDocumentFrame(n
, mCallingShow(false)
{
}
#ifdef ACCESSIBILITY
a11y::AccType
nsSubDocumentFrame::AccessibleType()
{
- return a11y::eOuterDocAccessible;
+ return a11y::eOuterDoc;
}
#endif
NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
NS_QUERYFRAME_ENTRY(nsSubDocumentFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame)
class AsyncFrameInit : public nsRunnable
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -3893,21 +3893,21 @@ nsTextPaintStyle::GetResolvedForeColor(n
#ifdef ACCESSIBILITY
a11y::AccType
nsTextFrame::AccessibleType()
{
if (IsEmpty()) {
nsAutoString renderedWhitespace;
GetRenderedText(&renderedWhitespace, nullptr, nullptr, 0, 1);
if (renderedWhitespace.IsEmpty()) {
- return a11y::eNoAccessible;
- }
- }
-
- return a11y::eTextLeafAccessible;
+ return a11y::eNoType;
+ }
+ }
+
+ return a11y::eTextLeaf;
}
#endif
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsTextFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -413,17 +413,17 @@ nsVideoFrame::GetType() const
{
return nsGkAtoms::HTMLVideoFrame;
}
#ifdef ACCESSIBILITY
a11y::AccType
nsVideoFrame::AccessibleType()
{
- return a11y::eHTMLMediaAccessible;
+ return a11y::eHTMLMedia;
}
#endif
#ifdef DEBUG
NS_IMETHODIMP
nsVideoFrame::GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("HTMLVideo"), aResult);
--- a/layout/ipc/PRenderFrame.ipdl
+++ b/layout/ipc/PRenderFrame.ipdl
@@ -37,16 +37,17 @@ parent:
* |id| is set to 0 in the "direct" case, and to a whole number
* in the "indirect" case.
*/
async PLayers();
async NotifyCompositorTransaction();
async CancelDefaultPanZoom();
+ async DetectScrollableSubframe();
async __delete__();
state EMPTY_OR_DIRECT_COMPOSITOR:
recv PLayers goto HAVE_CONTENT;
recv NotifyCompositorTransaction goto EMPTY_OR_DIRECT_COMPOSITOR;
recv __delete__;
--- a/layout/ipc/RenderFrameChild.cpp
+++ b/layout/ipc/RenderFrameChild.cpp
@@ -33,16 +33,22 @@ RenderFrameChild::Destroy()
}
void
RenderFrameChild::CancelDefaultPanZoom()
{
SendCancelDefaultPanZoom();
}
+void
+RenderFrameChild::DetectScrollableSubframe()
+{
+ SendDetectScrollableSubframe();
+}
+
PLayersChild*
RenderFrameChild::AllocPLayers()
{
return new ShadowLayersChild();
}
bool
RenderFrameChild::DeallocPLayers(PLayersChild* aLayers)
--- a/layout/ipc/RenderFrameChild.h
+++ b/layout/ipc/RenderFrameChild.h
@@ -15,16 +15,17 @@ namespace layout {
class RenderFrameChild : public PRenderFrameChild
{
public:
RenderFrameChild() {}
virtual ~RenderFrameChild() {}
void CancelDefaultPanZoom();
+ void DetectScrollableSubframe();
void Destroy();
protected:
virtual PLayersChild* AllocPLayers() MOZ_OVERRIDE;
virtual bool DeallocPLayers(PLayersChild* aLayers) MOZ_OVERRIDE;
};
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -805,16 +805,25 @@ bool
RenderFrameParent::RecvCancelDefaultPanZoom()
{
if (mPanZoomController) {
mPanZoomController->CancelDefaultPanZoom();
}
return true;
}
+bool
+RenderFrameParent::RecvDetectScrollableSubframe()
+{
+ if (mPanZoomController) {
+ mPanZoomController->DetectScrollableSubframe();
+ }
+ return true;
+}
+
PLayersParent*
RenderFrameParent::AllocPLayers()
{
if (!mFrameLoader || mFrameLoaderDestroyed) {
return nullptr;
}
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
return new ShadowLayersParent(lm->AsShadowManager(), this, 0);
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -104,16 +104,17 @@ public:
void UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom);
protected:
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE;
virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
+ virtual bool RecvDetectScrollableSubframe() MOZ_OVERRIDE;
virtual PLayersParent* AllocPLayers() MOZ_OVERRIDE;
virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
private:
void BuildViewMap();
void TriggerRepaint();
void DispatchEventForPanZoomController(const InputEvent& aEvent);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text/820255-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Test - Bug 820255</title>
+ </head>
+ <body>
+ <div>A <br>B</div>
+ <div>A <br>B</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text/820255.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ div { width: 0px; }
+ </style>
+ <title>Test - Bug 820255</title>
+ </head>
+ <body>
+ <div>A B</div>
+ <div>A B</div>
+ </body>
+</html>
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -157,16 +157,17 @@ fails-if(cocoaWidget) HTTP(..) == arabic
fails-if(cocoaWidget) HTTP(..) == arabic-fallback-3.html arabic-fallback-3-ref.html
fails-if(!cocoaWidget) HTTP(..) != arabic-fallback-4.html arabic-fallback-4-notref.html
== 726392-1.html 726392-1-ref.html
== 726392-2.html 726392-2-ref.html
== 726392-3.html 726392-3-ref.html
== 745555-1.html 745555-1-ref.html
== 745555-2.html 745555-2-ref.html
+== 820255.html 820255-ref.html
# ensure emoji chars don't render blank (bug 715798, bug 779042);
# should at least render hexboxes if there's no font support
!= emoji-01.html emoji-01-notref.html
!= emoji-02.html emoji-02-notref.html
# tests to compare graphite to opentype (will trivially pass when graphite not enabled)
HTTP(..) == graphite-05-ot-only.html graphite-05-ref.html
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -980,17 +980,17 @@ NS_QUERYFRAME_HEAD(nsTableCellFrame)
NS_QUERYFRAME_ENTRY(nsITableCellLayout)
NS_QUERYFRAME_ENTRY(nsIPercentHeightObserver)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsTableCellFrame::AccessibleType()
{
- return a11y::eHTMLTableCellAccessible;
+ return a11y::eHTMLTableCell;
}
#endif
/* This is primarily for editor access via nsITableLayout */
NS_IMETHODIMP
nsTableCellFrame::GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex)
{
nsresult res = GetRowIndex(aRowIndex);
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -110,20 +110,20 @@ nsTableCaptionFrame::GetParentStyleConte
return nsBlockFrame::GetParentStyleContextFrame();
}
#ifdef ACCESSIBILITY
a11y::AccType
nsTableCaptionFrame::AccessibleType()
{
if (!GetRect().IsEmpty()) {
- return a11y::eHTMLCaptionAccessible;
+ return a11y::eHTMLCaption;
}
- return a11y::eNoAccessible;
+ return a11y::eNoType;
}
#endif
#ifdef DEBUG
NS_IMETHODIMP
nsTableCaptionFrame::GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("Caption"), aResult);
@@ -152,17 +152,17 @@ nsTableOuterFrame::~nsTableOuterFrame()
NS_QUERYFRAME_HEAD(nsTableOuterFrame)
NS_QUERYFRAME_ENTRY(nsITableLayout)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
#ifdef ACCESSIBILITY
a11y::AccType
nsTableOuterFrame::AccessibleType()
{
- return a11y::eHTMLTableAccessible;
+ return a11y::eHTMLTable;
}
#endif
void
nsTableOuterFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
DestroyAbsoluteFrames(aDestructRoot);
mCaptionFrames.DestroyFramesFrom(aDestructRoot);
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1352,17 +1352,17 @@ void nsTableRowFrame::SetContinuousBCBor
default:
NS_ERROR("invalid NS_SIDE arg");
}
}
#ifdef ACCESSIBILITY
a11y::AccType
nsTableRowFrame::AccessibleType()
{
- return a11y::eHTMLTableRowAccessible;
+ return a11y::eHTMLTableRow;
}
#endif
/**
* Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
* this row has any cells that have non-auto-height. (Row-spanning
* cells are ignored.)
*/
void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -556,18 +556,18 @@ StackTrace::Print(const Writer& aWriter)
return;
}
for (uint32_t i = 0; i < mLength; i++) {
nsCodeAddressDetails details;
void* pc = mPcs[i];
PcInfo(pc, &details);
if (details.function[0]) {
- W(" %14p %s[%s +0x%X]\n", pc, details.function, details.library,
- details.loffset);
+ W(" %s[%s +0x%X] %p\n", details.function, details.library,
+ details.loffset, pc);
}
}
}
/* static */ const StackTrace*
StackTrace::Get(Thread* aT)
{
MOZ_ASSERT(gStateLock->IsLocked());
@@ -1259,18 +1259,18 @@ FrameGroup::Print(const Writer& aWriter,
Show(mCombinedSize.mSlop, gBuf3, kBufLen, showTilde));
W(" %4.2f%% of the heap; %4.2f%% of %s\n",
Percent(mCombinedSize.Usable(), aTotalUsableSize),
Percent(mCombinedSize.Usable(), aCategoryUsableSize),
astr);
W(" PC is\n");
- W(" %14p %s[%s +0x%X]\n\n", mPc, details.function, details.library,
- details.loffset);
+ W(" %s[%s +0x%X] %p\n\n", details.function, details.library,
+ details.loffset, mPc);
}
//---------------------------------------------------------------------------
// DMD start-up
//---------------------------------------------------------------------------
static void RunTestMode(FILE* fp);
static void RunStressMode();
@@ -1443,20 +1443,20 @@ Init(const malloc_table_t* aMallocTable)
StatusMsg("can't create test file %s: %s\n", filename, strerror(errno));
exit(1);
}
}
DMD_CREATE_TLS_INDEX(gTlsIndex);
gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
- gStackTraceTable->init(65536);
+ gStackTraceTable->init(8192);
gLiveBlockTable = InfallibleAllocPolicy::new_<BlockTable>();
- gLiveBlockTable->init(65536);
+ gLiveBlockTable->init(8192);
gDoubleReportBlockGroupTable = InfallibleAllocPolicy::new_<BlockGroupTable>();
gDoubleReportBlockGroupTable->init(0);
// Set this as late as possible, so that allocations during initialization
// aren't intercepted. Once this is set, we are intercepting malloc et al.
// in earnest.
gIsDMDRunning = true;
@@ -1662,45 +1662,38 @@ PrintSortedBlockAndFrameGroups(const Wri
// This is only needed because of the |const void*| vs |void*| arg mismatch.
static size_t
MallocSizeOf(const void* aPtr)
{
return gMallocTable->malloc_usable_size(const_cast<void*>(aPtr));
}
-static void
-ShowExecutionMeasurements(const Writer& aWriter)
+// Note that, unlike most SizeOf* functions, this function does not take a
+// |nsMallocSizeOfFun| argument. That's because those arguments are primarily
+// to aid DMD track heap blocks... but DMD deliberately doesn't track heap
+// blocks it allocated for itself!
+MOZ_EXPORT void
+SizeOf(Sizes* aSizes)
{
- // Stats are non-deterministic, so don't show it in test mode.
- if (gMode == Test) {
- return;
- }
-
- WriteTitle("Execution measurements\n");
-
- size_t sizeOfStackTraceTable =
- gStackTraceTable->sizeOfIncludingThis(MallocSizeOf);
+ aSizes->mStackTraces = 0;
for (StackTraceTable::Range r = gStackTraceTable->all();
!r.empty();
r.popFront()) {
StackTrace* const& st = r.front();
- sizeOfStackTraceTable += MallocSizeOf(st);
+ aSizes->mStackTraces += MallocSizeOf(st);
}
- W("Stack trace table: %s of %s entries used, taking up %s bytes\n",
- Show(gStackTraceTable->count(), gBuf1, kBufLen),
- Show(gStackTraceTable->capacity(), gBuf2, kBufLen),
- Show(sizeOfStackTraceTable, gBuf3, kBufLen));
- W("Live block table: %s of %s entries used, taking up %s bytes\n",
- Show(gLiveBlockTable->count(), gBuf1, kBufLen),
- Show(gLiveBlockTable->capacity(), gBuf2, kBufLen),
- Show(gLiveBlockTable->sizeOfIncludingThis(MallocSizeOf), gBuf3, kBufLen));
+ aSizes->mStackTraceTable =
+ gStackTraceTable->sizeOfIncludingThis(MallocSizeOf);
- W("\n");
+ aSizes->mLiveBlockTable = gLiveBlockTable->sizeOfIncludingThis(MallocSizeOf);
+
+ aSizes->mDoubleReportTable =
+ gDoubleReportBlockGroupTable->sizeOfIncludingThis(MallocSizeOf);
}
static void
ClearState()
{
// Unreport all blocks, except those that were reported on allocation,
// because they need to keep their reported marking.
for (BlockTable::Range r = gLiveBlockTable->all(); !r.empty(); r.popFront()) {
@@ -1726,21 +1719,21 @@ Dump(Writer aWriter)
AutoLockState lock;
static int dumpCount = 1;
StatusMsg("Dump %d {\n", dumpCount++);
StatusMsg(" gathering live block groups...\n");
BlockGroupTable unreportedBlockGroupTable;
- (void)unreportedBlockGroupTable.init(2048);
+ (void)unreportedBlockGroupTable.init(1024);
size_t unreportedUsableSize = 0;
BlockGroupTable reportedBlockGroupTable;
- (void)reportedBlockGroupTable.init(2048);
+ (void)reportedBlockGroupTable.init(1024);
size_t reportedUsableSize = 0;
bool anyBlocksSampled = false;
for (BlockTable::Range r = gLiveBlockTable->all(); !r.empty(); r.popFront()) {
const Block& b = r.front().value;
if (!b.IsReported()) {
unreportedUsableSize += b.mBlockSize.Usable();
@@ -1776,17 +1769,61 @@ Dump(Writer aWriter)
Show(reportedUsableSize, gBuf1, kBufLen, showTilde),
Percent(reportedUsableSize, totalUsableSize));
W("Unreported: %s bytes (%5.2f%%)\n",
Show(unreportedUsableSize, gBuf1, kBufLen, showTilde),
Percent(unreportedUsableSize, totalUsableSize));
W("\n");
- ShowExecutionMeasurements(aWriter);
+ // Stats are non-deterministic, so don't show them in test mode.
+ if (gMode != Test) {
+ Sizes sizes;
+ SizeOf(&sizes);
+
+ WriteTitle("Execution measurements\n");
+
+ W("Data structures that persist after Dump() ends:\n");
+
+ W(" Stack traces: %10s bytes\n",
+ Show(sizes.mStackTraces, gBuf1, kBufLen));
+
+ W(" Stack trace table: %10s bytes (%s entries, %s used)\n",
+ Show(sizes.mStackTraceTable, gBuf1, kBufLen),
+ Show(gStackTraceTable->capacity(), gBuf2, kBufLen),
+ Show(gStackTraceTable->count(), gBuf3, kBufLen));
+
+ W(" Live block table: %10s bytes (%s entries, %s used)\n",
+ Show(sizes.mLiveBlockTable, gBuf1, kBufLen),
+ Show(gLiveBlockTable->capacity(), gBuf2, kBufLen),
+ Show(gLiveBlockTable->count(), gBuf3, kBufLen));
+
+ W("\nData structures that are cleared after Dump() ends:\n");
+
+ W(" Double-report table: %10s bytes (%s entries, %s used)\n",
+ Show(sizes.mDoubleReportTable, gBuf1, kBufLen),
+ Show(gDoubleReportBlockGroupTable->capacity(), gBuf2, kBufLen),
+ Show(gDoubleReportBlockGroupTable->count(), gBuf3, kBufLen));
+
+ size_t unreportedSize =
+ unreportedBlockGroupTable.sizeOfIncludingThis(MallocSizeOf);
+ W(" Unreported table: %10s bytes (%s entries, %s used)\n",
+ Show(unreportedSize, gBuf1, kBufLen),
+ Show(unreportedBlockGroupTable.capacity(), gBuf2, kBufLen),
+ Show(unreportedBlockGroupTable.count(), gBuf3, kBufLen));
+
+ size_t reportedSize =
+ reportedBlockGroupTable.sizeOfIncludingThis(MallocSizeOf);
+ W(" Reported table: %10s bytes (%s entries, %s used)\n",
+ Show(reportedSize, gBuf1, kBufLen),
+ Show(reportedBlockGroupTable.capacity(), gBuf2, kBufLen),
+ Show(reportedBlockGroupTable.count(), gBuf3, kBufLen));
+
+ W("\n");
+ }
ClearState();
StatusMsg("}\n");
}
//---------------------------------------------------------------------------
// Testing
--- a/memory/replace/dmd/DMD.h
+++ b/memory/replace/dmd/DMD.h
@@ -3,16 +3,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DMD_h___
#define DMD_h___
#include <stdarg.h>
+#include <string.h>
#include "mozilla/Types.h"
namespace mozilla {
namespace dmd {
// Mark a heap block as reported by a memory reporter.
MOZ_EXPORT void
@@ -44,12 +45,27 @@ private:
MOZ_EXPORT void
Dump(Writer aWriter);
// A useful |WriterFun|. If |fp| is a FILE* you want |Dump|'s output to be
// written to, call |Dump(FpWrite, fp)|.
MOZ_EXPORT void
FpWrite(void* aFp, const char* aFmt, va_list aAp);
+struct Sizes
+{
+ size_t mStackTraces;
+ size_t mStackTraceTable;
+ size_t mLiveBlockTable;
+ size_t mDoubleReportTable;
+
+ Sizes() { memset(this, 0, sizeof(Sizes)); }
+};
+
+// Gets the size of various data structures. Used to implement a memory
+// reporter for DMD.
+MOZ_EXPORT void
+SizeOf(Sizes* aSizes);
+
} // namespace mozilla
} // namespace dmd
#endif /* DMD_h___ */
--- a/parser/html/jArray.h
+++ b/parser/html/jArray.h
@@ -96,18 +96,18 @@ class autoJArray {
return newArray;
}
void operator=(const jArray<T,L>& other) {
delete[] arr;
arr = other.arr;
length = other.length;
}
#if defined(MOZ_HAVE_CXX11_NULLPTR)
-# if defined(__clang__) || defined(__ANDROID__)
- // clang on OS X 10.7 and gcc-4.6 on android does not have std::nullptr_t
+# if defined(__clang__) || defined(_STLPORT_VERSION)
+ // clang on OS X 10.7 and Android's STLPort do not have std::nullptr_t
typedef decltype(nullptr) jArray_nullptr_t;
# else
// decltype(nullptr) does not evaluate to std::nullptr_t on GCC 4.6.3
typedef std::nullptr_t jArray_nullptr_t;
# endif
#elif defined(__GNUC__)
typedef void* jArray_nullptr_t;
#elif defined(_WIN64)
--- a/security/build/Makefile.in
+++ b/security/build/Makefile.in
@@ -137,17 +137,22 @@ DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
DEFAULT_GMAKE_FLAGS += NSINSTALL="$(NSINSTALL)"
ifndef MOZ_NATIVE_SQLITE
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=mozsqlite3
DEFAULT_GMAKE_FLAGS += SQLITE_INCLUDE_DIR=$(ABS_DIST)/include
endif
ifdef NSS_DISABLE_DBM
DEFAULT_GMAKE_FLAGS += NSS_DISABLE_DBM=1
endif
-ABS_topsrcdir := $(call core_abspath,$(topsrcdir))
+ABS_topsrcdir := $(shell cd $(topsrcdir); pwd)
+ifeq ($(HOST_OS_ARCH),WINNT)
+ifdef .PYMAKE
+ABS_topsrcdir := $(shell cd $(topsrcdir); pwd -W)
+endif
+endif
# Hack to force NSS build system to use "normal" object directories
DEFAULT_GMAKE_FLAGS += BUILD='$(MOZ_BUILD_ROOT)/security/$$(subst $(ABS_topsrcdir)/security/,,$$(CURDIR))'
DEFAULT_GMAKE_FLAGS += BUILD_TREE='$$(BUILD)' OBJDIR='$$(BUILD)' DEPENDENCIES='$$(BUILD)/.deps' SINGLE_SHLIB_DIR='$$(BUILD)'
DEFAULT_GMAKE_FLAGS += SOURCE_XP_DIR=$(ABS_DIST)
ifndef MOZ_DEBUG
DEFAULT_GMAKE_FLAGS += BUILD_OPT=1 OPT_CODE_SIZE=1
endif
ifdef GNU_CC
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -870,49 +870,103 @@ function run_test_in_child(testFile, opt
* Add a test function to the list of tests that are to be run asynchronously.
*
* Each test function must call run_next_test() when it's done. Test files
* should call run_next_test() in their run_test function to execute all
* async tests.
*
* @return the test function that was passed in.
*/
-let gTests = [];
+let _gTests = [];
function add_test(func) {
- gTests.push(func);
+ _gTests.push([false, func]);
return func;
}
+// We lazy import Task.jsm so we don't incur a run-time penalty for all tests.
+let _Task;
+
+/**
+ * Add a test function which is a Task function.
+ *
+ * Task functions are functions fed into Task.jsm's Task.spawn(). They are
+ * generators that emit promises.
+ *
+ * If an exception is thrown, a do_check_* comparison fails, or if a rejected
+ * promise is yielded, the test function aborts immediately and the test is
+ * reported as a failure.
+ *
+ * Unlike add_test(), there is no need to call run_next_test(). The next test
+ * will run automatically as soon the task function is exhausted. To trigger
+ * premature (but successful) termination of the function, simply return or
+ * throw a Task.Result instance.
+ *
+ * Example usage:
+ *
+ * add_task(function test() {
+ * let result = yield Promise.resolve(true);
+ *
+ * do_check_true(result);
+ *
+ * let secondary = yield someFunctionThatReturnsAPromise(result);
+ * do_check_eq(secondary, "expected value");
+ * });
+ *
+ * add_task(function test_early_return() {
+ * let result = yield somethingThatReturnsAPromise();
+ *
+ * if (!result) {
+ * // Test is ended immediately, with success.
+ * return;
+ * }
+ *
+ * do_check_eq(result, "foo");
+ * });
+ */
+function add_task(func) {
+ if (!_Task) {
+ let ns = {};
+ _Task = Components.utils.import("resource://gre/modules/Task.jsm", ns).Task;
+ }
+
+ _gTests.push([true, func]);
+}
+
/**
* Runs the next test function from the list of async tests.
*/
-let gRunningTest = null;
-let gTestIndex = 0; // The index of the currently running test.
+let _gRunningTest = null;
+let _gTestIndex = 0; // The index of the currently running test.
function run_next_test()
{
function _run_next_test()
{
- if (gTestIndex < gTests.length) {
+ if (_gTestIndex < _gTests.length) {
do_test_pending();
- gRunningTest = gTests[gTestIndex++];
- print("TEST-INFO | " + _TEST_FILE + " | Starting " +
- gRunningTest.name);
- // Exceptions do not kill asynchronous tests, so they'll time out.
- try {
- gRunningTest();
- }
- catch (e) {
- do_throw(e);
+ let _isTask;
+ [_isTask, _gRunningTest] = _gTests[_gTestIndex++];
+ print("TEST-INFO | " + _TEST_FILE + " | Starting " + _gRunningTest.name);
+
+ if (_isTask) {
+ _Task.spawn(_gRunningTest)
+ .then(run_next_test, do_report_unexpected_exception);
+ } else {
+ // Exceptions do not kill asynchronous tests, so they'll time out.
+ try {
+ _gRunningTest();
+ } catch (e) {
+ do_throw(e);
+ }
}
}
}
// For sane stacks during failures, we execute this code soon, but not now.
// We do this now, before we call do_test_finished(), to ensure the pending
// counter (_tests_pending) never reaches 0 while we still have tests to run
// (do_execute_soon bumps that counter).
do_execute_soon(_run_next_test);
- if (gRunningTest !== null) {
+ if (_gRunningTest !== null) {
// Close the previous test do_test_pending call.
do_test_finished();
}
}
--- a/testing/xpcshell/selftest.py
+++ b/testing/xpcshell/selftest.py
@@ -14,16 +14,81 @@ from runxpcshelltests import XPCShellTes
objdir = os.path.abspath(os.environ["OBJDIR"])
xpcshellBin = os.path.join(objdir, "dist", "bin", "xpcshell")
if sys.platform == "win32":
xpcshellBin += ".exe"
SIMPLE_PASSING_TEST = "function run_test() { do_check_true(true); }"
SIMPLE_FAILING_TEST = "function run_test() { do_check_true(false); }"
+ADD_TEST_SIMPLE = '''
+function run_test() { run_next_test(); }
+
+add_test(function test_simple() {
+ do_check_true(true);
+ run_next_test();
+});
+'''
+
+ADD_TEST_FAILING = '''
+function run_test() { run_next_test(); }
+
+add_test(function test_failing() {
+ do_check_true(false);
+ run_next_test();
+});
+'''
+
+ADD_TASK_SINGLE = '''
+Components.utils.import("resource://gre/modules/commonjs/promise/core.js");
+
+function run_test() { run_next_test(); }
+
+add_task(function test_task() {
+ yield Promise.resolve(true);
+ yield Promise.resolve(false);
+});
+'''
+
+ADD_TASK_MULTIPLE = '''
+Components.utils.import("resource://gre/modules/commonjs/promise/core.js");
+
+function run_test() { run_next_test(); }
+
+add_task(function test_task() {
+ yield Promise.resolve(true);
+});
+
+add_task(function test_2() {
+ yield Promise.resolve(true);
+});
+'''
+
+ADD_TASK_REJECTED = '''
+Components.utils.import("resource://gre/modules/commonjs/promise/core.js");
+
+function run_test() { run_next_test(); }
+
+add_task(function test_failing() {
+ yield Promise.reject(new Error("I fail."));
+});
+'''
+
+ADD_TASK_FAILURE_INSIDE = '''
+Components.utils.import("resource://gre/modules/commonjs/promise/core.js");
+
+function run_test() { run_next_test(); }
+
+add_task(function test() {
+ let result = yield Promise.resolve(false);
+
+ do_check_true(result);
+});
+'''
+
class XPCShellTestsTests(unittest.TestCase):
"""
Yes, these are unit tests for a unit test harness.
"""
def setUp(self):
self.log = StringIO()
self.tempdir = tempfile.mkdtemp()
self.x = XPCShellTests(log=self.log)
@@ -207,16 +272,91 @@ tail =
self.assertTestResult(False)
self.assertEquals(1, self.x.testCount)
self.assertEquals(0, self.x.passCount)
self.assertEquals(1, self.x.failCount)
self.assertEquals(0, self.x.todoCount)
self.assertInLog("TEST-UNEXPECTED-FAIL")
self.assertNotInLog("TEST-PASS")
+ def testAddTestSimple(self):
+ """
+ Ensure simple add_test() works.
+ """
+ self.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE)
+ self.writeManifest(["test_add_test_simple.js"])
+
+ self.assertTestResult(True)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(1, self.x.passCount)
+ self.assertEquals(0, self.x.failCount)
+
+ def testAddTestFailing(self):
+ """
+ Ensure add_test() with a failing test is reported.
+ """
+ self.writeFile("test_add_test_failing.js", ADD_TEST_FAILING)
+ self.writeManifest(["test_add_test_failing.js"])
+
+ self.assertTestResult(False)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(0, self.x.passCount)
+ self.assertEquals(1, self.x.failCount)
+
+ def testAddTaskTestSingle(self):
+ """
+ Ensure add_test_task() with a single passing test works.
+ """
+ self.writeFile("test_add_task_simple.js", ADD_TASK_SINGLE)
+ self.writeManifest(["test_add_task_simple.js"])
+
+ self.assertTestResult(True)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(1, self.x.passCount)
+ self.assertEquals(0, self.x.failCount)
+
+ def testAddTaskTestMultiple(self):
+ """
+ Ensure multiple calls to add_test_task() work as expected.
+ """
+ self.writeFile("test_add_task_multiple.js",
+ ADD_TASK_MULTIPLE)
+ self.writeManifest(["test_add_task_multiple.js"])
+
+ self.assertTestResult(True)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(1, self.x.passCount)
+ self.assertEquals(0, self.x.failCount)
+
+ def testAddTaskTestRejected(self):
+ """
+ Ensure rejected task reports as failure.
+ """
+ self.writeFile("test_add_task_rejected.js",
+ ADD_TASK_REJECTED)
+ self.writeManifest(["test_add_task_rejected.js"])
+
+ self.assertTestResult(False)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(0, self.x.passCount)
+ self.assertEquals(1, self.x.failCount)
+
+ def testAddTaskTestFailureInside(self):
+ """
+ Ensure tests inside task are reported as failures.
+ """
+ self.writeFile("test_add_task_failure_inside.js",
+ ADD_TASK_FAILURE_INSIDE)
+ self.writeManifest(["test_add_task_failure_inside.js"])
+
+ self.assertTestResult(False)
+ self.assertEquals(1, self.x.testCount)
+ self.assertEquals(0, self.x.passCount)
+ self.assertEquals(1, self.x.failCount)
+
def testMissingHeadFile(self):
"""
Ensure that missing head file results in fatal error.
"""
self.writeFile("test_basic.js", SIMPLE_PASSING_TEST)
self.writeManifest([("test_basic.js", "head = missing.js")])
raised = False
--- a/toolkit/components/filepicker/nsFileView.cpp
+++ b/toolkit/components/filepicker/nsFileView.cpp
@@ -209,23 +209,23 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIFILEVIEW
NS_DECL_NSITREEVIEW
protected:
virtual ~nsFileView();
void FilterFiles();
- void ReverseArray(nsISupportsArray* aArray);
- void SortArray(nsISupportsArray* aArray);
+ void ReverseArray(nsTArray<nsCOMPtr<nsIFile> >& aArray);
+ void SortArray(nsTArray<nsCOMPtr<nsIFile> >& aArray);
void SortInternal();
- nsCOMPtr<nsISupportsArray> mFileList;
- nsCOMPtr<nsISupportsArray> mDirList;
- nsCOMPtr<nsISupportsArray> mFilteredFiles;
+ nsTArray<nsCOMPtr<nsIFile> > mFileList;
+ nsTArray<nsCOMPtr<nsIFile> > mDirList;
+ nsTArray<nsCOMPtr<nsIFile> > mFilteredFiles;
nsCOMPtr<nsIFile> mDirectoryPath;
nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeSelection> mSelection;
nsCOMPtr<nsIAtom> mDirectoryAtom;
nsCOMPtr<nsIAtom> mFileAtom;
nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
@@ -287,28 +287,16 @@ nsFileView::Init()
mDirectoryAtom = do_GetAtom("directory");
if (!mDirectoryAtom)
return NS_ERROR_OUT_OF_MEMORY;
mFileAtom = do_GetAtom("file");
if (!mFileAtom)
return NS_ERROR_OUT_OF_MEMORY;
- NS_NewISupportsArray(getter_AddRefs(mFileList));
- if (!mFileList)
- return NS_ERROR_OUT_OF_MEMORY;
-
- NS_NewISupportsArray(getter_AddRefs(mDirList));
- if (!mDirList)
- return NS_ERROR_OUT_OF_MEMORY;
-
- NS_NewISupportsArray(getter_AddRefs(mFilteredFiles));
- if (!mFilteredFiles)
- return NS_ERROR_OUT_OF_MEMORY;
-
mDateFormatter = do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID);
if (!mDateFormatter)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
// nsISupports implementation
@@ -340,22 +328,21 @@ nsFileView::GetShowHiddenFiles(bool* aSh
NS_IMETHODIMP
nsFileView::SetShowOnlyDirectories(bool aOnlyDirs)
{
if (aOnlyDirs == mDirectoryFilter)
return NS_OK;
mDirectoryFilter = aOnlyDirs;
- uint32_t dirCount;
- mDirList->Count(&dirCount);
+ uint32_t dirCount = mDirList.Length();
if (mDirectoryFilter) {
int32_t rowDiff = mTotalRows - dirCount;
- mFilteredFiles->Clear();
+ mFilteredFiles.Clear();
mTotalRows = dirCount;
if (mTree)
mTree->RowCountChanged(mTotalRows, -rowDiff);
} else {
// Run the filter again to get the file list back
FilterFiles();
SortArray(mFilteredFiles);
@@ -422,39 +409,39 @@ nsFileView::SetDirectory(nsIFile* aDirec
if (!dirEntries) {
// Couldn't read in the directory, this can happen if the user does not
// have permission to list it.
return NS_ERROR_FAILURE;
}
mDirectoryPath = aDirectory;
- mFileList->Clear();
- mDirList->Clear();
+ mFileList.Clear();
+ mDirList.Clear();
bool hasMore = false;
while (NS_SUCCEEDED(dirEntries->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> nextItem;
dirEntries->GetNext(getter_AddRefs(nextItem));
nsCOMPtr<nsIFile> theFile = do_QueryInterface(nextItem);
bool isDirectory = false;
if (theFile) {
theFile->IsDirectory(&isDirectory);
if (isDirectory) {
bool isHidden;
theFile->IsHidden(&isHidden);
if (mShowHiddenFiles || !isHidden) {
- mDirList->AppendElement(theFile);
+ mDirList.AppendElement(theFile);
}
}
else {
- mFileList->AppendElement(theFile);
+ mFileList.AppendElement(theFile);
}
}
}
if (mTree) {
mTree->BeginUpdateBatch();
mTree->RowCountChanged(0, -mTotalRows);
}
@@ -511,22 +498,21 @@ nsFileView::SetFilter(const nsAString& a
if (iter == end)
break;
++iter; // we know this is either ';' or ' ', skip to next char
}
if (mTree) {
mTree->BeginUpdateBatch();
- uint32_t count;
- mDirList->Count(&count);
+ uint32_t count = mDirList.Length();
mTree->RowCountChanged(count, count - mTotalRows);
}
- mFilteredFiles->Clear();
+ mFilteredFiles.Clear();
FilterFiles();
SortArray(mFilteredFiles);
if (mReverseSort)
ReverseArray(mFilteredFiles);
if (mTree)
@@ -540,35 +526,33 @@ nsFileView::GetSelectedFiles(nsIArray**
{
*aFiles = nullptr;
if (!mSelection)
return NS_OK;
int32_t numRanges;
mSelection->GetRangeCount(&numRanges);
- uint32_t dirCount;
- mDirList->Count(&dirCount);
-
+ uint32_t dirCount = mDirList.Length();
nsCOMPtr<nsIMutableArray> fileArray =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_STATE(fileArray);
for (int32_t range = 0; range < numRanges; ++range) {
int32_t rangeBegin, rangeEnd;
mSelection->GetRangeAt(range, &rangeBegin, &rangeEnd);
for (int32_t itemIndex = rangeBegin; itemIndex <= rangeEnd; ++itemIndex) {
- nsCOMPtr<nsIFile> curFile;
+ nsIFile* curFile = nullptr;
if (itemIndex < (int32_t) dirCount)
- curFile = do_QueryElementAt(mDirList, itemIndex);
+ curFile = mDirList[itemIndex];
else {
if (itemIndex < mTotalRows)
- curFile = do_QueryElementAt(mFilteredFiles, itemIndex - dirCount);
+ curFile = mFilteredFiles[itemIndex - dirCount];
}
if (curFile)
fileArray->AppendElement(curFile, false);
}
}
NS_ADDREF(*aFiles = fileArray);
@@ -606,18 +590,17 @@ nsFileView::GetRowProperties(int32_t aIn
{
return NS_OK;
}
NS_IMETHODIMP
nsFileView::GetCellProperties(int32_t aRow, nsITreeColumn* aCol,
nsISupportsArray* aProperties)
{
- uint32_t dirCount;
- mDirList->Count(&dirCount);
+ uint32_t dirCount = mDirList.Length();
if (aRow < (int32_t) dirCount)
aProperties->AppendElement(mDirectoryAtom);
else if (aRow < mTotalRows)
aProperties->AppendElement(mFileAtom);
return NS_OK;
}
@@ -720,29 +703,26 @@ nsFileView::GetCellValue(int32_t aRow, n
{
return NS_OK;
}
NS_IMETHODIMP
nsFileView::GetCellText(int32_t aRow, nsITreeColumn* aCol,
nsAString& aCellText)
{
- uint32_t dirCount, fileCount;
- mDirList->Count(&dirCount);
- mFilteredFiles->Count(&fileCount);
-
+ uint32_t dirCount = mDirList.Length();
bool isDirectory;
- nsCOMPtr<nsIFile> curFile;
+ nsIFile* curFile = nullptr;
if (aRow < (int32_t) dirCount) {
isDirectory = true;
- curFile = do_QueryElementAt(mDirList, aRow);
+ curFile = mDirList[aRow];
} else if (aRow < mTotalRows) {
isDirectory = false;
- curFile = do_QueryElementAt(mFilteredFiles, aRow - dirCount);
+ curFile = mFilteredFiles[aRow - dirCount];
} else {
// invalid row
aCellText.SetCapacity(0);
return NS_OK;
}
const PRUnichar* colID;
aCol->GetIdConst(&colID);
@@ -850,26 +830,24 @@ nsFileView::PerformActionOnCell(const PR
return NS_OK;
}
// Private methods
void
nsFileView::FilterFiles()
{
- uint32_t count = 0;
- mDirList->Count(&count);
+ uint32_t count = mDirList.Length();
mTotalRows = count;
- mFileList->Count(&count);
- mFilteredFiles->Clear();
+ count = mFileList.Length();
+ mFilteredFiles.Clear();
uint32_t filterCount = mCurrentFilters.Length();
- nsCOMPtr<nsIFile> file;
for (uint32_t i = 0; i < count; ++i) {
- file = do_QueryElementAt(mFileList, i);
+ nsIFile* file = mFileList[i];
bool isHidden = false;
if (!mShowHiddenFiles)
file->IsHidden(&isHidden);
nsAutoString ucsLeafName;
if(NS_FAILED(file->GetLeafName(ucsLeafName))) {
// need to check return value for GetLeafName()
continue;
@@ -883,35 +861,35 @@ nsFileView::FilterFiles()
{
file->IsExecutable(&matched);
} else
matched = (NS_WildCardMatch(ucsLeafName.get(),
mCurrentFilters.ElementAt(j),
true) == MATCH);
if (matched) {
- mFilteredFiles->AppendElement(file);
+ mFilteredFiles.AppendElement(file);
++mTotalRows;
break;
}
}
}
}
}
void
-nsFileView::ReverseArray(nsISupportsArray* aArray)
+nsFileView::ReverseArray(nsTArray<nsCOMPtr<nsIFile> >& aArray)
{
- uint32_t count;
- aArray->Count(&count);
+ uint32_t count = aArray.Length();
for (uint32_t i = 0; i < count/2; ++i) {
- nsCOMPtr<nsISupports> element = dont_AddRef(aArray->ElementAt(i));
- nsCOMPtr<nsISupports> element2 = dont_AddRef(aArray->ElementAt(count-i-1));
- aArray->ReplaceElementAt(element2, i);
- aArray->ReplaceElementAt(element, count-i-1);
+ // If we get references to the COMPtrs in the array, and then .swap() them
+ // we avoid AdRef() / Release() calls.
+ nsCOMPtr<nsIFile>& element = aArray[i];
+ nsCOMPtr<nsIFile>& element2 = aArray[count - i - 1];
+ element.swap(element2);
}
}
static int
SortNameCallback(const void* aElement1, const void* aElement2, void* aContext)
{
nsIFile* file1 = *static_cast<nsIFile* const *>(aElement1);
nsIFile* file2 = *static_cast<nsIFile* const *>(aElement2);
@@ -951,17 +929,17 @@ SortDateCallback(const void* aElement1,
if (time1 == time2)
return 0;
return time1 < time2 ? -1 : 1;
}
void
-nsFileView::SortArray(nsISupportsArray* aArray)
+nsFileView::SortArray(nsTArray<nsCOMPtr<nsIFile> >& aArray)
{
// We assume the array to be in filesystem order, which
// for our purposes, is completely unordered.
int (*compareFunc)(const void*, const void*, void*);
switch (mSortType) {
case sortName:
@@ -972,31 +950,28 @@ nsFileView::SortArray(nsISupportsArray*
break;
case sortDate:
compareFunc = SortDateCallback;
break;
default:
return;
}
- uint32_t count;
- aArray->Count(&count);
+ uint32_t count = aArray.Length();
- // each item will have an additional refcount while
- // the array is alive.
nsIFile** array = new nsIFile*[count];
- uint32_t i;
- for (i = 0; i < count; ++i)
- aArray->QueryElementAt(i, NS_GET_IID(nsIFile), (void**)&(array[i]));
+ for (uint32_t i = 0; i < count; ++i) {
+ array[i] = aArray[i];
+ }
NS_QuickSort(array, count, sizeof(nsIFile*), compareFunc, nullptr);
- for (i = 0; i < count; ++i) {
- aArray->ReplaceElementAt(array[i], i);
- NS_RELEASE(array[i]);
+ for (uint32_t i = 0; i < count; ++i) {
+ // Use swap() to avoid refcounting.
+ aArray[i].swap(array[i]);
}
delete[] array;
}
void
nsFileView::SortInternal()
{
--- a/toolkit/components/places/tests/unit/test_sql_guid_functions.js
+++ b/toolkit/components/places/tests/unit/test_sql_guid_functions.js
@@ -9,18 +9,17 @@
/**
* Checks all our invariants about our guids for a given result.
*
* @param aGuid
* The guid to check.
*/
function check_invariants(aGuid)
{
- print("TEST-INFO | " + gRunningTest.name + " | Checking guid '" +
- aGuid + "'");
+ do_print("Checking guid '" + aGuid + "'");
do_check_valid_places_guid(aGuid);
}
////////////////////////////////////////////////////////////////////////////////
//// Test Functions
function test_guid_invariants()
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -52,18 +52,16 @@ nsFormFillController::nsFormFillControll
mMaxRows(0),
mDisableAutoComplete(false),
mCompleteDefaultIndex(false),
mCompleteSelectedIndex(false),
mForceComplete(false),
mSuppressOnInput(false)
{
mController = do_GetService("@mozilla.org/autocomplete/controller;1");
- mDocShells = do_CreateInstance("@mozilla.org/supports-array;1");
- mPopups = do_CreateInstance("@mozilla.org/supports-array;1");
mPwmgrInputs.Init();
}
struct PwmgrInputsEnumData
{
PwmgrInputsEnumData(nsFormFillController* aFFC, nsIDocument* aDoc)
: mFFC(aFFC), mDoc(aDoc) {}
@@ -81,22 +79,19 @@ nsFormFillController::~nsFormFillControl
MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nullptr;
mFocusedInput = nullptr;
}
PwmgrInputsEnumData ed(this, nullptr);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
// Remove ourselves as a focus listener from all cached docShells
- uint32_t count;
- mDocShells->Count(&count);
+ uint32_t count = mDocShells.Length();
for (uint32_t i = 0; i < count; ++i) {
- nsCOMPtr<nsIDocShell> docShell;
- mDocShells->GetElementAt(i, getter_AddRefs(docShell));
- nsCOMPtr<nsIDOMWindow> domWindow = GetWindowForDocShell(docShell);
+ nsCOMPtr<nsIDOMWindow> domWindow = GetWindowForDocShell(mDocShells[i]);
RemoveWindowListeners(domWindow);
}
}
////////////////////////////////////////////////////////////////////////
//// nsIMutationObserver
//
@@ -199,40 +194,39 @@ nsFormFillController::MaybeRemoveMutatio
////////////////////////////////////////////////////////////////////////
//// nsIFormFillController
NS_IMETHODIMP
nsFormFillController::AttachToBrowser(nsIDocShell *aDocShell, nsIAutoCompletePopup *aPopup)
{
NS_ENSURE_TRUE(aDocShell && aPopup, NS_ERROR_ILLEGAL_VALUE);
- mDocShells->AppendElement(aDocShell);
- mPopups->AppendElement(aPopup);
+ mDocShells.AppendElement(aDocShell);
+ mPopups.AppendElement(aPopup);
// Listen for focus events on the domWindow of the docShell
nsCOMPtr<nsIDOMWindow> domWindow = GetWindowForDocShell(aDocShell);
AddWindowListeners(domWindow);
return NS_OK;
}
NS_IMETHODIMP
nsFormFillController::DetachFromBrowser(nsIDocShell *aDocShell)
{
int32_t index = GetIndexOfDocShell(aDocShell);
NS_ENSURE_TRUE(index >= 0, NS_ERROR_FAILURE);
// Stop listening for focus events on the domWindow of the docShell
- nsCOMPtr<nsIDocShell> docShell;
- mDocShells->GetElementAt(index, getter_AddRefs(docShell));
- nsCOMPtr<nsIDOMWindow> domWindow = GetWindowForDocShell(docShell);
+ nsCOMPtr<nsIDOMWindow> domWindow =
+ GetWindowForDocShell(mDocShells.SafeElementAt(index));
RemoveWindowListeners(domWindow);
- mDocShells->RemoveElementAt(index);
- mPopups->RemoveElementAt(index);
+ mDocShells.RemoveElementAt(index);
+ mPopups.RemoveElementAt(index);
return NS_OK;
}
NS_IMETHODIMP
nsFormFillController::MarkAsLoginManagerField(nsIDOMHTMLInputElement *aInput)
{
@@ -1055,17 +1049,17 @@ nsFormFillController::StartControllingIn
// Find the currently focused docShell
nsCOMPtr<nsIDocShell> docShell = GetDocShellForInput(aInput);
int32_t index = GetIndexOfDocShell(docShell);
if (index < 0)
return;
// Cache the popup for the focused docShell
- mPopups->GetElementAt(index, getter_AddRefs(mFocusedPopup));
+ mFocusedPopup = mPopups.SafeElementAt(index);
nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
if (!node) {
return;
}
AddKeyListener(aInput);
@@ -1140,22 +1134,19 @@ nsFormFillController::GetWindowForDocShe
int32_t
nsFormFillController::GetIndexOfDocShell(nsIDocShell *aDocShell)
{
if (!aDocShell)
return -1;
// Loop through our cached docShells looking for the given docShell
- uint32_t count;
- mDocShells->Count(&count);
+ uint32_t count = mDocShells.Length();
for (uint32_t i = 0; i < count; ++i) {
- nsCOMPtr<nsIDocShell> docShell;
- mDocShells->GetElementAt(i, getter_AddRefs(docShell));
- if (docShell == aDocShell)
+ if (mDocShells[i] == aDocShell)
return i;
}
// Recursively check the parent docShell of this one
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(aDocShell);
nsCOMPtr<nsIDocShellTreeItem> parentItem;
treeItem->GetParent(getter_AddRefs(parentItem));
if (parentItem) {
--- a/toolkit/components/satchel/nsFormFillController.h
+++ b/toolkit/components/satchel/nsFormFillController.h
@@ -8,23 +8,23 @@
#include "nsIFormFillController.h"
#include "nsIAutoCompleteInput.h"
#include "nsIAutoCompleteSearch.h"
#include "nsIAutoCompleteController.h"
#include "nsIAutoCompletePopup.h"
#include "nsIDOMEventListener.h"
#include "nsCOMPtr.h"
-#include "nsISupportsArray.h"
#include "nsDataHashtable.h"
#include "nsIDocShell.h"
#include "nsIDOMWindow.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsILoginManager.h"
#include "nsIMutationObserver.h"
+#include "nsTArray.h"
// X.h defines KeyPress
#ifdef KeyPress
#undef KeyPress
#endif
class nsFormHistory;
class nsINode;
@@ -77,18 +77,18 @@ protected:
nsCOMPtr<nsIAutoCompleteController> mController;
nsCOMPtr<nsILoginManager> mLoginManager;
nsIDOMHTMLInputElement* mFocusedInput;
nsINode* mFocusedInputNode;
nsINode* mListNode;
nsCOMPtr<nsIAutoCompletePopup> mFocusedPopup;
- nsCOMPtr<nsISupportsArray> mDocShells;
- nsCOMPtr<nsISupportsArray> mPopups;
+ nsTArray<nsCOMPtr<nsIDocShell> > mDocShells;
+ nsTArray<nsCOMPtr<nsIAutoCompletePopup> > mPopups;
//these are used to dynamically update the autocomplete
nsCOMPtr<nsIAutoCompleteResult> mLastSearchResult;
nsCOMPtr<nsIAutoCompleteObserver> mLastListener;
nsString mLastSearchString;
nsDataHashtable<nsPtrHashKey<const nsINode>, bool> mPwmgrInputs;
--- a/toolkit/content/Makefile.in
+++ b/toolkit/content/Makefile.in
@@ -61,23 +61,23 @@ EXTRA_JS_MODULES = \
DeferredTask.jsm \
Dict.jsm \
Geometry.jsm \
InlineSpellChecker.jsm \
PageMenu.jsm \
PopupNotifications.jsm \
PropertyListUtils.jsm \
Task.jsm \
- UpdateChannel.jsm \
$(NULL)
EXTRA_PP_JS_MODULES = \
PrivateBrowsingUtils.jsm \
Services.jsm \
WindowDraggingUtils.jsm \
Troubleshoot.jsm \
+ UpdateChannel.jsm \
$(NULL)
ifneq (Android,$(OS_TARGET))
EXTRA_PP_JS_MODULES += LightweightThemeConsumer.jsm
endif
include $(topsrcdir)/config/rules.mk
--- a/toolkit/content/UpdateChannel.jsm
+++ b/toolkit/content/UpdateChannel.jsm
@@ -1,8 +1,10 @@
+#filter substitution
+
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = ["UpdateChannel"];
const Cu = Components.utils;
@@ -10,22 +12,22 @@ Cu.import("resource://gre/modules/Servic
this.UpdateChannel = {
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other instances of the application that may use the same profile.
*/
get: function UpdateChannel_get() {
- let channel = "default";
+ let channel = "@MOZ_UPDATE_CHANNEL@";
let defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
- // use default when pref not found
+ // use default value when pref not found
}
try {
let partners = Services.prefs.getChildList("app.partner.").sort();
if (partners.length) {
channel += "-cck";
partners.forEach(function (prefName) {
channel += "-" + Services.prefs.getCharPref(prefName);
--- a/toolkit/themes/pinstripe/mozapps/jar.mn
+++ b/toolkit/themes/pinstripe/mozapps/jar.mn
@@ -55,17 +55,17 @@ toolkit.jar:
skin/classic/mozapps/passwordmgr/key-16@2x.png (passwordmgr/key-16@2x.png)
skin/classic/mozapps/passwordmgr/key-64.png (passwordmgr/key-64.png)
skin/classic/mozapps/plugins/contentPluginBlocked.png (plugins/contentPluginBlocked.png)
skin/classic/mozapps/plugins/contentPluginCrashed.png (plugins/contentPluginCrashed.png)
skin/classic/mozapps/plugins/contentPluginDisabled.png (plugins/contentPluginDisabled.png)
skin/classic/mozapps/plugins/contentPluginDownload.png (plugins/contentPluginDownload.png)
skin/classic/mozapps/plugins/contentPluginMissing.png (plugins/contentPluginMissing.png)
skin/classic/mozapps/plugins/contentPluginClickToPlay.png (plugins/contentPluginClickToPlay.png)
- skin/classic/mozapps/plugins/notifyPluginBlocked.png (plugins/notifyPluginGeneric.png)
+ skin/classic/mozapps/plugins/notifyPluginBlocked.png (plugins/pluginBlocked-16.png)
skin/classic/mozapps/plugins/notifyPluginCrashed.png (plugins/notifyPluginGeneric.png)
skin/classic/mozapps/plugins/notifyPluginGeneric.png (plugins/notifyPluginGeneric.png)
skin/classic/mozapps/plugins/notifyPluginOutdated.png (plugins/notifyPluginGeneric.png)
skin/classic/mozapps/plugins/pluginProblem.css (plugins/pluginProblem.css)
skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png)
skin/classic/mozapps/plugins/pluginDisabled.png (plugins/pluginDisabled.png)
skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png)
skin/classic/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png)
deleted file mode 100755
--- a/tools/rb/fix-macosx-stack.pl
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/perl
-# vim:sw=4:ts=4:et:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id: fix-macosx-stack.pl,v 1.6 2007/08/17 06:26:09 dbaron%dbaron.org Exp $
-#
-# This script processes the output of nsTraceRefcnt's Mac OS X stack
-# walking code. This is useful for two things:
-# (1) Getting line number information out of
-# |nsTraceRefcntImpl::WalkTheStack|'s output in debug builds.
-# (2) Getting function names out of |nsTraceRefcntImpl::WalkTheStack|'s
-# output on all builds (where it mostly prints UNKNOWN because only
-# a handful of symbols are exported from component libraries).
-#
-# Use the script by piping output containing stacks (such as raw stacks
-# or make-tree.pl balance trees) through this script.
-
-use strict;
-use IPC::Open2;
-
-sub separate_debug_file_for($) {
- my ($file) = @_;
- return '';
-}
-
-my %address_adjustments;
-sub address_adjustment($) {
- my ($file) = @_;
- unless (exists $address_adjustments{$file}) {
- my $result = -1;
-
- open(OTOOL, '-|', 'otool', '-l', $file);
- while (<OTOOL>) {
- if (/^ segname __TEXT$/) {
- if (<OTOOL> =~ /^ vmaddr (0x[0-9a-f]{8})$/) {
- $result = hex($1);
- last;
- } else {
- die "Bad output from otool";
- }
- }
- }
- close(OTOOL);
-
- $result >= 0 || die "Bad output from otool";
-
- $address_adjustments{$file} = $result;
- }
-
- return $address_adjustments{$file};
-}
-
-sub add_info($$$) {
- my ($array, $address, $data) = @_;
-
- # only remember the last item at a given address
- pop @{$array} if ($#{$array} >= 0 && $array->[$#{$array}]->[0] == $address);
-
- push @{$array}, [ $address, $data ];
-}
-
-sub sort_by_address() {
- return $a->[0] <=> $b->[0];
-}
-
-# Return a reference to a hash whose {read} and {write} entries are a
-# bidirectional pipe to an addr2line process that gives symbol
-# information for a file.
-my %nmstructs;
-sub nmstruct_for($) {
- my ($file) = @_;
- my $nmstruct;
- my $curdir;
- unless (exists $nmstructs{$file}) {
- $nmstruct = { symbols => [], files => [], lines => [] };
-
- my $debug_file = separate_debug_file_for($file);
- $debug_file = $file if ($debug_file eq '');
-
- open(NM, '-|', 'nm', '-an', $debug_file);
- while (<NM>) {
- chomp;
- my ($addr, $ty, $rest) = ($_ =~ /^([0-9a-f ]{8}) (.) (.*)$/);
- $addr = hex($addr);
- if ($ty eq 't' || $ty eq 'T') {
- my $sym = $rest;
- if (substr($sym, 0, 1) eq '_') {
- # symbols on Mac have an extra leading _
- $sym = substr($sym, 1);
- }
- add_info($nmstruct->{symbols}, $addr, $sym);
- } elsif ($ty eq '-') {
- # nm gives us stabs debugging information
- my ($n1, $n2, $ty2, $rest2) =
- ($rest =~ /^([0-9a-f]{2}) ([0-9a-f]{4}) (.{5}) (.*)$/);
- # ignore $ty2 == ' FUN'
- if ($ty2 eq 'SLINE') {
- add_info($nmstruct->{lines}, $addr, hex($n2));
- } elsif ($ty2 eq ' SOL') {
- # We get SOL lines within the code for a source
- # file. They always have file names.
- my $file = $rest2;
- if (!($file =~ /^\//)) {
- # resolve relative paths
- $file = $curdir . $file;
- }
- add_info($nmstruct->{files}, $addr, $file);
- } elsif ($ty2 eq ' SO') {
- # We get SO lines at the beginning of the code for a
- # source file, for:
- # * the directory of the compilation
- # * the file
- # * sometimes a blank line
- if ($rest2 =~ /\/$/) {
- $curdir = $rest2;
- } elsif ($rest2 ne '') {
- add_info($nmstruct->{files}, $addr, $rest2);
- }
- }
- }
- }
- close(NM);
-
- # nm -n Doesn't sort across .o files.
- @{$nmstruct->{symbols}} = sort sort_by_address @{$nmstruct->{symbols}};
- @{$nmstruct->{lines}} = sort sort_by_address @{$nmstruct->{lines}};
- @{$nmstruct->{files}} = sort sort_by_address @{$nmstruct->{files}};
-
- $nmstructs{$file} = $nmstruct;
- } else {
- $nmstruct = $nmstructs{$file};
- }
- return $nmstruct;
-}
-
-my $cxxfilt_pipe;
-sub cxxfilt($) {
- my ($sym) = @_;
-
- unless($cxxfilt_pipe) {
- my $pid = open2($cxxfilt_pipe->{read}, $cxxfilt_pipe->{write},
- 'c++filt', '--no-strip-underscores',
- '--format', 'gnu-v3');
- }
- my $out = $cxxfilt_pipe->{write};
- my $in = $cxxfilt_pipe->{read};
- print {$out} $sym . "\n";
- chomp(my $fixedsym = <$in>);
- return $fixedsym;
-}
-
-# binary search the array for the address
-sub array_lookup($$) {
- my ($array, $address) = @_;
-
- my $start = 0;
- my $end = $#{$array};
-
- return [ -1 , "" ] if ($end == -1);
-
- while ($start != $end) {
- my $test = int(($start + $end + 1) / 2); # may equal $end
- # Since we're processing stack traces, and the addresses in
- # stack traces are the instructions to return to, and we really
- # want the instruction that made the call (the previous
- # instruction), use > instead of >=.
- if ($address > $array->[$test]->[0]) {
- $start = $test;
- } else {
- $end = $test - 1;
- }
- }
-
- return $array->[$start];
-}
-
-sub nm_lookup($$) {
- my ($nmstruct, $address) = @_;
- my $sym = array_lookup($nmstruct->{symbols}, $address);
- return {
- symbol => cxxfilt($sym->[1]),
- symbol_offset => ($address - $sym->[0]),
- file => array_lookup($nmstruct->{files}, $address)->[1],
- line => array_lookup($nmstruct->{lines}, $address)->[1]
- };
-}
-
-select STDOUT; $| = 1; # make STDOUT unbuffered
-while (<>) {
- my $line = $_;
- if ($line =~ /^([ \|0-9-]*)(.*) ?\[([^ ]*) \+(0x[0-9A-F]{1,8})\](.*)$/) {
- my $before = $1; # allow preservation of balance trees
- my $badsymbol = $2;
- my $file = $3;
- my $address = hex($4);
- my $after = $5; # allow preservation of counts
-
- if (-f $file) {
- my $nmstruct = nmstruct_for($file);
- $address += address_adjustment($file);
-
- my $info = nm_lookup($nmstruct, $address);
- my $symbol = $info->{symbol};
- my $fileandline = $info->{file} . ':' . $info->{line};
-
- # I'm not sure if it's possible for dlsym to have gotten
- # better information, but just in case:
- if (my ($offset) = ($badsymbol =~ /\+0x([0-9A-F]{8})/)) { # FIXME: add $
- if (hex($offset) < $info->{symbol_offset}) {
- $symbol = $badsymbol;
- }
- }
-
- if ($fileandline eq ':') { $fileandline = $file; }
- print "$before$symbol ($fileandline)$after\n";
- } else {
- print STDERR "Warning: File \"$file\" does not exist.\n";
- print $line;
- }
-
- } else {
- print $line;
- }
-}
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -278,29 +278,29 @@ void nsView::DoResetWidgetBounds(bool aM
// hidpi/lodpi screens to overlap each other and result in bad placement
// (bug 814434).
nsRefPtr<nsDeviceContext> dx;
mViewManager->GetDeviceContext(*getter_AddRefs(dx));
double invScale = dx->UnscaledAppUnitsPerDevPixel() / 60.0;
if (changedPos) {
if (changedSize && !aMoveOnly) {
- mWindow->ResizeClient(NSToIntRound(newBounds.x * invScale),
- NSToIntRound(newBounds.y * invScale),
- NSToIntRound(newBounds.width * invScale),
- NSToIntRound(newBounds.height * invScale),
+ mWindow->ResizeClient(newBounds.x * invScale,
+ newBounds.y * invScale,
+ newBounds.width * invScale,
+ newBounds.height * invScale,
aInvalidateChangedSize);
} else {
- mWindow->MoveClient(NSToIntRound(newBounds.x * invScale),
- NSToIntRound(newBounds.y * invScale));
+ mWindow->MoveClient(newBounds.x * invScale,
+ newBounds.y * invScale);
}
} else {
if (changedSize && !aMoveOnly) {
- mWindow->ResizeClient(NSToIntRound(newBounds.width * invScale),
- NSToIntRound(newBounds.height * invScale),
+ mWindow->ResizeClient(newBounds.width * invScale,
+ newBounds.height * invScale,
aInvalidateChangedSize);
} // else do nothing!
}
}
void nsView::SetDimensions(const nsRect& aRect, bool aPaint, bool aResizeWidget)
{
nsRect dims = aRect;
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -401,56 +401,56 @@ nsWindow::ConstrainPosition(bool aAllowS
*aX = 0;
*aY = 0;
}
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Move(int32_t aX,
- int32_t aY)
+nsWindow::Move(double aX,
+ double aY)
{
if (IsTopLevel())
return NS_OK;
return Resize(aX,
aY,
mBounds.width,
mBounds.height,
true);
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aWidth,
- int32_t aHeight,
+nsWindow::Resize(double aWidth,
+ double aHeight,
bool aRepaint)
{
return Resize(mBounds.x,
mBounds.y,
aWidth,
aHeight,
aRepaint);
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
+nsWindow::Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
bool aRepaint)
{
- ALOG("nsWindow[%p]::Resize [%d %d %d %d] (repaint %d)", (void*)this, aX, aY, aWidth, aHeight, aRepaint);
+ ALOG("nsWindow[%p]::Resize [%f %f %f %f] (repaint %d)", (void*)this, aX, aY, aWidth, aHeight, aRepaint);
bool needSizeDispatch = aWidth != mBounds.width || aHeight != mBounds.height;
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.x = NSToIntRound(aX);
+ mBounds.y = NSToIntRound(aY);
+ mBounds.width = NSToIntRound(aWidth);
+ mBounds.height = NSToIntRound(aHeight);
if (needSizeDispatch)
OnSizeChanged(gfxIntSize(aWidth, aHeight));
// Should we skip honoring aRepaint here?
if (aRepaint && FindTopLevel() == nsWindow::TopWindow())
RedrawAll();
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -74,25 +74,25 @@ public:
virtual nsIWidget *GetParent(void);
virtual float GetDPI();
NS_IMETHOD Show(bool aState);
NS_IMETHOD SetModal(bool aModal);
virtual bool IsVisible() const;
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY);
- NS_IMETHOD Move(int32_t aX,
- int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
- NS_IMETHOD Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
+ NS_IMETHOD Move(double aX,
+ double aY);
+ NS_IMETHOD Resize(double aWidth,
+ double aHeight,
+ bool aRepaint);
+ NS_IMETHOD Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
bool aRepaint);
NS_IMETHOD SetZIndex(int32_t aZIndex);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget,
bool aActivate);
NS_IMETHOD SetSizeMode(int32_t aMode);
NS_IMETHOD Enable(bool aState);
virtual bool IsEnabled() const;
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -374,19 +374,20 @@ public:
virtual bool IsVisible() const;
NS_IMETHOD SetParent(nsIWidget* aNewParent);
virtual nsIWidget* GetParent(void);
virtual float GetDPI();
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX, int32_t *aY);
- NS_IMETHOD Move(int32_t aX, int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth,int32_t aHeight, bool aRepaint);
- NS_IMETHOD Resize(int32_t aX, int32_t aY,int32_t aWidth,int32_t aHeight, bool aRepaint);
+ NS_IMETHOD Move(double aX, double aY);
+ NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint);
+ NS_IMETHOD Resize(double aX, double aY,
+ double aWidth, double aHeight, bool aRepaint);
NS_IMETHOD Enable(bool aState);
virtual bool IsEnabled() const;
NS_IMETHOD SetFocus(bool aRaise);
NS_IMETHOD GetBounds(nsIntRect &aRect);
// Returns the "backing scale factor" of the view's window, which is the
// ratio of pixels in the window's backing store to Cocoa points. Prior to
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -791,78 +791,90 @@ nsChildView::BackingScaleFactorChanged()
NS_IMETHODIMP nsChildView::ConstrainPosition(bool aAllowSlop,
int32_t *aX, int32_t *aY)
{
return NS_OK;
}
// Move this component, aX and aY are in the parent widget coordinate system
-NS_IMETHODIMP nsChildView::Move(int32_t aX, int32_t aY)
+NS_IMETHODIMP nsChildView::Move(double aX, double aY)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
- if (!mView || (mBounds.x == aX && mBounds.y == aY))
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+
+ if (!mView || (mBounds.x == x && mBounds.y == y))
return NS_OK;
- mBounds.x = aX;
- mBounds.y = aY;
+ mBounds.x = x;
+ mBounds.y = y;
[mView setFrame:DevPixelsToCocoaPoints(mBounds)];
if (mVisible)
[mView setNeedsDisplay:YES];
NotifyRollupGeometryChange();
ReportMoveEvent();
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
-NS_IMETHODIMP nsChildView::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
+NS_IMETHODIMP nsChildView::Resize(double aWidth, double aHeight, bool aRepaint)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
- if (!mView || (mBounds.width == aWidth && mBounds.height == aHeight))
+ int32_t width = NSToIntRound(aWidth);
+ int32_t height = NSToIntRound(aHeight);
+
+ if (!mView || (mBounds.width == width && mBounds.height == height))
return NS_OK;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.width = width;
+ mBounds.height = height;
[mView setFrame:DevPixelsToCocoaPoints(mBounds)];
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
NotifyRollupGeometryChange();
ReportSizeEvent();
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
-NS_IMETHODIMP nsChildView::Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool aRepaint)
+NS_IMETHODIMP nsChildView::Resize(double aX, double aY,
+ double aWidth, double aHeight, bool aRepaint)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
- BOOL isMoving = (mBounds.x != aX || mBounds.y != aY);
- BOOL isResizing = (mBounds.width != aWidth || mBounds.height != aHeight);
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+ int32_t width = NSToIntRound(aWidth);
+ int32_t height = NSToIntRound(aHeight);
+
+ BOOL isMoving = (mBounds.x != x || mBounds.y != y);
+ BOOL isResizing = (mBounds.width != width || mBounds.height != height);
if (!mView || (!isMoving && !isResizing))
return NS_OK;
if (isMoving) {
- mBounds.x = aX;
- mBounds.y = aY;
+ mBounds.x = x;
+ mBounds.y = y;
}
if (isResizing) {
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.width = width;
+ mBounds.height = height;
}
[mView setFrame:DevPixelsToCocoaPoints(mBounds)];
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
NotifyRollupGeometryChange();
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -221,25 +221,25 @@ public:
virtual nsIntPoint GetClientOffset();
virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize);
virtual void* GetNativeData(uint32_t aDataType) ;
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX, int32_t *aY);
virtual void SetSizeConstraints(const SizeConstraints& aConstraints);
- NS_IMETHOD Move(int32_t aX, int32_t aY);
+ NS_IMETHOD Move(double aX, double aY);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget, bool aActivate);
NS_IMETHOD SetSizeMode(int32_t aMode);
NS_IMETHOD HideWindowChrome(bool aShouldHide);
void EnteredFullScreen(bool aFullScreen);
NS_IMETHOD MakeFullScreen(bool aFullScreen);
- NS_IMETHOD Resize(int32_t aWidth,int32_t aHeight, bool aRepaint);
- NS_IMETHOD Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool aRepaint);
+ NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint);
+ NS_IMETHOD Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint);
NS_IMETHOD GetClientBounds(nsIntRect &aRect);
NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
void ReportMoveEvent();
void ReportSizeEvent();
NS_IMETHOD SetCursor(nsCursor aCursor);
NS_IMETHOD SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY);
CGFloat BackingScaleFactor();
@@ -320,17 +320,17 @@ protected:
nsresult CreatePopupContentView(const nsIntRect &aRect,
nsDeviceContext *aContext);
void DestroyNativeWindow();
void AdjustWindowShadow();
void SetUpWindowFilter();
void CleanUpWindowFilter();
void UpdateBounds();
- nsresult DoResize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
+ nsresult DoResize(double aX, double aY, double aWidth, double aHeight,
bool aRepaint, bool aConstrainToCurrentScreen);
virtual already_AddRefed<nsIWidget>
AllocateChildPopupWidget()
{
static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID);
nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID);
return widget.forget();
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -1120,27 +1120,27 @@ void nsCocoaWindow::SetSizeConstraints(c
[mWindow setMaxSize:maxSize];
nsBaseWidget::SetSizeConstraints(c);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
// Coordinates are global display pixels
-NS_IMETHODIMP nsCocoaWindow::Move(int32_t aX, int32_t aY)
+NS_IMETHODIMP nsCocoaWindow::Move(double aX, double aY)
{
if (!mWindow) {
return NS_OK;
}
// The point we have is in Gecko coordinates (origin top-left). Convert
// it to Cocoa ones (origin bottom-left).
NSPoint coord = {
static_cast<float>(aX),
- static_cast<float>(nsCocoaUtils::FlippedScreenY(aY))
+ static_cast<float>(nsCocoaUtils::FlippedScreenY(NSToIntRound(aY)))
};
NSRect frame = [mWindow frame];
if (frame.origin.x != coord.x ||
frame.origin.y + frame.size.height != coord.y) {
[mWindow setFrameTopLeftPoint:coord];
}
@@ -1303,37 +1303,37 @@ NS_METHOD nsCocoaWindow::MakeFullScreen(
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
// Coordinates are global display pixels
-nsresult nsCocoaWindow::DoResize(int32_t aX, int32_t aY,
- int32_t aWidth, int32_t aHeight,
+nsresult nsCocoaWindow::DoResize(double aX, double aY,
+ double aWidth, double aHeight,
bool aRepaint,
bool aConstrainToCurrentScreen)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
if (!mWindow) {
return NS_OK;
}
// ConstrainSize operates in device pixels, so we need to convert using
// the backing scale factor here
CGFloat scale = BackingScaleFactor();
- aWidth *= scale;
- aHeight *= scale;
- ConstrainSize(&aWidth, &aHeight);
- aWidth = NSToIntRound(aWidth / scale);
- aHeight = NSToIntRound(aHeight / scale);
-
- nsIntRect newBounds(aX, aY, aWidth, aHeight);
+ int32_t width = NSToIntRound(aWidth * scale);
+ int32_t height = NSToIntRound(aHeight * scale);
+ ConstrainSize(&width, &height);
+
+ nsIntRect newBounds(aX, aY,
+ NSToIntRound(width / scale),
+ NSToIntRound(height / scale));
// constrain to the screen that contains the largest area of the new rect
FitRectToVisibleAreaForScreen(newBounds, aConstrainToCurrentScreen ?
[mWindow screen] : nullptr);
// convert requested bounds into Cocoa coordinate system
NSRect newFrame = nsCocoaUtils::GeckoRectToCocoaRect(newBounds);
@@ -1353,29 +1353,28 @@ nsresult nsCocoaWindow::DoResize(int32_t
[mWindow setFrame:newFrame display:YES];
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
// Coordinates are global display pixels
-NS_IMETHODIMP nsCocoaWindow::Resize(int32_t aX, int32_t aY,
- int32_t aWidth, int32_t aHeight,
+NS_IMETHODIMP nsCocoaWindow::Resize(double aX, double aY,
+ double aWidth, double aHeight,
bool aRepaint)
{
return DoResize(aX, aY, aWidth, aHeight, aRepaint, false);
}
// Coordinates are global display pixels
-NS_IMETHODIMP nsCocoaWindow::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
+NS_IMETHODIMP nsCocoaWindow::Resize(double aWidth, double aHeight, bool aRepaint)
{
double invScale = 1.0 / GetDefaultScale();
- return DoResize(NSToIntRound(mBounds.x * invScale),
- NSToIntRound(mBounds.y * invScale),
+ return DoResize(mBounds.x * invScale, mBounds.y * invScale,
aWidth, aHeight, aRepaint, true);
}
NS_IMETHODIMP nsCocoaWindow::GetClientBounds(nsIntRect &aRect)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
CGFloat scaleFactor = BackingScaleFactor();
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -368,40 +368,41 @@ NS_IMETHODIMP
nsWindow::ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY)
{
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Move(int32_t aX,
- int32_t aY)
+nsWindow::Move(double aX,
+ double aY)
{
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint)
+nsWindow::Resize(double aWidth,
+ double aHeight,
+ bool aRepaint)
{
return Resize(0, 0, aWidth, aHeight, aRepaint);
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint)
+nsWindow::Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint)
{
- mBounds = nsIntRect(aX, aY, aWidth, aHeight);
+ mBounds = nsIntRect(NSToIntRound(aX), NSToIntRound(aY),
+ NSToIntRound(aWidth), NSToIntRound(aHeight));
if (mWidgetListener)
- mWidgetListener->WindowResized(this, aWidth, aHeight);
+ mWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
if (aRepaint && gWindowToRedraw)
gWindowToRedraw->Invalidate(sVirtualBounds);
return NS_OK;
}
NS_IMETHODIMP
--- a/widget/gonk/nsWindow.h
+++ b/widget/gonk/nsWindow.h
@@ -56,25 +56,25 @@ public:
nsWidgetInitData *aInitData);
NS_IMETHOD Destroy(void);
NS_IMETHOD Show(bool aState);
virtual bool IsVisible() const;
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY);
- NS_IMETHOD Move(int32_t aX,
- int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth,
- int32_t aHeight,
+ NS_IMETHOD Move(double aX,
+ double aY);
+ NS_IMETHOD Resize(double aWidth,
+ double aHeight,
bool aRepaint);
- NS_IMETHOD Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
+ NS_IMETHOD Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
bool aRepaint);
NS_IMETHOD Enable(bool aState);
virtual bool IsEnabled() const;
NS_IMETHOD SetFocus(bool aRaise = false);
NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&);
NS_IMETHOD Invalidate(const nsIntRect &aRect);
virtual void* GetNativeData(uint32_t aDataType);
NS_IMETHOD SetTitle(const nsAString& aTitle)
--- a/widget/gtk2/nsWindow.cpp
+++ b/widget/gtk2/nsWindow.cpp
@@ -1007,25 +1007,27 @@ nsWindow::Show(bool aState)
#endif
NativeShow(aState);
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
-{
- ConstrainSize(&aWidth, &aHeight);
+nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
+{
+ int32_t width = NSToIntRound(aWidth);
+ int32_t height = NSToIntRound(aHeight);
+ ConstrainSize(&width, &height);
// For top-level windows, aWidth and aHeight should possibly be
// interpreted as frame bounds, but NativeResize treats these as window
// bounds (Bug 581866).
- mBounds.SizeTo(aWidth, aHeight);
+ mBounds.SizeTo(width, height);
if (!mCreated)
return NS_OK;
// There are several cases here that we need to handle, based on a
// matrix of the visibility of the widget, the sanity of this resize
// and whether or not the widget was previously sane.
@@ -1065,58 +1067,62 @@ nsWindow::Resize(int32_t aWidth, int32_t
}
// If the widget hasn't been shown, mark the widget as needing to be
// resized before it is shown.
else {
if (AreBoundsSane() && mListenForResizes) {
// For widgets that we listen for resizes for (widgets created
// with native parents) we apparently _always_ have to resize. I
// dunno why, but apparently we're lame like that.
- NativeResize(aWidth, aHeight, aRepaint);
+ NativeResize(width, height, aRepaint);
}
else {
mNeedsResize = true;
}
}
NotifyRollupGeometryChange();
// send a resize notification if this is a toplevel
if (mIsTopLevel || mListenForResizes) {
- DispatchResized(aWidth, aHeight);
+ DispatchResized(width, height);
}
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
- bool aRepaint)
-{
- ConstrainSize(&aWidth, &aHeight);
-
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.SizeTo(aWidth, aHeight);
+nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
+ bool aRepaint)
+{
+ int32_t width = NSToIntRound(aWidth);
+ int32_t height = NSToIntRound(aHeight);
+ ConstrainSize(&width, &height);
+
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+ mBounds.x = x;
+ mBounds.y = y;
+ mBounds.SizeTo(width, height);
mNeedsMove = true;
if (!mCreated)
return NS_OK;
// There are several cases here that we need to handle, based on a
// matrix of the visibility of the widget, the sanity of this resize
// and whether or not the widget was previously sane.
// Has this widget been set to visible?
if (mIsShown) {
// Are the bounds sane?
if (AreBoundsSane()) {
// Yep? Resize the window
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ NativeResize(x, y, width, height, aRepaint);
// Does it need to be shown because it was previously insane?
if (mNeedsShow)
NativeShow(true);
}
else {
// If someone has set this so that the needs show flag is false
// and it needs to be hidden, update the flag and hide the
// window. This flag will be cleared the next time someone
@@ -1131,27 +1137,27 @@ nsWindow::Resize(int32_t aX, int32_t aY,
}
// If the widget hasn't been shown, mark the widget as needing to be
// resized before it is shown
else {
if (AreBoundsSane() && mListenForResizes){
// For widgets that we listen for resizes for (widgets created
// with native parents) we apparently _always_ have to resize. I
// dunno why, but apparently we're lame like that.
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ NativeResize(x, y, width, height, aRepaint);
}
else {
mNeedsResize = true;
}
}
NotifyRollupGeometryChange();
if (mIsTopLevel || mListenForResizes) {
- DispatchResized(aWidth, aHeight);
+ DispatchResized(width, height);
}
return NS_OK;
}
NS_IMETHODIMP
nsWindow::Enable(bool aState)
{
@@ -1164,48 +1170,51 @@ bool
nsWindow::IsEnabled() const
{
return mEnabled;
}
NS_IMETHODIMP
-nsWindow::Move(int32_t aX, int32_t aY)
-{
- LOG(("nsWindow::Move [%p] %d %d\n", (void *)this,
+nsWindow::Move(double aX, double aY)
+{
+ LOG(("nsWindow::Move [%p] %f %f\n", (void *)this,
aX, aY));
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+
if (mWindowType == eWindowType_toplevel ||
mWindowType == eWindowType_dialog) {
SetSizeMode(nsSizeMode_Normal);
}
// Since a popup window's x/y coordinates are in relation to to
// the parent, the parent might have moved so we always move a
// popup window.
- if (aX == mBounds.x && aY == mBounds.y &&
+ if (x == mBounds.x && y == mBounds.y &&
mWindowType != eWindowType_popup)
return NS_OK;
// XXX Should we do some AreBoundsSane check here?
- mBounds.x = aX;
- mBounds.y = aY;
+ mBounds.x = x;
+ mBounds.y = y;
if (!mCreated)
return NS_OK;
mNeedsMove = false;
if (mIsTopLevel) {
- gtk_window_move(GTK_WINDOW(mShell), aX, aY);
+ gtk_window_move(GTK_WINDOW(mShell), x, y);
}
else if (mGdkWindow) {
- gdk_window_move(mGdkWindow, aX, aY);
+ gdk_window_move(mGdkWindow, x, y);
}
NotifyRollupGeometryChange();
return NS_OK;
}
NS_IMETHODIMP
nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
--- a/widget/gtk2/nsWindow.h
+++ b/widget/gtk2/nsWindow.h
@@ -101,27 +101,27 @@ public:
virtual float GetDPI();
virtual nsresult SetParent(nsIWidget* aNewParent);
NS_IMETHOD SetModal(bool aModal);
virtual bool IsVisible() const;
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY);
virtual void SetSizeConstraints(const SizeConstraints& aConstraints);
- NS_IMETHOD Move(int32_t aX,
- int32_t aY);
+ NS_IMETHOD Move(double aX,
+ double aY);
NS_IMETHOD Show (bool aState);
- NS_IMETHOD Resize (int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
- NS_IMETHOD Resize (int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
+ NS_IMETHOD Resize (double aWidth,
+ double aHeight,
+ bool aRepaint);
+ NS_IMETHOD Resize (double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint);
virtual bool IsEnabled() const;
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget,
bool aActivate);
NS_IMETHOD SetZIndex(int32_t aZIndex);
NS_IMETHOD SetSizeMode(int32_t aMode);
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -87,18 +87,18 @@ typedef nsEventStatus (* EVENT_CALLBACK)
#ifdef XP_WIN
#define NS_NATIVE_TSF_THREAD_MGR 100
#define NS_NATIVE_TSF_CATEGORY_MGR 101
#define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102
#define NS_NATIVE_ICOREWINDOW 103 // winrt specific
#endif
#define NS_IWIDGET_IID \
- { 0xdb9b0931, 0xebf9, 0x4e0d, \
- { 0xb2, 0x0a, 0xf7, 0x5f, 0xcb, 0x17, 0xe6, 0xe1 } }
+ { 0x476D5716, 0xE225, 0x4497, \
+ { 0x80, 0x41, 0x92, 0xF8, 0x67, 0x59, 0xC4, 0x38 } }
/*
* Window shadow styles
* Also used for the -moz-window-shadow CSS property
*/
#define NS_STYLE_WINDOW_SHADOW_NONE 0
#define NS_STYLE_WINDOW_SHADOW_DEFAULT 1
@@ -692,88 +692,94 @@ class nsIWidget : public nsISupports {
* NOTE:
*
* For a top-level window widget, the "parent's coordinate system" is the
* "global" display pixel coordinate space, *not* device pixels (which
* may be inconsistent between multiple screens, at least in the Mac OS
* case with mixed hi-dpi and lo-dpi displays). This applies to all the
* following Move and Resize widget APIs.
*
- * Currently, only Mac OS X implements a display-/device-pixel distinction;
- * this may change in future, however.
+ * The display-/device-pixel distinction becomes important for (at least)
+ * Mac OS X with Hi-DPI (retina) displays, and Windows when the UI scale
+ * factor is set to other than 100%.
+ *
+ * The Move and Resize methods take floating-point parameters, rather than
+ * integer ones. This is important when manipulating top-level widgets,
+ * where the coordinate system may not be an integral multiple of the
+ * device-pixel space.
**/
/**
* Move this widget.
*
* Coordinates refer to the top-left of the widget. For toplevel windows
* with decorations, this is the top-left of the titlebar and frame .
*
* @param aX the new x position expressed in the parent's coordinate system
* @param aY the new y position expressed in the parent's coordinate system
*
**/
- NS_IMETHOD Move(int32_t aX, int32_t aY) = 0;
+ NS_IMETHOD Move(double aX, double aY) = 0;
/**
* Reposition this widget so that the client area has the given offset.
*
* @param aX the new x offset of the client area expressed as an
* offset from the origin of the client area of the parent
* widget (for root widgets and popup widgets it is in
* screen coordinates)
* @param aY the new y offset of the client area expressed as an
* offset from the origin of the client area of the parent
* widget (for root widgets and popup widgets it is in
* screen coordinates)
*
**/
- NS_IMETHOD MoveClient(int32_t aX, int32_t aY) = 0;
+ NS_IMETHOD MoveClient(double aX, double aY) = 0;
/**
* Resize this widget. Any size constraints set for the window by a
* previous call to SetSizeConstraints will be applied.
*
* @param aWidth the new width expressed in the parent's coordinate system
* @param aHeight the new height expressed in the parent's coordinate system
* @param aRepaint whether the widget should be repainted
*
*/
- NS_IMETHOD Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint) = 0;
+ NS_IMETHOD Resize(double aWidth,
+ double aHeight,
+ bool aRepaint) = 0;
/**
* Move or resize this widget. Any size constraints set for the window by
* a previous call to SetSizeConstraints will be applied.
*
* @param aX the new x position expressed in the parent's coordinate system
* @param aY the new y position expressed in the parent's coordinate system
* @param aWidth the new width expressed in the parent's coordinate system
* @param aHeight the new height expressed in the parent's coordinate system
* @param aRepaint whether the widget should be repainted if the size changes
*
*/
- NS_IMETHOD Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint) = 0;
+ NS_IMETHOD Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint) = 0;
/**
* Resize the widget so that the inner client area has the given size.
*
* @param aWidth the new width of the client area.
* @param aHeight the new height of the client area.
* @param aRepaint whether the widget should be repainted
*
*/
- NS_IMETHOD ResizeClient(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint) = 0;
+ NS_IMETHOD ResizeClient(double aWidth,
+ double aHeight,
+ bool aRepaint) = 0;
/**
* Resize and reposition the widget so tht inner client area has the given
* offset and size.
*
* @param aX the new x offset of the client area expressed as an
* offset from the origin of the client area of the parent
* widget (for root widgets and popup widgets it is in
@@ -782,21 +788,21 @@ class nsIWidget : public nsISupports {
* offset from the origin of the client area of the parent
* widget (for root widgets and popup widgets it is in
* screen coordinates)
* @param aWidth the new width of the client area.
* @param aHeight the new height of the client area.
* @param aRepaint whether the widget should be repainted
*
*/
- NS_IMETHOD ResizeClient(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint) = 0;
+ NS_IMETHOD ResizeClient(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint) = 0;
/**
* Sets the widget's z-index.
*/
NS_IMETHOD SetZIndex(int32_t aZIndex) = 0;
/**
* Gets the widget's z-index.
--- a/widget/os2/nsWindow.cpp
+++ b/widget/os2/nsWindow.cpp
@@ -798,81 +798,87 @@ void nsWindow::NS2PM_PARENT(POINTL& ptl)
SWP swp;
WinQueryWindowPos(hParent, &swp);
ptl.y = swp.cy - ptl.y - 1;
}
}
//-----------------------------------------------------------------------------
-NS_METHOD nsWindow::Move(int32_t aX, int32_t aY)
+NS_METHOD nsWindow::Move(double aX, double aY)
{
if (mFrame) {
- nsresult rv = mFrame->Move(aX, aY);
+ nsresult rv = mFrame->Move(NSToIntRound(aX), NSToIntRound(aY));
NotifyRollupGeometryChange();
return rv;
}
Resize(aX, aY, mBounds.width, mBounds.height, false);
return NS_OK;
}
//-----------------------------------------------------------------------------
-NS_METHOD nsWindow::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
+NS_METHOD nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
{
if (mFrame) {
- nsresult rv = mFrame->Resize(aWidth, aHeight, aRepaint);
+ nsresult rv = mFrame->Resize(NSToIntRound(aWidth), NSToIntRound(aHeight),
+ aRepaint);
NotifyRollupGeometryChange();
return rv;
}
Resize(mBounds.x, mBounds.y, aWidth, aHeight, aRepaint);
return NS_OK;
}
//-----------------------------------------------------------------------------
-NS_METHOD nsWindow::Resize(int32_t aX, int32_t aY,
- int32_t aWidth, int32_t aHeight, bool aRepaint)
+NS_METHOD nsWindow::Resize(double aX, double aY,
+ double aWidth, double aHeight, bool aRepaint)
{
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+ int32_t width = NSToIntRound(aWidth);
+ int32_t height = NSToIntRound(aHeight);
+
if (mFrame) {
- nsresult rv = mFrame->Resize(aX, aY, aWidth, aHeight, aRepaint);
+ nsresult rv = mFrame->Resize(x, y, width, height, aRepaint);
NotifyRollupGeometryChange();
return rv;
}
// For mWnd & eWindowType_child set the cached values upfront, see bug 286555.
// For other mWnd types we defer transfer of values to mBounds to
// WinSetWindowPos(), see bug 391421.
if (!mWnd ||
mWindowType == eWindowType_child ||
mWindowType == eWindowType_plugin) {
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.x = x;
+ mBounds.y = y;
+ mBounds.width = width;
+ mBounds.height = height;
}
// To keep top-left corner in the same place, use the new height
// to calculate the coordinates for the top & bottom left corners.
if (mWnd) {
- POINTL ptl = { aX, aY };
+ POINTL ptl = { x, y };
NS2PM_PARENT(ptl);
- ptl.y -= aHeight - 1;
+ ptl.y -= height - 1;
// For popups, aX already gives the correct position.
if (mWindowType == eWindowType_popup) {
- ptl.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - aHeight - 1 - aY;
+ ptl.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - height - 1 - y;
}
else if (mParent) {
WinMapWindowPoints(mParent->mWnd, WinQueryWindow(mWnd, QW_PARENT),
&ptl, 1);
}
- if (!WinSetWindowPos(mWnd, 0, ptl.x, ptl.y, aWidth, aHeight,
+ if (!WinSetWindowPos(mWnd, 0, ptl.x, ptl.y, width, height,
SWP_MOVE | SWP_SIZE) && aRepaint) {
WinInvalidateRect(mWnd, 0, FALSE);
}
}
NotifyRollupGeometryChange();
return NS_OK;
}
--- a/widget/os2/nsWindow.h
+++ b/widget/os2/nsWindow.h
@@ -146,21 +146,21 @@ public:
gfxASurface* GetThebesSurface();
virtual void* GetNativeData(uint32_t aDataType);
virtual void FreeNativeData(void* aDatum, uint32_t aDataType);
NS_IMETHOD CaptureMouse(bool aCapture);
virtual bool HasPendingInputEvent();
NS_IMETHOD GetBounds(nsIntRect& aRect);
NS_IMETHOD GetClientBounds(nsIntRect& aRect);
virtual nsIntPoint WidgetToScreenOffset();
- NS_IMETHOD Move(int32_t aX, int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth, int32_t aHeight,
+ NS_IMETHOD Move(double aX, double aY);
+ NS_IMETHOD Resize(double aWidth, double aHeight,
bool aRepaint);
- NS_IMETHOD Resize(int32_t aX, int32_t aY,
- int32_t aWidth, int32_t aHeight,
+ NS_IMETHOD Resize(double aX, double aY,
+ double aWidth, double aHeight,
bool aRepaint);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget* aWidget, bool aActivate);
NS_IMETHOD SetZIndex(int32_t aZIndex);
virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations);
NS_IMETHOD SetSizeMode(int32_t aMode);
NS_IMETHOD HideWindowChrome(bool aShouldHide);
NS_IMETHOD SetTitle(const nsAString& aTitle);
--- a/widget/qt/nsWindow.cpp
+++ b/widget/qt/nsWindow.cpp
@@ -540,36 +540,39 @@ nsWindow::ConstrainPosition(bool aAllowS
*aY = screenHeight - mBounds.height;
}
}
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Move(int32_t aX, int32_t aY)
+nsWindow::Move(double aX, double aY)
{
- LOG(("nsWindow::Move [%p] %d %d\n", (void *)this,
+ LOG(("nsWindow::Move [%p] %f %f\n", (void *)this,
aX, aY));
+ int32_t x = NSToIntRound(aX);
+ int32_t y = NSToIntRound(aY);
+
if (mIsTopLevel) {
SetSizeMode(nsSizeMode_Normal);
}
- if (aX == mBounds.x && aY == mBounds.y)
+ if (x == mBounds.x && y == mBounds.y)
return NS_OK;
mNeedsMove = false;
// update the bounds
- QPointF pos( aX, aY );
+ QPointF pos( x, y );
if (mIsTopLevel) {
QWidget *widget = GetViewWidget();
NS_ENSURE_TRUE(widget, NS_OK);
- widget->move(aX, aY);
+ widget->move(x, y);
}
else if (mWidget) {
// the position of the widget is set relative to the parent
// so we map the coordinates accordingly
pos = mWidget->mapFromScene(pos);
pos = mWidget->mapToParent(pos);
mWidget->setPos(pos);
}
@@ -2947,20 +2950,20 @@ nsWindow::Show(bool aState)
mNeedsShow = false;
NativeShow(aState);
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
+nsWindow::Resize(double aWidth, int32_t double, bool aRepaint)
{
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.width = NSToIntRound(aWidth);
+ mBounds.height = NSToIntRound(aHeight);
if (!mWidget)
return NS_OK;
if (mIsShown) {
if (AreBoundsSane()) {
if (mIsTopLevel || mNeedsShow)
NativeResize(mBounds.x, mBounds.y,
@@ -2984,53 +2987,53 @@ nsWindow::Resize(int32_t aWidth, int32_t
NativeShow(false);
}
}
}
else if (AreBoundsSane() && mListenForResizes) {
// For widgets that we listen for resizes for (widgets created
// with native parents) we apparently _always_ have to resize. I
// dunno why, but apparently we're lame like that.
- NativeResize(aWidth, aHeight, aRepaint);
+ NativeResize(mBounds.width, mBounds.height, aRepaint);
}
else {
mNeedsResize = true;
}
// synthesize a resize event if this isn't a toplevel
if (mIsTopLevel || mListenForResizes) {
- nsIntRect rect(mBounds.x, mBounds.y, aWidth, aHeight);
nsEventStatus status;
- DispatchResizeEvent(rect, status);
+ DispatchResizeEvent(mBounds, status);
}
NotifyRollupGeometryChange();
return NS_OK;
}
NS_IMETHODIMP
-nsWindow::Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
+nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
bool aRepaint)
{
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.x = NSToIntRound(aX);
+ mBounds.y = NSToIntRound(aY);
+ mBounds.width = NSToIntRound(aWidth);
+ mBounds.height = NSToIntRound(aHeight);
mPlaced = true;
if (!mWidget)
return NS_OK;
// Has this widget been set to visible?
if (mIsShown) {
// Are the bounds sane?
if (AreBoundsSane()) {
// Yep? Resize the window
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
+ aRepaint);
// Does it need to be shown because it was previously insane?
if (mNeedsShow)
NativeShow(true);
}
else {
// If someone has set this so that the needs show flag is false
// and it needs to be hidden, update the flag and hide the
// window. This flag will be cleared the next time someone
@@ -3044,28 +3047,28 @@ nsWindow::Resize(int32_t aX, int32_t aY,
}
}
// If the widget hasn't been shown, mark the widget as needing to be
// resized before it is shown
else if (AreBoundsSane() && mListenForResizes) {
// For widgets that we listen for resizes for (widgets created
// with native parents) we apparently _always_ have to resize. I
// dunno why, but apparently we're lame like that.
- NativeResize(aX, aY, aWidth, aHeight, aRepaint);
+ NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height,
+ aRepaint);
}
else {
mNeedsResize = true;
mNeedsMove = true;
}
if (mIsTopLevel || mListenForResizes) {
// synthesize a resize event
- nsIntRect rect(aX, aY, aWidth, aHeight);
nsEventStatus status;
- DispatchResizeEvent(rect, status);
+ DispatchResizeEvent(mBounds, status);
}
if (aRepaint)
mWidget->update();
NotifyRollupGeometryChange();
return NS_OK;
}
--- a/widget/qt/nsWindow.h
+++ b/widget/qt/nsWindow.h
@@ -111,26 +111,26 @@ public:
virtual nsIWidget *GetParent(void);
virtual float GetDPI();
NS_IMETHOD Show(bool aState);
NS_IMETHOD SetModal(bool aModal);
virtual bool IsVisible() const;
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY);
- NS_IMETHOD Move(int32_t aX,
- int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
- NS_IMETHOD Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
+ NS_IMETHOD Move(double aX,
+ double aY);
+ NS_IMETHOD Resize(double aWidth,
+ double aHeight,
+ bool aRepaint);
+ NS_IMETHOD Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget,
bool aActivate);
NS_IMETHOD SetSizeMode(int32_t aMode);
NS_IMETHOD Enable(bool aState);
NS_IMETHOD SetFocus(bool aRaise = false);
NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
NS_IMETHOD SetForegroundColor(const nscolor &aColor);
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -1317,17 +1317,17 @@ nsWindow::SetSizeConstraints(const SizeC
c.mMinSize.width = NS_MAX(int32_t(::GetSystemMetrics(SM_CXMINTRACK)), c.mMinSize.width);
c.mMinSize.height = NS_MAX(int32_t(::GetSystemMetrics(SM_CYMINTRACK)), c.mMinSize.height);
}
nsBaseWidget::SetSizeConstraints(c);
}
// Move this component
-NS_METHOD nsWindow::Move(int32_t aX, int32_t aY)
+NS_METHOD nsWindow::Move(double aX, double aY)
{
if (mWindowType == eWindowType_toplevel ||
mWindowType == eWindowType_dialog) {
SetSizeMode(nsSizeMode_Normal);
}
// Check to see if window needs to be moved first
// to avoid a costly call to SetWindowPos. This check
// can not be moved to the calling code in nsView, because
@@ -1337,32 +1337,35 @@ NS_METHOD nsWindow::Move(int32_t aX, int
// in fact change even when the x/y do not. We always need to perform the
// check. See bug #97805 for details.
if (mWindowType != eWindowType_popup && (mBounds.x == aX) && (mBounds.y == aY))
{
// Nothing to do, since it is already positioned correctly.
return NS_OK;
}
- mBounds.x = aX;
- mBounds.y = aY;
+ int32_t x = NSToIntRound(aX * GetDefaultScale());
+ int32_t y = NSToIntRound(aY * GetDefaultScale());
+
+ mBounds.x = x;
+ mBounds.y = y;
if (mWnd) {
#ifdef DEBUG
// complain if a window is moved offscreen (legal, but potentially worrisome)
if (mIsTopWidgetWindow) { // only a problem for top-level windows
// Make sure this window is actually on the screen before we move it
// XXX: Needs multiple monitor support
HDC dc = ::GetDC(mWnd);
if (dc) {
if (::GetDeviceCaps(dc, TECHNOLOGY) == DT_RASDISPLAY) {
RECT workArea;
::SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
// no annoying assertions. just mention the issue.
- if (aX < 0 || aX >= workArea.right || aY < 0 || aY >= workArea.bottom) {
+ if (x < 0 || x >= workArea.right || y < 0 || y >= workArea.bottom) {
PR_LOG(gWindowsLog, PR_LOG_ALWAYS,
("window moved to offscreen position\n"));
}
}
::ReleaseDC(mWnd, dc);
}
}
#endif
@@ -1373,102 +1376,113 @@ NS_METHOD nsWindow::Move(int32_t aX, int
// region, some drivers or OSes may incorrectly copy into the clipped-out
// area.
if (mWindowType == eWindowType_plugin &&
(!mLayerManager || mLayerManager->GetBackendType() == LAYERS_D3D9) &&
mClipRects &&
(mClipRectCount != 1 || !mClipRects[0].IsEqualInterior(nsIntRect(0, 0, mBounds.width, mBounds.height)))) {
flags |= SWP_NOCOPYBITS;
}
- VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, 0, 0, flags));
+ VERIFY(::SetWindowPos(mWnd, NULL, x, y, 0, 0, flags));
SetThemeRegion();
}
NotifyRollupGeometryChange();
return NS_OK;
}
// Resize this component
-NS_METHOD nsWindow::Resize(int32_t aWidth, int32_t aHeight, bool aRepaint)
-{
- NS_ASSERTION((aWidth >=0 ) , "Negative width passed to nsWindow::Resize");
- NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
- ConstrainSize(&aWidth, &aHeight);
+NS_METHOD nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
+{
+ int32_t width = NSToIntRound(aWidth * GetDefaultScale());
+ int32_t height = NSToIntRound(aHeight * GetDefaultScale());
+
+ NS_ASSERTION((width >= 0) , "Negative width passed to nsWindow::Resize");
+ NS_ASSERTION((height >= 0), "Negative height passed to nsWindow::Resize");
+
+ ConstrainSize(&width, &height);
// Avoid unnecessary resizing calls
- if (mBounds.width == aWidth && mBounds.height == aHeight) {
+ if (mBounds.width == width && mBounds.height == height) {
if (aRepaint) {
Invalidate();
}
return NS_OK;
}
#ifdef MOZ_XUL
if (eTransparencyTransparent == mTransparencyMode)
- ResizeTranslucentWindow(aWidth, aHeight);
+ ResizeTranslucentWindow(width, height);
#endif
// Set cached value for lightweight and printing
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.width = width;
+ mBounds.height = height;
if (mWnd) {
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE;
if (!aRepaint) {
flags |= SWP_NOREDRAW;
}
ClearThemeRegion();
- VERIFY(::SetWindowPos(mWnd, NULL, 0, 0, aWidth, GetHeight(aHeight), flags));
+ VERIFY(::SetWindowPos(mWnd, NULL, 0, 0, width, GetHeight(height), flags));
SetThemeRegion();
}
if (aRepaint)
Invalidate();
NotifyRollupGeometryChange();
return NS_OK;
}
// Resize this component
-NS_METHOD nsWindow::Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool aRepaint)
-{
- NS_ASSERTION((aWidth >=0 ), "Negative width passed to nsWindow::Resize");
- NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
- ConstrainSize(&aWidth, &aHeight);
+NS_METHOD nsWindow::Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint)
+{
+ double scale = GetDefaultScale();
+ int32_t x = NSToIntRound(aX * scale);
+ int32_t y = NSToIntRound(aY * scale);
+ int32_t width = NSToIntRound(aWidth * scale);
+ int32_t height = NSToIntRound(aHeight * scale);
+
+ NS_ASSERTION((width >= 0), "Negative width passed to nsWindow::Resize");
+ NS_ASSERTION((height >= 0), "Negative height passed to nsWindow::Resize");
+
+ ConstrainSize(&width, &height);
// Avoid unnecessary resizing calls
- if (mBounds.x == aX && mBounds.y == aY &&
- mBounds.width == aWidth && mBounds.height == aHeight) {
+ if (mBounds.x == x && mBounds.y == y &&
+ mBounds.width == width && mBounds.height == height) {
if (aRepaint) {
Invalidate();
}
return NS_OK;
}
#ifdef MOZ_XUL
if (eTransparencyTransparent == mTransparencyMode)
- ResizeTranslucentWindow(aWidth, aHeight);
+ ResizeTranslucentWindow(width, height);
#endif
// Set cached value for lightweight and printing
- mBounds.x = aX;
- mBounds.y = aY;
- mBounds.width = aWidth;
- mBounds.height = aHeight;
+ mBounds.x = x;
+ mBounds.y = y;
+ mBounds.width = width;
+ mBounds.height = height;
if (mWnd) {
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
if (!aRepaint) {
flags |= SWP_NOREDRAW;
}
ClearThemeRegion();
- VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, aWidth, GetHeight(aHeight), flags));
+ VERIFY(::SetWindowPos(mWnd, NULL, x, y, width, GetHeight(height), flags));
SetThemeRegion();
}
if (aRepaint)
Invalidate();
NotifyRollupGeometryChange();
return NS_OK;
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -90,19 +90,19 @@ public:
NS_IMETHOD SetParent(nsIWidget *aNewParent);
virtual nsIWidget* GetParent(void);
virtual float GetDPI();
virtual double GetDefaultScaleInternal();
NS_IMETHOD Show(bool bState);
virtual bool IsVisible() const;
NS_IMETHOD ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY);
virtual void SetSizeConstraints(const SizeConstraints& aConstraints);
- NS_IMETHOD Move(int32_t aX, int32_t aY);
- NS_IMETHOD Resize(int32_t aWidth, int32_t aHeight, bool aRepaint);
- NS_IMETHOD Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool aRepaint);
+ NS_IMETHOD Move(double aX, double aY);
+ NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint);
+ NS_IMETHOD Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint);
NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, int32_t aHorizontal, int32_t aVertical);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget *aWidget, bool aActivate);
NS_IMETHOD SetSizeMode(int32_t aMode);
NS_IMETHOD Enable(bool aState);
virtual bool IsEnabled() const;
NS_IMETHOD SetFocus(bool aRaise);
NS_IMETHOD GetBounds(nsIntRect &aRect);
NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
--- a/widget/xpwidgets/PuppetWidget.cpp
+++ b/widget/xpwidgets/PuppetWidget.cpp
@@ -174,22 +174,22 @@ PuppetWidget::Show(bool aState)
Resize(mBounds.width, mBounds.height, false);
Invalidate(mBounds);
}
return NS_OK;
}
NS_IMETHODIMP
-PuppetWidget::Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint)
+PuppetWidget::Resize(double aWidth,
+ double aHeight,
+ bool aRepaint)
{
nsIntRect oldBounds = mBounds;
- mBounds.SizeTo(nsIntSize(aWidth, aHeight));
+ mBounds.SizeTo(nsIntSize(NSToIntRound(aWidth), NSToIntRound(aHeight)));
if (mChild) {
return mChild->Resize(aWidth, aHeight, aRepaint);
}
// XXX: roc says that |aRepaint| dictates whether or not to
// invalidate the expanded area
if (oldBounds.Size() < mBounds.Size() && aRepaint) {
--- a/widget/xpwidgets/PuppetWidget.h
+++ b/widget/xpwidgets/PuppetWidget.h
@@ -68,27 +68,27 @@ public:
{ return mVisible; }
NS_IMETHOD ConstrainPosition(bool /*ignored aAllowSlop*/,
int32_t* aX,
int32_t* aY)
{ *aX = kMaxDimension; *aY = kMaxDimension; return NS_OK; }
// We're always at <0, 0>, and so ignore move requests.
- NS_IMETHOD Move(int32_t aX, int32_t aY)
+ NS_IMETHOD Move(double aX, double aY)
{ return NS_OK; }
- NS_IMETHOD Resize(int32_t aWidth,
- int32_t aHeight,
- bool aRepaint);
- NS_IMETHOD Resize(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
- bool aRepaint)
+ NS_IMETHOD Resize(double aWidth,
+ double aHeight,
+ bool aRepaint);
+ NS_IMETHOD Resize(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
+ bool aRepaint)
// (we're always at <0, 0>)
{ return Resize(aWidth, aHeight, aRepaint); }
// XXX/cjones: copying gtk behavior here; unclear what disabling a
// widget is supposed to entail
NS_IMETHOD Enable(bool aState)
{ mEnabled = aState; return NS_OK; }
virtual bool IsEnabled() const
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -985,43 +985,43 @@ void nsBaseWidget::OnDestroy()
NS_IF_RELEASE(mContext);
}
NS_METHOD nsBaseWidget::SetWindowClass(const nsAString& xulWinType)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
-NS_METHOD nsBaseWidget::MoveClient(int32_t aX, int32_t aY)
+NS_METHOD nsBaseWidget::MoveClient(double aX, double aY)
{
nsIntPoint clientOffset(GetClientOffset());
aX -= clientOffset.x;
aY -= clientOffset.y;
return Move(aX, aY);
}
-NS_METHOD nsBaseWidget::ResizeClient(int32_t aWidth,
- int32_t aHeight,
+NS_METHOD nsBaseWidget::ResizeClient(double aWidth,
+ double aHeight,
bool aRepaint)
{
NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
nsIntRect clientBounds;
GetClientBounds(clientBounds);
aWidth = mBounds.width + (aWidth - clientBounds.width);
aHeight = mBounds.height + (aHeight - clientBounds.height);
return Resize(aWidth, aHeight, aRepaint);
}
-NS_METHOD nsBaseWidget::ResizeClient(int32_t aX,
- int32_t aY,
- int32_t aWidth,
- int32_t aHeight,
+NS_METHOD nsBaseWidget::ResizeClient(double aX,
+ double aY,
+ double aWidth,
+ double aHeight,
bool aRepaint)
{
NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
nsIntRect clientBounds;
GetClientBounds(clientBounds);
aWidth = mBounds.width + (aWidth - clientBounds.width);
--- a/widget/xpwidgets/nsBaseWidget.h
+++ b/widget/xpwidgets/nsBaseWidget.h
@@ -111,19 +111,19 @@ public:
virtual void CreateCompositor();
virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) {}
virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) {}
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {}
virtual gfxASurface* GetThebesSurface();
NS_IMETHOD SetModal(bool aModal);
NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
- NS_IMETHOD MoveClient(int32_t aX, int32_t aY);
- NS_IMETHOD ResizeClient(int32_t aWidth, int32_t aHeight, bool aRepaint);
- NS_IMETHOD ResizeClient(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool aRepaint);
+ NS_IMETHOD MoveClient(double aX, double aY);
+ NS_IMETHOD ResizeClient(double aWidth, double aHeight, bool aRepaint);
+ NS_IMETHOD ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint);
NS_IMETHOD GetBounds(nsIntRect &aRect);
NS_IMETHOD GetClientBounds(nsIntRect &aRect);
NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
NS_IMETHOD GetNonClientMargins(nsIntMargin &margins);
NS_IMETHOD SetNonClientMargins(nsIntMargin &margins);
virtual nsIntPoint GetClientOffset();
NS_IMETHOD EnableDragDrop(bool aEnable);
NS_IMETHOD GetAttention(int32_t aCycleCount);
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -556,16 +556,88 @@ static int64_t GetAtomTableSize() {
// NS_RegisterMemoryReporter call fails. So instead we do it here.
NS_MEMORY_REPORTER_IMPLEMENT(AtomTable,
"explicit/atom-tables",
KIND_HEAP,
UNITS_BYTES,
GetAtomTableSize,
"Memory used by the dynamic and static atoms tables.")
+#ifdef MOZ_DMD
+
+namespace mozilla {
+namespace dmd {
+
+class MemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter
+{
+public:
+ MemoryReporter()
+ {}
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD GetName(nsACString &name)
+ {
+ name.Assign("dmd");
+ return NS_OK;
+ }
+
+ NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback,
+ nsISupports *closure)
+ {
+ dmd::Sizes sizes;
+ dmd::SizeOf(&sizes);
+
+#define REPORT(_path, _amount, _desc) \
+ do { \
+ nsresult rv; \
+ rv = callback->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
+ nsIMemoryReporter::KIND_HEAP, \
+ nsIMemoryReporter::UNITS_BYTES, _amount, \
+ NS_LITERAL_CSTRING(_desc), closure); \
+ NS_ENSURE_SUCCESS(rv, rv); \
+ } while (0)
+
+ REPORT("explicit/dmd/stack-traces",
+ sizes.mStackTraces,
+ "Memory used by DMD's stack traces.");
+
+ REPORT("explicit/dmd/stack-trace-table",
+ sizes.mStackTraceTable,
+ "Memory used by DMD's stack trace table.");
+
+ REPORT("explicit/dmd/live-block-table",
+ sizes.mLiveBlockTable,
+ "Memory used by DMD's live block table.");
+
+ REPORT("explicit/dmd/double-report-table",
+ sizes.mDoubleReportTable,
+ "Memory used by DMD's double-report table.");
+
+#undef REPORT
+
+ return NS_OK;
+ }
+
+ NS_IMETHOD GetExplicitNonHeap(int64_t *n)
+ {
+ // No non-heap allocations.
+ *n = 0;
+ return NS_OK;
+ }
+
+};
+
+NS_IMPL_ISUPPORTS1(MemoryReporter, nsIMemoryMultiReporter)
+
+} // namespace dmd
+} // namespace mozilla
+
+#endif // MOZ_DMD
+
/**
** nsMemoryReporterManager implementation
**/
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMemoryReporterManager, nsIMemoryReporterManager)
NS_IMETHODIMP
nsMemoryReporterManager::Init()
@@ -596,18 +668,21 @@ nsMemoryReporterManager::Init()
REGISTER(PageFaultsSoft);
REGISTER(PageFaultsHard);
#endif
#ifdef HAVE_PRIVATE_REPORTER
REGISTER(Private);
#endif
+ REGISTER(AtomTable);
- REGISTER(AtomTable);
+#ifdef MOZ_DMD
+ RegisterMultiReporter(new mozilla::dmd::MemoryReporter);
+#endif
#if defined(XP_LINUX)
nsMemoryInfoDumper::Initialize();
#endif
return NS_OK;
}
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -530,18 +530,17 @@ NS_IMETHODIMP nsXULWindow::GetUnscaledDe
return NS_OK;
}
NS_IMETHODIMP nsXULWindow::SetPosition(int32_t aX, int32_t aY)
{
// Don't reset the window's size mode here - platforms that don't want to move
// maximized windows should reset it in their respective Move implementation.
double invScale = 1.0 / mWindow->GetDefaultScale();
- nsresult rv = mWindow->Move(NSToIntRound(aX * invScale),
- NSToIntRound(aY * invScale));
+ nsresult rv = mWindow->Move(aX * invScale, aY * invScale);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this position. We don't persist this one-time position.
mIgnoreXULPosition = true;
return NS_OK;
}
PersistentAttributesDirty(PAD_POSITION);
@@ -559,19 +558,17 @@ NS_IMETHODIMP nsXULWindow::SetSize(int32
/* any attempt to set the window's size or position overrides the window's
zoom state. this is important when these two states are competing while
the window is being opened. but it should probably just always be so. */
mWindow->SetSizeMode(nsSizeMode_Normal);
mIntrinsicallySized = false;
double invScale = 1.0 / mWindow->GetDefaultScale();
- nsresult rv = mWindow->Resize(NSToIntRound(aCX * invScale),
- NSToIntRound(aCY * invScale),
- aRepaint);
+ nsresult rv = mWindow->Resize(aCX * invScale, aCY * invScale, aRepaint);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this size & in the normal size mode (since it is the only mode
// in which setting dimensions makes sense). We don't persist this one-time
// size.
mIgnoreXULSize = true;
mIgnoreXULSizeMode = true;
@@ -593,20 +590,18 @@ NS_IMETHODIMP nsXULWindow::SetPositionAn
/* any attempt to set the window's size or position overrides the window's
zoom state. this is important when these two states are competing while
the window is being opened. but it should probably just always be so. */
mWindow->SetSizeMode(nsSizeMode_Normal);
mIntrinsicallySized = false;
double invScale = 1.0 / mWindow->GetDefaultScale();
- nsresult rv = mWindow->Resize(NSToIntRound(aX * invScale),
- NSToIntRound(aY * invScale),
- NSToIntRound(aCX * invScale),
- NSToIntRound(aCY * invScale),
+ nsresult rv = mWindow->Resize(aX * invScale, aY * invScale,
+ aCX * invScale, aCY * invScale,
aRepaint);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
if (!mChromeLoaded) {
// If we're called before the chrome is loaded someone obviously wants this
// window at this size and position. We don't persist this one-time setting.
mIgnoreXULPosition = true;
mIgnoreXULSize = true;
mIgnoreXULSizeMode = true;