mirror of https://github.com/freeCodeCamp/devdocs
parent
1995d8a3bb
commit
7fa81665df
@ -1,266 +1,247 @@
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Sanity-check the conversion and remove this comment.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS205: Consider reworking code to avoid use of IIFEs
|
||||
* DS206: Consider reworking classes to avoid initClass
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
(function () {
|
||||
let LINKS = undefined;
|
||||
app.views.EntryPage = class EntryPage extends app.View {
|
||||
static initClass() {
|
||||
this.className = "_page";
|
||||
this.errorClass = "_page-error";
|
||||
|
||||
this.events = { click: "onClick" };
|
||||
|
||||
this.shortcuts = {
|
||||
altC: "onAltC",
|
||||
altO: "onAltO",
|
||||
};
|
||||
|
||||
this.routes = { before: "beforeRoute" };
|
||||
|
||||
LINKS = {
|
||||
home: "Homepage",
|
||||
code: "Source code",
|
||||
};
|
||||
}
|
||||
|
||||
init() {
|
||||
this.cacheMap = {};
|
||||
this.cacheStack = [];
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
if (super.deactivate(...arguments)) {
|
||||
this.empty();
|
||||
this.entry = null;
|
||||
}
|
||||
}
|
||||
|
||||
loading() {
|
||||
this.empty();
|
||||
this.trigger("loading");
|
||||
}
|
||||
|
||||
render(content, fromCache) {
|
||||
if (content == null) {
|
||||
content = "";
|
||||
}
|
||||
if (fromCache == null) {
|
||||
fromCache = false;
|
||||
}
|
||||
if (!this.activated) {
|
||||
return;
|
||||
}
|
||||
this.empty();
|
||||
this.subview = new (this.subViewClass())(this.el, this.entry);
|
||||
app.views.EntryPage = class EntryPage extends app.View {
|
||||
static className = "_page";
|
||||
static errorClass = "_page-error";
|
||||
|
||||
$.batchUpdate(this.el, () => {
|
||||
this.subview.render(content, fromCache);
|
||||
if (!fromCache) {
|
||||
this.addCopyButtons();
|
||||
}
|
||||
});
|
||||
static events = { click: "onClick" };
|
||||
|
||||
if (app.disabledDocs.findBy("slug", this.entry.doc.slug)) {
|
||||
this.hiddenView = new app.views.HiddenPage(this.el, this.entry);
|
||||
}
|
||||
|
||||
setFaviconForDoc(this.entry.doc);
|
||||
this.delay(this.polyfillMathML);
|
||||
this.trigger("loaded");
|
||||
}
|
||||
static shortcuts = {
|
||||
altC: "onAltC",
|
||||
altO: "onAltO",
|
||||
};
|
||||
|
||||
addCopyButtons() {
|
||||
if (!this.copyButton) {
|
||||
this.copyButton = document.createElement("button");
|
||||
this.copyButton.innerHTML = '<svg><use xlink:href="#icon-copy"/></svg>';
|
||||
this.copyButton.type = "button";
|
||||
this.copyButton.className = "_pre-clip";
|
||||
this.copyButton.title = "Copy to clipboard";
|
||||
this.copyButton.setAttribute("aria-label", "Copy to clipboard");
|
||||
}
|
||||
for (var el of Array.from(this.findAllByTag("pre"))) {
|
||||
el.appendChild(this.copyButton.cloneNode(true));
|
||||
}
|
||||
}
|
||||
static routes = { before: "beforeRoute" };
|
||||
|
||||
polyfillMathML() {
|
||||
if (
|
||||
window.supportsMathML !== false ||
|
||||
!!this.polyfilledMathML ||
|
||||
!this.findByTag("math")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.polyfilledMathML = true;
|
||||
$.append(
|
||||
document.head,
|
||||
`<link rel="stylesheet" href="${app.config.mathml_stylesheet}">`,
|
||||
);
|
||||
}
|
||||
static LINKS = {
|
||||
home: "Homepage",
|
||||
code: "Source code",
|
||||
};
|
||||
|
||||
prepareContent(content) {
|
||||
if (!this.entry.isIndex() || !this.entry.doc.links) {
|
||||
return content;
|
||||
}
|
||||
init() {
|
||||
this.cacheMap = {};
|
||||
this.cacheStack = [];
|
||||
}
|
||||
|
||||
const links = (() => {
|
||||
const result = [];
|
||||
for (var link in this.entry.doc.links) {
|
||||
var url = this.entry.doc.links[link];
|
||||
result.push(
|
||||
`<a href="${url}" class="_links-link">${LINKS[link]}</a>`,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
})();
|
||||
|
||||
return `<p class="_links">${links.join("")}</p>${content}`;
|
||||
deactivate() {
|
||||
if (super.deactivate(...arguments)) {
|
||||
this.empty();
|
||||
this.entry = null;
|
||||
}
|
||||
}
|
||||
|
||||
empty() {
|
||||
if (this.subview != null) {
|
||||
this.subview.deactivate();
|
||||
}
|
||||
this.subview = null;
|
||||
|
||||
if (this.hiddenView != null) {
|
||||
this.hiddenView.deactivate();
|
||||
}
|
||||
this.hiddenView = null;
|
||||
loading() {
|
||||
this.empty();
|
||||
this.trigger("loading");
|
||||
}
|
||||
|
||||
this.resetClass();
|
||||
super.empty(...arguments);
|
||||
render(content, fromCache) {
|
||||
if (content == null) {
|
||||
content = "";
|
||||
}
|
||||
|
||||
subViewClass() {
|
||||
return (
|
||||
app.views[`${$.classify(this.entry.doc.type)}Page`] ||
|
||||
app.views.BasePage
|
||||
);
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return (
|
||||
this.entry.doc.fullName +
|
||||
(this.entry.isIndex() ? " documentation" : ` / ${this.entry.name}`)
|
||||
);
|
||||
if (fromCache == null) {
|
||||
fromCache = false;
|
||||
}
|
||||
|
||||
beforeRoute() {
|
||||
this.cache();
|
||||
this.abort();
|
||||
if (!this.activated) {
|
||||
return;
|
||||
}
|
||||
this.empty();
|
||||
this.subview = new (this.subViewClass())(this.el, this.entry);
|
||||
|
||||
onRoute(context) {
|
||||
const isSameFile =
|
||||
context.entry.filePath() ===
|
||||
(this.entry != null ? this.entry.filePath() : undefined);
|
||||
this.entry = context.entry;
|
||||
if (!isSameFile) {
|
||||
this.restore() || this.load();
|
||||
$.batchUpdate(this.el, () => {
|
||||
this.subview.render(content, fromCache);
|
||||
if (!fromCache) {
|
||||
this.addCopyButtons();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
load() {
|
||||
this.loading();
|
||||
this.xhr = this.entry.loadFile(
|
||||
(response) => this.onSuccess(response),
|
||||
() => this.onError(),
|
||||
);
|
||||
if (app.disabledDocs.findBy("slug", this.entry.doc.slug)) {
|
||||
this.hiddenView = new app.views.HiddenPage(this.el, this.entry);
|
||||
}
|
||||
|
||||
abort() {
|
||||
if (this.xhr) {
|
||||
this.xhr.abort();
|
||||
this.xhr = this.entry = null;
|
||||
}
|
||||
}
|
||||
setFaviconForDoc(this.entry.doc);
|
||||
this.delay(this.polyfillMathML);
|
||||
this.trigger("loaded");
|
||||
}
|
||||
|
||||
onSuccess(response) {
|
||||
if (!this.activated) {
|
||||
return;
|
||||
}
|
||||
this.xhr = null;
|
||||
this.render(this.prepareContent(response));
|
||||
addCopyButtons() {
|
||||
if (!this.copyButton) {
|
||||
this.copyButton = document.createElement("button");
|
||||
this.copyButton.innerHTML = '<svg><use xlink:href="#icon-copy"/></svg>';
|
||||
this.copyButton.type = "button";
|
||||
this.copyButton.className = "_pre-clip";
|
||||
this.copyButton.title = "Copy to clipboard";
|
||||
this.copyButton.setAttribute("aria-label", "Copy to clipboard");
|
||||
}
|
||||
|
||||
onError() {
|
||||
this.xhr = null;
|
||||
this.render(this.tmpl("pageLoadError"));
|
||||
this.resetClass();
|
||||
this.addClass(this.constructor.errorClass);
|
||||
if (app.serviceWorker != null) {
|
||||
app.serviceWorker.update();
|
||||
}
|
||||
for (var el of this.findAllByTag("pre")) {
|
||||
el.appendChild(this.copyButton.cloneNode(true));
|
||||
}
|
||||
}
|
||||
|
||||
cache() {
|
||||
let path;
|
||||
if (
|
||||
this.xhr ||
|
||||
!this.entry ||
|
||||
this.cacheMap[(path = this.entry.filePath())]
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cacheMap[path] = this.el.innerHTML;
|
||||
this.cacheStack.push(path);
|
||||
|
||||
while (this.cacheStack.length > app.config.history_cache_size) {
|
||||
delete this.cacheMap[this.cacheStack.shift()];
|
||||
}
|
||||
polyfillMathML() {
|
||||
if (
|
||||
window.supportsMathML !== false ||
|
||||
!!this.polyfilledMathML ||
|
||||
!this.findByTag("math")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.polyfilledMathML = true;
|
||||
$.append(
|
||||
document.head,
|
||||
`<link rel="stylesheet" href="${app.config.mathml_stylesheet}">`,
|
||||
);
|
||||
}
|
||||
|
||||
restore() {
|
||||
let path;
|
||||
if (this.cacheMap[(path = this.entry.filePath())]) {
|
||||
this.render(this.cacheMap[path], true);
|
||||
return true;
|
||||
}
|
||||
prepareContent(content) {
|
||||
if (!this.entry.isIndex() || !this.entry.doc.links) {
|
||||
return content;
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
const target = $.eventTarget(event);
|
||||
if (target.hasAttribute("data-retry")) {
|
||||
$.stopEvent(event);
|
||||
this.load();
|
||||
} else if (target.classList.contains("_pre-clip")) {
|
||||
$.stopEvent(event);
|
||||
target.classList.add(
|
||||
$.copyToClipboard(target.parentNode.textContent)
|
||||
? "_pre-clip-success"
|
||||
: "_pre-clip-error",
|
||||
const links = (() => {
|
||||
const result = [];
|
||||
for (var link in this.entry.doc.links) {
|
||||
var url = this.entry.doc.links[link];
|
||||
result.push(
|
||||
`<a href="${url}" class="_links-link">${EntryPage.LINKS[link]}</a>`,
|
||||
);
|
||||
setTimeout(() => (target.className = "_pre-clip"), 2000);
|
||||
}
|
||||
return result;
|
||||
})();
|
||||
|
||||
return `<p class="_links">${links.join("")}</p>${content}`;
|
||||
}
|
||||
|
||||
empty() {
|
||||
if (this.subview != null) {
|
||||
this.subview.deactivate();
|
||||
}
|
||||
this.subview = null;
|
||||
|
||||
if (this.hiddenView != null) {
|
||||
this.hiddenView.deactivate();
|
||||
}
|
||||
this.hiddenView = null;
|
||||
|
||||
this.resetClass();
|
||||
super.empty(...arguments);
|
||||
}
|
||||
|
||||
subViewClass() {
|
||||
return (
|
||||
app.views[`${$.classify(this.entry.doc.type)}Page`] || app.views.BasePage
|
||||
);
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return (
|
||||
this.entry.doc.fullName +
|
||||
(this.entry.isIndex() ? " documentation" : ` / ${this.entry.name}`)
|
||||
);
|
||||
}
|
||||
|
||||
beforeRoute() {
|
||||
this.cache();
|
||||
this.abort();
|
||||
}
|
||||
|
||||
onRoute(context) {
|
||||
const isSameFile =
|
||||
context.entry.filePath() ===
|
||||
(this.entry != null ? this.entry.filePath() : undefined);
|
||||
this.entry = context.entry;
|
||||
if (!isSameFile) {
|
||||
this.restore() || this.load();
|
||||
}
|
||||
}
|
||||
|
||||
load() {
|
||||
this.loading();
|
||||
this.xhr = this.entry.loadFile(
|
||||
(response) => this.onSuccess(response),
|
||||
() => this.onError(),
|
||||
);
|
||||
}
|
||||
|
||||
abort() {
|
||||
if (this.xhr) {
|
||||
this.xhr.abort();
|
||||
this.xhr = this.entry = null;
|
||||
}
|
||||
}
|
||||
|
||||
onSuccess(response) {
|
||||
if (!this.activated) {
|
||||
return;
|
||||
}
|
||||
this.xhr = null;
|
||||
this.render(this.prepareContent(response));
|
||||
}
|
||||
|
||||
onError() {
|
||||
this.xhr = null;
|
||||
this.render(this.tmpl("pageLoadError"));
|
||||
this.resetClass();
|
||||
this.addClass(this.constructor.errorClass);
|
||||
if (app.serviceWorker != null) {
|
||||
app.serviceWorker.update();
|
||||
}
|
||||
}
|
||||
|
||||
cache() {
|
||||
let path;
|
||||
if (
|
||||
this.xhr ||
|
||||
!this.entry ||
|
||||
this.cacheMap[(path = this.entry.filePath())]
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cacheMap[path] = this.el.innerHTML;
|
||||
this.cacheStack.push(path);
|
||||
|
||||
while (this.cacheStack.length > app.config.history_cache_size) {
|
||||
delete this.cacheMap[this.cacheStack.shift()];
|
||||
}
|
||||
}
|
||||
|
||||
restore() {
|
||||
let path;
|
||||
if (this.cacheMap[(path = this.entry.filePath())]) {
|
||||
this.render(this.cacheMap[path], true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
const target = $.eventTarget(event);
|
||||
if (target.hasAttribute("data-retry")) {
|
||||
$.stopEvent(event);
|
||||
this.load();
|
||||
} else if (target.classList.contains("_pre-clip")) {
|
||||
$.stopEvent(event);
|
||||
target.classList.add(
|
||||
$.copyToClipboard(target.parentNode.textContent)
|
||||
? "_pre-clip-success"
|
||||
: "_pre-clip-error",
|
||||
);
|
||||
setTimeout(() => (target.className = "_pre-clip"), 2000);
|
||||
}
|
||||
}
|
||||
|
||||
onAltC() {
|
||||
let link;
|
||||
if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
|
||||
return;
|
||||
}
|
||||
console.log(link.href + location.hash);
|
||||
navigator.clipboard.writeText(link.href + location.hash);
|
||||
onAltC() {
|
||||
let link;
|
||||
if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
|
||||
return;
|
||||
}
|
||||
console.log(link.href + location.hash);
|
||||
navigator.clipboard.writeText(link.href + location.hash);
|
||||
}
|
||||
|
||||
onAltO() {
|
||||
let link;
|
||||
if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
|
||||
return;
|
||||
}
|
||||
this.delay(() => $.popup(link.href + location.hash));
|
||||
onAltO() {
|
||||
let link;
|
||||
if (!(link = this.find("._attribution:last-child ._attribution-link"))) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
app.views.EntryPage.initClass();
|
||||
return app.views.EntryPage;
|
||||
})();
|
||||
this.delay(() => $.popup(link.href + location.hash));
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in new issue