mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
merge mozilla-inbound to mozilla-central
This commit is contained in:
commit
84e1bc2be7
@ -1312,6 +1312,8 @@ pref("browser.newtabpage.rows", 3);
|
|||||||
// number of columns of newtab grid
|
// number of columns of newtab grid
|
||||||
pref("browser.newtabpage.columns", 3);
|
pref("browser.newtabpage.columns", 3);
|
||||||
|
|
||||||
|
pref("browser.newtabpage.directorySource", "chrome://global/content/directoryLinks.json");
|
||||||
|
|
||||||
// Enable the DOM fullscreen API.
|
// Enable the DOM fullscreen API.
|
||||||
pref("full-screen-api.enabled", true);
|
pref("full-screen-api.enabled", true);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ endif
|
|||||||
# Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
|
# Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
|
||||||
# This wrapping is only really useful for build status.
|
# This wrapping is only really useful for build status.
|
||||||
compile binaries libs export tools::
|
compile binaries libs export tools::
|
||||||
$(call BUILDSTATUS,TIER_START $@ $($@_subtiers))
|
$(call BUILDSTATUS,TIER_START $@)
|
||||||
+$(MAKE) recurse_$@
|
+$(MAKE) recurse_$@
|
||||||
$(call BUILDSTATUS,TIER_FINISH $@)
|
$(call BUILDSTATUS,TIER_FINISH $@)
|
||||||
|
|
||||||
@ -77,11 +77,9 @@ endif
|
|||||||
|
|
||||||
# Subtier delimiter rules
|
# Subtier delimiter rules
|
||||||
$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
|
$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
|
||||||
$(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*)))
|
|
||||||
@$(STAMP_TOUCH)
|
@$(STAMP_TOUCH)
|
||||||
|
|
||||||
$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
|
$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
|
||||||
$(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*)
|
|
||||||
@$(STAMP_TOUCH)
|
@$(STAMP_TOUCH)
|
||||||
|
|
||||||
$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
|
$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
|
||||||
@ -94,15 +92,9 @@ GARBAGE_DIRS += subtiers
|
|||||||
# root.mk defines subtier_of_* variables, that map a normalized subdir path to
|
# root.mk defines subtier_of_* variables, that map a normalized subdir path to
|
||||||
# a subtier name (e.g. subtier_of_memory_jemalloc = base)
|
# a subtier name (e.g. subtier_of_memory_jemalloc = base)
|
||||||
$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
|
$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
|
||||||
ifdef BUG_915535_FIXED
|
|
||||||
$(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
|
|
||||||
endif
|
|
||||||
+@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
|
+@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
|
||||||
# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
|
# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
|
||||||
$(if $(wildcard $@),@$(STAMP_TOUCH))
|
$(if $(wildcard $@),@$(STAMP_TOUCH))
|
||||||
ifdef BUG_915535_FIXED
|
|
||||||
$(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Dummy rules for possibly inexisting dependencies for the above tier targets
|
# Dummy rules for possibly inexisting dependencies for the above tier targets
|
||||||
$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
|
$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
|
||||||
@ -158,12 +150,10 @@ else
|
|||||||
ifdef TIERS
|
ifdef TIERS
|
||||||
|
|
||||||
libs export tools::
|
libs export tools::
|
||||||
$(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
|
$(call BUILDSTATUS,TIER_START $@)
|
||||||
$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
|
$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
|
||||||
$(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
|
|
||||||
$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
|
$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
|
||||||
$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
|
$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@))))
|
||||||
$(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
|
|
||||||
$(call BUILDSTATUS,TIER_FINISH $@)
|
$(call BUILDSTATUS,TIER_FINISH $@)
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -198,34 +188,24 @@ endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
|
|||||||
endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
|
endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
|
||||||
|
|
||||||
ifdef MOZ_PSEUDO_DERECURSE
|
ifdef MOZ_PSEUDO_DERECURSE
|
||||||
ifeq (.,$(DEPTH))
|
|
||||||
# top-level directories
|
|
||||||
ifndef JS_STANDALONE
|
|
||||||
# Only define recurse_targets for js, when it is built as part of gecko.
|
|
||||||
recurse_targets := $(addsuffix /binaries,$(call TIER_DIRS,binaries))
|
|
||||||
# we want to adjust paths for js/src.
|
|
||||||
want_abspaths = 1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef COMPILE_ENVIRONMENT
|
ifdef COMPILE_ENVIRONMENT
|
||||||
|
|
||||||
# Aggregate all dependency files relevant to a binaries build except in
|
# Aggregate all dependency files relevant to a binaries build except in
|
||||||
# the mozilla top-level directory.
|
# the mozilla top-level directory.
|
||||||
ifneq (_.,$(recurse_targets)_$(DEPTH))
|
ifneq (.,$(DEPTH))
|
||||||
ALL_DEP_FILES := \
|
ALL_DEP_FILES := \
|
||||||
$(BINARIES_PP) \
|
$(BINARIES_PP) \
|
||||||
$(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
|
$(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
|
||||||
$(TARGETS) \
|
$(TARGETS) \
|
||||||
$(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
|
$(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
|
||||||
))) \
|
))) \
|
||||||
$(recurse_targets) \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
binaries libs:: $(TARGETS) $(BINARIES_PP)
|
binaries libs:: $(TARGETS) $(BINARIES_PP)
|
||||||
ifneq (_.,$(recurse_targets)_$(DEPTH))
|
ifneq (.,$(DEPTH))
|
||||||
@$(if $(or $(recurse_targets),$^),$(call py_action,link_deps,-o binaries --group-all $(if $(want_abspaths),--abspaths )--topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
|
@$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -376,9 +376,7 @@ define SUBMAKE # $(call SUBMAKE,target,directory,static)
|
|||||||
endef # The extra line is important here! don't delete it
|
endef # The extra line is important here! don't delete it
|
||||||
|
|
||||||
define TIER_DIR_SUBMAKE
|
define TIER_DIR_SUBMAKE
|
||||||
$(call BUILDSTATUS,TIERDIR_START $(1) $(2) $(3))
|
|
||||||
$(call SUBMAKE,$(4),$(3),$(5))
|
$(call SUBMAKE,$(4),$(3),$(5))
|
||||||
$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
|
|
||||||
|
|
||||||
endef # Ths empty line is important.
|
endef # Ths empty line is important.
|
||||||
|
|
||||||
|
@ -2023,6 +2023,8 @@ GK_ATOM(DeleteTxnName, "Deleting")
|
|||||||
GK_ATOM(Remote, "remote")
|
GK_ATOM(Remote, "remote")
|
||||||
GK_ATOM(RemoteId, "_remote_id")
|
GK_ATOM(RemoteId, "_remote_id")
|
||||||
GK_ATOM(DisplayPort, "_displayport")
|
GK_ATOM(DisplayPort, "_displayport")
|
||||||
|
GK_ATOM(DisplayPortMargins, "_displayportmargins")
|
||||||
|
GK_ATOM(DisplayPortBase, "_displayportbase")
|
||||||
GK_ATOM(CriticalDisplayPort, "_critical_displayport")
|
GK_ATOM(CriticalDisplayPort, "_critical_displayport")
|
||||||
|
|
||||||
// Names for system metrics
|
// Names for system metrics
|
||||||
|
@ -322,49 +322,6 @@ nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
|
|
||||||
{
|
|
||||||
if (aPresContext) {
|
|
||||||
nsIPresShell* presShell = aPresContext->GetPresShell();
|
|
||||||
bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
|
|
||||||
presShell->NotifyFontSizeInflationEnabledIsDirty();
|
|
||||||
bool changed = false;
|
|
||||||
if (presShell && presShell->FontSizeInflationEnabled() &&
|
|
||||||
presShell->FontSizeInflationMinTwips() != 0) {
|
|
||||||
aPresContext->ScreenWidthInchesForFontInflation(&changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
changed = changed ||
|
|
||||||
(fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
|
|
||||||
if (changed) {
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
|
|
||||||
if (docShell) {
|
|
||||||
nsCOMPtr<nsIContentViewer> cv;
|
|
||||||
docShell->GetContentViewer(getter_AddRefs(cv));
|
|
||||||
nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
|
|
||||||
if (mudv) {
|
|
||||||
nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
|
|
||||||
mudv->AppendSubtree(array);
|
|
||||||
for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
|
|
||||||
nsCOMPtr<nsIPresShell> shell;
|
|
||||||
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
|
|
||||||
cv->GetPresShell(getter_AddRefs(shell));
|
|
||||||
if (shell) {
|
|
||||||
nsIFrame *rootFrame = shell->GetRootFrame();
|
|
||||||
if (rootFrame) {
|
|
||||||
shell->FrameNeedsReflow(rootFrame,
|
|
||||||
nsIPresShell::eStyleChange,
|
|
||||||
NS_FRAME_IS_DIRTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
||||||
float aWidthPx, float aHeightPx,
|
float aWidthPx, float aHeightPx,
|
||||||
@ -380,11 +337,6 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
|
|
||||||
nsPresContext::CSSPixelsToAppUnits(aYPx),
|
|
||||||
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
|
|
||||||
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
|
|
||||||
|
|
||||||
if (!aElement) {
|
if (!aElement) {
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
@ -405,25 +357,20 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
|
||||||
|
nsPresContext::CSSPixelsToAppUnits(aYPx),
|
||||||
|
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
|
||||||
|
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
|
||||||
|
|
||||||
content->SetProperty(nsGkAtoms::DisplayPort,
|
content->SetProperty(nsGkAtoms::DisplayPort,
|
||||||
new DisplayPortPropertyData(displayport, aPriority),
|
new DisplayPortPropertyData(displayport, aPriority),
|
||||||
nsINode::DeleteProperty<DisplayPortPropertyData>);
|
nsINode::DeleteProperty<DisplayPortPropertyData>);
|
||||||
|
|
||||||
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||||
if (rootScrollFrame) {
|
if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
|
||||||
if (content == rootScrollFrame->GetContent()) {
|
// We are setting a root displayport for a document.
|
||||||
// We are setting a root displayport for a document.
|
// The pres shell needs a special flag set.
|
||||||
// The pres shell needs a special flag set.
|
presShell->SetIgnoreViewportScrolling(true);
|
||||||
presShell->SetIgnoreViewportScrolling(true);
|
|
||||||
|
|
||||||
// When the "font.size.inflation.minTwips" preference is set, the
|
|
||||||
// layout depends on the size of the screen. Since when the size
|
|
||||||
// of the screen changes, the root displayport also changes, we
|
|
||||||
// hook in the needed updates here rather than adding a
|
|
||||||
// separate notification just for this change.
|
|
||||||
nsPresContext* presContext = GetPresContext();
|
|
||||||
MaybeReflowForInflationScreenWidthChange(presContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
||||||
@ -452,6 +399,107 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
|
||||||
|
float aTopMargin,
|
||||||
|
float aRightMargin,
|
||||||
|
float aBottomMargin,
|
||||||
|
uint32_t aAlignment,
|
||||||
|
nsIDOMElement* aElement,
|
||||||
|
uint32_t aPriority)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerChrome()) {
|
||||||
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIPresShell* presShell = GetPresShell();
|
||||||
|
if (!presShell) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aElement) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||||
|
|
||||||
|
if (!content) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content->GetCurrentDoc() != presShell->GetDocument()) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayPortMarginsPropertyData* currentData =
|
||||||
|
static_cast<DisplayPortMarginsPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPortMargins));
|
||||||
|
if (currentData && currentData->mPriority > aPriority) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note order change of arguments between our function signature and
|
||||||
|
// LayerMargin constructor.
|
||||||
|
LayerMargin displayportMargins(aTopMargin,
|
||||||
|
aRightMargin,
|
||||||
|
aBottomMargin,
|
||||||
|
aLeftMargin);
|
||||||
|
|
||||||
|
content->SetProperty(nsGkAtoms::DisplayPortMargins,
|
||||||
|
new DisplayPortMarginsPropertyData(displayportMargins, aAlignment, aPriority),
|
||||||
|
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
|
||||||
|
|
||||||
|
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||||
|
if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
|
||||||
|
// We are setting a root displayport for a document.
|
||||||
|
// The pres shell needs a special flag set.
|
||||||
|
presShell->SetIgnoreViewportScrolling(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
||||||
|
if (rootFrame) {
|
||||||
|
rootFrame->SchedulePaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
|
||||||
|
int32_t aY,
|
||||||
|
int32_t aWidth,
|
||||||
|
int32_t aHeight,
|
||||||
|
nsIDOMElement* aElement)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerChrome()) {
|
||||||
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIPresShell* presShell = GetPresShell();
|
||||||
|
if (!presShell) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aElement) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||||
|
|
||||||
|
if (!content) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content->GetCurrentDoc() != presShell->GetDocument()) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
content->SetProperty(nsGkAtoms::DisplayPortBase, new nsRect(aX, aY, aWidth, aHeight),
|
||||||
|
nsINode::DeleteProperty<nsRect>);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
|
nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
|
||||||
float aWidthPx, float aHeightPx,
|
float aWidthPx, float aHeightPx,
|
||||||
@ -3262,6 +3310,49 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugin
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
|
||||||
|
{
|
||||||
|
if (aPresContext) {
|
||||||
|
nsIPresShell* presShell = aPresContext->GetPresShell();
|
||||||
|
bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
|
||||||
|
presShell->NotifyFontSizeInflationEnabledIsDirty();
|
||||||
|
bool changed = false;
|
||||||
|
if (presShell && presShell->FontSizeInflationEnabled() &&
|
||||||
|
presShell->FontSizeInflationMinTwips() != 0) {
|
||||||
|
aPresContext->ScreenWidthInchesForFontInflation(&changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = changed ||
|
||||||
|
(fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
|
||||||
|
if (changed) {
|
||||||
|
nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
|
||||||
|
if (docShell) {
|
||||||
|
nsCOMPtr<nsIContentViewer> cv;
|
||||||
|
docShell->GetContentViewer(getter_AddRefs(cv));
|
||||||
|
nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
|
||||||
|
if (mudv) {
|
||||||
|
nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
|
||||||
|
mudv->AppendSubtree(array);
|
||||||
|
for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
|
||||||
|
cv->GetPresShell(getter_AddRefs(shell));
|
||||||
|
if (shell) {
|
||||||
|
nsIFrame *rootFrame = shell->GetRootFrame();
|
||||||
|
if (rootFrame) {
|
||||||
|
shell->FrameNeedsReflow(rootFrame,
|
||||||
|
nsIPresShell::eStyleChange,
|
||||||
|
NS_FRAME_IS_DIRTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
|
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
|
||||||
{
|
{
|
||||||
@ -3282,6 +3373,14 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
|
|||||||
nsPresContext::CSSPixelsToAppUnits(aWidth),
|
nsPresContext::CSSPixelsToAppUnits(aWidth),
|
||||||
nsPresContext::CSSPixelsToAppUnits(aHeight));
|
nsPresContext::CSSPixelsToAppUnits(aHeight));
|
||||||
|
|
||||||
|
// When the "font.size.inflation.minTwips" preference is set, the
|
||||||
|
// layout depends on the size of the screen. Since when the size
|
||||||
|
// of the screen changes, the scroll position clamping scroll port
|
||||||
|
// size also changes, we hook in the needed updates here rather
|
||||||
|
// than adding a separate notification just for this change.
|
||||||
|
nsPresContext* presContext = GetPresContext();
|
||||||
|
MaybeReflowForInflationScreenWidthChange(presContext);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ interface nsIDOMEventTarget;
|
|||||||
interface nsIRunnable;
|
interface nsIRunnable;
|
||||||
interface nsICompositionStringSynthesizer;
|
interface nsICompositionStringSynthesizer;
|
||||||
|
|
||||||
[scriptable, uuid(ef70a299-033c-4adc-b214-6649aed9d828)]
|
[scriptable, uuid(f3148b3e-6db8-4a49-aa5c-de726449054d)]
|
||||||
interface nsIDOMWindowUtils : nsISupports {
|
interface nsIDOMWindowUtils : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,6 +152,38 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||||||
in float aWidthPx, in float aHeightPx,
|
in float aWidthPx, in float aHeightPx,
|
||||||
in nsIDOMElement aElement,
|
in nsIDOMElement aElement,
|
||||||
in uint32_t aPriority);
|
in uint32_t aPriority);
|
||||||
|
/**
|
||||||
|
* An alternate way to represent a displayport rect as a set of margins and a
|
||||||
|
* base rect to apply those margins to. A consumer of pixels may ask for as
|
||||||
|
* many extra pixels as it would like in each direction. Layout then sets
|
||||||
|
* the base rect to the "visible rect" of the element, which is just the
|
||||||
|
* subrect of the element that is drawn (it does not take in account content
|
||||||
|
* covering the element).
|
||||||
|
*
|
||||||
|
* If both a displayport rect and displayport margins with corresponding base
|
||||||
|
* rect are set with the same priority then the margins will take precendence.
|
||||||
|
*
|
||||||
|
* Specifying an alignment value will ensure that after the base rect has
|
||||||
|
* been expanded by the displayport margins, it will be further expanded so
|
||||||
|
* that each edge is located at a multiple of the "alignment" value.
|
||||||
|
*
|
||||||
|
* Note that both the margin values and alignment are treated as values in
|
||||||
|
* LayerPixels. Refer to layout/base/Units.h for a description of this unit.
|
||||||
|
* The base rect values are in app units.
|
||||||
|
*/
|
||||||
|
void setDisplayPortMarginsForElement(in float aLeftMargin,
|
||||||
|
in float aTopMargin,
|
||||||
|
in float aRightMargin,
|
||||||
|
in float aBottomMargin,
|
||||||
|
in uint32_t aAlignment,
|
||||||
|
in nsIDOMElement aElement,
|
||||||
|
in uint32_t aPriority);
|
||||||
|
|
||||||
|
void setDisplayPortBaseForElement(in int32_t aX,
|
||||||
|
in int32_t aY,
|
||||||
|
in int32_t aWidth,
|
||||||
|
in int32_t aHeight,
|
||||||
|
in nsIDOMElement aElement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a display port is set, this allows a sub-section of that
|
* When a display port is set, this allows a sub-section of that
|
||||||
|
@ -244,6 +244,8 @@ TabChildBase::HandlePossibleViewportChange()
|
|||||||
metrics.mCompositionBounds = ParentLayerIntRect(
|
metrics.mCompositionBounds = ParentLayerIntRect(
|
||||||
ParentLayerIntPoint(),
|
ParentLayerIntPoint(),
|
||||||
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
|
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
|
||||||
|
metrics.SetRootCompositionSize(
|
||||||
|
ScreenSize(mInnerSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.mDevPixelsPerCSSPixel);
|
||||||
|
|
||||||
// This change to the zoom accounts for all types of changes I can conceive:
|
// This change to the zoom accounts for all types of changes I can conceive:
|
||||||
// 1. screen size changes, CSS viewport does not (pages with no meta viewport
|
// 1. screen size changes, CSS viewport does not (pages with no meta viewport
|
||||||
@ -302,11 +304,12 @@ TabChildBase::HandlePossibleViewportChange()
|
|||||||
|
|
||||||
// Calculate a display port _after_ having a scrollable rect because the
|
// Calculate a display port _after_ having a scrollable rect because the
|
||||||
// display port is clamped to the scrollable rect.
|
// display port is clamped to the scrollable rect.
|
||||||
metrics.mDisplayPort = AsyncPanZoomController::CalculatePendingDisplayPort(
|
metrics.SetDisplayPortMargins(AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||||
// The page must have been refreshed in some way such as a new document or
|
// The page must have been refreshed in some way such as a new document or
|
||||||
// new CSS viewport, so we know that there's no velocity, acceleration, and
|
// new CSS viewport, so we know that there's no velocity, acceleration, and
|
||||||
// we have no idea how long painting will take.
|
// we have no idea how long painting will take.
|
||||||
metrics, ScreenPoint(0.0f, 0.0f), 0.0);
|
metrics, ScreenPoint(0.0f, 0.0f), 0.0));
|
||||||
|
metrics.SetUseDisplayPortMargins();
|
||||||
|
|
||||||
// Force a repaint with these metrics. This, among other things, sets the
|
// Force a repaint with these metrics. This, among other things, sets the
|
||||||
// displayport, so we start with async painting.
|
// displayport, so we start with async painting.
|
||||||
|
@ -280,7 +280,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
|||||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||||
|
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
|
nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
|
||||||
rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
|
// Important: Use a null principal here
|
||||||
|
rv = xpc->CreateSandbox(cx, nullptr, getter_AddRefs(sandbox));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// The nsXPConnect sandbox API gives us a wrapper to the sandbox for
|
// The nsXPConnect sandbox API gives us a wrapper to the sandbox for
|
||||||
|
@ -28,7 +28,7 @@ var ConsoleObserver = {
|
|||||||
try {
|
try {
|
||||||
let tab = gBrowser.selectedTab;
|
let tab = gBrowser.selectedTab;
|
||||||
let browser = gBrowser.selectedBrowser;
|
let browser = gBrowser.selectedBrowser;
|
||||||
let win = XPCNativeWrapper.unwrap(browser.contentWindow);
|
let win = browser.contentWindow;
|
||||||
let windowID = getWindowId(win);
|
let windowID = getWindowId(win);
|
||||||
let messages = ConsoleAPIStorage.getEvents(windowID);
|
let messages = ConsoleAPIStorage.getEvents(windowID);
|
||||||
ok(messages.length >= 4, "Some messages found in the storage service");
|
ok(messages.length >= 4, "Some messages found in the storage service");
|
||||||
@ -56,6 +56,7 @@ var ConsoleObserver = {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
dump(ex + "\n\n\n");
|
dump(ex + "\n\n\n");
|
||||||
dump(ex.stack + "\n\n\n");
|
dump(ex.stack + "\n\n\n");
|
||||||
|
ok(false, "We got an unexpected exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +89,7 @@ function test()
|
|||||||
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
|
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
|
||||||
browser.removeEventListener("DOMContentLoaded", onLoad, false);
|
browser.removeEventListener("DOMContentLoaded", onLoad, false);
|
||||||
executeSoon(function test_executeSoon() {
|
executeSoon(function test_executeSoon() {
|
||||||
let win = XPCNativeWrapper.unwrap(browser.contentWindow);
|
let win = browser.contentWindow;
|
||||||
win.console.log("this", "is", "a", "log message");
|
win.console.log("this", "is", "a", "log message");
|
||||||
win.console.info("this", "is", "a", "info message");
|
win.console.info("this", "is", "a", "info message");
|
||||||
win.console.warn("this", "is", "a", "warn message");
|
win.console.warn("this", "is", "a", "warn message");
|
||||||
|
@ -563,10 +563,10 @@ struct ParamTraits< mozilla::gfx::IntPointTyped<T> >
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<class T>
|
||||||
struct ParamTraits<mozilla::gfx::Size>
|
struct ParamTraits< mozilla::gfx::SizeTyped<T> >
|
||||||
{
|
{
|
||||||
typedef mozilla::gfx::Size paramType;
|
typedef mozilla::gfx::SizeTyped<T> paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
@ -707,8 +707,11 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
|||||||
WriteParam(aMsg, aParam.mViewport);
|
WriteParam(aMsg, aParam.mViewport);
|
||||||
WriteParam(aMsg, aParam.mScrollOffset);
|
WriteParam(aMsg, aParam.mScrollOffset);
|
||||||
WriteParam(aMsg, aParam.mDisplayPort);
|
WriteParam(aMsg, aParam.mDisplayPort);
|
||||||
|
WriteParam(aMsg, aParam.mDisplayPortMargins);
|
||||||
|
WriteParam(aMsg, aParam.mUseDisplayPortMargins);
|
||||||
WriteParam(aMsg, aParam.mCriticalDisplayPort);
|
WriteParam(aMsg, aParam.mCriticalDisplayPort);
|
||||||
WriteParam(aMsg, aParam.mCompositionBounds);
|
WriteParam(aMsg, aParam.mCompositionBounds);
|
||||||
|
WriteParam(aMsg, aParam.mRootCompositionSize);
|
||||||
WriteParam(aMsg, aParam.mScrollId);
|
WriteParam(aMsg, aParam.mScrollId);
|
||||||
WriteParam(aMsg, aParam.mResolution);
|
WriteParam(aMsg, aParam.mResolution);
|
||||||
WriteParam(aMsg, aParam.mCumulativeResolution);
|
WriteParam(aMsg, aParam.mCumulativeResolution);
|
||||||
@ -730,8 +733,11 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
|||||||
ReadParam(aMsg, aIter, &aResult->mViewport) &&
|
ReadParam(aMsg, aIter, &aResult->mViewport) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
|
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
|
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
|
||||||
|
ReadParam(aMsg, aIter, &aResult->mDisplayPortMargins) &&
|
||||||
|
ReadParam(aMsg, aIter, &aResult->mUseDisplayPortMargins) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
|
ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
||||||
|
ReadParam(aMsg, aIter, &aResult->mRootCompositionSize) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
|
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
|
||||||
|
@ -85,6 +85,9 @@ public:
|
|||||||
, mZoom(1)
|
, mZoom(1)
|
||||||
, mUpdateScrollOffset(false)
|
, mUpdateScrollOffset(false)
|
||||||
, mScrollGeneration(0)
|
, mScrollGeneration(0)
|
||||||
|
, mRootCompositionSize(0, 0)
|
||||||
|
, mDisplayPortMargins(0, 0, 0, 0)
|
||||||
|
, mUseDisplayPortMargins(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Default copy ctor and operator= are fine
|
// Default copy ctor and operator= are fine
|
||||||
@ -94,7 +97,10 @@ public:
|
|||||||
// mContentDescription is not compared on purpose as it's only used
|
// mContentDescription is not compared on purpose as it's only used
|
||||||
// for debugging.
|
// for debugging.
|
||||||
return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
|
return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
|
||||||
|
mRootCompositionSize == aOther.mRootCompositionSize &&
|
||||||
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
||||||
|
mDisplayPortMargins == aOther.mDisplayPortMargins &&
|
||||||
|
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
|
||||||
mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
|
mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
|
||||||
mViewport.IsEqualEdges(aOther.mViewport) &&
|
mViewport.IsEqualEdges(aOther.mViewport) &&
|
||||||
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
|
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
|
||||||
@ -376,7 +382,37 @@ public:
|
|||||||
{
|
{
|
||||||
mScrollId = scrollId;
|
mScrollId = scrollId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetRootCompositionSize(const CSSSize& aRootCompositionSize)
|
||||||
|
{
|
||||||
|
mRootCompositionSize = aRootCompositionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSSSize& GetRootCompositionSize() const
|
||||||
|
{
|
||||||
|
return mRootCompositionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDisplayPortMargins(const LayerMargin& aDisplayPortMargins)
|
||||||
|
{
|
||||||
|
mDisplayPortMargins = aDisplayPortMargins;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LayerMargin& GetDisplayPortMargins() const
|
||||||
|
{
|
||||||
|
return mDisplayPortMargins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUseDisplayPortMargins()
|
||||||
|
{
|
||||||
|
mUseDisplayPortMargins = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetUseDisplayPortMargins() const
|
||||||
|
{
|
||||||
|
return mUseDisplayPortMargins;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// New fields from now on should be made private and old fields should
|
// New fields from now on should be made private and old fields should
|
||||||
// be refactored to be private.
|
// be refactored to be private.
|
||||||
@ -416,6 +452,17 @@ private:
|
|||||||
// A description of the content element corresponding to this frame.
|
// A description of the content element corresponding to this frame.
|
||||||
// This is empty unless the apz.printtree pref is turned on.
|
// This is empty unless the apz.printtree pref is turned on.
|
||||||
std::string mContentDescription;
|
std::string mContentDescription;
|
||||||
|
|
||||||
|
// The size of the root scrollable's composition bounds, but in local CSS pixels.
|
||||||
|
CSSSize mRootCompositionSize;
|
||||||
|
|
||||||
|
// A display port expressed as layer margins that apply to the rect of what
|
||||||
|
// is drawn of the scrollable element.
|
||||||
|
LayerMargin mDisplayPortMargins;
|
||||||
|
|
||||||
|
// If this is true then we use the display port margins on this metrics,
|
||||||
|
// otherwise use the display port rect.
|
||||||
|
bool mUseDisplayPortMargins;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,12 +66,15 @@
|
|||||||
// #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
|
// #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
|
||||||
#define APZC_LOG_FM(fm, prefix, ...) \
|
#define APZC_LOG_FM(fm, prefix, ...) \
|
||||||
APZC_LOG(prefix ":" \
|
APZC_LOG(prefix ":" \
|
||||||
" i=(%ld %lld) cb=(%d %d %d %d) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \
|
" i=(%ld %lld) cb=(%d %d %d %d) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) dpm=(%.3f %.3f %.3f %.3f) um=%d " \
|
||||||
"s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \
|
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \
|
||||||
__VA_ARGS__, \
|
__VA_ARGS__, \
|
||||||
fm.mPresShellId, fm.GetScrollId(), \
|
fm.mPresShellId, fm.GetScrollId(), \
|
||||||
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
|
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
|
||||||
|
fm.GetRootCompositionSize().width, fm.GetRootCompositionSize().height, \
|
||||||
fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \
|
fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \
|
||||||
|
fm.mDisplayPortMargins.top, fm.mDisplayPortMargins.right, fm.mDisplayPortMargins.bottom, fm.mDisplayPortMargins.left, \
|
||||||
|
fm.mUseDisplayPortMargins ? 1 : 0, \
|
||||||
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
|
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
|
||||||
fm.GetScrollOffset().x, fm.GetScrollOffset().y, \
|
fm.GetScrollOffset().x, fm.GetScrollOffset().y, \
|
||||||
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
|
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
|
||||||
@ -1368,7 +1371,7 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale,
|
|||||||
* Enlarges the displayport along both axes based on the velocity.
|
* Enlarges the displayport along both axes based on the velocity.
|
||||||
*/
|
*/
|
||||||
static CSSSize
|
static CSSSize
|
||||||
CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
|
CalculateDisplayPortSize(const CSSSize& aCompositionSize,
|
||||||
const CSSPoint& aVelocity)
|
const CSSPoint& aVelocity)
|
||||||
{
|
{
|
||||||
float xMultiplier = fabsf(aVelocity.x) < gMinSkateSpeed
|
float xMultiplier = fabsf(aVelocity.x) < gMinSkateSpeed
|
||||||
@ -1377,8 +1380,8 @@ CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
|
|||||||
float yMultiplier = fabsf(aVelocity.y) < gMinSkateSpeed
|
float yMultiplier = fabsf(aVelocity.y) < gMinSkateSpeed
|
||||||
? gYStationarySizeMultiplier
|
? gYStationarySizeMultiplier
|
||||||
: gYSkateSizeMultiplier;
|
: gYSkateSizeMultiplier;
|
||||||
return CSSSize(aCompositionBounds.width * xMultiplier,
|
return CSSSize(aCompositionSize.width * xMultiplier,
|
||||||
aCompositionBounds.height * yMultiplier);
|
aCompositionSize.height * yMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1388,7 +1391,6 @@ CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
|
RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
|
||||||
const CSSRect& aCompositionBounds,
|
|
||||||
const CSSRect& aScrollableRect)
|
const CSSRect& aScrollableRect)
|
||||||
{
|
{
|
||||||
float xSlack = std::max(0.0f, aDisplayPortSize.width - aScrollableRect.width);
|
float xSlack = std::max(0.0f, aDisplayPortSize.width - aScrollableRect.width);
|
||||||
@ -1408,21 +1410,25 @@ RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
|
const LayerMargin AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||||
const FrameMetrics& aFrameMetrics,
|
const FrameMetrics& aFrameMetrics,
|
||||||
const ScreenPoint& aVelocity,
|
const ScreenPoint& aVelocity,
|
||||||
double aEstimatedPaintDuration)
|
double aEstimatedPaintDuration)
|
||||||
{
|
{
|
||||||
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||||
|
CSSSize compositionSize = aFrameMetrics.GetRootCompositionSize();
|
||||||
|
compositionSize =
|
||||||
|
CSSSize(std::min(compositionBounds.width, compositionSize.width),
|
||||||
|
std::min(compositionBounds.height, compositionSize.height));
|
||||||
CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom();
|
CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom();
|
||||||
CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset();
|
CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset();
|
||||||
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
||||||
|
|
||||||
// Calculate the displayport size based on how fast we're moving along each axis.
|
// Calculate the displayport size based on how fast we're moving along each axis.
|
||||||
CSSSize displayPortSize = CalculateDisplayPortSize(compositionBounds, velocity);
|
CSSSize displayPortSize = CalculateDisplayPortSize(compositionSize, velocity);
|
||||||
|
|
||||||
if (gEnlargeDisplayPortWhenClipped) {
|
if (gEnlargeDisplayPortWhenClipped) {
|
||||||
RedistributeDisplayPortExcess(displayPortSize, compositionBounds, scrollableRect);
|
RedistributeDisplayPortExcess(displayPortSize, scrollableRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset the displayport, depending on how fast we're moving and the
|
// Offset the displayport, depending on how fast we're moving and the
|
||||||
@ -1432,9 +1438,9 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
|
|||||||
CSSRect displayPort = CSSRect(scrollOffset + (velocity * paintFactor * gVelocityBias),
|
CSSRect displayPort = CSSRect(scrollOffset + (velocity * paintFactor * gVelocityBias),
|
||||||
displayPortSize);
|
displayPortSize);
|
||||||
|
|
||||||
// Re-center the displayport based on its expansion over the composition bounds.
|
// Re-center the displayport based on its expansion over the composition size.
|
||||||
displayPort.MoveBy((compositionBounds.width - displayPort.width)/2.0f,
|
displayPort.MoveBy((compositionSize.width - displayPort.width)/2.0f,
|
||||||
(compositionBounds.height - displayPort.height)/2.0f);
|
(compositionSize.height - displayPort.height)/2.0f);
|
||||||
|
|
||||||
// Make sure the displayport remains within the scrollable rect.
|
// Make sure the displayport remains within the scrollable rect.
|
||||||
displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
|
displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
|
||||||
@ -1444,7 +1450,15 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
|
|||||||
displayPort.x, displayPort.y, displayPort.width, displayPort.height,
|
displayPort.x, displayPort.y, displayPort.width, displayPort.height,
|
||||||
aVelocity.x, aVelocity.y, (float)estimatedPaintDurationMillis);
|
aVelocity.x, aVelocity.y, (float)estimatedPaintDurationMillis);
|
||||||
|
|
||||||
return displayPort;
|
CSSMargin cssMargins;
|
||||||
|
cssMargins.left = -displayPort.x;
|
||||||
|
cssMargins.top = -displayPort.y;
|
||||||
|
cssMargins.right = displayPort.width - compositionSize.width - cssMargins.left;
|
||||||
|
cssMargins.bottom = displayPort.height - compositionSize.height - cssMargins.top;
|
||||||
|
|
||||||
|
LayerMargin layerMargins = cssMargins * aFrameMetrics.LayersPixelsPerCSSPixel();
|
||||||
|
|
||||||
|
return layerMargins;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncPanZoomController::ScheduleComposite() {
|
void AsyncPanZoomController::ScheduleComposite() {
|
||||||
@ -1464,10 +1478,11 @@ void AsyncPanZoomController::RequestContentRepaint() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics) {
|
void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics) {
|
||||||
aFrameMetrics.mDisplayPort =
|
aFrameMetrics.SetDisplayPortMargins(
|
||||||
CalculatePendingDisplayPort(aFrameMetrics,
|
CalculatePendingDisplayPort(aFrameMetrics,
|
||||||
GetVelocityVector(),
|
GetVelocityVector(),
|
||||||
mPaintThrottler.AverageDuration().ToSeconds());
|
mPaintThrottler.AverageDuration().ToSeconds()));
|
||||||
|
aFrameMetrics.SetUseDisplayPortMargins();
|
||||||
|
|
||||||
// If we're trying to paint what we already think is painted, discard this
|
// If we're trying to paint what we already think is painted, discard this
|
||||||
// request since it's a pointless paint.
|
// request since it's a pointless paint.
|
||||||
@ -1749,6 +1764,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
|
|||||||
}
|
}
|
||||||
mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect;
|
mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect;
|
||||||
mFrameMetrics.mCompositionBounds = aLayerMetrics.mCompositionBounds;
|
mFrameMetrics.mCompositionBounds = aLayerMetrics.mCompositionBounds;
|
||||||
|
mFrameMetrics.SetRootCompositionSize(aLayerMetrics.GetRootCompositionSize());
|
||||||
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
|
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
|
||||||
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
|
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
|
||||||
mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab;
|
mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab;
|
||||||
@ -1868,10 +1884,11 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
endZoomToMetrics.SetScrollOffset(aRect.TopLeft());
|
endZoomToMetrics.SetScrollOffset(aRect.TopLeft());
|
||||||
endZoomToMetrics.mDisplayPort =
|
endZoomToMetrics.SetDisplayPortMargins(
|
||||||
CalculatePendingDisplayPort(endZoomToMetrics,
|
CalculatePendingDisplayPort(endZoomToMetrics,
|
||||||
ScreenPoint(0,0),
|
ScreenPoint(0,0),
|
||||||
0);
|
0));
|
||||||
|
endZoomToMetrics.SetUseDisplayPortMargins();
|
||||||
|
|
||||||
StartAnimation(new ZoomAnimation(
|
StartAnimation(new ZoomAnimation(
|
||||||
mFrameMetrics.GetScrollOffset(),
|
mFrameMetrics.GetScrollOffset(),
|
||||||
|
@ -238,7 +238,7 @@ public:
|
|||||||
* checkerboard immediately. This includes a bunch of logic, including
|
* checkerboard immediately. This includes a bunch of logic, including
|
||||||
* algorithms to bias painting in the direction of the velocity.
|
* algorithms to bias painting in the direction of the velocity.
|
||||||
*/
|
*/
|
||||||
static const CSSRect CalculatePendingDisplayPort(
|
static const LayerMargin CalculatePendingDisplayPort(
|
||||||
const FrameMetrics& aFrameMetrics,
|
const FrameMetrics& aFrameMetrics,
|
||||||
const ScreenPoint& aVelocity,
|
const ScreenPoint& aVelocity,
|
||||||
double aEstimatedPaintDuration);
|
double aEstimatedPaintDuration);
|
||||||
|
@ -638,6 +638,85 @@ static bool GetApzcTreePrintPref() {
|
|||||||
return gPrintApzcTree;
|
return gPrintApzcTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CSSSize
|
||||||
|
CalculateRootCompositionSize(FrameMetrics& aMetrics,
|
||||||
|
bool aIsRootContentDocRootScrollFrame,
|
||||||
|
nsPresContext* aPresContext,
|
||||||
|
nsIFrame* aForFrame, nsIFrame* aScrollFrame)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (aIsRootContentDocRootScrollFrame) {
|
||||||
|
// convert from parent layer pixels to layer pixels to css pixels
|
||||||
|
return ParentLayerSize(aMetrics.mCompositionBounds.Size())
|
||||||
|
* aMetrics.mResolution / aMetrics.LayersPixelsPerCSSPixel();
|
||||||
|
}
|
||||||
|
ParentLayerIntSize rootCompositionSize;
|
||||||
|
nsPresContext* rootPresContext =
|
||||||
|
aPresContext->GetToplevelContentDocumentPresContext();
|
||||||
|
if (!rootPresContext) {
|
||||||
|
rootPresContext = aPresContext->GetRootPresContext();
|
||||||
|
}
|
||||||
|
nsIPresShell* rootPresShell = nullptr;
|
||||||
|
if (rootPresContext) {
|
||||||
|
nsIPresShell* rootPresShell = rootPresContext->PresShell();
|
||||||
|
if (nsIFrame* rootFrame = rootPresShell->GetRootFrame()) {
|
||||||
|
if (nsView* view = rootFrame->GetView()) {
|
||||||
|
nsIWidget* widget = view->GetWidget();
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
// Android hack - temporary workaround for bug 983208 until we figure
|
||||||
|
// out what a proper fix is.
|
||||||
|
if (!widget) {
|
||||||
|
widget = rootFrame->GetNearestWidget();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (widget) {
|
||||||
|
nsIntRect bounds;
|
||||||
|
widget->GetBounds(bounds);
|
||||||
|
rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
|
||||||
|
bounds.width, bounds.height));
|
||||||
|
} else {
|
||||||
|
gfxSize res = rootPresShell->GetCumulativeResolution();
|
||||||
|
LayoutDeviceToParentLayerScale parentResolution(res.width);
|
||||||
|
int32_t rootAUPerDevPixel = rootPresContext->AppUnitsPerDevPixel();
|
||||||
|
nsRect viewBounds = view->GetBounds();
|
||||||
|
rootCompositionSize =
|
||||||
|
RoundedToInt(LayoutDeviceRect::FromAppUnits(viewBounds, rootAUPerDevPixel)
|
||||||
|
* parentResolution).Size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsIWidget* widget = (aScrollFrame ? aScrollFrame : aForFrame)->GetNearestWidget();
|
||||||
|
nsIntRect bounds;
|
||||||
|
widget->GetBounds(bounds);
|
||||||
|
rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
|
||||||
|
bounds.width, bounds.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutDeviceToParentLayerScale parentResolution(1.0f);
|
||||||
|
if (rootPresShell) {
|
||||||
|
parentResolution.scale =
|
||||||
|
rootPresShell->GetCumulativeResolution().width / rootPresShell->GetResolution().width;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSSSize size =
|
||||||
|
ParentLayerSize(rootCompositionSize) / (parentResolution * aMetrics.mDevPixelsPerCSSPixel);
|
||||||
|
|
||||||
|
// Adjust composition size for the size of scroll bars.
|
||||||
|
nsIFrame* rootRootScrollFrame = rootPresShell ? rootPresShell->GetRootScrollFrame() : nullptr;
|
||||||
|
nsIScrollableFrame* rootScrollableFrame = nullptr;
|
||||||
|
if (rootRootScrollFrame) {
|
||||||
|
rootScrollableFrame = aScrollFrame->GetScrollTargetFrame();
|
||||||
|
}
|
||||||
|
if (rootScrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
|
||||||
|
CSSMargin margins = CSSMargin::FromAppUnits(rootScrollableFrame->GetActualScrollbarSizes());
|
||||||
|
size.width -= margins.LeftRight();
|
||||||
|
size.height -= margins.TopBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static void RecordFrameMetrics(nsIFrame* aForFrame,
|
static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||||
nsIFrame* aScrollFrame,
|
nsIFrame* aScrollFrame,
|
||||||
const nsIFrame* aReferenceFrame,
|
const nsIFrame* aReferenceFrame,
|
||||||
@ -670,29 +749,11 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
|||||||
if (aScrollFrame)
|
if (aScrollFrame)
|
||||||
scrollableFrame = aScrollFrame->GetScrollTargetFrame();
|
scrollableFrame = aScrollFrame->GetScrollTargetFrame();
|
||||||
|
|
||||||
|
metrics.mScrollableRect = CSSRect::FromAppUnits(
|
||||||
|
nsLayoutUtils::CalculateScrollableRectForFrame(scrollableFrame, aForFrame));
|
||||||
|
|
||||||
if (scrollableFrame) {
|
if (scrollableFrame) {
|
||||||
nsRect contentBounds = scrollableFrame->GetScrollRange();
|
|
||||||
nsPoint scrollPosition = scrollableFrame->GetScrollPosition();
|
nsPoint scrollPosition = scrollableFrame->GetScrollPosition();
|
||||||
|
|
||||||
// We ifndef the below code for Fennec because it requires special behaviour
|
|
||||||
// on the APZC side. Because Fennec has it's own PZC implementation which doesn't
|
|
||||||
// provide the special behaviour, this code will cause it to break. We can remove
|
|
||||||
// the ifndef once Fennec switches over to APZ or if we add the special handling
|
|
||||||
// to Fennec
|
|
||||||
#ifndef MOZ_WIDGET_ANDROID
|
|
||||||
if (scrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
|
|
||||||
contentBounds.y = scrollPosition.y;
|
|
||||||
contentBounds.height = 0;
|
|
||||||
}
|
|
||||||
if (scrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
|
|
||||||
contentBounds.x = scrollPosition.x;
|
|
||||||
contentBounds.width = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
|
|
||||||
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
|
|
||||||
metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds);
|
|
||||||
metrics.SetScrollOffset(CSSPoint::FromAppUnits(scrollPosition));
|
metrics.SetScrollOffset(CSSPoint::FromAppUnits(scrollPosition));
|
||||||
|
|
||||||
// If the frame was scrolled since the last layers update, and by
|
// If the frame was scrolled since the last layers update, and by
|
||||||
@ -703,10 +764,6 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
|||||||
metrics.SetScrollOffsetUpdated(scrollableFrame->CurrentScrollGeneration());
|
metrics.SetScrollOffsetUpdated(scrollableFrame->CurrentScrollGeneration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
nsRect contentBounds = aForFrame->GetRect();
|
|
||||||
metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
metrics.SetScrollId(aScrollId);
|
metrics.SetScrollId(aScrollId);
|
||||||
metrics.mIsRoot = aIsRoot;
|
metrics.mIsRoot = aIsRoot;
|
||||||
@ -806,6 +863,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
|||||||
metrics.mCompositionBounds.Deflate(boundMargins);
|
metrics.mCompositionBounds.Deflate(boundMargins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metrics.SetRootCompositionSize(
|
||||||
|
CalculateRootCompositionSize(metrics, isRootContentDocRootScrollFrame,
|
||||||
|
presContext, aForFrame, aScrollFrame));
|
||||||
|
|
||||||
if (GetApzcTreePrintPref()) {
|
if (GetApzcTreePrintPref()) {
|
||||||
if (nsIContent* content = frameForCompositionBoundsCalculation->GetContent()) {
|
if (nsIContent* content = frameForCompositionBoundsCalculation->GetContent()) {
|
||||||
nsAutoString contentDescription;
|
nsAutoString contentDescription;
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
#include "ActiveLayerTracker.h"
|
#include "ActiveLayerTracker.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "gfx2DGlue.h"
|
#include "gfx2DGlue.h"
|
||||||
|
#include "mozilla/LookAndFeel.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
@ -655,17 +656,120 @@ nsLayoutUtils::FindScrollableFrameFor(ViewID aId)
|
|||||||
bool
|
bool
|
||||||
nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
|
nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
|
||||||
{
|
{
|
||||||
void* property = aContent->GetProperty(nsGkAtoms::DisplayPort);
|
DisplayPortPropertyData* rectData =
|
||||||
if (!property) {
|
static_cast<DisplayPortPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPort));
|
||||||
|
DisplayPortMarginsPropertyData* marginsData =
|
||||||
|
static_cast<DisplayPortMarginsPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPortMargins));
|
||||||
|
if (!rectData && !marginsData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aResult) {
|
if (aResult) {
|
||||||
*aResult = (static_cast<DisplayPortPropertyData*>(property))->mRect;
|
if (rectData && marginsData) {
|
||||||
|
// choose margins if equal priority
|
||||||
|
if (rectData->mPriority > marginsData->mPriority) {
|
||||||
|
marginsData = nullptr;
|
||||||
|
} else {
|
||||||
|
rectData = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rectData) {
|
||||||
|
*aResult = rectData->mRect;
|
||||||
|
} else {
|
||||||
|
nsRect* baseData =
|
||||||
|
static_cast<nsRect*>(aContent->GetProperty(nsGkAtoms::DisplayPortBase));
|
||||||
|
nsRect base;
|
||||||
|
if (baseData) {
|
||||||
|
base = *baseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||||
|
if (frame) {
|
||||||
|
bool isRoot = false;
|
||||||
|
if (aContent->OwnerDoc()->GetRootElement() == aContent) {
|
||||||
|
// We want the scroll frame, the root scroll frame differs from all
|
||||||
|
// others in that the primary frame is not the scroll frame.
|
||||||
|
frame = frame->PresContext()->PresShell()->GetRootScrollFrame();
|
||||||
|
isRoot = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first convert the base rect to layer pixels
|
||||||
|
nsPresContext* presContext = frame->PresContext();
|
||||||
|
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||||
|
gfxSize res = presContext->PresShell()->GetCumulativeResolution();
|
||||||
|
gfxSize parentRes = res;
|
||||||
|
if (isRoot) {
|
||||||
|
// the base rect for root scroll frames is specified in the parent document
|
||||||
|
// coordinate space, so it doesn't include the local resolution.
|
||||||
|
gfxSize localRes = presContext->PresShell()->GetResolution();
|
||||||
|
parentRes.width /= localRes.width;
|
||||||
|
parentRes.height /= localRes.height;
|
||||||
|
}
|
||||||
|
LayerRect rect;
|
||||||
|
rect.x = parentRes.width * NSAppUnitsToFloatPixels(base.x, auPerDevPixel);
|
||||||
|
rect.y = parentRes.height * NSAppUnitsToFloatPixels(base.y, auPerDevPixel);
|
||||||
|
rect.width =
|
||||||
|
parentRes.width * NSAppUnitsToFloatPixels(base.width, auPerDevPixel);
|
||||||
|
rect.height =
|
||||||
|
parentRes.height * NSAppUnitsToFloatPixels(base.height, auPerDevPixel);
|
||||||
|
|
||||||
|
rect.Inflate(marginsData->mMargins);
|
||||||
|
|
||||||
|
nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame();
|
||||||
|
nsPoint scrollPos(
|
||||||
|
scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0));
|
||||||
|
if (marginsData->mAlignment > 0) {
|
||||||
|
LayerPoint scrollPosLayer(
|
||||||
|
res.width * NSAppUnitsToFloatPixels(scrollPos.x, auPerDevPixel),
|
||||||
|
res.height * NSAppUnitsToFloatPixels(scrollPos.y, auPerDevPixel));
|
||||||
|
rect += scrollPosLayer;
|
||||||
|
|
||||||
|
// Inflate the rectangle by 1 so that we always push to the next tile
|
||||||
|
// boundary. This is desirable to stop from having a rectangle with a
|
||||||
|
// moving origin occasionally being smaller when it coincidentally lines
|
||||||
|
// up to tile boundaries.
|
||||||
|
rect.Inflate(1);
|
||||||
|
|
||||||
|
float left =
|
||||||
|
marginsData->mAlignment * floor(rect.x / marginsData->mAlignment);
|
||||||
|
float top =
|
||||||
|
marginsData->mAlignment * floor(rect.y / marginsData->mAlignment);
|
||||||
|
float right =
|
||||||
|
marginsData->mAlignment * ceil(rect.XMost() / marginsData->mAlignment);
|
||||||
|
float bottom =
|
||||||
|
marginsData->mAlignment * ceil(rect.YMost() / marginsData->mAlignment);
|
||||||
|
rect = LayerRect(left, top, right - left, bottom - top);
|
||||||
|
rect -= scrollPosLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect result;
|
||||||
|
result.x = NSFloatPixelsToAppUnits(rect.x / res.width, auPerDevPixel);
|
||||||
|
result.y = NSFloatPixelsToAppUnits(rect.y / res.height, auPerDevPixel);
|
||||||
|
result.width =
|
||||||
|
NSFloatPixelsToAppUnits(rect.width / res.width, auPerDevPixel);
|
||||||
|
result.height =
|
||||||
|
NSFloatPixelsToAppUnits(rect.height / res.height, auPerDevPixel);
|
||||||
|
|
||||||
|
// Finally, clamp the display port to the expanded scrollable rect.
|
||||||
|
nsRect expandedScrollableRect = CalculateExpandedScrollableRect(frame);
|
||||||
|
result = expandedScrollableRect.Intersect(result + scrollPos) - scrollPos;
|
||||||
|
|
||||||
|
*aResult = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase)
|
||||||
|
{
|
||||||
|
aContent->SetProperty(nsGkAtoms::DisplayPortBase, new nsRect(aBase),
|
||||||
|
nsINode::DeleteProperty<nsRect>);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsLayoutUtils::GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult)
|
nsLayoutUtils::GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult)
|
||||||
{
|
{
|
||||||
@ -2279,7 +2383,12 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
|||||||
if (rootScrollFrame && !aFrame->GetParent()) {
|
if (rootScrollFrame && !aFrame->GetParent()) {
|
||||||
nsIContent* content = rootScrollFrame->GetContent();
|
nsIContent* content = rootScrollFrame->GetContent();
|
||||||
if (content) {
|
if (content) {
|
||||||
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content, &displayport);
|
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content);
|
||||||
|
if (usingDisplayPort) {
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(content,
|
||||||
|
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)));
|
||||||
|
nsLayoutUtils::GetDisplayPort(content, &displayport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5959,6 +6068,122 @@ nsLayoutUtils::UpdateImageVisibilityForFrame(nsIFrame* aImageFrame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsSize
|
||||||
|
nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
nsSize size(aFrame->GetSize());
|
||||||
|
|
||||||
|
nsPresContext* presContext = aFrame->PresContext();
|
||||||
|
nsIPresShell* presShell = presContext->PresShell();
|
||||||
|
|
||||||
|
// For the root scroll frame of the root content document, the above calculation
|
||||||
|
// will yield the size of the viewport frame as the composition bounds, which
|
||||||
|
// doesn't actually correspond to what is visible when
|
||||||
|
// nsIDOMWindowUtils::setCSSViewport has been called to modify the visible area of
|
||||||
|
// the prescontext that the viewport frame is reflowed into. In that case if our
|
||||||
|
// document has a widget then the widget's bounds will correspond to what is
|
||||||
|
// visible. If we don't have a widget the root view's bounds correspond to what
|
||||||
|
// would be visible because they don't get modified by setCSSViewport.
|
||||||
|
bool isRootContentDocRootScrollFrame = presContext->IsRootContentDocument()
|
||||||
|
&& aFrame == presShell->GetRootScrollFrame();
|
||||||
|
if (isRootContentDocRootScrollFrame) {
|
||||||
|
if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
|
||||||
|
if (nsView* view = rootFrame->GetView()) {
|
||||||
|
nsIWidget* widget = view->GetWidget();
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
// Android hack - temporary workaround for bug 983208 until we figure
|
||||||
|
// out what a proper fix is.
|
||||||
|
if (!widget) {
|
||||||
|
widget = rootFrame->GetNearestWidget();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (widget) {
|
||||||
|
nsIntRect bounds;
|
||||||
|
widget->GetBounds(bounds);
|
||||||
|
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||||
|
size = nsSize(bounds.width * auPerDevPixel,
|
||||||
|
bounds.height * auPerDevPixel);
|
||||||
|
} else {
|
||||||
|
nsRect viewBounds = view->GetBounds();
|
||||||
|
size = nsSize(viewBounds.width, viewBounds.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust composition bounds for the size of scroll bars.
|
||||||
|
nsIScrollableFrame* scrollableFrame = aFrame->GetScrollTargetFrame();
|
||||||
|
if (scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
|
||||||
|
nsMargin margins = scrollableFrame->GetActualScrollbarSizes();
|
||||||
|
size.width -= margins.LeftRight();
|
||||||
|
size.height -= margins.TopBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsRect
|
||||||
|
nsLayoutUtils::CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame)
|
||||||
|
{
|
||||||
|
nsRect contentBounds;
|
||||||
|
if (aScrollableFrame) {
|
||||||
|
contentBounds = aScrollableFrame->GetScrollRange();
|
||||||
|
|
||||||
|
// We ifndef the below code for Fennec because it requires special behaviour
|
||||||
|
// on the APZC side. Because Fennec has it's own PZC implementation which doesn't
|
||||||
|
// provide the special behaviour, this code will cause it to break. We can remove
|
||||||
|
// the ifndef once Fennec switches over to APZ or if we add the special handling
|
||||||
|
// to Fennec
|
||||||
|
#ifndef MOZ_WIDGET_ANDROID
|
||||||
|
nsPoint scrollPosition = aScrollableFrame->GetScrollPosition();
|
||||||
|
if (aScrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
|
||||||
|
contentBounds.y = scrollPosition.y;
|
||||||
|
contentBounds.height = 0;
|
||||||
|
}
|
||||||
|
if (aScrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
|
||||||
|
contentBounds.x = scrollPosition.x;
|
||||||
|
contentBounds.width = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
contentBounds.width += aScrollableFrame->GetScrollPortRect().width;
|
||||||
|
contentBounds.height += aScrollableFrame->GetScrollPortRect().height;
|
||||||
|
} else {
|
||||||
|
contentBounds = aRootFrame->GetRect();
|
||||||
|
}
|
||||||
|
return contentBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsRect
|
||||||
|
nsLayoutUtils::CalculateExpandedScrollableRect(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
nsRect scrollableRect =
|
||||||
|
CalculateScrollableRectForFrame(aFrame->GetScrollTargetFrame(),
|
||||||
|
aFrame->PresContext()->PresShell()->GetRootFrame());
|
||||||
|
nsSize compSize = CalculateCompositionSizeForFrame(aFrame);
|
||||||
|
|
||||||
|
if (aFrame == aFrame->PresContext()->PresShell()->GetRootScrollFrame()) {
|
||||||
|
// the composition size for the root scroll frame does not include the
|
||||||
|
// local resolution, so we adjust.
|
||||||
|
gfxSize res = aFrame->PresContext()->PresShell()->GetResolution();
|
||||||
|
compSize.width = NSToCoordRound(compSize.width / ((float) res.width));
|
||||||
|
compSize.height = NSToCoordRound(compSize.height / ((float) res.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollableRect.width < compSize.width) {
|
||||||
|
scrollableRect.x = std::max(0,
|
||||||
|
scrollableRect.x - (compSize.width - scrollableRect.width));
|
||||||
|
scrollableRect.width = compSize.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollableRect.height < compSize.height) {
|
||||||
|
scrollableRect.y = std::max(0,
|
||||||
|
scrollableRect.y - (compSize.height - scrollableRect.height));
|
||||||
|
scrollableRect.height = compSize.height;
|
||||||
|
}
|
||||||
|
return scrollableRect;
|
||||||
|
}
|
||||||
|
|
||||||
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
|
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
|
||||||
// Use safe default values here
|
// Use safe default values here
|
||||||
: mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)
|
: mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)
|
||||||
|
@ -85,6 +85,18 @@ struct DisplayPortPropertyData {
|
|||||||
uint32_t mPriority;
|
uint32_t mPriority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DisplayPortMarginsPropertyData {
|
||||||
|
DisplayPortMarginsPropertyData(const LayerMargin& aMargins,
|
||||||
|
uint32_t aAlignment, uint32_t aPriority)
|
||||||
|
: mMargins(aMargins)
|
||||||
|
, mAlignment(aAlignment)
|
||||||
|
, mPriority(aPriority)
|
||||||
|
{}
|
||||||
|
LayerMargin mMargins;
|
||||||
|
uint32_t mAlignment;
|
||||||
|
uint32_t mPriority;
|
||||||
|
};
|
||||||
|
|
||||||
template <class AnimationsOrTransitions>
|
template <class AnimationsOrTransitions>
|
||||||
extern AnimationsOrTransitions* HasAnimationOrTransition(nsIContent* aContent,
|
extern AnimationsOrTransitions* HasAnimationOrTransition(nsIContent* aContent,
|
||||||
nsIAtom* aAnimationProperty,
|
nsIAtom* aAnimationProperty,
|
||||||
@ -138,6 +150,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr);
|
static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the display port base rect for given element to be used with display
|
||||||
|
* port margins.
|
||||||
|
*/
|
||||||
|
static void SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the critical display port for the given element.
|
* Get the critical display port for the given element.
|
||||||
*/
|
*/
|
||||||
@ -2054,6 +2072,29 @@ public:
|
|||||||
static void
|
static void
|
||||||
UpdateImageVisibilityForFrame(nsIFrame* aImageFrame);
|
UpdateImageVisibilityForFrame(nsIFrame* aImageFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the compostion size for a frame. See FrameMetrics.h for
|
||||||
|
* defintion of composition size (or bounds).
|
||||||
|
*/
|
||||||
|
static nsSize
|
||||||
|
CalculateCompositionSizeForFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the scrollable rect for a frame. See FrameMetrics.h for
|
||||||
|
* defintion of scrollable rect. aScrollableFrame is the scroll frame to calculate
|
||||||
|
* the scrollable rect for. If it's null then we calculate the scrollable rect
|
||||||
|
* as the rect of the root frame.
|
||||||
|
*/
|
||||||
|
static nsRect
|
||||||
|
CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
|
||||||
|
* defintion of expanded scrollable rect.
|
||||||
|
*/
|
||||||
|
static nsRect
|
||||||
|
CalculateExpandedScrollableRect(nsIFrame* aFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uint32_t sFontSizeInflationEmPerLine;
|
static uint32_t sFontSizeInflationEmPerLine;
|
||||||
static uint32_t sFontSizeInflationMinTwips;
|
static uint32_t sFontSizeInflationMinTwips;
|
||||||
|
@ -2458,10 +2458,21 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||||||
nsRect dirtyRect = aDirtyRect.Intersect(mScrollPort);
|
nsRect dirtyRect = aDirtyRect.Intersect(mScrollPort);
|
||||||
|
|
||||||
// Override the dirty rectangle if the displayport has been set.
|
// Override the dirty rectangle if the displayport has been set.
|
||||||
nsRect displayPort;
|
|
||||||
bool usingDisplayport =
|
bool usingDisplayport =
|
||||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort) &&
|
nsLayoutUtils::GetDisplayPort(mOuter->GetContent()) &&
|
||||||
!aBuilder->IsForEventDelivery();
|
!aBuilder->IsForEventDelivery();
|
||||||
|
|
||||||
|
// don't set the display port base rect for root scroll frames,
|
||||||
|
// nsLayoutUtils::PaintFrame or nsSubDocumentFrame::BuildDisplayList
|
||||||
|
// does that for root scroll frames before it expands the dirty rect
|
||||||
|
// to the display port.
|
||||||
|
if (usingDisplayport && !mIsRoot) {
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(mOuter->GetContent(), dirtyRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now that we have an updated base rect we can get the display port
|
||||||
|
nsRect displayPort;
|
||||||
|
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort);
|
||||||
if (usingDisplayport && DisplayportExceedsMaxTextureSize(mOuter->PresContext(), displayPort)) {
|
if (usingDisplayport && DisplayportExceedsMaxTextureSize(mOuter->PresContext(), displayPort)) {
|
||||||
usingDisplayport = false;
|
usingDisplayport = false;
|
||||||
}
|
}
|
||||||
|
@ -376,18 +376,24 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||||||
bool ignoreViewportScrolling = false;
|
bool ignoreViewportScrolling = false;
|
||||||
nsIFrame* savedIgnoreScrollFrame = nullptr;
|
nsIFrame* savedIgnoreScrollFrame = nullptr;
|
||||||
if (subdocRootFrame) {
|
if (subdocRootFrame) {
|
||||||
nsRect displayPort;
|
// get the dirty rect relative to the root frame of the subdoc
|
||||||
if (nsLayoutUtils::ViewportHasDisplayPort(presContext, &displayPort)) {
|
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
|
||||||
haveDisplayPort = true;
|
// and convert into the appunits of the subdoc
|
||||||
dirty = displayPort;
|
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
|
||||||
} else {
|
|
||||||
// get the dirty rect relative to the root frame of the subdoc
|
|
||||||
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
|
|
||||||
// and convert into the appunits of the subdoc
|
|
||||||
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||||
|
if (nsLayoutUtils::ViewportHasDisplayPort(presContext)) {
|
||||||
|
haveDisplayPort = true;
|
||||||
|
// for root content documents we want the base to be the composition bounds
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(rootScrollFrame->GetContent(),
|
||||||
|
presContext->IsRootContentDocument() ?
|
||||||
|
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)) :
|
||||||
|
dirty);
|
||||||
|
nsRect displayPort;
|
||||||
|
nsLayoutUtils::ViewportHasDisplayPort(presContext, &displayPort);
|
||||||
|
dirty = displayPort;
|
||||||
|
}
|
||||||
|
|
||||||
ignoreViewportScrolling =
|
ignoreViewportScrolling =
|
||||||
rootScrollFrame && presShell->IgnoringViewportScrolling();
|
rootScrollFrame && presShell->IgnoringViewportScrolling();
|
||||||
if (ignoreViewportScrolling) {
|
if (ignoreViewportScrolling) {
|
||||||
|
@ -60,20 +60,12 @@ class TierStatus(object):
|
|||||||
|
|
||||||
The build system is organized into linear phases called tiers. Each tier
|
The build system is organized into linear phases called tiers. Each tier
|
||||||
executes in the order it was defined, 1 at a time.
|
executes in the order it was defined, 1 at a time.
|
||||||
|
|
||||||
Tiers can have subtiers. Subtiers can execute in any order. Some subtiers
|
|
||||||
execute sequentially. Others are concurrent.
|
|
||||||
|
|
||||||
Subtiers can have directories. Directories can execute in any order, just
|
|
||||||
like subtiers.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, resources):
|
def __init__(self, resources):
|
||||||
"""Accepts a SystemResourceMonitor to record results against."""
|
"""Accepts a SystemResourceMonitor to record results against."""
|
||||||
self.tiers = OrderedDict()
|
self.tiers = OrderedDict()
|
||||||
self.active_tier = None
|
self.active_tier = None
|
||||||
self.active_subtiers = set()
|
|
||||||
self.active_dirs = {}
|
|
||||||
self.resources = resources
|
self.resources = resources
|
||||||
|
|
||||||
def set_tiers(self, tiers):
|
def set_tiers(self, tiers):
|
||||||
@ -83,98 +75,22 @@ class TierStatus(object):
|
|||||||
begin_time=None,
|
begin_time=None,
|
||||||
finish_time=None,
|
finish_time=None,
|
||||||
duration=None,
|
duration=None,
|
||||||
subtiers=OrderedDict(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def begin_tier(self, tier, subtiers):
|
def begin_tier(self, tier):
|
||||||
"""Record that execution of a tier has begun."""
|
"""Record that execution of a tier has begun."""
|
||||||
t = self.tiers[tier]
|
t = self.tiers[tier]
|
||||||
# We should ideally use a monotonic clock here. Unfortunately, we won't
|
# We should ideally use a monotonic clock here. Unfortunately, we won't
|
||||||
# have one until Python 3.
|
# have one until Python 3.
|
||||||
t['begin_time'] = time.time()
|
t['begin_time'] = time.time()
|
||||||
self.resources.begin_phase(self._phase(tier))
|
self.resources.begin_phase(tier)
|
||||||
for subtier in subtiers:
|
|
||||||
t['subtiers'][subtier] = dict(
|
|
||||||
begin_time=None,
|
|
||||||
finish_time=None,
|
|
||||||
duration=None,
|
|
||||||
concurrent=False,
|
|
||||||
dirs=OrderedDict(),
|
|
||||||
dirs_complete=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.active_tier = tier
|
self.active_tier = tier
|
||||||
self.active_subtiers = set()
|
|
||||||
self.active_dirs = {}
|
|
||||||
|
|
||||||
def finish_tier(self, tier):
|
def finish_tier(self, tier):
|
||||||
"""Record that execution of a tier has finished."""
|
"""Record that execution of a tier has finished."""
|
||||||
t = self.tiers[tier]
|
t = self.tiers[tier]
|
||||||
t['finish_time'] = time.time()
|
t['finish_time'] = time.time()
|
||||||
t['duration'] = self.resources.finish_phase(self._phase(tier))
|
t['duration'] = self.resources.finish_phase(tier)
|
||||||
|
|
||||||
def begin_subtier(self, tier, subtier, dirs):
|
|
||||||
"""Record that execution of a subtier has begun."""
|
|
||||||
self.resources.begin_phase(self._phase(tier, subtier))
|
|
||||||
|
|
||||||
st = self.tiers[tier]['subtiers'][subtier]
|
|
||||||
st['begin_time'] = time.time()
|
|
||||||
|
|
||||||
for d in dirs:
|
|
||||||
st['dirs'][d] = dict(
|
|
||||||
begin_time=None,
|
|
||||||
finish_time=None,
|
|
||||||
duration=None,
|
|
||||||
concurrent=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.active_subtiers:
|
|
||||||
st['concurrent'] = True
|
|
||||||
|
|
||||||
self.active_subtiers.add(subtier)
|
|
||||||
|
|
||||||
def finish_subtier(self, tier, subtier):
|
|
||||||
"""Record that execution of a subtier has finished."""
|
|
||||||
st = self.tiers[tier]['subtiers'][subtier]
|
|
||||||
st['finish_time'] = time.time()
|
|
||||||
|
|
||||||
self.active_subtiers.remove(subtier)
|
|
||||||
if self.active_subtiers:
|
|
||||||
st['concurrent'] = True
|
|
||||||
|
|
||||||
# A subtier may not have directories.
|
|
||||||
try:
|
|
||||||
del self.active_dirs[subtier]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
st['duration'] = self.resources.finish_phase(self._phase(tier, subtier))
|
|
||||||
|
|
||||||
def begin_dir(self, tier, subtier, d):
|
|
||||||
"""Record that execution of a directory has begun."""
|
|
||||||
self.resources.begin_phase(self._phase(tier, subtier, d))
|
|
||||||
entry = self.tiers[tier]['subtiers'][subtier]['dirs'][d]
|
|
||||||
entry['begin_time'] = time.time()
|
|
||||||
|
|
||||||
self.active_dirs.setdefault(subtier, set()).add(d)
|
|
||||||
|
|
||||||
if len(self.active_dirs[subtier]) > 1:
|
|
||||||
entry['concurrent'] = True
|
|
||||||
|
|
||||||
def finish_dir(self, tier, subtier, d):
|
|
||||||
"""Record that execution of a directory has finished."""
|
|
||||||
st = self.tiers[tier]['subtiers'][subtier]
|
|
||||||
st['dirs_complete'] += 1
|
|
||||||
|
|
||||||
entry = st['dirs'][d]
|
|
||||||
entry['finish_time'] = time.time()
|
|
||||||
|
|
||||||
self.active_dirs[subtier].remove(d)
|
|
||||||
if self.active_dirs[subtier]:
|
|
||||||
entry['concurrent'] = True
|
|
||||||
|
|
||||||
entry['duration'] = self.resources.finish_phase(self._phase(tier,
|
|
||||||
subtier, d))
|
|
||||||
|
|
||||||
def tier_status(self):
|
def tier_status(self):
|
||||||
for tier, state in self.tiers.items():
|
for tier, state in self.tiers.items():
|
||||||
@ -183,21 +99,6 @@ class TierStatus(object):
|
|||||||
|
|
||||||
yield tier, active, finished
|
yield tier, active, finished
|
||||||
|
|
||||||
def current_subtier_status(self):
|
|
||||||
if self.active_tier not in self.tiers:
|
|
||||||
return
|
|
||||||
|
|
||||||
for subtier, state in self.tiers[self.active_tier]['subtiers'].items():
|
|
||||||
active = subtier in self.active_subtiers
|
|
||||||
finished = state['finish_time'] is not None
|
|
||||||
|
|
||||||
yield subtier, active, finished
|
|
||||||
|
|
||||||
def current_dirs_status(self):
|
|
||||||
for subtier, dirs in self.active_dirs.items():
|
|
||||||
st = self.tiers[self.active_tier]['subtiers'][subtier]
|
|
||||||
yield subtier, st['dirs'].keys(), dirs, st['dirs_complete']
|
|
||||||
|
|
||||||
def tiered_resource_usage(self):
|
def tiered_resource_usage(self):
|
||||||
"""Obtains an object containing resource usage for tiers.
|
"""Obtains an object containing resource usage for tiers.
|
||||||
|
|
||||||
@ -211,38 +112,9 @@ class TierStatus(object):
|
|||||||
start=state['begin_time'],
|
start=state['begin_time'],
|
||||||
end=state['finish_time'],
|
end=state['finish_time'],
|
||||||
duration=state['duration'],
|
duration=state['duration'],
|
||||||
subtiers=[],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.add_resources_to_dict(t_entry, phase=self._phase(tier))
|
self.add_resources_to_dict(t_entry, phase=tier)
|
||||||
|
|
||||||
for subtier, state in state['subtiers'].items():
|
|
||||||
st_entry = dict(
|
|
||||||
name=subtier,
|
|
||||||
start=state['begin_time'],
|
|
||||||
end=state['finish_time'],
|
|
||||||
duration=state['duration'],
|
|
||||||
concurrent=state['concurrent'],
|
|
||||||
dirs=[],
|
|
||||||
)
|
|
||||||
|
|
||||||
self.add_resources_to_dict(st_entry, phase=self._phase(tier,
|
|
||||||
subtier))
|
|
||||||
|
|
||||||
for d, state in state['dirs'].items():
|
|
||||||
d_entry = dict(
|
|
||||||
name=d,
|
|
||||||
start=state['begin_time'],
|
|
||||||
end=state['finish_time'],
|
|
||||||
duration=state['duration'],
|
|
||||||
)
|
|
||||||
|
|
||||||
self.add_resources_to_dict(d_entry, phase=self._phase(tier,
|
|
||||||
subtier, d))
|
|
||||||
|
|
||||||
st_entry['dirs'].append(d_entry)
|
|
||||||
|
|
||||||
t_entry['subtiers'].append(st_entry)
|
|
||||||
|
|
||||||
o.append(t_entry)
|
o.append(t_entry)
|
||||||
|
|
||||||
@ -276,15 +148,6 @@ class TierStatus(object):
|
|||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def _phase(self, tier, subtier=None, d=None):
|
|
||||||
parts = [tier]
|
|
||||||
if subtier:
|
|
||||||
parts.append(subtier)
|
|
||||||
if d:
|
|
||||||
parts.append(d)
|
|
||||||
|
|
||||||
return '_'.join(parts)
|
|
||||||
|
|
||||||
|
|
||||||
class BuildMonitor(MozbuildObject):
|
class BuildMonitor(MozbuildObject):
|
||||||
"""Monitors the output of the build."""
|
"""Monitors the output of the build."""
|
||||||
@ -356,24 +219,10 @@ class BuildMonitor(MozbuildObject):
|
|||||||
update_needed = False
|
update_needed = False
|
||||||
elif action == 'TIER_START':
|
elif action == 'TIER_START':
|
||||||
tier = args[0]
|
tier = args[0]
|
||||||
subtiers = args[1:]
|
self.tiers.begin_tier(tier)
|
||||||
self.tiers.begin_tier(tier, subtiers)
|
|
||||||
elif action == 'TIER_FINISH':
|
elif action == 'TIER_FINISH':
|
||||||
tier, = args
|
tier, = args
|
||||||
self.tiers.finish_tier(tier)
|
self.tiers.finish_tier(tier)
|
||||||
elif action == 'SUBTIER_START':
|
|
||||||
tier, subtier = args[0:2]
|
|
||||||
dirs = args[2:]
|
|
||||||
self.tiers.begin_subtier(tier, subtier, dirs)
|
|
||||||
elif action == 'SUBTIER_FINISH':
|
|
||||||
tier, subtier = args
|
|
||||||
self.tiers.finish_subtier(tier, subtier)
|
|
||||||
elif action == 'TIERDIR_START':
|
|
||||||
tier, subtier, d = args
|
|
||||||
self.tiers.begin_dir(tier, subtier, d)
|
|
||||||
elif action == 'TIERDIR_FINISH':
|
|
||||||
tier, subtier, d = args
|
|
||||||
self.tiers.finish_dir(tier, subtier, d)
|
|
||||||
else:
|
else:
|
||||||
raise Exception('Unknown build status: %s' % action)
|
raise Exception('Unknown build status: %s' % action)
|
||||||
|
|
||||||
|
@ -153,42 +153,6 @@ class BuildProgressFooter(object):
|
|||||||
else:
|
else:
|
||||||
parts.extend([tier, ' '])
|
parts.extend([tier, ' '])
|
||||||
|
|
||||||
parts.extend([('bold', 'SUBTIER'), ':', ' '])
|
|
||||||
for subtier, active, finished in tiers.current_subtier_status():
|
|
||||||
if active:
|
|
||||||
parts.extend([('underline_yellow', subtier), ' '])
|
|
||||||
elif finished:
|
|
||||||
parts.extend([('green', subtier), ' '])
|
|
||||||
else:
|
|
||||||
parts.extend([subtier, ' '])
|
|
||||||
|
|
||||||
if tiers.active_dirs:
|
|
||||||
parts.extend([('bold', 'DIRECTORIES'), ': '])
|
|
||||||
have_dirs = False
|
|
||||||
|
|
||||||
for subtier, all_dirs, active_dirs, complete in tiers.current_dirs_status():
|
|
||||||
if len(all_dirs) < 2:
|
|
||||||
continue
|
|
||||||
|
|
||||||
have_dirs = True
|
|
||||||
|
|
||||||
parts.extend([
|
|
||||||
'%02d' % (complete + 1),
|
|
||||||
'/',
|
|
||||||
'%02d' % len(all_dirs),
|
|
||||||
' ',
|
|
||||||
'(',
|
|
||||||
])
|
|
||||||
if active_dirs:
|
|
||||||
commas = [', '] * (len(active_dirs) - 1)
|
|
||||||
magenta_dirs = [('magenta', d) for d in active_dirs]
|
|
||||||
parts.extend(i.next() for i in itertools.cycle((iter(magenta_dirs),
|
|
||||||
iter(commas))))
|
|
||||||
parts.append(')')
|
|
||||||
|
|
||||||
if not have_dirs:
|
|
||||||
parts = parts[0:-2]
|
|
||||||
|
|
||||||
# We don't want to write more characters than the current width of the
|
# We don't want to write more characters than the current width of the
|
||||||
# terminal otherwise wrapping may result in weird behavior. We can't
|
# terminal otherwise wrapping may result in weird behavior. We can't
|
||||||
# simply truncate the line at terminal width characters because a)
|
# simply truncate the line at terminal width characters because a)
|
||||||
|
@ -201,38 +201,6 @@ BuildResources.prototype = Object.freeze({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubtier: function (tier, subtier) {
|
|
||||||
var t = this.getTier(tier);
|
|
||||||
|
|
||||||
if (!t) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < t.subtiers.length; i++) {
|
|
||||||
var entry = t.subtiers[i];
|
|
||||||
|
|
||||||
if (entry.name == subtier) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getDirectory: function (tier, subtier, directory) {
|
|
||||||
var st = this.getSubtier(tier, subtier);
|
|
||||||
|
|
||||||
if (!st) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < st.dirs.length; i++) {
|
|
||||||
var entry = st.dirs[i];
|
|
||||||
|
|
||||||
if (entry.name == directory) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateResourcesGraph() {
|
function updateResourcesGraph() {
|
||||||
@ -391,8 +359,8 @@ function renderResources(id, resources, what) {
|
|||||||
.call(yAxis)
|
.call(yAxis)
|
||||||
;
|
;
|
||||||
|
|
||||||
// Now we render a timeline of sorts of the tiers, subtiers, and directories.
|
// Now we render a timeline of sorts of the tiers
|
||||||
// There are 3 rows of rectangles that visualize divisions between the
|
// There is a row of rectangles that visualize divisions between the
|
||||||
// different items. We use the same x scale as the resource graph so times
|
// different items. We use the same x scale as the resource graph so times
|
||||||
// line up properly.
|
// line up properly.
|
||||||
svg = d3.select("#" + id).append("svg")
|
svg = d3.select("#" + id).append("svg")
|
||||||
@ -418,73 +386,14 @@ function renderResources(id, resources, what) {
|
|||||||
.attr("class", "timeline tier")
|
.attr("class", "timeline tier")
|
||||||
.attr("tier", t)
|
.attr("tier", t)
|
||||||
;
|
;
|
||||||
|
|
||||||
tier.subtiers.forEach(function (subtier) {
|
|
||||||
var x_start = x(subtier.start - resources.offset);
|
|
||||||
var x_end = x(subtier.end - resources.offset);
|
|
||||||
var draw_width = x_end - x_start;
|
|
||||||
|
|
||||||
var classes = "timeline subtier";
|
|
||||||
if (draw_width < 6) {
|
|
||||||
classes += " short";
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.append("rect")
|
|
||||||
.attr("x", x_start)
|
|
||||||
.attr("y", 60)
|
|
||||||
.attr("height", 30)
|
|
||||||
.attr("width", draw_width)
|
|
||||||
.attr("class", classes)
|
|
||||||
.attr("tier", t)
|
|
||||||
.attr("subtier", subtier.name)
|
|
||||||
;
|
|
||||||
|
|
||||||
subtier.dirs.forEach(function (dir) {
|
|
||||||
var x_start = x(dir.start - resources.offset);
|
|
||||||
var x_end = x(dir.end - resources.offset);
|
|
||||||
var draw_width = x_end - x_start;
|
|
||||||
|
|
||||||
var classes = "timeline directory";
|
|
||||||
|
|
||||||
if (draw_width < 6) {
|
|
||||||
classes += " short";
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.append("rect")
|
|
||||||
.attr("x", x_start)
|
|
||||||
.attr("y", 100)
|
|
||||||
.attr("height", 30)
|
|
||||||
.attr("width", draw_width)
|
|
||||||
.attr("class", classes)
|
|
||||||
.attr("tier", t)
|
|
||||||
.attr("subtier", subtier.name)
|
|
||||||
.attr("directory", dir.name)
|
|
||||||
;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function getEntry(element) {
|
function getEntry(element) {
|
||||||
var tier = element.getAttribute("tier");
|
var tier = element.getAttribute("tier");
|
||||||
var subtier = element.getAttribute("subtier");
|
|
||||||
var directory = element.getAttribute("directory");
|
|
||||||
|
|
||||||
var entry = resources.getTier(tier);
|
var entry = resources.getTier(tier);
|
||||||
entry.tier = tier;
|
entry.tier = tier;
|
||||||
|
|
||||||
if (subtier) {
|
|
||||||
entry = resources.getSubtier(tier, subtier);
|
|
||||||
entry.tier = tier;
|
|
||||||
entry.subtier = subtier;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directory) {
|
|
||||||
entry = resources.getDirectory(tier, subtier, directory);
|
|
||||||
entry.tier = tier;
|
|
||||||
entry.subtier = subtier;
|
|
||||||
entry.directory = directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,8 +402,6 @@ function renderResources(id, resources, what) {
|
|||||||
var entry = getEntry(this);
|
var entry = getEntry(this);
|
||||||
|
|
||||||
d3.select("#tt_tier").html(entry.tier);
|
d3.select("#tt_tier").html(entry.tier);
|
||||||
d3.select("#tt_subtier").html(entry.subtier || "n/a");
|
|
||||||
d3.select("#tt_directory").html(entry.directory || "n/a");
|
|
||||||
d3.select("#tt_duration").html(entry.duration || "n/a");
|
d3.select("#tt_duration").html(entry.duration || "n/a");
|
||||||
d3.select("#tt_cpu_percent").html(entry.cpu_percent || "n/a");
|
d3.select("#tt_cpu_percent").html(entry.cpu_percent || "n/a");
|
||||||
|
|
||||||
@ -536,8 +443,6 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||||||
<div id="tooltip" style="display: none;">
|
<div id="tooltip" style="display: none;">
|
||||||
<table border="0">
|
<table border="0">
|
||||||
<tr><td>Tier</td><td id="tt_tier"></td></tr>
|
<tr><td>Tier</td><td id="tt_tier"></td></tr>
|
||||||
<tr><td>Subtier</td><td id="tt_subtier"></td></tr>
|
|
||||||
<tr><td>Directory</td><td id="tt_directory"></td></tr>
|
|
||||||
<tr><td>Duration</td><td id="tt_duration"></td></tr>
|
<tr><td>Duration</td><td id="tt_duration"></td></tr>
|
||||||
<tr><td>CPU %</td><td id="tt_cpu_percent"></td></tr>
|
<tr><td>CPU %</td><td id="tt_cpu_percent"></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
67
toolkit/content/directoryLinks.json
Normal file
67
toolkit/content/directoryLinks.json
Normal file
File diff suppressed because one or more lines are too long
@ -39,6 +39,7 @@ toolkit.jar:
|
|||||||
* content/global/customizeToolbar.js (customizeToolbar.js)
|
* content/global/customizeToolbar.js (customizeToolbar.js)
|
||||||
content/global/customizeToolbar.xul (customizeToolbar.xul)
|
content/global/customizeToolbar.xul (customizeToolbar.xul)
|
||||||
content/global/devicestorage.properties (devicestorage.properties)
|
content/global/devicestorage.properties (devicestorage.properties)
|
||||||
|
content/global/directoryLinks.json (directoryLinks.json)
|
||||||
content/global/editMenuOverlay.js (editMenuOverlay.js)
|
content/global/editMenuOverlay.js (editMenuOverlay.js)
|
||||||
*+ content/global/editMenuOverlay.xul (editMenuOverlay.xul)
|
*+ content/global/editMenuOverlay.xul (editMenuOverlay.xul)
|
||||||
content/global/finddialog.js (finddialog.js)
|
content/global/finddialog.js (finddialog.js)
|
||||||
|
@ -165,11 +165,12 @@ ProfilerActor.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If these values are objects with a non-null 'wrappedJSObject'
|
* If these values are objects with a non-null 'wrappedJSObject' property
|
||||||
* property, use its value. Otherwise, use the value unchanged.
|
* and aren't Xrays, use their .wrappedJSObject. Otherwise, use the value
|
||||||
|
* unchanged.
|
||||||
*/
|
*/
|
||||||
aSubject = (aSubject && aSubject.wrappedJSObject) || aSubject;
|
aSubject = (aSubject && !Cu.isXrayWrapper(aSubject) && aSubject.wrappedJSObject) || aSubject;
|
||||||
aData = (aData && aData.wrappedJSObject) || aData;
|
aData = (aData && !Cu.isXrayWrapper(aData) && aData.wrappedJSObject) || aData;
|
||||||
|
|
||||||
let subj = JSON.parse(JSON.stringify(aSubject, cycleBreaker));
|
let subj = JSON.parse(JSON.stringify(aSubject, cycleBreaker));
|
||||||
let data = JSON.parse(JSON.stringify(aData, cycleBreaker));
|
let data = JSON.parse(JSON.stringify(aData, cycleBreaker));
|
||||||
|
@ -448,10 +448,7 @@ function ThreadActor(aHooks, aGlobal)
|
|||||||
this._state = "detached";
|
this._state = "detached";
|
||||||
this._frameActors = [];
|
this._frameActors = [];
|
||||||
this._hooks = aHooks;
|
this._hooks = aHooks;
|
||||||
this.global = this.globalSafe = aGlobal;
|
this.global = aGlobal;
|
||||||
if (aGlobal && aGlobal.wrappedJSObject) {
|
|
||||||
this.global = aGlobal.wrappedJSObject;
|
|
||||||
}
|
|
||||||
// A map of actorID -> actor for breakpoints created and managed by the server.
|
// A map of actorID -> actor for breakpoints created and managed by the server.
|
||||||
this._hiddenBreakpoints = new Map();
|
this._hiddenBreakpoints = new Map();
|
||||||
|
|
||||||
@ -1818,7 +1815,7 @@ ThreadActor.prototype = {
|
|||||||
// Clear DOM event breakpoints.
|
// Clear DOM event breakpoints.
|
||||||
// XPCShell tests don't use actual DOM windows for globals and cause
|
// XPCShell tests don't use actual DOM windows for globals and cause
|
||||||
// removeListenerForAllEvents to throw.
|
// removeListenerForAllEvents to throw.
|
||||||
if (this.globalSafe && !this.globalSafe.toString().contains("Sandbox")) {
|
if (this.global && !this.global.toString().contains("Sandbox")) {
|
||||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||||
.getService(Ci.nsIEventListenerService);
|
.getService(Ci.nsIEventListenerService);
|
||||||
els.removeListenerForAllEvents(this.global, this._allEventsListener, true);
|
els.removeListenerForAllEvents(this.global, this._allEventsListener, true);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
const { Cu } = require("chrome");
|
const { Cu } = require("chrome");
|
||||||
const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||||
|
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||||
addDebuggerToGlobal(this);
|
addDebuggerToGlobal(this);
|
||||||
@ -91,7 +92,13 @@ function TraceActor(aConn, aParentActor)
|
|||||||
this._buffer = [];
|
this._buffer = [];
|
||||||
this.onExitFrame = this.onExitFrame.bind(this);
|
this.onExitFrame = this.onExitFrame.bind(this);
|
||||||
|
|
||||||
this.global = aParentActor.window.wrappedJSObject;
|
// aParentActor.window might be an Xray for a window, but it might also be a
|
||||||
|
// double-wrapper for a Sandbox. We want to unwrap the latter but not the
|
||||||
|
// former.
|
||||||
|
this.global = aParentActor.window;
|
||||||
|
if (!Cu.isXrayWrapper(this.global)) {
|
||||||
|
this.global = this.global.wrappedJSObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceActor.prototype = {
|
TraceActor.prototype = {
|
||||||
|
@ -228,7 +228,7 @@ BrowserTabList.prototype.getList = function() {
|
|||||||
// For each tab in this XUL window, ensure that we have an actor for
|
// For each tab in this XUL window, ensure that we have an actor for
|
||||||
// it, reusing existing actors where possible. We actually iterate
|
// it, reusing existing actors where possible. We actually iterate
|
||||||
// over 'browser' XUL elements, and BrowserTabActor uses
|
// over 'browser' XUL elements, and BrowserTabActor uses
|
||||||
// browser.contentWindow.wrappedJSObject as the debuggee global.
|
// browser.contentWindow as the debuggee global.
|
||||||
for (let browser of this._getChildren(win)) {
|
for (let browser of this._getChildren(win)) {
|
||||||
// Do we have an existing actor for this browser? If not, create one.
|
// Do we have an existing actor for this browser? If not, create one.
|
||||||
let actor = this._actorByBrowser.get(browser);
|
let actor = this._actorByBrowser.get(browser);
|
||||||
@ -912,7 +912,7 @@ TabActor.prototype = {
|
|||||||
this.threadActor.clearDebuggees();
|
this.threadActor.clearDebuggees();
|
||||||
if (this.threadActor.dbg) {
|
if (this.threadActor.dbg) {
|
||||||
this.threadActor.dbg.enabled = true;
|
this.threadActor.dbg.enabled = true;
|
||||||
this.threadActor.global = evt.target.defaultView.wrappedJSObject;
|
this.threadActor.global = evt.target.defaultView;
|
||||||
this.threadActor.maybePauseOnExceptions();
|
this.threadActor.maybePauseOnExceptions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,8 @@ WebConsoleActor.prototype =
|
|||||||
hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI(aWindow) {
|
hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI(aWindow) {
|
||||||
let isNative = false;
|
let isNative = false;
|
||||||
try {
|
try {
|
||||||
|
// We are very explicitly examining the "console" property of
|
||||||
|
// the non-Xrayed object here.
|
||||||
let console = aWindow.wrappedJSObject.console;
|
let console = aWindow.wrappedJSObject.console;
|
||||||
isNative = console instanceof aWindow.Console;
|
isNative = console instanceof aWindow.Console;
|
||||||
}
|
}
|
||||||
|
196
toolkit/modules/DirectoryLinksProvider.jsm
Normal file
196
toolkit/modules/DirectoryLinksProvider.jsm
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
this.EXPORTED_SYMBOLS = ["DirectoryLinksProvider"];
|
||||||
|
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||||
|
"resource://gre/modules/NetUtil.jsm");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the currently selected locale for display.
|
||||||
|
* @return the selected locale or "en-US" if none is selected
|
||||||
|
*/
|
||||||
|
function getLocale() {
|
||||||
|
let matchOS;
|
||||||
|
try {
|
||||||
|
matchOS = Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE);
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
|
||||||
|
if (matchOS) {
|
||||||
|
return Services.locale.getLocaleComponentForUserAgent();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE,
|
||||||
|
Ci.nsIPrefLocalizedString);
|
||||||
|
if (locale) {
|
||||||
|
return locale.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Services.prefs.getCharPref(PREF_SELECTED_LOCALE);
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
|
||||||
|
return "en-US";
|
||||||
|
}
|
||||||
|
|
||||||
|
// The preference that tells whether to match the OS locale
|
||||||
|
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
|
||||||
|
|
||||||
|
// The preference that tells what locale the user selected
|
||||||
|
const PREF_SELECTED_LOCALE = "general.useragent.locale";
|
||||||
|
|
||||||
|
// The preference that tells where to obtain directory links
|
||||||
|
const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directorySource";
|
||||||
|
|
||||||
|
// The frecency of a directory link
|
||||||
|
const DIRECTORY_FRECENCY = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton that serves as the provider of directory links.
|
||||||
|
* Directory links are a hard-coded set of links shown if a user's link
|
||||||
|
* inventory is empty.
|
||||||
|
*/
|
||||||
|
let DirectoryLinksProvider = {
|
||||||
|
|
||||||
|
__linksURL: null,
|
||||||
|
|
||||||
|
_observers: [],
|
||||||
|
|
||||||
|
get _prefs() Object.freeze({
|
||||||
|
linksURL: PREF_DIRECTORY_SOURCE,
|
||||||
|
matchOSLocale: PREF_MATCH_OS_LOCALE,
|
||||||
|
prefSelectedLocale: PREF_SELECTED_LOCALE,
|
||||||
|
}),
|
||||||
|
|
||||||
|
get _linksURL() {
|
||||||
|
if (!this.__linksURL) {
|
||||||
|
try {
|
||||||
|
this.__linksURL = Services.prefs.getCharPref(this._prefs["linksURL"]);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Cu.reportError("Error fetching directory links url from prefs: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.__linksURL;
|
||||||
|
},
|
||||||
|
|
||||||
|
observe: function DirectoryLinksProvider_observe(aSubject, aTopic, aData) {
|
||||||
|
if (aTopic == "nsPref:changed") {
|
||||||
|
if (aData == this._prefs["linksURL"]) {
|
||||||
|
delete this.__linksURL;
|
||||||
|
}
|
||||||
|
this._callObservers("onManyLinksChanged");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_addPrefsObserver: function DirectoryLinksProvider_addObserver() {
|
||||||
|
for (let pref in this._prefs) {
|
||||||
|
let prefName = this._prefs[pref];
|
||||||
|
Services.prefs.addObserver(prefName, this, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_removePrefsObserver: function DirectoryLinksProvider_removeObserver() {
|
||||||
|
for (let pref in this._prefs) {
|
||||||
|
let prefName = this._prefs[pref];
|
||||||
|
Services.prefs.removeObserver(prefName, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the current set of directory links.
|
||||||
|
* @param aCallback a callback that is provided a set of links.
|
||||||
|
*/
|
||||||
|
_fetchLinks: function DirectoryLinksProvider_fetchLinks(aCallback) {
|
||||||
|
try {
|
||||||
|
NetUtil.asyncFetch(this._linksURL, (aInputStream, aResult, aRequest) => {
|
||||||
|
let output;
|
||||||
|
if (Components.isSuccessCode(aResult)) {
|
||||||
|
try {
|
||||||
|
let json = NetUtil.readInputStreamToString(aInputStream,
|
||||||
|
aInputStream.available(),
|
||||||
|
{charset: "UTF-8"});
|
||||||
|
let locale = getLocale();
|
||||||
|
output = JSON.parse(json)[locale];
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Cu.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Cu.reportError(new Error("the fetch of " + this._linksURL + "was unsuccessful"));
|
||||||
|
}
|
||||||
|
aCallback(output || []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Cu.reportError(e);
|
||||||
|
aCallback([]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current set of directory links.
|
||||||
|
* @param aCallback The function that the array of links is passed to.
|
||||||
|
*/
|
||||||
|
getLinks: function DirectoryLinksProvider_getLinks(aCallback) {
|
||||||
|
this._fetchLinks(rawLinks => {
|
||||||
|
// all directory links have a frecency of DIRECTORY_FRECENCY
|
||||||
|
aCallback(rawLinks.map((link, position) => {
|
||||||
|
link.frecency = DIRECTORY_FRECENCY;
|
||||||
|
link.lastVisitDate = rawLinks.length - position;
|
||||||
|
return link;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function DirectoryLinksProvider_init() {
|
||||||
|
this._addPrefsObserver();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the object to its pre-init state
|
||||||
|
*/
|
||||||
|
reset: function DirectoryLinksProvider_reset() {
|
||||||
|
delete this.__linksURL;
|
||||||
|
this._removePrefsObserver();
|
||||||
|
this._removeObservers();
|
||||||
|
},
|
||||||
|
|
||||||
|
addObserver: function DirectoryLinksProvider_addObserver(aObserver) {
|
||||||
|
this._observers.push(aObserver);
|
||||||
|
},
|
||||||
|
|
||||||
|
_callObservers: function DirectoryLinksProvider__callObservers(aMethodName, aArg) {
|
||||||
|
for (let obs of this._observers) {
|
||||||
|
if (typeof(obs[aMethodName]) == "function") {
|
||||||
|
try {
|
||||||
|
obs[aMethodName](this, aArg);
|
||||||
|
} catch (err) {
|
||||||
|
Cu.reportError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeObservers: function() {
|
||||||
|
while (this._observers.length) {
|
||||||
|
this._observers.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -17,6 +17,7 @@ EXTRA_JS_MODULES += [
|
|||||||
'DeferredTask.jsm',
|
'DeferredTask.jsm',
|
||||||
'Deprecated.jsm',
|
'Deprecated.jsm',
|
||||||
'Dict.jsm',
|
'Dict.jsm',
|
||||||
|
'DirectoryLinksProvider.jsm',
|
||||||
'FileUtils.jsm',
|
'FileUtils.jsm',
|
||||||
'Finder.jsm',
|
'Finder.jsm',
|
||||||
'Geometry.jsm',
|
'Geometry.jsm',
|
||||||
|
152
toolkit/modules/tests/xpcshell/test_DirectoryLinksProvider.js
Normal file
152
toolkit/modules/tests/xpcshell/test_DirectoryLinksProvider.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/DirectoryLinksProvider.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Promise.jsm");
|
||||||
|
|
||||||
|
const DIRECTORY_FRECENCY = 1000;
|
||||||
|
const kTestSource = 'data:application/json,{"en-US": [{"url":"http://example.com","title":"TestSource"}]}';
|
||||||
|
|
||||||
|
function isIdentical(actual, expected) {
|
||||||
|
if (expected == null) {
|
||||||
|
do_check_eq(actual, expected);
|
||||||
|
}
|
||||||
|
else if (typeof expected == "object") {
|
||||||
|
// Make sure all the keys match up
|
||||||
|
do_check_eq(Object.keys(actual).sort() + "", Object.keys(expected).sort());
|
||||||
|
|
||||||
|
// Recursively check each value individually
|
||||||
|
Object.keys(expected).forEach(key => {
|
||||||
|
isIdentical(actual[key], expected[key]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do_check_eq(actual, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchData(provider) {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
|
||||||
|
provider.getLinks(linkData => {
|
||||||
|
deferred.resolve(linkData);
|
||||||
|
});
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_task(function test_DirectoryLinksProvider__linkObservers() {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
let testObserver = {
|
||||||
|
onManyLinksChanged: function() {
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let provider = DirectoryLinksProvider;
|
||||||
|
provider.init();
|
||||||
|
provider.addObserver(testObserver);
|
||||||
|
do_check_eq(provider._observers.length, 1);
|
||||||
|
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
|
||||||
|
|
||||||
|
yield deferred.promise;
|
||||||
|
provider._removeObservers();
|
||||||
|
do_check_eq(provider._observers.length, 0);
|
||||||
|
|
||||||
|
provider.reset();
|
||||||
|
Services.prefs.clearUserPref(provider._prefs['linksURL']);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(function test_DirectoryLinksProvider__linksURL_locale() {
|
||||||
|
let data = {
|
||||||
|
"en-US": [{url: "http://example.com", title: "US"}],
|
||||||
|
"zh-CN": [
|
||||||
|
{url: "http://example.net", title: "CN"},
|
||||||
|
{url:"http://example.net/2", title: "CN2"}
|
||||||
|
],
|
||||||
|
};
|
||||||
|
let dataURI = 'data:application/json,' + JSON.stringify(data);
|
||||||
|
|
||||||
|
let provider = DirectoryLinksProvider;
|
||||||
|
Services.prefs.setCharPref(provider._prefs['linksURL'], dataURI);
|
||||||
|
Services.prefs.setCharPref('general.useragent.locale', 'en-US');
|
||||||
|
|
||||||
|
// set up the observer
|
||||||
|
provider.init();
|
||||||
|
do_check_eq(provider._linksURL, dataURI);
|
||||||
|
|
||||||
|
let links;
|
||||||
|
let expected_data;
|
||||||
|
|
||||||
|
links = yield fetchData(provider);
|
||||||
|
do_check_eq(links.length, 1);
|
||||||
|
expected_data = [{url: "http://example.com", title: "US", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
|
||||||
|
isIdentical(links, expected_data);
|
||||||
|
|
||||||
|
Services.prefs.setCharPref('general.useragent.locale', 'zh-CN');
|
||||||
|
|
||||||
|
links = yield fetchData(provider);
|
||||||
|
do_check_eq(links.length, 2)
|
||||||
|
expected_data = [
|
||||||
|
{url: "http://example.net", title: "CN", frecency: DIRECTORY_FRECENCY, lastVisitDate: 2},
|
||||||
|
{url: "http://example.net/2", title: "CN2", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}
|
||||||
|
];
|
||||||
|
isIdentical(links, expected_data);
|
||||||
|
|
||||||
|
provider.reset();
|
||||||
|
Services.prefs.clearUserPref('general.useragent.locale');
|
||||||
|
Services.prefs.clearUserPref(provider._prefs['linksURL']);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(function test_DirectoryLinksProvider__prefObserver_url() {
|
||||||
|
let provider = DirectoryLinksProvider;
|
||||||
|
Services.prefs.setCharPref('general.useragent.locale', 'en-US');
|
||||||
|
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
|
||||||
|
|
||||||
|
// set up the observer
|
||||||
|
provider.init();
|
||||||
|
do_check_eq(provider._linksURL, kTestSource);
|
||||||
|
|
||||||
|
let links = yield fetchData(provider);
|
||||||
|
do_check_eq(links.length, 1);
|
||||||
|
let expectedData = [{url: "http://example.com", title: "TestSource", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
|
||||||
|
isIdentical(links, expectedData);
|
||||||
|
|
||||||
|
// tests these 2 things:
|
||||||
|
// 1. observer trigger on pref change
|
||||||
|
// 2. invalid source url
|
||||||
|
let exampleUrl = 'http://example.com/bad';
|
||||||
|
Services.prefs.setCharPref(provider._prefs['linksURL'], exampleUrl);
|
||||||
|
|
||||||
|
do_check_eq(provider._linksURL, exampleUrl);
|
||||||
|
|
||||||
|
let newLinks = yield fetchData(provider);
|
||||||
|
isIdentical(newLinks, []);
|
||||||
|
|
||||||
|
provider.reset();
|
||||||
|
Services.prefs.clearUserPref('general.useragent.locale')
|
||||||
|
Services.prefs.clearUserPref(provider._prefs['linksURL']);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(function test_DirectoryLinksProvider_getLinks_noLocaleData() {
|
||||||
|
let provider = DirectoryLinksProvider;
|
||||||
|
Services.prefs.setCharPref('general.useragent.locale', 'zh-CN');
|
||||||
|
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
|
||||||
|
|
||||||
|
let links = yield fetchData(provider);
|
||||||
|
do_check_eq(links.length, 0);
|
||||||
|
provider.reset();
|
||||||
|
Services.prefs.clearUserPref('general.useragent.locale')
|
||||||
|
Services.prefs.clearUserPref(provider._prefs['linksURL']);
|
||||||
|
});
|
@ -10,6 +10,7 @@ support-files =
|
|||||||
[test_AsyncShutdown.js]
|
[test_AsyncShutdown.js]
|
||||||
[test_DeferredTask.js]
|
[test_DeferredTask.js]
|
||||||
[test_dict.js]
|
[test_dict.js]
|
||||||
|
[test_DirectoryLinksProvider.js]
|
||||||
[test_FileUtils.js]
|
[test_FileUtils.js]
|
||||||
[test_Http.js]
|
[test_Http.js]
|
||||||
[test_Log.js]
|
[test_Log.js]
|
||||||
|
@ -67,33 +67,52 @@ MaybeAlignAndClampDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics,
|
|||||||
{
|
{
|
||||||
// Correct the display-port by the difference between the requested scroll
|
// Correct the display-port by the difference between the requested scroll
|
||||||
// offset and the resulting scroll offset after setting the requested value.
|
// offset and the resulting scroll offset after setting the requested value.
|
||||||
CSSRect& displayPort = aFrameMetrics.mDisplayPort;
|
if (!aFrameMetrics.GetUseDisplayPortMargins()) {
|
||||||
displayPort += aFrameMetrics.GetScrollOffset() - aActualScrollOffset;
|
CSSRect& displayPort = aFrameMetrics.mDisplayPort;
|
||||||
|
displayPort += aFrameMetrics.GetScrollOffset() - aActualScrollOffset;
|
||||||
|
|
||||||
// Expand the display port to the next tile boundaries, if tiled thebes layers
|
// Expand the display port to the next tile boundaries, if tiled thebes layers
|
||||||
// are enabled.
|
// are enabled.
|
||||||
if (gfxPrefs::LayersTilesEnabled()) {
|
if (gfxPrefs::LayersTilesEnabled()) {
|
||||||
// We don't use LayersPixelsPerCSSPixel() here as mCumulativeResolution on
|
// We don't use LayersPixelsPerCSSPixel() here as mCumulativeResolution on
|
||||||
// this FrameMetrics may be incorrect (and is about to be reset by mZoom).
|
// this FrameMetrics may be incorrect (and is about to be reset by mZoom).
|
||||||
displayPort =
|
displayPort =
|
||||||
ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
|
ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
|
||||||
aFrameMetrics.GetZoom() *
|
aFrameMetrics.GetZoom() *
|
||||||
ScreenToLayerScale(1.0))
|
ScreenToLayerScale(1.0))
|
||||||
- aActualScrollOffset;
|
- aActualScrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, clamp the display port to the expanded scrollable rect.
|
||||||
|
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
||||||
|
displayPort = scrollableRect.Intersect(displayPort + aActualScrollOffset)
|
||||||
|
- aActualScrollOffset;
|
||||||
|
} else {
|
||||||
|
LayerPoint shift =
|
||||||
|
(aFrameMetrics.GetScrollOffset() - aActualScrollOffset) *
|
||||||
|
aFrameMetrics.LayersPixelsPerCSSPixel();
|
||||||
|
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||||
|
margins.left -= shift.x;
|
||||||
|
margins.right += shift.x;
|
||||||
|
margins.top -= shift.y;
|
||||||
|
margins.bottom += shift.y;
|
||||||
|
aFrameMetrics.SetDisplayPortMargins(margins);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, clamp the display port to the expanded scrollable rect.
|
|
||||||
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
|
||||||
displayPort = scrollableRect.Intersect(displayPort + aActualScrollOffset)
|
|
||||||
- aActualScrollOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
|
RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
|
||||||
{
|
{
|
||||||
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
if (!aFrameMetrics.GetUseDisplayPortMargins()) {
|
||||||
aFrameMetrics.mDisplayPort.x = (compositionBounds.width - aFrameMetrics.mDisplayPort.width) / 2;
|
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||||
aFrameMetrics.mDisplayPort.y = (compositionBounds.height - aFrameMetrics.mDisplayPort.height) / 2;
|
aFrameMetrics.mDisplayPort.x = (compositionBounds.width - aFrameMetrics.mDisplayPort.width) / 2;
|
||||||
|
aFrameMetrics.mDisplayPort.y = (compositionBounds.height - aFrameMetrics.mDisplayPort.height) / 2;
|
||||||
|
} else {
|
||||||
|
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||||
|
margins.right = margins.left = margins.LeftRight() / 2;
|
||||||
|
margins.top = margins.bottom = margins.TopBottom() / 2;
|
||||||
|
aFrameMetrics.SetDisplayPortMargins(margins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CSSPoint
|
static CSSPoint
|
||||||
@ -205,11 +224,29 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
|
|||||||
if (!element) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
|
if (!aMetrics.GetUseDisplayPortMargins()) {
|
||||||
aMetrics.mDisplayPort.y,
|
aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
|
||||||
aMetrics.mDisplayPort.width,
|
aMetrics.mDisplayPort.y,
|
||||||
aMetrics.mDisplayPort.height,
|
aMetrics.mDisplayPort.width,
|
||||||
element, 0);
|
aMetrics.mDisplayPort.height,
|
||||||
|
element, 0);
|
||||||
|
} else {
|
||||||
|
uint32_t alignment = gfxPrefs::LayersTilesEnabled()
|
||||||
|
? TILEDLAYERBUFFER_TILE_SIZE : 1;
|
||||||
|
LayerMargin margins = aMetrics.GetDisplayPortMargins();
|
||||||
|
aUtils->SetDisplayPortMarginsForElement(margins.left,
|
||||||
|
margins.top,
|
||||||
|
margins.right,
|
||||||
|
margins.bottom,
|
||||||
|
alignment,
|
||||||
|
element, 0);
|
||||||
|
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
|
||||||
|
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(content, base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -240,11 +277,29 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
|
|||||||
RecenterDisplayPort(aMetrics);
|
RecenterDisplayPort(aMetrics);
|
||||||
}
|
}
|
||||||
MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
|
MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
|
||||||
utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
|
if (!aMetrics.GetUseDisplayPortMargins()) {
|
||||||
aMetrics.mDisplayPort.y,
|
utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
|
||||||
aMetrics.mDisplayPort.width,
|
aMetrics.mDisplayPort.y,
|
||||||
aMetrics.mDisplayPort.height,
|
aMetrics.mDisplayPort.width,
|
||||||
element, 0);
|
aMetrics.mDisplayPort.height,
|
||||||
|
element, 0);
|
||||||
|
} else {
|
||||||
|
uint32_t alignment = gfxPrefs::LayersTilesEnabled()
|
||||||
|
? TILEDLAYERBUFFER_TILE_SIZE : 1;
|
||||||
|
LayerMargin margins = aMetrics.GetDisplayPortMargins();
|
||||||
|
utils->SetDisplayPortMarginsForElement(margins.left,
|
||||||
|
margins.top,
|
||||||
|
margins.right,
|
||||||
|
margins.bottom,
|
||||||
|
alignment,
|
||||||
|
element, 0);
|
||||||
|
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
|
||||||
|
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
|
||||||
|
baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
|
||||||
|
nsLayoutUtils::SetDisplayPortBase(aContent, base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aMetrics.SetScrollOffset(actualScrollOffset);
|
aMetrics.SetScrollOffset(actualScrollOffset);
|
||||||
|
Loading…
Reference in New Issue
Block a user