mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1358443 - remove reflows from adjustHeight itself, r=mak,florian
This goes back to relying on rows being the same height. Places where we replace the popup will likely not use the richlistbox, and we no longer have code that changes the height or exceeds the maximum number of visible children with a scrollbar, so we should be OK. To determine the padding on the richlistbox and the height of the initial row, I've used a promiseDocumentFlushed callback. It's possible this causes flicker the first time the popup opens. I can't see any, but it's quite possible I'm missing something. Differential Revision: https://phabricator.services.mozilla.com/D2242 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
4f0be13f9c
commit
5c512f312d
@ -799,7 +799,6 @@
|
||||
autocompletesearchparam="enable-actions"
|
||||
autocompletepopup="PopupAutoCompleteRichResult"
|
||||
completeselectedindex="true"
|
||||
shrinkdelay="250"
|
||||
tabscrolling="true"
|
||||
newlines="stripsurroundingwhitespace"
|
||||
ontextentered="this.handleCommand(param);"
|
||||
|
@ -30,22 +30,6 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
|
||||
],
|
||||
maxCount: 5, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
|
||||
],
|
||||
maxCount: 51, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
|
||||
|
@ -30,22 +30,6 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
|
||||
],
|
||||
maxCount: 5, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
|
||||
],
|
||||
maxCount: 6, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
|
||||
@ -83,22 +67,6 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
|
||||
|
||||
/* These reflows happen everytime the awesomebar panel opens. */
|
||||
const EXPECTED_REFLOWS_SECOND_OPEN = [
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"onxblpopupshown@chrome://global/content/bindings/autocomplete.xml"
|
||||
],
|
||||
maxCount: 3, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"adjustHeight@chrome://global/content/bindings/autocomplete.xml",
|
||||
"_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
|
||||
],
|
||||
maxCount: 6, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
|
||||
|
@ -1911,6 +1911,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "footer");
|
||||
</field>
|
||||
|
||||
<field name="shrinkDelay" readonly="true">
|
||||
250
|
||||
</field>
|
||||
|
||||
<field name="oneOffSearchButtons" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"one-off-search-buttons");
|
||||
@ -2195,6 +2199,83 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="adjustHeight">
|
||||
<body>
|
||||
<![CDATA[
|
||||
// If we were going to shrink later, cancel that for now:
|
||||
if (this._shrinkTimeout) {
|
||||
clearTimeout(this._shrinkTimeout);
|
||||
this._shrinkTimeout = null;
|
||||
}
|
||||
let lastRowCount = this._lastRowCount;
|
||||
// Figure out how many rows to show
|
||||
let rows = this.richlistbox.childNodes;
|
||||
this._lastRowCount = rows.length;
|
||||
let numRows = Math.min(this.matchCount, this.maxRows, rows.length);
|
||||
|
||||
// If we're going from 0 to non-0 rows, we might need to remove
|
||||
// the height attribute to allow the popup to size. The attribute
|
||||
// is set from XUL popup management code.
|
||||
if (!lastRowCount && rows.length) {
|
||||
this.removeAttribute("height");
|
||||
}
|
||||
|
||||
// Default the height to 0 if we have no rows to show
|
||||
let height = 0;
|
||||
if (numRows) {
|
||||
if (!this._rowHeight) {
|
||||
window.promiseDocumentFlushed(() => {
|
||||
if (window.closed) {
|
||||
return;
|
||||
}
|
||||
this._rowHeight = rows[0].getBoundingClientRect().height;
|
||||
let style = window.getComputedStyle(this.richlistbox);
|
||||
|
||||
let paddingTop = parseInt(style.paddingTop) || 0;
|
||||
let paddingBottom = parseInt(style.paddingBottom) || 0;
|
||||
this._rlbPadding = paddingTop + paddingBottom;
|
||||
// Then re-run - but don't dirty layout from inside this callback.
|
||||
window.requestAnimationFrame(() => this.adjustHeight());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the height to have the first row to last row shown
|
||||
height = (this._rowHeight * numRows) + this._rlbPadding;
|
||||
}
|
||||
|
||||
let animate = this.getAttribute("dontanimate") != "true";
|
||||
let currentHeight =
|
||||
parseFloat(this.richlistbox.getAttribute("height"), 10) ||
|
||||
parseFloat(this.richlistbox.style.height, 10) ||
|
||||
0; // It's possible we get here when we haven't set height on the richlistbox
|
||||
// yet, which means parseFloat will return NaN. It should return 0 instead.
|
||||
if (height > currentHeight) {
|
||||
// Grow immediately.
|
||||
if (animate) {
|
||||
this.richlistbox.removeAttribute("height");
|
||||
this.richlistbox.style.height = height + "px";
|
||||
} else {
|
||||
this.richlistbox.style.removeProperty("height");
|
||||
this.richlistbox.height = height;
|
||||
}
|
||||
} else if (height < currentHeight) { // Don't shrink if height matches exactly
|
||||
// Delay shrinking to avoid flicker.
|
||||
this._shrinkTimeout = setTimeout(() => {
|
||||
this._collapseUnusedItems();
|
||||
if (animate) {
|
||||
this.richlistbox.removeAttribute("height");
|
||||
this.richlistbox.style.height = height + "px";
|
||||
} else {
|
||||
this.richlistbox.style.removeProperty("height");
|
||||
this.richlistbox.height = height;
|
||||
}
|
||||
}, this.shrinkDelay);
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_showSearchSuggestionsNotification">
|
||||
<parameter name="whichNotification"/>
|
||||
<parameter name="popupDirection"/>
|
||||
|
@ -131,10 +131,6 @@
|
||||
<property name="searchCount" readonly="true"
|
||||
onget="this.initSearchNames(); return this.mSearchNames.length;"/>
|
||||
|
||||
<field name="shrinkDelay" readonly="true">
|
||||
parseInt(this.getAttribute("shrinkdelay")) || 0
|
||||
</field>
|
||||
|
||||
<property name="PrivateBrowsingUtils" readonly="true">
|
||||
<getter><![CDATA[
|
||||
let module = {};
|
||||
@ -657,7 +653,6 @@
|
||||
<field name="mInput">null</field>
|
||||
<field name="mPopupOpen">false</field>
|
||||
<field name="_currentIndex">0</field>
|
||||
<field name="_rlbAnimated">false</field>
|
||||
|
||||
<!-- =================== nsIAutoCompletePopup =================== -->
|
||||
|
||||
@ -826,16 +821,14 @@
|
||||
this.richlistbox.collapsed = (this.matchCount == 0);
|
||||
|
||||
// Update the richlistbox height.
|
||||
if (this._adjustHeightTimeout) {
|
||||
clearTimeout(this._adjustHeightTimeout);
|
||||
}
|
||||
if (this._shrinkTimeout) {
|
||||
clearTimeout(this._shrinkTimeout);
|
||||
if (this._adjustHeightRAFToken) {
|
||||
cancelAnimationFrame(this._adjustHeightRAFToken);
|
||||
this._adjustHeightRAFToken = null;
|
||||
}
|
||||
|
||||
if (this.mPopupOpen) {
|
||||
delete this._adjustHeightOnPopupShown;
|
||||
this._adjustHeightTimeout = setTimeout(() => this.adjustHeight(), 0);
|
||||
this._adjustHeightRAFToken = requestAnimationFrame(() => this.adjustHeight());
|
||||
} else {
|
||||
this._adjustHeightOnPopupShown = true;
|
||||
}
|
||||
@ -896,31 +889,17 @@
|
||||
let rows = this.richlistbox.childNodes;
|
||||
let numRows = Math.min(this.matchCount, this.maxRows, rows.length);
|
||||
|
||||
this.removeAttribute("height");
|
||||
|
||||
// Default the height to 0 if we have no rows to show
|
||||
let height = 0;
|
||||
if (numRows) {
|
||||
let firstRowRect = rows[0].getBoundingClientRect();
|
||||
if (this._rlbPadding == undefined) {
|
||||
let style = window.getComputedStyle(this.richlistbox);
|
||||
|
||||
let transition = style.transitionProperty;
|
||||
this._rlbAnimated = transition && transition != "none";
|
||||
|
||||
let paddingTop = parseInt(style.paddingTop) || 0;
|
||||
let paddingBottom = parseInt(style.paddingBottom) || 0;
|
||||
this._rlbPadding = paddingTop + paddingBottom;
|
||||
}
|
||||
|
||||
if (numRows > this.maxRows) {
|
||||
// Set a fixed max-height to avoid flicker when growing the panel.
|
||||
let lastVisibleRowRect = rows[this.maxRows - 1].getBoundingClientRect();
|
||||
let visibleHeight = lastVisibleRowRect.bottom - firstRowRect.top;
|
||||
this.richlistbox.style.maxHeight =
|
||||
visibleHeight + this._rlbPadding + "px";
|
||||
}
|
||||
|
||||
// The class `forceHandleUnderflow` is for the item might need to
|
||||
// handle OverUnderflow or Overflow when the height of an item will
|
||||
// be changed dynamically.
|
||||
@ -936,31 +915,12 @@
|
||||
this._rlbPadding;
|
||||
}
|
||||
|
||||
let animate = this._rlbAnimated &&
|
||||
this.getAttribute("dontanimate") != "true";
|
||||
let currentHeight = this.richlistbox.getBoundingClientRect().height;
|
||||
if (height > currentHeight) {
|
||||
// Grow immediately.
|
||||
if (animate) {
|
||||
this.richlistbox.removeAttribute("height");
|
||||
this.richlistbox.style.height = height + "px";
|
||||
} else {
|
||||
this.richlistbox.style.removeProperty("height");
|
||||
this.richlistbox.height = height;
|
||||
}
|
||||
} else {
|
||||
// Delay shrinking to avoid flicker.
|
||||
this._shrinkTimeout = setTimeout(() => {
|
||||
this._collapseUnusedItems();
|
||||
if (animate) {
|
||||
this.richlistbox.removeAttribute("height");
|
||||
this.richlistbox.style.height = height + "px";
|
||||
} else {
|
||||
this.richlistbox.style.removeProperty("height");
|
||||
this.richlistbox.height = height;
|
||||
}
|
||||
}, this.mInput.shrinkDelay);
|
||||
if (height <= currentHeight) {
|
||||
this._collapseUnusedItems();
|
||||
}
|
||||
this.richlistbox.style.removeProperty("height");
|
||||
this.richlistbox.height = height;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
Loading…
Reference in New Issue
Block a user