@teipublisher/pb-components 3.3.2 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/pb-view.js CHANGED
@@ -650,6 +650,18 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
650
650
  _doLoad(params) {
651
651
  this.emitTo('pb-start-update', params);
652
652
 
653
+ // On the first load, check whether the server already rendered this
654
+ // fragment into our light DOM. If so, request only
655
+ // the navigation metadata (content=none) and adopt the existing markup
656
+ // instead of rendering the same content a second time.
657
+ if (this._ssrContent === undefined) {
658
+ this._ssrContent = this.querySelector(':scope > [data-pb-ssr]') || null;
659
+ this._ssrFootnotes = this.querySelector(':scope > [data-pb-ssr-footnotes]') || null;
660
+ }
661
+ if (this._ssrContent) {
662
+ params.content = 'none';
663
+ }
664
+
653
665
  console.log('<pb-view> Loading view with params %o', params);
654
666
  if (!this.infiniteScroll) {
655
667
  this._clear();
@@ -709,9 +721,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
709
721
 
710
722
  const index = await fetch(`index.json`).then(response => response.json());
711
723
  const paramNames = ['odd', 'view', 'xpath', 'map'];
712
- this.querySelectorAll('pb-param').forEach(param =>
713
- paramNames.push(`user.${param.getAttribute('name')}`),
714
- );
724
+ this._params().forEach(param => paramNames.push(`user.${param.getAttribute('name')}`));
715
725
  let url = params.id ? createKey([...paramNames, 'id']) : createKey([...paramNames, 'root']);
716
726
  let file = index[url];
717
727
  if (!file) {
@@ -827,7 +837,17 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
827
837
  const elem = document.createElement('div');
828
838
  // elem.style.opacity = 0; //hide it - animation has to make sure to blend it in
829
839
  fragment.appendChild(elem);
830
- elem.innerHTML = resp.content;
840
+ if (this._ssrContent && (!resp.content || resp.content.length === 0)) {
841
+ // Adopt the server-rendered content from light DOM (SSR) rather than
842
+ // re-rendering it: move its children into the shadow content container.
843
+ while (this._ssrContent.firstChild) {
844
+ elem.appendChild(this._ssrContent.firstChild);
845
+ }
846
+ this._ssrContent.remove();
847
+ this._ssrContent = null;
848
+ } else {
849
+ elem.innerHTML = resp.content;
850
+ }
831
851
 
832
852
  // if before-update-event is set, we do not replace the content immediately,
833
853
  // but emit an event
@@ -889,11 +909,23 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
889
909
 
890
910
  if (this.appendFootnotes) {
891
911
  const footnotes = document.createElement('div');
892
- if (resp.footnotes) {
912
+ if (this._ssrFootnotes) {
913
+ // Adopt the server-rendered footnotes from light DOM (SSR).
914
+ while (this._ssrFootnotes.firstChild) {
915
+ footnotes.appendChild(this._ssrFootnotes.firstChild);
916
+ }
917
+ } else if (resp.footnotes) {
893
918
  footnotes.innerHTML = resp.footnotes;
894
919
  }
895
920
  this._footnotes = footnotes;
896
921
  }
922
+ // Drop the SSR footnotes marker even when not appending, so it does not
923
+ // linger in the light DOM (matches the dynamic path, which ignores
924
+ // footnotes unless append-footnotes is set).
925
+ if (this._ssrFootnotes) {
926
+ this._ssrFootnotes.remove();
927
+ this._ssrFootnotes = null;
928
+ }
897
929
 
898
930
  this._initFootnotes(this._footnotes);
899
931
 
@@ -1013,9 +1045,20 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1013
1045
  }
1014
1046
  }
1015
1047
 
1048
+ /**
1049
+ * Collect the configuration `pb-param` children of this view. Excludes any
1050
+ * `pb-param` that may occur inside server-rendered (SSR) content adopted into
1051
+ * the light DOM, so injected content can never be mistaken for a parameter.
1052
+ */
1053
+ _params() {
1054
+ return Array.from(this.querySelectorAll('pb-param')).filter(
1055
+ param => !param.closest('[data-pb-ssr], [data-pb-ssr-footnotes]'),
1056
+ );
1057
+ }
1058
+
1016
1059
  _getParameters() {
1017
1060
  const params = [];
1018
- this.querySelectorAll('pb-param').forEach(param => {
1061
+ this._params().forEach(param => {
1019
1062
  params[`user.${param.getAttribute('name')}`] = param.getAttribute('value');
1020
1063
  });
1021
1064
  // add parameters for features set with pb-toggle-feature