1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/modules/View.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +this.EXPORTED_SYMBOLS = ["View"]; 1.10 + 1.11 +Components.utils.import("resource://gre/modules/PlacesUtils.jsm"); 1.12 +Components.utils.import("resource:///modules/colorUtils.jsm"); 1.13 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.14 +Components.utils.import("resource://gre/modules/Task.jsm"); 1.15 + 1.16 +// -------------------------------- 1.17 +// module helpers 1.18 +// 1.19 + 1.20 +function makeURI(aURL, aOriginCharset, aBaseURI) { 1.21 + return Services.io.newURI(aURL, aOriginCharset, aBaseURI); 1.22 +} 1.23 + 1.24 +// -------------------------------- 1.25 + 1.26 + 1.27 +// -------------------------------- 1.28 +// View prototype for shared functionality 1.29 + 1.30 +function View(aSet) { 1.31 + this._set = aSet; 1.32 + this._set.controller = this; 1.33 + this._window = aSet.ownerDocument.defaultView; 1.34 + this._maxTiles = 8; 1.35 + this._tilePrefName = "unknown"; 1.36 + 1.37 + this.onResize = () => this._adjustDOMforViewState(); 1.38 + this._window.addEventListener("resize", this.onResize); 1.39 + 1.40 + ColorUtils.init(); 1.41 + this._adjustDOMforViewState(); 1.42 +} 1.43 + 1.44 +View.prototype = { 1.45 + set maxTiles(aVal) { 1.46 + this._maxTiles = aVal; 1.47 + }, 1.48 + 1.49 + get maxTiles() { 1.50 + return this._maxTiles; 1.51 + }, 1.52 + 1.53 + set showing(aFlag) { 1.54 + // 'vbox' must be defined on objects that inherit from us 1.55 + this.vbox.setAttribute("hidden", aFlag ? "false" : "true"); 1.56 + }, 1.57 + 1.58 + set tilePrefName(aStr) { 1.59 + // Should be called once on init by objects that inherit from us 1.60 + this._tilePrefName = aStr; 1.61 + this._maxTiles = Services.prefs.getIntPref(this._tilePrefName); 1.62 + Services.prefs.addObserver(this._tilePrefName, this, false); 1.63 + }, 1.64 + 1.65 + destruct: function () { 1.66 + this._window.removeEventListener("resize", this.onResize); 1.67 + if (this._tilePrefName != "unknown") { 1.68 + Services.prefs.removeObserver(this._tilePrefName, this); 1.69 + } 1.70 + }, 1.71 + 1.72 + _adjustDOMforViewState: function _adjustDOMforViewState(aState) { 1.73 + let grid = this._set; 1.74 + if (!grid) { 1.75 + return; 1.76 + } 1.77 + if (!aState) { 1.78 + aState = grid.getAttribute("viewstate"); 1.79 + } 1.80 + switch (aState) { 1.81 + case "snapped": 1.82 + grid.setAttribute("nocontext", true); 1.83 + grid.selectNone(); 1.84 + grid.disableCrossSlide(); 1.85 + break; 1.86 + case "portrait": 1.87 + grid.removeAttribute("nocontext"); 1.88 + grid.setAttribute("vertical", true); 1.89 + grid.enableCrossSlide(); 1.90 + break; 1.91 + default: 1.92 + grid.removeAttribute("nocontext"); 1.93 + grid.removeAttribute("vertical"); 1.94 + grid.enableCrossSlide(); 1.95 + } 1.96 + if ("arrangeItems" in grid) { 1.97 + grid.arrangeItems(); 1.98 + } 1.99 + }, 1.100 + 1.101 + _updateFavicon: function pv__updateFavicon(aItem, aUri) { 1.102 + if ("string" == typeof aUri) { 1.103 + aUri = makeURI(aUri); 1.104 + } 1.105 + PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aItem)); 1.106 + }, 1.107 + 1.108 + _gotIcon: function pv__gotIcon(aItem, aIconUri) { 1.109 + if (!aIconUri) { 1.110 + aItem.removeAttribute("iconURI"); 1.111 + if (aItem.refresh) { 1.112 + aItem.refresh(); 1.113 + } 1.114 + return; 1.115 + } 1.116 + if ("string" == typeof aIconUri) { 1.117 + aIconUri = makeURI(aIconUri); 1.118 + } 1.119 + let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(aIconUri)).spec; 1.120 + aItem.iconSrc = faviconURL; 1.121 + 1.122 + let xpFaviconURI = makeURI(faviconURL.replace("moz-anno:favicon:","")); 1.123 + Task.spawn(function() { 1.124 + let colorInfo = yield ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI); 1.125 + if (!(colorInfo && colorInfo.background && colorInfo.foreground)) { 1.126 + return; 1.127 + } 1.128 + let { background, foreground } = colorInfo; 1.129 + aItem.style.color = foreground; //color text 1.130 + aItem.setAttribute("customColor", background); 1.131 + let matteColor = 0xffffff; // white 1.132 + let alpha = 0.04; // the tint weight 1.133 + let [,r,g,b] = background.match(/rgb\((\d+),(\d+),(\d+)/); 1.134 + // get the rgb value that represents this color at given opacity over a white matte 1.135 + let tintColor = ColorUtils.addRgbColors(matteColor, ColorUtils.createDecimalColorWord(r,g,b,alpha)); 1.136 + aItem.setAttribute("tintColor", ColorUtils.convertDecimalToRgbColor(tintColor)); 1.137 + // when bound, use the setter to propogate the color change through the tile 1.138 + if ('color' in aItem) { 1.139 + aItem.color = background; 1.140 + } 1.141 + }); 1.142 + }, 1.143 + 1.144 + refreshView: function () { 1.145 + }, 1.146 + 1.147 + observe: function (aSubject, aTopic, aState) { 1.148 + switch (aTopic) { 1.149 + case "nsPref:changed": { 1.150 + if (aState == this._tilePrefName) { 1.151 + let count = Services.prefs.getIntPref(this._tilePrefName); 1.152 + this.maxTiles = count; 1.153 + this.showing = this.maxTiles > 0; 1.154 + this.refreshView(); 1.155 + } 1.156 + break; 1.157 + } 1.158 + } 1.159 + } 1.160 +};