michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = ["ScrollbarSampler"]; michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "Promise", michael@0: "resource://gre/modules/Promise.jsm"); michael@0: michael@0: let gSystemScrollbarWidth = null; michael@0: michael@0: this.ScrollbarSampler = { michael@0: getSystemScrollbarWidth: function() { michael@0: let deferred = Promise.defer(); michael@0: michael@0: if (gSystemScrollbarWidth !== null) { michael@0: deferred.resolve(gSystemScrollbarWidth); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: this._sampleSystemScrollbarWidth().then(function(systemScrollbarWidth) { michael@0: gSystemScrollbarWidth = systemScrollbarWidth; michael@0: deferred.resolve(gSystemScrollbarWidth); michael@0: }); michael@0: return deferred.promise; michael@0: }, michael@0: michael@0: resetSystemScrollbarWidth: function() { michael@0: gSystemScrollbarWidth = null; michael@0: }, michael@0: michael@0: _sampleSystemScrollbarWidth: function() { michael@0: let deferred = Promise.defer(); michael@0: let hwin = Services.appShell.hiddenDOMWindow; michael@0: let hdoc = hwin.document.documentElement; michael@0: let iframe = hwin.document.createElementNS("http://www.w3.org/1999/xhtml", michael@0: "html:iframe"); michael@0: iframe.setAttribute("srcdoc", ''); michael@0: hdoc.appendChild(iframe); michael@0: michael@0: let cwindow = iframe.contentWindow; michael@0: let utils = cwindow.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIDOMWindowUtils); michael@0: michael@0: cwindow.addEventListener("load", function onLoad(aEvent) { michael@0: cwindow.removeEventListener("load", onLoad); michael@0: let sbWidth = {}; michael@0: try { michael@0: utils.getScrollbarSize(true, sbWidth, {}); michael@0: } catch(e) { michael@0: Cu.reportError("Could not sample scrollbar size: " + e + " -- " + michael@0: e.stack); michael@0: sbWidth.value = 0; michael@0: } michael@0: // Minimum width of 10 so that we have enough padding: michael@0: sbWidth.value = Math.max(sbWidth.value, 10); michael@0: deferred.resolve(sbWidth.value); michael@0: iframe.remove(); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: }; michael@0: Object.freeze(this.ScrollbarSampler);