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

Side by Side Diff: third_party/document_image_extractor/src/dom_controller.js

Issue 1138123002: Update third_party/document_image_extractor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 goog.provide('image.collections.extension.DomController'); 5 goog.provide('image.collections.extension.domextractor.DomController');
6 6
7 goog.require('goog.Timer'); 7 goog.require('image.collections.extension.domextractor.DocumentImage');
8 goog.require('goog.array'); 8 goog.require('image.collections.extension.domextractor.DocumentVideo');
9 goog.require('goog.dom'); 9 goog.require('image.collections.extension.domextractor.DomUtils');
10 goog.require('goog.events.EventType');
11 goog.require('goog.log');
12 goog.require('gws.collections.common.Constants');
13 goog.require('image.collections.extension.Controller');
14 goog.require('image.collections.extension.DocumentImage');
15 goog.require('image.collections.extension.DocumentVideo');
16 goog.require('image.collections.extension.DomEvent');
17 10
18 goog.scope(function() { 11 goog.scope(function() {
19 var Constants = gws.collections.common.Constants; 12 var DocumentImage = image.collections.extension.domextractor.DocumentImage;
20 var DocumentImage = image.collections.extension.DocumentImage; 13 var DocumentVideo = image.collections.extension.domextractor.DocumentVideo;
21 var DocumentVideo = image.collections.extension.DocumentVideo; 14 var DomUtils = image.collections.extension.domextractor.DomUtils;
22 var DomEvent = image.collections.extension.DomEvent; 15
23 16
24 17
25 /** 18 /**
26 * This class handles page DOM events and implements DOM manipulation. 19 * This class handles page DOM events and implements DOM manipulation.
27 * It should be instantiated by a content script. 20 * It should be instantiated by a content script.
28 * TODO(busaryev): preloading may not be the best choice for mobile clients. 21 * TODO(busaryev): preloading may not be the best choice for mobile clients.
29 * @extends {image.collections.extension.Controller}
30 * @constructor 22 * @constructor
31 */ 23 */
32 image.collections.extension.DomController = function() { 24 image.collections.extension.domextractor.DomController = function() {
33 DomController.base(this, 'constructor');
34
35 /** @private {number} Number of DOM elements left. */ 25 /** @private {number} Number of DOM elements left. */
36 this.numElementsToProcess_ = 0; 26 this.numElementsToProcess_ = 0;
37 27
38 /** @private {number} The timeout id for goog.Timer.callOnce. */ 28 /**
39 this.timeoutId_ = -1; 29 * Promise returned by initialize() call. Resolves when all elements have been
30 * processed, or alternatively when a timeout has been reached.
31 * @private {!Promise}
32 */
33 this.initializedPromise_ = Promise.resolve();
34
35 /** @private {?function()} Resolve function for the initialized promise. */
36 this.initializedPromiseResolve_ = null;
40 }; 37 };
41 goog.inherits(image.collections.extension.DomController, 38 var DomController = image.collections.extension.domextractor.DomController;
42 image.collections.extension.Controller);
43 var DomController = image.collections.extension.DomController;
44
45
46 /** @private {goog.log.Logger} */
47 DomController.logger_ = goog.log.getLogger(
48 'image.collections.extension.DomController');
49 39
50 40
51 /** 41 /**
52 * @private {number} The number of milliseconds to wait for the load 42 * @private {number} The number of milliseconds to wait for the load
53 * event to occur before giving up. This ensures we are not wasting too much 43 * event to occur before giving up. This ensures we are not wasting too much
54 * time trying to get the clip. 44 * time trying to get the clip.
55 */ 45 */
56 DomController.LOAD_TIMEOUT_MS_ = 5000; 46 DomController.LOAD_TIMEOUT_MS_ = 5000;
57 47
58 48
59 /** @override */
60 DomController.prototype.initialize = function(parentEventTarget) {
61 DomController.base(this, 'initialize', parentEventTarget);
62
63 this.eventHandler.
64 listen(parentEventTarget, DomEvent.Type.INITIALIZE_DOM,
65 this.handleInitializeDom_);
66 };
67
68
69 /** 49 /**
70 * @param {DomEvent} e 50 * Initializes the DomController.
71 * @private 51 * @return {!Promise} A promise that resolves when all elements have been
52 * processed, or alternatively after a timeout has expired.
72 */ 53 */
73 DomController.prototype.handleInitializeDom_ = function(e) { 54 DomController.prototype.initialize = function() {
74 if (this.numElementsToProcess_ == 0) { 55 if (this.numElementsToProcess_ == 0) {
75 // Find <meta> and <link> tags that specify canonical page images, compute 56 // Find <meta> and <link> tags that specify canonical page images, compute
76 // image sizes with preloading and store them in element attributes. 57 // image sizes with preloading and store them in element attributes.
77 var doc = goog.dom.getDocument(); 58 var metaElements = document.getElementsByTagName('meta');
78 var metaElements = doc.getElementsByTagName('meta'); 59 var linkElements = document.getElementsByTagName('link');
79 var linkElements = doc.getElementsByTagName('link');
80 this.numElementsToProcess_ = metaElements.length + linkElements.length; 60 this.numElementsToProcess_ = metaElements.length + linkElements.length;
81 if (this.numElementsToProcess_ > 0) { 61 if (this.numElementsToProcess_ > 0) {
82 goog.array.forEach(metaElements, this.processMetaElement_, this); 62 this.initializedPromise_ =
83 goog.array.forEach(linkElements, this.processLinkElement_, this); 63 new Promise(function(resolve, reject) {
84 this.timeoutId_ = goog.Timer.callOnce( 64 this.initializedPromiseResolve_ = resolve;
85 goog.bind(this.dispatchEvent, this, DomEvent.Type.DOM_INITIALIZED), 65 }.bind(this));
66 for (var i = 0; i < metaElements.length; i++) {
67 this.processMetaElement_(metaElements[i]);
68 }
69 for (var i = 0; i < linkElements.length; i++) {
70 this.processLinkElement_(linkElements[i]);
71 }
72 setTimeout(this.initializedPromiseResolve_,
86 DomController.LOAD_TIMEOUT_MS_); 73 DomController.LOAD_TIMEOUT_MS_);
74 return this.initializedPromise_;
87 } else { 75 } else {
88 this.dispatchEvent(DomEvent.Type.DOM_INITIALIZED); 76 this.initializedPromise_ = Promise.resolve();
77 return this.initializedPromise_;
89 } 78 }
79 } else {
80 return this.initializedPromise_;
90 } 81 }
91 }; 82 };
92 83
93 84
94 /** 85 /**
95 * Tries to compute the size of the image specified in a <meta> element. 86 * Tries to compute the size of the image specified in a <meta> element.
96 * @param {Element} element The element to process. 87 * @param {Element} element The element to process.
97 * @param {number} index Index of the element in the array.
98 * @param {goog.array.ArrayLike} array The array.
99 * @private 88 * @private
100 */ 89 */
101 DomController.prototype.processMetaElement_ = function(element, index, array) { 90 DomController.prototype.processMetaElement_ = function(element) {
102 var url = ''; 91 var url = '';
103 if (element.hasAttribute('property')) { 92 if (element.hasAttribute('property')) {
104 switch (element.getAttribute('property').toLowerCase()) { 93 switch (element.getAttribute('property').toLowerCase()) {
105 case 'og:image': 94 case 'og:image':
106 url = element.getAttribute('content'); 95 url = element.getAttribute('content');
107 var siblings = goog.dom.getChildren(goog.dom.getParentElement(element)); 96 var siblings = DomUtils.getParentElement(element).children;
108 var width = this.getPropertyContent_(siblings, 'og:image:width'); 97 var width = this.getPropertyContent_(siblings, 'og:image:width');
109 var height = this.getPropertyContent_(siblings, 'og:image:height'); 98 var height = this.getPropertyContent_(siblings, 'og:image:height');
110 if (width > 0 && height > 0) { 99 if (width > 0 && height > 0) {
111 element.setAttribute(DocumentImage.CustomAttribute.WIDTH, width); 100 element.setAttribute(DocumentImage.CustomAttribute.WIDTH, width);
112 element.setAttribute(DocumentImage.CustomAttribute.HEIGHT, height); 101 element.setAttribute(DocumentImage.CustomAttribute.HEIGHT, height);
113 } 102 }
114 break; 103 break;
115 case 'og:video': 104 case 'og:video':
116 var children = goog.dom.getChildren(goog.dom.getParentElement(element)); 105 var children = DomUtils.getParentElement(element).children;
117 var width = this.getPropertyContent_(children, 'og:video:width'); 106 var width = this.getPropertyContent_(children, 'og:video:width');
118 var height = this.getPropertyContent_(children, 'og:video:height'); 107 var height = this.getPropertyContent_(children, 'og:video:height');
119 if (width > 0 && height > 0) { 108 if (width > 0 && height > 0) {
120 element.setAttribute(DocumentVideo.CustomAttribute.WIDTH, width); 109 element.setAttribute(DocumentVideo.CustomAttribute.WIDTH, width);
121 element.setAttribute(DocumentVideo.CustomAttribute.HEIGHT, height); 110 element.setAttribute(DocumentVideo.CustomAttribute.HEIGHT, height);
122 } 111 }
123 } 112 }
124 } else if (element.hasAttribute('name')) { 113 } else if (element.hasAttribute('name')) {
125 switch (element.getAttribute('name').toLowerCase()) { 114 switch (element.getAttribute('name').toLowerCase()) {
126 case 'msapplication-tileimage': 115 case 'msapplication-tileimage':
127 case 'twitter:image': 116 case 'twitter:image':
128 url = element.getAttribute('content'); 117 url = element.getAttribute('content');
129 } 118 }
130 } else if (element.hasAttribute('itemprop')) { 119 } else if (element.hasAttribute('itemprop')) {
131 switch (element.getAttribute('itemprop').toLowerCase()) { 120 switch (element.getAttribute('itemprop').toLowerCase()) {
132 case 'thumbnailurl': 121 case 'thumbnailurl':
133 url = element.getAttribute('href') || 122 url = element.getAttribute('href') ||
134 element.getAttribute('content'); 123 element.getAttribute('content');
135 } 124 }
136 } 125 }
137 this.maybeComputeAndStoreImageSize_(url, element); 126 this.maybeComputeAndStoreImageSize_(url, element);
138 }; 127 };
139 128
140 129
141 /** 130 /**
142 * Tries to compute the size of the image specified in a <link> element. 131 * Tries to compute the size of the image specified in a <link> element.
143 * @param {Element} element The element to process. 132 * @param {Element} element The element to process.
144 * @param {number} index Index of the element in the array.
145 * @param {goog.array.ArrayLike} array The array.
146 * @private 133 * @private
147 */ 134 */
148 DomController.prototype.processLinkElement_ = function(element, index, array) { 135 DomController.prototype.processLinkElement_ = function(element) {
149 var url = ''; 136 var url = '';
150 if (element.hasAttribute('rel')) { 137 if (element.hasAttribute('rel')) {
151 switch (element.getAttribute('rel').toLowerCase()) { 138 switch (element.getAttribute('rel').toLowerCase()) {
152 case 'apple-touch-icon-precomposed': 139 case 'apple-touch-icon-precomposed':
153 case 'apple-touch-icon': 140 case 'apple-touch-icon':
154 case 'image_src': 141 case 'image_src':
155 url = element.getAttribute('href'); 142 url = element.getAttribute('href');
156 } 143 }
157 } else if (element.hasAttribute('itemprop')) { 144 } else if (element.hasAttribute('itemprop')) {
158 switch (element.getAttribute('itemprop').toLowerCase()) { 145 switch (element.getAttribute('itemprop').toLowerCase()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 * Tries to store the size of the element image in custom element tags. 177 * Tries to store the size of the element image in custom element tags.
191 * @param {string} url Image url (empty if the element defines no image). 178 * @param {string} url Image url (empty if the element defines no image).
192 * @param {!Element} element Element. 179 * @param {!Element} element Element.
193 * @private 180 * @private
194 */ 181 */
195 DomController.prototype.maybeComputeAndStoreImageSize_ = function( 182 DomController.prototype.maybeComputeAndStoreImageSize_ = function(
196 url, element) { 183 url, element) {
197 var CustomAttribute = DocumentImage.CustomAttribute; 184 var CustomAttribute = DocumentImage.CustomAttribute;
198 if (url && (!element.hasAttribute(CustomAttribute.WIDTH) || 185 if (url && (!element.hasAttribute(CustomAttribute.WIDTH) ||
199 !element.hasAttribute(CustomAttribute.HEIGHT))) { 186 !element.hasAttribute(CustomAttribute.HEIGHT))) {
200 this.computeImageSize_(url, goog.bind(this.storeImageSize_, this, element)); 187 this.computeImageSize_(url, this.storeImageSize_.bind(this, element));
201 } else { 188 } else {
202 this.maybeDispatchDomInitialized_(); 189 this.maybeResolveInitializedPromise_();
203 } 190 }
204 }; 191 };
205 192
206 193
207 /** 194 /**
208 * Computes the image size with preloading and returns it via a callback. 195 * Computes the image size with preloading and returns it via a callback.
209 * @param {string} url Image url. 196 * @param {string} url Image url.
210 * @param {!function(number, number)} callback A callback. 197 * @param {!function(number, number)} callback A callback.
211 * @private 198 * @private
212 */ 199 */
213 DomController.prototype.computeImageSize_ = function(url, callback) { 200 DomController.prototype.computeImageSize_ = function(url, callback) {
214 var image = new Image(); 201 var image = new Image();
215 this.eventHandler.listenOnce(image, 202
216 [goog.events.EventType.LOAD, goog.events.EventType.ERROR], 203 var that = this;
217 goog.bind(this.handleImageLoadOrError_, this, callback)); 204 var handleImageLoadOrError = function(e) {
205 if (e.type == 'load') {
206 callback(image.naturalWidth, image.naturalHeight);
207 }
208 that.maybeResolveInitializedPromise_();
209 image.removeEventListener('load', handleImageLoadOrError);
210 image.removeEventListener('error', handleImageLoadOrError);
211 };
212
213 image.addEventListener('load', handleImageLoadOrError);
214 image.addEventListener('error', handleImageLoadOrError);
218 image.src = url; 215 image.src = url;
219 }; 216 };
220 217
221 218
222 /** 219 /**
223 * Handles image LOAD and ERROR events. 220 * Resolves the initialized promise if all elements have been processed.
224 * @param {!function(number, number)} callback A callback.
225 * @param {goog.events.Event} e Image event.
226 * @private 221 * @private
227 */ 222 */
228 DomController.prototype.handleImageLoadOrError_ = function(callback, e) { 223 DomController.prototype.maybeResolveInitializedPromise_ = function() {
229 var image = /** @type {!Image} */ (e.target);
230 if (e.type == goog.events.EventType.LOAD) {
231 callback(image.naturalWidth, image.naturalHeight);
232 } else {
233 goog.log.warning(DomController.logger_,
234 'Failed to load image ' + image.src);
235 }
236 this.maybeDispatchDomInitialized_();
237 };
238
239
240 /**
241 * Dispatches the DOM_INITIALIZED event if all elements have been processed.
242 * @private
243 */
244 DomController.prototype.maybeDispatchDomInitialized_ = function() {
245 if (--this.numElementsToProcess_ == 0) { 224 if (--this.numElementsToProcess_ == 0) {
246 if (this.timeoutId_ != -1) { 225 this.initializedPromiseResolve_();
247 goog.Timer.clear(this.timeoutId_);
248 this.timeoutId_ = -1;
249 }
250 this.dispatchEvent(DomEvent.Type.DOM_INITIALIZED);
251 } 226 }
252 }; 227 };
253 228
254 229
255 /** 230 /**
256 * Stores the image size in custom element attributes. 231 * Stores the image size in custom element attributes.
257 * @param {!Element} element An element defining the image url. 232 * @param {!Element} element An element defining the image url.
258 * @param {number} width Image width. 233 * @param {number} width Image width.
259 * @param {number} height Image height. 234 * @param {number} height Image height.
260 * @private 235 * @private
261 */ 236 */
262 DomController.prototype.storeImageSize_ = function(element, width, height) { 237 DomController.prototype.storeImageSize_ = function(element, width, height) {
263 var CustomAttribute = DocumentImage.CustomAttribute; 238 var CustomAttribute = DocumentImage.CustomAttribute;
264 element.setAttribute(CustomAttribute.WIDTH, width); 239 element.setAttribute(CustomAttribute.WIDTH, width);
265 element.setAttribute(CustomAttribute.HEIGHT, height); 240 element.setAttribute(CustomAttribute.HEIGHT, height);
266 }; 241 };
267 242
268 }); // goog.scope 243 }); // goog.scope
OLDNEW
« no previous file with comments | « third_party/document_image_extractor/src/document_video.js ('k') | third_party/document_image_extractor/src/dom_event.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698