Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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/. -->
7 <!DOCTYPE bindings [
8 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
9 %browserDTD;
10 ]>
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">
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;
27 if (this._contentScrollHeight == -1) {
28 let scrollheight = {};
29 this.scrollBoxObject.getScrolledSize({}, scrollheight);
30 this._contentScrollHeight = scrollheight.value;
31 }
33 let y = {};
34 this.scrollBoxObject.getPosition({}, y);
35 let scrollRatio = (y.value + this._childrenHeight) / this._contentScrollHeight;
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')"/>
53 <field name="_childrenHeight">this.scrollBoxObject.height;</field>
54 <field name="_items">[]</field>
56 <method name="setItems">
57 <parameter name="aItems"/>
58 <body><![CDATA[
59 this._items = aItems;
60 this._insertItems();
61 ]]></body>
62 </method>
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
70 let count = items.length;
71 for (let i = 0; i<count; i++)
72 this.appendChild(items[i]);
75 // make sure we recalculate the scrollHeight of the content
76 this._contentScrollHeight = -1;
77 ]]></body>
78 </method>
79 </implementation>
80 </binding>
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>
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>
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>
131 <handler event="click" button="0">
132 <![CDATA[
133 if (this.disabled || this.itemCount == 0)
134 return;
136 this.focus();
137 MenuControlUI.show(this);
138 ]]>
139 </handler>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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;
265 let json = { types: ["input-text"], string: "" };
266 if (selectionStart != selectionEnd) {
267 json.types.push("cut");
268 json.types.push("copy");
269 }
271 if (selectionStart > 0 || selectionEnd < aTextbox.textLength)
272 json.types.push("select-all");
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);
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>
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>
359 </bindings>