mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 20:41:24 +08:00
DEV: Small refactor to header offset (#15421)
Centralizes calculations in a helper under the site header component. This also reverts a small CSS change to the composer: since ac79c5ef, the composer height was not including the grippie, which means that the composer height was off by 11 pixels, and the topic progress widget was sometimes being displayed cut off by 11 pixels.
This commit is contained in:
@ -8,7 +8,7 @@ import Composer from "discourse/models/composer";
|
|||||||
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
|
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
|
||||||
import afterTransition from "discourse/lib/after-transition";
|
import afterTransition from "discourse/lib/after-transition";
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
import { headerHeight } from "discourse/components/site-header";
|
import { headerOffset } from "discourse/components/site-header";
|
||||||
import positioningWorkaround from "discourse/lib/safari-hacks";
|
import positioningWorkaround from "discourse/lib/safari-hacks";
|
||||||
|
|
||||||
const START_DRAG_EVENTS = ["touchstart", "mousedown"];
|
const START_DRAG_EVENTS = ["touchstart", "mousedown"];
|
||||||
@ -130,7 +130,7 @@ export default Component.extend(KeyEnterEscape, {
|
|||||||
const currentMousePos = mouseYPos(event);
|
const currentMousePos = mouseYPos(event);
|
||||||
let size = this.origComposerSize + (this.lastMousePos - currentMousePos);
|
let size = this.origComposerSize + (this.lastMousePos - currentMousePos);
|
||||||
|
|
||||||
size = Math.min(size, window.innerHeight - headerHeight());
|
size = Math.min(size, window.innerHeight - headerOffset());
|
||||||
this.movePanels(size);
|
this.movePanels(size);
|
||||||
this.element.style.height = size ? `${size}px` : "";
|
this.element.style.height = size ? `${size}px` : "";
|
||||||
},
|
},
|
||||||
|
@ -183,13 +183,13 @@ const SiteHeaderComponent = MountWidget.extend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const headerRect = header.getBoundingClientRect();
|
const headerRect = header.getBoundingClientRect();
|
||||||
let headerOffset = headerRect.top + headerRect.height;
|
let headerOffsetCalc = headerRect.top + headerRect.height;
|
||||||
|
|
||||||
if (window.scrollY < 0) {
|
if (window.scrollY < 0) {
|
||||||
headerOffset += window.scrollY;
|
headerOffsetCalc += window.scrollY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newValue = `${headerOffset}px`;
|
const newValue = `${headerOffsetCalc}px`;
|
||||||
if (newValue !== this.currentHeaderOffsetValue) {
|
if (newValue !== this.currentHeaderOffsetValue) {
|
||||||
this.currentHeaderOffsetValue = newValue;
|
this.currentHeaderOffsetValue = newValue;
|
||||||
document.documentElement.style.setProperty("--header-offset", newValue);
|
document.documentElement.style.setProperty("--header-offset", newValue);
|
||||||
@ -389,7 +389,7 @@ const SiteHeaderComponent = MountWidget.extend(
|
|||||||
headerCloak.style.display = "block";
|
headerCloak.style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
const menuTop = this.site.mobileView ? headerTop() : headerHeight();
|
const menuTop = this.site.mobileView ? headerTop() : headerOffset();
|
||||||
|
|
||||||
const winHeightOffset = 16;
|
const winHeightOffset = 16;
|
||||||
let initialWinHeight = window.innerHeight;
|
let initialWinHeight = window.innerHeight;
|
||||||
@ -438,16 +438,13 @@ export default SiteHeaderComponent.extend({
|
|||||||
classNames: ["d-header-wrap"],
|
classNames: ["d-header-wrap"],
|
||||||
});
|
});
|
||||||
|
|
||||||
export function headerHeight() {
|
export function headerOffset() {
|
||||||
const header = document.querySelector("header.d-header");
|
return (
|
||||||
|
parseInt(
|
||||||
// Header may not exist in tests (e.g. in the user menu component test).
|
document.documentElement.style.getPropertyValue("--header-offset"),
|
||||||
if (!header) {
|
10
|
||||||
return 0;
|
) || 0
|
||||||
}
|
);
|
||||||
|
|
||||||
const headerOffsetTop = header.offsetTop ? header.offsetTop : 0;
|
|
||||||
return header.offsetHeight + headerOffsetTop - document.body.scrollTop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function headerTop() {
|
export function headerTop() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Docking from "discourse/mixins/docking";
|
import Docking from "discourse/mixins/docking";
|
||||||
import MountWidget from "discourse/components/mount-widget";
|
import MountWidget from "discourse/components/mount-widget";
|
||||||
|
import { headerOffset } from "discourse/components/site-header";
|
||||||
import { next } from "@ember/runloop";
|
import { next } from "@ember/runloop";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import optionalService from "discourse/lib/optional-service";
|
import optionalService from "discourse/lib/optional-service";
|
||||||
@ -50,7 +51,7 @@ export default MountWidget.extend(Docking, {
|
|||||||
const timelineHeight = (timeline && timeline.offsetHeight) || 400;
|
const timelineHeight = (timeline && timeline.offsetHeight) || 400;
|
||||||
|
|
||||||
const prev = this.dockAt;
|
const prev = this.dockAt;
|
||||||
const posTop = this.headerOffset() + window.pageYOffset;
|
const posTop = headerOffset() + window.pageYOffset;
|
||||||
const pos = posTop + timelineHeight;
|
const pos = posTop + timelineHeight;
|
||||||
|
|
||||||
this.dockBottom = false;
|
this.dockBottom = false;
|
||||||
@ -72,12 +73,6 @@ export default MountWidget.extend(Docking, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
headerOffset() {
|
|
||||||
return (
|
|
||||||
parseInt(document.body.style.getPropertyValue("--header-offset"), 10) || 0
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { addWidgetCleanCallback } from "discourse/components/mount-widget";
|
import { addWidgetCleanCallback } from "discourse/components/mount-widget";
|
||||||
import Site from "discourse/models/site";
|
import Site from "discourse/models/site";
|
||||||
import { bind } from "discourse-common/utils/decorators";
|
import { bind } from "discourse-common/utils/decorators";
|
||||||
|
import { headerOffset } from "discourse/components/site-header";
|
||||||
import { schedule } from "@ember/runloop";
|
import { schedule } from "@ember/runloop";
|
||||||
|
|
||||||
export default class StickyAvatars {
|
export default class StickyAvatars {
|
||||||
@ -78,11 +79,6 @@ export default class StickyAvatars {
|
|||||||
@bind
|
@bind
|
||||||
_initIntersectionObserver() {
|
_initIntersectionObserver() {
|
||||||
schedule("afterRender", () => {
|
schedule("afterRender", () => {
|
||||||
const headerOffset =
|
|
||||||
parseInt(document.body.style.getPropertyValue("--header-offset"), 10) ||
|
|
||||||
0;
|
|
||||||
const headerHeight = Math.max(headerOffset, 0);
|
|
||||||
|
|
||||||
this.intersectionObserver = new IntersectionObserver(
|
this.intersectionObserver = new IntersectionObserver(
|
||||||
(entries) => {
|
(entries) => {
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
@ -95,13 +91,16 @@ export default class StickyAvatars {
|
|||||||
?.clientHeight;
|
?.clientHeight;
|
||||||
if (
|
if (
|
||||||
this.direction === "⬆️" ||
|
this.direction === "⬆️" ||
|
||||||
postContentHeight > window.innerHeight - headerHeight
|
postContentHeight > window.innerHeight - headerOffset()
|
||||||
) {
|
) {
|
||||||
entry.target.classList.add(this.stickyClass);
|
entry.target.classList.add(this.stickyClass);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{ threshold: [0.0, 1.0], rootMargin: `-${headerHeight}px 0px 0px 0px` }
|
{
|
||||||
|
threshold: [0.0, 1.0],
|
||||||
|
rootMargin: `-${headerOffset()}px 0px 0px 0px`,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
height: calc(100% - 11px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.submit-panel {
|
.submit-panel {
|
||||||
@ -60,7 +60,6 @@
|
|||||||
cursor: row-resize;
|
cursor: row-resize;
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
background: var(--tertiary);
|
background: var(--tertiary);
|
||||||
margin-top: -11px;
|
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
|
import { headerOffset } from "discourse/components/site-header";
|
||||||
import isElementInViewport from "discourse/lib/is-element-in-viewport";
|
import isElementInViewport from "discourse/lib/is-element-in-viewport";
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
|
|
||||||
@ -85,17 +86,10 @@ function initialize(api) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerOffset =
|
|
||||||
parseInt(
|
|
||||||
getComputedStyle(document.body).getPropertyValue(
|
|
||||||
"--header-offset"
|
|
||||||
),
|
|
||||||
10
|
|
||||||
) || 0;
|
|
||||||
const viewportOffset = post.getBoundingClientRect();
|
const viewportOffset = post.getBoundingClientRect();
|
||||||
|
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
top: window.scrollY + viewportOffset.top - headerOffset,
|
top: window.scrollY + viewportOffset.top - headerOffset(),
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user