|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 this.EXPORTED_SYMBOLS = ["ScrollbarSampler"]; |
|
8 |
|
9 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; |
|
10 |
|
11 Cu.import("resource://gre/modules/Services.jsm"); |
|
12 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
13 XPCOMUtils.defineLazyModuleGetter(this, "Promise", |
|
14 "resource://gre/modules/Promise.jsm"); |
|
15 |
|
16 let gSystemScrollbarWidth = null; |
|
17 |
|
18 this.ScrollbarSampler = { |
|
19 getSystemScrollbarWidth: function() { |
|
20 let deferred = Promise.defer(); |
|
21 |
|
22 if (gSystemScrollbarWidth !== null) { |
|
23 deferred.resolve(gSystemScrollbarWidth); |
|
24 return deferred.promise; |
|
25 } |
|
26 |
|
27 this._sampleSystemScrollbarWidth().then(function(systemScrollbarWidth) { |
|
28 gSystemScrollbarWidth = systemScrollbarWidth; |
|
29 deferred.resolve(gSystemScrollbarWidth); |
|
30 }); |
|
31 return deferred.promise; |
|
32 }, |
|
33 |
|
34 resetSystemScrollbarWidth: function() { |
|
35 gSystemScrollbarWidth = null; |
|
36 }, |
|
37 |
|
38 _sampleSystemScrollbarWidth: function() { |
|
39 let deferred = Promise.defer(); |
|
40 let hwin = Services.appShell.hiddenDOMWindow; |
|
41 let hdoc = hwin.document.documentElement; |
|
42 let iframe = hwin.document.createElementNS("http://www.w3.org/1999/xhtml", |
|
43 "html:iframe"); |
|
44 iframe.setAttribute("srcdoc", '<body style="overflow-y: scroll"></body>'); |
|
45 hdoc.appendChild(iframe); |
|
46 |
|
47 let cwindow = iframe.contentWindow; |
|
48 let utils = cwindow.QueryInterface(Ci.nsIInterfaceRequestor) |
|
49 .getInterface(Ci.nsIDOMWindowUtils); |
|
50 |
|
51 cwindow.addEventListener("load", function onLoad(aEvent) { |
|
52 cwindow.removeEventListener("load", onLoad); |
|
53 let sbWidth = {}; |
|
54 try { |
|
55 utils.getScrollbarSize(true, sbWidth, {}); |
|
56 } catch(e) { |
|
57 Cu.reportError("Could not sample scrollbar size: " + e + " -- " + |
|
58 e.stack); |
|
59 sbWidth.value = 0; |
|
60 } |
|
61 // Minimum width of 10 so that we have enough padding: |
|
62 sbWidth.value = Math.max(sbWidth.value, 10); |
|
63 deferred.resolve(sbWidth.value); |
|
64 iframe.remove(); |
|
65 }); |
|
66 |
|
67 return deferred.promise; |
|
68 } |
|
69 }; |
|
70 Object.freeze(this.ScrollbarSampler); |