blob: c12d26a14a99051a134d341a1805915db1080698 [file] [log] [blame]
Nils Diewald0e6992a2015-04-14 20:13:52 +00001// Input field for queries
2define({
Nils Diewald7148c6f2015-05-04 15:07:53 +00003
4 /**
5 * Create a new input field.
6 */
Nils Diewald0e6992a2015-04-14 20:13:52 +00007 create : function (element) {
8 return Object.create(this)._init(element);
9 },
Nils Diewald7148c6f2015-05-04 15:07:53 +000010
11 // Initialize new input field
Nils Diewald0e6992a2015-04-14 20:13:52 +000012 _init : function (element) {
13 this._element = element;
14
15 // Create mirror for searchField
16 if ((this._mirror = document.getElementById("searchMirror")) === null) {
17 this._mirror = document.createElement("div");
18 this._mirror.setAttribute("id", "searchMirror");
19 this._mirror.appendChild(document.createElement("span"));
20 this._container = this._mirror.appendChild(document.createElement("div"));
21 this._mirror.style.height = "0px";
22 document.getElementsByTagName("body")[0].appendChild(this._mirror);
23 };
24
25 // Update position of the mirror
26 var that = this;
27 var repos = function () {
28 that.reposition();
29 };
30 window.addEventListener('resize', repos);
31 this._element.addEventListener('onfocus', repos);
32 that.reposition();
33
34 return this;
35 },
36
Nils Diewald7148c6f2015-05-04 15:07:53 +000037 // Get the right position
38 _rightPos : function () {
Nils Diewald0e6992a2015-04-14 20:13:52 +000039 var box = this._mirror.firstChild.getBoundingClientRect();
40 return box.right - box.left;
41 },
42
Nils Diewald7148c6f2015-05-04 15:07:53 +000043 /**
44 * Get the mirrored input field.
45 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000046 mirror : function () {
47 return this._mirror;
48 },
49
Nils Diewald7148c6f2015-05-04 15:07:53 +000050
51 /**
52 * Get the container element.
53 * This contains the mirror and
54 * the hint helper.
55 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000056 container : function () {
57 return this._container;
58 },
59
Nils Diewald7148c6f2015-05-04 15:07:53 +000060
61 /**
62 * Get the input element the
63 * hint helper is attached to.
64 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000065 element : function () {
66 return this._element;
67 },
68
Nils Diewald7148c6f2015-05-04 15:07:53 +000069 /**
70 * Get the value of the input field
71 * the hint helper is attached to.
72 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000073 value : function () {
74 return this._element.value;
75 },
76
Nils Diewald7148c6f2015-05-04 15:07:53 +000077
78 /**
79 * Update the mirror content.
80 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000081 update : function () {
Nils Diewald7148c6f2015-05-04 15:07:53 +000082 this._mirror.firstChild.textContent = this._split()[0];
83 this._container.style.left = this._rightPos() + 'px';
Nils Diewald0e6992a2015-04-14 20:13:52 +000084 },
85
Nils Diewald7148c6f2015-05-04 15:07:53 +000086 /**
87 * Insert text into the mirror.
88 * This is a prefix of the input field's
89 * value.
90 */
Nils Diewald0e6992a2015-04-14 20:13:52 +000091 insert : function (text) {
Nils Diewald7148c6f2015-05-04 15:07:53 +000092 var splittedText = this._split();
Nils Diewald0e6992a2015-04-14 20:13:52 +000093 var s = this._element;
94 s.value = splittedText[0] + text + splittedText[1];
95 s.selectionStart = (splittedText[0] + text).length;
96 s.selectionEnd = s.selectionStart;
97 this._mirror.firstChild.textContent = splittedText[0] + text;
98 },
99
Nils Diewald0e6992a2015-04-14 20:13:52 +0000100
Nils Diewald7148c6f2015-05-04 15:07:53 +0000101 /**
102 * Reposition the input mirror directly
103 * below the input box.
104 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000105 reposition : function () {
106 var inputClientRect = this._element.getBoundingClientRect();
107 var inputStyle = window.getComputedStyle(this._element, null);
108
109 var bodyClientRect =
110 document.getElementsByTagName('body')[0].getBoundingClientRect();
111
112 // Reset position
113 var mirrorStyle = this._mirror.style;
114 mirrorStyle.left = inputClientRect.left + "px";
115 mirrorStyle.top = (inputClientRect.bottom - bodyClientRect.top) + "px";
116 mirrorStyle.width = inputStyle.getPropertyValue("width");
117
118 // These may be relevant in case of media depending css
119 mirrorStyle.paddingLeft = inputStyle.getPropertyValue("padding-left");
120 mirrorStyle.marginLeft = inputStyle.getPropertyValue("margin-left");
121 mirrorStyle.borderLeftWidth = inputStyle.getPropertyValue("border-left-width");
122 mirrorStyle.borderLeftStyle = inputStyle.getPropertyValue("border-left-style");
123 mirrorStyle.fontSize = inputStyle.getPropertyValue("font-size");
124 mirrorStyle.fontFamily = inputStyle.getPropertyValue("font-family");
125 },
Nils Diewald7148c6f2015-05-04 15:07:53 +0000126
127 /**
128 * Get the context, which is the input
129 * field's value bounded to the
130 * cursor position.
131 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000132 context : function () {
Nils Diewald7148c6f2015-05-04 15:07:53 +0000133 return this._split()[0];
134 },
135
136 /*
137 * Return two substrings,
138 * splitted at the current cursor position.
139 */
140 _split : function () {
141 var s = this._element;
142 var value = s.value;
143 var start = s.selectionStart;
144 return new Array(
145 value.substring(0, start),
146 value.substring(start, value.length)
147 );
Nils Diewald0e6992a2015-04-14 20:13:52 +0000148 }
149});