Skip to content

Commit 200df2e

Browse files
committed
fix cross browser open a popup strangeness Issue #56
1 parent 07c8154 commit 200df2e

File tree

1 file changed

+60
-35
lines changed

1 file changed

+60
-35
lines changed

html/classhelper.js

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ class ClassHelper extends HTMLElement {
178178
});
179179
};
180180

181+
const handlePopupReadyEvent = (event) => {
182+
// we get a document Fragment in event.detail we replace it with the root
183+
// Assuming that browser implementors are smart enough to not replace the same document
184+
this.popupRef.document.replaceChild(event.detail, this.popupRef.document.documentElement);
185+
}
186+
181187
const handleNextPageEvent = (event) => {
182188
this.pageChange(event.detail.value, this.helpurlProps)
183189
.catch(error => {
@@ -233,6 +239,7 @@ class ClassHelper extends HTMLElement {
233239
}
234240

235241
this.addEventListener("click", handleClickEvent);
242+
this.addEventListener("popupReady", handlePopupReadyEvent);
236243
this.addEventListener("prevPage", handlePrevPageEvent);
237244
this.addEventListener("nextPage", handleNextPageEvent);
238245
this.addEventListener("valueSelected", handleValueSelectedEvent);
@@ -889,65 +896,83 @@ class ClassHelper extends HTMLElement {
889896
nextPageURL = links.next[0].uri;
890897
}
891898

899+
const itemDesignator = window.location.pathname.split("/").at(-1);
900+
let title = `${itemDesignator} - Classhelper`;
901+
892902
if (props.formProperty) {
893903
// Find preselected values
894904
const input = document.getElementsByName(props.formProperty).item(0);
895905
if (input?.value) {
896906
preSelectedValues = input.value.split(',');
897907
}
908+
const label = document.getElementsByName(props.formProperty).item(0).parentElement.previousElementSibling;
909+
title = label.textContent + " - " + title;
898910
}
899911

900912
const popupFeatures = CLASSHELPER_POPUP_FEATURES(props.width, props.height);
901913
this.popupRef = window.open(CLASSHELPER_POPUP_URL, CLASSHELPER_POPUP_TARGET, popupFeatures);
902914

903-
if (this.popupRef == null) {
904-
throw new Error("Browser Failed to open Popup Window");
905-
}
915+
// Create the popup root level page
916+
const page = document.createDocumentFragment();
917+
const html = document.createElement("html");
918+
const head = document.createElement("head");
919+
const body = document.createElement("body");
906920

907-
this.popupRef.addEventListener("load", (event) => {
908-
const doc = event.target;
909-
const body = doc.body;
921+
body.classList.add("flex-container");
910922

911-
const itemDesignator = window.location.pathname.split("/").at(-1);
912-
let title = `${itemDesignator} - Classhelper`;
923+
const titleTag = document.createElement("title");
924+
titleTag.textContent = title;
913925

914-
if (props.formProperty) {
915-
const label = document.getElementsByName(props.formProperty).item(0).parentElement.previousElementSibling;
916-
title = label.textContent + " - " + title;
917-
}
926+
const styleSheet = document.createElement("link");
927+
styleSheet.rel = "stylesheet";
928+
styleSheet.type = "text/css";
929+
styleSheet.href = this.trackerBaseURL + '/' + CSS_STYLESHEET_FILE_NAME;
930+
931+
head.appendChild(titleTag);
932+
head.appendChild(styleSheet);
918933

919-
doc.title = title;
934+
if (this.dataset.searchWith) {
935+
const searchFrag = this.getSearchFragment();
936+
body.appendChild(searchFrag);
937+
}
920938

921-
// Add external classhelper stylesheet to head
922-
const styleSheet = doc.createElement("link");
923-
styleSheet.rel = "stylesheet";
924-
styleSheet.type = "text/css";
925-
styleSheet.href = this.trackerBaseURL + '/' + CSS_STYLESHEET_FILE_NAME;
926-
doc.head.appendChild(styleSheet);
939+
const paginationFrag = this.getPaginationFragment(prevPageURL, nextPageURL, props.pageIndex, props.pageSize, collection.length);
927940

928-
body.classList.add("flex-container");
941+
const separator = document.createElement("div");
942+
separator.classList.add("separator");
929943

930-
if (this.dataset.searchWith) {
931-
const searchFrag = this.getSearchFragment(null);
932-
body.appendChild(searchFrag);
933-
}
944+
const tableFrag = this.getTableFragment(props.fields, collection, preSelectedValues, !!props.formProperty);
934945

935-
const paginationFrag = this.getPaginationFragment(prevPageURL, nextPageURL, props.pageIndex, props.pageSize, collection.length);
936-
body.appendChild(paginationFrag);
946+
body.appendChild(paginationFrag);
947+
body.appendChild(tableFrag);
948+
body.appendChild(separator);
937949

938-
const tableFrag = this.getTableFragment(props.fields, collection, preSelectedValues, !!props.formProperty);
939-
body.appendChild(tableFrag);
950+
if (props.formProperty) {
951+
const accumulatorFrag = this.getAccumulatorFragment(preSelectedValues);
952+
body.appendChild(accumulatorFrag);
953+
}
940954

941-
const separator = doc.createElement("div");
942-
separator.classList.add("separator");
943-
body.appendChild(separator);
955+
html.appendChild(head);
956+
html.appendChild(body);
957+
page.appendChild(html);
944958

945-
if (props.formProperty) {
946-
const accumulatorFrag = this.getAccumulatorFragment(preSelectedValues);
947-
body.appendChild(accumulatorFrag);
948-
}
959+
const popupReadyEvent = new CustomEvent("popupReady", { detail: page });
960+
961+
if (this.popupRef == null) {
962+
throw new Error("Failed to open popup window");
963+
}
964+
965+
// Wait for the popup window to load, onload fire popupReady event on the classhelper
966+
this.popupRef.addEventListener("load", () => {
967+
this.dispatchEvent(popupReadyEvent);
949968
});
950969

970+
// If load event was already fired way before the event listener was attached
971+
// we need to trigger it manually if popupRef is readyState complete
972+
if (this.popupRef.document.readyState === "complete") {
973+
this.dispatchEvent(popupReadyEvent);
974+
}
975+
951976
this.popupRef.addEventListener("keydown", (e) => {
952977
if (e.key === "ArrowDown") {
953978
if (e.target.tagName === "TR") {

0 commit comments

Comments
 (0)