mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
283 lines
11 KiB
JavaScript
283 lines
11 KiB
JavaScript
// ###### Helper functions ######
|
|
|
|
// get query as string from form Element
|
|
function getQueryStr(queryFormElement) {
|
|
// gets query
|
|
let queryFormData;
|
|
let queryStr;
|
|
queryFormData = new FormData(queryFormElement);
|
|
queryStr = queryFormData.get("query-form-query");
|
|
return queryStr
|
|
}
|
|
|
|
// get display options from display options form element
|
|
function getDisplayOptions(displayOptionsFormElement) {
|
|
// gets display options parameters
|
|
let displayOptionsFormData
|
|
let displayOptionsData;
|
|
displayOptionsFormData = new FormData(displayOptionsFormElement);
|
|
displayOptionsData = {"resultsPerPage": displayOptionsFormData.get("display-options-form-results_per_page"),
|
|
"resultsContex": displayOptionsFormData.get("display-options-form-result_context"),
|
|
"expertMode": displayOptionsFormData.get("display-options-form-expert_mode")};
|
|
console.log(displayOptionsData);
|
|
return displayOptionsData
|
|
}
|
|
|
|
// ###### Download results functions ######
|
|
// TODO: Maybe write these as class functions? For this maybe create a result class
|
|
|
|
// function creates a unique and safe filename for the download
|
|
function createDownloadFilename() {
|
|
let today;
|
|
let currentDate;
|
|
let currentTime;
|
|
let safeFilename;
|
|
let resultFilename;
|
|
// get and create metadata
|
|
console.log("Create Metadata!");
|
|
today = new Date();
|
|
currentDate = today.getUTCFullYear() + '-' + (today.getUTCMonth() +1) + '-' + today.getUTCDate();
|
|
currentTime = today.getUTCHours() + ":" + today.getUTCMinutes() + ":" + today.getUTCSeconds();
|
|
safeFilename = results.resultsJSON["query"].replace(/[^a-z0-9_-]/gi, "_");
|
|
resultFilename = "UTC-" + currentDate + "_" + currentTime + "_" + safeFilename;
|
|
return resultFilename
|
|
}
|
|
|
|
// function to download the results as JSON
|
|
function downloadJSONRessource(resultFilename) {
|
|
let dataStr;
|
|
let downloadElement;
|
|
// stringify JSON object for json download
|
|
dataStr = JSON.stringify(results.resultsJSON, undefined, "\t"); // use tabs to save some space
|
|
// get downloadResultsElement
|
|
downloadElement = document.getElementById("download-results-json");
|
|
// start actual download
|
|
download(downloadElement, dataStr, resultFilename, "text/json", ".json")
|
|
}
|
|
|
|
// Function to download data as a Blob created from a string, should be multi purpose
|
|
function download(downloadElem, dataStr, filename, type, filenameSlug) {
|
|
let file;
|
|
console.log("Start Download!");
|
|
filename += filenameSlug;
|
|
file = new Blob([dataStr], {type: type});
|
|
if (window.navigator.msSaveOrOpenBlob) // IE10+
|
|
window.navigator.msSaveOrOpenBlob(file, filename);
|
|
else { // Others
|
|
var url = URL.createObjectURL(file);
|
|
downloadElem.href = url;
|
|
downloadElem.download = filename;
|
|
}
|
|
}
|
|
|
|
// ###### Functions to inspect one match, to show more details ######
|
|
|
|
// activate inspect buttons if queryFinished is true
|
|
function activateInspect() {
|
|
console.log("activation progress", progress);
|
|
if (progress === 100) {
|
|
let inspectBtnElements;
|
|
inspectBtnElements = document.getElementsByClassName("inspect");
|
|
for (let inspectBtn of inspectBtnElements) {
|
|
inspectBtn.classList.remove("disabled");
|
|
}
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
|
|
//gets result cpos infos for one dataIndex to send back to the server
|
|
function inspect(dataIndex) {
|
|
// This function should be in the AnalysisClient class as a method.
|
|
console.log("Inspect!");
|
|
console.log(results.resultsJSON.matches[dataIndex].c);
|
|
contextResultsElement = document.getElementById("context-results");
|
|
contextResultsElement.innerHTML = ""; // clear it from old inspects
|
|
contextModal.open();
|
|
nopaque.socket.emit("pj_corpus_analysis_inspect_match",
|
|
{payload: {
|
|
first_cpos: results.resultsJSON.matches[dataIndex].c[0],
|
|
last_cpos: results.resultsJSON.matches[dataIndex].c[1]
|
|
}
|
|
});
|
|
}
|
|
|
|
function showMatchContext(response) {
|
|
let contextData = response.payload
|
|
let contextResultsElement;
|
|
let contextModalLoading;
|
|
let contextModalReady;
|
|
let expertModeSwitchElement
|
|
let partElement
|
|
let token;
|
|
let tokenElement;
|
|
console.log("###### match_context ######");
|
|
console.log("Incoming data:", contextData);
|
|
expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
|
|
contextResultsElement = document.getElementById("context-results");
|
|
contextModalLoading = document.getElementById("context-modal-loading");
|
|
contextModalLoading.classList.add("hide");
|
|
contextModalReady = document.getElementById("context-modal-ready");
|
|
contextModalReady.classList.remove("hide");
|
|
|
|
if (contextData.cpos_ranges == true) {
|
|
// python range like function from MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range)
|
|
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
|
|
lc = range(contextData.match.lc[0], contextData.match.lc[1], 1)
|
|
c = range(contextData.match.c[0], contextData.match.c[1], 1)
|
|
rc = range(contextData.match.rc[0], contextData.match.rc[1], 1)
|
|
} else {
|
|
lc = contextData.match.lc;
|
|
c = contextData.match.c;
|
|
rc = contextData.match.rc;
|
|
}
|
|
|
|
partElement = document.createElement("p");
|
|
for (let cpos of lc) {
|
|
token = contextData["cpos_lookup"][cpos];
|
|
partElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
|
|
contextResultsElement.append(partElement);
|
|
}
|
|
for (let cpos of c) {
|
|
token = contextData["cpos_lookup"][cpos];
|
|
partElement.insertAdjacentHTML("beforeend", `<span class="token bold underline" data-cpos="${cpos}" style="text-decoration-line: underline;">${token["word"]} </span>`);
|
|
contextResultsElement.append(partElement);
|
|
}
|
|
for (let cpos of rc) {
|
|
token = contextData["cpos_lookup"][cpos];
|
|
partElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
|
|
contextResultsElement.append(partElement);
|
|
}
|
|
if (expertModeSwitchElement.checked) {
|
|
let tokenElements = partElement.getElementsByClassName("token");
|
|
expertModeOn(tokenElements, contextData);
|
|
}
|
|
}
|
|
|
|
// ###### Display options changing live how the matches are being displayed ######
|
|
|
|
// Event function that changes the shown hits per page.
|
|
// Just alters the resultsList.page property
|
|
function changeHitsPerPage(event) {
|
|
try {
|
|
resultsList.page = event.target.value;
|
|
resultsList.update();
|
|
nopaque.flash("Updated matches per page.")
|
|
} catch (e) {
|
|
console.log("resultsList has no results right now. Live update of items per page is useless for now.");
|
|
}
|
|
}
|
|
|
|
// Event function triggered on context select change and also if pagination is clicked
|
|
function changeContext(event) {
|
|
let newContextValue;
|
|
let lc;
|
|
let rc;
|
|
let array;
|
|
try {
|
|
if (event.type === "change") {
|
|
nopaque.flash("Updated context per match!");
|
|
}
|
|
} catch (e) {
|
|
// console.log(e);
|
|
// console.log("This error is expected.");
|
|
} finally {
|
|
newContextValue = document.getElementById("display-options-form-result_context").value;
|
|
console.log("Context value is:", newContextValue);
|
|
lc = document.getElementsByClassName("left-context");
|
|
rc = document.getElementsByClassName("right-context");
|
|
for (let element of lc) {
|
|
array = Array.from(element.childNodes);
|
|
for (let element of array.slice(newContextValue)) {
|
|
element.classList.add("hide");
|
|
}
|
|
for (let element of array.slice(0, newContextValue)) {
|
|
element.classList.remove("hide");
|
|
}
|
|
}
|
|
for (let element of rc) {
|
|
array = Array.from(element.childNodes);
|
|
for (let element of array.slice(newContextValue)) {
|
|
element.classList.add("hide");
|
|
}
|
|
for (let element of array.slice(0, newContextValue)) {
|
|
element.classList.remove("hide");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ###### Expert view event functions ######
|
|
|
|
// Event function to check if pagination is used and then look if
|
|
// expertModeSwitchElement is checked
|
|
// if checked than expertModeOn is executed
|
|
// if unchecked expertModeOff is executed
|
|
function eventHandlerCheck(event) {
|
|
console.log("pagination used!");
|
|
console.log(expertModeSwitchElement.checked);
|
|
if (expertModeSwitchElement.checked) {
|
|
expertModeOn(event.currentTarget.tokenElements, resultsJSON);
|
|
} else if (!expertModeSwitchElement.checked) {
|
|
event.preventDefault();
|
|
console.log("prevented! Destroy");
|
|
expertModeOff(event.currentTarget.tokenElements);
|
|
}
|
|
}
|
|
|
|
// function to apply extra information and animation to every token
|
|
function expertModeOn(tokenElements, results) {
|
|
let token;
|
|
|
|
console.log("expertModeOn!");
|
|
for (let tokenElement of tokenElements) {
|
|
tokenElement.classList.add("chip");
|
|
tokenElement.classList.add("hoverable");
|
|
tokenElement.classList.add("expert-view");
|
|
token = results["cpos_lookup"][tokenElement.dataset.cpos];
|
|
tokenElement.addEventListener("mouseover", function(event) {
|
|
console.log("Mouseover!");
|
|
console.log(event.target);
|
|
token = results["cpos_lookup"][event.target.dataset.cpos];
|
|
addToolTipToTokenElement(event.target, token);
|
|
});
|
|
}
|
|
}
|
|
|
|
// fuction that creates Tooltip for one token and extracts the corresponding
|
|
// infos from the result JSON
|
|
function addToolTipToTokenElement(tokenElement, token) {
|
|
M.Tooltip.init(tokenElement,
|
|
{"html": `<table>
|
|
<tr>
|
|
<th>Token information</th>
|
|
<th>Source information</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="left-align">
|
|
Word: ${token["word"]}<br>
|
|
Lemma: ${token["lemma"]}<br>
|
|
POS: ${token["pos"]}<br>
|
|
Simple POS: ${token["simple_pos"]}<br>
|
|
NER: ${token["ner"]}
|
|
</td>
|
|
<td class="left-align">
|
|
Title: ${resultsJSON["text_lookup"][token["text"]]["title"]}<br>
|
|
Author: ${resultsJSON["text_lookup"][token["text"]]["author"]}<br>
|
|
Publishing year: ${resultsJSON["text_lookup"][token["text"]]["publishing_year"]}
|
|
</td>
|
|
</tr>
|
|
</table>`});
|
|
}
|
|
|
|
// function to remove extra informations and animations from tokens
|
|
function expertModeOff(tokenElements) {
|
|
console.log("expertModeOff!");
|
|
for (let tokenElement of tokenElements) {
|
|
tokenElement.classList.remove("chip");
|
|
tokenElement.classList.remove("hoverable");
|
|
tokenElement.classList.remove("expert-view");
|
|
tokenElement.outerHTML = tokenElement.outerHTML; // this is actually a workaround, but it works pretty fast
|
|
}
|
|
}
|