summaryrefslogtreecommitdiff
path: root/assets/js/mumi.js
diff options
context:
space:
mode:
Diffstat (limited to 'assets/js/mumi.js')
-rw-r--r--assets/js/mumi.js161
1 files changed, 147 insertions, 14 deletions
diff --git a/assets/js/mumi.js b/assets/js/mumi.js
index f98a902..1ba77d0 100644
--- a/assets/js/mumi.js
+++ b/assets/js/mumi.js
@@ -1,19 +1,152 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later
-(function () {
- var loadSnippet = function (targetId, URL) {
- var req = new XMLHttpRequest();
- req.onload = function (e) {
- var target = document.getElementById(targetId);
- target.outerHTML = req.responseText;
- };
- req.onerror = function (e) {
- var target = document.getElementById(targetId);
- target.outerHTML = "Never mind...";
+var mumi = (function () {
+ var initTokenInput = function () {
+ var inputElement = document.querySelector (".tokenInput input#query");
+ if (inputElement == null) {
+ return;
+ }
+ 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 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' },
+ ];
+ 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'
};
- req.open('GET', URL, true);
- req.send();
+ },
+ 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';
+ }
};
- loadSnippet ('snippet-recent', '/snippet/recent');
- loadSnippet ('snippet-priority', '/snippet/priority');
+
+ 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 ();
+ for (token of tokenInput.getTokens ()) {
+ inputElement.value += token.text + " ";
+ }
+ inputElement.style.visibility = 'hidden';
+ form.submit ();
+ });
+
+ /* tokenize existing input text */
+ if (inputElement.value.length > 0) {
+ let items = inputElement.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));
+ }
+ }
+ inputElement.value = "";
+ tokenInput.setTokens(tokens);
+ }
+ };
+ var init = function () {
+ initTokenInput ();
+ };
+ return({
+ 'init': init,
+ });
})();
+
+window.addEventListener ("load", mumi.init);
// @license-end