Compare commits

...

4 Commits

Author SHA1 Message Date
Inga Kirschnick
8a5c94f448 Bug fix 2023-08-11 14:38:18 +02:00
Inga Kirschnick
3d38e550a0 Update Positional Attribute Modal Query Builder 2023-08-11 13:55:41 +02:00
Patrick Jentsch
1387d80a26 Update cqi utils 2023-08-11 13:50:56 +02:00
Patrick Jentsch
5c00c5740e upgrade cqi to 0.1.6 2023-08-11 10:49:40 +02:00
10 changed files with 230 additions and 211 deletions

View File

@ -9,8 +9,7 @@ def lookups_by_cpos(corpus: CQiCorpus, cpos_list: List[int]) -> Dict:
for attr in corpus.positional_attributes.list(): for attr in corpus.positional_attributes.list():
cpos_attr_values: List[str] = attr.values_by_cpos(cpos_list) cpos_attr_values: List[str] = attr.values_by_cpos(cpos_list)
for i, cpos in enumerate(cpos_list): for i, cpos in enumerate(cpos_list):
lookups['cpos_lookup'][cpos][attr.attrs['name']] = \ lookups['cpos_lookup'][cpos][attr.name] = cpos_attr_values[i]
cpos_attr_values[i]
for attr in corpus.structural_attributes.list(): for attr in corpus.structural_attributes.list():
# We only want to iterate over non subattributes, identifiable by # We only want to iterate over non subattributes, identifiable by
# attr.has_values == False # attr.has_values == False
@ -20,19 +19,19 @@ def lookups_by_cpos(corpus: CQiCorpus, cpos_list: List[int]) -> Dict:
for i, cpos in enumerate(cpos_list): for i, cpos in enumerate(cpos_list):
if cpos_attr_ids[i] == -1: if cpos_attr_ids[i] == -1:
continue continue
lookups['cpos_lookup'][cpos][attr.attrs['name']] = cpos_attr_ids[i] lookups['cpos_lookup'][cpos][attr.name] = cpos_attr_ids[i]
occured_attr_ids = [x for x in set(cpos_attr_ids) if x != -1] occured_attr_ids = [x for x in set(cpos_attr_ids) if x != -1]
if not occured_attr_ids: if len(occured_attr_ids) == 0:
continue continue
subattrs = corpus.structural_attributes.list(filters={'part_of': attr}) subattrs = corpus.structural_attributes.list(filters={'part_of': attr})
if not subattrs: if len(subattrs) == 0:
continue continue
lookup_name: str = f'{attr.attrs["name"]}_lookup' lookup_name: str = f'{attr.name}_lookup'
lookups[lookup_name] = {} lookups[lookup_name] = {}
for attr_id in occured_attr_ids: for attr_id in occured_attr_ids:
lookups[lookup_name][attr_id] = {} lookups[lookup_name][attr_id] = {}
for subattr in subattrs: for subattr in subattrs:
subattr_name = subattr.attrs['name'][(len(attr.attrs['name']) + 1):] # noqa subattr_name = subattr.name[(len(attr.name) + 1):] # noqa
for i, subattr_value in enumerate(subattr.values_by_ids(occured_attr_ids)): # noqa for i, subattr_value in enumerate(subattr.values_by_ids(occured_attr_ids)): # noqa
lookups[lookup_name][occured_attr_ids[i]][subattr_name] = subattr_value # noqa lookups[lookup_name][occured_attr_ids[i]][subattr_name] = subattr_value # noqa
return lookups return lookups

View File

@ -75,16 +75,20 @@
color: black; color: black;
} }
#corpus-analysis-concordance-incidence-modifiers-button a{ [data-toggle-area="input-field-options"] a {
background-color: #2FBBAB; margin-right: 10px;
}
#corpus-analysis-concordance-ignore-case-checkbox {
margin-left: 5px;
} }
#corpus-analysis-concordance-incidence-modifiers-dropdown a{ #corpus-analysis-concordance-incidence-modifiers-dropdown a{
background-color: white; background-color: white;
} }
#corpus-analysis-concordance-ignore-case-checkbox { [data-target="corpus-analysis-concordance-incidence-modifiers-dropdown"] {
margin-left: 5px; background-color: #2FBBAB;
} }
#corpus-analysis-concordance-or, #corpus-analysis-concordance-and { #corpus-analysis-concordance-or, #corpus-analysis-concordance-and {

View File

@ -93,7 +93,6 @@ class CorpusAnalysisApp {
actionElement.disabled = true; actionElement.disabled = true;
break; break;
case 'SELECT': case 'SELECT':
console.log(actionElement);
actionElement.parentNode.querySelector('input.select-dropdown').disabled = true; actionElement.parentNode.querySelector('input.select-dropdown').disabled = true;
break; break;
default: default:

View File

@ -32,7 +32,9 @@ class CorpusAnalysisConcordance {
async submitForm() { async submitForm() {
this.app.disableActionElements(); this.app.disableActionElements();
let query = this.elements.form.query.value.trim(); // let query = this.elements.form.query.value.trim();
let query = this.checkQueryInput();
console.log(query);
let subcorpusName = this.elements.form['subcorpus-name'].value; let subcorpusName = this.elements.form['subcorpus-name'].value;
this.elements.error.innerText = ''; this.elements.error.innerText = '';
this.elements.error.classList.add('hide'); this.elements.error.classList.add('hide');
@ -78,10 +80,7 @@ class CorpusAnalysisConcordance {
}); });
this.elements.userInterfaceForm.addEventListener('change', (event) => { this.elements.userInterfaceForm.addEventListener('change', (event) => {
if (event.target === this.elements.userInterfaceForm['context']) { if (event.target === this.elements.userInterfaceForm['context']) {
console.log(this.settings.context);
console.log(parseInt(this.elements.userInterfaceForm['context'].value));
this.settings.context = parseInt(this.elements.userInterfaceForm['context'].value); this.settings.context = parseInt(this.elements.userInterfaceForm['context'].value);
console.log(this.settings.context);
this.submitForm(); this.submitForm();
} }
if (event.target === this.elements.userInterfaceForm['per-page']) { if (event.target === this.elements.userInterfaceForm['per-page']) {
@ -99,6 +98,14 @@ class CorpusAnalysisConcordance {
}); });
} }
checkQueryInput() {
if (document.querySelector('#corpus-analysis-concordance-expert-mode-display').classList.contains('hide')) {
return document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim();
} else {
return this.elements.form.query.value.trim();
}
}
clearSubcorpusList() { clearSubcorpusList() {
this.elements.subcorpusList.innerHTML = ''; this.elements.subcorpusList.innerHTML = '';
this.elements.subcorpusList.classList.add('hide'); this.elements.subcorpusList.classList.add('hide');

View File

@ -4,32 +4,42 @@ class ConcordanceQueryBuilder {
this.elements = new ElementReferencesQueryBuilder(); this.elements = new ElementReferencesQueryBuilder();
this.generalFunctions = new GeneralFunctionsQueryBuilder(this.elements); this.generalFunctions = new GeneralFunctionsQueryBuilder(this.elements);
this.tokenAttributeBuilder = new TokenAttributeBuilderFunctionsQueryBuilder(this.elements); this.tokenAttributeBuilderFunctions = new TokenAttributeBuilderFunctionsQueryBuilder(this.elements);
this.structuralAttributeBuilder = new StructuralAttributeBuilderFunctionsQueryBuilder(this.elements); this.structuralAttributeBuilderFunctions = new StructuralAttributeBuilderFunctionsQueryBuilder(this.elements);
// Event listener for structural attribute modal // Event listener for structural attribute modal
document.querySelectorAll('[data-structural-attr-modal-action-button]').forEach(button => { document.querySelectorAll('[data-structural-attr-modal-action-button]').forEach(button => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
this.structuralAttributeBuilder.actionButtonHandler(button.dataset.structuralAttrModalActionButton); this.structuralAttributeBuilderFunctions.actionButtonInStrucAttrModalHandler(button.dataset.structuralAttrModalActionButton);
}); });
}); });
// Event listener for token attribute modal // Event listener for token attribute modal
this.elements.positionalAttrSelection.addEventListener('change', (event) => { this.elements.positionalAttrSelection.addEventListener('change', (event) => {
this.generalFunctions.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add'); this.generalFunctions.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
if (event.target.value !== 'empty-token') {
this.generalFunctions.toggleClass([event.target.value], 'hide', 'remove'); this.generalFunctions.toggleClass([event.target.value], 'hide', 'remove');
this.generalFunctions.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add'); this.generalFunctions.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
this.tokenAttributeBuilderFunctions.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
}
if (event.target.value === 'word' || event.target.value === 'lemma') {
this.generalFunctions.toggleClass(['input-field-options'], 'hide', 'remove');
} else if (event.target.value === 'empty-token'){
this.tokenAttributeBuilderFunctions.addTokenToQuery();
} else {
this.generalFunctions.toggleClass(['input-field-options'], 'hide', 'add');
}
}); });
// Options for positional attribute selection // Options for positional attribute selection
document.querySelectorAll('.positional-attr-options-action-button[data-options-action]').forEach(button => { document.querySelectorAll('.positional-attr-options-action-button[data-options-action]').forEach(button => {
button.addEventListener('click', () => {this.tokenAttributeBuilder.actionButtonHandler(button.dataset.optionsAction);}); button.addEventListener('click', () => {this.tokenAttributeBuilderFunctions.actionButtonInOptionSectionHandler(button.dataset.optionsAction);});
}); });
document.querySelectorAll('.incidence-modifier-selection[data-incidence-modifier]').forEach(button => { document.querySelectorAll('.incidence-modifier-selection[data-incidence-modifier]').forEach(button => {
button.addEventListener('click', () => {this.tokenAttributeBuilder.incidenceModifierHandler(button);}); button.addEventListener('click', () => {this.tokenAttributeBuilderFunctions.incidenceModifierHandler(button);});
}); });
document.querySelectorAll('.n-m-submit-button').forEach(button => { document.querySelectorAll('.n-m-submit-button').forEach(button => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
this.tokenAttributeBuilder.nmSubmitHandler(button.dataset.modalId); this.tokenAttributeBuilderFunctions.nmSubmitHandler(button.dataset.modalId);
}); });
}); });
@ -46,7 +56,7 @@ class ConcordanceQueryBuilder {
document.querySelector('#corpus-analysis-concordance-positional-attr-modal'), document.querySelector('#corpus-analysis-concordance-positional-attr-modal'),
{ {
onOpenStart: () => { onOpenStart: () => {
this.tokenAttributeBuilder.optionToggleHandler(); this.tokenAttributeBuilderFunctions.optionToggleHandler();
} }
} }
); );

View File

@ -22,25 +22,35 @@ class GeneralFunctionsQueryBuilder {
queryChipElement.setAttribute('data-query', queryText); queryChipElement.setAttribute('data-query', queryText);
queryChipElement.setAttribute('draggable', 'true'); queryChipElement.setAttribute('draggable', 'true');
queryChipElement.addEventListener('click', () => {this.deleteAttr(queryChipElement);}); queryChipElement.addEventListener('click', () => this.deleteAttr(queryChipElement));
queryChipElement.addEventListener('dragstart', (event) => { queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement));
// selects all nodes without target class queryChipElement.addEventListener('dragend', this.handleDragEnd);
let queryChips = this.elements.queryInputField.querySelectorAll('.query-component');
// Adds a target chip in front of all draggable childnodes this.queryPreviewBuilder();
}
handleDragStart(queryChipElement, event) {
let queryChips = this.elements.queryInputField.querySelectorAll('.query-component');
setTimeout(() => { setTimeout(() => {
let targetChipElement = Utils.HTMLToElement('<span class="chip drop-target">Drop here</span>'); let targetChipElement = Utils.HTMLToElement('<span class="chip drop-target">Drop here</span>');
for (let element of queryChips) { for (let element of queryChips) {
if (element === queryChipElement.nextSibling) {continue;} if (element === queryChipElement.nextSibling) {continue;}
let targetChipClone = targetChipElement.cloneNode(true); let targetChipClone = targetChipElement.cloneNode(true);
if (element === queryChipElement) { if (element === queryChipElement && queryChips[queryChips.length - 1] !== element) {
// If the dragged element is not at the very end, a target chip is also inserted at the end
if (queryChips[queryChips.length - 1] !== element) {
queryChips[queryChips.length - 1].insertAdjacentElement('afterend', targetChipClone); queryChips[queryChips.length - 1].insertAdjacentElement('afterend', targetChipClone);
}
} else { } else {
element.insertAdjacentElement('beforebegin', targetChipClone); element.insertAdjacentElement('beforebegin', targetChipClone);
} }
this.addDragDropListeners(targetChipClone, queryChipElement);
}
}, 0);
}
handleDragEnd(event) {
document.querySelectorAll('.drop-target').forEach(target => target.remove());
}
addDragDropListeners(targetChipClone, queryChipElement) {
targetChipClone.addEventListener('dragover', (event) => { targetChipClone.addEventListener('dragover', (event) => {
event.preventDefault(); event.preventDefault();
}); });
@ -55,43 +65,17 @@ class GeneralFunctionsQueryBuilder {
targetChipClone.addEventListener('drop', (event) => { targetChipClone.addEventListener('drop', (event) => {
let dropzone = event.target; let dropzone = event.target;
dropzone.parentElement.replaceChild(queryChipElement, dropzone); dropzone.parentElement.replaceChild(queryChipElement, dropzone);
this.elements.queryInputFieldInstance.$chips = Array.from(this.elements.queryInputField.querySelectorAll('.chip'));
this.queryPreviewBuilder(); this.queryPreviewBuilder();
}); });
} }
}, 0);
});
queryChipElement.addEventListener('dragend', (event) => {
let targets = document.querySelectorAll('.drop-target');
for (let target of targets) {
target.remove();
}
});
// Ensures that metadata is always at the end of the query:
// const lastChild = this.elements.queryInputFieldInstance.lastChild;
// const isLastChildTextAnnotation = lastChild && lastChild.dataset.type === 'text-annotation';
// console.log(isLastChildTextAnnotation);
// console.log(lastChild);
// if (!isLastChildTextAnnotation) {
// this.elements.queryInputFieldInstance.appendChild(queryChipElement);
// } else {
// this.elements.queryInputFieldInstance.insertBefore(queryChipElement, lastChild);
// }
this.queryPreviewBuilder();
// Shows a hint about possible functions for editing the query at the first added element in the query
// if (this.elements.queryInputFieldInstance.childNodes.length === 1) {
// app.flash('You can edit your query by deleting individual elements or moving them via drag and drop.');
// }
}
queryPreviewBuilder() { queryPreviewBuilder() {
let queryPreview = document.querySelector('#corpus-analysis-concordance-query-preview'); let queryPreview = document.querySelector('#corpus-analysis-concordance-query-preview');
let queryChipElements = Array.from(Object.values(this.elements.queryInputFieldInstance.$chips)); let queryChipElements = Array.from(Object.values(this.elements.queryInputFieldInstance.$chips));
if (!isNaN(queryChipElements[queryChipElements.length - 1])) {
queryChipElements.pop(); queryChipElements.pop();
}
this.elements.queryInputFieldContent = []; this.elements.queryInputFieldContent = [];
queryChipElements.forEach(element => { queryChipElements.forEach(element => {

View File

@ -4,7 +4,7 @@ class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQu
this.elements = elements; this.elements = elements;
} }
actionButtonHandler(action) { actionButtonInStrucAttrModalHandler(action) {
switch (action) { switch (action) {
case 'sentence': case 'sentence':
break; break;

View File

@ -6,24 +6,34 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
this.elements.tokenSubmitButton.addEventListener('click', () => {this.addTokenToQuery();}); this.elements.tokenSubmitButton.addEventListener('click', () => {this.addTokenToQuery();});
this.elements.wordInput.addEventListener('input', () => {this.optionToggleHandler();}); this.elements.wordInput.addEventListener('input', () => {this.optionToggleHandler();});
this.elements.lemmaInput.addEventListener('input', () => {this.optionToggleHandler();}); this.elements.lemmaInput.addEventListener('input', () => {this.optionToggleHandler();});
this.elements.englishPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
this.elements.germanPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
this.elements.simplePosSelection.addEventListener('change', () => {this.optionToggleHandler();});
} }
lemmaOrWordInputCheck() { tokenInputCheck() {
let input; let input;
if (document.querySelector('[data-toggle-area="word"]').classList.contains('hide') === false) { if (!document.querySelector('[data-toggle-area="word"]').classList.contains('hide')) {
input = this.elements.wordInput; input = this.elements.wordInput;
} else { } else if (!document.querySelector('[data-toggle-area="lemma"]').classList.contains('hide')){
input = this.elements.lemmaInput; input = this.elements.lemmaInput;
} else if (!document.querySelector('[data-toggle-area="english-pos"]').classList.contains('hide')){
input = this.elements.englishPosSelection;
} else if (!document.querySelector('[data-toggle-area="german-pos"]').classList.contains('hide')){
input = this.elements.germanPosSelection;
} else if (!document.querySelector('[data-toggle-area="simple-pos"]').classList.contains('hide')){
input = this.elements.simplePosSelection;
} }
return input; return input;
} }
optionToggleHandler() { optionToggleHandler() {
let input = this.lemmaOrWordInputCheck() let input;
input = this.tokenInputCheck();
if (input.value === '') { if (input.value === '' || input.value === 'default') {
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add'); this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
} else { } else {
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'remove'); this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'remove');
@ -58,17 +68,13 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
addTokenToQuery() { addTokenToQuery() {
let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : ''; let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
let tokenQueryContent = ''; let tokenQueryPrettyText = '';
let tokenQueryText = ''; let tokenQueryCQLText = '';
this.elements.isTokenQueryInvalid = false; this.elements.isTokenQueryInvalid = false;
let tokenIsEmpty = false;
this.elements.tokenQuery.childNodes.forEach(element => { this.elements.tokenQuery.childNodes.forEach(element => {
tokenQueryContent += ' ' + element.firstChild.data + ' '; tokenQueryPrettyText += ' ' + element.firstChild.data + ' ';
tokenQueryText += decodeURI(element.dataset.tokentext); tokenQueryCQLText += decodeURI(element.dataset.tokentext);
if (element.innerText.indexOf('empty token') !== -1) {
tokenIsEmpty = true;
}
}); });
switch (this.elements.positionalAttrSelection.value) { switch (this.elements.positionalAttrSelection.value) {
@ -76,8 +82,8 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
if (this.elements.wordInput.value === '') { if (this.elements.wordInput.value === '') {
this.disableTokenSubmit(); this.disableTokenSubmit();
} else { } else {
tokenQueryContent += `word=${this.elements.wordInput.value}${c}`; tokenQueryPrettyText += `word=${this.elements.wordInput.value}${c}`;
tokenQueryText += `word="${this.elements.wordInput.value}"${c}`; tokenQueryCQLText += `word="${this.elements.wordInput.value}"${c}`;
this.elements.wordInput.value = ''; this.elements.wordInput.value = '';
} }
break; break;
@ -85,17 +91,17 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
if (this.elements.lemmaInput.value === '') { if (this.elements.lemmaInput.value === '') {
this.disableTokenSubmit(); this.disableTokenSubmit();
} else { } else {
tokenQueryContent += `lemma=${this.elements.lemmaInput.value}${c}`; tokenQueryPrettyText += `lemma=${this.elements.lemmaInput.value}${c}`;
tokenQueryText += `lemma="${this.elements.lemmaInput.value}"${c}`; tokenQueryCQLText += `lemma="${this.elements.lemmaInput.value}"${c}`;
this.elements.lemmaInput.value = ''; this.elements.lemmaInput.value = '';
} }
break; break;
case 'english-pos': case 'english-pos':
if (this.elements.englishPos.value === 'default') { if (this.elements.englishPosSelection.value === 'default') {
this.disableTokenSubmit(); this.disableTokenSubmit();
} else { } else {
tokenQueryContent += `pos=${this.elements.englishPosSelection.value}`; tokenQueryPrettyText += `pos=${this.elements.englishPosSelection.value}`;
tokenQueryText += `pos="${this.elements.englishPosSelection.value}"`; tokenQueryCQLText += `pos="${this.elements.englishPosSelection.value}"`;
this.elements.englishPosSelection.value = ''; this.elements.englishPosSelection.value = '';
} }
break; break;
@ -103,8 +109,8 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
if (this.elements.germanPosSelection.value === 'default') { if (this.elements.germanPosSelection.value === 'default') {
this.disableTokenSubmit(); this.disableTokenSubmit();
} else { } else {
tokenQueryContent += `pos=${this.elements.germanPosSelection.value}`; tokenQueryPrettyText += `pos=${this.elements.germanPosSelection.value}`;
tokenQueryText += `pos="${this.elements.germanPosSelection.value}"`; tokenQueryCQLText += `pos="${this.elements.germanPosSelection.value}"`;
this.elements.germanPosSelection.value = ''; this.elements.germanPosSelection.value = '';
} }
break; break;
@ -112,53 +118,28 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
if (this.elements.simplePosSelection.value === 'default') { if (this.elements.simplePosSelection.value === 'default') {
this.disableTokenSubmit(); this.disableTokenSubmit();
} else { } else {
tokenQueryContent += `simple_pos=${this.elements.simplePosSelection.value}`; tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
tokenQueryText += `simple_pos="${this.elements.simplePosSelection.value}"`; tokenQueryCQLText += `simple_pos="${this.elements.simplePosSelection.value}"`;
this.elements.simplePosSelection.value = ''; this.elements.simplePosSelection.value = '';
} }
break; break;
case 'empty-token':
tokenQueryPrettyText += 'empty token';
default: default:
break; break;
} }
// isTokenQueryInvalid looks if a valid value is passed. If the input fields/dropdowns are empty (isTokenQueryInvalid === true), no token is added. // isTokenQueryInvalid looks if a valid value is passed. If the input fields/dropdowns are empty (isTokenQueryInvalid === true), no token is added.
if (this.elements.isTokenQueryInvalid === false) { if (this.elements.isTokenQueryInvalid === false) {
// Square brackets are added only if it is not an empty token (where they are already present). tokenQueryCQLText = '[' + tokenQueryCQLText + ']';
if (tokenIsEmpty === false) { this.queryChipFactory('token', tokenQueryPrettyText, tokenQueryCQLText);
tokenQueryText = '[' + tokenQueryText + ']';
}
this.queryChipFactory('token', tokenQueryContent, tokenQueryText);
this.resetPositionalAttrModal(); this.resetPositionalAttrModal();
this.elements.positionalAttrModal.close(); this.elements.positionalAttrModal.close();
} }
} }
resetPositionalAttrModal() { actionButtonInOptionSectionHandler(elem) {
let originalSelectionList = let input = this.tokenInputCheck();
`
<option value="word" selected>word</option>
<option value="lemma" >lemma</option>
<option value="english-pos">english pos</option>
<option value="german-pos">german pos</option>
<option value="simple-pos">simple_pos</option>
<option value="empty-token">empty token</option>
`;
document.querySelector('#corpus-analysis-concordance-positional-attr-selection').innerHTML = originalSelectionList;
this.elements.tokenQuery.innerHTML = '';
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
this.toggleClass(['word'], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
document.querySelector(`#corpus-analysis-concordance-positional-attr-selection option[value="word"]`).selected = true;
let instance = M.FormSelect.getInstance(document.getElementById('positional-attr-selection'));
instance.destroy();
M.FormSelect.init(document.getElementById('positional-attr-selection'));
}
actionButtonHandler(elem) {
let input = this.lemmaOrWordInputCheck();
switch (elem) { switch (elem) {
case 'option-group': case 'option-group':
input.value += '(option1|option2)'; input.value += '(option1|option2)';
@ -189,31 +170,32 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
this.tokenChipFactory(elem.innerText, elem.dataset.token); this.tokenChipFactory(elem.innerText, elem.dataset.token);
break; break;
case 'english-pos': case 'english-pos':
this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`); this.tokenChipFactory(`pos=${this.elements.englishPosSelection.value}`, `pos="${this.elements.englishPosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token); this.tokenChipFactory(elem.innerText, elem.dataset.token);
this.elements.tokenQueryFilled = true;
break; break;
case 'german-pos': case 'german-pos':
this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`); this.tokenChipFactory(`pos=${this.elements.germanPosSelection.value}`, `pos="${this.elements.germanPosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token); this.tokenChipFactory(elem.innerText, elem.dataset.token);
this.elements.tokenQueryFilled = true;
break; break;
case 'simple-pos': case 'simple-pos':
this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`); this.tokenChipFactory(`simple_pos=${this.elements.simplePosSelection.value}`, `simple_pos="${this.elements.simplePosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token); this.tokenChipFactory(elem.innerText, elem.dataset.token);
this.elements.tokenQueryFilled = true;
break; break;
default: default:
let input = this.lemmaOrWordInputCheck(); let input = this.tokenInputCheck();
input.value += elem.dataset.token; input.value += elem.dataset.token;
break; break;
} }
if (this.elements.positionalAttrSelection.value !== "word" && this.elements.positionalAttrSelection.value !== "lemma") {
this.toggleClass([this.elements.positionalAttrSelection.value], "hide", "add");
}
} }
nmSubmitHandler(modalId) { nmSubmitHandler(modalId) {
let modal = document.querySelector(`#${modalId}`); let modal = document.querySelector(`#${modalId}`);
let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value; let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value;
let input_m = modalId === 'between-nm-modal' ? ',' + modal.querySelector('.n-m-input[data-value-type="m"]').value : ''; let input_m = modalId === 'corpus-analysis-concordance-between-nm-modal' ? ',' + modal.querySelector('.n-m-input[data-value-type="m"]').value : '';
let input = `${input_n}${input_m}`; let input = `${input_n}${input_m}`;
let instance = M.Modal.getInstance(modal); let instance = M.Modal.getInstance(modal);
@ -232,69 +214,107 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
} }
conditionHandler(conditionText, conditionQueryContent) { conditionHandler(conditionText, conditionQueryContent) {
let tokenQueryContent; let tokenQueryPrettyText;
let tokenQueryText; let tokenQueryCQLText;
let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : ''; let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
let selectionDefault = "word";
let optionDeleteList = [];
switch (this.elements.positionalAttrSelection.value) { switch (this.elements.positionalAttrSelection.value) {
case 'word': case 'word':
tokenQueryContent = `word=${this.elements.wordInput.value}${c}`; tokenQueryPrettyText = `word=${this.elements.wordInput.value}${c}`;
tokenQueryText = `word="${this.elements.wordInput.value}"${c}`; tokenQueryCQLText = `word="${this.elements.wordInput.value}"${c}`;
this.elements.wordInput.value = ''; this.elements.wordInput.value = '';
if (conditionText === 'and') {
selectionDefault = "english-pos";
optionDeleteList = ['word', 'lemma', 'empty-token'];
}
break; break;
case 'lemma': case 'lemma':
tokenQueryContent = `lemma=${this.elements.lemmaInput.value}${c}`; tokenQueryPrettyText = `lemma=${this.elements.lemmaInput.value}${c}`;
tokenQueryText = `lemma="${this.elements.lemmaInput.value}"${c}`; tokenQueryCQLText = `lemma="${this.elements.lemmaInput.value}"${c}`;
this.elements.lemmaInput.value = ''; this.elements.lemmaInput.value = '';
if (conditionText === 'and') {
selectionDefault = "english-pos";
optionDeleteList = ['word', 'lemma', 'empty-token'];
}
break; break;
case 'english-pos': case 'english-pos':
tokenQueryContent = `pos=${this.elements.englishPos.value}`; tokenQueryPrettyText = `pos=${this.elements.englishPosSelection.value}`;
tokenQueryText = `pos="${this.elements.englishPos.value}"`; tokenQueryCQLText = `pos="${this.elements.englishPosSelection.value}"`;
this.elements.englishPos.value = ''; this.elements.englishPosSelection.value = '';
break; break;
case 'german-pos': case 'german-pos':
tokenQueryContent = `pos=${this.elements.germanPos.value}`; tokenQueryPrettyText = `pos=${this.elements.germanPosSelection.value}`;
tokenQueryText = `pos="${this.elements.germanPos.value}"`; tokenQueryCQLText = `pos="${this.elements.germanPosSelection.value}"`;
this.elements.germanPos.value = ''; this.elements.germanPosSelection.value = '';
break; break;
case 'simple-pos': case 'simple-pos':
tokenQueryContent = `simple_pos=${this.elements.simplePos.value}`; tokenQueryPrettyText = `simple_pos=${this.elements.simplePosSelection.value}`;
tokenQueryText = `simple_pos="${this.elements.simplePos.value}"`; tokenQueryCQLText = `simple_pos="${this.elements.simplePosSelection.value}"`;
this.elements.simplePos.value = ''; this.elements.simplePosSelection.value = '';
break; break;
default: default:
break; break;
} }
this.tokenChipFactory(tokenQueryContent, tokenQueryText); // Deleting the options which do not make sense in the context of the condition like "word" AND "word". Also sets selection default.
let selectionDefault = "word";
let optionDeleteList = ['empty-token'];
if (conditionText === 'and') {
if (this.elements.positionalAttrSelection.value === 'word' || this.elements.positionalAttrSelection.value === 'lemma') {
selectionDefault = "english-pos";
optionDeleteList.push('word', 'lemma');
} else if (this.elements.positionalAttrSelection.value === 'english-pos' || this.elements.positionalAttrSelection.value === 'german-pos') {
optionDeleteList.push('english-pos', 'german-pos');
} else {
optionDeleteList.push('simple-pos');
}
}
this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
this.tokenChipFactory(tokenQueryPrettyText, tokenQueryCQLText);
this.tokenChipFactory(conditionText, conditionQueryContent); this.tokenChipFactory(conditionText, conditionQueryContent);
this.setTokenSelection(selectionDefault, optionDeleteList); this.setTokenSelection(selectionDefault, optionDeleteList);
} }
setTokenSelection(selection, optionDeleteList) { setTokenSelection(selection, optionDeleteList) {
optionDeleteList.forEach(option => { optionDeleteList.forEach(option => {
document.querySelector(`#corpus-analysis-concordance-positional-attr-selection option[value=${option}]`).remove(); this.elements.positionalAttrSelection.querySelector(`option[value=${option}]`).remove();
}); });
document.querySelector(`#corpus-analysis-concordance-positional-attr-selection option[value=${selection}]`).selected = true; this.resetMaterializeSelection([this.elements.positionalAttrSelection], selection);
let instance = M.FormSelect.getInstance(document.getElementById('positional-attr-selection'));
instance.destroy();
M.FormSelect.init(document.getElementById('positional-attr-selection'));
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add'); this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
this.toggleClass([selection], 'hide', 'remove'); this.toggleClass([selection], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add'); this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
if (selection === "word" || selection === "lemma") {
this.toggleClass(['input-field-options'], 'hide', 'remove');
} else {
this.toggleClass(['input-field-options'], 'hide', 'add');
}
} }
resetPositionalAttrModal() {
let originalSelectionList =
`
<option value="word" selected>word</option>
<option value="lemma" >lemma</option>
<option value="english-pos">english pos</option>
<option value="german-pos">german pos</option>
<option value="simple-pos">simple_pos</option>
<option value="empty-token">empty token</option>
`;
this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
this.elements.tokenQuery.innerHTML = '';
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
this.toggleClass(['word', 'input-field-options'], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
document.querySelector('#corpus-analysis-concordance-positional-attr-selection option[value="word"]').selected = true;
this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
this.resetMaterializeSelection([this.elements.positionalAttrSelection], "word");
}
resetMaterializeSelection(selectionElements, value = "default") {
selectionElements.forEach(selectionElement => {
selectionElement.querySelector(`option[value=${value}]`).selected = true;
let instance = M.FormSelect.getInstance(selectionElement);
instance.destroy();
M.FormSelect.init(selectionElement);
})
}
} }

View File

@ -35,7 +35,7 @@
<div class="row"> <div class="row">
<div class="col s12 right-align"> <div class="col s12 right-align">
<p class="hide-on-small-only">&nbsp;</p> <p class="hide-on-small-only">&nbsp;</p>
<button class="btn waves-effect waves-light corpus-analysis-action" id="corpus-analysis-concordance-form-submit" type="submit" name="submit"> <button class="btn waves-effect waves-light corpus-analysis-action" type="submit" name="submit">
Send Send
<i class="material-icons right">send</i> <i class="material-icons right">send</i>
</button> </button>
@ -347,12 +347,20 @@
</div> </div>
<p></p> <p></p>
<div class="row"> <div class="row">
<div id="corpus-analysis-concordance-input-options" class="col s5 m5 l5 xl4"> <div class="col s6" data-toggle-area="input-field-options">
<a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-toggle-area="wildcard-char" data-options-action="wildcard-char" data-position="top" data-tooltip="Look for a variable character (also called wildcard character)">Wildcard character</a> <a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-options-action="wildcard-char" data-position="top" data-tooltip="Look for a variable character (also called wildcard character)">Wildcard character</a>
<a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-toggle-area="option-group" data-options-action="option-group" data-position="top" data-tooltip="Find character sequences from a list of options">Option Group</a> <a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-options-action="option-group" data-position="top" data-tooltip="Find character sequences from a list of options">Option Group</a>
</div>
<div class="col s3 m3 l3 xl3" id="corpus-analysis-concordance-incidence-modifiers-button">
<a class="dropdown-trigger btn-small waves-effect waves-light disabled" href="#" data-target="corpus-analysis-concordance-incidence-modifiers-dropdown" data-toggle-area="incidence-modifiers" data-position="top" data-tooltip="Incidence Modifiers are special characters or patterns, <br>which determine how often a character represented previously should occur.">incidence modifiers</a> <a class="dropdown-trigger btn-small waves-effect waves-light disabled" href="#" data-target="corpus-analysis-concordance-incidence-modifiers-dropdown" data-toggle-area="incidence-modifiers" data-position="top" data-tooltip="Incidence Modifiers are special characters or patterns, <br>which determine how often a character represented previously should occur.">incidence modifiers</a>
<span data-toggle-area="ignore-case-checkbox">
<label>
<input type="checkbox" class="filled-in" id="corpus-analysis-concordance-ignore-case-checkbox"/>
<span>Ignore Case</span>
</label>
</span>
</div>
<div class="col s2" data-toggle-area="condition-option-container">
<a class="btn-small tooltipped waves-effect waves-light disabled positional-attr-options-action-button" data-options-action="or" data-toggle-area="or" data-position="bottom" data-tooltip="You can add another condition to your token. <br>At least one must be fulfilled">or</a>
<a class="btn-small tooltipped waves-effect waves-light disabled positional-attr-options-action-button" data-options-action="and" data-toggle-area="and" data-position="bottom" data-tooltip="You can add another condition to your token. <br>Both must be fulfilled">and</a>
</div> </div>
<ul id="corpus-analysis-concordance-incidence-modifiers-dropdown" class="dropdown-content"> <ul id="corpus-analysis-concordance-incidence-modifiers-dropdown" class="dropdown-content">
@ -363,18 +371,6 @@
<li><a class="modal-trigger tooltipped" href="#corpus-analysis-concordance-between-nm-modal" data-position ="top" data-tooltip="...occurrences of the character/token before">between n and m ({n,m})</a></li> <li><a class="modal-trigger tooltipped" href="#corpus-analysis-concordance-between-nm-modal" data-position ="top" data-tooltip="...occurrences of the character/token before">between n and m ({n,m})</a></li>
</ul> </ul>
<div class="col s2 m2 l2 xl2">
<p>
<label>
<input type="checkbox" class="filled-in" data-toggle-area="ignore-case-checkbox" id="corpus-analysis-concordance-ignore-case-checkbox"/>
<span>Ignore Case</span>
</label>
</p>
</div>
<div class="col s2 m2 l2 xl2" id="corpus-analysis-concordance-condition-container">
<a class="btn-small tooltipped waves-effect waves-light disabled positional-attr-options-action-button" data-options-action="or" data-toggle-area="or" data-position="bottom" data-tooltip="You can add another condition to your token. <br>At least one must be fulfilled">or</a>
<a class="btn-small tooltipped waves-effect waves-light disabled positional-attr-options-action-button" data-options-action="and" data-toggle-area="and" data-position="bottom" data-tooltip="You can add another condition to your token. <br>Both must be fulfilled">and</a>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,5 @@
apifairy apifairy
cqi>=0.1.5 cqi>=0.1.6
dnspython==2.2.1 dnspython==2.2.1
docker docker
eventlet eventlet