146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var SetIconCommon = requireNative('setIcon').SetIconCommon;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var sendRequest = require('sendRequest').sendRequest;
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function loadImagePath(path, iconSize, actionType, callback) {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var img = new Image();
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  img.onerror = function() {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    console.error('Could not load ' + actionType + ' icon \'' +
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  path + '\'.');
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  img.onload = function() {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var canvas = document.createElement('canvas');
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas.width = img.width > iconSize ? iconSize : img.width;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas.height = img.height > iconSize ? iconSize : img.height;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var canvas_context = canvas.getContext('2d');
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas_context.clearRect(0, 0, canvas.width, canvas.height);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height);
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var imageData = canvas_context.getImageData(0, 0, canvas.width,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                canvas.height);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback(imageData);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  img.src = path;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function verifyImageData(imageData, iconSize) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that this at least looks like an ImageData element.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unfortunately, we cannot use instanceof because the ImageData
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // constructor is not public.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do this manually instead of using JSONSchema to avoid having these
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // properties show up in the doc.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!('width' in imageData) ||
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !('height' in imageData) ||
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !('data' in imageData)) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    throw new Error(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'The imageData property must contain an ImageData object or' +
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ' dictionary of ImageData objects.');
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (imageData.width > iconSize ||
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      imageData.height > iconSize) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    throw new Error(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'The imageData property must contain an ImageData object that ' +
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'is no larger than ' + iconSize + ' pixels square.');
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function setIcon(details, callback, name, parameters, actionType) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var iconSizes = [19, 38];
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ('iconIndex' in details) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sendRequest(name, [details, callback], parameters);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ('imageData' in details) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (typeof details.imageData == 'object') {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var isEmpty = true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (var i = 0; i < iconSizes.length; i++) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var sizeKey = iconSizes[i].toString();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (sizeKey in details.imageData) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          verifyImageData(details.imageData[sizeKey], iconSizes[i]);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          isEmpty =false;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!isEmpty) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sendRequest(name, [details, callback], parameters,
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    {nativeFunction: SetIconCommon});
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // If details.imageData is not dictionary with keys in set {'19', '38'},
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // it must be an ImageData object.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var sizeKey = iconSizes[0].toString();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var imageData = details.imageData;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        details.imageData = {};
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        details.imageData[sizeKey] = imageData;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        verifyImageData(details.imageData[sizeKey], iconSizes[0]);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sendRequest(name, [details, callback], parameters,
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    {nativeFunction: SetIconCommon});
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      throw new Error('imageData property has unexpected type.');
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ('path' in details) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (typeof details.path == 'object') {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      details.imageData = {};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var isEmpty = true;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      var processIconSize = function(index) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (index == iconSizes.length) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delete details.path;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (isEmpty)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw new Error('The path property must not be empty.');
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sendRequest(name, [details, callback], parameters,
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      {nativeFunction: SetIconCommon});
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var sizeKey = iconSizes[index].toString();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!(sizeKey in details.path)) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          processIconSize(index + 1);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        isEmpty = false;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        loadImagePath(details.path[sizeKey], iconSizes[index], actionType,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          function(imageData) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            details.imageData[sizeKey] = imageData;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processIconSize(index + 1);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          });
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      processIconSize(0);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (typeof details.path == 'string') {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var sizeKey = iconSizes[0].toString();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      details.imageData = {};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loadImagePath(details.path, iconSizes[0], actionType,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          function(imageData) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            details.imageData[sizeKey] = imageData;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            delete details.path;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sendRequest(name, [details, callback], parameters,
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        {nativeFunction: SetIconCommon});
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      });
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      throw new Error('The path property should contain either string or ' +
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      'dictionary of strings.');
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    throw new Error(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'Either the path or imageData property must be specified.');
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exports.setIcon = setIcon;
132