Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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 "use strict";
6 this.EXPORTED_SYMBOLS = ["View"];
8 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
9 Components.utils.import("resource:///modules/colorUtils.jsm");
10 Components.utils.import("resource://gre/modules/Services.jsm");
11 Components.utils.import("resource://gre/modules/Task.jsm");
13 // --------------------------------
14 // module helpers
15 //
17 function makeURI(aURL, aOriginCharset, aBaseURI) {
18 return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
19 }
21 // --------------------------------
24 // --------------------------------
25 // View prototype for shared functionality
27 function View(aSet) {
28 this._set = aSet;
29 this._set.controller = this;
30 this._window = aSet.ownerDocument.defaultView;
31 this._maxTiles = 8;
32 this._tilePrefName = "unknown";
34 this.onResize = () => this._adjustDOMforViewState();
35 this._window.addEventListener("resize", this.onResize);
37 ColorUtils.init();
38 this._adjustDOMforViewState();
39 }
41 View.prototype = {
42 set maxTiles(aVal) {
43 this._maxTiles = aVal;
44 },
46 get maxTiles() {
47 return this._maxTiles;
48 },
50 set showing(aFlag) {
51 // 'vbox' must be defined on objects that inherit from us
52 this.vbox.setAttribute("hidden", aFlag ? "false" : "true");
53 },
55 set tilePrefName(aStr) {
56 // Should be called once on init by objects that inherit from us
57 this._tilePrefName = aStr;
58 this._maxTiles = Services.prefs.getIntPref(this._tilePrefName);
59 Services.prefs.addObserver(this._tilePrefName, this, false);
60 },
62 destruct: function () {
63 this._window.removeEventListener("resize", this.onResize);
64 if (this._tilePrefName != "unknown") {
65 Services.prefs.removeObserver(this._tilePrefName, this);
66 }
67 },
69 _adjustDOMforViewState: function _adjustDOMforViewState(aState) {
70 let grid = this._set;
71 if (!grid) {
72 return;
73 }
74 if (!aState) {
75 aState = grid.getAttribute("viewstate");
76 }
77 switch (aState) {
78 case "snapped":
79 grid.setAttribute("nocontext", true);
80 grid.selectNone();
81 grid.disableCrossSlide();
82 break;
83 case "portrait":
84 grid.removeAttribute("nocontext");
85 grid.setAttribute("vertical", true);
86 grid.enableCrossSlide();
87 break;
88 default:
89 grid.removeAttribute("nocontext");
90 grid.removeAttribute("vertical");
91 grid.enableCrossSlide();
92 }
93 if ("arrangeItems" in grid) {
94 grid.arrangeItems();
95 }
96 },
98 _updateFavicon: function pv__updateFavicon(aItem, aUri) {
99 if ("string" == typeof aUri) {
100 aUri = makeURI(aUri);
101 }
102 PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aItem));
103 },
105 _gotIcon: function pv__gotIcon(aItem, aIconUri) {
106 if (!aIconUri) {
107 aItem.removeAttribute("iconURI");
108 if (aItem.refresh) {
109 aItem.refresh();
110 }
111 return;
112 }
113 if ("string" == typeof aIconUri) {
114 aIconUri = makeURI(aIconUri);
115 }
116 let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(aIconUri)).spec;
117 aItem.iconSrc = faviconURL;
119 let xpFaviconURI = makeURI(faviconURL.replace("moz-anno:favicon:",""));
120 Task.spawn(function() {
121 let colorInfo = yield ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI);
122 if (!(colorInfo && colorInfo.background && colorInfo.foreground)) {
123 return;
124 }
125 let { background, foreground } = colorInfo;
126 aItem.style.color = foreground; //color text
127 aItem.setAttribute("customColor", background);
128 let matteColor = 0xffffff; // white
129 let alpha = 0.04; // the tint weight
130 let [,r,g,b] = background.match(/rgb\((\d+),(\d+),(\d+)/);
131 // get the rgb value that represents this color at given opacity over a white matte
132 let tintColor = ColorUtils.addRgbColors(matteColor, ColorUtils.createDecimalColorWord(r,g,b,alpha));
133 aItem.setAttribute("tintColor", ColorUtils.convertDecimalToRgbColor(tintColor));
134 // when bound, use the setter to propogate the color change through the tile
135 if ('color' in aItem) {
136 aItem.color = background;
137 }
138 });
139 },
141 refreshView: function () {
142 },
144 observe: function (aSubject, aTopic, aState) {
145 switch (aTopic) {
146 case "nsPref:changed": {
147 if (aState == this._tilePrefName) {
148 let count = Services.prefs.getIntPref(this._tilePrefName);
149 this.maxTiles = count;
150 this.showing = this.maxTiles > 0;
151 this.refreshView();
152 }
153 break;
154 }
155 }
156 }
157 };