OLD | NEW |
| (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 /** | |
6 * @param {string} opt_workerPath path to the worker source JS file. | |
7 */ | |
8 function MetadataProvider(opt_workerPath) { | |
9 this.cache_ = {}; | |
10 | |
11 // Pass all URLs to the metadata reader until we have a correct filter. | |
12 this.urlFilter = /.*/; | |
13 | |
14 if (!opt_workerPath) { | |
15 var path = document.location.pathname; | |
16 opt_workerPath = document.location.origin + | |
17 path.substring(0, path.lastIndexOf('/') + 1) + | |
18 'js/metadata_dispatcher.js'; | |
19 } | |
20 | |
21 this.dispatcher_ = new Worker(opt_workerPath); | |
22 this.dispatcher_.onmessage = this.onMessage_.bind(this); | |
23 this.dispatcher_.postMessage({verb: 'init'}); | |
24 // Initialization is not complete until the Worker sends back the | |
25 // 'initialized' message. See below. | |
26 } | |
27 | |
28 MetadataProvider.prototype.fetch = function(url, callback) { | |
29 var cacheValue = this.cache_[url]; | |
30 | |
31 if (!cacheValue) { | |
32 // This is the first time anyone's asked, go get it. | |
33 if (url.match(this.urlFilter)) { | |
34 this.cache_[url] = [callback]; | |
35 this.dispatcher_.postMessage({verb: 'request', arguments: [url]}); | |
36 return; | |
37 } | |
38 // Cannot extract metadata for this file, return an empty map. | |
39 setTimeout(function() { callback({}) }, 0); | |
40 return; | |
41 } | |
42 | |
43 if (cacheValue instanceof Array) { | |
44 // Something is already pending, add to the list of observers. | |
45 cacheValue.push(callback); | |
46 return; | |
47 } | |
48 | |
49 if (cacheValue instanceof Object) { | |
50 // We already know the answer, let the caller know in a fresh call stack. | |
51 setTimeout(function() { callback(cacheValue) }, 0); | |
52 return; | |
53 } | |
54 | |
55 console.error('Unexpected metadata cache value:' + cacheValue); | |
56 }; | |
57 | |
58 MetadataProvider.prototype.reset = function(url) { | |
59 if (this.cache_[url] instanceof Array) { | |
60 console.error( | |
61 'Abandoned ' + this.cache_[url].length + ' metadata subscribers', | |
62 url); | |
63 } | |
64 delete this.cache_[url]; | |
65 }; | |
66 | |
67 | |
68 /** | |
69 * Dispatch a message from a metadata reader to the appropriate on* method. | |
70 */ | |
71 MetadataProvider.prototype.onMessage_ = function(event) { | |
72 var data = event.data; | |
73 | |
74 var methodName = | |
75 'on' + data.verb.substr(0, 1).toUpperCase() + data.verb.substr(1) + '_'; | |
76 | |
77 if (!(methodName in this)) { | |
78 console.log('Unknown message from metadata reader: ' + data.verb, data); | |
79 return; | |
80 } | |
81 | |
82 this[methodName].apply(this, data.arguments); | |
83 }; | |
84 | |
85 /** | |
86 * Handles the 'initialized' message from the metadata reader Worker. | |
87 */ | |
88 MetadataProvider.prototype.onInitialized_ = function(regexp) { | |
89 this.urlFilter = regexp; | |
90 }; | |
91 | |
92 MetadataProvider.prototype.onResult_ = function(url, metadata) { | |
93 var observers = this.cache_[url]; | |
94 if (!observers || !(observers instanceof Array)) { | |
95 console.error('Missing or invalid metadata observers: ' + url + ': ' + | |
96 observers); | |
97 return; | |
98 } | |
99 | |
100 console.log('metadata result:', metadata); | |
101 for (var i = 0; i < observers.length; i++) { | |
102 observers[i](metadata); | |
103 } | |
104 | |
105 this.cache_[url] = metadata; | |
106 }; | |
107 | |
108 MetadataProvider.prototype.onError_ = function(url, step, error, metadata) { | |
109 console.warn('metadata: ' + url + ': ' + step + ': ' + error); | |
110 this.onResult_(url, metadata || {}); | |
111 }; | |
112 | |
113 MetadataProvider.prototype.onLog_ = function(arglist) { | |
114 console.log.apply(console, ['metadata:'].concat(arglist)); | |
115 }; | |
OLD | NEW |