Unified · Split
| @@ -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"; | |
| 63 | 4 | |
| 64 | − $.batchUpdate(this.el, () => { | |
| 65 | − this.subview.render(content, fromCache); | |
| 66 | − if (!fromCache) { | |
| 67 | − this.addCopyButtons(); | |
| 68 | − } | |
| 69 | − }); | |
| 5 | + static events = { click: "onClick" }; | |
| 70 | 6 | |
| 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 | + }; | |
| 79 | 11 | |
| 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" }; | |
| 93 | 13 | |
| 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 | + }; | |
| 108 | 18 | |
| 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 | + } | |
| 113 | 23 | |
| 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; | |
| 126 | 28 | } |
| 29 | + } | |
| 127 | 30 | |
| 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 | + } | |
| 138 | 35 | |
| 139 | − this.resetClass(); | |
| 140 | − super.empty(...arguments); | |
| 36 | + render(content, fromCache) { | |
| 37 | + if (content == null) { | |
| 38 | + content = ""; | |
| 141 | 39 | } |
| 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; | |
| 155 | 42 | } |
| 156 | − | |
| 157 | − beforeRoute() { | |
| 158 | − this.cache(); | |
| 159 | − this.abort(); | |
| 43 | + if (!this.activated) { | |
| 44 | + return; | |
| 160 | 45 | } |
| 46 | + this.empty(); | |
| 47 | + this.subview = new (this.subViewClass())(this.el, this.entry); | |
| 161 | 48 | |
| 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(); | |
| 169 | 53 | } |
| 170 | − } | |
| 54 | + }); | |
| 171 | 55 | |
| 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); | |
| 178 | 58 | } |
| 179 | 59 | |
| 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 | + } | |
| 186 | 64 | |
| 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"); | |
| 193 | 73 | } |
| 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)); | |
| 203 | 76 | } |
| 77 | + } | |
| 204 | 78 | |
| 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; | |
| 221 | 86 | } |
| 87 | + this.polyfilledMathML = true; | |
| 88 | + $.append( | |
| 89 | + document.head, | |
| 90 | + `<link rel="stylesheet" href="${app.config.mathml_stylesheet}">`, | |
| 91 | + ); | |
| 92 | + } | |
| 222 | 93 | |
| 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; | |
| 229 | 97 | } |
| 230 | 98 | |
| 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>`, | |
| 242 | 105 | ); |
| 243 | − setTimeout(() => (target.className = "_pre-clip"), 2000); | |
| 244 | 106 | } |
| 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); | |
| 245 | 228 | } |
| 229 | + } | |
| 246 | 230 | |
| 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; | |
| 254 | 235 | } |
| 236 | + console.log(link.href + location.hash); | |
| 237 | + navigator.clipboard.writeText(link.href + location.hash); | |
| 238 | + } | |
| 255 | 239 | |
| 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; | |
| 262 | 244 | } |
| 263 | − }; | |
| 264 | − app.views.EntryPage.initClass(); | |
| 265 | − return app.views.EntryPage; | |
| 266 | −})(); | |
| 245 | + this.delay(() => $.popup(link.href + location.hash)); | |
| 246 | + } | |
| 247 | +}; | |