Wait for stylesheets to load before setting field content

This commit is contained in:
Henrik Giesel 2021-08-07 01:02:57 +02:00
parent ea01183bfd
commit 701f260c3f
2 changed files with 54 additions and 21 deletions

View file

@ -5,10 +5,41 @@
@typescript-eslint/no-non-null-assertion: "off",
*/
function loadStyleLink(container: Node, href: string): Promise<void> {
const rootStyle = document.createElement("link");
rootStyle.setAttribute("rel", "stylesheet");
rootStyle.setAttribute("href", href);
let styleResolve: () => void;
const stylePromise = new Promise<void>((resolve) => (styleResolve = resolve));
rootStyle.addEventListener("load", () => styleResolve());
container.appendChild(rootStyle);
return stylePromise;
}
function loadStyleTag(container: Node): [HTMLStyleElement, Promise<void>] {
const style = document.createElement("style");
style.setAttribute("rel", "stylesheet");
let styleResolve: () => void;
const stylePromise = new Promise<void>((resolve) => (styleResolve = resolve));
style.addEventListener("load", () => styleResolve());
container.appendChild(style);
return [style, stylePromise];
}
export class EditableContainer extends HTMLDivElement {
baseStyle: HTMLStyleElement;
imageStyle: HTMLStyleElement;
imagePromise: Promise<void>;
stylePromise: Promise<void>;
baseRule?: CSSStyleRule;
imageStyle?: HTMLStyleElement;
constructor() {
super();
@ -18,15 +49,19 @@ export class EditableContainer extends HTMLDivElement {
this.classList.add("night-mode");
}
const rootStyle = document.createElement("link");
rootStyle.setAttribute("rel", "stylesheet");
rootStyle.setAttribute("href", "./_anki/css/editable-build.css");
shadow.appendChild(rootStyle);
const rootPromise = loadStyleLink(shadow, "./_anki/css/editable-build.css");
const [baseStyle, basePromise] = loadStyleTag(shadow);
const [imageStyle, imagePromise] = loadStyleTag(shadow);
this.baseStyle = document.createElement("style");
this.baseStyle.setAttribute("rel", "stylesheet");
this.baseStyle.id = "baseStyle";
shadow.appendChild(this.baseStyle);
this.baseStyle = baseStyle;
this.imageStyle = imageStyle;
this.imagePromise = imagePromise;
this.stylePromise = Promise.all([
rootPromise,
basePromise,
imagePromise,
]) as unknown as Promise<void>;
}
connectedCallback(): void {

View file

@ -39,12 +39,7 @@ export class EditingArea extends HTMLDivElement {
is: "anki-editable-container",
}) as EditableContainer;
const imageStyle = document.createElement("style");
imageStyle.setAttribute("rel", "stylesheet");
imageStyle.id = "imageHandleStyle";
this.editable = document.createElement("anki-editable") as Editable;
this.editableContainer.shadowRoot!.appendChild(imageStyle);
this.editableContainer.shadowRoot!.appendChild(this.editable);
this.appendChild(this.editableContainer);
@ -55,18 +50,18 @@ export class EditingArea extends HTMLDivElement {
);
let imageHandleResolve: (value: ImageHandle) => void;
this.imageHandle = new Promise<ImageHandle>((resolve) => {
imageHandleResolve = resolve;
});
this.imageHandle = new Promise<ImageHandle>(
(resolve) => (imageHandleResolve = resolve)
);
imageStyle.addEventListener("load", () =>
this.editableContainer.imagePromise.then(() =>
imageHandleResolve(
new ImageHandle({
target: this,
anchor: this.editableContainer,
props: {
container: this.editable,
sheet: imageStyle.sheet,
sheet: this.editableContainer.imageStyle.sheet,
},
context,
} as any)
@ -105,6 +100,7 @@ export class EditingArea extends HTMLDivElement {
set fieldHTML(content: string) {
this.imageHandle.then(() => {
let result = content;
for (const component of decoratedComponents) {
result = component.toUndecorated(result);
}
@ -149,8 +145,10 @@ export class EditingArea extends HTMLDivElement {
}
initialize(color: string, content: string): void {
this.editableContainer.stylePromise.then(() => {
this.setBaseColor(color);
this.fieldHTML = content;
});
}
setBaseColor(color: string): void {