Skip to content

Instantly share code, notes, and snippets.

@kaiye

kaiye/injectEgretApiDoc.js

Last active Jan 16, 2020
Embed
What would you like to do?
Make the Egret API documents better searchable
(function(oldInput) {
if (!oldInput) return;
if (oldInput.__injected) return;
class DB {
constructor({ database, table, onload = () => {} }) {
this.database = database;
this.table = table;
this.onload = onload;
this.open();
}
open(version) {
if (this.db) {
this.db.close();
}
this.request = window.indexedDB.open(this.database, version);
this.request.onsuccess = this.onDBsuccess.bind(this);
this.request.onupgradeneeded = this.onDBupgrade.bind(this);
}
onDBsuccess() {
this.db = this.request.result;
if (this.db.objectStoreNames.contains(this.table)) {
this.read();
} else {
this.open(this.db.version + 1);
}
}
onDBupgrade(event) {
const db = event.target.result;
if (!db.objectStoreNames.contains(this.table)) {
db.createObjectStore(this.table, { keyPath: "id" });
}
}
read() {
const transaction = this.db.transaction([this.table]);
const objectStore = transaction.objectStore(this.table);
const request = objectStore.get(1);
request.onsuccess = () => {
console.log("read success", request.result);
this.onload(request.result ? JSON.parse(request.result.data) : {});
};
}
save(data) {
this.remove(() => {
this.add(data);
});
}
add(data) {
const request = this.db
.transaction([this.table], "readwrite")
.objectStore(this.table)
.add({ id: 1, data: JSON.stringify(data) });
request.onsuccess = () => {
console.log("add success");
};
}
remove(callback) {
const request = this.db
.transaction([this.table], "readwrite")
.objectStore(this.table)
.delete(1);
request.onsuccess = () => {
callback && callback();
};
}
}
const lang = location.pathname
.slice(1)
.split("/")
.shift();
const database = "__injectDocData__";
const table = `data_${lang}`;
let localData = {};
const db = new DB({
database,
table,
onload: data => {
localData = data;
exSearch();
}
});
const button = document.createElement("button");
const buttonText = "Preload Docs into Local Cache";
function load() {
button.disabled = true;
const validListTypes = Array.from(
document.querySelectorAll(".bdsharebuttonbox a")
).map(el => el.id.split("-").pop());
Array.from(document.querySelectorAll("#treelist a[data-class-name]"))
.map(a => [a.parentNode.dataset.listType, a.dataset.className])
.filter(([type]) => validListTypes.includes(type))
// .slice(-1)
// .concat([['9001', 'egret.gui.DropDownList']])
// .filter((el, index) => index < 10)
.map(([type, name], index) => accData => {
return fetch(
`/${lang}/apidoc/ajaxcontent/type/${type}/name/${name}`
).then(resp => {
if (!resp.ok) throw new Error("preload fail, try again");
button.innerHTML = "Loading" + Array((index % 4) + 1).join(".");
return resp.text().then(data => {
const tempNode = document.createElement("div");
tempNode.innerHTML = data.replace(/<img\s.*?>/g, "");
accData[`${type}|${name}`] = Array.from(
tempNode.querySelectorAll(
".MainContent>span:not([class^=hideInherited])"
)
)
.map(el => el.textContent)
.join();
return accData;
});
});
})
.reduce((promise, next) => {
return promise.then(accData => {
return new Promise(resolve => {
setTimeout(() => {
resolve(next(accData));
}, 0);
});
});
}, Promise.resolve({}))
.then(accData => {
localData = accData;
db.save(localData);
button.disabled = false;
button.innerHTML = `${buttonText} > success`;
exSearch();
})
.catch(err => {
button.disabled = false;
button.innerHTML = `${buttonText} > ${err.message}`;
});
}
button.innerHTML = buttonText;
button.style.display = "block";
button.onclick = load;
oldInput.parentNode.insertBefore(button, oldInput);
oldInput.__injected = true;
function exSearch() {
if (!Object.keys(localData).length) return;
const newInputId = "exInput";
if (oldInput.previousSibling.id === newInputId) return;
const newInput = document.createElement("input");
newInput.id = newInputId;
newInput.type = "text";
newInput.placeholder = "Search any keyword in API Docs";
newInput.style.width = "100%";
newInput.oninput = function(e) {
const searchKeyword = e.target.value;
const matchKeys = Object.keys(localData).filter(name => {
return new RegExp(searchKeyword, "i").test(localData[name]);
});
Array.from(
document.querySelectorAll("#treelist li[data-list-type]")
).forEach(li => {
li.style.display = "none";
});
Array.from(document.querySelectorAll("#treelist a[data-class-name]"))
.filter(a =>
matchKeys.includes(
[a.parentNode.dataset.listType, a.dataset.className].join("|")
)
)
.forEach(a => {
a.parentNode.style.display = "block";
});
};
oldInput.parentNode.insertBefore(newInput, oldInput);
}
})(document.querySelector("#searchclass"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.