Merge last PGO-green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2012-08-23 11:29:20 +01:00
commit a35a77c9d9
295 changed files with 5689 additions and 2626 deletions

View File

@ -11,6 +11,10 @@ include $(DEPTH)/config/autoconf.mk
PREF_JS_EXPORTS = $(srcdir)/b2g.js PREF_JS_EXPORTS = $(srcdir)/b2g.js
ifdef ENABLE_MARIONETTE
DEFINES += -DENABLE_MARIONETTE=1
endif
ifndef LIBXUL_SDK ifndef LIBXUL_SDK
PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX) PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)

View File

@ -432,9 +432,11 @@ pref("full-screen-api.ignore-widgets", true);
pref("media.volume.steps", 10); pref("media.volume.steps", 10);
#ifdef ENABLE_MARIONETTE
//Enable/disable marionette server, set listening port //Enable/disable marionette server, set listening port
pref("marionette.defaultPrefs.enabled", true); pref("marionette.defaultPrefs.enabled", true);
pref("marionette.defaultPrefs.port", 2828); pref("marionette.defaultPrefs.port", 2828);
#endif
#ifdef MOZ_UPDATER #ifdef MOZ_UPDATER
pref("app.update.enabled", true); pref("app.update.enabled", true);

View File

@ -11,7 +11,7 @@ ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols ac_add_options --enable-debug-symbols
ac_add_options --enable-debug ac_add_options --enable-debug
ac_add_options --with-ccache ac_add_options --with-ccache
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
# Enable dump() from JS. # Enable dump() from JS.
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -11,7 +11,7 @@ ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols ac_add_options --enable-debug-symbols
ac_add_options --enable-profiling ac_add_options --enable-profiling
ac_add_options --with-ccache ac_add_options --with-ccache
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
# Enable dump() from JS. # Enable dump() from JS.
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -14,7 +14,7 @@ ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols ac_add_options --enable-debug-symbols
ac_add_options --enable-debug ac_add_options --enable-debug
#ac_add_options --with-ccache #ac_add_options --with-ccache
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
# Enable dump() from JS. # Enable dump() from JS.
export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h" export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"

View File

@ -14,7 +14,7 @@ ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols ac_add_options --enable-debug-symbols
ac_add_options --enable-profiling ac_add_options --enable-profiling
#ac_add_options --with-ccache #ac_add_options --with-ccache
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
# Enable dump() from JS. # Enable dump() from JS.
export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h" export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"

View File

@ -33,6 +33,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
#B2G options #B2G options
ac_add_options --enable-application=b2g ac_add_options --enable-application=b2g
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
ac_add_options --disable-elf-hack ac_add_options --disable-elf-hack
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -35,6 +35,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
#B2G options #B2G options
ac_add_options --enable-application=b2g ac_add_options --enable-application=b2g
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
ac_add_options --disable-elf-hack ac_add_options --disable-elf-hack
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -23,6 +23,6 @@ ac_add_options --enable-warnings-as-errors
ac_add_options --enable-application=b2g ac_add_options --enable-application=b2g
ac_add_options --enable-debug-symbols ac_add_options --enable-debug-symbols
ac_add_options --with-ccache ac_add_options --with-ccache
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -24,6 +24,6 @@ fi
# B2G Options # B2G Options
ac_add_options --enable-application=b2g ac_add_options --enable-application=b2g
ac_add_options --enable-marionette ENABLE_MARIONETTE=1
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

@ -38,6 +38,5 @@ fi
MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61} MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
MOZ_EXTENSION_MANAGER=1 MOZ_EXTENSION_MANAGER=1
ENABLE_MARIONETTE=1
MOZ_SYS_MSG=1 MOZ_SYS_MSG=1

View File

@ -38,6 +38,10 @@ DEFINES += -DJAREXT=$(JAREXT)
include $(topsrcdir)/ipc/app/defs.mk include $(topsrcdir)/ipc/app/defs.mk
DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
ifdef ENABLE_MARIONETTE
DEFINES += -DENABLE_MARIONETTE=1
endif
ifdef MOZ_PKG_MANIFEST_P ifdef MOZ_PKG_MANIFEST_P
MOZ_PKG_MANIFEST = package-manifest MOZ_PKG_MANIFEST = package-manifest
endif endif

View File

@ -675,10 +675,12 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/B2GComponents.xpt @BINPATH@/components/B2GComponents.xpt
@BINPATH@/components/CameraContent.js @BINPATH@/components/CameraContent.js
@BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
#ifdef ENABLE_MARIONETTE
@BINPATH@/chrome/marionette@JAREXT@ @BINPATH@/chrome/marionette@JAREXT@
@BINPATH@/chrome/marionette.manifest @BINPATH@/chrome/marionette.manifest
@BINPATH@/components/MarionetteComponents.manifest @BINPATH@/components/MarionetteComponents.manifest
@BINPATH@/components/marionettecomponent.js @BINPATH@/components/marionettecomponent.js
#endif
@BINPATH@/components/AlertsService.js @BINPATH@/components/AlertsService.js
@BINPATH@/components/ContentPermissionPrompt.js @BINPATH@/components/ContentPermissionPrompt.js
#ifdef MOZ_UPDATER #ifdef MOZ_UPDATER

View File

@ -12,6 +12,10 @@ include $(DEPTH)/config/autoconf.mk
DIRS = profile/extensions DIRS = profile/extensions
dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME) dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
ifdef ENABLE_MARIONETTE
DEFINES += -DENABLE_MARIONETTE=1
endif
PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \ PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
$(NULL) $(NULL)

View File

@ -282,14 +282,6 @@ var SocialToolbar = {
init: function SocialToolbar_init() { init: function SocialToolbar_init() {
document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL); document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
let removeItem = document.getElementById("social-remove-menuitem");
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
let label = gNavigatorBundle.getFormattedString("social.remove.label",
[brandShortName]);
let accesskey = gNavigatorBundle.getString("social.remove.accesskey");
removeItem.setAttribute("label", label);
removeItem.setAttribute("accesskey", accesskey);
let statusAreaPopup = document.getElementById("social-statusarea-popup"); let statusAreaPopup = document.getElementById("social-statusarea-popup");
statusAreaPopup.addEventListener("popupshown", function(e) { statusAreaPopup.addEventListener("popupshown", function(e) {
this.button.setAttribute("open", "true"); this.button.setAttribute("open", "true");
@ -344,23 +336,24 @@ var SocialToolbar = {
let iconNames = Object.keys(provider.ambientNotificationIcons); let iconNames = Object.keys(provider.ambientNotificationIcons);
let iconBox = document.getElementById("social-status-iconbox"); let iconBox = document.getElementById("social-status-iconbox");
let notifBox = document.getElementById("social-notification-box"); let notifBox = document.getElementById("social-notification-box");
let notifBrowsers = document.createDocumentFragment(); let notificationFrames = document.createDocumentFragment();
let iconContainers = document.createDocumentFragment(); let iconContainers = document.createDocumentFragment();
for each(let name in iconNames) { for each(let name in iconNames) {
let icon = provider.ambientNotificationIcons[name]; let icon = provider.ambientNotificationIcons[name];
let notifBrowserId = "social-status-" + icon.name; let notificationFrameId = "social-status-" + icon.name;
let notifBrowser = document.getElementById(notifBrowserId); let notificationFrame = document.getElementById(notificationFrameId);
if (!notifBrowser) { if (!notificationFrame) {
notifBrowser = document.createElement("iframe"); notificationFrame = document.createElement("iframe");
notifBrowser.setAttribute("type", "content"); notificationFrame.setAttribute("type", "content");
notifBrowser.setAttribute("id", notifBrowserId); notificationFrame.setAttribute("id", notificationFrameId);
notifBrowsers.appendChild(notifBrowser); notificationFrame.setAttribute("mozbrowser", "true");
notificationFrames.appendChild(notificationFrame);
} }
notifBrowser.setAttribute("origin", provider.origin); notificationFrame.setAttribute("origin", provider.origin);
if (notifBrowser.getAttribute("src") != icon.contentPanel) if (notificationFrame.getAttribute("src") != icon.contentPanel)
notifBrowser.setAttribute("src", icon.contentPanel); notificationFrame.setAttribute("src", icon.contentPanel);
let iconId = "social-notification-icon-" + icon.name; let iconId = "social-notification-icon-" + icon.name;
let iconContainer = document.getElementById(iconId); let iconContainer = document.getElementById(iconId);
@ -387,33 +380,27 @@ var SocialToolbar = {
} }
if (iconImage.getAttribute("src") != icon.iconURL) if (iconImage.getAttribute("src") != icon.iconURL)
iconImage.setAttribute("src", icon.iconURL); iconImage.setAttribute("src", icon.iconURL);
iconImage.setAttribute("notifBrowserId", notifBrowserId); iconImage.setAttribute("notificationFrameId", notificationFrameId);
iconCounter.collapsed = !icon.counter; iconCounter.collapsed = !icon.counter;
iconCounter.firstChild.textContent = icon.counter || ""; iconCounter.firstChild.textContent = icon.counter || "";
} }
notifBox.appendChild(notifBrowsers); notifBox.appendChild(notificationFrames);
iconBox.appendChild(iconContainers); iconBox.appendChild(iconContainers);
let browserIter = notifBox.firstElementChild;
while (browserIter) {
browserIter.docShell.isAppTab = true;
browserIter = browserIter.nextElementSibling;
}
}, },
showAmbientPopup: function SocialToolbar_showAmbientPopup(iconContainer) { showAmbientPopup: function SocialToolbar_showAmbientPopup(iconContainer) {
let iconImage = iconContainer.firstChild; let iconImage = iconContainer.firstChild;
let panel = document.getElementById("social-notification-panel"); let panel = document.getElementById("social-notification-panel");
let notifBox = document.getElementById("social-notification-box"); let notifBox = document.getElementById("social-notification-box");
let notifBrowser = document.getElementById(iconImage.getAttribute("notifBrowserId")); let notificationFrame = document.getElementById(iconImage.getAttribute("notificationFrameId"));
panel.hidden = false; panel.hidden = false;
function sizePanelToContent() { function sizePanelToContent() {
// FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here? // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
// Need to handle dynamic sizing // Need to handle dynamic sizing
let doc = notifBrowser.contentDocument; let doc = notificationFrame.contentDocument;
if (!doc) { if (!doc) {
return; return;
} }
@ -426,23 +413,23 @@ var SocialToolbar = {
// Clear dimensions on all browsers so the panel size will // Clear dimensions on all browsers so the panel size will
// only use the selected browser. // only use the selected browser.
let browserIter = notifBox.firstElementChild; let frameIter = notifBox.firstElementChild;
while (browserIter) { while (frameIter) {
browserIter.hidden = (browserIter != notifBrowser); frameIter.hidden = (frameIter != notificationFrame);
browserIter = browserIter.nextElementSibling; frameIter = frameIter.nextElementSibling;
} }
let [height, width] = [body.firstChild.offsetHeight || 300, 330]; let [height, width] = [body.firstChild.offsetHeight || 300, 330];
notifBrowser.style.width = width + "px"; notificationFrame.style.width = width + "px";
notifBrowser.style.height = height + "px"; notificationFrame.style.height = height + "px";
} }
sizePanelToContent(); sizePanelToContent();
function dispatchPanelEvent(name) { function dispatchPanelEvent(name) {
let evt = notifBrowser.contentDocument.createEvent("CustomEvent"); let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
evt.initCustomEvent(name, true, true, {}); evt.initCustomEvent(name, true, true, {});
notifBrowser.contentDocument.documentElement.dispatchEvent(evt); notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
} }
panel.addEventListener("popuphiding", function onpopuphiding() { panel.addEventListener("popuphiding", function onpopuphiding() {
@ -454,12 +441,13 @@ var SocialToolbar = {
panel.addEventListener("popupshown", function onpopupshown() { panel.addEventListener("popupshown", function onpopupshown() {
panel.removeEventListener("popupshown", onpopupshown); panel.removeEventListener("popupshown", onpopupshown);
SocialToolbar.button.setAttribute("open", "true"); SocialToolbar.button.setAttribute("open", "true");
if (notifBrowser.contentDocument.readyState == "complete") { notificationFrame.docShell.isAppTab = true;
if (notificationFrame.contentDocument.readyState == "complete") {
dispatchPanelEvent("socialFrameShow"); dispatchPanelEvent("socialFrameShow");
} else { } else {
// first time load, wait for load and dispatch after load // first time load, wait for load and dispatch after load
notifBrowser.addEventListener("load", function panelBrowserOnload(e) { notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
notifBrowser.removeEventListener("load", panelBrowserOnload, true); notificationFrame.removeEventListener("load", panelBrowserOnload, true);
setTimeout(function() { setTimeout(function() {
dispatchPanelEvent("socialFrameShow"); dispatchPanelEvent("socialFrameShow");
}, 0); }, 0);

View File

@ -1286,9 +1286,7 @@ var gBrowserInit = {
UpdateUrlbarSearchSplitterState(); UpdateUrlbarSearchSplitterState();
if (isLoadingBlank && gURLBar) if (!isLoadingBlank || !focusAndSelectUrlBar())
gURLBar.focus();
if (!isLoadingBlank || !gURLBar || !gURLBar.focused)
gBrowser.selectedBrowser.focus(); gBrowser.selectedBrowser.focus();
gNavToolbox.customizeDone = BrowserToolboxCustomizeDone; gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
@ -1990,7 +1988,7 @@ function focusAndSelectUrlBar() {
FullScreen.mouseoverToggle(true); FullScreen.mouseoverToggle(true);
gURLBar.focus(); gURLBar.focus();
if (gURLBar.focused) { if (document.activeElement == gURLBar.inputField) {
gURLBar.select(); gURLBar.select();
return true; return true;
} }
@ -3350,7 +3348,7 @@ const BrowserSearch = {
FullScreen.mouseoverToggle(true); FullScreen.mouseoverToggle(true);
if (searchBar) if (searchBar)
searchBar.focus(); searchBar.focus();
if (searchBar && searchBar.textbox.focused) { if (searchBar && document.activeElement == searchBar.textbox.inputField) {
searchBar.select(); searchBar.select();
} else { } else {
openUILinkIn(Services.search.defaultEngine.searchForm, "current"); openUILinkIn(Services.search.defaultEngine.searchForm, "current");

View File

@ -674,8 +674,6 @@
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/> oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
</vbox> </vbox>
</hbox> </hbox>
<menuitem id="social-remove-menuitem"
oncommand="Social.active = false;"/>
<menuitem id="social-toggle-sidebar-menuitem" <menuitem id="social-toggle-sidebar-menuitem"
type="checkbox" type="checkbox"
autocheck="false" autocheck="false"

View File

@ -380,10 +380,6 @@ social.pageShared.label=Page shared
social.enable.label=%S integration social.enable.label=%S integration
social.enable.accesskey=n social.enable.accesskey=n
# LOCALIZATION NOTE (social.remove.label): %S = brandShortName
social.remove.label=Remove from %S
social.remove.accesskey=R
# LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox) # LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
social.activated.message=%1$S integration with %2$S has been activated. social.activated.message=%1$S integration with %2$S has been activated.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

View File

@ -1327,13 +1327,42 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
font-weight: bold; font-weight: bold;
} }
#editBMPanel_rows > row {
margin-bottom: 8px;
}
#editBMPanel_rows > row:last-of-type {
margin-bottom: 0;
}
/**** Input elements ****/
#editBMPanel_rows > row > textbox,
#editBMPanel_rows > row > hbox > textbox {
-moz-appearance: none;
background: linear-gradient(#fafafa, #fff);
background-clip: padding-box;
border-radius: 3px;
border: 1px solid rgba(0,0,0,.3) !important;
box-shadow: inset 0 1px 1px 1px rgba(0,0,0,.05),
0 1px rgba(255,255,255,.3);
margin: 0;
padding: 3px 6px;
}
#editBMPanel_rows > row > textbox[focused="true"],
#editBMPanel_rows > row > hbox > textbox[focused="true"] {
border-color: -moz-mac-focusring !important;
box-shadow: @focusRingShadow@;
}
/**** HUD style buttons ****/ /**** HUD style buttons ****/
.editBookmarkPanelHeaderButton, .editBookmarkPanelHeaderButton,
.editBookmarkPanelBottomButton { .editBookmarkPanelBottomButton {
@hudButton@ @hudButton@
margin: 6px; margin: 0;
min-width: 79px; min-width: 82px;
min-height: 22px; min-height: 22px;
} }
@ -1355,47 +1384,45 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
margin-bottom: 6px; margin-bottom: 6px;
} }
.editBookmarkPanelBottomButton:last-child {
-moz-margin-start: 8px;
}
/* The following elements come from editBookmarkOverlay.xul. Styling that's /* The following elements come from editBookmarkOverlay.xul. Styling that's
specific to the editBookmarkPanel should be in browser.css. Styling that specific to the editBookmarkPanel should be in browser.css. Styling that
should be shared by all editBookmarkOverlay.xul consumers should be in should be shared by all editBookmarkOverlay.xul consumers should be in
editBookmarkOverlay.css. */ editBookmarkOverlay.css. */
#editBMPanel_newFolderBox { #editBMPanel_newFolderBox {
background-image: -moz-linear-gradient(rgb(90,90,90), rgb(40,40,40)); background: linear-gradient(#fff, #f2f2f2);
background-origin: padding-box; background-origin: padding-box;
background-clip: padding-box; background-clip: padding-box;
border-radius: 0 0 3px 3px; border-radius: 0 0 3px 3px;
border: 1px solid rgba(0,0,0,.3); border: 1px solid #a5a5a5;
border-top: none; box-shadow: inset 0 1px rgba(255,255,255,.8),
box-shadow: inset 0 -1px 2px rgba(0,0,0,.2), inset 0 0 1px rgba(255,255, 255,.25),
inset 0 1px 0 rgba(255,255,255,.15), 0 1px rgba(255,255,255,.3);
0 1px 0 rgba(255,255,255,.15); margin: 0;
padding: 0; padding: 0;
margin-left: 4px;
margin-right: 4px;
margin-bottom: 8px;
height: 20px; height: 20px;
} }
#editBMPanel_newFolderButton { #editBMPanel_newFolderButton {
-moz-appearance: none; -moz-appearance: none;
border: 0; border: 0 solid #a5a5a5;
-moz-border-end-width: 3px; -moz-border-end-width: 1px;
border-style: solid;
-moz-border-right-colors: rgba(255,255,255,.1) rgba(0,0,0,.5) rgba(255,255,255,.1);
-moz-border-left-colors: rgba(255,255,255,.1) rgba(0,0,0,.5) rgba(255,255,255,.1);
padding: 0 9px; padding: 0 9px;
margin: 0; margin: 0;
min-width: 21px; min-width: 21px;
min-height: 20px; min-height: 20px;
height: 20px; height: 20px;
color: #fff; color: #fff;
list-style-image: url("chrome://browser/skin/hud-style-new-folder-plus-sign.png"); list-style-image: url("chrome://browser/skin/panel-plus-sign.png");
position: relative; position: relative;
} }
#editBMPanel_newFolderButton:hover:active { #editBMPanel_newFolderButton:hover:active {
background: -moz-linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9)); background: linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9));
box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4); box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4);
} }
@ -1409,10 +1436,13 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
#editBMPanel_folderMenuList { #editBMPanel_folderMenuList {
@hudButton@ @hudButton@
border-radius: 3px; background-clip: padding-box;
margin: 0;
min-height: 22px; min-height: 22px;
-moz-padding-start: 4px; padding-top: 2px;
-moz-padding-end: 0; padding-bottom: 1px;
-moz-padding-start: 8px;
-moz-padding-end: 4px;
} }
#editBMPanel_folderMenuList:-moz-focusring { #editBMPanel_folderMenuList:-moz-focusring {
@ -1431,101 +1461,42 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
border: 0; border: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
-moz-padding-end: 4px;
width: 7px;
} }
#editBMPanel_folderMenuList > .menulist-dropmarker > .dropmarker-icon { #editBMPanel_folderMenuList > .menulist-dropmarker > .dropmarker-icon {
list-style-image: url("chrome://browser/skin/hud-style-dropmarker-double-arrows.png"); list-style-image: url("chrome://global/skin/icons/panel-dropmarker.png");
} }
/**** folder tree ****/ /**** folder tree and tag selector ****/
#editBMPanel_folderTree {
-moz-appearance: none;
border-radius: 2px 2px 0 0;
background-color: rgba(50,50,50,.9);
border: 1px solid rgba(0,0,0,.3);
border-bottom: none;
box-shadow: inset 0 1px 2px rgba(0,0,0,.15);
color: #fff;
/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
min-width: 27em;
position: relative;
}
#editBMPanel_folderTree:-moz-focusring {
box-shadow: 0 0 4px 1px -moz-mac-focusring,
0 0 2px 1px -moz-mac-focusring;
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty {
-moz-appearance: none;
list-style-image: url("chrome://browser/skin/hud-style-twisties.png");
-moz-image-region: rect(0px, 10px, 10px, 0px);
margin-top: 1px;
-moz-margin-end: 1px;
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty(open) {
-moz-image-region: rect(0px, 20px, 10px, 10px);
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty(selected) {
-moz-image-region: rect(0px, 30px, 10px, 20px);
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty(selected, open) {
-moz-image-region: rect(0px, 40px, 10px, 30px);
}
#editBMPanel_folderTree,
#editBMPanel_tagsSelector { #editBMPanel_tagsSelector {
-moz-appearance: none; -moz-appearance: none;
border-radius: 2px; background: linear-gradient(#fafafa, #fff);
background-color: rgba(50,50,50,1); background-clip: padding-box;
border-radius: 3px;
border: 1px solid rgba(0,0,0,.3); border: 1px solid rgba(0,0,0,.3);
border-bottom: none; box-shadow: inset 0 1px 1px 1px rgba(0,0,0,.05),
box-shadow: inset 0 1px 2px rgba(0,0,0,.15), 0 1px rgba(255,255,255,.3);
0 1px 0 rgba(255,255,255,.15); margin: 0;
color: #fff;
} }
#editBMPanel_folderTree:-moz-focusring,
#editBMPanel_tagsSelector:-moz-focusring { #editBMPanel_tagsSelector:-moz-focusring {
@hudButtonFocused@ border-color: -moz-mac-focusring;
box-shadow: @focusRingShadow@;
} }
#editBMPanel_tagsSelector .listcell-check { #editBMPanel_folderTree {
-moz-appearance: none; border-bottom: none;
border: 0; border-bottom-left-radius: 0;
background: url("chrome://browser/skin/hud-style-check-box-empty.png") no-repeat 50% 50%; border-bottom-right-radius: 0;
min-height: 14px; /* Implements editBookmarkPanel resizing on folderTree un-collapse. */
min-width: 14px; margin: 0 !important;
} min-width: 27em;
position: relative;
#editBMPanel_tagsSelector .listcell-check[checked="true"] {
background-image: url("chrome://browser/skin/hud-style-check-box-checked.png");
}
#editBMPanel_folderTree > treechildren::-moz-tree-row {
color: #fff;
background-color: transparent;
border: none;
}
#editBMPanel_folderTree > treechildren::-moz-tree-row(selected) {
background-color: #b3b3b3;
}
#editBMPanel_folderTree > treechildren::-moz-tree-cell-text(selected),
#editBMPanel_folderTree > treechildren::-moz-tree-cell-text(selected, focus) {
color: #222222;
}
#editBMPanel_folderTree > treechildren::-moz-tree-row(selected, focus) {
background-color: #b3b3b3;
}
#editBMPanel_tagsSelector > listitem[selected="true"] {
color: #222222;
background-color: #b3b3b3;
} }
/**** expanders ****/ /**** expanders ****/
@ -1533,13 +1504,10 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
#editBookmarkPanel .expander-up, #editBookmarkPanel .expander-up,
#editBookmarkPanel .expander-down { #editBookmarkPanel .expander-down {
@hudButton@ @hudButton@
border-radius: 3px; margin: 0;
-moz-margin-start: 4px; -moz-margin-start: 4px;
-moz-margin-end: 2px; min-width: 27px;
padding: 0; min-height: 22px;
-moz-padding-start: 4px;
min-width: 10px;
min-height: 20px;
} }
#editBookmarkPanel .expander-up:-moz-focusring, #editBookmarkPanel .expander-up:-moz-focusring,
@ -1553,36 +1521,27 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
} }
#editBookmarkPanel .expander-up { #editBookmarkPanel .expander-up {
list-style-image: url("chrome://browser/skin/hud-style-expander-open.png"); list-style-image: url("chrome://browser/skin/panel-expander-open.png");
} }
#editBookmarkPanel .expander-down { #editBookmarkPanel .expander-down {
list-style-image: url("chrome://browser/skin/hud-style-expander-closed.png"); list-style-image: url("chrome://browser/skin/panel-expander-closed.png");
} }
#editBMPanel_tagsField { #editBookmarkPanel .expander-up .button-icon,
-moz-appearance: none !important; #editBookmarkPanel .expander-down .button-icon {
-moz-padding-start: 3px !important; margin: 1px 0 0;
margin: 2px !important; }
border: 1px solid rgba(0,0,0,.5) !important;
box-shadow: inset 0 1px 0 rgba(0,0,0,.3); #editBookmarkPanel .expander-up .button-text,
background-color: #666 !important; #editBookmarkPanel .expander-down .button-text {
background-clip: padding-box; display: none;
background-origin: padding-box;
color: #fff !important;
min-height: 20px;
} }
#editBMPanel_tagsField > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input:-moz-placeholder { #editBMPanel_tagsField > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input:-moz-placeholder {
color: #bbb; color: #bbb;
} }
#editBMPanel_tagsField[focused="true"] {
@hudButtonFocused@
background-color: #eee !important;
color: #000 !important;
}
.editBMPanel_rowLabel { .editBMPanel_rowLabel {
text-align: end; text-align: end;
} }
@ -1590,16 +1549,11 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
.panel-promo-box { .panel-promo-box {
margin: 8px -16px -16px -16px; margin: 8px -16px -16px -16px;
padding: 8px 16px; padding: 8px 16px;
background-color: hsla(0,0%,7%,.3); background: #e5e5e5;
border-top: 1px solid hsla(0,0%,100%,.1); border-top: 1px solid hsla(0,0%,0%,.1);
border-bottom-left-radius: 6px; border-radius: 0 0 5px 5px;
border-bottom-right-radius: 6px; box-shadow: 0 -1px hsla(0,0%,100%,.5) inset, 0 1px 1px hsla(0,0%,0%,.03) inset;
box-shadow: 0 1px 1px hsla(0,0%,0%,.25) inset; color: #808080;
color: hsl(0,0%,60%);
}
.panel-promo-message > .text-link {
color: hsl(210,100%,75%);
} }
.panel-promo-icon { .panel-promo-icon {
@ -1609,7 +1563,7 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
} }
.panel-promo-closebutton { .panel-promo-closebutton {
list-style-image: url("chrome://global/skin/notification/close.png"); list-style-image: url("chrome://global/skin/icons/close.png");
-moz-image-region: rect(0, 16px, 16px, 0); -moz-image-region: rect(0, 16px, 16px, 0);
border: none; border: none;
-moz-margin-end: -14px; -moz-margin-end: -14px;
@ -2330,7 +2284,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption > vbox > #identity-popup-encryption-icon , #identity-popup-content-box.verifiedIdentity > #identity-popup-encryption > vbox > #identity-popup-encryption-icon ,
#identity-popup-content-box.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon { #identity-popup-content-box.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon {
margin-top: 5px; margin-top: 5px;
list-style-image: url("chrome://browser/skin/Secure-Glyph-White.png"); list-style-image: url("chrome://browser/skin/Secure-Glyph.png");
} }
#notification-popup-box { #notification-popup-box {
@ -2377,18 +2331,15 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://browser/skin/Geolocation-16.png); list-style-image: url(chrome://browser/skin/Geolocation-16.png);
} }
#notification-popup .text-link { #notification-popup .text-link, .panel-arrowcontent .text-link {
color: #fff; color: #0073e6;
text-decoration: none;
} }
.geolocation-text-link { .geolocation-text-link {
-moz-margin-start: 0; /* override default label margin to match description margin */ -moz-margin-start: 0; /* override default label margin to match description margin */
} }
.telemetry-text-link {
color: #fff;
}
#addons-notification-icon { #addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png); list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -32,12 +32,13 @@
} }
#downloadsPanel[hasdownloads] > #downloadsHistory { #downloadsPanel[hasdownloads] > #downloadsHistory {
border-top: 1px solid hsla(0,0%,100%,.1); background: #e5e5e5;
background-color: hsla(0,0%,7%,.3); border-top: 1px solid hsla(0,0%,0%,.1);
box-shadow: 0 1px 1px hsla(0,0%,0%,.25) inset; box-shadow: 0 -1px hsla(0,0%,100%,.5) inset, 0 1px 1px hsla(0,0%,0%,.03) inset;
} }
#downloadsHistory > .button-box { #downloadsHistory > .button-box {
color: #808080;
margin: 1em; margin: 1em;
} }
@ -78,7 +79,6 @@ richlistitem[type="download"]:last-child {
} }
.downloadInfo { .downloadInfo {
color: white;
padding: 8px; padding: 8px;
-moz-padding-end: 0; -moz-padding-end: 0;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

View File

@ -21,13 +21,6 @@ browser.jar:
skin/classic/browser/Geolocation-16.png skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png skin/classic/browser/Geolocation-64.png
skin/classic/browser/home.png skin/classic/browser/home.png
skin/classic/browser/hud-style-check-box-checked.png
skin/classic/browser/hud-style-check-box-empty.png
skin/classic/browser/hud-style-dropmarker-double-arrows.png
skin/classic/browser/hud-style-expander-closed.png
skin/classic/browser/hud-style-expander-open.png
skin/classic/browser/hud-style-new-folder-plus-sign.png
skin/classic/browser/hud-style-twisties.png
skin/classic/browser/identity.png skin/classic/browser/identity.png
skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-generic.png
skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https.png
@ -37,6 +30,9 @@ browser.jar:
skin/classic/browser/KUI-close.png skin/classic/browser/KUI-close.png
skin/classic/browser/menu-back.png skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png skin/classic/browser/menu-forward.png
skin/classic/browser/panel-expander-closed.png
skin/classic/browser/panel-expander-open.png
skin/classic/browser/panel-plus-sign.png
skin/classic/browser/page-livemarks.png skin/classic/browser/page-livemarks.png
skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.css
skin/classic/browser/Privacy-16.png skin/classic/browser/Privacy-16.png
@ -45,7 +41,7 @@ browser.jar:
skin/classic/browser/searchbar-dropmarker.png skin/classic/browser/searchbar-dropmarker.png
skin/classic/browser/searchbar.css skin/classic/browser/searchbar.css
skin/classic/browser/Search.png skin/classic/browser/Search.png
skin/classic/browser/Secure-Glyph-White.png skin/classic/browser/Secure-Glyph.png
skin/classic/browser/keyhole-circle.png skin/classic/browser/keyhole-circle.png
skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar.png
skin/classic/browser/toolbarbutton-dropmarker.png skin/classic/browser/toolbarbutton-dropmarker.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View File

@ -1,6 +1,6 @@
%include ../../../toolkit/themes/pinstripe/global/shared.inc %include ../../../toolkit/themes/pinstripe/global/shared.inc
%include ../browserShared.inc %include ../browserShared.inc
%define hudButton -moz-appearance: none; color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,.5); border-radius: 12px; border: 1px solid rgba(0,0,0,.65); background: -moz-linear-gradient(rgba(110,110,110,.9), rgba(70,70,70,.9) 49%, rgba(50,50,50,.9) 51%, rgba(40,40,40,.9)); box-shadow: inset 0 1px 0 rgba(255,255,255,.2), inset 0 0 1px rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); background-clip: padding-box; background-origin: padding-box; padding: 2px 9px; %define hudButton -moz-appearance: none; color: #434343; border-radius: 4px; border: 1px solid #b5b5b5; background: -moz-linear-gradient(#fff, #f2f2f2); box-shadow: inset 0 1px rgba(255,255,255,.8), inset 0 0 1px rgba(255,255, 255,.25), 0 1px rgba(255,255,255,.3); background-clip: padding-box; background-origin: padding-box; padding: 2px 6px;
%define hudButtonPressed background: -moz-linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9)); box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.1); %define hudButtonPressed box-shadow: inset 0 1px 4px -3px #000, 0 1px rgba(255,255,255,.3);
%define hudButtonFocused box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring; %define hudButtonFocused box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 776 B

View File

@ -5774,6 +5774,10 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
MOZ_D3DX9_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *d3dx9_${MOZ_D3DX9_VERSION}_${MOZ_DIRECTX_SDK_CPU_SUFFIX}.cab | head -n1` MOZ_D3DX9_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *d3dx9_${MOZ_D3DX9_VERSION}_${MOZ_DIRECTX_SDK_CPU_SUFFIX}.cab | head -n1`
MOZ_D3DCOMPILER_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *D3DCompiler_${MOZ_D3DX9_VERSION}_${MOZ_DIRECTX_SDK_CPU_SUFFIX}.cab | head -n1` MOZ_D3DCOMPILER_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *D3DCompiler_${MOZ_D3DX9_VERSION}_${MOZ_DIRECTX_SDK_CPU_SUFFIX}.cab | head -n1`
if test -z "$MOZ_D3DX9_CAB" -o -z "$MOZ_D3DCOMPILER_CAB"; then
AC_MSG_ERROR([Couldn't find the DirectX redistributable files. Either reinstall the DirectX SDK (making sure the "DirectX Redistributable Files" option is selected), or reconfigure with --disable-webgl.])
fi
MOZ_D3DX9_DLL=d3dx9_$MOZ_D3DX9_VERSION.dll MOZ_D3DX9_DLL=d3dx9_$MOZ_D3DX9_VERSION.dll
MOZ_D3DCOMPILER_DLL=D3DCompiler_$MOZ_D3DX9_VERSION.dll MOZ_D3DCOMPILER_DLL=D3DCompiler_$MOZ_D3DX9_VERSION.dll
fi fi

View File

@ -174,14 +174,6 @@ struct ViewportInfo
// Whether or not the user can zoom in and out on the page. Default is true. // Whether or not the user can zoom in and out on the page. Default is true.
bool allowZoom; bool allowZoom;
// This is a holdover from e10s fennec, and might be removed in the future.
// It's a hack to work around bugs that didn't allow zooming of documents
// from within the parent process. It is still used in native Fennec for XUL
// documents, but it should probably be removed.
// Currently, from, within GetViewportInfo(), This is only set to false
// if the document is a XUL document.
bool autoScale;
}; };
struct EventNameMapping struct EventNameMapping

View File

@ -5055,42 +5055,37 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
ret.defaultZoom = 1.0; ret.defaultZoom = 1.0;
ret.autoSize = true; ret.autoSize = true;
ret.allowZoom = true; ret.allowZoom = true;
ret.autoScale = true;
// If the docType specifies that we are on a site optimized for mobile, nsAutoString viewport;
// then we want to return specially crafted defaults for the viewport info. aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
nsCOMPtr<nsIDOMDocument> if (viewport.IsEmpty()) {
domDoc(do_QueryInterface(aDocument)); // If the docType specifies that we are on a site optimized for mobile,
// then we want to return specially crafted defaults for the viewport info.
nsCOMPtr<nsIDOMDocumentType> docType; nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aDocument));
nsresult rv = domDoc->GetDoctype(getter_AddRefs(docType)); nsCOMPtr<nsIDOMDocumentType> docType;
if (NS_SUCCEEDED(rv) && docType) { nsresult rv = domDoc->GetDoctype(getter_AddRefs(docType));
nsAutoString docId; if (NS_SUCCEEDED(rv) && docType) {
rv = docType->GetPublicId(docId); nsAutoString docId;
if (NS_SUCCEEDED(rv)) { rv = docType->GetPublicId(docId);
if ((docId.Find("WAP") != -1) || if (NS_SUCCEEDED(rv)) {
(docId.Find("Mobile") != -1) || if ((docId.Find("WAP") != -1) ||
(docId.Find("WML") != -1)) (docId.Find("Mobile") != -1) ||
{ (docId.Find("WML") != -1))
return ret; {
return ret;
}
} }
} }
nsAutoString handheldFriendly;
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
return ret;
}
} }
if (aDocument->IsXUL()) {
ret.autoScale = false;
return ret;
}
nsAutoString handheldFriendly;
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
return ret;
}
nsAutoString minScaleStr; nsAutoString minScaleStr;
aDocument->GetHeaderData(nsGkAtoms::minimum_scale, minScaleStr); aDocument->GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
nsresult errorCode; nsresult errorCode;
float scaleMinFloat = minScaleStr.ToFloat(&errorCode); float scaleMinFloat = minScaleStr.ToFloat(&errorCode);
@ -5103,7 +5098,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale); scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale);
nsAutoString maxScaleStr; nsAutoString maxScaleStr;
aDocument->GetHeaderData(nsGkAtoms::maximum_scale, maxScaleStr); aDocument->GetHeaderData(nsGkAtoms::viewport_maximum_scale, maxScaleStr);
// We define a special error code variable for the scale and max scale, // We define a special error code variable for the scale and max scale,
// because they are used later (see the width calculations). // because they are used later (see the width calculations).
@ -5239,6 +5234,8 @@ nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
/* We never fail. */ /* We never fail. */
nsresult rv = NS_OK; nsresult rv = NS_OK;
aDocument->SetHeaderData(nsGkAtoms::viewport, viewportInfo);
/* Iterators. */ /* Iterators. */
nsAString::const_iterator tip, tail, end; nsAString::const_iterator tip, tail, end;
viewportInfo.BeginReading(tip); viewportInfo.BeginReading(tip);

View File

@ -8599,9 +8599,7 @@ HasCrossProcessParent(nsIDocument* aDocument)
if (!docShell) { if (!docShell) {
return false; return false;
} }
bool isBrowserElement = false; return docShell->GetIsBrowserElement();
docShell->GetIsBrowserElement(&isBrowserElement);
return isBrowserElement;
} }
static bool static bool

View File

@ -1142,27 +1142,10 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
bool ourContentBoundary, otherContentBoundary; if (ourDocshell->GetIsBrowserElement() !=
ourDocshell->GetIsContentBoundary(&ourContentBoundary); otherDocshell->GetIsBrowserElement() ||
otherDocshell->GetIsContentBoundary(&otherContentBoundary); ourDocshell->GetIsApp() != otherDocshell->GetIsApp()) {
if (ourContentBoundary != otherContentBoundary) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (ourContentBoundary) {
bool ourIsBrowser, otherIsBrowser;
ourDocshell->GetIsBrowserElement(&ourIsBrowser);
otherDocshell->GetIsBrowserElement(&otherIsBrowser);
if (ourIsBrowser != otherIsBrowser) {
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
}
bool ourIsApp, otherIsApp;
ourDocshell->GetIsApp(&ourIsApp);
otherDocshell->GetIsApp(&otherIsApp);
if (ourIsApp != otherIsApp) {
return NS_ERROR_NOT_IMPLEMENTED;
}
} }
if (mInSwap || aOther->mInSwap) { if (mInSwap || aOther->mInSwap) {

View File

@ -311,9 +311,7 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
parentDocShellItem) { parentDocShellItem) {
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem); nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
bool isContentBoundary; if (curDocShell && curDocShell->GetIsContentBoundary()) {
curDocShell->GetIsContentBoundary(&isContentBoundary);
if (isContentBoundary) {
break; break;
} }

View File

@ -5135,9 +5135,7 @@ nsDocShell::SetIsActive(bool aIsActive)
continue; continue;
} }
bool isContentBoundary = false; if (!docshell->GetIsContentBoundary()) {
docshell->GetIsContentBoundary(&isContentBoundary);
if (!isContentBoundary) {
docshell->SetIsActive(aIsActive); docshell->SetIsActive(aIsActive);
} }
} }
@ -12268,22 +12266,21 @@ nsDocShell::GetFrameType()
return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular; return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser) nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{ {
*aIsBrowser = (GetFrameType() == eFrameTypeBrowser); *aIsBrowser = (GetFrameType() == eFrameTypeBrowser);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp) nsDocShell::GetIsApp(bool* aIsApp)
{ {
*aIsApp = (GetFrameType() == eFrameTypeApp); *aIsApp = (GetFrameType() == eFrameTypeApp);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary) nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
{ {
switch (GetFrameType()) { switch (GetFrameType()) {
@ -12299,21 +12296,21 @@ nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement) nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
{ {
*aIsInBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser); *aIsInBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInApp(bool* aIsInApp) nsDocShell::GetIsInApp(bool* aIsInApp)
{ {
*aIsInApp = (GetInheritedFrameType() == eFrameTypeApp); *aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary) nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
{ {
switch (GetInheritedFrameType()) { switch (GetInheritedFrameType()) {
@ -12339,7 +12336,7 @@ nsDocShell::SetAppId(uint32_t aAppId)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP /* [infallible] */ NS_IMETHODIMP
nsDocShell::GetAppId(uint32_t* aAppId) nsDocShell::GetAppId(uint32_t* aAppId)
{ {
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) { if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {

View File

@ -589,23 +589,23 @@ interface nsIDocShell : nsISupports
/** /**
* Returns true iff the docshell is marked as a browser frame. * Returns true iff the docshell is marked as a browser frame.
*/ */
readonly attribute boolean isBrowserElement; [infallible] readonly attribute boolean isBrowserElement;
/** /**
* Returns true iif the docshell is marked as an app frame. * Returns true iif the docshell is marked as an app frame.
*/ */
readonly attribute boolean isApp; [infallible] readonly attribute boolean isApp;
/** /**
* Returns true iif the docshell is marked as a type that behaves like a * Returns true iif the docshell is marked as a type that behaves like a
* content boundary. * content boundary.
*/ */
readonly attribute boolean isContentBoundary; [infallible] readonly attribute boolean isContentBoundary;
/** /**
* Returns true iif the docshell is inside a browser element. * Returns true iif the docshell is inside a browser element.
*/ */
readonly attribute boolean isInBrowserElement; [infallible] readonly attribute boolean isInBrowserElement;
/** /**
* Returns true iif the docshell is inside an application. However, it will * Returns true iif the docshell is inside an application. However, it will
@ -625,13 +625,13 @@ interface nsIDocShell : nsISupports
* If you're doing a security check, use the content's principal instead of * If you're doing a security check, use the content's principal instead of
* this method. * this method.
*/ */
readonly attribute boolean isInApp; [infallible] readonly attribute boolean isInApp;
/** /**
* Returns if the docshell has a docshell that behaves as a content boundary * Returns if the docshell has a docshell that behaves as a content boundary
* in his parent hierarchy. * in his parent hierarchy.
*/ */
readonly attribute boolean isBelowContentBoundary; [infallible] readonly attribute boolean isBelowContentBoundary;
/** /**
* Set the app id this docshell is associated with. The id has to be a valid * Set the app id this docshell is associated with. The id has to be a valid
@ -650,7 +650,7 @@ interface nsIDocShell : nsISupports
* Returns the app id of the app the docshell is in. Returns * Returns the app id of the app the docshell is in. Returns
* nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app. * nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app.
*/ */
readonly attribute unsigned long appId; [infallible] readonly attribute unsigned long appId;
/** /**
* True iff asynchronous panning and zooming is enabled for this * True iff asynchronous panning and zooming is enabled for this

View File

@ -7,7 +7,7 @@
const Cc = Components.classes; const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "cpmm", function() { XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
@ -31,7 +31,7 @@ function ActivityRequestHandler() {
// When a system message of type 'activity' is emitted, it forces the // When a system message of type 'activity' is emitted, it forces the
// creation of an ActivityWrapper which in turns replace the default // creation of an ActivityWrapper which in turns replace the default
// system message callback. The newly created wrapper then create a // system message callback. The newly created wrapper then create a
// nsIDOMActivityRequestHandler object and fills up the properties of // nsIDOMActivityRequestHandler object and fills up the properties of
// this object as well as the properties of the nsIDOMActivityOptions // this object as well as the properties of the nsIDOMActivityOptions
// object contains by the request handler. // object contains by the request handler.
this._id = null; this._id = null;
@ -40,6 +40,12 @@ function ActivityRequestHandler() {
} }
ActivityRequestHandler.prototype = { ActivityRequestHandler.prototype = {
__exposedProps__: {
source: "r",
postResult: "r",
postError: "r"
},
get source() { get source() {
return this._options; return this._options;
}, },

View File

@ -305,12 +305,16 @@ let AlarmService = {
let alarmQueue = this._alarmQueue; let alarmQueue = this._alarmQueue;
alarmQueue.length = 0; alarmQueue.length = 0;
this._currentAlarm = null; this._currentAlarm = null;
// only add the alarm that is valid // Only restore the alarm that's not yet expired; otherwise,
let nowTime = Date.now(); // fire a system message for it and remove it from database.
aAlarms.forEach(function addAlarm(aAlarm) { aAlarms.forEach(function addAlarm(aAlarm) {
if (this._getAlarmTime(aAlarm) > nowTime) if (this._getAlarmTime(aAlarm) > Date.now()) {
alarmQueue.push(aAlarm); alarmQueue.push(aAlarm);
} else {
this._fireSystemMessage(aAlarm);
this._removeAlarmFromDb(aAlarm.id, null);
}
}.bind(this)); }.bind(this));
// set the next alarm from queue // set the next alarm from queue
@ -329,7 +333,7 @@ let AlarmService = {
_getAlarmTime: function _getAlarmTime(aAlarm) { _getAlarmTime: function _getAlarmTime(aAlarm) {
let alarmTime = (new Date(aAlarm.date)).getTime(); let alarmTime = (new Date(aAlarm.date)).getTime();
// For an alarm specified with "ignoreTimezone", // For an alarm specified with "ignoreTimezone",
// it must be fired respect to the user's timezone. // it must be fired respect to the user's timezone.
// Supposing an alarm was set at 7:00pm at Tokyo, // Supposing an alarm was set at 7:00pm at Tokyo,

View File

@ -56,6 +56,7 @@
#include "nsIDOMGlobalPropertyInitializer.h" #include "nsIDOMGlobalPropertyInitializer.h"
using namespace mozilla::dom::power; using namespace mozilla::dom::power;
using namespace mozilla::dom::sms;
// This should not be in the namespace. // This should not be in the namespace.
DOMCI_DATA(Navigator, mozilla::dom::Navigator) DOMCI_DATA(Navigator, mozilla::dom::Navigator)
@ -1064,61 +1065,6 @@ Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLoc
// Navigator::nsIDOMNavigatorSms // Navigator::nsIDOMNavigatorSms
//***************************************************************************** //*****************************************************************************
bool
Navigator::IsSmsAllowed() const
{
static const bool defaultSmsPermission = false;
// First of all, the general pref has to be turned on.
if (!Preferences::GetBool("dom.sms.enabled", defaultSmsPermission)) {
return false;
}
// In addition of having 'dom.sms.enabled' set to true, we require the
// website to be whitelisted. This is a temporary 'security model'.
// 'dom.sms.whitelist' has to contain comma-separated values of URI prepath.
// For local files, "file://" must be listed.
// For data-urls: "moz-nullprincipal:".
// Chrome files also have to be whitelisted for the moment.
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetDocShell()) {
return defaultSmsPermission;
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
if (!doc) {
return defaultSmsPermission;
}
nsCOMPtr<nsIURI> uri;
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
if (!uri) {
return defaultSmsPermission;
}
nsCAutoString uriPrePath;
uri->GetPrePath(uriPrePath);
const nsAdoptingString& whitelist =
Preferences::GetString("dom.sms.whitelist");
nsCharSeparatedTokenizer tokenizer(whitelist, ',',
nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
while (tokenizer.hasMoreTokens()) {
const nsSubstring& whitelistItem = tokenizer.nextToken();
if (NS_ConvertUTF16toUTF8(whitelistItem).Equals(uriPrePath)) {
return true;
}
}
// The current page hasn't been whitelisted.
return false;
}
bool bool
Navigator::IsSmsSupported() const Navigator::IsSmsSupported() const
{ {
@ -1141,15 +1087,15 @@ Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
*aSmsManager = nullptr; *aSmsManager = nullptr;
if (!mSmsManager) { if (!mSmsManager) {
if (!IsSmsSupported() || !IsSmsAllowed()) { if (!IsSmsSupported()) {
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow); nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK); NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
mSmsManager = new sms::SmsManager(); mSmsManager = SmsManager::CheckPermissionAndCreateInstance(window);
mSmsManager->Init(window); NS_ENSURE_TRUE(mSmsManager, NS_OK);
} }
NS_ADDREF(*aSmsManager = mSmsManager); NS_ADDREF(*aSmsManager = mSmsManager);

View File

@ -142,7 +142,6 @@ public:
NS_DECL_NSIDOMNAVIGATORCAMERA NS_DECL_NSIDOMNAVIGATORCAMERA
private: private:
bool IsSmsAllowed() const;
bool IsSmsSupported() const; bool IsSmsSupported() const;
nsRefPtr<nsMimeTypeArray> mMimeTypes; nsRefPtr<nsMimeTypeArray> mMimeTypes;

View File

@ -518,7 +518,6 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "BluetoothAdapter.h" #include "BluetoothAdapter.h"
#include "BluetoothDevice.h" #include "BluetoothDevice.h"
#include "BluetoothPropertyEvent.h" #include "BluetoothPropertyEvent.h"
#include "BluetoothPairingEvent.h"
#endif #endif
#include "nsIDOMNavigatorSystemMessages.h" #include "nsIDOMNavigatorSystemMessages.h"
@ -1679,8 +1678,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
EVENTTARGET_SCRIPTABLE_FLAGS) EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(BluetoothPropertyEvent, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(BluetoothPropertyEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(BluetoothPairingEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#endif #endif
NS_DEFINE_CLASSINFO_DATA(CameraManager, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(CameraManager, nsDOMGenericSH,
@ -4475,12 +4472,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothPropertyEvent) DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothPropertyEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent) DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(BluetoothPairingEvent, nsIDOMBluetoothPairingEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothPairingEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
#endif #endif
DOM_CLASSINFO_MAP_BEGIN(CameraManager, nsIDOMCameraManager) DOM_CLASSINFO_MAP_BEGIN(CameraManager, nsIDOMCameraManager)

View File

@ -524,7 +524,6 @@ DOMCI_CLASS(BluetoothManager)
DOMCI_CLASS(BluetoothAdapter) DOMCI_CLASS(BluetoothAdapter)
DOMCI_CLASS(BluetoothDevice) DOMCI_CLASS(BluetoothDevice)
DOMCI_CLASS(BluetoothPropertyEvent) DOMCI_CLASS(BluetoothPropertyEvent)
DOMCI_CLASS(BluetoothPairingEvent)
#endif #endif
DOMCI_CLASS(CameraManager) DOMCI_CLASS(CameraManager)

View File

@ -328,12 +328,6 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
nsRect lastDisplayPort;
if (nsLayoutUtils::GetDisplayPort(content, &lastDisplayPort) &&
displayport.IsEqualInterior(lastDisplayPort)) {
return NS_OK;
}
content->SetProperty(nsGkAtoms::DisplayPort, new nsRect(displayport), content->SetProperty(nsGkAtoms::DisplayPort, new nsRect(displayport),
DestroyNsRect); DestroyNsRect);

View File

@ -2973,9 +2973,7 @@ nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
return NS_OK; return NS_OK;
} }
bool isContentBoundary = false; if (mDocShell->GetIsContentBoundary()) {
mDocShell->GetIsContentBoundary(&isContentBoundary);
if (isContentBoundary) {
nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this); nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
parent.swap(*aParent); parent.swap(*aParent);
return NS_OK; return NS_OK;
@ -3082,12 +3080,8 @@ nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
// If we're contained in <iframe mozbrowser>, then GetContent is the same as // If we're contained in <iframe mozbrowser>, then GetContent is the same as
// window.top. // window.top.
if (mDocShell) { if (mDocShell && mDocShell->GetIsBelowContentBoundary()) {
bool belowContentBoundary = false; return GetScriptableTop(aContent);
mDocShell->GetIsBelowContentBoundary(&belowContentBoundary);
if (belowContentBoundary) {
return GetScriptableTop(aContent);
}
} }
nsCOMPtr<nsIDocShellTreeItem> primaryContent; nsCOMPtr<nsIDocShellTreeItem> primaryContent;
@ -6490,13 +6484,8 @@ nsGlobalWindow::Close()
{ {
FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED); FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
bool isContentBoundary = false; if (!mDocShell || IsInModalState() ||
if (mDocShell) { (IsFrame() && !mDocShell->GetIsContentBoundary())) {
mDocShell->GetIsContentBoundary(&isContentBoundary);
}
if ((!isContentBoundary && IsFrame()) ||
!mDocShell || IsInModalState()) {
// window.close() is called on a frame in a frameset, on a window // window.close() is called on a frame in a frameset, on a window
// that's already closed, or on a window for which there's // that's already closed, or on a window for which there's
// currently a modal dialog open. Ignore such calls. // currently a modal dialog open. Ignore such calls.
@ -7021,13 +7010,7 @@ nsGlobalWindow::GetScriptableFrameElement(nsIDOMElement** aFrameElement)
FORWARD_TO_OUTER(GetScriptableFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED); FORWARD_TO_OUTER(GetScriptableFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
*aFrameElement = NULL; *aFrameElement = NULL;
if (!mDocShell) { if (!mDocShell || mDocShell->GetIsContentBoundary()) {
return NS_OK;
}
bool isContentBoundary = false;
mDocShell->GetIsContentBoundary(&isContentBoundary);
if (isContentBoundary) {
return NS_OK; return NS_OK;
} }

View File

@ -147,6 +147,7 @@ static bool sCCLockedOut;
static PRTime sCCLockedOutTime; static PRTime sCCLockedOutTime;
static js::GCSliceCallback sPrevGCSliceCallback; static js::GCSliceCallback sPrevGCSliceCallback;
static js::AnalysisPurgeCallback sPrevAnalysisPurgeCallback;
// The number of currently pending document loads. This count isn't // The number of currently pending document loads. This count isn't
// guaranteed to always reflect reality and can't easily as we don't // guaranteed to always reflect reality and can't easily as we don't
@ -199,6 +200,17 @@ static nsIScriptSecurityManager *sSecurityManager;
static bool sGCOnMemoryPressure; static bool sGCOnMemoryPressure;
static PRTime
GetCollectionTimeDelta()
{
PRTime now = PR_Now();
if (sFirstCollectionTime) {
return now - sFirstCollectionTime;
}
sFirstCollectionTime = now;
return 0;
}
class nsMemoryPressureObserver MOZ_FINAL : public nsIObserver class nsMemoryPressureObserver MOZ_FINAL : public nsIObserver
{ {
public: public:
@ -3117,12 +3129,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX, Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC); sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
PRTime delta = 0; PRTime delta = GetCollectionTimeDelta();
if (sFirstCollectionTime) {
delta = now - sFirstCollectionTime;
} else {
sFirstCollectionTime = now;
}
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1; uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
uint32_t minForgetSkippableTime = (sMinForgetSkippableTime == PR_UINT32_MAX) uint32_t minForgetSkippableTime = (sMinForgetSkippableTime == PR_UINT32_MAX)
@ -3508,13 +3515,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread"); NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
if (aProgress == js::GC_CYCLE_END) { if (aProgress == js::GC_CYCLE_END) {
PRTime now = PR_Now(); PRTime delta = GetCollectionTimeDelta();
PRTime delta = 0;
if (sFirstCollectionTime) {
delta = now - sFirstCollectionTime;
} else {
sFirstCollectionTime = now;
}
if (sPostGCEventsToConsole) { if (sPostGCEventsToConsole) {
NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) "); NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) ");
@ -3531,7 +3532,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
if (sPostGCEventsToConsole || sPostGCEventsToObserver) { if (sPostGCEventsToConsole || sPostGCEventsToObserver) {
nsString json; nsString json;
json.Adopt(aDesc.formatJSON(aRt, now)); json.Adopt(aDesc.formatJSON(aRt, PR_Now()));
nsRefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json); nsRefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
NS_DispatchToMainThread(notify); NS_DispatchToMainThread(notify);
} }
@ -3588,6 +3589,32 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
(*sPrevGCSliceCallback)(aRt, aProgress, aDesc); (*sPrevGCSliceCallback)(aRt, aProgress, aDesc);
} }
static void
DOMAnalysisPurgeCallback(JSRuntime *aRt, JSFlatString *aDesc)
{
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
PRTime delta = GetCollectionTimeDelta();
if (sPostGCEventsToConsole) {
NS_NAMED_LITERAL_STRING(kFmt, "Analysis Purge (T+%.1f) ");
nsString prefix;
prefix.Adopt(nsTextFormatter::smprintf(kFmt.get(),
double(delta) / PR_USEC_PER_SEC));
nsDependentJSString stats(aDesc);
nsString msg = prefix + stats;
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(msg.get());
}
}
if (sPrevAnalysisPurgeCallback)
(*sPrevAnalysisPurgeCallback)(aRt, aDesc);
}
// Script object mananagement - note duplicate implementation // Script object mananagement - note duplicate implementation
// in nsJSRuntime below... // in nsJSRuntime below...
nsresult nsresult
@ -4004,6 +4031,7 @@ nsJSRuntime::Init()
NS_ASSERTION(NS_IsMainThread(), "bad"); NS_ASSERTION(NS_IsMainThread(), "bad");
sPrevGCSliceCallback = js::SetGCSliceCallback(sRuntime, DOMGCSliceCallback); sPrevGCSliceCallback = js::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
sPrevAnalysisPurgeCallback = js::SetAnalysisPurgeCallback(sRuntime, DOMAnalysisPurgeCallback);
// Set up the structured clone callbacks. // Set up the structured clone callbacks.
static JSStructuredCloneCallbacks cloneCallbacks = { static JSStructuredCloneCallbacks cloneCallbacks = {
@ -4098,6 +4126,12 @@ nsJSRuntime::Init()
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_high_limit_mb", SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_high_limit_mb",
(void *)JSGC_HIGH_FREQUENCY_HIGH_LIMIT); (void *)JSGC_HIGH_FREQUENCY_HIGH_LIMIT);
Preferences::RegisterCallback(SetMemoryGCPrefChangedCallback,
"javascript.options.mem.analysis_purge_mb",
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
SetMemoryGCPrefChangedCallback("javascript.options.mem.analysis_purge_mb",
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) if (!obs)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

View File

@ -60,6 +60,11 @@ MOCHITEST_FILES := \
test_forOf.html \ test_forOf.html \
forOf_iframe.html \ forOf_iframe.html \
test_sequence_wrapping.html \ test_sequence_wrapping.html \
file_bug775543.html \
$(NULL)
MOCHITEST_CHROME_FILES = \
test_bug775543.html \
$(NULL) $(NULL)
# Include rules.mk before any of our targets so our first target is coming from # Include rules.mk before any of our targets so our first target is coming from

View File

@ -0,0 +1,5 @@
<body>
<script>
worker = new Worker("a");
</script>
</body>

View File

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=775543
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 775543</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775543">Mozilla Bug 775543</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_bug775543.html" onload="test();"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 775543 **/
function test()
{
var a = XPCNativeWrapper(document.getElementById("t").contentWindow.wrappedJSObject.worker);
isnot(XPCNativeWrapper.unwrap(a), a, "XPCNativeWrapper(Worker) should be an Xray wrapper");
a.toString();
ok(true, "Shouldn't crash when calling a method on an Xray wrapper around a worker");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -8,21 +8,22 @@
#include "BluetoothAdapter.h" #include "BluetoothAdapter.h"
#include "BluetoothDevice.h" #include "BluetoothDevice.h"
#include "BluetoothPropertyEvent.h" #include "BluetoothPropertyEvent.h"
#include "BluetoothPairingEvent.h"
#include "BluetoothService.h" #include "BluetoothService.h"
#include "BluetoothTypes.h" #include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h" #include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h" #include "BluetoothUtils.h"
#include "GeneratedEvents.h" #include "GeneratedEvents.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h" #include "nsDOMClassInfo.h"
#include "nsDOMEvent.h" #include "nsDOMEvent.h"
#include "nsThreadUtils.h" #include "nsIDOMBluetoothAuthorizeEvent.h"
#include "nsXPCOMCIDInternal.h"
#include "nsIDOMDOMRequest.h"
#include "nsIDOMBluetoothDeviceEvent.h" #include "nsIDOMBluetoothDeviceEvent.h"
#include "nsIDOMBluetoothDeviceAddressEvent.h" #include "nsIDOMBluetoothDeviceAddressEvent.h"
#include "nsContentUtils.h" #include "nsIDOMBluetoothPairingEvent.h"
#include "nsIDOMDOMRequest.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "mozilla/LazyIdleThread.h" #include "mozilla/LazyIdleThread.h"
#include "mozilla/Util.h" #include "mozilla/Util.h"
@ -322,66 +323,100 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
} else if (aData.name().EqualsLiteral("PropertyChanged")) { } else if (aData.name().EqualsLiteral("PropertyChanged")) {
// Get BluetoothNamedValue, make sure array length is 1 // Get BluetoothNamedValue, make sure array length is 1
arr = aData.value().get_ArrayOfBluetoothNamedValue(); arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 1) {
// This really should not happen NS_ASSERTION(arr.Length() == 1, "Got more than one property in a change message!");
NS_ERROR("Got more than one property in a change message!"); NS_ASSERTION(arr[0].value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
return; "PropertyChanged: Invalid value type");
}
BluetoothNamedValue v = arr[0]; BluetoothNamedValue v = arr[0];
SetPropertyByValue(v); SetPropertyByValue(v);
nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name()); nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged")); e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
} else if (aData.name().EqualsLiteral("RequestConfirmation")) { } else if (aData.name().EqualsLiteral("RequestConfirmation")) {
arr = aData.value().get_ArrayOfBluetoothNamedValue(); arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 2) {
NS_ERROR("RequestConfirmation: Length of parameters is wrong");
return;
}
nsString deviceAddress = arr[0].value().get_nsString(); NS_ASSERTION(arr.Length() == 2, "RequestConfirmation: Wrong length of parameters");
uint32_t passkey = arr[1].value().get_uint32_t(); NS_ASSERTION(arr[0].value().type() == BluetoothValue::TnsString,
"RequestConfirmation: Invalid value type");
NS_ASSERTION(arr[1].value().type() == BluetoothValue::Tuint32_t,
"RequestConfirmation: Invalid value type");
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, passkey); nsCOMPtr<nsIDOMEvent> event;
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestconfirmation")); NS_NewDOMBluetoothPairingEvent(getter_AddRefs(event), nullptr, nullptr);
nsCOMPtr<nsIDOMBluetoothPairingEvent> e = do_QueryInterface(event);
e->InitBluetoothPairingEvent(NS_LITERAL_STRING("requestconfirmation"),
false,
false,
arr[0].value().get_nsString(),
arr[1].value().get_uint32_t());
e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else if (aData.name().EqualsLiteral("RequestPinCode")) { } else if (aData.name().EqualsLiteral("RequestPinCode")) {
arr = aData.value().get_ArrayOfBluetoothNamedValue(); arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 1) {
NS_ERROR("RequestPinCode: Length of parameters is wrong");
return;
}
nsString deviceAddress = arr[0].value().get_nsString(); NS_ASSERTION(arr.Length() == 1, "RequestPinCode: Wrong length of parameters");
NS_ASSERTION(arr[0].value().type() == BluetoothValue::TnsString,
"RequestPinCode: Invalid value type");
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, 0); nsCOMPtr<nsIDOMEvent> event;
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpincode")); NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
nsCOMPtr<nsIDOMBluetoothDeviceAddressEvent> e = do_QueryInterface(event);
e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("requestpincode"),
false, false, arr[0].value().get_nsString());
e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else if (aData.name().EqualsLiteral("RequestPasskey")) { } else if (aData.name().EqualsLiteral("RequestPasskey")) {
arr = aData.value().get_ArrayOfBluetoothNamedValue(); arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 1) {
NS_ERROR("RequestPasskey: Length of parameters is wrong");
return;
}
nsString deviceAddress = arr[0].value().get_nsString(); NS_ASSERTION(arr.Length() == 1, "RequestPasskey: Wrong length of parameters");
NS_ASSERTION(arr[0].value().type() == BluetoothValue::TnsString,
"RequestPasskey: Invalid value type");
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, 0); nsCOMPtr<nsIDOMEvent> event;
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpasskey")); NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
nsCOMPtr<nsIDOMBluetoothDeviceAddressEvent> e = do_QueryInterface(event);
e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("requestpasskey"),
false, false, arr[0].value().get_nsString());
e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else if (aData.name().EqualsLiteral("Authorize")) { } else if (aData.name().EqualsLiteral("Authorize")) {
arr = aData.value().get_ArrayOfBluetoothNamedValue(); arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 2) {
NS_ERROR("Authorize: Length of parameters is wrong");
return;
}
nsString deviceAddress = arr[0].value().get_nsString(); NS_ASSERTION(arr.Length() == 2, "Authorize: Wrong length of parameters");
nsString serviceUuid = arr[1].value().get_nsString(); NS_ASSERTION(arr[0].value().type() == BluetoothValue::TnsString,
"Authorize: Invalid value type");
NS_ASSERTION(arr[1].value().type() == BluetoothValue::TnsString,
"Authorize: Invalid value type");
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, serviceUuid); nsCOMPtr<nsIDOMEvent> event;
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("authorize")); NS_NewDOMBluetoothAuthorizeEvent(getter_AddRefs(event), nullptr, nullptr);
nsCOMPtr<nsIDOMBluetoothAuthorizeEvent> e = do_QueryInterface(event);
e->InitBluetoothAuthorizeEvent(NS_LITERAL_STRING("authorize"),
false,
false,
arr[0].value().get_nsString(),
arr[1].value().get_nsString());
e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else if (aData.name().EqualsLiteral("Cancel")) { } else if (aData.name().EqualsLiteral("Cancel")) {
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMBluetoothDeviceAddressEvent(getter_AddRefs(event), nullptr, nullptr);
nsCOMPtr<nsIDOMBluetoothDeviceAddressEvent> e = do_QueryInterface(event);
// Just send a null nsString, won't be used // Just send a null nsString, won't be used
nsString deviceObjectPath = EmptyString(); e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("cancel"),
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceObjectPath, 0); false, false, EmptyString());
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("cancel")); e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else { } else {
#ifdef DEBUG #ifdef DEBUG
nsCString warningMsg; nsCString warningMsg;

View File

@ -33,7 +33,6 @@ CPPSRCS += \
BluetoothAdapter.cpp \ BluetoothAdapter.cpp \
BluetoothDevice.cpp \ BluetoothDevice.cpp \
BluetoothPropertyEvent.cpp \ BluetoothPropertyEvent.cpp \
BluetoothPairingEvent.cpp \
BluetoothReplyRunnable.cpp \ BluetoothReplyRunnable.cpp \
BluetoothPropertyContainer.cpp \ BluetoothPropertyContainer.cpp \
BluetoothUtils.cpp \ BluetoothUtils.cpp \
@ -48,6 +47,7 @@ XPIDLSRCS = \
nsIDOMBluetoothDeviceAddressEvent.idl \ nsIDOMBluetoothDeviceAddressEvent.idl \
nsIDOMBluetoothPropertyEvent.idl \ nsIDOMBluetoothPropertyEvent.idl \
nsIDOMBluetoothPairingEvent.idl \ nsIDOMBluetoothPairingEvent.idl \
nsIDOMBluetoothAuthorizeEvent.idl \
$(NULL) $(NULL)
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))

View File

@ -0,0 +1,26 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#include "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(1cfe7854-31a6-4a41-add6-b4ed35869a6d)]
interface nsIDOMBluetoothAuthorizeEvent : nsIDOMEvent
{
readonly attribute DOMString deviceAddress;
readonly attribute DOMString uuid;
[noscript] void initBluetoothAuthorizeEvent(in DOMString aType,
in boolean aCanBubble,
in boolean aCancelable,
in DOMString aDeviceAddress,
in DOMString aUuid);
};
dictionary BluetoothAuthorizeEventInit : EventInit
{
DOMString deviceAddress;
DOMString uuid;
};

View File

@ -6,10 +6,21 @@
#include "nsIDOMEvent.idl" #include "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(b905b05e-2141-444c-a90d-525b6c0daff1)] [scriptable, builtinclass, uuid(333022b8-a7e5-4fff-8588-36f2eedff17e)]
interface nsIDOMBluetoothPairingEvent : nsIDOMEvent interface nsIDOMBluetoothPairingEvent : nsIDOMEvent
{ {
readonly attribute DOMString deviceAddress; readonly attribute DOMString deviceAddress;
readonly attribute DOMString uuid;
readonly attribute unsigned long passkey; readonly attribute unsigned long passkey;
[noscript] void initBluetoothPairingEvent(in DOMString aType,
in boolean aCanBubble,
in boolean aCancelable,
in DOMString aDeviceAddress,
in unsigned long aPasskey);
};
dictionary BluetoothPairingEventInit : EventInit
{
DOMString deviceAddress;
unsigned long passkey;
}; };

View File

@ -4,12 +4,8 @@
"use strict"; "use strict";
/* static functions */ const DEBUG = false;
let DEBUG = 0; function debug(s) { dump("-*- ContactManager: " + s + "\n"); }
if (DEBUG)
debug = function (s) { dump("-*- ContactManager: " + s + "\n"); }
else
debug = function (s) {}
const Cc = Components.classes; const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
@ -37,7 +33,7 @@ const nsIDOMContactProperties = Ci.nsIDOMContactProperties;
// ContactProperties is not directly instantiated. It is used as interface. // ContactProperties is not directly instantiated. It is used as interface.
function ContactProperties(aProp) { debug("ContactProperties Constructor"); } function ContactProperties(aProp) { if (DEBUG) debug("ContactProperties Constructor"); }
ContactProperties.prototype = { ContactProperties.prototype = {
@ -67,6 +63,14 @@ function ContactAddress(aType, aStreetAddress, aLocality, aRegion, aPostalCode,
}; };
ContactAddress.prototype = { ContactAddress.prototype = {
__exposedProps__: {
type: 'rw',
streetAddress: 'rw',
locality: 'rw',
region: 'rw',
postalCode: 'rw',
countryName: 'rw'
},
classID : CONTACTADDRESS_CID, classID : CONTACTADDRESS_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID, classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
@ -90,6 +94,10 @@ function ContactField(aType, aValue) {
}; };
ContactField.prototype = { ContactField.prototype = {
__exposedProps__: {
type: 'rw',
value: 'rw'
},
classID : CONTACTFIELD_CID, classID : CONTACTFIELD_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTFIELD_CID, classInfo : XPCOMUtils.generateCI({classID: CONTACTFIELD_CID,
@ -114,6 +122,11 @@ function ContactTelField(aType, aValue, aCarrier) {
}; };
ContactTelField.prototype = { ContactTelField.prototype = {
__exposedProps__: {
type: 'rw',
value: 'rw',
carrier: 'rw'
},
classID : CONTACTTELFIELD_CID, classID : CONTACTTELFIELD_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTTELFIELD_CID, classInfo : XPCOMUtils.generateCI({classID: CONTACTTELFIELD_CID,
@ -151,13 +164,38 @@ const CONTACT_CONTRACTID = "@mozilla.org/contact;1";
const CONTACT_CID = Components.ID("{da0f7040-388b-11e1-b86c-0800200c9a66}"); const CONTACT_CID = Components.ID("{da0f7040-388b-11e1-b86c-0800200c9a66}");
const nsIDOMContact = Components.interfaces.nsIDOMContact; const nsIDOMContact = Components.interfaces.nsIDOMContact;
// The wrappedJSObject magic here allows callers to get at the underlying JS object function Contact() {
// of the XPCOM component. We use this below to modify properties that are read-only if (DEBUG) debug("Contact constr: ");
// per-idl. See https://developer.mozilla.org/en-US/docs/wrappedJSObject. };
function Contact() { debug("Contact constr: "); this.wrappedJSObject = this; };
Contact.prototype = { Contact.prototype = {
__exposedProps__: {
id: 'rw',
updated: 'rw',
published: 'rw',
name: 'rw',
honorificPrefix: 'rw',
givenName: 'rw',
additionalName: 'rw',
familyName: 'rw',
honorificSuffix: 'rw',
nickname: 'rw',
email: 'rw',
photo: 'rw',
url: 'rw',
category: 'rw',
adr: 'rw',
tel: 'rw',
org: 'rw',
jobTitle: 'rw',
bday: 'rw',
note: 'rw',
impp: 'rw',
anniversary: 'rw',
sex: 'rw',
genderIdentity: 'rw'
},
init: function init(aProp) { init: function init(aProp) {
// Accept non-array strings for DOMString[] properties and convert them. // Accept non-array strings for DOMString[] properties and convert them.
function _create(aField) { function _create(aField) {
@ -290,7 +328,7 @@ const nsIDOMContactManager = Components.interfaces.nsIDOMContactManager;
function ContactManager() function ContactManager()
{ {
debug("Constructor"); if (DEBUG) debug("Constructor");
} }
ContactManager.prototype = { ContactManager.prototype = {
@ -298,7 +336,7 @@ ContactManager.prototype = {
_oncontactchange: null, _oncontactchange: null,
set oncontactchange(aCallback) { set oncontactchange(aCallback) {
debug("set oncontactchange"); if (DEBUG) debug("set oncontactchange");
let allowCallback = function() { let allowCallback = function() {
this._oncontactchange = aCallback; this._oncontactchange = aCallback;
}.bind(this); }.bind(this);
@ -321,16 +359,16 @@ ContactManager.prototype = {
_convertContactsArray: function(aContacts) { _convertContactsArray: function(aContacts) {
let contacts = new Array(); let contacts = new Array();
for (let i in aContacts) { for (let i in aContacts) {
let newContact = Components.classes['@mozilla.org/contact;1'].createInstance(); let newContact = new Contact();
newContact.init(aContacts[i].properties); newContact.init(aContacts[i].properties);
this._setMetaData(newContact.wrappedJSObject, aContacts[i]); this._setMetaData(newContact, aContacts[i]);
contacts.push(newContact); contacts.push(newContact);
} }
return contacts; return contacts;
}, },
receiveMessage: function(aMessage) { receiveMessage: function(aMessage) {
debug("Contactmanager::receiveMessage: " + aMessage.name); if (DEBUG) debug("Contactmanager::receiveMessage: " + aMessage.name);
let msg = aMessage.json; let msg = aMessage.json;
let contacts = msg.contacts; let contacts = msg.contacts;
@ -339,10 +377,9 @@ ContactManager.prototype = {
let req = this.getRequest(msg.requestID); let req = this.getRequest(msg.requestID);
if (req) { if (req) {
let result = this._convertContactsArray(contacts); let result = this._convertContactsArray(contacts);
debug("result: " + JSON.stringify(result));
Services.DOMRequest.fireSuccess(req.request, result); Services.DOMRequest.fireSuccess(req.request, result);
} else { } else {
debug("no request stored!" + msg.requestID); if (DEBUG) debug("no request stored!" + msg.requestID);
} }
break; break;
case "Contact:Save:Return:OK": case "Contact:Save:Return:OK":
@ -370,7 +407,7 @@ ContactManager.prototype = {
Services.DOMRequest.fireError(req.request, msg.errorMsg); Services.DOMRequest.fireError(req.request, msg.errorMsg);
break; break;
case "PermissionPromptHelper:AskPermission:OK": case "PermissionPromptHelper:AskPermission:OK":
debug("id: " + msg.requestID); if (DEBUG) debug("id: " + msg.requestID);
req = this.getRequest(msg.requestID); req = this.getRequest(msg.requestID);
if (!req) { if (!req) {
break; break;
@ -383,13 +420,13 @@ ContactManager.prototype = {
} }
break; break;
default: default:
debug("Wrong message: " + aMessage.name); if (DEBUG) debug("Wrong message: " + aMessage.name);
} }
this.removeRequest(msg.requestID); this.removeRequest(msg.requestID);
}, },
askPermission: function (aAccess, aReqeust, aAllowCallback, aCancelCallback) { askPermission: function (aAccess, aReqeust, aAllowCallback, aCancelCallback) {
debug("askPermission for contacts"); if (DEBUG) debug("askPermission for contacts");
let requestID = this.getRequestId({ let requestID = this.getRequestId({
request: aReqeust, request: aReqeust,
allow: function() { allow: function() {
@ -417,7 +454,7 @@ ContactManager.prototype = {
save: function save(aContact) { save: function save(aContact) {
let request; let request;
debug("save: " + JSON.stringify(aContact) + " :" + aContact.id); if (DEBUG) debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
let newContact = {}; let newContact = {};
newContact.properties = { newContact.properties = {
name: [], name: [],
@ -457,7 +494,7 @@ ContactManager.prototype = {
} }
this._setMetaData(newContact, aContact); this._setMetaData(newContact, aContact);
debug("send: " + JSON.stringify(newContact)); if (DEBUG) debug("send: " + JSON.stringify(newContact));
request = this.createRequest(); request = this.createRequest();
let options = { contact: newContact }; let options = { contact: newContact };
let allowCallback = function() { let allowCallback = function() {
@ -468,7 +505,7 @@ ContactManager.prototype = {
}, },
find: function(aOptions) { find: function(aOptions) {
debug("find! " + JSON.stringify(aOptions)); if (DEBUG) debug("find! " + JSON.stringify(aOptions));
let request; let request;
request = this.createRequest(); request = this.createRequest();
let options = { findOptions: aOptions }; let options = { findOptions: aOptions };
@ -491,7 +528,7 @@ ContactManager.prototype = {
}, },
clear: function() { clear: function() {
debug("clear"); if (DEBUG) debug("clear");
let request; let request;
request = this.createRequest(); request = this.createRequest();
let options = {}; let options = {};
@ -508,16 +545,16 @@ ContactManager.prototype = {
let allowCallback = function() { let allowCallback = function() {
let callback = function(aType, aContacts) { let callback = function(aType, aContacts) {
debug("got SIM contacts: " + aType + " " + JSON.stringify(aContacts)); if (DEBUG) debug("got SIM contacts: " + aType + " " + JSON.stringify(aContacts));
let result = aContacts.map(function(c) { let result = aContacts.map(function(c) {
var contact = new Contact(); var contact = new Contact();
contact.init( { name: [c.alphaId], tel: [ { number: c.number } ] } ); contact.init( { name: [c.alphaId], tel: [ { number: c.number } ] } );
return contact; return contact;
}); });
debug("result: " + JSON.stringify(result)); if (DEBUG) debug("result: " + JSON.stringify(result));
Services.DOMRequest.fireSuccess(request, result); Services.DOMRequest.fireSuccess(request, result);
}; };
debug("getSimContacts " + aType); if (DEBUG) debug("getSimContacts " + aType);
mRIL.getICCContacts(aType, callback); mRIL.getICCContacts(aType, callback);
}.bind(this); }.bind(this);
@ -543,7 +580,7 @@ ContactManager.prototype = {
// Called from DOMRequestIpcHelper // Called from DOMRequestIpcHelper
uninit: function uninit() { uninit: function uninit() {
debug("uninit call"); if (DEBUG) debug("uninit call");
if (this._oncontactchange) if (this._oncontactchange)
this._oncontactchange = null; this._oncontactchange = null;
}, },

View File

@ -6,13 +6,8 @@
const EXPORTED_SYMBOLS = ['ContactDB']; const EXPORTED_SYMBOLS = ['ContactDB'];
let DEBUG = 0; const DEBUG = false;
/* static functions */ function debug(s) { dump("-*- ContactDB component: " + s + "\n"); }
if (DEBUG) {
debug = function (s) { dump("-*- ContactDB component: " + s + "\n"); }
} else {
debug = function (s) {}
}
const Cu = Components.utils; const Cu = Components.utils;
const Cc = Components.classes; const Cc = Components.classes;
@ -26,7 +21,7 @@ const DB_VERSION = 4;
const STORE_NAME = "contacts"; const STORE_NAME = "contacts";
function ContactDB(aGlobal) { function ContactDB(aGlobal) {
debug("Constructor"); if (DEBUG) debug("Constructor");
this._global = aGlobal; this._global = aGlobal;
} }
@ -34,7 +29,7 @@ ContactDB.prototype = {
__proto__: IndexedDBHelper.prototype, __proto__: IndexedDBHelper.prototype,
upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!"); if (DEBUG) debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!");
let db = aDb; let db = aDb;
let objectStore; let objectStore;
for (let currVersion = aOldVersion; currVersion < aNewVersion; currVersion++) { for (let currVersion = aOldVersion; currVersion < aNewVersion; currVersion++) {
@ -50,7 +45,7 @@ ContactDB.prototype = {
* properties: {...} // Object holding the ContactProperties * properties: {...} // Object holding the ContactProperties
* } * }
*/ */
debug("create schema"); if (DEBUG) debug("create schema");
objectStore = db.createObjectStore(this.dbStoreName, {keyPath: "id"}); objectStore = db.createObjectStore(this.dbStoreName, {keyPath: "id"});
// Metadata indexes // Metadata indexes
@ -74,7 +69,7 @@ ContactDB.prototype = {
objectStore.createIndex("emailLowerCase", "search.email", { unique: false, multiEntry: true }); objectStore.createIndex("emailLowerCase", "search.email", { unique: false, multiEntry: true });
objectStore.createIndex("noteLowerCase", "search.note", { unique: false, multiEntry: true }); objectStore.createIndex("noteLowerCase", "search.note", { unique: false, multiEntry: true });
} else if (currVersion == 1) { } else if (currVersion == 1) {
debug("upgrade 1"); if (DEBUG) debug("upgrade 1");
// Create a new scheme for the tel field. We move from an array of tel-numbers to an array of // Create a new scheme for the tel field. We move from an array of tel-numbers to an array of
// ContactTelephone. // ContactTelephone.
@ -88,12 +83,12 @@ ContactDB.prototype = {
objectStore.openCursor().onsuccess = function(event) { objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result; let cursor = event.target.result;
if (cursor) { if (cursor) {
debug("upgrade tel1: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade tel1: " + JSON.stringify(cursor.value));
for (let number in cursor.value.properties.tel) { for (let number in cursor.value.properties.tel) {
cursor.value.properties.tel[number] = {number: number}; cursor.value.properties.tel[number] = {number: number};
} }
cursor.update(cursor.value); cursor.update(cursor.value);
debug("upgrade tel2: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade tel2: " + JSON.stringify(cursor.value));
cursor.continue(); cursor.continue();
} }
}; };
@ -102,7 +97,7 @@ ContactDB.prototype = {
objectStore.createIndex("tel", "search.tel", { unique: false, multiEntry: true }); objectStore.createIndex("tel", "search.tel", { unique: false, multiEntry: true });
objectStore.createIndex("category", "properties.category", { unique: false, multiEntry: true }); objectStore.createIndex("category", "properties.category", { unique: false, multiEntry: true });
} else if (currVersion == 2) { } else if (currVersion == 2) {
debug("upgrade 2"); if (DEBUG) debug("upgrade 2");
// Create a new scheme for the email field. We move from an array of emailaddresses to an array of // Create a new scheme for the email field. We move from an array of emailaddresses to an array of
// ContactEmail. // ContactEmail.
if (!objectStore) { if (!objectStore) {
@ -115,11 +110,11 @@ ContactDB.prototype = {
objectStore.openCursor().onsuccess = function(event) { objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result; let cursor = event.target.result;
if (cursor) { if (cursor) {
debug("upgrade email1: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade email1: " + JSON.stringify(cursor.value));
cursor.value.properties.email = cursor.value.properties.email =
cursor.value.properties.email.map(function(address) { return { address: address }; }); cursor.value.properties.email.map(function(address) { return { address: address }; });
cursor.update(cursor.value); cursor.update(cursor.value);
debug("upgrade email2: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade email2: " + JSON.stringify(cursor.value));
cursor.continue(); cursor.continue();
} }
}; };
@ -127,7 +122,7 @@ ContactDB.prototype = {
// Create new searchable indexes. // Create new searchable indexes.
objectStore.createIndex("email", "search.email", { unique: false, multiEntry: true }); objectStore.createIndex("email", "search.email", { unique: false, multiEntry: true });
} else if (currVersion == 3) { } else if (currVersion == 3) {
debug("upgrade 3"); if (DEBUG) debug("upgrade 3");
if (!objectStore) { if (!objectStore) {
objectStore = aTransaction.objectStore(STORE_NAME); objectStore = aTransaction.objectStore(STORE_NAME);
@ -137,11 +132,11 @@ ContactDB.prototype = {
objectStore.openCursor().onsuccess = function(event) { objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result; let cursor = event.target.result;
if (cursor) { if (cursor) {
debug("upgrade impp1: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade impp1: " + JSON.stringify(cursor.value));
cursor.value.properties.impp = cursor.value.properties.impp =
cursor.value.properties.impp.map(function(value) { return { value: value }; }); cursor.value.properties.impp.map(function(value) { return { value: value }; });
cursor.update(cursor.value); cursor.update(cursor.value);
debug("upgrade impp2: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade impp2: " + JSON.stringify(cursor.value));
cursor.continue(); cursor.continue();
} }
}; };
@ -149,11 +144,11 @@ ContactDB.prototype = {
objectStore.openCursor().onsuccess = function(event) { objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result; let cursor = event.target.result;
if (cursor) { if (cursor) {
debug("upgrade url1: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade url1: " + JSON.stringify(cursor.value));
cursor.value.properties.url = cursor.value.properties.url =
cursor.value.properties.url.map(function(value) { return { value: value }; }); cursor.value.properties.url.map(function(value) { return { value: value }; });
cursor.update(cursor.value); cursor.update(cursor.value);
debug("upgrade impp2: " + JSON.stringify(cursor.value)); if (DEBUG) debug("upgrade impp2: " + JSON.stringify(cursor.value));
cursor.continue(); cursor.continue();
} }
}; };
@ -228,7 +223,7 @@ ContactDB.prototype = {
contact.search[field].push(digits.substring(i, digits.length)); contact.search[field].push(digits.substring(i, digits.length));
} }
} }
debug("lookup: " + JSON.stringify(contact.search[field])); if (DEBUG) debug("lookup: " + JSON.stringify(contact.search[field]));
} }
} else if (field == "email") { } else if (field == "email") {
let address = aContact.properties[field][i].value; let address = aContact.properties[field][i].value;
@ -250,7 +245,7 @@ ContactDB.prototype = {
} }
} }
} }
debug("contact:" + JSON.stringify(contact)); if (DEBUG) debug("contact:" + JSON.stringify(contact));
contact.updated = aContact.updated; contact.updated = aContact.updated;
contact.published = aContact.published; contact.published = aContact.published;
@ -285,24 +280,24 @@ ContactDB.prototype = {
saveContact: function saveContact(aContact, successCb, errorCb) { saveContact: function saveContact(aContact, successCb, errorCb) {
let contact = this.makeImport(aContact); let contact = this.makeImport(aContact);
this.newTxn("readwrite", function (txn, store) { this.newTxn("readwrite", function (txn, store) {
debug("Going to update" + JSON.stringify(contact)); if (DEBUG) debug("Going to update" + JSON.stringify(contact));
// Look up the existing record and compare the update timestamp. // Look up the existing record and compare the update timestamp.
// If no record exists, just add the new entry. // If no record exists, just add the new entry.
let newRequest = store.get(contact.id); let newRequest = store.get(contact.id);
newRequest.onsuccess = function (event) { newRequest.onsuccess = function (event) {
if (!event.target.result) { if (!event.target.result) {
debug("new record!") if (DEBUG) debug("new record!")
this.updateRecordMetadata(contact); this.updateRecordMetadata(contact);
store.put(contact); store.put(contact);
} else { } else {
debug("old record!") if (DEBUG) debug("old record!")
if (new Date(typeof contact.updated === "undefined" ? 0 : contact.updated) < new Date(event.target.result.updated)) { if (new Date(typeof contact.updated === "undefined" ? 0 : contact.updated) < new Date(event.target.result.updated)) {
debug("rev check fail!"); if (DEBUG) debug("rev check fail!");
txn.abort(); txn.abort();
return; return;
} else { } else {
debug("rev check OK"); if (DEBUG) debug("rev check OK");
contact.published = event.target.result.published; contact.published = event.target.result.published;
contact.updated = new Date(); contact.updated = new Date();
store.put(contact); store.put(contact);
@ -314,14 +309,14 @@ ContactDB.prototype = {
removeContact: function removeContact(aId, aSuccessCb, aErrorCb) { removeContact: function removeContact(aId, aSuccessCb, aErrorCb) {
this.newTxn("readwrite", function (txn, store) { this.newTxn("readwrite", function (txn, store) {
debug("Going to delete" + aId); if (DEBUG) debug("Going to delete" + aId);
store.delete(aId); store.delete(aId);
}, aSuccessCb, aErrorCb); }, aSuccessCb, aErrorCb);
}, },
clear: function clear(aSuccessCb, aErrorCb) { clear: function clear(aSuccessCb, aErrorCb) {
this.newTxn("readwrite", function (txn, store) { this.newTxn("readwrite", function (txn, store) {
debug("Going to clear all!"); if (DEBUG) debug("Going to clear all!");
store.clear(); store.clear();
}, aSuccessCb, aErrorCb); }, aSuccessCb, aErrorCb);
}, },
@ -339,7 +334,7 @@ ContactDB.prototype = {
* - count * - count
*/ */
find: function find(aSuccessCb, aFailureCb, aOptions) { find: function find(aSuccessCb, aFailureCb, aOptions) {
debug("ContactDB:find val:" + aOptions.filterValue + " by: " + aOptions.filterBy + " op: " + aOptions.filterOp + "\n"); if (DEBUG) debug("ContactDB:find val:" + aOptions.filterValue + " by: " + aOptions.filterBy + " op: " + aOptions.filterOp + "\n");
let self = this; let self = this;
this.newTxn("readonly", function (txn, store) { this.newTxn("readonly", function (txn, store) {
if (aOptions && (aOptions.filterOp == "equals" || aOptions.filterOp == "contains")) { if (aOptions && (aOptions.filterOp == "equals" || aOptions.filterOp == "contains")) {
@ -351,12 +346,12 @@ ContactDB.prototype = {
}, },
_findWithIndex: function _findWithIndex(txn, store, options) { _findWithIndex: function _findWithIndex(txn, store, options) {
debug("_findWithIndex: " + options.filterValue +" " + options.filterOp + " " + options.filterBy + " "); if (DEBUG) debug("_findWithIndex: " + options.filterValue +" " + options.filterOp + " " + options.filterBy + " ");
let fields = options.filterBy; let fields = options.filterBy;
for (let key in fields) { for (let key in fields) {
debug("key: " + fields[key]); if (DEBUG) debug("key: " + fields[key]);
if (!store.indexNames.contains(fields[key]) && !fields[key] == "id") { if (!store.indexNames.contains(fields[key]) && !fields[key] == "id") {
debug("Key not valid!" + fields[key] + ", " + store.indexNames); if (DEBUG) debug("Key not valid!" + fields[key] + ", " + store.indexNames);
txn.abort(); txn.abort();
return; return;
} }
@ -364,7 +359,7 @@ ContactDB.prototype = {
// lookup for all keys // lookup for all keys
if (options.filterBy.length == 0) { if (options.filterBy.length == 0) {
debug("search in all fields!" + JSON.stringify(store.indexNames)); if (DEBUG) debug("search in all fields!" + JSON.stringify(store.indexNames));
for(let myIndex = 0; myIndex < store.indexNames.length; myIndex++) { for(let myIndex = 0; myIndex < store.indexNames.length; myIndex++) {
fields = Array.concat(fields, store.indexNames[myIndex]) fields = Array.concat(fields, store.indexNames[myIndex])
} }
@ -383,7 +378,7 @@ ContactDB.prototype = {
let index = store.index(key); let index = store.index(key);
request = index.mozGetAll(options.filterValue, limit); request = index.mozGetAll(options.filterValue, limit);
} else if (options.filterOp == "equals") { } else if (options.filterOp == "equals") {
debug("Getting index: " + key); if (DEBUG) debug("Getting index: " + key);
// case sensitive // case sensitive
let index = store.index(key); let index = store.index(key);
request = index.mozGetAll(options.filterValue, limit); request = index.mozGetAll(options.filterValue, limit);
@ -400,7 +395,7 @@ ContactDB.prototype = {
txn.result = {}; txn.result = {};
request.onsuccess = function (event) { request.onsuccess = function (event) {
debug("Request successful. Record count:" + event.target.result.length); if (DEBUG) debug("Request successful. Record count:" + event.target.result.length);
for (let i in event.target.result) for (let i in event.target.result)
txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]); txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
}.bind(this); }.bind(this);
@ -408,13 +403,13 @@ ContactDB.prototype = {
}, },
_findAll: function _findAll(txn, store, options) { _findAll: function _findAll(txn, store, options) {
debug("ContactDB:_findAll: " + JSON.stringify(options)); if (DEBUG) debug("ContactDB:_findAll: " + JSON.stringify(options));
if (!txn.result) if (!txn.result)
txn.result = {}; txn.result = {};
// Sorting functions takes care of limit if set. // Sorting functions takes care of limit if set.
let limit = options.sortBy === 'undefined' ? options.filterLimit : null; let limit = options.sortBy === 'undefined' ? options.filterLimit : null;
store.mozGetAll(null, limit).onsuccess = function (event) { store.mozGetAll(null, limit).onsuccess = function (event) {
debug("Request successful. Record count:", event.target.result.length); if (DEBUG) debug("Request successful. Record count:", event.target.result.length);
for (let i in event.target.result) for (let i in event.target.result)
txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]); txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
}.bind(this); }.bind(this);

View File

@ -4,11 +4,8 @@
"use strict"; "use strict";
let DEBUG = 0; const DEBUG = false;
if (DEBUG) function debug(s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
debug = function (s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
else
debug = function (s) {}
const Cu = Components.utils; const Cu = Components.utils;
const Cc = Components.classes; const Cc = Components.classes;
@ -28,7 +25,7 @@ let myGlobal = this;
let DOMContactManager = { let DOMContactManager = {
init: function() { init: function() {
debug("Init"); if (DEBUG) debug("Init");
this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"]; this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
this._messages.forEach((function(msgName) { this._messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this); ppmm.addMessageListener(msgName, this);
@ -56,7 +53,7 @@ let DOMContactManager = {
}, },
receiveMessage: function(aMessage) { receiveMessage: function(aMessage) {
debug("Fallback DOMContactManager::receiveMessage " + aMessage.name); if (DEBUG) debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager); let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
let msg = aMessage.data; let msg = aMessage.data;
@ -112,14 +109,14 @@ let DOMContactManager = {
if (msg.options && msg.options.findOptions) { if (msg.options && msg.options.findOptions) {
let findOptions = msg.options.findOptions; let findOptions = msg.options.findOptions;
if (findOptions.sortOrder !== 'undefined' && findOptions.sortBy !== 'undefined') { if (findOptions.sortOrder !== 'undefined' && findOptions.sortBy !== 'undefined') {
debug('sortBy: ' + findOptions.sortBy + ', sortOrder: ' + findOptions.sortOrder ); if (DEBUG) debug('sortBy: ' + findOptions.sortBy + ', sortOrder: ' + findOptions.sortOrder );
result.sort(sortfunction); result.sort(sortfunction);
if (findOptions.filterLimit) if (findOptions.filterLimit)
result = result.slice(0, findOptions.filterLimit); result = result.slice(0, findOptions.filterLimit);
} }
} }
debug("result:" + JSON.stringify(result)); if (DEBUG) debug("result:" + JSON.stringify(result));
mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result}); mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
}.bind(this), }.bind(this),
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this), function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
@ -145,7 +142,7 @@ let DOMContactManager = {
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this) function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
); );
default: default:
debug("WRONG MESSAGE NAME: " + aMessage.name); if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);
} }
} }
} }

View File

@ -92,7 +92,7 @@ var properties2 = {
honorificSuffix: "dummyHonorificSuffix", honorificSuffix: "dummyHonorificSuffix",
additionalName: "dummyadditionalName", additionalName: "dummyadditionalName",
nickname: "dummyNickname", nickname: "dummyNickname",
tel: [{type: ["test"], value: "123456789"},{type: ["home", "custom"], value: "234567890"}], tel: [{type: ["test"], value: "123456789", carrier: "myCarrier"},{type: ["home", "custom"], value: "234567890"}],
email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d"}], email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d"}],
adr: [adr1, adr2], adr: [adr1, adr2],
impp: [{type: ["aim"], value:"im1"}, {value: "im2"}], impp: [{type: ["aim"], value:"im1"}, {value: "im2"}],
@ -154,8 +154,8 @@ function checkTel(tel1, tel2) {
} }
function checkField(field1, field2) { function checkField(field1, field2) {
checkStr(field1.type, field1.type, "Same type"); checkStr(field1.type, field2.type, "Same type");
checkStr(field1.value, field1.value, "Same value"); checkStr(field1.value, field2.value, "Same value");
} }
function checkContacts(contact1, contact2) { function checkContacts(contact1, contact2) {
@ -312,6 +312,20 @@ var steps = [
findResult1 = req.result[0]; findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID"); ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1); checkContacts(createResult1, properties1);
dump("findResult: " + JSON.stringify(findResult1) + "\n");
// Some manual testing. Testint the testfunctions
// tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
is(findResult1.tel[0].carrier, "testCarrier", "Same Carrier");
is(findResult1.tel[0].type, "work", "Same type");
is(findResult1.tel[0].value, "123456", "Same Value");
is(findResult1.tel[1].type[1], "fax", "Same type");
is(findResult1.tel[1].value, "+9-876-5432", "Same Value");
is(findResult1.adr[0].countryName, "country 1", "Same country");
// email: [{type: ["work"], value: "x@y.com"}]
is(findResult1.email[0].type, "work", "Same Type");
is(findResult1.email[0].value, "x@y.com", "Same Value");
next(); next();
}; };
req.onerror = onFailure; req.onerror = onFailure;

View File

@ -121,12 +121,17 @@ interface nsIDOMWindowUtils : nsISupports {
* *
* It's legal to set a displayport that extends beyond the overflow * It's legal to set a displayport that extends beyond the overflow
* area in any direction (left/right/top/bottom). * area in any direction (left/right/top/bottom).
* *
* It's also legal to set a displayport that extends beyond the * It's also legal to set a displayport that extends beyond the
* area's bounds. No pixels are rendered outside the area bounds. * area's bounds. No pixels are rendered outside the area bounds.
* *
* The caller of this method must have UniversalXPConnect * The caller of this method must have UniversalXPConnect
* privileges. * privileges.
*
* Calling this will always force a recomposite, so it should be
* avoided if at all possible. Client code should do checks before
* calling this so that duplicate sets are not made with the same
* displayport.
*/ */
void setDisplayPortForElement(in float aXPx, in float aYPx, void setDisplayPortForElement(in float aXPx, in float aYPx,
in float aWidthPx, in float aHeightPx, in float aWidthPx, in float aHeightPx,

View File

@ -757,16 +757,9 @@ ContentChild::AddRemoteAlertObserver(const nsString& aData,
} }
bool bool
ContentChild::RecvPreferenceUpdate(const PrefTuple& aPref) ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
{ {
Preferences::SetPreference(&aPref); Preferences::SetPreference(aPref);
return true;
}
bool
ContentChild::RecvClearUserPreference(const nsCString& aPrefName)
{
Preferences::ClearContentPref(aPrefName.get());
return true; return true;
} }

View File

@ -136,8 +136,7 @@ public:
// auto remove when alertfinished is received. // auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver); nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
virtual bool RecvPreferenceUpdate(const PrefTuple& aPref); virtual bool RecvPreferenceUpdate(const PrefSetting& aPref);
virtual bool RecvClearUserPreference(const nsCString& aPrefName);
virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData); virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);

View File

@ -732,9 +732,9 @@ ContentParent::IsForApp()
} }
bool bool
ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefTuple> *prefs) ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs)
{ {
Preferences::MirrorPreferences(prefs); Preferences::GetPreferences(aPrefs);
return true; return true;
} }
@ -954,17 +954,10 @@ ContentParent::Observe(nsISupports* aSubject,
// We know prefs are ASCII here. // We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData); NS_LossyConvertUTF16toASCII strData(aData);
PrefTuple pref; PrefSetting pref(strData, null_t(), null_t());
bool prefNeedUpdate = Preferences::MirrorPreference(strData.get(), &pref); Preferences::GetPreference(&pref);
if (prefNeedUpdate) { if (!SendPreferenceUpdate(pref)) {
if (!SendPreferenceUpdate(pref)) { return NS_ERROR_NOT_AVAILABLE;
return NS_ERROR_NOT_AVAILABLE;
}
} else {
// Pref wasn't found. It was probably removed.
if (!SendClearUserPreference(strData)) {
return NS_ERROR_NOT_AVAILABLE;
}
} }
} }
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) { else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {

View File

@ -212,7 +212,7 @@ private:
virtual PStorageParent* AllocPStorage(const StorageConstructData& aData); virtual PStorageParent* AllocPStorage(const StorageConstructData& aData);
virtual bool DeallocPStorage(PStorageParent* aActor); virtual bool DeallocPStorage(PStorageParent* aActor);
virtual bool RecvReadPrefsArray(InfallibleTArray<PrefTuple> *retValue); virtual bool RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs);
virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue); virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue);
virtual bool RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions); virtual bool RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions);

View File

@ -251,14 +251,21 @@ parent:
nsString aName, nsString aFeatures) nsString aName, nsString aFeatures)
returns (bool windowOpened); returns (bool windowOpened);
NotifyDOMTouchListenerAdded();
/** /**
* Instructs the TabParent to forward a request to zoom to a rect given in * Instructs the TabParent to forward a request to zoom to a rect given in
* CSS pixels. This rect is relative to the document. * CSS pixels. This rect is relative to the document.
*/ */
ZoomToRect(gfxRect aRect); ZoomToRect(gfxRect aRect);
/**
* We know for sure that content has either preventDefaulted or not
* preventDefaulted. This applies to an entire batch of touch events. It is
* expected that, if there are any DOM touch listeners, touch events will be
* batched and only processed for panning and zooming if content does not
* preventDefault.
*/
ContentReceivedTouch(bool aPreventDefault);
__delete__(); __delete__();
child: child:

View File

@ -24,7 +24,6 @@ include "mozilla/net/NeckoMessageUtils.h";
include "mozilla/dom/TabMessageUtils.h"; include "mozilla/dom/TabMessageUtils.h";
include "nsGeoPositionIPCSerialiser.h"; include "nsGeoPositionIPCSerialiser.h";
include "PPrefTuple.h";
include DOMTypes; include DOMTypes;
@ -135,6 +134,23 @@ union AppId {
nullable PBrowser; nullable PBrowser;
}; };
union PrefValue {
nsCString;
int32_t;
bool;
};
union MaybePrefValue {
PrefValue;
null_t;
};
struct PrefSetting {
nsCString name;
MaybePrefValue defaultValue;
MaybePrefValue userValue;
};
rpc protocol PContent rpc protocol PContent
{ {
parent opens PCompositor; parent opens PCompositor;
@ -183,8 +199,7 @@ child:
async NotifyVisited(URI uri); async NotifyVisited(URI uri);
PreferenceUpdate(PrefTuple pref); PreferenceUpdate(PrefSetting pref);
ClearUserPreference(nsCString prefName);
NotifyAlertsObserver(nsCString topic, nsString data); NotifyAlertsObserver(nsCString topic, nsString data);
@ -248,7 +263,7 @@ parent:
async LoadURIExternal(URI uri); async LoadURIExternal(URI uri);
// PrefService message // PrefService message
sync ReadPrefsArray() returns (PrefTuple[] retValue); sync ReadPrefsArray() returns (PrefSetting[] prefs);
sync ReadFontList() returns (FontListEntry[] retValue); sync ReadFontList() returns (FontListEntry[] retValue);

View File

@ -114,15 +114,7 @@ TabChild::Observe(nsISupports *aSubject,
const char *aTopic, const char *aTopic,
const PRUnichar *aData) const PRUnichar *aData)
{ {
if (!strcmp(aTopic, "dom-touch-listener-added")) { if (!strcmp(aTopic, "cancel-default-pan-zoom")) {
nsCOMPtr<nsIDOMWindow> subject(do_QueryInterface(aSubject));
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mWebNav));
nsCOMPtr<nsIDOMWindow> topSubject;
subject->GetTop(getter_AddRefs(topSubject));
if (win == topSubject) {
SendNotifyDOMTouchListenerAdded();
}
} else if (!strcmp(aTopic, "cancel-default-pan-zoom")) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject)); nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell)); nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) { if (tabChild == this) {
@ -163,9 +155,6 @@ TabChild::Init()
do_GetService(NS_OBSERVERSERVICE_CONTRACTID); do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) { if (observerService) {
observerService->AddObserver(this,
"dom-touch-listener-added",
false);
observerService->AddObserver(this, observerService->AddObserver(this,
"cancel-default-pan-zoom", "cancel-default-pan-zoom",
false); false);
@ -397,12 +386,7 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
// open a modal-type window, we're going to create a new <iframe mozbrowser> // open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here. // and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
bool isInContentBoundary = false; if (docshell && docshell->GetIsBelowContentBoundary() &&
if (docshell) {
docshell->GetIsBelowContentBoundary(&isInContentBoundary);
}
if (isInContentBoundary &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL | !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) { nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
@ -737,8 +721,8 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
} }
nsCString data; nsCString data;
data += nsPrintfCString("{ \"x\" : %d", aFrameMetrics.mViewportScrollOffset.x); data += nsPrintfCString("{ \"x\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.x));
data += nsPrintfCString(", \"y\" : %d", aFrameMetrics.mViewportScrollOffset.y); data += nsPrintfCString(", \"y\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.y));
// We don't treat the x and y scales any differently for this // We don't treat the x and y scales any differently for this
// semi-platform-specific code. // semi-platform-specific code.
data += nsPrintfCString(", \"zoom\" : %f", aFrameMetrics.mResolution.width); data += nsPrintfCString(", \"zoom\" : %f", aFrameMetrics.mResolution.width);
@ -836,6 +820,13 @@ TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
{ {
nsTouchEvent localEvent(aEvent); nsTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent); nsEventStatus status = DispatchWidgetEvent(localEvent);
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav);
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow && innerWindow->HasTouchEventListeners()) {
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
}
if (status == nsEventStatus_eConsumeNoDefault) { if (status == nsEventStatus_eConsumeNoDefault) {
return true; return true;
} }

View File

@ -1098,15 +1098,6 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
return true; return true;
} }
bool
TabParent::RecvNotifyDOMTouchListenerAdded()
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyDOMTouchListenerAdded();
}
return true;
}
bool bool
TabParent::RecvZoomToRect(const gfxRect& aRect) TabParent::RecvZoomToRect(const gfxRect& aRect)
{ {
@ -1116,5 +1107,14 @@ TabParent::RecvZoomToRect(const gfxRect& aRect)
return true; return true;
} }
bool
TabParent::RecvContentReceivedTouch(const bool& aPreventDefault)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->ContentReceivedTouch(aPreventDefault);
}
return true;
}
} // namespace tabs } // namespace tabs
} // namespace mozilla } // namespace mozilla

View File

@ -105,8 +105,8 @@ public:
virtual bool RecvSetBackgroundColor(const nscolor& aValue); virtual bool RecvSetBackgroundColor(const nscolor& aValue);
virtual bool RecvGetDPI(float* aValue); virtual bool RecvGetDPI(float* aValue);
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue); virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
virtual bool RecvNotifyDOMTouchListenerAdded();
virtual bool RecvZoomToRect(const gfxRect& aRect); virtual bool RecvZoomToRect(const gfxRect& aRect);
virtual bool RecvContentReceivedTouch(const bool& aPreventDefault);
virtual PContentDialogParent* AllocPContentDialog(const uint32_t& aType, virtual PContentDialogParent* AllocPContentDialog(const uint32_t& aType,
const nsCString& aName, const nsCString& aName,
const nsCString& aFeatures, const nsCString& aFeatures,

View File

@ -8,6 +8,7 @@
#include "nsIDOMClassInfo.h" #include "nsIDOMClassInfo.h"
#include "nsISmsService.h" #include "nsISmsService.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "Constants.h" #include "Constants.h"
#include "SmsEvent.h" #include "SmsEvent.h"
@ -18,6 +19,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsISmsDatabaseService.h" #include "nsISmsDatabaseService.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsIPermissionManager.h"
/** /**
* We have to use macros here because our leak analysis tool things we are * We have to use macros here because our leak analysis tool things we are
@ -59,6 +61,45 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(SmsManager, nsDOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(SmsManager, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(SmsManager, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(SmsManager, nsDOMEventTargetHelper)
/* static */already_AddRefed<SmsManager>
SmsManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
{
NS_ASSERTION(aWindow, "Null pointer!");
// First of all, the general pref has to be turned on.
bool enabled = false;
Preferences::GetBool("dom.sms.enabled", &enabled);
NS_ENSURE_TRUE(enabled, nullptr);
nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
aWindow :
aWindow->GetCurrentInnerWindow();
// Need the document for security check.
nsCOMPtr<nsIDocument> document =
do_QueryInterface(innerWindow->GetExtantDocument());
NS_ENSURE_TRUE(document, nullptr);
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
NS_ENSURE_TRUE(principal, nullptr);
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, nullptr);
PRUint32 permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromPrincipal(principal, "sms", &permission);
if (permission != nsIPermissionManager::ALLOW_ACTION) {
return nullptr;
}
nsRefPtr<SmsManager> smsMgr = new SmsManager();
smsMgr->Init(aWindow);
return smsMgr.forget();
}
void void
SmsManager::Init(nsPIDOMWindow *aWindow) SmsManager::Init(nsPIDOMWindow *aWindow)
{ {

View File

@ -30,6 +30,9 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SmsManager, NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SmsManager,
nsDOMEventTargetHelper) nsDOMEventTargetHelper)
static already_AddRefed<SmsManager>
CheckPermissionAndCreateInstance(nsPIDOMWindow *aWindow);
void Init(nsPIDOMWindow *aWindow); void Init(nsPIDOMWindow *aWindow);
void Shutdown(); void Shutdown();

View File

@ -11,8 +11,8 @@ class SMSTest(MarionetteTestCase):
sender = self.get_new_emulator() sender = self.get_new_emulator()
receiver = self.marionette receiver = self.marionette
self.set_up_test_page(sender, "test.html", ["dom.sms.whitelist"]) self.set_up_test_page(sender, "test.html", ["sms"])
self.set_up_test_page(receiver, "test.html", ["dom.sms.whitelist"]) self.set_up_test_page(receiver, "test.html", ["sms"])
# Setup the event listsener on the receiver, which should store # Setup the event listsener on the receiver, which should store
# a global variable when an SMS is received. # a global variable when an SMS is received.
@ -21,7 +21,7 @@ class SMSTest(MarionetteTestCase):
receiver.execute_script(""" receiver.execute_script("""
global.smsreceived = null; global.smsreceived = null;
window.navigator.mozSms.addEventListener("received", function(e) { window.navigator.mozSms.addEventListener("received", function(e) {
global.smsreceived = e.message; global.smsreceived = e.message.body;
}); });
""", new_sandbox=False) """, new_sandbox=False)

View File

@ -3,9 +3,8 @@
MARIONETTE_TIMEOUT = 10000; MARIONETTE_TIMEOUT = 10000;
const WHITELIST_PREF = "dom.sms.whitelist"; SpecialPowers.setBoolPref("dom.sms.enabled", true);
let uriPrePath = window.location.protocol + "//" + window.location.host; SpecialPowers.addPermission("sms", true, document);
SpecialPowers.setCharPref(WHITELIST_PREF, uriPrePath);
let sms = window.navigator.mozSms; let sms = window.navigator.mozSms;
let sender = "5555552368"; let sender = "5555552368";
@ -42,6 +41,6 @@ function cleanUp() {
return; return;
} }
SpecialPowers.clearUserPref(WHITELIST_PREF); SpecialPowers.removePermission("sms", document);
finish(); finish();
} }

View File

@ -17,11 +17,11 @@
function checkSmsDisabled() { function checkSmsDisabled() {
ok('mozSms' in frames[0].navigator, "navigator.mozSms should exist"); ok('mozSms' in frames[0].navigator, "navigator.mozSms should exist");
is(navigator.mozSms, null, "navigator.mozSms should return null"); is(frames[0].navigator.mozSms, null, "navigator.mozSms should return null");
} }
function checkSmsEnabled() { function checkSmsEnabled() {
// WebSms is disabled on all platforms except Android for the moment. // Bug 784617: WebSms is disabled on all platforms except Android for the moment.
if (navigator.appVersion.indexOf("Android") == -1) { if (navigator.appVersion.indexOf("Android") == -1) {
checkSmsDisabled(); checkSmsDisabled();
return; return;
@ -39,7 +39,6 @@ function checkInterface(aInterface) {
function test() { function test() {
var gSmsEnabled = SpecialPowers.getBoolPref("dom.sms.enabled"); var gSmsEnabled = SpecialPowers.getBoolPref("dom.sms.enabled");
var gSmsWhiteList = SpecialPowers.getCharPref("dom.sms.whitelist");
checkInterface("SmsManager"); checkInterface("SmsManager");
checkInterface("NavigatorSms"); checkInterface("NavigatorSms");
@ -49,32 +48,24 @@ function test() {
checkInterface("SmsFilter"); checkInterface("SmsFilter");
checkInterface("SmsCursor"); checkInterface("SmsCursor");
// If sms are disabled and whitelist is empty, sms is disabled. // If sms is disabled and permission is removed, sms is disabled.
SpecialPowers.setBoolPref("dom.sms.enabled", false); SpecialPowers.setBoolPref("dom.sms.enabled", false);
SpecialPowers.setCharPref("dom.sms.whitelist", ""); SpecialPowers.removePermission("sms", document);
checkSmsDisabled(); checkSmsDisabled();
// If sms are enabled and whitelist is empty, sms are disabled. // If sms is enabled and permission is removed, sms is disabled.
SpecialPowers.setBoolPref("dom.sms.enabled", true); SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", ""); SpecialPowers.removePermission("sms", document);
checkSmsDisabled(); checkSmsDisabled();
// If sms are disabled and whitelist contains the current URL prepath, // If sms is disabled and permission is granted, sms is disabled.
// sms are disabled.
SpecialPowers.setBoolPref("dom.sms.enabled", false); SpecialPowers.setBoolPref("dom.sms.enabled", false);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://mochi.test:8888"); SpecialPowers.addPermission("sms", true, document);
checkSmsDisabled(); checkSmsDisabled();
// If sms are enabled and whitelist contains something else than the current // If sms is enabled and permission is granted, sms is enabled.
// URL prepath, sms are disabled.
SpecialPowers.setBoolPref("dom.sms.enabled", true); SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://foo.mochi.test:8888"); SpecialPowers.addPermission("sms", true, document);
checkSmsDisabled();
// If sms are enabled and whitelist contains the current URL prepath,
// sms are enabled.
SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://mochi.test:8888");
checkSmsEnabled(); checkSmsEnabled();
// Now, if sms are disabled with the pref, they will still be enabled. // Now, if sms are disabled with the pref, they will still be enabled.
@ -96,15 +87,13 @@ function test() {
// Cleanup and quit. // Cleanup and quit.
SpecialPowers.setBoolPref("dom.sms.enabled", gSmsEnabled); SpecialPowers.setBoolPref("dom.sms.enabled", gSmsEnabled);
SpecialPowers.setCharPref("dom.sms.whitelist", gSmsWhiteList); SpecialPowers.removePermission("sms", document);
SimpleTest.finish(); SimpleTest.finish();
}); });
frames[0].location.reload(); frames[0].location.reload();
}); });
// Having more than one item in the whitelist should work.
SpecialPowers.setBoolPref("dom.sms.enabled", true); SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://mochi.test:8888, http://foo.com");
frames[0].location.reload(); frames[0].location.reload();
} }

View File

@ -33,6 +33,9 @@
#include "nsXPCOMCIDInternal.h" #include "nsXPCOMCIDInternal.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsString.h" #include "nsString.h"
#include "nsAutoPtr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "OSFileConstants.h" #include "OSFileConstants.h"
#include "nsIOSFileConstantsService.h" #include "nsIOSFileConstantsService.h"
@ -53,10 +56,42 @@ namespace {
*/ */
bool gInitialized = false; bool gInitialized = false;
typedef struct {
/**
* The name of the directory holding all the libraries (libxpcom, libnss, etc.)
*/
nsString libDir;
nsString tmpDir;
nsString profileDir;
} Paths;
/** /**
* The name of the directory holding all the libraries (libxpcom, libnss, etc.) * System directories.
*/ */
nsString* gLibDirectory; Paths* gPaths = NULL;
}
/**
* Return the path to one of the special directories.
*
* @param aKey The key to the special directory (e.g. "TmpD", "ProfD", ...)
* @param aOutPath The path to the special directory. In case of error,
* the string is set to void.
*/
nsresult GetPathToSpecialDir(const char *aKey, nsString& aOutPath)
{
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(aKey, getter_AddRefs(file));
if (NS_FAILED(rv) || !file) {
return rv;
}
rv = file->GetPath(aOutPath);
if (NS_FAILED(rv)) {
aOutPath.SetIsVoid(true);
}
return rv;
} }
/** /**
@ -72,23 +107,39 @@ nsresult InitOSFileConstants()
gInitialized = true; gInitialized = true;
// Initialize gLibDirectory nsAutoPtr<Paths> paths(new Paths);
nsCOMPtr<nsIFile> xpcomLib;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(xpcomLib));
if (NS_FAILED(rv) || !xpcomLib) {
return rv;
}
nsCOMPtr<nsIFile> libDir; // Initialize paths->libDir
rv = xpcomLib->GetParent(getter_AddRefs(libDir)); nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(file));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
gLibDirectory = new nsString(); nsCOMPtr<nsIFile> libDir;
return libDir->GetPath(*gLibDirectory); rv = file->GetParent(getter_AddRefs(libDir));
if (NS_FAILED(rv)) {
return rv;
}
rv = libDir->GetPath(paths->libDir);
if (NS_FAILED(rv)) {
return rv;
}
// For other directories, ignore errors (they may be undefined on
// some platforms or in non-Firefox embeddings of Gecko).
GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir);
GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir);
gPaths = paths.forget();
return NS_OK;
} }
/**
* Perform the cleaning up that can only be executed on the main thread.
*/
void CleanupOSFileConstants() void CleanupOSFileConstants()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
@ -97,7 +148,7 @@ void CleanupOSFileConstants()
} }
gInitialized = false; gInitialized = false;
delete gLibDirectory; delete gPaths;
} }
@ -478,6 +529,22 @@ JSObject *GetOrCreateObjectProperty(JSContext *cx, JSObject *aObject,
return JS_DefineObject(cx, aObject, aProperty, NULL, NULL, JSPROP_ENUMERATE); return JS_DefineObject(cx, aObject, aProperty, NULL, NULL, JSPROP_ENUMERATE);
} }
/**
* Set a property of an object from a nsString.
*
* If the nsString is void (i.e. IsVoid is true), do nothing.
*/
bool SetStringProperty(JSContext *cx, JSObject *aObject, const char *aProperty,
const nsString aValue)
{
if (aValue.IsVoid()) {
return true;
}
JSString* strValue = JS_NewUCStringCopyZ(cx, aValue.get());
jsval valValue = STRING_TO_JSVAL(strValue);
return JS_SetProperty(cx, aObject, aProperty, &valValue);
}
/** /**
* Define OS-specific constants. * Define OS-specific constants.
* *
@ -488,6 +555,16 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
{ {
MOZ_ASSERT(gInitialized); MOZ_ASSERT(gInitialized);
if (gPaths == NULL) {
// If an initialization error was ignored, we may end up with
// |gInitialized == true| but |gPaths == NULL|. We cannot
// |MOZ_ASSERT| this, as this would kill precompile_cache.js,
// so we simply return an error.
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_OPEN, "OSFileConstants", "initialization has failed");
return false;
}
JSObject *objOS; JSObject *objOS;
if (!(objOS = GetOrCreateObjectProperty(cx, global, "OS"))) { if (!(objOS = GetOrCreateObjectProperty(cx, global, "OS"))) {
return false; return false;
@ -550,10 +627,9 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
return false; return false;
} }
// Locate libxul // Locate libxul
{ {
nsAutoString xulPath(*gLibDirectory); nsAutoString xulPath(gPaths->libDir);
xulPath.Append(PR_GetDirectorySeparator()); xulPath.Append(PR_GetDirectorySeparator());
@ -568,13 +644,23 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
xulPath.Append(NS_LITERAL_STRING(DLL_SUFFIX)); xulPath.Append(NS_LITERAL_STRING(DLL_SUFFIX));
#endif // defined(XP_MACOSX) #endif // defined(XP_MACOSX)
JSString* strPathToLibXUL = JS_NewUCStringCopyZ(cx, xulPath.get()); if (!SetStringProperty(cx, objPath, "libxul", xulPath)) {
jsval valXul = STRING_TO_JSVAL(strPathToLibXUL);
if (!JS_SetProperty(cx, objPath, "libxul", &valXul)) {
return false; return false;
} }
} }
if (!SetStringProperty(cx, objPath, "libDir", gPaths->libDir)) {
return false;
}
if (!SetStringProperty(cx, objPath, "tmpDir", gPaths->tmpDir)) {
return false;
}
if (!SetStringProperty(cx, objPath, "profileDir", gPaths->profileDir)) {
return false;
}
return true; return true;
} }

View File

@ -25,6 +25,22 @@ USING_WORKERS_NAMESPACE
using namespace mozilla::dom; using namespace mozilla::dom;
using mozilla::ErrorResult; using mozilla::ErrorResult;
// These are temporary until these classes are moved to be codegenerated.
bool
WorkerResolveProperty(JSContext* cx, JSObject* wrapper, jsid id, bool set,
JSPropertyDescriptor* desc)
{
return true;
}
bool
WorkerEnumerateProperties(JS::AutoIdVector& props)
{
return true;
}
NativePropertyHooks mozilla::dom::workers::sNativePropertyHooks =
{ WorkerResolveProperty, WorkerEnumerateProperties, NULL };
namespace { namespace {
class Worker class Worker
@ -276,6 +292,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3, MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"The MaxProtoChainLength must match our manual DOMJSClasses"); "The MaxProtoChainLength must match our manual DOMJSClasses");
// When this DOMJSClass is removed and it's the last consumer of
// sNativePropertyHooks then sNativePropertyHooks should be removed too.
DOMJSClass Worker::sClass = { DOMJSClass Worker::sClass = {
{ {
"Worker", "Worker",
@ -287,7 +305,7 @@ DOMJSClass Worker::sClass = {
}, },
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count, { prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count }, prototypes::id::_ID_Count },
-1, false, NULL -1, false, &sNativePropertyHooks
}; };
JSPropertySpec Worker::sProperties[] = { JSPropertySpec Worker::sProperties[] = {
@ -395,6 +413,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3, MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"The MaxProtoChainLength must match our manual DOMJSClasses"); "The MaxProtoChainLength must match our manual DOMJSClasses");
// When this DOMJSClass is removed and it's the last consumer of
// sNativePropertyHooks then sNativePropertyHooks should be removed too.
DOMJSClass ChromeWorker::sClass = { DOMJSClass ChromeWorker::sClass = {
{ "ChromeWorker", { "ChromeWorker",
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) |
@ -405,7 +425,7 @@ DOMJSClass ChromeWorker::sClass = {
}, },
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count, { prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count }, prototypes::id::_ID_Count },
-1, false, NULL -1, false, &sNativePropertyHooks
}; };
WorkerPrivate* WorkerPrivate*

View File

@ -9,9 +9,12 @@
#include "Workers.h" #include "Workers.h"
#include "jspubtd.h" #include "jspubtd.h"
#include "mozilla/dom/DOMJSClass.h"
BEGIN_WORKERS_NAMESPACE BEGIN_WORKERS_NAMESPACE
extern mozilla::dom::NativePropertyHooks sNativePropertyHooks;
namespace worker { namespace worker {
JSObject* JSObject*

View File

@ -848,6 +848,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3, MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"The MaxProtoChainLength must match our manual DOMJSClasses"); "The MaxProtoChainLength must match our manual DOMJSClasses");
// When this DOMJSClass is removed and it's the last consumer of
// sNativePropertyHooks then sNativePropertyHooks should be removed too.
DOMJSClass DedicatedWorkerGlobalScope::sClass = { DOMJSClass DedicatedWorkerGlobalScope::sClass = {
{ {
"DedicatedWorkerGlobalScope", "DedicatedWorkerGlobalScope",
@ -859,7 +861,7 @@ DOMJSClass DedicatedWorkerGlobalScope::sClass = {
}, },
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count, { prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count }, prototypes::id::_ID_Count },
-1, false, NULL -1, false, &sNativePropertyHooks
}; };
JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = { JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {

View File

@ -207,13 +207,13 @@ nsContentBlocker::ShouldProcess(uint32_t aContentType,
bool shouldLoad, fromPrefs; bool shouldLoad, fromPrefs;
nsresult rv = TestPermission(aContentLocation, aRequestingLocation, nsresult rv = TestPermission(aContentLocation, aRequestingLocation,
aContentType, &shouldLoad, &fromPrefs); aContentType, &shouldLoad, &fromPrefs);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!shouldLoad) { if (!shouldLoad) {
if (fromPrefs) { if (fromPrefs) {
*aDecision = nsIContentPolicy::REJECT_TYPE; *aDecision = nsIContentPolicy::REJECT_TYPE;
} else { } else {
*aDecision = nsIContentPolicy::REJECT_SERVER; *aDecision = nsIContentPolicy::REJECT_SERVER;
} }
} }
return NS_OK; return NS_OK;

View File

@ -151,6 +151,10 @@ GetCairoSurfaceForSourceSurface(SourceSurface *aSurface)
} }
RefPtr<DataSourceSurface> data = aSurface->GetDataSurface(); RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
if (!data) {
return nullptr;
}
cairo_surface_t* surf = cairo_surface_t* surf =
cairo_image_surface_create_for_data(data->GetData(), cairo_image_surface_create_for_data(data->GetData(),
GfxFormatToCairoFormat(data->GetFormat()), GfxFormatToCairoFormat(data->GetFormat()),

View File

@ -2090,19 +2090,20 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
AddDependencyOnSource(surf); AddDependencyOnSource(surf);
} }
break; break;
case SURFACE_DATA: default:
{ {
DataSourceSurface *dataSurf = RefPtr<DataSourceSurface> dataSurf = pat->mSurface->GetDataSurface();
static_cast<DataSourceSurface*>(pat->mSurface.get()); if (!dataSurf) {
bitmap = CreatePartialBitmapForSurface(dataSurf, mat, pat->mExtendMode); gfxWarning() << "Invalid surface type.";
return nullptr;
}
bitmap = CreatePartialBitmapForSurface(dataSurf, mat, pat->mExtendMode);
if (!bitmap) { if (!bitmap) {
return nullptr; return nullptr;
} }
} }
break; break;
default:
break;
} }
mRT->CreateBitmapBrush(bitmap, mRT->CreateBitmapBrush(bitmap,

View File

@ -36,6 +36,7 @@ public:
, mScrollId(NULL_SCROLL_ID) , mScrollId(NULL_SCROLL_ID)
, mCSSContentRect(0, 0, 0, 0) , mCSSContentRect(0, 0, 0, 0)
, mResolution(1, 1) , mResolution(1, 1)
, mMayHaveTouchListeners(false)
{} {}
// Default copy ctor and operator= are fine // Default copy ctor and operator= are fine
@ -70,7 +71,7 @@ public:
// These are all in layer coordinate space. // These are all in layer coordinate space.
nsIntRect mViewport; nsIntRect mViewport;
nsIntRect mContentRect; nsIntRect mContentRect;
nsIntPoint mViewportScrollOffset; gfx::Point mViewportScrollOffset;
nsIntRect mDisplayPort; nsIntRect mDisplayPort;
ViewID mScrollId; ViewID mScrollId;
@ -81,6 +82,9 @@ public:
// This represents the resolution at which the associated layer // This represents the resolution at which the associated layer
// will been rendered. // will been rendered.
gfxSize mResolution; gfxSize mResolution;
// Whether or not this frame may have touch listeners.
bool mMayHaveTouchListeners;
}; };
} }

View File

@ -39,6 +39,8 @@ using mozilla::gfx::SourceSurface;
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
int32_t Image::sSerialCounter = 0;
already_AddRefed<Image> already_AddRefed<Image>
ImageFactory::CreateImage(const ImageFormat *aFormats, ImageFactory::CreateImage(const ImageFormat *aFormats,
uint32_t aNumFormats, uint32_t aNumFormats,

View File

@ -80,16 +80,21 @@ public:
void SetBackendData(LayersBackend aBackend, ImageBackendData* aData) void SetBackendData(LayersBackend aBackend, ImageBackendData* aData)
{ mBackendData[aBackend] = aData; } { mBackendData[aBackend] = aData; }
int32_t GetSerial() { return mSerial; }
protected: protected:
Image(void* aImplData, ImageFormat aFormat) : Image(void* aImplData, ImageFormat aFormat) :
mImplData(aImplData), mImplData(aImplData),
mSerial(PR_ATOMIC_INCREMENT(&sSerialCounter)),
mFormat(aFormat) mFormat(aFormat)
{} {}
nsAutoPtr<ImageBackendData> mBackendData[mozilla::layers::LAYERS_LAST]; nsAutoPtr<ImageBackendData> mBackendData[mozilla::layers::LAYERS_LAST];
void* mImplData; void* mImplData;
int32_t mSerial;
ImageFormat mFormat; ImageFormat mFormat;
static int32_t sSerialCounter;
}; };
/** /**

View File

@ -123,6 +123,15 @@ AppendToString(nsACString& s, const nsIntPoint& p,
return s += sfx; return s += sfx;
} }
nsACString&
AppendToString(nsACString& s, const Point& p,
const char* pfx="", const char* sfx="")
{
s += pfx;
s += nsPrintfCString("(x=%f, y=%f)", p.x, p.y);
return s += sfx;
}
nsACString& nsACString&
AppendToString(nsACString& s, const nsIntRect& r, AppendToString(nsACString& s, const nsIntRect& r,
const char* pfx="", const char* sfx="") const char* pfx="", const char* sfx="")

View File

@ -177,7 +177,8 @@ class BasicShadowableImageLayer : public BasicImageLayer,
public: public:
BasicShadowableImageLayer(BasicShadowLayerManager* aManager) : BasicShadowableImageLayer(BasicShadowLayerManager* aManager) :
BasicImageLayer(aManager), BasicImageLayer(aManager),
mBufferIsOpaque(false) mBufferIsOpaque(false),
mLastPaintedImageSerial(0)
{ {
MOZ_COUNT_CTOR(BasicShadowableImageLayer); MOZ_COUNT_CTOR(BasicShadowableImageLayer);
} }
@ -246,6 +247,7 @@ private:
SurfaceDescriptor mBackBufferU; SurfaceDescriptor mBackBufferU;
SurfaceDescriptor mBackBufferV; SurfaceDescriptor mBackBufferV;
gfxIntSize mCbCrSize; gfxIntSize mCbCrSize;
int32_t mLastPaintedImageSerial;
}; };
void void
@ -374,6 +376,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
if (!BasicManager()->AllocBuffer(mSize, type, &mBackBuffer)) if (!BasicManager()->AllocBuffer(mSize, type, &mBackBuffer))
NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
} else if (mLastPaintedImageSerial == image->GetSerial()) {
return;
} }
AutoOpenSurface backSurface(OPEN_READ_WRITE, mBackBuffer); AutoOpenSurface backSurface(OPEN_READ_WRITE, mBackBuffer);
@ -385,6 +389,7 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
BasicManager()->PaintedImage(BasicManager()->Hold(this), BasicManager()->PaintedImage(BasicManager()->Hold(this),
mBackBuffer); mBackBuffer);
mLastPaintedImageSerial = image->GetSerial();
} }
class BasicShadowImageLayer : public ShadowImageLayer, public BasicImplData { class BasicShadowImageLayer : public ShadowImageLayer, public BasicImplData {

View File

@ -71,9 +71,18 @@ static const double MAX_ZOOM = 8.0;
*/ */
static const double MIN_ZOOM = 0.125; static const double MIN_ZOOM = 0.125;
/**
* Amount of time before we timeout touch event listeners. For example, if
* content is being unruly/slow and we don't get a response back within this
* time, we will just pretend that content did not preventDefault any touch
* events we dispatched to it.
*/
static const int TOUCH_LISTENER_TIMEOUT = 300;
AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController, AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController,
GestureBehavior aGestures) GestureBehavior aGestures)
: mGeckoContentController(aGeckoContentController), : mGeckoContentController(aGeckoContentController),
mTouchListenerTimeoutTask(nullptr),
mX(this), mX(this),
mY(this), mY(this),
mMonitor("AsyncPanZoomController"), mMonitor("AsyncPanZoomController"),
@ -81,8 +90,8 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mState(NOTHING), mState(NOTHING),
mDPI(72), mDPI(72),
mContentPainterStatus(CONTENT_IDLE), mContentPainterStatus(CONTENT_IDLE),
mMayHaveTouchListeners(false), mDisableNextTouchBatch(false),
mDisableNextTouchBatch(false) mHandlingTouchQueue(false)
{ {
if (aGestures == USE_GESTURE_DETECTOR) { if (aGestures == USE_GESTURE_DETECTOR) {
mGestureEventListener = new GestureEventListener(this); mGestureEventListener = new GestureEventListener(this);
@ -121,8 +130,8 @@ WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint,
} }
nsEventStatus nsEventStatus
AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent, AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent) nsInputEvent* aOutEvent)
{ {
float currentZoom; float currentZoom;
gfx::Point currentScrollOffset, lastScrollOffset; gfx::Point currentScrollOffset, lastScrollOffset;
@ -139,12 +148,12 @@ AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent,
switch (aEvent.eventStructType) { switch (aEvent.eventStructType) {
case NS_TOUCH_EVENT: { case NS_TOUCH_EVENT: {
MultiTouchInput event(static_cast<const nsTouchEvent&>(aEvent)); MultiTouchInput event(static_cast<const nsTouchEvent&>(aEvent));
status = HandleInputEvent(event); status = ReceiveInputEvent(event);
break; break;
} }
case NS_MOUSE_EVENT: { case NS_MOUSE_EVENT: {
MultiTouchInput event(static_cast<const nsMouseEvent&>(aEvent)); MultiTouchInput event(static_cast<const nsMouseEvent&>(aEvent));
status = HandleInputEvent(event); status = ReceiveInputEvent(event);
break; break;
} }
default: default:
@ -179,11 +188,47 @@ AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent,
return status; return status;
} }
nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) {
// If we may have touch listeners, we enable the machinery that allows touch
// listeners to preventDefault any touch inputs. This should not happen unless
// there are actually touch listeners as it introduces potentially unbounded
// lag because it causes a round-trip through content. Usually, if content is
// responding in a timely fashion, this only introduces a nearly constant few
// hundred ms of lag.
if (mFrameMetrics.mMayHaveTouchListeners && aEvent.mInputType == MULTITOUCH_INPUT &&
(mState == NOTHING || mState == TOUCHING || mState == PANNING)) {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) {
SetState(WAITING_LISTENERS);
}
}
if (mState == WAITING_LISTENERS || mHandlingTouchQueue) {
if (aEvent.mInputType == MULTITOUCH_INPUT) {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
mTouchQueue.AppendElement(multiTouchInput);
if (!mTouchListenerTimeoutTask) {
mTouchListenerTimeoutTask =
NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
mTouchListenerTimeoutTask,
TOUCH_LISTENER_TIMEOUT);
}
}
return nsEventStatus_eConsumeNoDefault;
}
return HandleInputEvent(aEvent);
}
nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) { nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) {
nsEventStatus rv = nsEventStatus_eIgnore; nsEventStatus rv = nsEventStatus_eIgnore;
if (mGestureEventListener && !mDisableNextTouchBatch) { if (mGestureEventListener && !mDisableNextTouchBatch) {
nsEventStatus rv = mGestureEventListener->HandleInputEvent(aEvent); rv = mGestureEventListener->HandleInputEvent(aEvent);
if (rv == nsEventStatus_eConsumeNoDefault) if (rv == nsEventStatus_eConsumeNoDefault)
return rv; return rv;
} }
@ -253,6 +298,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
case TOUCHING: case TOUCHING:
case PANNING: case PANNING:
case PINCHING: case PINCHING:
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchStart"); NS_WARNING("Received impossible touch in OnTouchStart");
break; break;
default: default:
@ -297,6 +343,10 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
// The scale gesture listener should have handled this. // The scale gesture listener should have handled this.
NS_WARNING("Gesture listener should have handled pinching in OnTouchMove."); NS_WARNING("Gesture listener should have handled pinching in OnTouchMove.");
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchMove");
break;
} }
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
@ -333,11 +383,16 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
mY.EndTouch(); mY.EndTouch();
SetState(FLING); SetState(FLING);
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
case PINCHING: case PINCHING:
SetState(NOTHING); SetState(NOTHING);
// Scale gesture listener should have handled this. // Scale gesture listener should have handled this.
NS_WARNING("Gesture listener should have handled pinching in OnTouchEnd."); NS_WARNING("Gesture listener should have handled pinching in OnTouchEnd.");
return nsEventStatus_eIgnore; return nsEventStatus_eIgnore;
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchEnd");
break;
} }
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
@ -370,7 +425,7 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
float scale = mFrameMetrics.mResolution.width; float scale = mFrameMetrics.mResolution.width;
nsIntPoint focusPoint = aEvent.mFocusPoint; nsIntPoint focusPoint = aEvent.mFocusPoint;
int32_t xFocusChange = (mLastZoomFocus.x - focusPoint.x) / scale, yFocusChange = (mLastZoomFocus.y - focusPoint.y) / scale; float xFocusChange = (mLastZoomFocus.x - focusPoint.x) / scale, yFocusChange = (mLastZoomFocus.y - focusPoint.y) / scale;
// If displacing by the change in focus point will take us off page bounds, // If displacing by the change in focus point will take us off page bounds,
// then reduce the displacement such that it doesn't. // then reduce the displacement such that it doesn't.
if (mX.DisplacementWillOverscroll(xFocusChange) != Axis::OVERSCROLL_NONE) { if (mX.DisplacementWillOverscroll(xFocusChange) != Axis::OVERSCROLL_NONE) {
@ -379,12 +434,12 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
if (mY.DisplacementWillOverscroll(yFocusChange) != Axis::OVERSCROLL_NONE) { if (mY.DisplacementWillOverscroll(yFocusChange) != Axis::OVERSCROLL_NONE) {
yFocusChange -= mY.DisplacementWillOverscrollAmount(yFocusChange); yFocusChange -= mY.DisplacementWillOverscrollAmount(yFocusChange);
} }
ScrollBy(nsIntPoint(xFocusChange, yFocusChange)); ScrollBy(gfx::Point(xFocusChange, yFocusChange));
// When we zoom in with focus, we can zoom too much towards the boundaries // When we zoom in with focus, we can zoom too much towards the boundaries
// that we actually go over them. These are the needed displacements along // that we actually go over them. These are the needed displacements along
// either axis such that we don't overscroll the boundaries when zooming. // either axis such that we don't overscroll the boundaries when zooming.
int32_t neededDisplacementX = 0, neededDisplacementY = 0; float neededDisplacementX = 0, neededDisplacementY = 0;
// Only do the scaling if we won't go over 8x zoom in or out. // Only do the scaling if we won't go over 8x zoom in or out.
bool doScale = (scale < MAX_ZOOM && spanRatio > 1.0f) || (scale > MIN_ZOOM && spanRatio < 1.0f); bool doScale = (scale < MAX_ZOOM && spanRatio > 1.0f) || (scale > MIN_ZOOM && spanRatio < 1.0f);
@ -436,7 +491,7 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
focusPoint); focusPoint);
if (neededDisplacementX != 0 || neededDisplacementY != 0) { if (neededDisplacementX != 0 || neededDisplacementY != 0) {
ScrollBy(nsIntPoint(neededDisplacementX, neededDisplacementY)); ScrollBy(gfx::Point(neededDisplacementX, neededDisplacementY));
} }
ScheduleComposite(); ScheduleComposite();
@ -559,7 +614,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
return; return;
} }
ScrollBy(nsIntPoint(xDisplacement, yDisplacement)); ScrollBy(gfx::Point(xDisplacement, yDisplacement));
ScheduleComposite(); ScheduleComposite();
RequestContentRepaint(); RequestContentRepaint();
@ -588,7 +643,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
// larger swipe should move you a shorter distance. // larger swipe should move you a shorter distance.
float inverseScale = 1 / mFrameMetrics.mResolution.width; float inverseScale = 1 / mFrameMetrics.mResolution.width;
ScrollBy(nsIntPoint( ScrollBy(gfx::Point(
mX.GetDisplacementForDuration(inverseScale, aDelta), mX.GetDisplacementForDuration(inverseScale, aDelta),
mY.GetDisplacementForDuration(inverseScale, aDelta) mY.GetDisplacementForDuration(inverseScale, aDelta)
)); ));
@ -605,8 +660,8 @@ void AsyncPanZoomController::SetCompositorParent(CompositorParent* aCompositorPa
mCompositorParent = aCompositorParent; mCompositorParent = aCompositorParent;
} }
void AsyncPanZoomController::ScrollBy(const nsIntPoint& aOffset) { void AsyncPanZoomController::ScrollBy(const gfx::Point& aOffset) {
nsIntPoint newOffset(mFrameMetrics.mViewportScrollOffset.x + aOffset.x, gfx::Point newOffset(mFrameMetrics.mViewportScrollOffset.x + aOffset.x,
mFrameMetrics.mViewportScrollOffset.y + aOffset.y); mFrameMetrics.mViewportScrollOffset.y + aOffset.y);
FrameMetrics metrics(mFrameMetrics); FrameMetrics metrics(mFrameMetrics);
metrics.mViewportScrollOffset = newOffset; metrics.mViewportScrollOffset = newOffset;
@ -642,10 +697,10 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale, const nsIntPoint& aFoc
// current CSS page rect (which is unchanged since it's not affected by zoom). // current CSS page rect (which is unchanged since it's not affected by zoom).
SetPageRect(mFrameMetrics.mCSSContentRect); SetPageRect(mFrameMetrics.mCSSContentRect);
nsIntPoint scrollOffset = metrics.mViewportScrollOffset; gfx::Point scrollOffset = metrics.mViewportScrollOffset;
scrollOffset.x += NS_lround(float(aFocus.x) * (scaleFactor - 1.0f) / oldScale); scrollOffset.x += float(aFocus.x) * (scaleFactor - 1.0f) / oldScale;
scrollOffset.y += NS_lround(float(aFocus.y) * (scaleFactor - 1.0f) / oldScale); scrollOffset.y += float(aFocus.y) * (scaleFactor - 1.0f) / oldScale;
metrics.mViewportScrollOffset = scrollOffset; metrics.mViewportScrollOffset = scrollOffset;
@ -674,7 +729,7 @@ const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
nsIntRect viewport = mFrameMetrics.mViewport; nsIntRect viewport = mFrameMetrics.mViewport;
viewport.ScaleRoundIn(1 / scale); viewport.ScaleRoundIn(1 / scale);
nsIntPoint scrollOffset = mFrameMetrics.mViewportScrollOffset; gfx::Point scrollOffset = mFrameMetrics.mViewportScrollOffset;
gfx::Point velocity = GetVelocityVector(); gfx::Point velocity = GetVelocityVector();
// The displayport is relative to the current scroll offset. Here's a little // The displayport is relative to the current scroll offset. Here's a little
@ -751,14 +806,30 @@ void AsyncPanZoomController::ScheduleComposite() {
void AsyncPanZoomController::RequestContentRepaint() { void AsyncPanZoomController::RequestContentRepaint() {
mFrameMetrics.mDisplayPort = CalculatePendingDisplayPort(); mFrameMetrics.mDisplayPort = CalculatePendingDisplayPort();
gfx::Point oldScrollOffset = mLastPaintRequestMetrics.mViewportScrollOffset,
newScrollOffset = mFrameMetrics.mViewportScrollOffset;
// If we're trying to paint what we already think is painted, discard this // If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint. // request since it's a pointless paint.
nsIntRect oldDisplayPort = mLastPaintRequestMetrics.mDisplayPort, nsRect oldDisplayPort = nsRect(
newDisplayPort = mFrameMetrics.mDisplayPort; mLastPaintRequestMetrics.mDisplayPort.x,
oldDisplayPort.MoveBy(mLastPaintRequestMetrics.mViewportScrollOffset); mLastPaintRequestMetrics.mDisplayPort.y,
newDisplayPort.MoveBy(mFrameMetrics.mViewportScrollOffset); mLastPaintRequestMetrics.mDisplayPort.width,
mLastPaintRequestMetrics.mDisplayPort.height);
if (oldDisplayPort.IsEqualEdges(newDisplayPort) && gfx::Rect newDisplayPort = gfx::Rect(
mFrameMetrics.mDisplayPort.x,
mFrameMetrics.mDisplayPort.y,
mFrameMetrics.mDisplayPort.width,
mFrameMetrics.mDisplayPort.height);
oldDisplayPort.MoveBy(oldScrollOffset.x, oldScrollOffset.y);
newDisplayPort.MoveBy(newScrollOffset.x, newScrollOffset.y);
if (fabsf(oldDisplayPort.x - newDisplayPort.x) < EPSILON &&
fabsf(oldDisplayPort.y - newDisplayPort.y) < EPSILON &&
fabsf(oldDisplayPort.width - newDisplayPort.width) < EPSILON &&
fabsf(oldDisplayPort.height - newDisplayPort.height) < EPSILON &&
mFrameMetrics.mResolution.width == mLastPaintRequestMetrics.mResolution.width) { mFrameMetrics.mResolution.width == mLastPaintRequestMetrics.mResolution.width) {
return; return;
} }
@ -788,8 +859,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
float rootScaleX = currentTransform.GetXScale(), float rootScaleX = currentTransform.GetXScale(),
rootScaleY = currentTransform.GetYScale(); rootScaleY = currentTransform.GetYScale();
nsIntPoint metricsScrollOffset(0, 0); gfx::Point metricsScrollOffset(0, 0);
nsIntPoint scrollOffset; gfx::Point scrollOffset;
float localScaleX, localScaleY; float localScaleX, localScaleY;
const FrameMetrics& frame = aLayer->GetFrameMetrics(); const FrameMetrics& frame = aLayer->GetFrameMetrics();
{ {
@ -813,7 +884,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
mEndZoomToMetrics.mResolution.width * sampledPosition + mEndZoomToMetrics.mResolution.width * sampledPosition +
mStartZoomToMetrics.mResolution.width * (1 - sampledPosition); mStartZoomToMetrics.mResolution.width * (1 - sampledPosition);
mFrameMetrics.mViewportScrollOffset = nsIntPoint( mFrameMetrics.mViewportScrollOffset = gfx::Point(
mEndZoomToMetrics.mViewportScrollOffset.x * sampledPosition + mEndZoomToMetrics.mViewportScrollOffset.x * sampledPosition +
mStartZoomToMetrics.mViewportScrollOffset.x * (1 - sampledPosition), mStartZoomToMetrics.mViewportScrollOffset.x * (1 - sampledPosition),
mEndZoomToMetrics.mViewportScrollOffset.y * sampledPosition + mEndZoomToMetrics.mViewportScrollOffset.y * sampledPosition +
@ -848,8 +919,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
} }
nsIntPoint scrollCompensation( nsIntPoint scrollCompensation(
(scrollOffset.x / rootScaleX - metricsScrollOffset.x) * localScaleX, NS_lround((scrollOffset.x / rootScaleX - metricsScrollOffset.x) * localScaleX),
(scrollOffset.y / rootScaleY - metricsScrollOffset.y) * localScaleY); NS_lround((scrollOffset.y / rootScaleY - metricsScrollOffset.y) * localScaleY));
ViewTransform treeTransform(-scrollCompensation, localScaleX, localScaleY); ViewTransform treeTransform(-scrollCompensation, localScaleX, localScaleY);
*aNewTransform = gfx3DMatrix(treeTransform) * currentTransform; *aNewTransform = gfx3DMatrix(treeTransform) * currentTransform;
@ -897,10 +968,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
// we get a larger displayport. This is very bad because we're wasting a // we get a larger displayport. This is very bad because we're wasting a
// paint and not initializating the displayport correctly. // paint and not initializating the displayport correctly.
RequestContentRepaint(); RequestContentRepaint();
// Assuming a first paint means a new page has been loaded, clear the flag
// indicating that we may have touch listeners.
mMayHaveTouchListeners = false;
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) { } else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect; mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect); SetPageRect(mFrameMetrics.mCSSContentRect);
@ -919,10 +986,6 @@ void AsyncPanZoomController::UpdateViewportSize(int aWidth, int aHeight) {
mFrameMetrics = metrics; mFrameMetrics = metrics;
} }
void AsyncPanZoomController::NotifyDOMTouchListenerAdded() {
mMayHaveTouchListeners = true;
}
void AsyncPanZoomController::CancelDefaultPanZoom() { void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true; mDisableNextTouchBatch = true;
if (mGestureEventListener) { if (mGestureEventListener) {
@ -932,7 +995,6 @@ void AsyncPanZoomController::CancelDefaultPanZoom() {
void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) { void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height)); gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height));
gfx::Rect cssPageRect = mFrameMetrics.mCSSContentRect;
SetState(ANIMATING_ZOOM); SetState(ANIMATING_ZOOM);
@ -940,13 +1002,15 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
MonitorAutoLock mon(mMonitor); MonitorAutoLock mon(mMonitor);
nsIntRect viewport = mFrameMetrics.mViewport; nsIntRect viewport = mFrameMetrics.mViewport;
gfx::Rect cssPageRect = mFrameMetrics.mCSSContentRect;
gfx::Point scrollOffset = mFrameMetrics.mViewportScrollOffset;
// If the rect is empty, treat it as a request to zoom out to the full page // If the rect is empty, treat it as a request to zoom out to the full page
// size. // size.
if (zoomToRect.IsEmpty()) { if (zoomToRect.IsEmpty()) {
nsIntRect cssViewport = viewport; nsIntRect cssViewport = viewport;
cssViewport.ScaleRoundIn(1 / mFrameMetrics.mResolution.width); cssViewport.ScaleRoundIn(1 / mFrameMetrics.mResolution.width);
cssViewport.MoveBy(mFrameMetrics.mViewportScrollOffset); cssViewport.MoveBy(nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y)));
float y = mFrameMetrics.mViewportScrollOffset.y; float y = mFrameMetrics.mViewportScrollOffset.y;
float newHeight = cssViewport.height * cssPageRect.width / cssViewport.width; float newHeight = cssViewport.height * cssPageRect.width / cssViewport.width;
@ -996,7 +1060,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
mStartZoomToMetrics = mFrameMetrics; mStartZoomToMetrics = mFrameMetrics;
mEndZoomToMetrics.mViewportScrollOffset = mEndZoomToMetrics.mViewportScrollOffset =
nsIntPoint(NS_lround(zoomToRect.x), NS_lround(zoomToRect.y)); gfx::Point(zoomToRect.x, zoomToRect.y);
mAnimationStartTime = TimeStamp::Now(); mAnimationStartTime = TimeStamp::Now();
@ -1004,10 +1068,50 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
} }
} }
void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
if (!mFrameMetrics.mMayHaveTouchListeners) {
mTouchQueue.Clear();
return;
}
if (mTouchListenerTimeoutTask) {
mTouchListenerTimeoutTask->Cancel();
mTouchListenerTimeoutTask = nullptr;
}
if (mState == WAITING_LISTENERS) {
if (!aPreventDefault) {
SetState(NOTHING);
}
mHandlingTouchQueue = true;
while (!mTouchQueue.IsEmpty()) {
if (!aPreventDefault) {
HandleInputEvent(mTouchQueue[0]);
}
if (mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_END ||
mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_CANCEL) {
mTouchQueue.RemoveElementAt(0);
break;
}
mTouchQueue.RemoveElementAt(0);
}
mHandlingTouchQueue = false;
}
}
void AsyncPanZoomController::SetState(PanZoomState aState) { void AsyncPanZoomController::SetState(PanZoomState aState) {
MonitorAutoLock monitor(mMonitor); MonitorAutoLock monitor(mMonitor);
mState = aState; mState = aState;
} }
void AsyncPanZoomController::TimeoutTouchListeners() {
ContentReceivedTouch(false);
}
} }
} }

View File

@ -15,6 +15,8 @@
#include "InputData.h" #include "InputData.h"
#include "Axis.h" #include "Axis.h"
#include "base/message_loop.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -76,10 +78,10 @@ public:
/** /**
* General handler for incoming input events. Manipulates the frame metrics * General handler for incoming input events. Manipulates the frame metrics
* basde on what type of input it is. For example, a PinchGestureEvent will * basde on what type of input it is. For example, a PinchGestureEvent will
* cause scaling. * cause scaling. This should only be called externally to this class.
* HandleInputEvent() should be used internally.
*/ */
nsEventStatus ReceiveInputEvent(const InputData& aEvent);
nsEventStatus HandleInputEvent(const InputData& aEvent);
/** /**
* Special handler for nsInputEvents. Also sets |aOutEvent| (which is assumed * Special handler for nsInputEvents. Also sets |aOutEvent| (which is assumed
@ -91,8 +93,8 @@ public:
* called on the main thread. See widget/InputData.h for more information on * called on the main thread. See widget/InputData.h for more information on
* why we have InputData and nsInputEvent separated. * why we have InputData and nsInputEvent separated.
*/ */
nsEventStatus HandleInputEvent(const nsInputEvent& aEvent, nsEventStatus ReceiveInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent); nsInputEvent* aOutEvent);
/** /**
* Updates the viewport size, i.e. the dimensions of the frame (not * Updates the viewport size, i.e. the dimensions of the frame (not
@ -107,16 +109,6 @@ public:
*/ */
void UpdateViewportSize(int aWidth, int aHeight); void UpdateViewportSize(int aWidth, int aHeight);
/**
* A DOM touch listener has been added. When called, we enable the machinery
* that allows touch listeners to preventDefault any touch inputs. This should
* not be called unless there are actually touch listeners as it introduces
* potentially unbounded lag because it causes a round-trip through content.
* Usually, if content is responding in a timely fashion, this only introduces
* a nearly constant few hundred ms of lag.
*/
void NotifyDOMTouchListenerAdded();
/** /**
* We have found a scrollable subframe, so disable our machinery until we hit * We have found a scrollable subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally * a touch end or a new touch start. This prevents us from accidentally
@ -134,6 +126,14 @@ public:
*/ */
void ZoomToRect(const gfxRect& aRect); void ZoomToRect(const gfxRect& aRect);
/**
* If we have touch listeners, this should always be called when we know
* definitively whether or not content has preventDefaulted any touch events
* that have come in. If |aPreventDefault| is true, any touch events in the
* queue will be discarded.
*/
void ContentReceivedTouch(bool aPreventDefault);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// These methods must only be called on the compositor thread. // These methods must only be called on the compositor thread.
// //
@ -194,6 +194,11 @@ public:
int GetDPI(); int GetDPI();
protected: protected:
/**
* Internal handler for ReceiveInputEvent(). Does all the actual work.
*/
nsEventStatus HandleInputEvent(const InputData& aEvent);
/** /**
* Helper method for touches beginning. Sets everything up for panning and any * Helper method for touches beginning. Sets everything up for panning and any
* multitouch gestures. * multitouch gestures.
@ -275,7 +280,7 @@ protected:
/** /**
* Scrolls the viewport by an X,Y offset. * Scrolls the viewport by an X,Y offset.
*/ */
void ScrollBy(const nsIntPoint& aOffset); void ScrollBy(const gfx::Point& aOffset);
/** /**
* Scales the viewport by an amount (note that it multiplies this scale in to * Scales the viewport by an amount (note that it multiplies this scale in to
@ -382,6 +387,15 @@ protected:
*/ */
const FrameMetrics& GetFrameMetrics(); const FrameMetrics& GetFrameMetrics();
/**
* Timeout function for touch listeners. This should be called on a timer
* after we get our first touch event in a batch, under the condition that we
* have touch listeners. If a notification comes indicating whether or not
* content preventDefaulted a series of touch events before the timeout, the
* timeout should be cancelled.
*/
void TimeoutTouchListeners();
private: private:
enum PanZoomState { enum PanZoomState {
NOTHING, /* no touch-start events received */ NOTHING, /* no touch-start events received */
@ -389,7 +403,10 @@ private:
TOUCHING, /* one touch-start event received */ TOUCHING, /* one touch-start event received */
PANNING, /* panning without axis lock */ PANNING, /* panning without axis lock */
PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */ PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
ANIMATING_ZOOM /* animated zoom to a new rect */ ANIMATING_ZOOM, /* animated zoom to a new rect */
WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has
put a finger down, but we don't yet know if a touch listener has
prevented the default actions yet. we still need to abort animations. */
}; };
enum ContentPainterStatus { enum ContentPainterStatus {
@ -443,6 +460,10 @@ private:
// |mResolution| fields on this. // |mResolution| fields on this.
FrameMetrics mEndZoomToMetrics; FrameMetrics mEndZoomToMetrics;
nsTArray<MultiTouchInput> mTouchQueue;
CancelableTask* mTouchListenerTimeoutTask;
AxisX mX; AxisX mX;
AxisY mY; AxisY mY;
@ -478,14 +499,16 @@ private:
// requests a repaint. // requests a repaint.
ContentPainterStatus mContentPainterStatus; ContentPainterStatus mContentPainterStatus;
// Whether or not we might have touch listeners. This is a conservative
// approximation and may not be accurate.
bool mMayHaveTouchListeners;
// Flag used to determine whether or not we should disable handling of the // Flag used to determine whether or not we should disable handling of the
// next batch of touch events. This is used for sync scrolling of subframes. // next batch of touch events. This is used for sync scrolling of subframes.
bool mDisableNextTouchBatch; 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;
friend class Axis; friend class Axis;
}; };

View File

@ -23,13 +23,13 @@ static const float MAX_EVENT_ACCELERATION = 0.5f;
/** /**
* Amount of friction applied during flings. * Amount of friction applied during flings.
*/ */
static const float FLING_FRICTION = 0.013f; static const float FLING_FRICTION = 0.007f;
/** /**
* Threshold for velocity beneath which we turn off any acceleration we had * Threshold for velocity beneath which we turn off any acceleration we had
* during repeated flings. * during repeated flings.
*/ */
static const float VELOCITY_THRESHOLD = 0.1f; static const float VELOCITY_THRESHOLD = 0.14f;
/** /**
* Amount of acceleration we multiply in each time the user flings in one * Amount of acceleration we multiply in each time the user flings in one
@ -94,10 +94,10 @@ void Axis::StartTouch(int32_t aPos) {
mLockPanning = false; mLockPanning = false;
} }
int32_t Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) { float Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) {
float velocityFactor = powf(ACCELERATION_MULTIPLIER, float velocityFactor = powf(ACCELERATION_MULTIPLIER,
NS_MAX(0, (mAcceleration - 4) * 3)); NS_MAX(0, (mAcceleration - 4) * 3));
int32_t displacement = NS_lround(mVelocity * aScale * aDelta.ToMilliseconds() * velocityFactor); float displacement = mVelocity * aScale * aDelta.ToMilliseconds() * velocityFactor;
// If this displacement will cause an overscroll, throttle it. Can potentially // If this displacement will cause an overscroll, throttle it. Can potentially
// bring it to 0 even if the velocity is high. // bring it to 0 even if the velocity is high.
if (DisplacementWillOverscroll(displacement) != OVERSCROLL_NONE) { if (DisplacementWillOverscroll(displacement) != OVERSCROLL_NONE) {
@ -158,7 +158,7 @@ Axis::Overscroll Axis::GetOverscroll() {
return OVERSCROLL_NONE; return OVERSCROLL_NONE;
} }
int32_t Axis::GetExcess() { float Axis::GetExcess() {
switch (GetOverscroll()) { switch (GetOverscroll()) {
case OVERSCROLL_MINUS: return GetOrigin() - GetPageStart(); case OVERSCROLL_MINUS: return GetOrigin() - GetPageStart();
case OVERSCROLL_PLUS: return GetViewportEnd() - GetPageEnd(); case OVERSCROLL_PLUS: return GetViewportEnd() - GetPageEnd();
@ -186,7 +186,7 @@ Axis::Overscroll Axis::DisplacementWillOverscroll(int32_t aDisplacement) {
return OVERSCROLL_NONE; return OVERSCROLL_NONE;
} }
int32_t Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) { float Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) {
switch (DisplacementWillOverscroll(aDisplacement)) { switch (DisplacementWillOverscroll(aDisplacement)) {
case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart(); case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart();
case OVERSCROLL_PLUS: return (GetViewportEnd() + aDisplacement) - GetPageEnd(); case OVERSCROLL_PLUS: return (GetViewportEnd() + aDisplacement) - GetPageEnd();
@ -197,11 +197,11 @@ int32_t Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) {
} }
Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) { Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) {
int32_t originAfterScale = NS_lround((GetOrigin() + aFocus) * aScale - aFocus); float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus;
bool both = ScaleWillOverscrollBothSides(aScale); bool both = ScaleWillOverscrollBothSides(aScale);
bool minus = originAfterScale < NS_lround(GetPageStart() * aScale); bool minus = originAfterScale < GetPageStart() * aScale;
bool plus = (originAfterScale + GetViewportLength()) > NS_lround(GetPageEnd() * aScale); bool plus = (originAfterScale + GetViewportLength()) > GetPageEnd() * aScale;
if ((minus && plus) || both) { if ((minus && plus) || both) {
return OVERSCROLL_BOTH; return OVERSCROLL_BOTH;
@ -215,11 +215,11 @@ Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) {
return OVERSCROLL_NONE; return OVERSCROLL_NONE;
} }
int32_t Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) { float Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) {
int32_t originAfterScale = NS_lround((GetOrigin() + aFocus) * aScale - aFocus); float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus;
switch (ScaleWillOverscroll(aScale, aFocus)) { switch (ScaleWillOverscroll(aScale, aFocus)) {
case OVERSCROLL_MINUS: return originAfterScale - NS_lround(GetPageStart() * aScale); case OVERSCROLL_MINUS: return originAfterScale - GetPageStart() * aScale;
case OVERSCROLL_PLUS: return (originAfterScale + GetViewportLength()) - NS_lround(GetPageEnd() * aScale); case OVERSCROLL_PLUS: return (originAfterScale + GetViewportLength()) - GetPageEnd() * aScale;
// Don't handle OVERSCROLL_BOTH. Client code is expected to deal with it. // Don't handle OVERSCROLL_BOTH. Client code is expected to deal with it.
default: return 0; default: return 0;
} }
@ -229,32 +229,32 @@ float Axis::GetVelocity() {
return mVelocity; return mVelocity;
} }
int32_t Axis::GetViewportEnd() { float Axis::GetViewportEnd() {
return GetOrigin() + GetViewportLength(); return GetOrigin() + GetViewportLength();
} }
int32_t Axis::GetPageEnd() { float Axis::GetPageEnd() {
return GetPageStart() + GetPageLength(); return GetPageStart() + GetPageLength();
} }
int32_t Axis::GetOrigin() { float Axis::GetOrigin() {
nsIntPoint origin = mAsyncPanZoomController->GetFrameMetrics().mViewportScrollOffset; gfx::Point origin = mAsyncPanZoomController->GetFrameMetrics().mViewportScrollOffset;
return GetPointOffset(origin); return GetPointOffset(origin);
} }
int32_t Axis::GetViewportLength() { float Axis::GetViewportLength() {
nsIntRect viewport = mAsyncPanZoomController->GetFrameMetrics().mViewport; nsIntRect viewport = mAsyncPanZoomController->GetFrameMetrics().mViewport;
gfx::Rect scaledViewport = gfx::Rect(viewport.x, viewport.y, viewport.width, viewport.height); gfx::Rect scaledViewport = gfx::Rect(viewport.x, viewport.y, viewport.width, viewport.height);
scaledViewport.ScaleRoundIn(1 / mAsyncPanZoomController->GetFrameMetrics().mResolution.width); scaledViewport.ScaleRoundIn(1 / mAsyncPanZoomController->GetFrameMetrics().mResolution.width);
return GetRectLength(scaledViewport); return GetRectLength(scaledViewport);
} }
int32_t Axis::GetPageStart() { float Axis::GetPageStart() {
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect; gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
return GetRectOffset(pageRect); return GetRectOffset(pageRect);
} }
int32_t Axis::GetPageLength() { float Axis::GetPageLength() {
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect; gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
return GetRectLength(pageRect); return GetRectLength(pageRect);
} }
@ -280,19 +280,19 @@ AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
} }
int32_t AxisX::GetPointOffset(const nsIntPoint& aPoint) float AxisX::GetPointOffset(const gfx::Point& aPoint)
{ {
return aPoint.x; return aPoint.x;
} }
int32_t AxisX::GetRectLength(const gfx::Rect& aRect) float AxisX::GetRectLength(const gfx::Rect& aRect)
{ {
return NS_lround(aRect.width); return aRect.width;
} }
int32_t AxisX::GetRectOffset(const gfx::Rect& aRect) float AxisX::GetRectOffset(const gfx::Rect& aRect)
{ {
return NS_lround(aRect.x); return aRect.x;
} }
AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController) AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
@ -301,19 +301,19 @@ AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
} }
int32_t AxisY::GetPointOffset(const nsIntPoint& aPoint) float AxisY::GetPointOffset(const gfx::Point& aPoint)
{ {
return aPoint.y; return aPoint.y;
} }
int32_t AxisY::GetRectLength(const gfx::Rect& aRect) float AxisY::GetRectLength(const gfx::Rect& aRect)
{ {
return NS_lround(aRect.height); return aRect.height;
} }
int32_t AxisY::GetRectOffset(const gfx::Rect& aRect) float AxisY::GetRectOffset(const gfx::Rect& aRect)
{ {
return NS_lround(aRect.y); return aRect.y;
} }
} }

View File

@ -84,7 +84,7 @@ public:
* apply a displacement that takes you to the boundary of the page, then call * apply a displacement that takes you to the boundary of the page, then call
* it again. The result will be different in this case. * it again. The result will be different in this case.
*/ */
int32_t GetDisplacementForDuration(float aScale, const TimeDuration& aDelta); float GetDisplacementForDuration(float aScale, const TimeDuration& aDelta);
/** /**
* Gets the distance between the starting position of the touch supplied in * Gets the distance between the starting position of the touch supplied in
@ -114,7 +114,7 @@ public:
* in both directions, this returns 0; it assumes that you check * in both directions, this returns 0; it assumes that you check
* GetOverscroll() first. * GetOverscroll() first.
*/ */
int32_t GetExcess(); float GetExcess();
/** /**
* Gets the raw velocity of this axis at this moment. * Gets the raw velocity of this axis at this moment.
@ -132,7 +132,7 @@ public:
* If a displacement will overscroll the axis, this returns the amount and in * If a displacement will overscroll the axis, this returns the amount and in
* what direction. Similar to getExcess() but takes a displacement to apply. * what direction. Similar to getExcess() but takes a displacement to apply.
*/ */
int32_t DisplacementWillOverscrollAmount(int32_t aDisplacement); float DisplacementWillOverscrollAmount(int32_t aDisplacement);
/** /**
* Gets the overscroll state of the axis given a scaling of the page. That is * Gets the overscroll state of the axis given a scaling of the page. That is
@ -153,7 +153,7 @@ public:
* scroll offset in such a way that it remains in the same place on the page * scroll offset in such a way that it remains in the same place on the page
* relative. * relative.
*/ */
int32_t ScaleWillOverscrollAmount(float aScale, int32_t aFocus); float ScaleWillOverscrollAmount(float aScale, int32_t aFocus);
/** /**
* Checks if an axis will overscroll in both directions by computing the * Checks if an axis will overscroll in both directions by computing the
@ -164,16 +164,16 @@ public:
*/ */
bool ScaleWillOverscrollBothSides(float aScale); bool ScaleWillOverscrollBothSides(float aScale);
int32_t GetOrigin(); float GetOrigin();
int32_t GetViewportLength(); float GetViewportLength();
int32_t GetPageStart(); float GetPageStart();
int32_t GetPageLength(); float GetPageLength();
int32_t GetViewportEnd(); float GetViewportEnd();
int32_t GetPageEnd(); float GetPageEnd();
virtual int32_t GetPointOffset(const nsIntPoint& aPoint) = 0; virtual float GetPointOffset(const gfx::Point& aPoint) = 0;
virtual int32_t GetRectLength(const gfx::Rect& aRect) = 0; virtual float GetRectLength(const gfx::Rect& aRect) = 0;
virtual int32_t GetRectOffset(const gfx::Rect& aRect) = 0; virtual float GetRectOffset(const gfx::Rect& aRect) = 0;
protected: protected:
int32_t mPos; int32_t mPos;
@ -192,17 +192,17 @@ protected:
class AxisX : public Axis { class AxisX : public Axis {
public: public:
AxisX(AsyncPanZoomController* mAsyncPanZoomController); AxisX(AsyncPanZoomController* mAsyncPanZoomController);
virtual int32_t GetPointOffset(const nsIntPoint& aPoint); virtual float GetPointOffset(const gfx::Point& aPoint);
virtual int32_t GetRectLength(const gfx::Rect& aRect); virtual float GetRectLength(const gfx::Rect& aRect);
virtual int32_t GetRectOffset(const gfx::Rect& aRect); virtual float GetRectOffset(const gfx::Rect& aRect);
}; };
class AxisY : public Axis { class AxisY : public Axis {
public: public:
AxisY(AsyncPanZoomController* mAsyncPanZoomController); AxisY(AsyncPanZoomController* mAsyncPanZoomController);
virtual int32_t GetPointOffset(const nsIntPoint& aPoint); virtual float GetPointOffset(const gfx::Point& aPoint);
virtual int32_t GetRectLength(const gfx::Rect& aRect); virtual float GetRectLength(const gfx::Rect& aRect);
virtual int32_t GetRectOffset(const gfx::Rect& aRect); virtual float GetRectOffset(const gfx::Rect& aRect);
}; };
} }

View File

@ -761,7 +761,9 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
if (mIsFirstPaint) { if (mIsFirstPaint) {
mContentRect = metrics.mContentRect; mContentRect = metrics.mContentRect;
SetFirstPaintViewport(metrics.mViewportScrollOffset, const gfx::Point& scrollOffset = metrics.mViewportScrollOffset;
SetFirstPaintViewport(nsIntPoint(NS_lround(scrollOffset.x),
NS_lround(scrollOffset.y)),
1/rootScaleX, 1/rootScaleX,
mContentRect, mContentRect,
metrics.mCSSContentRect); metrics.mCSSContentRect);
@ -775,9 +777,9 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
// notifications, so that Java can take these into account in its response. // notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java // Calculate the absolute display port to send to Java
nsIntRect displayPort = metrics.mDisplayPort; nsIntRect displayPort = metrics.mDisplayPort;
nsIntPoint scrollOffset = metrics.mViewportScrollOffset; gfx::Point scrollOffset = metrics.mViewportScrollOffset;
displayPort.x += scrollOffset.x; displayPort.x += NS_lround(scrollOffset.x);
displayPort.y += scrollOffset.y; displayPort.y += NS_lround(scrollOffset.y);
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated, SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale); mScrollOffset, mXScale, mYScale);
@ -794,7 +796,8 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
nsIntPoint metricsScrollOffset(0, 0); nsIntPoint metricsScrollOffset(0, 0);
if (metrics.IsScrollable()) { if (metrics.IsScrollable()) {
metricsScrollOffset = metrics.mViewportScrollOffset; metricsScrollOffset =
nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y));
} }
nsIntPoint scrollCompensation( nsIntPoint scrollCompensation(

View File

@ -202,7 +202,7 @@ nsEventStatus GestureEventListener::HandlePinchGestureEvent(const MultiTouchInpu
currentSpan, currentSpan,
currentSpan); currentSpan);
mAsyncPanZoomController->HandleInputEvent(pinchEvent); mAsyncPanZoomController->ReceiveInputEvent(pinchEvent);
mState = GESTURE_PINCH; mState = GESTURE_PINCH;
} }
@ -216,7 +216,7 @@ nsEventStatus GestureEventListener::HandlePinchGestureEvent(const MultiTouchInpu
currentSpan, currentSpan,
mPreviousSpan); mPreviousSpan);
mAsyncPanZoomController->HandleInputEvent(pinchEvent); mAsyncPanZoomController->ReceiveInputEvent(pinchEvent);
break; break;
} }
default: default:
@ -234,7 +234,7 @@ nsEventStatus GestureEventListener::HandlePinchGestureEvent(const MultiTouchInpu
1.0f, 1.0f,
1.0f); 1.0f);
mAsyncPanZoomController->HandleInputEvent(pinchEvent); mAsyncPanZoomController->ReceiveInputEvent(pinchEvent);
mState = GESTURE_NONE; mState = GESTURE_NONE;
@ -251,13 +251,13 @@ nsEventStatus GestureEventListener::HandlePinchGestureEvent(const MultiTouchInpu
nsEventStatus GestureEventListener::HandleSingleTapUpEvent(const MultiTouchInput& aEvent) nsEventStatus GestureEventListener::HandleSingleTapUpEvent(const MultiTouchInput& aEvent)
{ {
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_UP, aEvent.mTime, aEvent.mTouches[0].mScreenPoint); TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_UP, aEvent.mTime, aEvent.mTouches[0].mScreenPoint);
return mAsyncPanZoomController->HandleInputEvent(tapEvent); return mAsyncPanZoomController->ReceiveInputEvent(tapEvent);
} }
nsEventStatus GestureEventListener::HandleSingleTapConfirmedEvent(const MultiTouchInput& aEvent) nsEventStatus GestureEventListener::HandleSingleTapConfirmedEvent(const MultiTouchInput& aEvent)
{ {
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_CONFIRMED, aEvent.mTime, aEvent.mTouches[0].mScreenPoint); TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_CONFIRMED, aEvent.mTime, aEvent.mTouches[0].mScreenPoint);
return mAsyncPanZoomController->HandleInputEvent(tapEvent); return mAsyncPanZoomController->ReceiveInputEvent(tapEvent);
} }
nsEventStatus GestureEventListener::HandleTapCancel(const MultiTouchInput& aEvent) nsEventStatus GestureEventListener::HandleTapCancel(const MultiTouchInput& aEvent)
@ -280,7 +280,7 @@ nsEventStatus GestureEventListener::HandleTapCancel(const MultiTouchInput& aEven
nsEventStatus GestureEventListener::HandleDoubleTap(const MultiTouchInput& aEvent) nsEventStatus GestureEventListener::HandleDoubleTap(const MultiTouchInput& aEvent)
{ {
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_DOUBLE, aEvent.mTime, aEvent.mTouches[0].mScreenPoint); TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_DOUBLE, aEvent.mTime, aEvent.mTouches[0].mScreenPoint);
return mAsyncPanZoomController->HandleInputEvent(tapEvent); return mAsyncPanZoomController->ReceiveInputEvent(tapEvent);
} }
void GestureEventListener::TimeoutDoubleTap() void GestureEventListener::TimeoutDoubleTap()

View File

@ -8,6 +8,8 @@
#include "InputData.h" #include "InputData.h"
#include "Axis.h" #include "Axis.h"
#include "base/message_loop.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {

View File

@ -220,7 +220,9 @@ ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
TransformBounds(gfxRect(parentMetrics.mDisplayPort)); TransformBounds(gfxRect(parentMetrics.mDisplayPort));
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics(); const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const nsIntSize& contentSize = metrics.mContentRect.Size(); const nsIntSize& contentSize = metrics.mContentRect.Size();
const nsIntPoint& contentOrigin = metrics.mContentRect.TopLeft() - metrics.mViewportScrollOffset; const gfx::Point& scrollOffset = metrics.mViewportScrollOffset;
const nsIntPoint& contentOrigin = metrics.mContentRect.TopLeft() -
nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y));
gfxRect contentRect = gfxRect(contentOrigin.x, contentOrigin.y, gfxRect contentRect = gfxRect(contentOrigin.x, contentOrigin.y,
contentSize.width, contentSize.height); contentSize.width, contentSize.height);
contentBounds = scrollableLayer->GetEffectiveTransform().TransformBounds(contentRect); contentBounds = scrollableLayer->GetEffectiveTransform().TransformBounds(contentRect);

View File

@ -535,6 +535,12 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
} }
#endif // ANDROID #endif // ANDROID
#ifdef MOZ_WIDGET_GONK
if (const char *ldPreloadPath = getenv("LD_PRELOAD")) {
newEnvVars["LD_PRELOAD"] = ldPreloadPath;
}
#endif // MOZ_WIDGET_GONK
// remap the IPC socket fd to a well-known int, as the OS does for // remap the IPC socket fd to a well-known int, as the OS does for
// STDOUT_FILENO, for example // STDOUT_FILENO, for example
int srcChannelFd, dstChannelFd; int srcChannelFd, dstChannelFd;

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