|
1 <?xml version="1.0"?> |
|
2 <!-- This Source Code Form is subject to the terms of the Mozilla Public |
|
3 - License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
|
5 |
|
6 |
|
7 <!DOCTYPE bindings [ |
|
8 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd"> |
|
9 %browserDTD; |
|
10 ]> |
|
11 |
|
12 <bindings |
|
13 xmlns="http://www.mozilla.org/xbl" |
|
14 xmlns:xbl="http://www.mozilla.org/xbl" |
|
15 xmlns:svg="http://www.w3.org/2000/svg" |
|
16 xmlns:html="http://www.w3.org/1999/xhtml" |
|
17 xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
|
18 |
|
19 <binding id="richlistbox-batch" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox"> |
|
20 <handlers> |
|
21 <handler event="scroll"> |
|
22 <![CDATA[ |
|
23 // if there no more items to insert, just return early |
|
24 if (this._items.length == 0) |
|
25 return; |
|
26 |
|
27 if (this._contentScrollHeight == -1) { |
|
28 let scrollheight = {}; |
|
29 this.scrollBoxObject.getScrolledSize({}, scrollheight); |
|
30 this._contentScrollHeight = scrollheight.value; |
|
31 } |
|
32 |
|
33 let y = {}; |
|
34 this.scrollBoxObject.getPosition({}, y); |
|
35 let scrollRatio = (y.value + this._childrenHeight) / this._contentScrollHeight; |
|
36 |
|
37 // If we're scrolled 80% to the bottom of the list, append the next |
|
38 // set of items |
|
39 if (scrollRatio > 0.8) |
|
40 this._insertItems(); |
|
41 ]]> |
|
42 </handler> |
|
43 </handlers> |
|
44 <implementation> |
|
45 <!-- Number of elements to add to the list initially. If there are more |
|
46 than this many elements to display, only add them to the list once |
|
47 the user has scrolled towards them. This is a performance |
|
48 optimization to avoid locking up while attempting to append hundreds |
|
49 of nodes to our richlistbox. |
|
50 --> |
|
51 <property name="batchSize" readonly="true" onget="return this.getAttribute('batch')"/> |
|
52 |
|
53 <field name="_childrenHeight">this.scrollBoxObject.height;</field> |
|
54 <field name="_items">[]</field> |
|
55 |
|
56 <method name="setItems"> |
|
57 <parameter name="aItems"/> |
|
58 <body><![CDATA[ |
|
59 this._items = aItems; |
|
60 this._insertItems(); |
|
61 ]]></body> |
|
62 </method> |
|
63 |
|
64 <method name="_insertItems"> |
|
65 <body><![CDATA[ |
|
66 let items = this._items.splice(0, this.batchSize); |
|
67 if (!items.length) |
|
68 return; // no items to insert |
|
69 |
|
70 let count = items.length; |
|
71 for (let i = 0; i<count; i++) |
|
72 this.appendChild(items[i]); |
|
73 |
|
74 |
|
75 // make sure we recalculate the scrollHeight of the content |
|
76 this._contentScrollHeight = -1; |
|
77 ]]></body> |
|
78 </method> |
|
79 </implementation> |
|
80 </binding> |
|
81 |
|
82 <binding id="richlistbox-contextmenu" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox"> |
|
83 <handlers> |
|
84 <handler event="click" phase="bubble"> |
|
85 <![CDATA[ |
|
86 ContextMenuUI.hide(); |
|
87 ]]> |
|
88 </handler> |
|
89 </handlers> |
|
90 </binding> |
|
91 |
|
92 <binding id="richlistitem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> |
|
93 <handlers> |
|
94 <handler event="mousedown" phase="capturing"> |
|
95 <![CDATA[ |
|
96 // We'll get this if the user is interacting via the mouse |
|
97 let domUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]. |
|
98 getService(Ci.inIDOMUtils); |
|
99 domUtils.setContentState(this, 0x00000001); |
|
100 ]]> |
|
101 </handler> |
|
102 <handler event="click" phase="capturing"> |
|
103 <![CDATA[ |
|
104 // allow normal mouse event processing |
|
105 if (!InputSourceHelper || InputSourceHelper.isPrecise) |
|
106 return; |
|
107 // trap this here, we'll rely on tap events |
|
108 // event.stopPropagation(); |
|
109 ]]> |
|
110 </handler> |
|
111 <handler event="touchstart" phase="capturing"> |
|
112 <![CDATA[ |
|
113 // touch input event |
|
114 let domUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]. |
|
115 getService(Ci.inIDOMUtils); |
|
116 domUtils.setContentState(this, 0x00000001); |
|
117 ]]> |
|
118 </handler> |
|
119 </handlers> |
|
120 </binding> |
|
121 |
|
122 <binding id="menulist" display="xul:box" extends="chrome://global/content/bindings/menulist.xml#menulist"> |
|
123 <handlers> |
|
124 <handler event="mousedown" phase="capturing"> |
|
125 <![CDATA[ |
|
126 // Stop the normal menupopup from appearing |
|
127 event.stopPropagation(); |
|
128 ]]> |
|
129 </handler> |
|
130 |
|
131 <handler event="click" button="0"> |
|
132 <![CDATA[ |
|
133 if (this.disabled || this.itemCount == 0) |
|
134 return; |
|
135 |
|
136 this.focus(); |
|
137 MenuControlUI.show(this); |
|
138 ]]> |
|
139 </handler> |
|
140 |
|
141 <handler event="command" phase="capturing"> |
|
142 <![CDATA[ |
|
143 // The dropmark (button) fires a command event too. Don't forward that. |
|
144 // Just forward the menuitem command events, which the toolkit version does. |
|
145 if (event.target.parentNode.parentNode != this) |
|
146 event.stopPropagation(); |
|
147 ]]> |
|
148 </handler> |
|
149 </handlers> |
|
150 </binding> |
|
151 |
|
152 <binding id="chrome-select-option"> |
|
153 <content orient="horizontal" flex="1"> |
|
154 <xul:image class="chrome-select-option-image" anonid="check"/> |
|
155 <xul:label anonid="label" xbl:inherits="value=label"/> |
|
156 </content> |
|
157 |
|
158 <implementation> |
|
159 <property name="selected"> |
|
160 <getter> |
|
161 <![CDATA[ |
|
162 return this.hasAttribute("selected"); |
|
163 ]]> |
|
164 </getter> |
|
165 <setter> |
|
166 <![CDATA[ |
|
167 if (val) |
|
168 this.setAttribute("selected", "true"); |
|
169 else |
|
170 this.removeAttribute("selected"); |
|
171 return val; |
|
172 ]]> |
|
173 </setter> |
|
174 </property> |
|
175 </implementation> |
|
176 </binding> |
|
177 |
|
178 <binding id="select-button" extends="xul:box"> |
|
179 <content> |
|
180 <svg:svg width="11px" version="1.1" xmlns="http://www.w3.org/2000/svg" style="position: absolute; top: -moz-calc(50% - 2px); left: 4px;"> |
|
181 <svg:polyline points="1 1 5 6 9 1" stroke="#414141" stroke-width="2" stroke-linecap="round" fill="transparent" stroke-linejoin="round"/> |
|
182 </svg:svg> |
|
183 </content> |
|
184 </binding> |
|
185 |
|
186 <binding id="textbox" extends="chrome://global/content/bindings/textbox.xml#textbox"> |
|
187 <handlers> |
|
188 <handler event="contextmenu" phase="capturing"> |
|
189 <![CDATA[ |
|
190 let box = this.inputField.parentNode; |
|
191 box.showContextMenu(this, event, false); |
|
192 ]]> |
|
193 </handler> |
|
194 <handler event="click" phase="capturing"> |
|
195 <![CDATA[ |
|
196 if (event.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) { |
|
197 if (typeof SelectionHelperUI != 'undefined') { |
|
198 SelectionHelperUI.attachEditSession(ChromeSelectionHandler, |
|
199 event.clientX, event.clientY, this); |
|
200 } else { |
|
201 // If we don't have access to SelectionHelperUI then we are using this |
|
202 // binding for browser content (e.g. about:config) |
|
203 Services.obs.notifyObservers(event, "attach_edit_session_to_content", ""); |
|
204 } |
|
205 } |
|
206 ]]> |
|
207 </handler> |
|
208 </handlers> |
|
209 </binding> |
|
210 |
|
211 <binding id="search-textbox" extends="chrome://global/content/bindings/textbox.xml#search-textbox"> |
|
212 <implementation> |
|
213 <field name="_searchClear"> |
|
214 <![CDATA[ |
|
215 document.getAnonymousElementByAttribute(this, "class", "textbox-search-clear"); |
|
216 ]]> |
|
217 </field> |
|
218 </implementation> |
|
219 |
|
220 <handlers> |
|
221 <handler event="contextmenu" phase="capturing"> |
|
222 <![CDATA[ |
|
223 let box = this.inputField.parentNode; |
|
224 box.showContextMenu(this, event, false); |
|
225 ]]> |
|
226 </handler> |
|
227 |
|
228 <handler event="text" phase="bubbling"><![CDATA[ |
|
229 // Listen for composition update, some VKB that does suggestions does not |
|
230 // update directly the content of the field but in this case we want to |
|
231 // search as soon as something is entered in the field |
|
232 let evt = document.createEvent("Event"); |
|
233 evt.initEvent("input", true, false); |
|
234 this.dispatchEvent(evt); |
|
235 ]]></handler> |
|
236 |
|
237 <handler event="click" phase="bubbling"><![CDATA[ |
|
238 // bug 629661. To reset the autosuggestions mechanism of Android, the |
|
239 // textfield need to reset the IME state |
|
240 if (event.originalTarget == this._searchClear) { |
|
241 setTimeout(function(self) { |
|
242 try { |
|
243 let imeEditor = self.inputField.QueryInterface(Ci.nsIDOMNSEditableElement) |
|
244 .editor |
|
245 .QueryInterface(Ci.nsIEditorIMESupport); |
|
246 if (imeEditor.composing) |
|
247 imeEditor.forceCompositionEnd(); |
|
248 } catch(e) {} |
|
249 }, 0, this); |
|
250 } |
|
251 ]]></handler> |
|
252 </handlers> |
|
253 </binding> |
|
254 |
|
255 <binding id="input-box" extends="xul:box"> |
|
256 <implementation> |
|
257 <method name="showContextMenu"> |
|
258 <parameter name="aTextbox"/> |
|
259 <parameter name="aEvent"/> |
|
260 <parameter name="aIgnoreReadOnly"/> |
|
261 <body><![CDATA[ |
|
262 let selectionStart = aTextbox.selectionStart; |
|
263 let selectionEnd = aTextbox.selectionEnd; |
|
264 |
|
265 let json = { types: ["input-text"], string: "" }; |
|
266 if (selectionStart != selectionEnd) { |
|
267 json.types.push("cut"); |
|
268 json.types.push("copy"); |
|
269 } |
|
270 |
|
271 if (selectionStart > 0 || selectionEnd < aTextbox.textLength) |
|
272 json.types.push("select-all"); |
|
273 |
|
274 let clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]. |
|
275 getService(Ci.nsIClipboard); |
|
276 let flavors = ["text/unicode"]; |
|
277 let hasData = clipboard.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard); |
|
278 |
|
279 if (hasData && (!aTextbox.readOnly || aIgnoreReadOnly)) { |
|
280 json.types.push("paste"); |
|
281 if (aTextbox.type == "url") { |
|
282 json.types.push("paste-url"); |
|
283 } |
|
284 } |
|
285 json.xPos = aEvent.clientX; |
|
286 json.yPos = aEvent.clientY; |
|
287 json.source = aEvent.mozInputSource; |
|
288 ContextMenuUI.showContextMenu({ target: aTextbox, json: json }); |
|
289 ]]></body> |
|
290 </method> |
|
291 </implementation> |
|
292 <handlers> |
|
293 <handler event="click" phase="capturing"> |
|
294 <![CDATA[ |
|
295 if (event.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) { |
|
296 if (typeof SelectionHelperUI != 'undefined') { |
|
297 SelectionHelperUI.attachEditSession(ChromeSelectionHandler, |
|
298 event.clientX, event.clientY, event.target); |
|
299 } else { |
|
300 // If we don't have access to SelectionHelperUI then we are using this |
|
301 // binding for browser content (e.g. about:config) |
|
302 Services.obs.notifyObservers(event, "attach_edit_session_to_content", ""); |
|
303 } |
|
304 } |
|
305 ]]> |
|
306 </handler> |
|
307 </handlers> |
|
308 </binding> |
|
309 |
|
310 <binding id="line-wrap-label" extends="chrome://global/content/bindings/text.xml#text-label"> |
|
311 <implementation> |
|
312 <constructor> |
|
313 <![CDATA[ |
|
314 if (this.hasAttribute("value")) { |
|
315 this.textContent = this.getAttribute("value"); |
|
316 this.removeAttribute("value"); |
|
317 } |
|
318 ]]> |
|
319 </constructor> |
|
320 <property name="value"> |
|
321 <getter> |
|
322 <![CDATA[ |
|
323 return this.textContent; |
|
324 ]]> |
|
325 </getter> |
|
326 <setter> |
|
327 <![CDATA[ |
|
328 return (this.textContent = val); |
|
329 ]]> |
|
330 </setter> |
|
331 </property> |
|
332 </implementation> |
|
333 </binding> |
|
334 <binding id="line-wrap-text-link" extends="chrome://global/content/bindings/text.xml#text-link"> |
|
335 <implementation> |
|
336 <constructor> |
|
337 <![CDATA[ |
|
338 if (this.hasAttribute("value")) { |
|
339 this.textContent = this.getAttribute("value"); |
|
340 this.removeAttribute("value"); |
|
341 } |
|
342 ]]> |
|
343 </constructor> |
|
344 <property name="value"> |
|
345 <getter> |
|
346 <![CDATA[ |
|
347 return this.textContent; |
|
348 ]]> |
|
349 </getter> |
|
350 <setter> |
|
351 <![CDATA[ |
|
352 return (this.textContent = val); |
|
353 ]]> |
|
354 </setter> |
|
355 </property> |
|
356 </implementation> |
|
357 </binding> |
|
358 |
|
359 </bindings> |