for #375: M1349940 M1355595 M1334635 M1353708 M1354782 M1354781 M1349742 M1345315 M1356655 M1356663 M1357638 M1358809 M1307134 M1331342 M1220466
This commit is contained in:
parent
966d8cab82
commit
964aa7e7c9
|
@ -1947,11 +1947,9 @@
|
|||
|
||||
if (animate) {
|
||||
requestAnimationFrame(function () {
|
||||
//this.tabContainer._handleTabTelemetryStart(t, aURI);
|
||||
|
||||
// kick the animation off
|
||||
t.setAttribute("fadein", "true");
|
||||
}.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
return t;
|
||||
|
@ -2132,8 +2130,6 @@
|
|||
return;
|
||||
}
|
||||
|
||||
//this.tabContainer._handleTabTelemetryStart(aTab);
|
||||
|
||||
this._blurTab(aTab);
|
||||
aTab.style.maxWidth = ""; // ensure that fade-out transition happens
|
||||
aTab.removeAttribute("fadein");
|
||||
|
@ -4529,8 +4525,12 @@
|
|||
|
||||
<handlers>
|
||||
<handler event="underflow" phase="capturing"><![CDATA[
|
||||
if (event.originalTarget != this._scrollbox)
|
||||
return;
|
||||
|
||||
// Ignore vertical events
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
return;
|
||||
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.removeAttribute("overflow");
|
||||
|
@ -4544,8 +4544,12 @@
|
|||
tabs._positionPinnedTabs();
|
||||
]]></handler>
|
||||
<handler event="overflow"><![CDATA[
|
||||
if (event.originalTarget != this._scrollbox)
|
||||
return;
|
||||
|
||||
// Ignore vertical events
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
return;
|
||||
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.setAttribute("overflow", "true");
|
||||
|
@ -4602,13 +4606,6 @@
|
|||
|
||||
window.addEventListener("resize", this, false);
|
||||
window.addEventListener("load", this, false);
|
||||
|
||||
try {
|
||||
this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled");
|
||||
} catch (ex) {
|
||||
this._tabAnimationLoggingEnabled = false;
|
||||
}
|
||||
this._browserNewtabpageEnabled = false; //Services.prefs.getBoolPref("browser.newtabpage.enabled");
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
|
@ -4757,6 +4754,12 @@
|
|||
|
||||
<method name="adjustTabstrip">
|
||||
<body><![CDATA[
|
||||
// If we're overflowing, tab widths don't change anymore, so we can
|
||||
// return early to avoid flushing layout.
|
||||
if (this.getAttribute("overflow") == "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
let numTabs = this.childNodes.length -
|
||||
this.tabbrowser._removingTabs.length;
|
||||
if (numTabs > 2) {
|
||||
|
@ -4913,16 +4916,19 @@
|
|||
|
||||
let scrollButtonWidth = this.mTabstrip._scrollButtonDown.getBoundingClientRect().width;
|
||||
let paddingStart = this.mTabstrip.scrollboxPaddingStart;
|
||||
let pinnedTabWidth;
|
||||
let width = 0;
|
||||
|
||||
for (let i = numPinned - 1; i >= 0; i--) {
|
||||
let tab = this.childNodes[i];
|
||||
width += tab.getBoundingClientRect().width;
|
||||
if (!pinnedTabWidth) {
|
||||
pinnedTabWidth = tab.getBoundingClientRect().width;
|
||||
}
|
||||
width += pinnedTabWidth;
|
||||
tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
|
||||
}
|
||||
|
||||
this.style.MozPaddingStart = width + paddingStart + "px";
|
||||
|
||||
} else {
|
||||
this.removeAttribute("positionpinnedtabs");
|
||||
|
||||
|
@ -5258,89 +5264,6 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_handleTabTelemetryStart">
|
||||
<parameter name="aTab"/>
|
||||
<parameter name="aURI"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
/*
|
||||
// Animation-smoothness telemetry/logging
|
||||
if (Services.telemetry.canRecordExtended || this._tabAnimationLoggingEnabled) {
|
||||
if (aURI == "about:newtab" && (aTab._tPos == 1 || aTab._tPos == 2)) {
|
||||
// Indicate newtab page animation where other tabs are unaffected
|
||||
// (for which case, the 2nd or 3rd tabs are good representatives, even if not absolute)
|
||||
aTab._recordingTabOpenPlain = true;
|
||||
}
|
||||
aTab._recordingHandle = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.startFrameTimeRecording();
|
||||
}
|
||||
|
||||
// Overall animation duration
|
||||
aTab._animStartTime = Date.now();
|
||||
*/
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_handleTabTelemetryEnd">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
/*
|
||||
if (!aTab._animStartTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
Services.telemetry.getHistogramById(aTab.closing ?
|
||||
"FX_TAB_ANIM_CLOSE_MS" :
|
||||
"FX_TAB_ANIM_OPEN_MS")
|
||||
.add(Date.now() - aTab._animStartTime);
|
||||
aTab._animStartTime = 0;
|
||||
|
||||
// Handle tab animation smoothness telemetry/logging of frame intervals and paint times
|
||||
if (!("_recordingHandle" in aTab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let intervals = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.stopFrameTimeRecording(aTab._recordingHandle);
|
||||
delete aTab._recordingHandle;
|
||||
let frameCount = intervals.length;
|
||||
|
||||
if (this._tabAnimationLoggingEnabled) {
|
||||
let msg = "Tab " + (aTab.closing ? "close" : "open") + " (Frame-interval):\n";
|
||||
for (let i = 0; i < frameCount; i++) {
|
||||
msg += Math.round(intervals[i]) + "\n";
|
||||
}
|
||||
Services.console.logStringMessage(msg);
|
||||
}
|
||||
|
||||
// For telemetry, the first frame interval is not useful since it may represent an interval
|
||||
// to a relatively old frame (prior to recording start). So we'll ignore it for the average.
|
||||
if (frameCount > 1) {
|
||||
let averageInterval = 0;
|
||||
for (let i = 1; i < frameCount; i++) {
|
||||
averageInterval += intervals[i];
|
||||
};
|
||||
averageInterval = averageInterval / (frameCount - 1);
|
||||
|
||||
Services.telemetry.getHistogramById("FX_TAB_ANIM_ANY_FRAME_INTERVAL_MS").add(averageInterval);
|
||||
|
||||
if (aTab._recordingTabOpenPlain) {
|
||||
delete aTab._recordingTabOpenPlain;
|
||||
// While we do have a telemetry probe NEWTAB_PAGE_ENABLED to monitor newtab preview, it'll be
|
||||
// easier to overview the data without slicing by it. Hence the additional histograms with _PREVIEW.
|
||||
let preview = this._browserNewtabpageEnabled ? "_PREVIEW" : "";
|
||||
Services.telemetry.getHistogramById("FX_TAB_ANIM_OPEN" + preview + "_FRAME_INTERVAL_MS").add(averageInterval);
|
||||
}
|
||||
}
|
||||
*/
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- Deprecated stuff, implemented for backwards compatibility. -->
|
||||
<property name="mAllTabsPopup" readonly="true"
|
||||
onget="return document.getElementById('alltabs-popup');"/>
|
||||
|
@ -5355,8 +5278,6 @@
|
|||
|
||||
var tab = event.target;
|
||||
|
||||
//this._handleTabTelemetryEnd(tab);
|
||||
|
||||
if (tab.getAttribute("fadein") == "true") {
|
||||
if (tab._fullyOpen)
|
||||
this.adjustTabstrip();
|
||||
|
@ -6389,7 +6310,7 @@
|
|||
if (val) {
|
||||
this.setAttribute("label", val);
|
||||
this.removeAttribute("inactive");
|
||||
this._calcMouseTargetRect();
|
||||
this._mouseTargetRect = null;
|
||||
MousePosTracker.addListener(this);
|
||||
} else {
|
||||
this.setAttribute("inactive", "true");
|
||||
|
@ -6405,6 +6326,9 @@
|
|||
|
||||
<method name="getMouseTargetRect">
|
||||
<body><![CDATA[
|
||||
if (!this._mouseTargetRect) {
|
||||
this._calcMouseTargetRect();
|
||||
}
|
||||
return this._mouseTargetRect;
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -6429,7 +6353,7 @@
|
|||
|
||||
switch (event.type) {
|
||||
case "resize":
|
||||
this._calcMouseTargetRect();
|
||||
this._mouseTargetRect = null;
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
|
@ -6460,7 +6384,7 @@
|
|||
|
||||
if (!this.hasAttribute("sizelimit")) {
|
||||
this.setAttribute("sizelimit", "true");
|
||||
this._calcMouseTargetRect();
|
||||
this._mouseTargetRect = null;
|
||||
}
|
||||
</body>
|
||||
</method>
|
||||
|
|
|
@ -735,7 +735,12 @@ this.UITour = {
|
|||
}
|
||||
}
|
||||
|
||||
this.initForBrowser(browser, window);
|
||||
// For performance reasons, only call initForBrowser if we did something
|
||||
// that will require a teardownTourForBrowser call later.
|
||||
// getConfiguration (called from about:home) doesn't require any future
|
||||
// uninitialization.
|
||||
if (action != "getConfiguration")
|
||||
this.initForBrowser(browser, window);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
|
|
@ -4890,12 +4890,6 @@ nsGlobalWindow::GetOuterSize(ErrorResult& aError)
|
|||
return nsIntSize(0, 0);
|
||||
}
|
||||
|
||||
nsGlobalWindow* rootWindow =
|
||||
static_cast<nsGlobalWindow *>(GetPrivateRoot());
|
||||
if (rootWindow) {
|
||||
rootWindow->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIntSize sizeDevPixels;
|
||||
aError = treeOwnerAsWin->GetSize(&sizeDevPixels.width, &sizeDevPixels.height);
|
||||
if (aError.Failed()) {
|
||||
|
@ -5077,11 +5071,7 @@ nsGlobalWindow::GetInnerScreenRect()
|
|||
return nsRect();
|
||||
}
|
||||
|
||||
nsGlobalWindow* rootWindow =
|
||||
static_cast<nsGlobalWindow*>(GetPrivateRoot());
|
||||
if (rootWindow) {
|
||||
rootWindow->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
EnsureSizeUpToDate();
|
||||
|
||||
if (!mDocShell) {
|
||||
return nsRect();
|
||||
|
|
|
@ -171,6 +171,7 @@ TextCompositionArray* IMEStateManager::sTextCompositions = nullptr;
|
|||
bool IMEStateManager::sInstalledMenuKeyboardListener = false;
|
||||
bool IMEStateManager::sIsGettingNewIMEState = false;
|
||||
bool IMEStateManager::sCheckForIMEUnawareWebApps = false;
|
||||
bool IMEStateManager::sInputModeSupported = false;
|
||||
bool IMEStateManager::sRemoteHasFocus = false;
|
||||
|
||||
// static
|
||||
|
@ -181,6 +182,11 @@ IMEStateManager::Init()
|
|||
&sCheckForIMEUnawareWebApps,
|
||||
"intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition",
|
||||
false);
|
||||
|
||||
Preferences::AddBoolVarCache(
|
||||
&sInputModeSupported,
|
||||
"dom.forms.inputmode",
|
||||
false);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1036,7 +1042,7 @@ IMEStateManager::SetIMEState(const IMEState& aState,
|
|||
context.mHTMLInputType.Assign(nsGkAtoms::textarea->GetUTF16String());
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("dom.forms.inputmode", false) ||
|
||||
if (sInputModeSupported ||
|
||||
nsContentUtils::IsChromeDoc(aContent->OwnerDoc())) {
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::inputmode,
|
||||
context.mHTMLInputInputmode);
|
||||
|
|
|
@ -251,6 +251,7 @@ protected:
|
|||
static bool sInstalledMenuKeyboardListener;
|
||||
static bool sIsGettingNewIMEState;
|
||||
static bool sCheckForIMEUnawareWebApps;
|
||||
static bool sInputModeSupported;
|
||||
static bool sRemoteHasFocus;
|
||||
|
||||
class MOZ_STACK_CLASS GettingNewIMEStateBlocker final
|
||||
|
|
|
@ -65,11 +65,19 @@ DeleteRangeTxn::DoTransaction()
|
|||
MOZ_ASSERT(mRange && mEditor);
|
||||
nsresult res;
|
||||
|
||||
// Swap mRange out into a stack variable, so we make sure to null it
|
||||
// out on return from this function. Once this function returns, we no longer
|
||||
// need mRange, and keeping it alive in the long term slows down all
|
||||
// DOM mutations because it's observing them.
|
||||
// (Modified from bug 1349940.)
|
||||
RefPtr<nsRange> rangeToDelete;
|
||||
rangeToDelete.swap(mRange);
|
||||
|
||||
// build the child transactions
|
||||
nsCOMPtr<nsINode> startParent = mRange->GetStartParent();
|
||||
int32_t startOffset = mRange->StartOffset();
|
||||
nsCOMPtr<nsINode> endParent = mRange->GetEndParent();
|
||||
int32_t endOffset = mRange->EndOffset();
|
||||
nsCOMPtr<nsINode> startParent = rangeToDelete->GetStartParent();
|
||||
int32_t startOffset = rangeToDelete->StartOffset();
|
||||
nsCOMPtr<nsINode> endParent = rangeToDelete->GetEndParent();
|
||||
int32_t endOffset = rangeToDelete->EndOffset();
|
||||
MOZ_ASSERT(startParent && endParent);
|
||||
|
||||
if (startParent == endParent) {
|
||||
|
@ -82,7 +90,7 @@ DeleteRangeTxn::DoTransaction()
|
|||
res = CreateTxnsToDeleteContent(startParent, startOffset, nsIEditor::eNext);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
// delete the intervening nodes
|
||||
res = CreateTxnsToDeleteNodesBetween();
|
||||
res = CreateTxnsToDeleteNodesBetween(rangeToDelete);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
// delete the relevant content in the end node
|
||||
res = CreateTxnsToDeleteContent(endParent, endOffset, nsIEditor::ePrevious);
|
||||
|
@ -110,16 +118,12 @@ DeleteRangeTxn::DoTransaction()
|
|||
NS_IMETHODIMP
|
||||
DeleteRangeTxn::UndoTransaction()
|
||||
{
|
||||
MOZ_ASSERT(mRange && mEditor);
|
||||
|
||||
return EditAggregateTxn::UndoTransaction();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DeleteRangeTxn::RedoTransaction()
|
||||
{
|
||||
MOZ_ASSERT(mRange && mEditor);
|
||||
|
||||
return EditAggregateTxn::RedoTransaction();
|
||||
}
|
||||
|
||||
|
@ -211,11 +215,11 @@ DeleteRangeTxn::CreateTxnsToDeleteContent(nsINode* aNode,
|
|||
}
|
||||
|
||||
nsresult
|
||||
DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
|
||||
DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsRange *aRangeToDelete)
|
||||
{
|
||||
nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
|
||||
|
||||
nsresult res = iter->Init(mRange);
|
||||
nsresult res = iter->Init(aRangeToDelete);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
while (!iter->IsDone()) {
|
||||
|
|
|
@ -54,7 +54,7 @@ protected:
|
|||
int32_t aStartOffset,
|
||||
int32_t aEndOffset);
|
||||
|
||||
nsresult CreateTxnsToDeleteNodesBetween();
|
||||
nsresult CreateTxnsToDeleteNodesBetween(nsRange *aRangeToDelete);
|
||||
|
||||
nsresult CreateTxnsToDeleteContent(nsINode* aParent,
|
||||
int32_t aOffset,
|
||||
|
@ -63,6 +63,8 @@ protected:
|
|||
protected:
|
||||
|
||||
/** p1 in the range */
|
||||
/* After bug 1349940, this is only non-null until DoTransaction is called
|
||||
and we convert it into child transactions. */
|
||||
RefPtr<nsRange> mRange;
|
||||
|
||||
/** the editor for this transaction */
|
||||
|
|
|
@ -1046,7 +1046,8 @@ public:
|
|||
mContainerBounds(aContainerBounds),
|
||||
mParameters(aParameters),
|
||||
mPaintedLayerDataTree(*this, aBackgroundColor),
|
||||
mFlattenToSingleLayer(aFlattenToSingleLayer)
|
||||
mFlattenToSingleLayer(aFlattenToSingleLayer),
|
||||
mLastDisplayPortAGR(nullptr)
|
||||
{
|
||||
nsPresContext* presContext = aContainerFrame->PresContext();
|
||||
mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
|
@ -1364,6 +1365,12 @@ protected:
|
|||
bool ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
|
||||
AnimatedGeometryRoot **aAnimatedGeometryRoot);
|
||||
|
||||
/**
|
||||
* Get the display port for an AGR.
|
||||
* The result would be cached for later reusing.
|
||||
*/
|
||||
nsRect GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot);
|
||||
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
LayerManager* mManager;
|
||||
FrameLayerBuilder* mLayerBuilder;
|
||||
|
@ -1420,6 +1427,8 @@ protected:
|
|||
|
||||
nsDataHashtable<nsGenericHashKey<MaskLayerKey>, RefPtr<ImageLayer>>
|
||||
mRecycledMaskImageLayers;
|
||||
AnimatedGeometryRoot* mLastDisplayPortAGR;
|
||||
nsRect mLastDisplayPortRect;
|
||||
};
|
||||
|
||||
class PaintedDisplayItemLayerUserData : public LayerUserData
|
||||
|
@ -3703,6 +3712,34 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
|
|||
return false;
|
||||
}
|
||||
|
||||
nsRect
|
||||
ContainerState::GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot)
|
||||
{
|
||||
// Faster version of the code from ComputeOpaqueRect (after bug 1331342).
|
||||
if (mLastDisplayPortAGR == aAnimatedGeometryRoot) {
|
||||
return mLastDisplayPortRect;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
|
||||
if (sf == nullptr) {
|
||||
return nsRect();
|
||||
}
|
||||
|
||||
mLastDisplayPortAGR = aAnimatedGeometryRoot;
|
||||
nsRect& displayport = mLastDisplayPortRect;
|
||||
|
||||
bool usingDisplayport =
|
||||
nsLayoutUtils::GetDisplayPort((*aAnimatedGeometryRoot)->GetContent(), &displayport);
|
||||
if (!usingDisplayport) {
|
||||
// No async scrolling, so all that matters is that the layer contents
|
||||
// cover the scrollport.
|
||||
displayport = sf->GetScrollPortRect();
|
||||
}
|
||||
nsIFrame* scrollFrame = do_QueryFrame(sf);
|
||||
displayport += scrollFrame->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
return displayport;
|
||||
}
|
||||
|
||||
nsIntRegion
|
||||
ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
|
||||
AnimatedGeometryRoot* aAnimatedGeometryRoot,
|
||||
|
@ -3740,6 +3777,7 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
|
|||
}
|
||||
opaquePixels = ScaleRegionToInsidePixels(opaqueClipped, snapOpaque);
|
||||
|
||||
#if(0)
|
||||
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
|
||||
if (sf) {
|
||||
nsRect displayport;
|
||||
|
@ -3756,6 +3794,17 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
|
|||
*aOpaqueForAnimatedGeometryRootParent = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// backbugs from bug 1220466 and bug 1331342
|
||||
if (IsInInactiveLayer()) return opaquePixels;
|
||||
|
||||
const nsRect& displayport =
|
||||
GetDisplayPortForAnimatedGeometryRoot(aAnimatedGeometryRoot);
|
||||
if (!displayport.IsEmpty() &&
|
||||
opaquePixels.Contains(ScaleRegionToNearestPixels(displayport))) {
|
||||
*aOpaqueForAnimatedGeometryRootParent = true;
|
||||
}
|
||||
#endif
|
||||
// }
|
||||
return opaquePixels;
|
||||
}
|
||||
|
@ -4041,11 +4090,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
// clip we care about is the overflow:hidden clip on the scrollbar.
|
||||
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
|
||||
clipPtr,
|
||||
uniformColorPtr);
|
||||
IsInInactiveLayer() ? nullptr : uniformColorPtr);
|
||||
} else if (prerenderedTransform) {
|
||||
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot,
|
||||
clipPtr,
|
||||
uniformColorPtr);
|
||||
IsInInactiveLayer() ? nullptr : uniformColorPtr);
|
||||
} else {
|
||||
// Using itemVisibleRect here isn't perfect. itemVisibleRect can be
|
||||
// larger or smaller than the potential bounds of item's contents in
|
||||
|
@ -4056,7 +4105,8 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
// Time will tell whether this is good enough, or whether we need to do
|
||||
// something more sophisticated here.
|
||||
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot,
|
||||
&itemVisibleRect, uniformColorPtr);
|
||||
&itemVisibleRect,
|
||||
IsInInactiveLayer() ? nullptr : uniformColorPtr);
|
||||
}
|
||||
|
||||
mParameters.mBackgroundColor = uniformColor;
|
||||
|
|
|
@ -5444,10 +5444,12 @@ nsTextFrame::ComputeSelectionUnderlineHeight(
|
|||
// the default font size, we should use the actual font size because the
|
||||
// computed value from the default font size can be too thick for the
|
||||
// current font size.
|
||||
int32_t defaultFontSize =
|
||||
aPresContext->AppUnitsToDevPixels(nsStyleFont(aPresContext).mFont.size);
|
||||
gfxFloat fontSize = std::min(gfxFloat(defaultFontSize),
|
||||
aFontMetrics.emHeight);
|
||||
nscoord defaultFontSize = aPresContext->GetDefaultFont(
|
||||
kPresContext_DefaultVariableFont_ID, nullptr)->size;
|
||||
int32_t zoomedFontSize = aPresContext->AppUnitsToDevPixels(
|
||||
nsStyleFont::ZoomText(aPresContext, defaultFontSize));
|
||||
gfxFloat fontSize = std::min(gfxFloat(zoomedFontSize),
|
||||
aFontMetrics.emHeight);
|
||||
fontSize = std::max(fontSize, 1.0);
|
||||
return ceil(fontSize / 20);
|
||||
}
|
||||
|
|
|
@ -909,6 +909,9 @@ nsTreeBodyFrame::CheckOverflow(const ScrollParts& aParts)
|
|||
}
|
||||
}
|
||||
|
||||
if (!horizontalOverflowChanged && !verticalOverflowChanged)
|
||||
return;
|
||||
|
||||
nsWeakFrame weakFrame(this);
|
||||
|
||||
RefPtr<nsPresContext> presContext = PresContext();
|
||||
|
|
|
@ -1035,12 +1035,17 @@ extends="chrome://global/content/bindings/popup.xml#popup">
|
|||
<setter>
|
||||
<![CDATA[
|
||||
this.richlistbox.selectedIndex = val;
|
||||
|
||||
// when clearing the selection (val == -1, so selectedItem will be
|
||||
// null), we want to scroll back to the top. see bug #406194
|
||||
this.richlistbox.ensureElementIsVisible(
|
||||
this.richlistbox.selectedItem || this.richlistbox.firstChild);
|
||||
|
||||
// Since ensureElementIsVisible may cause an expensive Layout flush,
|
||||
// invoke it only if there may be a scrollbar, so if we could fetch
|
||||
// more results than we can show at once.
|
||||
// maxResults is the maximum number of fetched results, maxRows is the
|
||||
// maximum number of rows we show at once, without a scrollbar.
|
||||
if (this.maxResults > this.maxRows) {
|
||||
// when clearing the selection (val == -1, so selectedItem will be
|
||||
// null), we want to scroll back to the top. see bug #406194
|
||||
this.richlistbox.ensureElementIsVisible(
|
||||
this.richlistbox.selectedItem || this.richlistbox.firstChild);
|
||||
}
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
|
|
Loading…
Reference in New Issue