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

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

Issue 9583009: [File Manager] Cleanup: Moving js/css/html files to dedicated directories (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 2011->2012 Created 8 years, 9 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) 2011 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 // Webworker spec says that the worker global object is called self. That's
6 // a terrible name since we use it all over the chrome codebase to capture
7 // the 'this' keyword in lambdas.
8 var global = self;
9
10 // All of these scripts could be imported with a single call to importScripts,
11 // but then load and compile time errors would all be reported from the same
12 // line.
13 importScripts('metadata_parser.js');
14 importScripts('byte_reader.js');
15
16 /**
17 * Dispatches metadata requests to the correct parser.
18 */
19 function MetadataDispatcher() {
20 // Make sure to ipdate component_extension_resources.grd
21 // when adding new parsers.
22 importScripts('exif_parser.js');
23 importScripts('image_parsers.js');
24 importScripts('mpeg_parser.js');
25 importScripts('id3_parser.js');
26
27 var patterns = ['blob:']; // We use blob urls in gallery_demo.js
28
29 for (var i = 0; i < MetadataDispatcher.parserClasses_.length; i++) {
30 var parserClass = MetadataDispatcher.parserClasses_[i];
31 var parser = new parserClass(this);
32 this.parserInstances_.push(parser);
33 patterns.push(parser.urlFilter.source);
34 }
35
36 this.parserRegexp_ = new RegExp('(' + patterns.join('|') + ')', 'i');
37 }
38
39 MetadataDispatcher.parserClasses_ = [];
40
41 MetadataDispatcher.registerParserClass = function(parserClass) {
42 MetadataDispatcher.parserClasses_.push(parserClass);
43 };
44
45 MetadataDispatcher.prototype.parserInstances_ = [];
46
47 /**
48 * Verbose logging for the dispatcher.
49 *
50 * Individual parsers also take this as their default verbosity setting.
51 */
52 MetadataDispatcher.prototype.verbose = false;
53
54 MetadataDispatcher.prototype.messageHandlers = {
55 init: function() {
56 // Inform our owner that we're done initializing.
57 // If we need to pass more data back, we can add it to the param array.
58 this.postMessage('initialized', [this.parserRegexp_]);
59 this.log('initialized with URL filter ' + this.parserRegexp_);
60 },
61
62 request: function(fileURL) {
63 var self = this;
64
65 try {
66 this.processOneFile(fileURL, function callback(metadata) {
67 self.postMessage('result', [fileURL, metadata]);
68 });
69 } catch (ex) {
70 this.error(fileURL, ex);
71 }
72 }
73 };
74
75 /**
76 * Indicate to the caller that an operation has failed.
77 *
78 * No other messages relating to the failed operation should be sent.
79 */
80 MetadataDispatcher.prototype.error = function(var_args) {
81 var ary = Array.apply(null, arguments);
82 this.postMessage('error', ary);
83 };
84
85 /**
86 * Send a log message to the caller.
87 *
88 * Callers must not parse log messages for control flow.
89 */
90 MetadataDispatcher.prototype.log = function(var_args) {
91 var ary = Array.apply(null, arguments);
92 this.postMessage('log', ary);
93 };
94
95 /**
96 * Send a log message to the caller only if this.verbose is true.
97 */
98 MetadataDispatcher.prototype.vlog = function(var_args) {
99 if (this.verbose)
100 this.log.apply(this, arguments);
101 };
102
103 /**
104 * Post a properly formatted message to the caller.
105 */
106 MetadataDispatcher.prototype.postMessage = function(verb, arguments) {
107 global.postMessage({verb: verb, arguments: arguments});
108 };
109
110 MetadataDispatcher.prototype.onMessage = function(event) {
111 var data = event.data;
112
113 if (this.messageHandlers.hasOwnProperty(data.verb)) {
114 this.messageHandlers[data.verb].apply(this, data.arguments);
115 } else {
116 this.log('Unknown message from client: ' + data.verb, data);
117 }
118 };
119
120 MetadataDispatcher.prototype.processOneFile = function(fileURL, callback) {
121 var self = this;
122 var currentStep = -1;
123
124 function nextStep(var_args) {
125 self.vlog('nextStep: ' + steps[currentStep + 1].name);
126 steps[++currentStep].apply(self, arguments);
127 }
128
129 var metadata;
130
131 function onError(err, stepName) {
132 self.error(fileURL, stepName || steps[currentStep].name, err.toString(),
133 metadata);
134 }
135
136 var steps =
137 [ // Step one, find the parser matching the url.
138 function detectFormat() {
139 for (var i = 0; i != self.parserInstances_.length; i++) {
140 var parser = self.parserInstances_[i];
141 if (fileURL.match(parser.urlFilter)) {
142 // Create the metadata object as early as possible so that we can
143 // pass it with the error message.
144 metadata = parser.createDefaultMetadata();
145 nextStep(parser);
146 return;
147 }
148 }
149 onError('unsupported format');
150 },
151
152 // Step two, turn the url into an entry.
153 function getEntry(parser) {
154 webkitResolveLocalFileSystemURL(
155 fileURL,
156 function(entry) { nextStep(entry, parser) },
157 onError);
158 },
159
160 // Step three, turn the entry into a file.
161 function getFile(entry, parser) {
162 entry.file(function(file) { nextStep(file, parser) }, onError);
163 },
164
165 // Step four, parse the file content.
166 function parseContent(file, parser) {
167 metadata.fileSize = file.size;
168 parser.parse(file, metadata, callback, onError);
169 }
170 ];
171
172 if (fileURL.indexOf('blob:') == 0) {
173 // Blob urls require different steps:
174 steps =
175 [ // Read the blob into an array buffer and get the content type
176 function readBlob() {
177 var xhr = new XMLHttpRequest();
178 xhr.open('GET', fileURL, true);
179 xhr.responseType = 'arraybuffer';
180 xhr.onload = function(e) {
181 if (xhr.status == 200) {
182 nextStep(xhr.getResponseHeader('Content-Type'), xhr.response);
183 } else {
184 onError('HTTP ' + xhr.status);
185 }
186 };
187 xhr.send();
188 },
189
190 // Step two, find the parser matching the content type.
191 function detectFormat(mimeType, arrayBuffer) {
192 for (var i = 0; i != self.parserInstances_.length; i++) {
193 var parser = self.parserInstances_[i];
194 if (parser.acceptsMimeType(mimeType)) {
195 metadata = parser.createDefaultMetadata();
196 var blobBuilder = new WebKitBlobBuilder();
197 blobBuilder.append(arrayBuffer);
198 nextStep(blobBuilder.getBlob(), parser);
199 return;
200 }
201 }
202 callback({}); // Unrecognized mime type.
203 },
204
205 // Reuse the last step from the standard sequence.
206 steps[steps.length - 1]
207 ];
208 }
209
210 nextStep();
211 };
212
213 var dispatcher = new MetadataDispatcher();
214 global.onmessage = dispatcher.onMessage.bind(dispatcher);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698