class ConcordanceQueryBuilder { constructor() { this.positionalAttrList = { "emptyToken": {prettyText: "empty token", cqlOpening: "[", tokenValue:"", cqlClosing: "]"}, "word": {prettyText: "word", cqlOpening: "[word=", tokenValue: "", cqlClosing: "]"}, "lemma": {prettyText: "lemma", cqlOpening: "[lemma=", tokenValue:"", cqlClosing: "]"}, "pos": {prettyText: "pos", cqlOpening: "[pos=", tokenValue:"", cqlClosing: "]"}, "simplePos": {prettyText: "simple_pos", cqlOpening: "[simple_pos=", tokenValue:"", cqlClosing: "]"} } this.elements = { counter: 0, yourQueryContent: [], queryContent:[], //#region QueryBuilder Elements concordanceQueryBuilder: document.querySelector("#concordance-query-builder"), concordanceQueryBuilderButton: document.querySelector("#concordance-query-builder-button"), positionalAttr: document.querySelector("#token-attr"), structuralAttr: document.querySelector("#structural-attr"), buttonPreparer: document.querySelector("#button-preparer"), yourQuery: document.querySelector("#your-query"), insertQueryButton: document.querySelector("#insert-query-button"), tokenQuery: document.querySelector("#token-query"), tokenBuilderContent: document.querySelector("#token-builder-content"), buildTokenButton: document.querySelector("#build-token-button"), extFormQuery: document.querySelector('#concordance-extension-form-query'), //#endregion QueryBuilder Elements //#region Strucutral Attributes sentence:document.querySelector("#sentence"), entity: document.querySelector("#entity"), textAnnotation: document.querySelector("#text-annotation"), entityBuilder: document.querySelector("#entity-builder"), englishEntType: document.querySelector("#english-ent-type"), germanEntType: document.querySelector("#german-ent-type"), emptyEntity: document.querySelector("#empty-entity"), entityAnyType: false, textAnnotationBuilder: document.querySelector("#text-annotation-builder"), textAnnotationOptions: document.querySelector("#text-annotation-options"), textAnnotationInput: document.querySelector("#text-annotation-input"), textAnnotationSubmit: document.querySelector("#text-annotation-submit"), //#endregion Structural Attributes //#region Token Attributes tokenCounter: 0, lemma: document.querySelector("#lemma"), emptyToken: document.querySelector("#empty-token"), word: document.querySelector("#word"), lemma: document.querySelector("#lemma"), pos: document.querySelector("#pos"), simplePosButton: document.querySelector("#simple-pos-button"), incidenceModifiers: document.querySelector("[data-target='incidence-modifiers']"), or: document.querySelector("#or"), and: document.querySelector("#and"), //#region Word and Lemma Elements wordBuilder: document.querySelector("#word-builder"), lemmaBuilder: document.querySelector("#lemma-builder"), inputOptions: document.querySelector("#input-options"), wordInput: document.querySelector("#word-input"), wordSubmit: document.querySelector("#word-submit"), lemmaInput: document.querySelector("#lemma-input"), lemmaSubmit: document.querySelector("#lemma-submit"), ignoreCaseCheckbox : document.querySelector("#ignore-case-checkbox"), ignoreCase: document.querySelector("input[type='checkbox']"), wildcardChar: document.querySelector("#wildcard-char"), optionGroup: document.querySelector("#option-group"), incidenceModifiersTB: document.querySelector("[data-target='incidence-modifiers-text-builder']"), //#endregion Word and Lemma Elements //#region posBuilder Elements posBuilder: document.querySelector("#pos-builder"), englishPos: document.querySelector("#english-pos"), germanPos: document.querySelector("#german-pos"), //#endregion posBuilder Elements //#region simple_posBuilder Elements simplePosBuilder: document.querySelector("#simplepos-builder"), simplePos: document.querySelector("#simple-pos"), //#endregion simple_posBuilder Elements //#region incidence modifiers oneOrMore: document.querySelector("#one-or-more"), zeroOrMore: document.querySelector("#zero-or-more"), zeroOrOne: document.querySelector("#zero-or-one"), exactlyN: document.querySelector("#exactlyN"), betweenNM: document.querySelector("#betweenNM"), nInput: document.querySelector("#n-input"), nSubmit: document.querySelector("#n-submit"), nmInput: document.querySelector("#n-m-input"), mInput: document.querySelector("#m-input"), nmSubmit: document.querySelector("#n-m-submit"), oneOrMoreTB: document.querySelector("#one-or-more-tb"), zeroOrMoreTB: document.querySelector("#zero-or-more-tb"), zeroOrOneTB: document.querySelector("#zero-or-one-tb"), exactlyNTB: document.querySelector("#exactly-n-tb"), betweenNMTB: document.querySelector("#between-n-m-tb") //#endregion incidence modifiers //#endregion Token Attributes } this.elements.concordanceQueryBuilderButton.addEventListener("click", () => {this.clearAll();}); this.elements.insertQueryButton.addEventListener("click", () => {this.insertQuery();}); //#region Structural Attribute Event Listeners this.elements.sentence.addEventListener("click", () => {this.addSentence();}); this.elements.entity.addEventListener("click", () => {this.addEntity();}); this.elements.textAnnotation.addEventListener("click", () => {this.addTextAnnotation();}); this.elements.englishEntType.addEventListener("change", () => {this.englishEntTypeHandler();}); this.elements.germanEntType.addEventListener("change", () => {this.germanEntTypeHandler();}); this.elements.emptyEntity.addEventListener("click", () => {this.emptyEntityButton();}); this.elements.textAnnotationSubmit.addEventListener("click", () => {this.textAnnotationSubmitHandler();}); //#endregion //#region Token Attribute Event Listeners this.elements.buildTokenButton.addEventListener("click", () => {this.addToken();}); this.elements.emptyToken.addEventListener("click", () => {this.emptyTokenHandler();}); this.elements.word.addEventListener("click", () => {this.wordBuilder();}); this.elements.lemma.addEventListener("click", () => {this.lemmaBuilder();}); this.elements.pos.addEventListener("click", () => {this.posBuilder();}); this.elements.simplePosButton.addEventListener("click", () => {this.simplePosBuilder();}); this.elements.or.addEventListener("click", () => {this.orHandler();}); this.elements.and.addEventListener("click", () => {this.andHandler();}); this.elements.ignoreCase.addEventListener("change", () => {this.inputOptionHandler(this.elements.ignoreCase);}); this.elements.wildcardChar.addEventListener("click", () => {this.inputOptionHandler(this.elements.wildcardChar);}); this.elements.optionGroup.addEventListener("click", () => {this.inputOptionHandler(this.elements.optionGroup);}); this.elements.wordSubmit.addEventListener("click", () => {this.textSubmit();}); this.elements.lemmaSubmit.addEventListener("click", () => {this.textSubmit();}); this.elements.englishPos.addEventListener("change", () => {this.englishPosHandler();}); this.elements.germanPos.addEventListener("change", () => {this.germanPosHandler();}); this.elements.simplePos.addEventListener("change", () => {this.simplePosHandler();}); this.elements.oneOrMore.addEventListener("click", () => {this.incidenceModifiersHandler(this.elements.oneOrMore);}); this.elements.zeroOrMore.addEventListener("click", () => {this.incidenceModifiersHandler(this.elements.zeroOrMore);}); this.elements.zeroOrOne.addEventListener("click", () => {this.incidenceModifiersHandler(this.elements.zeroOrOne);}); this.elements.nSubmit.addEventListener("click", () => {this.nSubmitHandler();}); this.elements.nmSubmit.addEventListener("click", () => {this.nmSubmitHandler();}); this.elements.oneOrMoreTB.addEventListener("click", () => {this.incidenceModifiersHandlerTB(this.elements.oneOrMoreTB);}); this.elements.zeroOrMoreTB.addEventListener("click", () => {this.incidenceModifiersHandlerTB(this.elements.zeroOrMoreTB);}); this.elements.zeroOrOneTB.addEventListener("click", () => {this.incidenceModifiersHandlerTB(this.elements.zeroOrOneTB);}); this.elements.exactlyNTB.addEventListener("click", () => {this.incidenceModifiersHandlerTB(this.elements.exactlyNTB);}); this.elements.betweenNMTB.addEventListener("click", () => {this.incidenceModifiersHandlerTB(this.elements.betweenNMTB);}); //#endregion Token Attribute Event Listeners } //#region Structural Attribute Builder Functions addSentence() { this.hideEverything(); if(this.elements.sentence.text === 'End Sentence') { this.buttonfactory('end-sentence', 'Sentence End', ''); this.elements.sentence.innerHTML = 'Sentence'; this.elements.insertQueryButton.classList.remove("disabled"); this.elements.counter += 1; } else { this.buttonfactory('start-sentence', 'Sentence Start', ''); this.elements.queryContent.push("sentence"); this.elements.sentence.innerHTML = 'End Sentence'; } } addEntity() { if(this.elements.entity.text === 'End Entity'){ let queryText; if (this.elements.entityAnyType === false){ queryText = ''; } else { queryText = ''; } this.buttonfactory('end-entity', 'Entity End', queryText); this.elements.entity.innerHTML = 'Entity'; this.elements.insertQueryButton.classList.remove("disabled"); this.elements.counter += 1; } else { this.hideEverything(); this.elements.entityBuilder.classList.remove("hide"); } } englishEntTypeHandler() { this.buttonfactory('start-entity', 'Entity Type=' + this.elements.englishEntType.value, ''); this.elements.entity.innerHTML = 'End Entity'; this.hideEverything(); this.elements.entityAnyType = false; } germanEntTypeHandler() { this.buttonfactory('start-entity', 'Entity Type=' + this.elements.germanEntType.value, ''); this.elements.entity.innerHTML = 'End Entity'; this.hideEverything(); this.elements.entityAnyType = false; } emptyEntityButton() { this.buttonfactory('start-empty-entity', 'Entity Start', ''); this.elements.entity.innerHTML = 'End Entity'; this.hideEverything(); this.elements.entityAnyType = true; } addTextAnnotation() { this.hideEverything(); this.elements.textAnnotationBuilder.classList.remove("hide"); } textAnnotationSubmitHandler() { let queryText = ':: match.text_' + this.elements.textAnnotationOptions.value + '="' + this.elements.textAnnotationInput.value + '"'; this.buttonfactory('text-annotation', this.elements.textAnnotationOptions.value + '= ' + this.elements.textAnnotationInput.value, queryText); this.elements.insertQueryButton.classList.remove("disabled"); this.elements.counter+=1; this.hideEverything(); this.elements.textAnnotationInput.value = ''; } //#endregion Structural Attribute Builder Functions //#region Token Attribute Builder Functions emptyTokenHandler() { this.hideEverything(); this.elements.incidenceModifiers.classList.remove('hide'); this.tokenButtonfactory('emptyToken', 'empty token', '[]'); this.buttonDisabler('empty'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } wordBuilder() { this.elements.incidenceModifiers.classList.add('hide'); this.hideEverything(); this.elements.wordBuilder.classList.remove("hide"); this.elements.inputOptions.classList.remove("hide"); this.elements.ignoreCaseCheckbox.classList.remove("hide"); this.elements.incidenceModifiersTB.classList.remove('disabled'); } lemmaBuilder() { this.elements.incidenceModifiers.classList.add('hide'); this.hideEverything(); this.elements.lemmaBuilder.classList.remove("hide"); this.elements.inputOptions.classList.remove("hide"); this.elements.ignoreCaseCheckbox.classList.remove("hide"); this.elements.incidenceModifiersTB.classList.remove('disabled'); } inputOptionHandler(elem) { let input; if (this.elements.wordBuilder.classList.contains('hide') === false){ input = this.elements.wordInput; }else{ input = this.elements.lemmaInput; } if (elem === this.elements.optionGroup) { input.value += '( option1 | option2 )'; let firstIndex = input.value.indexOf('option1'); let lastIndex = firstIndex + 'option1'.length; input.focus(); input.setSelectionRange(firstIndex, lastIndex); }else if (elem === this.elements.wildcardChar){ input.value += '.'; } } textSubmit() { this.buttonDisabler(); this.elements.incidenceModifiers.classList.remove("disabled"); let c; if (this.elements.ignoreCase.checked){ c = ' %c'; }else{ c = ''; } if (this.elements.wordBuilder.classList.contains('hide') === false){ this.tokenButtonfactory('word', 'word=' + this.elements.wordInput.value + c, 'word="'+ this.elements.wordInput.value + '"' + c ); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; this.elements.wordInput.value = ''; }else if (this.elements.lemmaBuilder.classList.contains('hide') === false){ this.tokenButtonfactory('lemma', 'lemma=' + this.elements.lemmaInput.value + c, 'lemma="'+ this.elements.lemmaInput.value + '"' + c); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; this.elements.lemmaInput.value = ''; } } posBuilder() { this.hideEverything(); this.elements.incidenceModifiers.classList.remove('hide'); this.elements.positionalAttr.appendChild(this.elements.incidenceModifiers); this.elements.posBuilder.classList.remove("hide"); } englishPosHandler() { this.buttonDisabler(); this.tokenButtonfactory('pos', 'pos=' + this.elements.englishPos.value, 'pos="' + this.elements.englishPos.value + '"'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } germanPosHandler() { this.buttonDisabler(); this.tokenButtonfactory('pos', 'pos=' + this.elements.germanPos.value, 'pos="' + this.elements.germanPos.value + '"'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } simplePosBuilder() { this.hideEverything(); this.elements.incidenceModifiers.classList.remove('hide'); this.elements.positionalAttr.appendChild(this.elements.incidenceModifiers); this.elements.simplePosBuilder.classList.remove("hide"); } simplePosHandler() { this.buttonDisabler(); this.tokenButtonfactory('simplePos', 'simple_pos=' + this.elements.simplePos.value, 'simple_pos="' + this.elements.simplePos.value + '"'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } incidenceModifiersHandler(input) { this.tokenButtonfactory('incidenceModifier', input.text, input.dataset.token); this.elements.incidenceModifiers.classList.add("disabled"); this.elements.tokenCounter+=1; } nSubmitHandler() { this.tokenButtonfactory('exactlyN', 'Exactly ' + this.elements.nInput.value, '{' + this.elements.nInput.value + '}'); let instance = M.Modal.getInstance(this.elements.exactlyN); instance.close(); this.elements.incidenceModifiers.classList.add('disabled'); } nmSubmitHandler() { this.tokenButtonfactory('betweenNM', 'Between ' + this.elements.nmInput.value + ' and ' + this.elements.mInput.value, '{' + this.elements.nmInput.value + ',' + this.elements.mInput.value + '}'); let instance = M.Modal.getInstance(this.elements.betweenNM); instance.close(); this.elements.incidenceModifiers.classList.add('disabled'); } // TB = Text Builder incidenceModifiersHandlerTB(elem) { let input; if (this.elements.wordBuilder.classList.contains('hide') === false){ input = this.elements.wordInput; }else{ input = this.elements.lemmaInput; } if (elem.id === 'exactly-n-tb'){ input.value += elem.dataset.token; let index = input.value.lastIndexOf('{n}'); let instance = M.Dropdown.getInstance(this.elements.incidenceModifiersTB); instance.close(); input.focus(); input.setSelectionRange(index+1, index+2); }else if (elem.id === 'between-n-m-tb') { input.value += elem.dataset.token; let index = input.value.lastIndexOf('{n,m}'); let instance = M.Dropdown.getInstance(this.elements.incidenceModifiersTB); instance.close(); input.focus(); input.setSelectionRange(index+1, index+2); }else { input.value += ' ' + elem.dataset.token; } this.elements.incidenceModifiersTB.classList.add('disabled'); } orHandler() { this.elements.positionalAttr.appendChild(this.elements.incidenceModifiers); this.buttonDisabler('condition'); this.hideEverything(); this.tokenButtonfactory('or', 'or', '|'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } andHandler() { this.elements.positionalAttr.appendChild(this.elements.incidenceModifiers); this.buttonDisabler('condition'); this.hideEverything(); this.tokenButtonfactory('and', 'and', '&'); this.elements.buildTokenButton.classList.remove("disabled"); this.elements.tokenCounter+=1; } hideEverything(){ this.elements.wordBuilder.classList.add("hide"); this.elements.lemmaBuilder.classList.add("hide"); this.elements.ignoreCaseCheckbox.classList.add("hide"); this.elements.inputOptions.classList.add("hide"); this.elements.posBuilder.classList.add("hide"); this.elements.simplePosBuilder.classList.add("hide"); this.elements.entityBuilder.classList.add("hide"); this.elements.textAnnotationBuilder.classList.add("hide"); } buttonDisabler(attr = 'token') { let tokenButtonList = this.elements.positionalAttr.querySelectorAll("a"); if (attr === 'start'){ tokenButtonList.forEach(element => { if (element.id === 'or'){ element.classList.add("disabled"); } else if (element.id === 'and'){ element.classList.add("disabled"); }else if (element.dataset.target == 'incidence-modifiers') { element.classList.add("disabled"); } else if (element.id === 'empty-token'){ element.classList.remove("disabled"); } else { element.classList.remove("disabled"); } }); }else if (attr === 'condition'){ tokenButtonList.forEach(element => { if (element.id === 'or'){ element.classList.add("disabled"); } else if (element.id === 'and'){ element.classList.add("disabled"); }else if (element.dataset.target == 'incidence-modifiers') { element.classList.add("disabled"); } else if (element.id === 'empty-token'){ element.classList.add("disabled"); } else { element.classList.remove("disabled"); } }); }else if (attr === 'empty') { tokenButtonList.forEach(element => { if (element.id == 'or'){ element.classList.add("disabled"); } else if (element.id == 'and'){ element.classList.add("disabled"); }else if (element.dataset.target == 'incidence-modifiers') { element.classList.remove("disabled"); } else { element.classList.add("disabled"); } }); }else{ tokenButtonList.forEach(element => { if (element.id == 'or'){ element.classList.remove("disabled"); } else if (element.id == 'and'){ element.classList.remove("disabled"); }else if (element.dataset.target == 'incidence-modifiers') { element.classList.remove("disabled"); } else { element.classList.add("disabled"); } }); } } tokenButtonfactory(dataType, prettyText, tokenText) { tokenText = encodeURI(tokenText); this.elements.buttonPreparer.innerHTML += '' + prettyText + ''; let tokenDummyButton = this.elements.buttonPreparer.querySelector(':first-child'); tokenDummyButton.addEventListener("click", () => {this.deleteTokenAttr(tokenDummyButton);}); this.elements.tokenQuery.appendChild(tokenDummyButton); } deleteTokenAttr(attr){ let nodesList = attr.parentElement.childNodes; let indexOfAttr; for (let i = 0; i < nodesList.length; i++) { if(nodesList[i] === attr){ indexOfAttr = i; } } if(indexOfAttr>0){ if (attr.dataset.type === 'or' || attr.dataset.type === 'and') { this.elements.tokenQuery.removeChild(nodesList[indexOfAttr+1]); this.elements.tokenCounter-=1; }else { if (nodesList[indexOfAttr-1].dataset.type === 'or' || nodesList[indexOfAttr-1].dataset.type === 'and'){ this.elements.tokenQuery.removeChild(nodesList[indexOfAttr-1]) this.elements.tokenCounter-=1; } } } this.elements.tokenQuery.removeChild(attr); this.elements.tokenCounter-=1; if(this.elements.tokenCounter === 0){ this.elements.buildTokenButton.classList.add("disabled"); this.buttonDisabler('start'); this.hideEverything(); } } addToken() { let tokenQueryContent = ''; let tokenQueryText = ''; let emptyTokenCheck = false; for (let element of this.elements.tokenQuery.childNodes) { tokenQueryContent += ' ' + element.text + ' '; tokenQueryText += ' ' + decodeURI(element.dataset.tokentext); if (element.dataset.type === "emptyToken"){ emptyTokenCheck = true; } } if (emptyTokenCheck === false){ tokenQueryText = '[' + tokenQueryText + ']'; } this.buttonfactory('token', tokenQueryContent, tokenQueryText); tokenQueryContent = ''; this.elements.tokenQuery.innerHTML = ''; this.elements.tokenCounter = 0; this.elements.buildTokenButton.classList.add("disabled"); this.hideEverything(); this.buttonDisabler('start'); this.elements.insertQueryButton.classList.remove("disabled"); this.elements.counter += 1; } //#endregion Token Attribute Builder Functions //#region General Functions buttonfactory(dataType, prettyText, queryText) { queryText = encodeURI(queryText); this.elements.buttonPreparer.innerHTML += '' + prettyText + ''; let dummyButton = this.elements.buttonPreparer.querySelector(':first-child'); dummyButton.addEventListener("click", () => {this.deleteAttr(dummyButton);}); this.elements.yourQuery.appendChild(dummyButton); } deleteAttr(attr) { let siblingList = []; let nodesList = attr.parentElement.childNodes; let indexOfAttr; let connectedElement; // Why nodesList.indexOf(attr) doesn"t work?! for (let i = 0; i < nodesList.length; i++) { if(nodesList[i] === attr){ indexOfAttr = i; } } switch (attr.dataset.type) { case 'start-sentence': for (let i = indexOfAttr; i < nodesList.length; i++) { if (nodesList[i].dataset.type === 'end-sentence'){ siblingList.push(nodesList[i]); } } connectedElement = siblingList[0]; if (connectedElement === undefined){ this.elements.sentence.innerHTML = 'Sentence'; } break; case 'end-sentence': for (let i = 0; i < indexOfAttr; i++) { if (nodesList[i].dataset.type === 'start-sentence'){ siblingList.push(nodesList[i]); } } connectedElement = siblingList[siblingList.length -1]; break; case 'start-entity': for (let i = indexOfAttr; i < nodesList.length; i++) { if (nodesList[i].dataset.type === 'end-entity'){ siblingList.push(nodesList[i]); } } connectedElement = siblingList[0]; if (connectedElement === undefined){ this.elements.entity.innerHTML = 'Entity'; } break; case 'end-entity': for (let i = 0; i < indexOfAttr; i++) { if (nodesList[i].dataset.type === 'start-entity'){ siblingList.push(nodesList[i]); } } connectedElement = siblingList[siblingList.length -1]; break; default: connectedElement = undefined; break; } if (connectedElement !== undefined ){ this.elements.yourQuery.removeChild(connectedElement); } this.elements.yourQuery.removeChild(attr); this.elements.counter -= 1; if(this.elements.counter === 0){ this.elements.insertQueryButton.classList.add("disabled"); } } insertQuery() { this.elements.yourQueryContent = []; for (let element of this.elements.yourQuery.childNodes) { let queryElement = decodeURI(element.dataset.query); this.elements.yourQueryContent.push(queryElement); } let queryString = this.elements.yourQueryContent.join(' '); queryString += ";"; this.elements.concordanceQueryBuilder.classList.add('modal-close'); this.elements.extFormQuery.value = queryString; } clearAll() { this.elements.tokenQuery.innerHTML = ''; this.elements.tokenCounter = 0; this.elements.counter = 0; this.elements.buildTokenButton.classList.add("disabled"); this.elements.insertQueryButton.classList.add("disabled"); this.elements.concordanceQueryBuilder.classList.remove('modal-close'); this.hideEverything(); this.buttonDisabler('start'); this.elements.yourQuery.innerHTML = ''; } //#endregion General Functions }