History

Sanity-check decaffeinate app.views.EntryPage

Simon Legner committed 2 years ago

Commit 7fa81661 parent 1995d8a1 file · +215 −234Browse files

Unified · Split

assets/javascripts/views/content/entry_page.js+215−234
@@ -1,266 +1,247 @@
1−// TODO: This file was created by bulk-decaffeinate.
2−// Sanity-check the conversion and remove this comment.
3−/*
4− * decaffeinate suggestions:
5− * DS101: Remove unnecessary use of Array.from
6− * DS102: Remove unnecessary code created because of implicit returns
7− * DS205: Consider reworking code to avoid use of IIFEs
8− * DS206: Consider reworking classes to avoid initClass
9− * DS207: Consider shorter variations of null checks
10− * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
11− */
12−(function () {
13− let LINKS = undefined;
14− app.views.EntryPage = class EntryPage extends app.View {
15− static initClass() {
16− this.className = "_page";
17− this.errorClass = "_page-error";
18−
19− this.events = { click: "onClick" };
20−
21− this.shortcuts = {
22− altC: "onAltC",
23− altO: "onAltO",
24− };
25−
26− this.routes = { before: "beforeRoute" };
27−
28− LINKS = {
29− home: "Homepage",
30− code: "Source code",
31− };
32− }
33−
34− init() {
35− this.cacheMap = {};
36− this.cacheStack = [];
37− }
38−
39− deactivate() {
40− if (super.deactivate(...arguments)) {
41− this.empty();
42− this.entry = null;
43− }
44− }
45−
46− loading() {
47− this.empty();
48− this.trigger("loading");
49− }
50−
51− render(content, fromCache) {
52− if (content == null) {
53− content = "";
54− }
55− if (fromCache == null) {
56− fromCache = false;
57− }
58− if (!this.activated) {
59− return;
60− }
61− this.empty();
62− this.subview = new (this.subViewClass())(this.el, this.entry);
1+app.views.EntryPage = class EntryPage extends app.View {
2+ static className = "_page";
3+ static errorClass = "_page-error";
634
64− $.batchUpdate(this.el, () => {
65− this.subview.render(content, fromCache);
66− if (!fromCache) {
67− this.addCopyButtons();
68− }
69− });
5+ static events = { click: "onClick" };
706
71− if (app.disabledDocs.findBy("slug", this.entry.doc.slug)) {
72− this.hiddenView = new app.views.HiddenPage(this.el, this.entry);
73− }
74−
75− setFaviconForDoc(this.entry.doc);
76− this.delay(this.polyfillMathML);
77− this.trigger("loaded");
78− }
7+ static shortcuts = {
8+ altC: "onAltC",
9+ altO: "onAltO",
10+ };
7911
80− addCopyButtons() {
81− if (!this.copyButton) {
82− this.copyButton = document.createElement("button");
83− this.copyButton.innerHTML = '<svg><use xlink:href="#icon-copy"/></svg>';
84− this.copyButton.type = "button";
85− this.copyButton.className = "_pre-clip";
86− this.copyButton.title = "Copy to clipboard";
87− this.copyButton.setAttribute("aria-label", "Copy to clipboard");
88− }
89− for (var el of Array.from(this.findAllByTag("pre"))) {
90− el.appendChild(this.copyButton.cloneNode(true));
91− }
92− }
12+ static routes = { before: "beforeRoute" };
9313
94− polyfillMathML() {
95− if (
96− window.supportsMathML !== false ||
97− !!this.polyfilledMathML ||
98− !this.findByTag("math")
99− ) {
100− return;
101− }
102− this.polyfilledMathML = true;
103− $.append(
104− document.head,
105− `<link rel="stylesheet" href="${app.config.mathml_stylesheet}">`,
106− );
107− }
14+ static LINKS = {
15+ home: "Homepage",
16+ code: "Source code",
17+ };
10818
109− prepareContent(content) {
110− if (!this.entry.isIndex() || !this.entry.doc.links) {
111− return content;
112− }
19+ init() {
20+ this.cacheMap = {};
21+ this.cacheStack = [];
22+ }
11323
114− const links = (() => {
115− const result = [];
116− for (var link in this.entry.doc.links) {
117− var url = this.entry.doc.links[link];
118− result.push(
119− `<a href="${url}" class="_links-link">${LINKS[link]}</a>`,
120− );
121− }
122− return result;
123− })();
124−
125− return `<p class="_links">${links.join("")}</p>${content}`;
24+ deactivate() {
25+ if (super.deactivate(...arguments)) {
26+ this.empty();
27+ this.entry = null;
12628 }
29+ }
12730
128− empty() {
129− if (this.subview != null) {
130− this.subview.deactivate();
131− }
132− this.subview = null;
133−
134− if (this.hiddenView != null) {
135− this.hiddenView.deactivate();
136− }
137− this.hiddenView = null;
31+ loading() {
32+ this.empty();
33+ this.trigger("loading");
34+ }
13835
139− this.resetClass();
140− super.empty(...arguments);
36+ render(content, fromCache) {
37+ if (content == null) {
38+ content = "";
14139 }
142−
143− subViewClass() {
144− return (
145− app.views[`${$.classify(this.entry.doc.type)}Page`] ||
146− app.views.BasePage
147− );
148− }
149−
150− getTitle() {
151− return (
152− this.entry.doc.fullName +
153− (this.entry.isIndex() ? " documentation" : ` / ${this.entry.name}`)
154− );
40+ if (fromCache == null) {
41+ fromCache = false;
15542 }
156−
157− beforeRoute() {
158− this.cache();
159− this.abort();
43+ if (!this.activated) {
44+ return;
16045 }
46+ this.empty();
47+ this.subview = new (this.subViewClass())(this.el, this.entry);
16148
162− onRoute(context) {
163− const isSameFile =
164− context.entry.filePath() ===
165− (this.entry != null ? this.entry.filePath() : undefined);
166− this.entry = context.entry;
167− if (!isSameFile) {
168− this.restore() || this.load();
49+ $.batchUpdate(this.el, () => {
50+ this.subview.render(content, fromCache);
51+ if (!fromCache) {
52+ this.addCopyButtons();
16953 }
170− }
54+ });
17155
172− load() {
173− this.loading();
174− this.xhr = this.entry.loadFile(
175− (response) => this.onSuccess(response),
176− () => this.onError(),
177− );
56+ if (app.disabledDocs.findBy("slug", this.entry.doc.slug)) {
57+ this.hiddenView = new app.views.HiddenPage(this.el, this.entry);
17858 }
17959
180− abort() {
181− if (this.xhr) {
182− this.xhr.abort();
183− this.xhr = this.entry = null;
184− }
185− }
60+ setFaviconForDoc(this.entry.doc);
61+ this.delay(this.polyfillMathML);
62+ this.trigger("loaded");
63+ }
18664
187− onSuccess(response) {
188− if (!this.activated) {
189− return;
190− }
191− this.xhr = null;
192− this.render(this.prepareContent(response));
65+ addCopyButtons() {
66+ if (!this.copyButton) {
67+ this.copyButton = document.createElement("button");
68+ this.copyButton.innerHTML = '<svg><use xlink:href="#icon-copy"/></svg>';
69+ this.copyButton.type = "button";
70+ this.copyButton.className = "_pre-clip";
71+ this.copyButton.title = "Copy to clipboard";
72+ this.copyButton.setAttribute("aria-label", "Copy to clipboard");
19373 }
194−
195− onError() {
196− this.xhr = null;
197− this.render(this.tmpl("pageLoadError"));
198− this.resetClass();
199− this.addClass(this.constructor.errorClass);
200− if (app.serviceWorker != null) {
201− app.serviceWorker.update();
202− }
74+ for (var el of this.findAllByTag("pre")) {
75+ el.appendChild(this.copyButton.cloneNode(true));
20376 }
77+ }
20478
205− cache() {
206− let path;
207− if (
208− this.xhr ||
209− !this.entry ||
210− this.cacheMap[(path = this.entry.filePath())]
211− ) {
212− return;
213− }
214−
215− this.cacheMap[path] = this.el.innerHTML;
216− this.cacheStack.push(path);
217−
218− while (this.cacheStack.length > app.config.history_cache_size) {
219− delete this.cacheMap[this.cacheStack.shift()];
220− }
79+ polyfillMathML() {
80+ if (
81+ window.supportsMathML !== false ||
82+ !!this.polyfilledMathML ||
83+ !this.findByTag("math")
84+ ) {
85+ return;
22186 }
87+ this.polyfilledMathML = true;
88+ $.append(
89+ document.head,
90+ `<link rel="stylesheet" href="${app.config.mathml_stylesheet}">`,
91+ );
92+ }
22293
223− restore() {
224− let path;
225− if (this.cacheMap[(path = this.entry.filePath())]) {
226− this.render(this.cacheMap[path], true);
227− return true;
228− }
94+ prepareContent(content) {
95+ if (!this.entry.isIndex() || !this.entry.doc.links) {
96+ return content;
22997 }
23098
231− onClick(event) {
232− const target = $.eventTarget(event);
233− if (target.hasAttribute("data-retry")) {
234− $.stopEvent(event);
235− this.load();
236− } else if (target.classList.contains("_pre-clip")) {
237− $.stopEvent(event);
238− target.classList.add(
239− $.copyToClipboard(target.parentNode.textContent)
240− ? "_pre-clip-success"
241− : "_pre-clip-error",
99+ const links = (() => {
100+ const result = [];
101+ for (var link in this.entry.doc.links) {
102+ var url = this.entry.doc.links[link];
103+ result.push(
104+ `<a href="${url}" class="_links-link">${EntryPage.LINKS[link]}</a>`,
242105 );
243− setTimeout(() => (target.className = "_pre-clip"), 2000);
244106 }
107+ return result;
108+ })();
109+
110+ return `<p class="_links">${links.join("")}</p>${content}`;
111+ }
112+
113+ empty() {
114+ if (this.subview != null) {
115+ this.subview.deactivate();
116+ }
117+ this.subview = null;
118+
119+ if (this.hiddenView != null) {
120+ this.hiddenView.deactivate();
121+ }
122+ this.hiddenView = null;
123+
124+ this.resetClass();
125+ super.empty(...arguments);
126+ }
127+
128+ subViewClass() {
129+ return (
130+ app.views[`${$.classify(this.entry.doc.type)}Page`] || app.views.BasePage
131+ );
132+ }
133+
134+ getTitle() {
135+ return (
136+ this.entry.doc.fullName +
137+ (this.entry.isIndex() ? " documentation" : ` / ${this.entry.name}`)
138+ );
139+ }
140+
141+ beforeRoute() {
142+ this.cache();
143+ this.abort();
144+ }
145+
146+ onRoute(context) {
147+ const isSameFile =
148+ context.entry.filePath() ===
149+ (this.entry != null ? this.entry.filePath() : undefined);
150+ this.entry = context.entry;
151+ if (!isSameFile) {
152+ this.restore() || this.load();
153+ }
154+ }
155+
156+ load() {
157+ this.loading();
158+ this.xhr = this.entry.loadFile(
159+ (response) => this.onSuccess(response),
160+ () => this.onError(),
161+ );
162+ }
163+
164+ abort() {
165+ if (this.xhr) {
166+ this.xhr.abort();
167+ this.xhr = this.entry = null;
168+ }
169+ }
170+
171+ onSuccess(response) {
172+ if (!this.activated) {
173+ return;
174+ }
175+ this.xhr = null;
176+ this.render(this.prepareContent(response));
177+ }
178+
179+ onError() {
180+ this.xhr = null;
181+ this.render(this.tmpl("pageLoadError"));
182+ this.resetClass();
183+ this.addClass(this.constructor.errorClass);
184+ if (app.serviceWorker != null) {
185+ app.serviceWorker.update();
186+ }
187+ }
188+
189+ cache() {
190+ let path;
191+ if (
192+ this.xhr ||
193+ !this.entry ||
194+ this.cacheMap[(path = this.entry.filePath())]
195+ ) {
196+ return;
197+ }
198+
199+ this.cacheMap[path] = this.el.innerHTML;
200+ this.cacheStack.push(path);
201+
202+ while (this.cacheStack.length > app.config.history_cache_size) {
203+ delete this.cacheMap[this.cacheStack.shift()];
204+ }
205+ }
206+
207+ restore() {
208+ let path;
209+ if (this.cacheMap[(path = this.entry.filePath())]) {
210+ this.render(this.cacheMap[path], true);
211+ return true;
212+ }
213+ }
214+
215+ onClick(event) {
216+ const target = $.eventTarget(event);
217+ if (target.hasAttribute("data-retry")) {
218+ $.stopEvent(event);
219+ this.load();
220+ } else if (target.classList.contains("_pre-clip")) {
221+ $.stopEvent(event);
222+ target.classList.add(
223+ $.copyToClipboard(target.parentNode.textContent)
224+ ? "_pre-clip-success"
225+ : "_pre-clip-error",
226+ );
227+ setTimeout(() => (target.className = "_pre-clip"), 2000);
245228 }
229+ }
246230
247− onAltC() {
248− let link;
249− if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
250− return;
251− }
252− console.log(link.href + location.hash);
253− navigator.clipboard.writeText(link.href + location.hash);
231+ onAltC() {
232+ let link;
233+ if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
234+ return;
254235 }
236+ console.log(link.href + location.hash);
237+ navigator.clipboard.writeText(link.href + location.hash);
238+ }
255239
256− onAltO() {
257− let link;
258− if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
259− return;
260− }
261− this.delay(() => $.popup(link.href + location.hash));
240+ onAltO() {
241+ let link;
242+ if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
243+ return;
262244 }
263− };
264− app.views.EntryPage.initClass();
265− return app.views.EntryPage;
266−})();
245+ this.delay(() => $.popup(link.href + location.hash));
246+ }
247+};