// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later var mumi = (function () { const possibleTokens = [ { text: 'is:open' }, { text: 'is:pending' }, { text: 'is:done' }, { text: 'is:closed' }, { text: 'tag:confirmed' }, { text: 'tag:easy' }, { text: 'tag:fixed' }, { text: 'tag:help' }, { text: 'tag:moreinfo' }, { text: 'tag:notabug' }, { text: 'tag:patch' }, { text: 'tag:pending' }, { text: 'tag:security' }, { text: 'tag:unreproducible' }, { text: 'tag:wontfix' }, { text: 'severity:critical' }, { text: 'severity:grave' }, { text: 'severity:important' }, { text: 'severity:minor' }, { text: 'severity:normal' }, { text: 'severity:serious' }, { text: 'severity:wishlist' }, ]; const queryTokenizer = { [Symbol.split](str) { let phrase = false; let phrasePos = 0; let pos = 0; const result = []; while (pos < str.length) { let matchPos = str.substring(pos).search(/(\s|\")/); if (matchPos === -1) { result.push(str.substring(pos)); break; } matchPos += pos; let char = str.charAt(matchPos); let begin = pos; if (char === '"') { if (phrase) { /* finished phrase, record from beginning */ phrase = false; begin = phrasePos; matchPos += 1; } else { /* beginning phrase, remember position */ phrase = true; phrasePos = matchPos; } } /* don't push anything while inside a phrase */ if (!phrase) { result.push(str.substring(begin, matchPos)); } pos = matchPos + 1; } return result; }, }; var tokenizeText = function (input, options, tokenInput) { let items = input.value.split(queryTokenizer).filter(entry => entry.trim() != ''); let tokens = []; for (item of items) { if (possibleTokens.find(element => element.text == item)) { tokens.push({text: item}); } else { tokens.push(options.freeTextToken(item)); } } input.value = ""; var existing = tokenInput.getTokens () || []; tokenInput.setTokens(existing.concat(tokens)); }; var initTokenInput = function () { var inputElement = document.querySelector (".tokenInput input#query"); if (inputElement == null) { return; } var completionsForTextWithSuggestions = function (suggestions) { return function (text) { var completions = []; text = text.toLowerCase(); if (text.length) { suggestions.forEach(function (suggestion) { var suggestionText = suggestion.text.toLowerCase(); if (suggestionText.substr (0, text.length) == text) { completions.push (suggestion); } }, this); } return completions; }; }; var options = { freeTextEnabled: true, freeTextToken : function (text) { return { text: text, value: text, freeText: true, group: 'freeText' }; }, tokenFormatter: function (datum, element) { if (datum.freeText) { element.classList += " free-text"; } else { element.classList += " completed"; } }, completionsForText: completionsForTextWithSuggestions (possibleTokens), positionFloatingElement: function (element) { element.style.position = 'absolute'; element.style.display = 'inline-block'; element.style.left = '0px'; element.style.top = inputElement.offsetTop + inputElement.offsetHeight + 'px'; } }; tokenInput = new TokenInput (inputElement, options); window.tokenInputs = window.tokenInputs || []; window.tokenInputs.push (tokenInput); const form = document.querySelector ("form#search"); form.addEventListener ("submit", function (event) { event.preventDefault (); inputElement.value = tokenInput.getTokens().map(t => t.text).join(' '); inputElement.style.visibility = 'hidden'; form.submit (); }); /* tokenize existing input text */ if (inputElement.value.length > 0) { tokenizeText (inputElement, options, tokenInput); } inputElement.style.visibility = 'visible'; }; var setupLineHandler = function () { let lineClickHandler = (evt) => { if ((evt.target.classList.contains("line")) && (evt.x < evt.target.offsetLeft)) { window.location.hash = evt.target.id; return; } }; var root = document.querySelector ("div.conversation"); if (root === null) { return; } root.addEventListener ("click", lineClickHandler); }; var init = function () { initTokenInput (); }; return({ 'init': init, 'lines': setupLineHandler, }); })(); window.addEventListener ("load", mumi.init); window.addEventListener ("DOMContentLoaded", mumi.lines); // @license-end