Fix search results being clipped in app list.
[chromium-blink-merge.git] / ui / file_manager / image_loader / piex_loader.js
blobe506e3a4d03f208f61e9f521ce9cdfe7c45cbf86
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * @typedef {{
7  *   fulfill: function(PiexLoaderResponse):undefined,
8  *   reject: function(string):undefined}
9  * }}
10  */
11 var PiexRequestCallbacks;
13 /**
14  * Color space.
15  * @enum {string}
16  */
17 var ColorSpace = {
18   SRGB: 'sRgb',
19   ADOBE_RGB: 'adobeRgb'
22 /**
23  * @param {{id:number, thumbnail:!ArrayBuffer, orientation:number,
24  *          colorSpace: ColorSpace}}
25  *     data Data directly returned from NaCl module.
26  * @constructor
27  * @struct
28  */
29 function PiexLoaderResponse(data) {
30   /**
31    * @public {number}
32    * @const
33    */
34   this.id = data.id;
36   /**
37    * @public {!ArrayBuffer}
38    * @const
39    */
40   this.thumbnail = data.thumbnail;
42   /**
43    * @public {!ImageOrientation}
44    * @const
45    */
46   this.orientation =
47       ImageOrientation.fromExifOrientation(data.orientation);
49   /**
50    * @public {ColorSpace}
51    * @const
52    */
53   this.colorSpace = data.colorSpace;
56 /**
57  * @constructor
58  * @struct
59  */
60 function PiexLoader() {
61   /**
62    * @private {!Element}
63    * @const
64    */
65   this.naclModule_ = document.createElement('embed');
67   /**
68    * @private {!Promise}
69    * @const
70    */
71   this.naclPromise_ = new Promise(function(fulfill) {
72     chrome.fileManagerPrivate.isPiexLoaderEnabled(fulfill);
73   }).then(function(enabled) {
74     if (!enabled)
75       return Promise.reject('PiexLoader is not enabled for chromium build.');
76     return new Promise(function(fulfill, reject) {
77       var embed = this.naclModule_;
78       embed.setAttribute('type', 'application/x-pnacl');
79       // The extension nmf is not allowed to load. We uses .nmf.js instead.
80       embed.setAttribute('src', '/piex/piex.nmf.txt');
81       embed.width = 0;
82       embed.height = 0;
84       // The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
85       // and a 'message' event listener attached.  This wrapping method is used
86       // instead of attaching the event listeners directly to the <EMBED>
87       // element to ensure that the listeners are active before the NaCl module
88       // 'load' event fires.
89       var listenerContainer = document.createElement('div');
90       listenerContainer.appendChild(embed);
91       listenerContainer.addEventListener('load', fulfill, true);
92       listenerContainer.addEventListener(
93           'message', this.onMessage_.bind(this), true);
94       listenerContainer.addEventListener('error', function() {
95         reject(embed['lastError']);
96       }.bind(this), true);
97       listenerContainer.addEventListener('crash', function() {
98         reject('PiexLoader crashed.');
99       }.bind(this), true);
100       listenerContainer.style.height = '0px';
101       document.body.appendChild(listenerContainer);
102     }.bind(this));
103   }.bind(this));
105   /**
106    * @private {!Object<number, PiexRequestCallbacks>}
107    * @const
108    */
109   this.requests_ = {};
111   /**
112    * @private {number}
113    */
114   this.requestIdCount_ = 0;
118  * @param {Event} event
119  * @private
120  */
121 PiexLoader.prototype.onMessage_ = function(event) {
122   var id = event.data.id;
123   if (!event.data.error) {
124     var response = new PiexLoaderResponse(event.data);
125     this.requests_[id].fulfill(response);
126   } else {
127     this.requests_[id].reject(event.data.error);
128   }
129   delete this.requests_[id];
133  * Starts to load RAW image.
134  * @param {string} url
135  * @return {!Promise<!PiexLoaderResponse>}
136  */
137 PiexLoader.prototype.load = function(url) {
138   return this.naclPromise_.then(function() {
139     var message = {
140       id: this.requestIdCount_++,
141       name: 'loadThumbnail',
142       url: url
143     };
144     this.naclModule_.postMessage(message);
145     return new Promise(function(fulfill, reject) {
146       this.requests_[message.id] = {fulfill: fulfill, reject: reject};
147     }.bind(this));
148   }.bind(this));