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
ifdef ENABLE_MARIONETTE
DEFINES += -DENABLE_MARIONETTE=1
endif
ifndef LIBXUL_SDK
PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)

View File

@ -432,9 +432,11 @@ pref("full-screen-api.ignore-widgets", true);
pref("media.volume.steps", 10);
#ifdef ENABLE_MARIONETTE
//Enable/disable marionette server, set listening port
pref("marionette.defaultPrefs.enabled", true);
pref("marionette.defaultPrefs.port", 2828);
#endif
#ifdef MOZ_UPDATER
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
ac_add_options --with-ccache
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
# Enable dump() from JS.
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-profiling
ac_add_options --with-ccache
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
# Enable dump() from JS.
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
#ac_add_options --with-ccache
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
# 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"

View File

@ -14,7 +14,7 @@ ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols
ac_add_options --enable-profiling
#ac_add_options --with-ccache
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
# 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"

View File

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

View File

@ -35,6 +35,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
#B2G options
ac_add_options --enable-application=b2g
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
ac_add_options --disable-elf-hack
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-debug-symbols
ac_add_options --with-ccache
ac_add_options --enable-marionette
ENABLE_MARIONETTE=1
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -380,10 +380,6 @@ social.pageShared.label=Page shared
social.enable.label=%S integration
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)
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;
}
#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 ****/
.editBookmarkPanelHeaderButton,
.editBookmarkPanelBottomButton {
@hudButton@
margin: 6px;
min-width: 79px;
margin: 0;
min-width: 82px;
min-height: 22px;
}
@ -1355,47 +1384,45 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
margin-bottom: 6px;
}
.editBookmarkPanelBottomButton:last-child {
-moz-margin-start: 8px;
}
/* The following elements come from editBookmarkOverlay.xul. Styling that's
specific to the editBookmarkPanel should be in browser.css. Styling that
should be shared by all editBookmarkOverlay.xul consumers should be in
editBookmarkOverlay.css. */
#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-clip: padding-box;
border-radius: 0 0 3px 3px;
border: 1px solid rgba(0,0,0,.3);
border-top: none;
box-shadow: inset 0 -1px 2px rgba(0,0,0,.2),
inset 0 1px 0 rgba(255,255,255,.15),
0 1px 0 rgba(255,255,255,.15);
border: 1px solid #a5a5a5;
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);
margin: 0;
padding: 0;
margin-left: 4px;
margin-right: 4px;
margin-bottom: 8px;
height: 20px;
}
#editBMPanel_newFolderButton {
-moz-appearance: none;
border: 0;
-moz-border-end-width: 3px;
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);
border: 0 solid #a5a5a5;
-moz-border-end-width: 1px;
padding: 0 9px;
margin: 0;
min-width: 21px;
min-height: 20px;
height: 20px;
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;
}
#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);
}
@ -1409,10 +1436,13 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
#editBMPanel_folderMenuList {
@hudButton@
border-radius: 3px;
background-clip: padding-box;
margin: 0;
min-height: 22px;
-moz-padding-start: 4px;
-moz-padding-end: 0;
padding-top: 2px;
padding-bottom: 1px;
-moz-padding-start: 8px;
-moz-padding-end: 4px;
}
#editBMPanel_folderMenuList:-moz-focusring {
@ -1431,101 +1461,42 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
border: 0;
margin: 0;
padding: 0;
-moz-padding-end: 4px;
width: 7px;
}
#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 ****/
#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);
}
/**** folder tree and tag selector ****/
#editBMPanel_folderTree,
#editBMPanel_tagsSelector {
-moz-appearance: none;
border-radius: 2px;
background-color: rgba(50,50,50,1);
background: linear-gradient(#fafafa, #fff);
background-clip: padding-box;
border-radius: 3px;
border: 1px solid rgba(0,0,0,.3);
border-bottom: none;
box-shadow: inset 0 1px 2px rgba(0,0,0,.15),
0 1px 0 rgba(255,255,255,.15);
color: #fff;
box-shadow: inset 0 1px 1px 1px rgba(0,0,0,.05),
0 1px rgba(255,255,255,.3);
margin: 0;
}
#editBMPanel_folderTree:-moz-focusring,
#editBMPanel_tagsSelector:-moz-focusring {
@hudButtonFocused@
border-color: -moz-mac-focusring;
box-shadow: @focusRingShadow@;
}
#editBMPanel_tagsSelector .listcell-check {
-moz-appearance: none;
border: 0;
background: url("chrome://browser/skin/hud-style-check-box-empty.png") no-repeat 50% 50%;
min-height: 14px;
min-width: 14px;
}
#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;
#editBMPanel_folderTree {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
margin: 0 !important;
min-width: 27em;
position: relative;
}
/**** expanders ****/
@ -1533,13 +1504,10 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
#editBookmarkPanel .expander-up,
#editBookmarkPanel .expander-down {
@hudButton@
border-radius: 3px;
margin: 0;
-moz-margin-start: 4px;
-moz-margin-end: 2px;
padding: 0;
-moz-padding-start: 4px;
min-width: 10px;
min-height: 20px;
min-width: 27px;
min-height: 22px;
}
#editBookmarkPanel .expander-up:-moz-focusring,
@ -1553,36 +1521,27 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
}
#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 {
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 {
-moz-appearance: none !important;
-moz-padding-start: 3px !important;
margin: 2px !important;
border: 1px solid rgba(0,0,0,.5) !important;
box-shadow: inset 0 1px 0 rgba(0,0,0,.3);
background-color: #666 !important;
background-clip: padding-box;
background-origin: padding-box;
color: #fff !important;
min-height: 20px;
#editBookmarkPanel .expander-up .button-icon,
#editBookmarkPanel .expander-down .button-icon {
margin: 1px 0 0;
}
#editBookmarkPanel .expander-up .button-text,
#editBookmarkPanel .expander-down .button-text {
display: none;
}
#editBMPanel_tagsField > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input:-moz-placeholder {
color: #bbb;
}
#editBMPanel_tagsField[focused="true"] {
@hudButtonFocused@
background-color: #eee !important;
color: #000 !important;
}
.editBMPanel_rowLabel {
text-align: end;
}
@ -1590,16 +1549,11 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
.panel-promo-box {
margin: 8px -16px -16px -16px;
padding: 8px 16px;
background-color: hsla(0,0%,7%,.3);
border-top: 1px solid hsla(0,0%,100%,.1);
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
box-shadow: 0 1px 1px hsla(0,0%,0%,.25) inset;
color: hsl(0,0%,60%);
}
.panel-promo-message > .text-link {
color: hsl(210,100%,75%);
background: #e5e5e5;
border-top: 1px solid hsla(0,0%,0%,.1);
border-radius: 0 0 5px 5px;
box-shadow: 0 -1px hsla(0,0%,100%,.5) inset, 0 1px 1px hsla(0,0%,0%,.03) inset;
color: #808080;
}
.panel-promo-icon {
@ -1609,7 +1563,7 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
}
.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);
border: none;
-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.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon {
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 {
@ -2377,18 +2331,15 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
#notification-popup .text-link {
color: #fff;
#notification-popup .text-link, .panel-arrowcontent .text-link {
color: #0073e6;
text-decoration: none;
}
.geolocation-text-link {
-moz-margin-start: 0; /* override default label margin to match description margin */
}
.telemetry-text-link {
color: #fff;
}
#addons-notification-icon {
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 {
border-top: 1px solid hsla(0,0%,100%,.1);
background-color: hsla(0,0%,7%,.3);
box-shadow: 0 1px 1px hsla(0,0%,0%,.25) inset;
background: #e5e5e5;
border-top: 1px solid hsla(0,0%,0%,.1);
box-shadow: 0 -1px hsla(0,0%,100%,.5) inset, 0 1px 1px hsla(0,0%,0%,.03) inset;
}
#downloadsHistory > .button-box {
color: #808080;
margin: 1em;
}
@ -78,7 +79,6 @@ richlistitem[type="download"]:last-child {
}
.downloadInfo {
color: white;
padding: 8px;
-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-64.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-icons-generic.png
skin/classic/browser/identity-icons-https.png
@ -37,6 +30,9 @@ browser.jar:
skin/classic/browser/KUI-close.png
skin/classic/browser/menu-back.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/pageInfo.css
skin/classic/browser/Privacy-16.png
@ -45,7 +41,7 @@ browser.jar:
skin/classic/browser/searchbar-dropmarker.png
skin/classic/browser/searchbar.css
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/Toolbar.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 ../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 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 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 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;

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_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_D3DCOMPILER_DLL=D3DCompiler_$MOZ_D3DX9_VERSION.dll
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.
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

View File

@ -5055,42 +5055,37 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
ret.defaultZoom = 1.0;
ret.autoSize = true;
ret.allowZoom = true;
ret.autoScale = true;
// 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<nsIDOMDocument>
domDoc(do_QueryInterface(aDocument));
nsCOMPtr<nsIDOMDocumentType> docType;
nsresult rv = domDoc->GetDoctype(getter_AddRefs(docType));
if (NS_SUCCEEDED(rv) && docType) {
nsAutoString docId;
rv = docType->GetPublicId(docId);
if (NS_SUCCEEDED(rv)) {
if ((docId.Find("WAP") != -1) ||
(docId.Find("Mobile") != -1) ||
(docId.Find("WML") != -1))
{
return ret;
nsAutoString viewport;
aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
if (viewport.IsEmpty()) {
// 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<nsIDOMDocument> domDoc(do_QueryInterface(aDocument));
nsCOMPtr<nsIDOMDocumentType> docType;
nsresult rv = domDoc->GetDoctype(getter_AddRefs(docType));
if (NS_SUCCEEDED(rv) && docType) {
nsAutoString docId;
rv = docType->GetPublicId(docId);
if (NS_SUCCEEDED(rv)) {
if ((docId.Find("WAP") != -1) ||
(docId.Find("Mobile") != -1) ||
(docId.Find("WML") != -1))
{
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;
aDocument->GetHeaderData(nsGkAtoms::minimum_scale, minScaleStr);
aDocument->GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
nsresult errorCode;
float scaleMinFloat = minScaleStr.ToFloat(&errorCode);
@ -5103,7 +5098,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
scaleMinFloat = NS_MAX(scaleMinFloat, kViewportMinScale);
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,
// because they are used later (see the width calculations).
@ -5239,6 +5234,8 @@ nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
/* We never fail. */
nsresult rv = NS_OK;
aDocument->SetHeaderData(nsGkAtoms::viewport, viewportInfo);
/* Iterators. */
nsAString::const_iterator tip, tail, end;
viewportInfo.BeginReading(tip);

View File

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

View File

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

View File

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

View File

@ -5135,9 +5135,7 @@ nsDocShell::SetIsActive(bool aIsActive)
continue;
}
bool isContentBoundary = false;
docshell->GetIsContentBoundary(&isContentBoundary);
if (!isContentBoundary) {
if (!docshell->GetIsContentBoundary()) {
docshell->SetIsActive(aIsActive);
}
}
@ -12268,22 +12266,21 @@ nsDocShell::GetFrameType()
return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{
*aIsBrowser = (GetFrameType() == eFrameTypeBrowser);
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
*aIsApp = (GetFrameType() == eFrameTypeApp);
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
{
switch (GetFrameType()) {
@ -12299,21 +12296,21 @@ nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser);
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInApp(bool* aIsInApp)
{
*aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
{
switch (GetInheritedFrameType()) {
@ -12339,7 +12336,7 @@ nsDocShell::SetAppId(uint32_t aAppId)
return NS_OK;
}
NS_IMETHODIMP
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetAppId(uint32_t* aAppId)
{
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.
*/
readonly attribute boolean isBrowserElement;
[infallible] readonly attribute boolean isBrowserElement;
/**
* 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
* content boundary.
*/
readonly attribute boolean isContentBoundary;
[infallible] readonly attribute boolean isContentBoundary;
/**
* 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
@ -625,13 +625,13 @@ interface nsIDocShell : nsISupports
* If you're doing a security check, use the content's principal instead of
* this method.
*/
readonly attribute boolean isInApp;
[infallible] readonly attribute boolean isInApp;
/**
* Returns if the docshell has a docshell that behaves as a content boundary
* 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
@ -650,7 +650,7 @@ interface nsIDocShell : nsISupports
* Returns the app id of the app the docshell is in. Returns
* 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

View File

@ -7,7 +7,7 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
@ -31,7 +31,7 @@ function ActivityRequestHandler() {
// When a system message of type 'activity' is emitted, it forces the
// creation of an ActivityWrapper which in turns replace the default
// 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
// object contains by the request handler.
this._id = null;
@ -40,6 +40,12 @@ function ActivityRequestHandler() {
}
ActivityRequestHandler.prototype = {
__exposedProps__: {
source: "r",
postResult: "r",
postError: "r"
},
get source() {
return this._options;
},

View File

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

View File

@ -56,6 +56,7 @@
#include "nsIDOMGlobalPropertyInitializer.h"
using namespace mozilla::dom::power;
using namespace mozilla::dom::sms;
// This should not be in the namespace.
DOMCI_DATA(Navigator, mozilla::dom::Navigator)
@ -1064,61 +1065,6 @@ Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLoc
// 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
Navigator::IsSmsSupported() const
{
@ -1141,15 +1087,15 @@ Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
*aSmsManager = nullptr;
if (!mSmsManager) {
if (!IsSmsSupported() || !IsSmsAllowed()) {
if (!IsSmsSupported()) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
mSmsManager = new sms::SmsManager();
mSmsManager->Init(window);
mSmsManager = SmsManager::CheckPermissionAndCreateInstance(window);
NS_ENSURE_TRUE(mSmsManager, NS_OK);
}
NS_ADDREF(*aSmsManager = mSmsManager);

View File

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

View File

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

View File

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

View File

@ -328,12 +328,6 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
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),
DestroyNsRect);

View File

@ -2973,9 +2973,7 @@ nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
return NS_OK;
}
bool isContentBoundary = false;
mDocShell->GetIsContentBoundary(&isContentBoundary);
if (isContentBoundary) {
if (mDocShell->GetIsContentBoundary()) {
nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
parent.swap(*aParent);
return NS_OK;
@ -3082,12 +3080,8 @@ nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
// If we're contained in <iframe mozbrowser>, then GetContent is the same as
// window.top.
if (mDocShell) {
bool belowContentBoundary = false;
mDocShell->GetIsBelowContentBoundary(&belowContentBoundary);
if (belowContentBoundary) {
return GetScriptableTop(aContent);
}
if (mDocShell && mDocShell->GetIsBelowContentBoundary()) {
return GetScriptableTop(aContent);
}
nsCOMPtr<nsIDocShellTreeItem> primaryContent;
@ -6490,13 +6484,8 @@ nsGlobalWindow::Close()
{
FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
bool isContentBoundary = false;
if (mDocShell) {
mDocShell->GetIsContentBoundary(&isContentBoundary);
}
if ((!isContentBoundary && IsFrame()) ||
!mDocShell || IsInModalState()) {
if (!mDocShell || IsInModalState() ||
(IsFrame() && !mDocShell->GetIsContentBoundary())) {
// 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
// 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);
*aFrameElement = NULL;
if (!mDocShell) {
return NS_OK;
}
bool isContentBoundary = false;
mDocShell->GetIsContentBoundary(&isContentBoundary);
if (isContentBoundary) {
if (!mDocShell || mDocShell->GetIsContentBoundary()) {
return NS_OK;
}

View File

@ -147,6 +147,7 @@ static bool sCCLockedOut;
static PRTime sCCLockedOutTime;
static js::GCSliceCallback sPrevGCSliceCallback;
static js::AnalysisPurgeCallback sPrevAnalysisPurgeCallback;
// The number of currently pending document loads. This count isn'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 PRTime
GetCollectionTimeDelta()
{
PRTime now = PR_Now();
if (sFirstCollectionTime) {
return now - sFirstCollectionTime;
}
sFirstCollectionTime = now;
return 0;
}
class nsMemoryPressureObserver MOZ_FINAL : public nsIObserver
{
public:
@ -3117,12 +3129,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
PRTime delta = 0;
if (sFirstCollectionTime) {
delta = now - sFirstCollectionTime;
} else {
sFirstCollectionTime = now;
}
PRTime delta = GetCollectionTimeDelta();
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
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");
if (aProgress == js::GC_CYCLE_END) {
PRTime now = PR_Now();
PRTime delta = 0;
if (sFirstCollectionTime) {
delta = now - sFirstCollectionTime;
} else {
sFirstCollectionTime = now;
}
PRTime delta = GetCollectionTimeDelta();
if (sPostGCEventsToConsole) {
NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) ");
@ -3531,7 +3532,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
if (sPostGCEventsToConsole || sPostGCEventsToObserver) {
nsString json;
json.Adopt(aDesc.formatJSON(aRt, now));
json.Adopt(aDesc.formatJSON(aRt, PR_Now()));
nsRefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
NS_DispatchToMainThread(notify);
}
@ -3588,6 +3589,32 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
(*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
// in nsJSRuntime below...
nsresult
@ -4004,6 +4031,7 @@ nsJSRuntime::Init()
NS_ASSERTION(NS_IsMainThread(), "bad");
sPrevGCSliceCallback = js::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
sPrevAnalysisPurgeCallback = js::SetAnalysisPurgeCallback(sRuntime, DOMAnalysisPurgeCallback);
// Set up the structured clone callbacks.
static JSStructuredCloneCallbacks cloneCallbacks = {
@ -4098,6 +4126,12 @@ nsJSRuntime::Init()
SetMemoryGCPrefChangedCallback("javascript.options.mem.gc_high_frequency_high_limit_mb",
(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();
if (!obs)
return NS_ERROR_FAILURE;

View File

@ -60,6 +60,11 @@ MOCHITEST_FILES := \
test_forOf.html \
forOf_iframe.html \
test_sequence_wrapping.html \
file_bug775543.html \
$(NULL)
MOCHITEST_CHROME_FILES = \
test_bug775543.html \
$(NULL)
# 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 "BluetoothDevice.h"
#include "BluetoothPropertyEvent.h"
#include "BluetoothPairingEvent.h"
#include "BluetoothService.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "GeneratedEvents.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "nsIDOMDOMRequest.h"
#include "nsIDOMBluetoothAuthorizeEvent.h"
#include "nsIDOMBluetoothDeviceEvent.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/Util.h"
@ -322,66 +323,100 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
} else if (aData.name().EqualsLiteral("PropertyChanged")) {
// Get BluetoothNamedValue, make sure array length is 1
arr = aData.value().get_ArrayOfBluetoothNamedValue();
if(arr.Length() != 1) {
// This really should not happen
NS_ERROR("Got more than one property in a change message!");
return;
}
NS_ASSERTION(arr.Length() == 1, "Got more than one property in a change message!");
NS_ASSERTION(arr[0].value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
"PropertyChanged: Invalid value type");
BluetoothNamedValue v = arr[0];
SetPropertyByValue(v);
nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
} else if (aData.name().EqualsLiteral("RequestConfirmation")) {
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();
uint32_t passkey = arr[1].value().get_uint32_t();
NS_ASSERTION(arr.Length() == 2, "RequestConfirmation: Wrong length of parameters");
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);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestconfirmation"));
nsCOMPtr<nsIDOMEvent> event;
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")) {
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);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpincode"));
nsCOMPtr<nsIDOMEvent> event;
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")) {
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);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpasskey"));
nsCOMPtr<nsIDOMEvent> event;
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")) {
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();
nsString serviceUuid = arr[1].value().get_nsString();
NS_ASSERTION(arr.Length() == 2, "Authorize: Wrong length of parameters");
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);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("authorize"));
nsCOMPtr<nsIDOMEvent> event;
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")) {
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
nsString deviceObjectPath = EmptyString();
nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceObjectPath, 0);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("cancel"));
e->InitBluetoothDeviceAddressEvent(NS_LITERAL_STRING("cancel"),
false, false, EmptyString());
e->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
} else {
#ifdef DEBUG
nsCString warningMsg;

View File

@ -33,7 +33,6 @@ CPPSRCS += \
BluetoothAdapter.cpp \
BluetoothDevice.cpp \
BluetoothPropertyEvent.cpp \
BluetoothPairingEvent.cpp \
BluetoothReplyRunnable.cpp \
BluetoothPropertyContainer.cpp \
BluetoothUtils.cpp \
@ -48,6 +47,7 @@ XPIDLSRCS = \
nsIDOMBluetoothDeviceAddressEvent.idl \
nsIDOMBluetoothPropertyEvent.idl \
nsIDOMBluetoothPairingEvent.idl \
nsIDOMBluetoothAuthorizeEvent.idl \
$(NULL)
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"
[scriptable, builtinclass, uuid(b905b05e-2141-444c-a90d-525b6c0daff1)]
[scriptable, builtinclass, uuid(333022b8-a7e5-4fff-8588-36f2eedff17e)]
interface nsIDOMBluetoothPairingEvent : nsIDOMEvent
{
readonly attribute DOMString deviceAddress;
readonly attribute DOMString uuid;
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";
/* static functions */
let DEBUG = 0;
if (DEBUG)
debug = function (s) { dump("-*- ContactManager: " + s + "\n"); }
else
debug = function (s) {}
const DEBUG = false;
function debug(s) { dump("-*- ContactManager: " + s + "\n"); }
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -37,7 +33,7 @@ const nsIDOMContactProperties = Ci.nsIDOMContactProperties;
// 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 = {
@ -67,6 +63,14 @@ function ContactAddress(aType, aStreetAddress, aLocality, aRegion, aPostalCode,
};
ContactAddress.prototype = {
__exposedProps__: {
type: 'rw',
streetAddress: 'rw',
locality: 'rw',
region: 'rw',
postalCode: 'rw',
countryName: 'rw'
},
classID : CONTACTADDRESS_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
@ -90,6 +94,10 @@ function ContactField(aType, aValue) {
};
ContactField.prototype = {
__exposedProps__: {
type: 'rw',
value: 'rw'
},
classID : CONTACTFIELD_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTFIELD_CID,
@ -114,6 +122,11 @@ function ContactTelField(aType, aValue, aCarrier) {
};
ContactTelField.prototype = {
__exposedProps__: {
type: 'rw',
value: 'rw',
carrier: 'rw'
},
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 nsIDOMContact = Components.interfaces.nsIDOMContact;
// The wrappedJSObject magic here allows callers to get at the underlying JS object
// of the XPCOM component. We use this below to modify properties that are read-only
// per-idl. See https://developer.mozilla.org/en-US/docs/wrappedJSObject.
function Contact() { debug("Contact constr: "); this.wrappedJSObject = this; };
function Contact() {
if (DEBUG) debug("Contact constr: ");
};
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) {
// Accept non-array strings for DOMString[] properties and convert them.
function _create(aField) {
@ -290,7 +328,7 @@ const nsIDOMContactManager = Components.interfaces.nsIDOMContactManager;
function ContactManager()
{
debug("Constructor");
if (DEBUG) debug("Constructor");
}
ContactManager.prototype = {
@ -298,7 +336,7 @@ ContactManager.prototype = {
_oncontactchange: null,
set oncontactchange(aCallback) {
debug("set oncontactchange");
if (DEBUG) debug("set oncontactchange");
let allowCallback = function() {
this._oncontactchange = aCallback;
}.bind(this);
@ -321,16 +359,16 @@ ContactManager.prototype = {
_convertContactsArray: function(aContacts) {
let contacts = new Array();
for (let i in aContacts) {
let newContact = Components.classes['@mozilla.org/contact;1'].createInstance();
let newContact = new Contact();
newContact.init(aContacts[i].properties);
this._setMetaData(newContact.wrappedJSObject, aContacts[i]);
this._setMetaData(newContact, aContacts[i]);
contacts.push(newContact);
}
return contacts;
},
receiveMessage: function(aMessage) {
debug("Contactmanager::receiveMessage: " + aMessage.name);
if (DEBUG) debug("Contactmanager::receiveMessage: " + aMessage.name);
let msg = aMessage.json;
let contacts = msg.contacts;
@ -339,10 +377,9 @@ ContactManager.prototype = {
let req = this.getRequest(msg.requestID);
if (req) {
let result = this._convertContactsArray(contacts);
debug("result: " + JSON.stringify(result));
Services.DOMRequest.fireSuccess(req.request, result);
} else {
debug("no request stored!" + msg.requestID);
if (DEBUG) debug("no request stored!" + msg.requestID);
}
break;
case "Contact:Save:Return:OK":
@ -370,7 +407,7 @@ ContactManager.prototype = {
Services.DOMRequest.fireError(req.request, msg.errorMsg);
break;
case "PermissionPromptHelper:AskPermission:OK":
debug("id: " + msg.requestID);
if (DEBUG) debug("id: " + msg.requestID);
req = this.getRequest(msg.requestID);
if (!req) {
break;
@ -383,13 +420,13 @@ ContactManager.prototype = {
}
break;
default:
debug("Wrong message: " + aMessage.name);
if (DEBUG) debug("Wrong message: " + aMessage.name);
}
this.removeRequest(msg.requestID);
},
askPermission: function (aAccess, aReqeust, aAllowCallback, aCancelCallback) {
debug("askPermission for contacts");
if (DEBUG) debug("askPermission for contacts");
let requestID = this.getRequestId({
request: aReqeust,
allow: function() {
@ -417,7 +454,7 @@ ContactManager.prototype = {
save: function save(aContact) {
let request;
debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
if (DEBUG) debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
let newContact = {};
newContact.properties = {
name: [],
@ -457,7 +494,7 @@ ContactManager.prototype = {
}
this._setMetaData(newContact, aContact);
debug("send: " + JSON.stringify(newContact));
if (DEBUG) debug("send: " + JSON.stringify(newContact));
request = this.createRequest();
let options = { contact: newContact };
let allowCallback = function() {
@ -468,7 +505,7 @@ ContactManager.prototype = {
},
find: function(aOptions) {
debug("find! " + JSON.stringify(aOptions));
if (DEBUG) debug("find! " + JSON.stringify(aOptions));
let request;
request = this.createRequest();
let options = { findOptions: aOptions };
@ -491,7 +528,7 @@ ContactManager.prototype = {
},
clear: function() {
debug("clear");
if (DEBUG) debug("clear");
let request;
request = this.createRequest();
let options = {};
@ -508,16 +545,16 @@ ContactManager.prototype = {
let allowCallback = function() {
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) {
var contact = new Contact();
contact.init( { name: [c.alphaId], tel: [ { number: c.number } ] } );
return contact;
});
debug("result: " + JSON.stringify(result));
if (DEBUG) debug("result: " + JSON.stringify(result));
Services.DOMRequest.fireSuccess(request, result);
};
debug("getSimContacts " + aType);
if (DEBUG) debug("getSimContacts " + aType);
mRIL.getICCContacts(aType, callback);
}.bind(this);
@ -543,7 +580,7 @@ ContactManager.prototype = {
// Called from DOMRequestIpcHelper
uninit: function uninit() {
debug("uninit call");
if (DEBUG) debug("uninit call");
if (this._oncontactchange)
this._oncontactchange = null;
},

View File

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

View File

@ -4,11 +4,8 @@
"use strict";
let DEBUG = 0;
if (DEBUG)
debug = function (s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
else
debug = function (s) {}
const DEBUG = false;
function debug(s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
const Cu = Components.utils;
const Cc = Components.classes;
@ -28,7 +25,7 @@ let myGlobal = this;
let DOMContactManager = {
init: function() {
debug("Init");
if (DEBUG) debug("Init");
this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
this._messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this);
@ -56,7 +53,7 @@ let DOMContactManager = {
},
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 msg = aMessage.data;
@ -112,14 +109,14 @@ let DOMContactManager = {
if (msg.options && msg.options.findOptions) {
let findOptions = msg.options.findOptions;
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);
if (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});
}.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)
);
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",
additionalName: "dummyadditionalName",
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"}],
adr: [adr1, adr2],
impp: [{type: ["aim"], value:"im1"}, {value: "im2"}],
@ -154,8 +154,8 @@ function checkTel(tel1, tel2) {
}
function checkField(field1, field2) {
checkStr(field1.type, field1.type, "Same type");
checkStr(field1.value, field1.value, "Same value");
checkStr(field1.type, field2.type, "Same type");
checkStr(field1.value, field2.value, "Same value");
}
function checkContacts(contact1, contact2) {
@ -312,6 +312,20 @@ var steps = [
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
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();
};
req.onerror = onFailure;

View File

@ -121,12 +121,17 @@ interface nsIDOMWindowUtils : nsISupports {
*
* It's legal to set a displayport that extends beyond the overflow
* area in any direction (left/right/top/bottom).
*
*
* It's also legal to set a displayport that extends beyond the
* area's bounds. No pixels are rendered outside the area bounds.
*
* The caller of this method must have UniversalXPConnect
* 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,
in float aWidthPx, in float aHeightPx,

View File

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

View File

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

View File

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

View File

@ -212,7 +212,7 @@ private:
virtual PStorageParent* AllocPStorage(const StorageConstructData& aData);
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 RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions);

View File

@ -251,14 +251,21 @@ parent:
nsString aName, nsString aFeatures)
returns (bool windowOpened);
NotifyDOMTouchListenerAdded();
/**
* Instructs the TabParent to forward a request to zoom to a rect given in
* CSS pixels. This rect is relative to the document.
*/
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__();
child:

View File

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

View File

@ -114,15 +114,7 @@ TabChild::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, "dom-touch-listener-added")) {
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")) {
if (!strcmp(aTopic, "cancel-default-pan-zoom")) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
if (tabChild == this) {
@ -163,9 +155,6 @@ TabChild::Init()
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) {
observerService->AddObserver(this,
"dom-touch-listener-added",
false);
observerService->AddObserver(this,
"cancel-default-pan-zoom",
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>
// and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
bool isInContentBoundary = false;
if (docshell) {
docshell->GetIsBelowContentBoundary(&isInContentBoundary);
}
if (isInContentBoundary &&
if (docshell && docshell->GetIsBelowContentBoundary() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
@ -737,8 +721,8 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
}
nsCString data;
data += nsPrintfCString("{ \"x\" : %d", aFrameMetrics.mViewportScrollOffset.x);
data += nsPrintfCString(", \"y\" : %d", aFrameMetrics.mViewportScrollOffset.y);
data += nsPrintfCString("{ \"x\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.x));
data += nsPrintfCString(", \"y\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.y));
// We don't treat the x and y scales any differently for this
// semi-platform-specific code.
data += nsPrintfCString(", \"zoom\" : %f", aFrameMetrics.mResolution.width);
@ -836,6 +820,13 @@ TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
{
nsTouchEvent localEvent(aEvent);
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) {
return true;
}

View File

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

View File

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

View File

@ -8,6 +8,7 @@
#include "nsIDOMClassInfo.h"
#include "nsISmsService.h"
#include "nsIObserverService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "Constants.h"
#include "SmsEvent.h"
@ -18,6 +19,7 @@
#include "nsContentUtils.h"
#include "nsISmsDatabaseService.h"
#include "nsIXPConnect.h"
#include "nsIPermissionManager.h"
/**
* 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_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
SmsManager::Init(nsPIDOMWindow *aWindow)
{

View File

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

View File

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

View File

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

View File

@ -17,11 +17,11 @@
function checkSmsDisabled() {
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() {
// 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) {
checkSmsDisabled();
return;
@ -39,7 +39,6 @@ function checkInterface(aInterface) {
function test() {
var gSmsEnabled = SpecialPowers.getBoolPref("dom.sms.enabled");
var gSmsWhiteList = SpecialPowers.getCharPref("dom.sms.whitelist");
checkInterface("SmsManager");
checkInterface("NavigatorSms");
@ -49,32 +48,24 @@ function test() {
checkInterface("SmsFilter");
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.setCharPref("dom.sms.whitelist", "");
SpecialPowers.removePermission("sms", document);
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.setCharPref("dom.sms.whitelist", "");
SpecialPowers.removePermission("sms", document);
checkSmsDisabled();
// If sms are disabled and whitelist contains the current URL prepath,
// sms are disabled.
// If sms is disabled and permission is granted, sms is disabled.
SpecialPowers.setBoolPref("dom.sms.enabled", false);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://mochi.test:8888");
SpecialPowers.addPermission("sms", true, document);
checkSmsDisabled();
// If sms are enabled and whitelist contains something else than the current
// URL prepath, sms are disabled.
// If sms is enabled and permission is granted, sms is enabled.
SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://foo.mochi.test:8888");
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");
SpecialPowers.addPermission("sms", true, document);
checkSmsEnabled();
// Now, if sms are disabled with the pref, they will still be enabled.
@ -96,15 +87,13 @@ function test() {
// Cleanup and quit.
SpecialPowers.setBoolPref("dom.sms.enabled", gSmsEnabled);
SpecialPowers.setCharPref("dom.sms.whitelist", gSmsWhiteList);
SpecialPowers.removePermission("sms", document);
SimpleTest.finish();
});
frames[0].location.reload();
});
// Having more than one item in the whitelist should work.
SpecialPowers.setBoolPref("dom.sms.enabled", true);
SpecialPowers.setCharPref("dom.sms.whitelist", "http://mochi.test:8888, http://foo.com");
frames[0].location.reload();
}

View File

@ -33,6 +33,9 @@
#include "nsXPCOMCIDInternal.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsAutoPtr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "OSFileConstants.h"
#include "nsIOSFileConstantsService.h"
@ -53,10 +56,42 @@ namespace {
*/
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;
// Initialize gLibDirectory
nsCOMPtr<nsIFile> xpcomLib;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(xpcomLib));
if (NS_FAILED(rv) || !xpcomLib) {
return rv;
}
nsAutoPtr<Paths> paths(new Paths);
nsCOMPtr<nsIFile> libDir;
rv = xpcomLib->GetParent(getter_AddRefs(libDir));
// Initialize paths->libDir
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(file));
if (NS_FAILED(rv)) {
return rv;
}
gLibDirectory = new nsString();
return libDir->GetPath(*gLibDirectory);
nsCOMPtr<nsIFile> libDir;
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()
{
MOZ_ASSERT(NS_IsMainThread());
@ -97,7 +148,7 @@ void CleanupOSFileConstants()
}
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);
}
/**
* 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.
*
@ -488,6 +555,16 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
{
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;
if (!(objOS = GetOrCreateObjectProperty(cx, global, "OS"))) {
return false;
@ -550,10 +627,9 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
return false;
}
// Locate libxul
{
nsAutoString xulPath(*gLibDirectory);
nsAutoString xulPath(gPaths->libDir);
xulPath.Append(PR_GetDirectorySeparator());
@ -568,13 +644,23 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
xulPath.Append(NS_LITERAL_STRING(DLL_SUFFIX));
#endif // defined(XP_MACOSX)
JSString* strPathToLibXUL = JS_NewUCStringCopyZ(cx, xulPath.get());
jsval valXul = STRING_TO_JSVAL(strPathToLibXUL);
if (!JS_SetProperty(cx, objPath, "libxul", &valXul)) {
if (!SetStringProperty(cx, objPath, "libxul", xulPath)) {
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;
}

View File

@ -25,6 +25,22 @@ USING_WORKERS_NAMESPACE
using namespace mozilla::dom;
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 {
class Worker
@ -276,6 +292,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"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 = {
{
"Worker",
@ -287,7 +305,7 @@ DOMJSClass Worker::sClass = {
},
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
-1, false, NULL
-1, false, &sNativePropertyHooks
};
JSPropertySpec Worker::sProperties[] = {
@ -395,6 +413,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"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 = {
{ "ChromeWorker",
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::_ID_Count },
-1, false, NULL
-1, false, &sNativePropertyHooks
};
WorkerPrivate*

View File

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

View File

@ -848,6 +848,8 @@ private:
MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
"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 = {
{
"DedicatedWorkerGlobalScope",
@ -859,7 +861,7 @@ DOMJSClass DedicatedWorkerGlobalScope::sClass = {
},
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
-1, false, NULL
-1, false, &sNativePropertyHooks
};
JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {

View File

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

View File

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

View File

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

View File

@ -36,6 +36,7 @@ public:
, mScrollId(NULL_SCROLL_ID)
, mCSSContentRect(0, 0, 0, 0)
, mResolution(1, 1)
, mMayHaveTouchListeners(false)
{}
// Default copy ctor and operator= are fine
@ -70,7 +71,7 @@ public:
// These are all in layer coordinate space.
nsIntRect mViewport;
nsIntRect mContentRect;
nsIntPoint mViewportScrollOffset;
gfx::Point mViewportScrollOffset;
nsIntRect mDisplayPort;
ViewID mScrollId;
@ -81,6 +82,9 @@ public:
// This represents the resolution at which the associated layer
// will been rendered.
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 layers {
int32_t Image::sSerialCounter = 0;
already_AddRefed<Image>
ImageFactory::CreateImage(const ImageFormat *aFormats,
uint32_t aNumFormats,

View File

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

View File

@ -123,6 +123,15 @@ AppendToString(nsACString& s, const nsIntPoint& p,
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&
AppendToString(nsACString& s, const nsIntRect& r,
const char* pfx="", const char* sfx="")

View File

@ -177,7 +177,8 @@ class BasicShadowableImageLayer : public BasicImageLayer,
public:
BasicShadowableImageLayer(BasicShadowLayerManager* aManager) :
BasicImageLayer(aManager),
mBufferIsOpaque(false)
mBufferIsOpaque(false),
mLastPaintedImageSerial(0)
{
MOZ_COUNT_CTOR(BasicShadowableImageLayer);
}
@ -246,6 +247,7 @@ private:
SurfaceDescriptor mBackBufferU;
SurfaceDescriptor mBackBufferV;
gfxIntSize mCbCrSize;
int32_t mLastPaintedImageSerial;
};
void
@ -374,6 +376,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
if (!BasicManager()->AllocBuffer(mSize, type, &mBackBuffer))
NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
} else if (mLastPaintedImageSerial == image->GetSerial()) {
return;
}
AutoOpenSurface backSurface(OPEN_READ_WRITE, mBackBuffer);
@ -385,6 +389,7 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
BasicManager()->PaintedImage(BasicManager()->Hold(this),
mBackBuffer);
mLastPaintedImageSerial = image->GetSerial();
}
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;
/**
* 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,
GestureBehavior aGestures)
: mGeckoContentController(aGeckoContentController),
mTouchListenerTimeoutTask(nullptr),
mX(this),
mY(this),
mMonitor("AsyncPanZoomController"),
@ -81,8 +90,8 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
mState(NOTHING),
mDPI(72),
mContentPainterStatus(CONTENT_IDLE),
mMayHaveTouchListeners(false),
mDisableNextTouchBatch(false)
mDisableNextTouchBatch(false),
mHandlingTouchQueue(false)
{
if (aGestures == USE_GESTURE_DETECTOR) {
mGestureEventListener = new GestureEventListener(this);
@ -121,8 +130,8 @@ WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint,
}
nsEventStatus
AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent)
AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent)
{
float currentZoom;
gfx::Point currentScrollOffset, lastScrollOffset;
@ -139,12 +148,12 @@ AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent,
switch (aEvent.eventStructType) {
case NS_TOUCH_EVENT: {
MultiTouchInput event(static_cast<const nsTouchEvent&>(aEvent));
status = HandleInputEvent(event);
status = ReceiveInputEvent(event);
break;
}
case NS_MOUSE_EVENT: {
MultiTouchInput event(static_cast<const nsMouseEvent&>(aEvent));
status = HandleInputEvent(event);
status = ReceiveInputEvent(event);
break;
}
default:
@ -179,11 +188,47 @@ AsyncPanZoomController::HandleInputEvent(const nsInputEvent& aEvent,
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 rv = nsEventStatus_eIgnore;
if (mGestureEventListener && !mDisableNextTouchBatch) {
nsEventStatus rv = mGestureEventListener->HandleInputEvent(aEvent);
rv = mGestureEventListener->HandleInputEvent(aEvent);
if (rv == nsEventStatus_eConsumeNoDefault)
return rv;
}
@ -253,6 +298,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
case TOUCHING:
case PANNING:
case PINCHING:
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchStart");
break;
default:
@ -297,6 +343,10 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
// The scale gesture listener should have handled this.
NS_WARNING("Gesture listener should have handled pinching in OnTouchMove.");
return nsEventStatus_eIgnore;
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchMove");
break;
}
return nsEventStatus_eConsumeNoDefault;
@ -333,11 +383,16 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
mY.EndTouch();
SetState(FLING);
return nsEventStatus_eConsumeNoDefault;
case PINCHING:
SetState(NOTHING);
// Scale gesture listener should have handled this.
NS_WARNING("Gesture listener should have handled pinching in OnTouchEnd.");
return nsEventStatus_eIgnore;
case WAITING_LISTENERS:
NS_WARNING("Received impossible touch in OnTouchEnd");
break;
}
return nsEventStatus_eConsumeNoDefault;
@ -370,7 +425,7 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
float scale = mFrameMetrics.mResolution.width;
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,
// then reduce the displacement such that it doesn't.
if (mX.DisplacementWillOverscroll(xFocusChange) != Axis::OVERSCROLL_NONE) {
@ -379,12 +434,12 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
if (mY.DisplacementWillOverscroll(yFocusChange) != Axis::OVERSCROLL_NONE) {
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
// that we actually go over them. These are the needed displacements along
// 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.
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);
if (neededDisplacementX != 0 || neededDisplacementY != 0) {
ScrollBy(nsIntPoint(neededDisplacementX, neededDisplacementY));
ScrollBy(gfx::Point(neededDisplacementX, neededDisplacementY));
}
ScheduleComposite();
@ -559,7 +614,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
return;
}
ScrollBy(nsIntPoint(xDisplacement, yDisplacement));
ScrollBy(gfx::Point(xDisplacement, yDisplacement));
ScheduleComposite();
RequestContentRepaint();
@ -588,7 +643,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
// larger swipe should move you a shorter distance.
float inverseScale = 1 / mFrameMetrics.mResolution.width;
ScrollBy(nsIntPoint(
ScrollBy(gfx::Point(
mX.GetDisplacementForDuration(inverseScale, aDelta),
mY.GetDisplacementForDuration(inverseScale, aDelta)
));
@ -605,8 +660,8 @@ void AsyncPanZoomController::SetCompositorParent(CompositorParent* aCompositorPa
mCompositorParent = aCompositorParent;
}
void AsyncPanZoomController::ScrollBy(const nsIntPoint& aOffset) {
nsIntPoint newOffset(mFrameMetrics.mViewportScrollOffset.x + aOffset.x,
void AsyncPanZoomController::ScrollBy(const gfx::Point& aOffset) {
gfx::Point newOffset(mFrameMetrics.mViewportScrollOffset.x + aOffset.x,
mFrameMetrics.mViewportScrollOffset.y + aOffset.y);
FrameMetrics metrics(mFrameMetrics);
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).
SetPageRect(mFrameMetrics.mCSSContentRect);
nsIntPoint scrollOffset = metrics.mViewportScrollOffset;
gfx::Point scrollOffset = metrics.mViewportScrollOffset;
scrollOffset.x += NS_lround(float(aFocus.x) * (scaleFactor - 1.0f) / oldScale);
scrollOffset.y += NS_lround(float(aFocus.y) * (scaleFactor - 1.0f) / oldScale);
scrollOffset.x += float(aFocus.x) * (scaleFactor - 1.0f) / oldScale;
scrollOffset.y += float(aFocus.y) * (scaleFactor - 1.0f) / oldScale;
metrics.mViewportScrollOffset = scrollOffset;
@ -674,7 +729,7 @@ const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
nsIntRect viewport = mFrameMetrics.mViewport;
viewport.ScaleRoundIn(1 / scale);
nsIntPoint scrollOffset = mFrameMetrics.mViewportScrollOffset;
gfx::Point scrollOffset = mFrameMetrics.mViewportScrollOffset;
gfx::Point velocity = GetVelocityVector();
// The displayport is relative to the current scroll offset. Here's a little
@ -751,14 +806,30 @@ void AsyncPanZoomController::ScheduleComposite() {
void AsyncPanZoomController::RequestContentRepaint() {
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
// request since it's a pointless paint.
nsIntRect oldDisplayPort = mLastPaintRequestMetrics.mDisplayPort,
newDisplayPort = mFrameMetrics.mDisplayPort;
oldDisplayPort.MoveBy(mLastPaintRequestMetrics.mViewportScrollOffset);
newDisplayPort.MoveBy(mFrameMetrics.mViewportScrollOffset);
nsRect oldDisplayPort = nsRect(
mLastPaintRequestMetrics.mDisplayPort.x,
mLastPaintRequestMetrics.mDisplayPort.y,
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) {
return;
}
@ -788,8 +859,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
float rootScaleX = currentTransform.GetXScale(),
rootScaleY = currentTransform.GetYScale();
nsIntPoint metricsScrollOffset(0, 0);
nsIntPoint scrollOffset;
gfx::Point metricsScrollOffset(0, 0);
gfx::Point scrollOffset;
float localScaleX, localScaleY;
const FrameMetrics& frame = aLayer->GetFrameMetrics();
{
@ -813,7 +884,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
mEndZoomToMetrics.mResolution.width * sampledPosition +
mStartZoomToMetrics.mResolution.width * (1 - sampledPosition);
mFrameMetrics.mViewportScrollOffset = nsIntPoint(
mFrameMetrics.mViewportScrollOffset = gfx::Point(
mEndZoomToMetrics.mViewportScrollOffset.x * sampledPosition +
mStartZoomToMetrics.mViewportScrollOffset.x * (1 - sampledPosition),
mEndZoomToMetrics.mViewportScrollOffset.y * sampledPosition +
@ -848,8 +919,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
}
nsIntPoint scrollCompensation(
(scrollOffset.x / rootScaleX - metricsScrollOffset.x) * localScaleX,
(scrollOffset.y / rootScaleY - metricsScrollOffset.y) * localScaleY);
NS_lround((scrollOffset.x / rootScaleX - metricsScrollOffset.x) * localScaleX),
NS_lround((scrollOffset.y / rootScaleY - metricsScrollOffset.y) * localScaleY));
ViewTransform treeTransform(-scrollCompensation, localScaleX, localScaleY);
*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
// paint and not initializating the displayport correctly.
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)) {
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
SetPageRect(mFrameMetrics.mCSSContentRect);
@ -919,10 +986,6 @@ void AsyncPanZoomController::UpdateViewportSize(int aWidth, int aHeight) {
mFrameMetrics = metrics;
}
void AsyncPanZoomController::NotifyDOMTouchListenerAdded() {
mMayHaveTouchListeners = true;
}
void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true;
if (mGestureEventListener) {
@ -932,7 +995,6 @@ void AsyncPanZoomController::CancelDefaultPanZoom() {
void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height));
gfx::Rect cssPageRect = mFrameMetrics.mCSSContentRect;
SetState(ANIMATING_ZOOM);
@ -940,13 +1002,15 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
MonitorAutoLock mon(mMonitor);
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
// size.
if (zoomToRect.IsEmpty()) {
nsIntRect cssViewport = viewport;
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 newHeight = cssViewport.height * cssPageRect.width / cssViewport.width;
@ -996,7 +1060,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
mStartZoomToMetrics = mFrameMetrics;
mEndZoomToMetrics.mViewportScrollOffset =
nsIntPoint(NS_lround(zoomToRect.x), NS_lround(zoomToRect.y));
gfx::Point(zoomToRect.x, zoomToRect.y);
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) {
MonitorAutoLock monitor(mMonitor);
mState = aState;
}
void AsyncPanZoomController::TimeoutTouchListeners() {
ContentReceivedTouch(false);
}
}
}

View File

@ -15,6 +15,8 @@
#include "InputData.h"
#include "Axis.h"
#include "base/message_loop.h"
namespace mozilla {
namespace layers {
@ -76,10 +78,10 @@ public:
/**
* General handler for incoming input events. Manipulates the frame metrics
* 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 HandleInputEvent(const InputData& aEvent);
nsEventStatus ReceiveInputEvent(const InputData& aEvent);
/**
* 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
* why we have InputData and nsInputEvent separated.
*/
nsEventStatus HandleInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent);
nsEventStatus ReceiveInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent);
/**
* Updates the viewport size, i.e. the dimensions of the frame (not
@ -107,16 +109,6 @@ public:
*/
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
* a touch end or a new touch start. This prevents us from accidentally
@ -134,6 +126,14 @@ public:
*/
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.
//
@ -194,6 +194,11 @@ public:
int GetDPI();
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
* multitouch gestures.
@ -275,7 +280,7 @@ protected:
/**
* 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
@ -382,6 +387,15 @@ protected:
*/
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:
enum PanZoomState {
NOTHING, /* no touch-start events received */
@ -389,7 +403,10 @@ private:
TOUCHING, /* one touch-start event received */
PANNING, /* panning without axis lock */
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 {
@ -443,6 +460,10 @@ private:
// |mResolution| fields on this.
FrameMetrics mEndZoomToMetrics;
nsTArray<MultiTouchInput> mTouchQueue;
CancelableTask* mTouchListenerTimeoutTask;
AxisX mX;
AxisY mY;
@ -478,14 +499,16 @@ private:
// requests a repaint.
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
// next batch of touch events. This is used for sync scrolling of subframes.
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;
};

View File

@ -23,13 +23,13 @@ static const float MAX_EVENT_ACCELERATION = 0.5f;
/**
* 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
* 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
@ -94,10 +94,10 @@ void Axis::StartTouch(int32_t aPos) {
mLockPanning = false;
}
int32_t Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) {
float Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) {
float velocityFactor = powf(ACCELERATION_MULTIPLIER,
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
// bring it to 0 even if the velocity is high.
if (DisplacementWillOverscroll(displacement) != OVERSCROLL_NONE) {
@ -158,7 +158,7 @@ Axis::Overscroll Axis::GetOverscroll() {
return OVERSCROLL_NONE;
}
int32_t Axis::GetExcess() {
float Axis::GetExcess() {
switch (GetOverscroll()) {
case OVERSCROLL_MINUS: return GetOrigin() - GetPageStart();
case OVERSCROLL_PLUS: return GetViewportEnd() - GetPageEnd();
@ -186,7 +186,7 @@ Axis::Overscroll Axis::DisplacementWillOverscroll(int32_t aDisplacement) {
return OVERSCROLL_NONE;
}
int32_t Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) {
float Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) {
switch (DisplacementWillOverscroll(aDisplacement)) {
case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart();
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) {
int32_t originAfterScale = NS_lround((GetOrigin() + aFocus) * aScale - aFocus);
float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus;
bool both = ScaleWillOverscrollBothSides(aScale);
bool minus = originAfterScale < NS_lround(GetPageStart() * aScale);
bool plus = (originAfterScale + GetViewportLength()) > NS_lround(GetPageEnd() * aScale);
bool minus = originAfterScale < GetPageStart() * aScale;
bool plus = (originAfterScale + GetViewportLength()) > GetPageEnd() * aScale;
if ((minus && plus) || both) {
return OVERSCROLL_BOTH;
@ -215,11 +215,11 @@ Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) {
return OVERSCROLL_NONE;
}
int32_t Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) {
int32_t originAfterScale = NS_lround((GetOrigin() + aFocus) * aScale - aFocus);
float Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) {
float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus;
switch (ScaleWillOverscroll(aScale, aFocus)) {
case OVERSCROLL_MINUS: return originAfterScale - NS_lround(GetPageStart() * aScale);
case OVERSCROLL_PLUS: return (originAfterScale + GetViewportLength()) - NS_lround(GetPageEnd() * aScale);
case OVERSCROLL_MINUS: return originAfterScale - GetPageStart() * aScale;
case OVERSCROLL_PLUS: return (originAfterScale + GetViewportLength()) - GetPageEnd() * aScale;
// Don't handle OVERSCROLL_BOTH. Client code is expected to deal with it.
default: return 0;
}
@ -229,32 +229,32 @@ float Axis::GetVelocity() {
return mVelocity;
}
int32_t Axis::GetViewportEnd() {
float Axis::GetViewportEnd() {
return GetOrigin() + GetViewportLength();
}
int32_t Axis::GetPageEnd() {
float Axis::GetPageEnd() {
return GetPageStart() + GetPageLength();
}
int32_t Axis::GetOrigin() {
nsIntPoint origin = mAsyncPanZoomController->GetFrameMetrics().mViewportScrollOffset;
float Axis::GetOrigin() {
gfx::Point origin = mAsyncPanZoomController->GetFrameMetrics().mViewportScrollOffset;
return GetPointOffset(origin);
}
int32_t Axis::GetViewportLength() {
float Axis::GetViewportLength() {
nsIntRect viewport = mAsyncPanZoomController->GetFrameMetrics().mViewport;
gfx::Rect scaledViewport = gfx::Rect(viewport.x, viewport.y, viewport.width, viewport.height);
scaledViewport.ScaleRoundIn(1 / mAsyncPanZoomController->GetFrameMetrics().mResolution.width);
return GetRectLength(scaledViewport);
}
int32_t Axis::GetPageStart() {
float Axis::GetPageStart() {
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
return GetRectOffset(pageRect);
}
int32_t Axis::GetPageLength() {
float Axis::GetPageLength() {
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
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;
}
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)
@ -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;
}
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
* 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
@ -114,7 +114,7 @@ public:
* in both directions, this returns 0; it assumes that you check
* GetOverscroll() first.
*/
int32_t GetExcess();
float GetExcess();
/**
* 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
* 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
@ -153,7 +153,7 @@ public:
* scroll offset in such a way that it remains in the same place on the page
* 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
@ -164,16 +164,16 @@ public:
*/
bool ScaleWillOverscrollBothSides(float aScale);
int32_t GetOrigin();
int32_t GetViewportLength();
int32_t GetPageStart();
int32_t GetPageLength();
int32_t GetViewportEnd();
int32_t GetPageEnd();
float GetOrigin();
float GetViewportLength();
float GetPageStart();
float GetPageLength();
float GetViewportEnd();
float GetPageEnd();
virtual int32_t GetPointOffset(const nsIntPoint& aPoint) = 0;
virtual int32_t GetRectLength(const gfx::Rect& aRect) = 0;
virtual int32_t GetRectOffset(const gfx::Rect& aRect) = 0;
virtual float GetPointOffset(const gfx::Point& aPoint) = 0;
virtual float GetRectLength(const gfx::Rect& aRect) = 0;
virtual float GetRectOffset(const gfx::Rect& aRect) = 0;
protected:
int32_t mPos;
@ -192,17 +192,17 @@ protected:
class AxisX : public Axis {
public:
AxisX(AsyncPanZoomController* mAsyncPanZoomController);
virtual int32_t GetPointOffset(const nsIntPoint& aPoint);
virtual int32_t GetRectLength(const gfx::Rect& aRect);
virtual int32_t GetRectOffset(const gfx::Rect& aRect);
virtual float GetPointOffset(const gfx::Point& aPoint);
virtual float GetRectLength(const gfx::Rect& aRect);
virtual float GetRectOffset(const gfx::Rect& aRect);
};
class AxisY : public Axis {
public:
AxisY(AsyncPanZoomController* mAsyncPanZoomController);
virtual int32_t GetPointOffset(const nsIntPoint& aPoint);
virtual int32_t GetRectLength(const gfx::Rect& aRect);
virtual int32_t GetRectOffset(const gfx::Rect& aRect);
virtual float GetPointOffset(const gfx::Point& aPoint);
virtual float GetRectLength(const gfx::Rect& aRect);
virtual float GetRectOffset(const gfx::Rect& aRect);
};
}

View File

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

View File

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

View File

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

View File

@ -220,7 +220,9 @@ ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
TransformBounds(gfxRect(parentMetrics.mDisplayPort));
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
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,
contentSize.width, contentSize.height);
contentBounds = scrollableLayer->GetEffectiveTransform().TransformBounds(contentRect);

View File

@ -535,6 +535,12 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
}
#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
// STDOUT_FILENO, for example
int srcChannelFd, dstChannelFd;

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