@mindful-web/marko-web-digital-edition 1.95.0

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.
Files changed (41) hide show
  1. package/.eslintignore +1 -0
  2. package/LICENSE +21 -0
  3. package/README.md +121 -0
  4. package/components/ad.marko +81 -0
  5. package/components/ad.marko.js +102 -0
  6. package/components/article-body.marko +134 -0
  7. package/components/article-body.marko.js +186 -0
  8. package/components/author.marko +30 -0
  9. package/components/author.marko.js +59 -0
  10. package/components/gate.marko +158 -0
  11. package/components/gate.marko.js +147 -0
  12. package/components/ld-json.marko +5 -0
  13. package/components/ld-json.marko.js +29 -0
  14. package/components/marko.json +78 -0
  15. package/components/reflow.marko +67 -0
  16. package/components/reflow.marko.js +106 -0
  17. package/components/replica.marko +86 -0
  18. package/components/replica.marko.js +128 -0
  19. package/components/scroll.marko +134 -0
  20. package/components/scroll.marko.js +23 -0
  21. package/components/theme.marko +73 -0
  22. package/components/theme.marko.js +30 -0
  23. package/components/toc.marko +28 -0
  24. package/components/toc.marko.js +53 -0
  25. package/components/toolbar.marko +47 -0
  26. package/components/toolbar.marko.js +54 -0
  27. package/components/tracking.marko +211 -0
  28. package/components/tracking.marko.js +60 -0
  29. package/lib/authors.js +125 -0
  30. package/lib/entities.js +97 -0
  31. package/lib/index.js +453 -0
  32. package/marko.json +6 -0
  33. package/package.json +33 -0
  34. package/routes/index.js +129 -0
  35. package/scss/index.scss +679 -0
  36. package/templates/article.marko +108 -0
  37. package/templates/article.marko.js +238 -0
  38. package/templates/hub.marko +94 -0
  39. package/templates/hub.marko.js +219 -0
  40. package/templates/partial.marko +17 -0
  41. package/templates/partial.marko.js +44 -0
@@ -0,0 +1,59 @@
1
+ // Compiled using marko@4.20.2 - DO NOT EDIT
2
+ "use strict";
3
+
4
+ var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
+ marko_componentType = "/@mindful-web/marko-web-digital-edition$1.95.0/components/author.marko",
6
+ marko_renderer = require("marko/dist/runtime/components/renderer"),
7
+ marko_dynamicTag = require("marko/dist/runtime/helpers/dynamic-tag"),
8
+ helpers_escape_xml = require("marko/dist/runtime/html/helpers/escape-xml"),
9
+ marko_escapeXml = helpers_escape_xml.x,
10
+ marko_attr = require("marko/dist/runtime/html/helpers/attr");
11
+
12
+ function render(input, out, __component, component, state) {
13
+ var data = input;
14
+
15
+ const { author } = input;
16
+
17
+ const { authorNode } = (out.global.digitalEdition || {});
18
+
19
+ const path = author && author.siteContext && author.siteContext.path;
20
+
21
+ if (author) {
22
+ if (authorNode) {
23
+ marko_dynamicTag(out, authorNode, function() {
24
+ return {
25
+ author: author
26
+ };
27
+ }, null, null, null, __component, "0");
28
+ } else {
29
+ out.w("<p class=\"edition-article__byline\">By ");
30
+
31
+ if (path) {
32
+ out.w("<a" +
33
+ marko_attr("href", path) +
34
+ ">" +
35
+ marko_escapeXml(author.name) +
36
+ "</a>");
37
+ } else {
38
+ out.w(marko_escapeXml(author.name));
39
+ }
40
+
41
+ if (author.title) {
42
+ out.w("<span class=\"edition-article__byline-title\">, " +
43
+ marko_escapeXml(author.title) +
44
+ "</span>");
45
+ }
46
+
47
+ out.w("</p>");
48
+ }
49
+ }
50
+ }
51
+
52
+ marko_template._ = marko_renderer(render, {
53
+ d_: true,
54
+ e_: marko_componentType
55
+ });
56
+
57
+ marko_template.meta = {
58
+ id: "/@mindful-web/marko-web-digital-edition$1.95.0/components/author.marko"
59
+ };
@@ -0,0 +1,158 @@
1
+ import defaultValue from "@mindful-web/marko-core/utils/default-value";
2
+
3
+ $ const { req, site, config, i18n } = out.global;
4
+ $ const siteName = (config && typeof config.siteName === "function" && config.siteName()) || (config && typeof config.website === "function" && config.website("name")) || "";
5
+ $ const { manifest, item } = input;
6
+ $ const context = input.context || {};
7
+ $ const variant = input.variant === "bar" ? "bar" : "inline";
8
+ $ const {
9
+ canAccess, isLoggedIn, hasRequiredAccessLevel, requiresAccessLevel, requiresUserInput,
10
+ } = context;
11
+ $ const t = typeof i18n === "function" ? i18n : (v) => v;
12
+ $ const redirect = input.redirect || (req && req.originalUrl);
13
+ $ const source = "digitalEdition";
14
+
15
+ $ // Everything the IdentityX events carry for this gate, so the new source can be
16
+ $ // reported alongside the content meter and article gates.
17
+ $ const additionalEventData = {
18
+ contentGateType: source,
19
+ issueId: manifest.issueId,
20
+ publication: manifest.publication,
21
+ issueName: manifest.name,
22
+ ...(item && { articleSlug: item.slug, printPage: item.printPage }),
23
+ ...defaultValue(input.additionalEventData, {}),
24
+ };
25
+
26
+ $ const title = defaultValue(input.title, variant === "bar"
27
+ ? t("Read the full issue")
28
+ : t("Log in to read the full article"));
29
+ $ const callToAction = defaultValue(input.callToAction,
30
+ `${t("Create a free")} <span class="edition-gate__site-name">${siteName}</span> ${t("account to keep reading")} ${variant === "bar" ? t("this issue") : t("this article")}.`);
31
+ $ const userInputTitle = defaultValue(input.userInputTitle, t("Complete your profile to keep reading"));
32
+ $ const buttonLabels = defaultValue(input.buttonLabels, {
33
+ continue: t("Continue"),
34
+ profile: t("Modify Profile"),
35
+ logout: t("Logout"),
36
+ });
37
+ $ const lang = defaultValue(site.config && site.config.lang, "en");
38
+
39
+ <!--
40
+ The reader's gate: the same IdentityX flow as the content meter bar and the
41
+ hard-gated article gate (email first; a new user is then asked for the site's
42
+ required create fields; an existing user gets a login link), with the source
43
+ `digitalEdition` so the conversion is attributable.
44
+
45
+ variant="bar" fixed bottom bar for the hub / continuous reader, collapsible
46
+ variant="inline" in the flow of a single gated article page
47
+ -->
48
+ <if(!canAccess)>
49
+ <div id="edition-gate" class=`edition-gate edition-gate--${variant} edition-gate--open` role="region" aria-label=t("Digital edition sign in") data-edition-issue-id=String(manifest.issueId)>
50
+ <div class="edition-gate__panel">
51
+ <if(variant === "bar")>
52
+ <button
53
+ type="button"
54
+ class="edition-gate__toggle"
55
+ aria-expanded="true"
56
+ data-edition-gate-toggle
57
+ >
58
+ <span class="edition-gate__title edition-gate__title--expanded">${title}</span>
59
+ <span class="edition-gate__title edition-gate__title--collapsed">${t("Create a free account")}</span>
60
+ <span class="edition-gate__chevron" aria-hidden="true"></span>
61
+ </button>
62
+ </if>
63
+ <else>
64
+ <h2 class="edition-gate__title">
65
+ <if(isLoggedIn && requiresUserInput)>${userInputTitle}</if>
66
+ <else>${title}</else>
67
+ </h2>
68
+ </else>
69
+
70
+ <if(isLoggedIn && requiresUserInput)>
71
+ <div class="edition-gate__body">
72
+ <div class="edition-gate__form">
73
+ <marko-web-identity-x-form-profile
74
+ call-to-action=t("A few details are needed before you can keep reading.")
75
+ reload-page-on-submit=true
76
+ additional-event-data=additionalEventData
77
+ login-source=source
78
+ lang=lang
79
+ />
80
+ </div>
81
+ </div>
82
+ </if>
83
+ <else-if(isLoggedIn && requiresAccessLevel && !hasRequiredAccessLevel)>
84
+ <p class="edition-gate__call-to-action">
85
+ ${t("Your account does not include access to this issue.")}
86
+ </p>
87
+ </else-if>
88
+ <else>
89
+ <p class="edition-gate__call-to-action">$!{callToAction}</p>
90
+ <div class="edition-gate__body">
91
+ <div class="edition-gate__form">
92
+ <marko-web-identity-x-form-login
93
+ source=source
94
+ login-email-placeholder="your@email.com"
95
+ additional-event-data=additionalEventData
96
+ button-labels=buttonLabels
97
+ redirect=redirect
98
+ lang=lang
99
+ />
100
+ </div>
101
+ </div>
102
+ </else>
103
+ </div>
104
+
105
+ <!--
106
+ 1. Collapse/expand of the bar, without a theme dependency.
107
+ 2. "Continue reading": one delegated listener on the document, because the
108
+ scroll reader appends later stories as fragments after this runs. A click on
109
+ a teaser band or its link opens the bar if collapsed, focuses the email field
110
+ (which scrolls it into view) and records the intent.
111
+ -->
112
+ <script>
113
+ (function () {
114
+ var gate = document.currentScript && document.currentScript.parentNode;
115
+ if (!gate) return;
116
+ var btn = gate.querySelector('[data-edition-gate-toggle]');
117
+ function setOpen(open) {
118
+ gate.classList.toggle('edition-gate--open', open);
119
+ if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false');
120
+ }
121
+ if (btn) {
122
+ btn.addEventListener('click', function () {
123
+ setOpen(!gate.classList.contains('edition-gate--open'));
124
+ });
125
+ }
126
+ if (window.__editionContinueBound) return;
127
+ window.__editionContinueBound = true;
128
+ document.addEventListener('click', function (e) {
129
+ var target = e.target && e.target.closest && e.target.closest('[data-edition-continue]');
130
+ if (!target) return;
131
+ e.preventDefault();
132
+ setOpen(true);
133
+ var field = gate.querySelector('input[type="email"]') || gate.querySelector('input');
134
+ if (field) {
135
+ field.focus({ preventScroll: true });
136
+ field.scrollIntoView({ block: 'center', behavior: 'smooth' });
137
+ } else {
138
+ gate.scrollIntoView({ block: 'center', behavior: 'smooth' });
139
+ }
140
+ if (window.p1events) {
141
+ // Attribute the intent to the story it was clicked on (entity stamped on
142
+ // the enclosing article by article-body.marko).
143
+ var art = target.closest('[data-edition-entity]');
144
+ var entity = null;
145
+ try { entity = art && JSON.parse(art.getAttribute('data-edition-entity')); } catch (err) { entity = null; }
146
+ p1events('track', {
147
+ action: 'Continue Reading',
148
+ category: 'Digital Edition Article',
149
+ label: target.getAttribute('data-edition-slug') || '',
150
+ entity: entity || undefined,
151
+ props: { issueId: gate.getAttribute('data-edition-issue-id'), slug: target.getAttribute('data-edition-slug') || null, gate: gate.classList.contains('edition-gate--bar') ? 'bar' : 'inline' }
152
+ });
153
+ }
154
+ });
155
+ })();
156
+ </script>
157
+ </div>
158
+ </if>
@@ -0,0 +1,147 @@
1
+ // Compiled using marko@4.20.2 - DO NOT EDIT
2
+ "use strict";
3
+
4
+ var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
+ marko_componentType = "/@mindful-web/marko-web-digital-edition$1.95.0/components/gate.marko",
6
+ marko_renderer = require("marko/dist/runtime/components/renderer"),
7
+ module_defaultValue = require("@mindful-web/marko-core/utils/default-value"),
8
+ defaultValue = module_defaultValue.default || module_defaultValue,
9
+ helpers_escape_xml = require("marko/dist/runtime/html/helpers/escape-xml"),
10
+ marko_escapeXml = helpers_escape_xml.x,
11
+ marko_web_identity_x_form_profile_template = require("@mindful-web/marko-web-identity-x/components/form-profile.marko"),
12
+ marko_loadTag = require("marko/dist/runtime/helpers/load-tag"),
13
+ marko_web_identity_x_form_profile_tag = marko_loadTag(marko_web_identity_x_form_profile_template),
14
+ marko_str = require("marko/dist/runtime/helpers/to-string"),
15
+ marko_web_identity_x_form_login_template = require("@mindful-web/marko-web-identity-x/components/form-login.marko"),
16
+ marko_web_identity_x_form_login_tag = marko_loadTag(marko_web_identity_x_form_login_template),
17
+ marko_classAttr = require("marko/dist/runtime/html/helpers/class-attr"),
18
+ marko_attr = require("marko/dist/runtime/html/helpers/attr");
19
+
20
+ function render(input, out, __component, component, state) {
21
+ var data = input;
22
+
23
+ const { req, site, config, i18n } = out.global;
24
+
25
+ const siteName = (config && typeof config.siteName === "function" && config.siteName()) || (config && typeof config.website === "function" && config.website("name")) || "";
26
+
27
+ const { manifest, item } = input;
28
+
29
+ const context = input.context || {};
30
+
31
+ const variant = input.variant === "bar" ? "bar" : "inline";
32
+
33
+ const {
34
+ canAccess, isLoggedIn, hasRequiredAccessLevel, requiresAccessLevel, requiresUserInput,
35
+ } = context;
36
+
37
+ const t = typeof i18n === "function" ? i18n : (v) => v;
38
+
39
+ const redirect = input.redirect || (req && req.originalUrl);
40
+
41
+ const source = "digitalEdition";
42
+
43
+ // Everything the IdentityX events carry for this gate, so the new source can be
44
+
45
+ // reported alongside the content meter and article gates.
46
+
47
+ const additionalEventData = {
48
+ contentGateType: source,
49
+ issueId: manifest.issueId,
50
+ publication: manifest.publication,
51
+ issueName: manifest.name,
52
+ ...(item && { articleSlug: item.slug, printPage: item.printPage }),
53
+ ...defaultValue(input.additionalEventData, {}),
54
+ };
55
+
56
+ const title = defaultValue(input.title, variant === "bar"
57
+ ? t("Read the full issue")
58
+ : t("Log in to read the full article"));
59
+
60
+ const callToAction = defaultValue(input.callToAction,
61
+ `${t("Create a free")} <span class="edition-gate__site-name">${siteName}</span> ${t("account to keep reading")} ${variant === "bar" ? t("this issue") : t("this article")}.`);
62
+
63
+ const userInputTitle = defaultValue(input.userInputTitle, t("Complete your profile to keep reading"));
64
+
65
+ const buttonLabels = defaultValue(input.buttonLabels, {
66
+ continue: t("Continue"),
67
+ profile: t("Modify Profile"),
68
+ logout: t("Logout"),
69
+ });
70
+
71
+ const lang = defaultValue(site.config && site.config.lang, "en");
72
+
73
+ if (!canAccess) {
74
+ out.w("<div id=\"edition-gate\"" +
75
+ marko_classAttr(("edition-gate edition-gate--" + variant) + " edition-gate--open") +
76
+ " role=\"region\"" +
77
+ marko_attr("aria-label", t("Digital edition sign in")) +
78
+ marko_attr("data-edition-issue-id", String(manifest.issueId)) +
79
+ "><div class=\"edition-gate__panel\">");
80
+
81
+ if (variant === "bar") {
82
+ out.w("<button type=\"button\" class=\"edition-gate__toggle\" aria-expanded=\"true\" data-edition-gate-toggle><span class=\"edition-gate__title edition-gate__title--expanded\">" +
83
+ marko_escapeXml(title) +
84
+ "</span><span class=\"edition-gate__title edition-gate__title--collapsed\">" +
85
+ marko_escapeXml(t("Create a free account")) +
86
+ "</span><span class=\"edition-gate__chevron\" aria-hidden=\"true\"></span></button>");
87
+ } else {
88
+ out.w("<h2 class=\"edition-gate__title\">");
89
+
90
+ if (isLoggedIn && requiresUserInput) {
91
+ out.w(marko_escapeXml(userInputTitle));
92
+ } else {
93
+ out.w(marko_escapeXml(title));
94
+ }
95
+
96
+ out.w("</h2>");
97
+ }
98
+
99
+ if (isLoggedIn && requiresUserInput) {
100
+ out.w("<div class=\"edition-gate__body\"><div class=\"edition-gate__form\">");
101
+
102
+ marko_web_identity_x_form_profile_tag({
103
+ loginSource: source,
104
+ callToAction: t("A few details are needed before you can keep reading."),
105
+ reloadPageOnSubmit: true,
106
+ additionalEventData: additionalEventData,
107
+ lang: lang
108
+ }, out, __component, "9");
109
+
110
+ out.w("</div></div>");
111
+ } else if ((isLoggedIn && requiresAccessLevel) && (!hasRequiredAccessLevel)) {
112
+ out.w("<p class=\"edition-gate__call-to-action\">" +
113
+ marko_escapeXml(t("Your account does not include access to this issue.")) +
114
+ "</p>");
115
+ } else {
116
+ out.w("<p class=\"edition-gate__call-to-action\">" +
117
+ marko_str(callToAction) +
118
+ "</p><div class=\"edition-gate__body\"><div class=\"edition-gate__form\">");
119
+
120
+ marko_web_identity_x_form_login_tag({
121
+ source: source,
122
+ loginEmailPlaceholder: "your@email.com",
123
+ additionalEventData: additionalEventData,
124
+ buttonLabels: buttonLabels,
125
+ redirect: redirect,
126
+ lang: lang
127
+ }, out, __component, "14");
128
+
129
+ out.w("</div></div>");
130
+ }
131
+
132
+ out.w("</div><script>\n (function () {\n var gate = document.currentScript && document.currentScript.parentNode;\n if (!gate) return;\n var btn = gate.querySelector('[data-edition-gate-toggle]');\n function setOpen(open) {\n gate.classList.toggle('edition-gate--open', open);\n if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false');\n }\n if (btn) {\n btn.addEventListener('click', function () {\n setOpen(!gate.classList.contains('edition-gate--open'));\n });\n }\n if (window.__editionContinueBound) return;\n window.__editionContinueBound = true;\n document.addEventListener('click', function (e) {\n var target = e.target && e.target.closest && e.target.closest('[data-edition-continue]');\n if (!target) return;\n e.preventDefault();\n setOpen(true);\n var field = gate.querySelector('input[type=\"email\"]') || gate.querySelector('input');\n if (field) {\n field.focus({ preventScroll: true });\n field.scrollIntoView({ block: 'center', behavior: 'smooth' });\n } else {\n gate.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n if (window.p1events) {\n // Attribute the intent to the story it was clicked on (entity stamped on\n // the enclosing article by article-body.marko).\n var art = target.closest('[data-edition-entity]');\n var entity = null;\n try { entity = art && JSON.parse(art.getAttribute('data-edition-entity')); } catch (err) { entity = null; }\n p1events('track', {\n action: 'Continue Reading',\n category: 'Digital Edition Article',\n label: target.getAttribute('data-edition-slug') || '',\n entity: entity || undefined,\n props: { issueId: gate.getAttribute('data-edition-issue-id'), slug: target.getAttribute('data-edition-slug') || null, gate: gate.classList.contains('edition-gate--bar') ? 'bar' : 'inline' }\n });\n }\n });\n })();\n </script></div>");
133
+ }
134
+ }
135
+
136
+ marko_template._ = marko_renderer(render, {
137
+ d_: true,
138
+ e_: marko_componentType
139
+ });
140
+
141
+ marko_template.meta = {
142
+ id: "/@mindful-web/marko-web-digital-edition$1.95.0/components/gate.marko",
143
+ tags: [
144
+ "@mindful-web/marko-web-identity-x/components/form-profile.marko",
145
+ "@mindful-web/marko-web-identity-x/components/form-login.marko"
146
+ ]
147
+ };
@@ -0,0 +1,5 @@
1
+ import { buildLdJson } from "../lib";
2
+
3
+ $ const ld = buildLdJson(input);
4
+
5
+ <script type="application/ld+json">$!{JSON.stringify(ld)}</script>
@@ -0,0 +1,29 @@
1
+ // Compiled using marko@4.20.2 - DO NOT EDIT
2
+ "use strict";
3
+
4
+ var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
+ marko_componentType = "/@mindful-web/marko-web-digital-edition$1.95.0/components/ld-json.marko",
6
+ marko_renderer = require("marko/dist/runtime/components/renderer"),
7
+ module_lib_module = require("../lib"),
8
+ lib_module = module_lib_module.default || module_lib_module,
9
+ buildLdJson = module_lib_module.buildLdJson,
10
+ marko_str = require("marko/dist/runtime/helpers/to-string");
11
+
12
+ function render(input, out, __component, component, state) {
13
+ var data = input;
14
+
15
+ const ld = buildLdJson(input);
16
+
17
+ out.w("<script type=\"application/ld+json\">" +
18
+ marko_str(JSON.stringify(ld)) +
19
+ "</script>");
20
+ }
21
+
22
+ marko_template._ = marko_renderer(render, {
23
+ d_: true,
24
+ e_: marko_componentType
25
+ });
26
+
27
+ marko_template.meta = {
28
+ id: "/@mindful-web/marko-web-digital-edition$1.95.0/components/ld-json.marko"
29
+ };
@@ -0,0 +1,78 @@
1
+ {
2
+ "<marko-web-digital-edition-ad>": {
3
+ "template": "./ad.marko",
4
+ "@manifest": "object",
5
+ "@item": "object",
6
+ "@eager": "boolean",
7
+ "@inline": "boolean"
8
+ },
9
+ "<marko-web-digital-edition-reflow>": {
10
+ "template": "./reflow.marko",
11
+ "@manifest": "object",
12
+ "@can-access": "boolean"
13
+ },
14
+ "<marko-web-digital-edition-replica>": {
15
+ "template": "./replica.marko",
16
+ "@manifest": "object",
17
+ "@page": "number",
18
+ "@can-access": "boolean",
19
+ "@preview-pages": "number"
20
+ },
21
+ "<marko-web-digital-edition-tracking>": {
22
+ "template": "./tracking.marko",
23
+ "@manifest": "object",
24
+ "@view": "string",
25
+ "@item": "object"
26
+ },
27
+ "<marko-web-digital-edition-ld-json>": {
28
+ "template": "./ld-json.marko",
29
+ "@manifest": "object",
30
+ "@gated": "boolean",
31
+ "@canonical-url": "string"
32
+ },
33
+ "<marko-web-digital-edition-toolbar>": {
34
+ "template": "./toolbar.marko",
35
+ "@manifest": "object",
36
+ "@view": "string",
37
+ "@show-theme-toggle": "boolean"
38
+ },
39
+ "<marko-web-digital-edition-article>": {
40
+ "template": "./article-body.marko",
41
+ "@manifest": "object",
42
+ "@item": "object",
43
+ "@can-access": "boolean",
44
+ "@heading-level": "number"
45
+ },
46
+ "<marko-web-digital-edition-toc>": {
47
+ "template": "./toc.marko",
48
+ "@manifest": "object",
49
+ "@items": "array",
50
+ "@current-slug": "string"
51
+ },
52
+ "<marko-web-digital-edition-scroll>": {
53
+ "template": "./scroll.marko",
54
+ "@manifest": "object"
55
+ },
56
+ "<marko-web-digital-edition-theme>": {
57
+ "template": "./theme.marko",
58
+ "@view": "string",
59
+ "@default-theme": "string"
60
+ },
61
+ "<marko-web-digital-edition-author>": {
62
+ "template": "./author.marko",
63
+ "@author": "object"
64
+ },
65
+ "<marko-web-digital-edition-gate>": {
66
+ "template": "./gate.marko",
67
+ "@manifest": "object",
68
+ "@context": "object",
69
+ "@item": "object",
70
+ "@variant": "string",
71
+ "@redirect": "string",
72
+ "@title": "string",
73
+ "@call-to-action": "string",
74
+ "@user-input-title": "string",
75
+ "@button-labels": "object",
76
+ "@additional-event-data": "object"
77
+ }
78
+ }
@@ -0,0 +1,67 @@
1
+ import { articles, editionPath } from "../lib";
2
+
3
+ $ const { manifest, canAccess } = input;
4
+ $ const list = articles(manifest);
5
+ $ const first = list[0] || null;
6
+ $ const rest = list.slice(1);
7
+
8
+ <!--
9
+ The hub.
10
+
11
+ Its initial HTML deliberately contains only the FIRST article body. Each article
12
+ also lives at its own URL, so rendering all 17 here would make the hub compete with
13
+ every article page for the same text. Instead the hub is a cover + contents + the
14
+ opening story, and the scroll reader fetches the rest as `?partial=1` fragments
15
+ while pushState-ing to each article's real URL.
16
+ -->
17
+ <div
18
+ class="edition-reflow"
19
+ data-edition-issue-id=manifest.issueId
20
+ data-edition-hub-path=editionPath(manifest.issueId)
21
+ >
22
+ <header class="edition-reflow__masthead">
23
+ <if(manifest.coverImage)>
24
+ <img
25
+ class="edition-reflow__cover"
26
+ src=manifest.coverImage
27
+ alt=`${manifest.publication} — ${manifest.name} cover`
28
+ />
29
+ </if>
30
+ <div class="edition-reflow__meta">
31
+ <p class="edition-reflow__pub">${manifest.publication}</p>
32
+ <h1 class="edition-reflow__issue">${manifest.name}</h1>
33
+ <p class="edition-reflow__count">
34
+ ${list.length} articles · ${manifest.pdf.pageCount} pages
35
+ </p>
36
+ </div>
37
+ </header>
38
+
39
+ <marko-web-digital-edition-toc manifest=manifest items=list />
40
+
41
+ <div class="edition-reflow__flow" data-edition-flow>
42
+ <if(first)>
43
+ <marko-web-digital-edition-article manifest=manifest item=first can-access=canAccess />
44
+ </if>
45
+ </div>
46
+
47
+ <!--
48
+ The remaining articles as plain links. The scroll reader consumes this list and
49
+ replaces it; without JS it stays visible and every story is still reachable.
50
+ -->
51
+ <if(rest.length)>
52
+ <nav class="edition-reflow__more" data-edition-queue aria-label="More from this issue">
53
+ <h2 class="edition-reflow__more-title">Continue reading</h2>
54
+ <ul class="edition-reflow__more-list">
55
+ <for|item| of=rest>
56
+ <li>
57
+ <a
58
+ class="edition-reflow__more-link"
59
+ href=editionPath(manifest.issueId, { slug: item.slug })
60
+ data-edition-queue-slug=item.slug
61
+ >${item.headline || "Untitled"}</a>
62
+ </li>
63
+ </for>
64
+ </ul>
65
+ </nav>
66
+ </if>
67
+ </div>
@@ -0,0 +1,106 @@
1
+ // Compiled using marko@4.20.2 - DO NOT EDIT
2
+ "use strict";
3
+
4
+ var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
+ marko_componentType = "/@mindful-web/marko-web-digital-edition$1.95.0/components/reflow.marko",
6
+ marko_renderer = require("marko/dist/runtime/components/renderer"),
7
+ module_lib_module = require("../lib"),
8
+ lib_module = module_lib_module.default || module_lib_module,
9
+ articles = module_lib_module.articles,
10
+ editionPath = module_lib_module.editionPath,
11
+ marko_attr = require("marko/dist/runtime/html/helpers/attr"),
12
+ helpers_escape_xml = require("marko/dist/runtime/html/helpers/escape-xml"),
13
+ marko_escapeXml = helpers_escape_xml.x,
14
+ marko_web_digital_edition_toc_template = require("./toc.marko"),
15
+ marko_loadTag = require("marko/dist/runtime/helpers/load-tag"),
16
+ marko_web_digital_edition_toc_tag = marko_loadTag(marko_web_digital_edition_toc_template),
17
+ marko_web_digital_edition_article_template = require("./article-body.marko"),
18
+ marko_web_digital_edition_article_tag = marko_loadTag(marko_web_digital_edition_article_template),
19
+ marko_forOf = require("marko/dist/runtime/helpers/for-of");
20
+
21
+ function render(input, out, __component, component, state) {
22
+ var data = input;
23
+
24
+ const { manifest, canAccess } = input;
25
+
26
+ const list = articles(manifest);
27
+
28
+ const first = list[0] || null;
29
+
30
+ const rest = list.slice(1);
31
+
32
+ out.w("<div class=\"edition-reflow\"" +
33
+ marko_attr("data-edition-issue-id", manifest.issueId) +
34
+ marko_attr("data-edition-hub-path", editionPath(manifest.issueId)) +
35
+ "><header class=\"edition-reflow__masthead\">");
36
+
37
+ if (manifest.coverImage) {
38
+ out.w("<img class=\"edition-reflow__cover\"" +
39
+ marko_attr("src", manifest.coverImage) +
40
+ marko_attr("alt", ((manifest.publication + " — ") + manifest.name) + " cover") +
41
+ ">");
42
+ }
43
+
44
+ out.w("<div class=\"edition-reflow__meta\"><p class=\"edition-reflow__pub\">" +
45
+ marko_escapeXml(manifest.publication) +
46
+ "</p><h1 class=\"edition-reflow__issue\">" +
47
+ marko_escapeXml(manifest.name) +
48
+ "</h1><p class=\"edition-reflow__count\">" +
49
+ marko_escapeXml(list.length) +
50
+ " articles · " +
51
+ marko_escapeXml(manifest.pdf.pageCount) +
52
+ " pages</p></div></header>");
53
+
54
+ marko_web_digital_edition_toc_tag({
55
+ manifest: manifest,
56
+ items: list
57
+ }, out, __component, "7");
58
+
59
+ out.w("<div class=\"edition-reflow__flow\" data-edition-flow>");
60
+
61
+ if (first) {
62
+ marko_web_digital_edition_article_tag({
63
+ manifest: manifest,
64
+ item: first,
65
+ canAccess: canAccess
66
+ }, out, __component, "9");
67
+ }
68
+
69
+ out.w("</div>");
70
+
71
+ if (rest.length) {
72
+ out.w("<nav class=\"edition-reflow__more\" data-edition-queue aria-label=\"More from this issue\"><h2 class=\"edition-reflow__more-title\">Continue reading</h2><ul class=\"edition-reflow__more-list\">");
73
+
74
+ var $for$0 = 0;
75
+
76
+ marko_forOf(rest, function(item) {
77
+ var $keyScope$0 = "[" + (($for$0++) + "]");
78
+
79
+ out.w("<li><a class=\"edition-reflow__more-link\"" +
80
+ marko_attr("href", editionPath(manifest.issueId, {
81
+ slug: item.slug
82
+ })) +
83
+ marko_attr("data-edition-queue-slug", item.slug) +
84
+ ">" +
85
+ marko_escapeXml(item.headline || "Untitled") +
86
+ "</a></li>");
87
+ });
88
+
89
+ out.w("</ul></nav>");
90
+ }
91
+
92
+ out.w("</div>");
93
+ }
94
+
95
+ marko_template._ = marko_renderer(render, {
96
+ d_: true,
97
+ e_: marko_componentType
98
+ });
99
+
100
+ marko_template.meta = {
101
+ id: "/@mindful-web/marko-web-digital-edition$1.95.0/components/reflow.marko",
102
+ tags: [
103
+ "./toc.marko",
104
+ "./article-body.marko"
105
+ ]
106
+ };