Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
137 lines
3.4 KiB
JavaScript
Executable file
137 lines
3.4 KiB
JavaScript
Executable file
'use strict';
|
|
/* global GridIconRenderer, devicePixelRatio, Promise */
|
|
|
|
(function(exports) {
|
|
|
|
const FETCH_XHR_TIMEOUT = 10000;
|
|
|
|
/**
|
|
* XHR wrapper for fetching blobs with timeout logic.
|
|
*
|
|
* @param {String} uri to fetch.
|
|
* @return {Promise[Blob]}
|
|
*/
|
|
function fetchBlob(uri) {
|
|
return new Promise(function(accept, reject) {
|
|
var xhr = new XMLHttpRequest({
|
|
mozAnon: true,
|
|
mozSystem: true
|
|
});
|
|
|
|
xhr.open('GET', uri, true);
|
|
xhr.responseType = 'blob';
|
|
xhr.timeout = FETCH_XHR_TIMEOUT;
|
|
xhr.send();
|
|
|
|
xhr.onload = function() {
|
|
var status = xhr.status;
|
|
if (status !== 0 && status !== 200) {
|
|
reject(
|
|
new Error('Got HTTP status ' + status + ' trying to load ' + uri)
|
|
);
|
|
return;
|
|
}
|
|
accept(xhr.response);
|
|
};
|
|
|
|
xhr.onerror = xhr.ontimeout = function() {
|
|
reject(new Error('Error while HTTP GET: ', uri));
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Represents a generic icon.
|
|
*
|
|
* @param {DOMElement} The DOM element.
|
|
* @param {String} icon uri.
|
|
*/
|
|
function Icon(elem, uri) {
|
|
this.elem = elem;
|
|
this.uri = uri;
|
|
}
|
|
|
|
Icon.prototype = {
|
|
/**
|
|
* The size icon by default.
|
|
*/
|
|
get size() {
|
|
return this._size || 40;
|
|
},
|
|
|
|
set size(size) {
|
|
this._size = size || this.size;
|
|
var style = this.elem.style;
|
|
var sizeInRems = (this._size / 10) + 'rem';
|
|
style.backgroundSize = style.width = style.height = sizeInRems;
|
|
},
|
|
|
|
/**
|
|
* It renders the icon. If the URI of the icon is not defined or there is an
|
|
* error fetching this one, the icon by default will be displayed if it is
|
|
* defined in the stylesheet.
|
|
*
|
|
* @param {Object} It defines two optional parameters. "size" which defines
|
|
* the size of the icon and "type" that describes how the
|
|
* icon will be rendered ('clip', 'favicon' or 'standard').
|
|
* See GridIconRenderer.
|
|
*/
|
|
render: function render(options) {
|
|
options = options || {};
|
|
var uri = this.uri;
|
|
this.size = options.size;
|
|
if (!uri) {
|
|
return;
|
|
}
|
|
|
|
fetchBlob(uri).then(function(blob) {
|
|
this.renderBlob(blob, options);
|
|
}.bind(this));
|
|
},
|
|
|
|
renderBlob: function renderBlob(blob, options) {
|
|
options = options || {};
|
|
var style = this.elem.style;
|
|
this.size = options.size;
|
|
var img = new Image();
|
|
img.src = URL.createObjectURL(blob);
|
|
var size = this.size;
|
|
|
|
img.onload = () => {
|
|
var renderer = new GridIconRenderer({
|
|
grid: {
|
|
layout: {
|
|
get gridIconSize() {
|
|
return size;
|
|
},
|
|
get gridMaxIconSize() {
|
|
return size * devicePixelRatio;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
var type = options.type || GridIconRenderer.TYPE.FAVICON;
|
|
renderer[type](img).then((blob) => {
|
|
var url = URL.createObjectURL(blob);
|
|
var imageUrl = 'url(' + url + ')';
|
|
style.backgroundImage = imageUrl;
|
|
if (options.onLoad) {
|
|
options.onLoad(blob);
|
|
}
|
|
});
|
|
|
|
URL.revokeObjectURL(img.src);
|
|
};
|
|
|
|
img.onerror = () => {
|
|
if (options.onerror) {
|
|
options.onerror();
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
exports.Icon = Icon;
|
|
|
|
}(window));
|