Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/browser/resources/file_manager/js/metadata/metadata_dispatcher.js

Issue 39123003: [Files.app] Split the JavaScript files into subdirectories: common, background, and foreground (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed test failure. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 'use strict';
6
7 // All of these scripts could be imported with a single call to importScripts,
8 // but then load and compile time errors would all be reported from the same
9 // line.
10 importScripts('metadata_parser.js');
11 importScripts('byte_reader.js');
12 importScripts('../util.js');
13
14 /**
15 * Dispatches metadata requests to the correct parser.
16 *
17 * @param {Object} port Worker port.
18 * @constructor
19 */
20 function MetadataDispatcher(port) {
21 this.port_ = port;
22 this.port_.onmessage = this.onMessage.bind(this);
23
24 // Make sure to update component_extension_resources.grd
25 // when adding new parsers.
26 importScripts('exif_parser.js');
27 importScripts('image_parsers.js');
28 importScripts('mpeg_parser.js');
29 importScripts('id3_parser.js');
30
31 var patterns = [];
32
33 this.parserInstances_ = [];
34 for (var i = 0; i < MetadataDispatcher.parserClasses_.length; i++) {
35 var parserClass = MetadataDispatcher.parserClasses_[i];
36 var parser = new parserClass(this);
37 this.parserInstances_.push(parser);
38 patterns.push(parser.urlFilter.source);
39 }
40
41 this.parserRegexp_ = new RegExp('(' + patterns.join('|') + ')', 'i');
42
43 this.messageHandlers_ = {
44 init: this.init_.bind(this),
45 request: this.request_.bind(this)
46 };
47 }
48
49 /**
50 * List of registered parser classes.
51 * @private
52 */
53 MetadataDispatcher.parserClasses_ = [];
54
55 /**
56 * @param {function} parserClass Parser constructor function.
57 */
58 MetadataDispatcher.registerParserClass = function(parserClass) {
59 MetadataDispatcher.parserClasses_.push(parserClass);
60 };
61
62 /**
63 * Verbose logging for the dispatcher.
64 *
65 * Individual parsers also take this as their default verbosity setting.
66 */
67 MetadataDispatcher.prototype.verbose = false;
68
69 /**
70 * |init| message handler.
71 * @private
72 */
73 MetadataDispatcher.prototype.init_ = function() {
74 // Inform our owner that we're done initializing.
75 // If we need to pass more data back, we can add it to the param array.
76 this.postMessage('initialized', [this.parserRegexp_]);
77 this.log('initialized with URL filter ' + this.parserRegexp_);
78 };
79
80 /**
81 * |request| message handler.
82 * @param {string} fileURL File URL.
83 * @private
84 */
85 MetadataDispatcher.prototype.request_ = function(fileURL) {
86 try {
87 this.processOneFile(fileURL, function callback(metadata) {
88 this.postMessage('result', [fileURL, metadata]);
89 }.bind(this));
90 } catch (ex) {
91 this.error(fileURL, ex);
92 }
93 };
94
95 /**
96 * Indicate to the caller that an operation has failed.
97 *
98 * No other messages relating to the failed operation should be sent.
99 * @param {...Object} var_args Arguments.
100 */
101 MetadataDispatcher.prototype.error = function(var_args) {
102 var ary = Array.apply(null, arguments);
103 this.postMessage('error', ary);
104 };
105
106 /**
107 * Send a log message to the caller.
108 *
109 * Callers must not parse log messages for control flow.
110 * @param {...Object} var_args Arguments.
111 */
112 MetadataDispatcher.prototype.log = function(var_args) {
113 var ary = Array.apply(null, arguments);
114 this.postMessage('log', ary);
115 };
116
117 /**
118 * Send a log message to the caller only if this.verbose is true.
119 * @param {...Object} var_args Arguments.
120 */
121 MetadataDispatcher.prototype.vlog = function(var_args) {
122 if (this.verbose)
123 this.log.apply(this, arguments);
124 };
125
126 /**
127 * Post a properly formatted message to the caller.
128 * @param {string} verb Message type descriptor.
129 * @param {Array.<Object>} args Arguments array.
130 */
131 MetadataDispatcher.prototype.postMessage = function(verb, args) {
132 this.port_.postMessage({verb: verb, arguments: args});
133 };
134
135 /**
136 * Message handler.
137 * @param {Event} event Event object.
138 */
139 MetadataDispatcher.prototype.onMessage = function(event) {
140 var data = event.data;
141
142 if (this.messageHandlers_.hasOwnProperty(data.verb)) {
143 this.messageHandlers_[data.verb].apply(this, data.arguments);
144 } else {
145 this.log('Unknown message from client: ' + data.verb, data);
146 }
147 };
148
149 /**
150 * @param {string} fileURL File URL.
151 * @param {function(Object)} callback Completion callback.
152 */
153 MetadataDispatcher.prototype.processOneFile = function(fileURL, callback) {
154 var self = this;
155 var currentStep = -1;
156
157 function nextStep(var_args) {
158 self.vlog('nextStep: ' + steps[currentStep + 1].name);
159 steps[++currentStep].apply(self, arguments);
160 }
161
162 var metadata;
163
164 function onError(err, stepName) {
165 self.error(fileURL, stepName || steps[currentStep].name, err.toString(),
166 metadata);
167 }
168
169 var steps =
170 [ // Step one, find the parser matching the url.
171 function detectFormat() {
172 for (var i = 0; i != self.parserInstances_.length; i++) {
173 var parser = self.parserInstances_[i];
174 if (fileURL.match(parser.urlFilter)) {
175 // Create the metadata object as early as possible so that we can
176 // pass it with the error message.
177 metadata = parser.createDefaultMetadata();
178 nextStep(parser);
179 return;
180 }
181 }
182 onError('unsupported format');
183 },
184
185 // Step two, turn the url into an entry.
186 function getEntry(parser) {
187 webkitResolveLocalFileSystemURL(
188 fileURL,
189 function(entry) { nextStep(entry, parser) },
190 onError);
191 },
192
193 // Step three, turn the entry into a file.
194 function getFile(entry, parser) {
195 entry.file(function(file) { nextStep(file, parser) }, onError);
196 },
197
198 // Step four, parse the file content.
199 function parseContent(file, parser) {
200 metadata.fileSize = file.size;
201 try {
202 parser.parse(file, metadata, callback, onError);
203 } catch (e) {
204 onError(e.stack);
205 }
206 }
207 ];
208
209 nextStep();
210 };
211
212 // Webworker spec says that the worker global object is called self. That's
213 // a terrible name since we use it all over the chrome codebase to capture
214 // the 'this' keyword in lambdas.
215 var global = self;
216
217 if (global.constructor.name == 'SharedWorkerGlobalScope') {
218 global.addEventListener('connect', function(e) {
219 var port = e.ports[0];
220 new MetadataDispatcher(port);
221 port.start();
222 });
223 } else {
224 // Non-shared worker.
225 new MetadataDispatcher(global);
226 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698