blob: 885e1ea1dd09b632f7131017926cb55a02bfd9f0 [file] [log] [blame]
Nils Diewald19ccee92014-12-08 11:30:08 +00001/**
Nils Diewald5c5a7472015-04-02 22:13:38 +00002 * Hint menu for Kalamar.
Nils Diewald47f366b2015-04-15 20:06:35 +00003 * Based on menu object.
Nils Diewald19ccee92014-12-08 11:30:08 +00004 *
5 * @author Nils Diewald
6 */
Nils Diewald0e6992a2015-04-14 20:13:52 +00007define([
8 'hint/input',
9 'hint/menu',
10 'hint/contextanalyzer',
11 'util'
12], function (inputClass,
13 menuClass,
14 analyzerClass) {
Nils Diewald19ccee92014-12-08 11:30:08 +000015 "use strict";
16
Nils Diewald19ccee92014-12-08 11:30:08 +000017 /**
18 * @define {regex} Regular expression for context
19 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000020 KorAP.context = KorAP.context ||
Nils Diewald19ccee92014-12-08 11:30:08 +000021 "(?:^|[^-_a-zA-Z0-9])" + // Anchor
22 "((?:[-_a-zA-Z0-9]+?)\/" + // Foundry
23 "(?:" +
24 "(?:[-_a-zA-Z0-9]+?)=" + // Layer
25 "(?:(?:[^:=\/ ]+?):)?" + // Key
26 ")?" +
27 ")$";
Nils Diewald19ccee92014-12-08 11:30:08 +000028 KorAP.hintArray = KorAP.hintArray || {};
29
Nils Diewald0e6992a2015-04-14 20:13:52 +000030 /**
31 * Return keycode based on event
32 */
33 function _codeFromEvent (e) {
34 if ((e.charCode) && (e.keyCode==0))
35 return e.charCode
36 return e.keyCode;
37 };
38
39 // Initialize hint array
Nils Diewald5c5a7472015-04-02 22:13:38 +000040
41 /**
42 * KorAP.Hint.create({
43 * inputField : node,
44 * context : context regex
45 * });
46 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000047 return {
Nils Diewald5c5a7472015-04-02 22:13:38 +000048
49 // Some variables
50 // _firstTry : true,
51 active : false,
52
Nils Diewald0e6992a2015-04-14 20:13:52 +000053 /**
54 * Create new hint helper.
55 */
Nils Diewald5c5a7472015-04-02 22:13:38 +000056 create : function (param) {
Nils Diewald0e6992a2015-04-14 20:13:52 +000057 return Object.create(this)._init(param);
Nils Diewald5c5a7472015-04-02 22:13:38 +000058 },
59
Nils Diewald0e6992a2015-04-14 20:13:52 +000060 // Initialize hint helper
Nils Diewald5c5a7472015-04-02 22:13:38 +000061 _init : function (param) {
62 param = param || {};
63
64 // Holds all menus per prefix context
65 this._menu = {};
66
67 // Get input field
Nils Diewald0e6992a2015-04-14 20:13:52 +000068 var qfield = param["inputField"] || document.getElementById("q-field");
69 if (!qfield)
70 return null;
71
72 this._inputField = inputClass.create(qfield);
Nils Diewald5c5a7472015-04-02 22:13:38 +000073
74 var inputFieldElement = this._inputField.element();
75
76 var that = this;
77
78 // Add event listener for key pressed down
79 inputFieldElement.addEventListener(
Nils Diewald47f366b2015-04-15 20:06:35 +000080 "keydown", function (e) {
Nils Diewald5c5a7472015-04-02 22:13:38 +000081 var code = _codeFromEvent(e);
82 if (code === 40) {
83 that.show(false);
84 e.halt();
85 };
86 }, false
87 );
88
Nils Diewald47f366b2015-04-15 20:06:35 +000089 this._inputField.container().addEventListener('click', function (e) {
90 if (!this.classList.contains('active')) {
91 that.show(false);
92 };
93 });
94
95 var _up = function (e) {
96 var input = that._inputField;
97 input.update();
98 };
99
100 // Move infobox
101 inputFieldElement.addEventListener("keyup", _up);
102 inputFieldElement.addEventListener("click", _up);
Nils Diewald5c5a7472015-04-02 22:13:38 +0000103
104 // Set Analyzer for context
Nils Diewald0e6992a2015-04-14 20:13:52 +0000105 this._analyzer = analyzerClass.create(
Nils Diewald5c5a7472015-04-02 22:13:38 +0000106 param["context"] || KorAP.context
107 );
Nils Diewald19ccee92014-12-08 11:30:08 +0000108 return this;
109 },
110
Nils Diewald5c5a7472015-04-02 22:13:38 +0000111 inputField : function () {
112 return this._inputField;
113 },
Nils Diewald19ccee92014-12-08 11:30:08 +0000114
Nils Diewald5c5a7472015-04-02 22:13:38 +0000115 /**
Nils Diewald5c5a7472015-04-02 22:13:38 +0000116 * Return hint menu and probably init based on an action
117 */
118 menu : function (action) {
119
120 if (this._menu[action] === undefined) {
121
122 // No matching hint menu
123 if (KorAP.hintArray[action] === undefined)
124 return;
125
126 // Create matching hint menu
Nils Diewald0e6992a2015-04-14 20:13:52 +0000127 this._menu[action] = menuClass.create(
Nils Diewald5c5a7472015-04-02 22:13:38 +0000128 this, action, KorAP.hintArray[action]
Nils Diewald19ccee92014-12-08 11:30:08 +0000129 );
Nils Diewald5c5a7472015-04-02 22:13:38 +0000130 };
131
132 // Return matching hint menu
133 return this._menu[action];
134 },
135
136 /**
137 * Get the correct menu based on the context
138 */
139 contextMenu : function (ifContext) {
140 var context = this._inputField.context();
141 if (context === undefined || context.length == 0)
142 return ifContext ? undefined : this.menu("-");
143
144 context = this._analyzer.test(context);
145 if (context === undefined || context.length == 0)
146 return ifContext ? undefined : this.menu("-");
147
148 return this.menu(context);
149 },
150
151
152 /**
153 * Show the menu
154 */
155 show : function (ifContext) {
156
157 // Menu is already active
158 if (this.active)
159 return;
160
161 // Initialize the menus position
162 /*
163 if (this._firstTry) {
164 this._inputField.reposition();
165 this._firstTry = false;
166 };
167 */
168
169 // update
170
171 // Get the menu
172 var menu;
173 if (menu = this.contextMenu(ifContext)) {
Nils Diewald2488d052015-04-09 21:46:02 +0000174 var c = this._inputField.container();
175 c.classList.add('active');
176 c.appendChild(menu.element());
Nils Diewald5c5a7472015-04-02 22:13:38 +0000177 menu.show('');
178 menu.focus();
Nils Diewald5c5a7472015-04-02 22:13:38 +0000179 // Focus on input field
180 // this.inputField.element.focus();
Nils Diewald19ccee92014-12-08 11:30:08 +0000181 };
182 }
183 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000184});