// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var SetIconCommon = requireNative('setIcon').SetIconCommon; var sendRequest = require('sendRequest').sendRequest; function loadImagePath(path, iconSize, actionType, callback) { var img = new Image(); img.onerror = function() { console.error('Could not load ' + actionType + ' icon \'' + path + '\'.'); }; img.onload = function() { var canvas = document.createElement('canvas'); canvas.width = img.width > iconSize ? iconSize : img.width; canvas.height = img.height > iconSize ? iconSize : img.height; var canvas_context = canvas.getContext('2d'); canvas_context.clearRect(0, 0, canvas.width, canvas.height); canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); var imageData = canvas_context.getImageData(0, 0, canvas.width, canvas.height); callback(imageData); }; img.src = path; } function verifyImageData(imageData, iconSize) { // Verify that this at least looks like an ImageData element. // Unfortunately, we cannot use instanceof because the ImageData // constructor is not public. // // We do this manually instead of using JSONSchema to avoid having these // properties show up in the doc. if (!('width' in imageData) || !('height' in imageData) || !('data' in imageData)) { throw new Error( 'The imageData property must contain an ImageData object or' + ' dictionary of ImageData objects.'); } if (imageData.width > iconSize || imageData.height > iconSize) { throw new Error( 'The imageData property must contain an ImageData object that ' + 'is no larger than ' + iconSize + ' pixels square.'); } } function setIcon(details, callback, name, parameters, actionType) { var iconSizes = [19, 38]; if ('iconIndex' in details) { sendRequest(name, [details, callback], parameters); } else if ('imageData' in details) { if (typeof details.imageData == 'object') { var isEmpty = true; for (var i = 0; i < iconSizes.length; i++) { var sizeKey = iconSizes[i].toString(); if (sizeKey in details.imageData) { verifyImageData(details.imageData[sizeKey], iconSizes[i]); isEmpty =false; } } if (!isEmpty) { sendRequest(name, [details, callback], parameters, {nativeFunction: SetIconCommon}); } else { // If details.imageData is not dictionary with keys in set {'19', '38'}, // it must be an ImageData object. var sizeKey = iconSizes[0].toString(); var imageData = details.imageData; details.imageData = {}; details.imageData[sizeKey] = imageData; verifyImageData(details.imageData[sizeKey], iconSizes[0]); sendRequest(name, [details, callback], parameters, {nativeFunction: SetIconCommon}); } } else { throw new Error('imageData property has unexpected type.'); } } else if ('path' in details) { if (typeof details.path == 'object') { details.imageData = {}; var isEmpty = true; var processIconSize = function(index) { if (index == iconSizes.length) { delete details.path; if (isEmpty) throw new Error('The path property must not be empty.'); sendRequest(name, [details, callback], parameters, {nativeFunction: SetIconCommon}); return; } var sizeKey = iconSizes[index].toString(); if (!(sizeKey in details.path)) { processIconSize(index + 1); return; } isEmpty = false; loadImagePath(details.path[sizeKey], iconSizes[index], actionType, function(imageData) { details.imageData[sizeKey] = imageData; processIconSize(index + 1); }); } processIconSize(0); } else if (typeof details.path == 'string') { var sizeKey = iconSizes[0].toString(); details.imageData = {}; loadImagePath(details.path, iconSizes[0], actionType, function(imageData) { details.imageData[sizeKey] = imageData; delete details.path; sendRequest(name, [details, callback], parameters, {nativeFunction: SetIconCommon}); }); } else { throw new Error('The path property should contain either string or ' + 'dictionary of strings.'); } } else { throw new Error( 'Either the path or imageData property must be specified.'); } } exports.setIcon = setIcon;