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

Side by Side Diff: chrome/browser/resources/print_preview/search/provisional_destination_resolver.js

Issue 1144983002: Introduce concept of provisional destinations to print preview (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 6 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
(Empty)
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.
4
5 cr.define('print_preview', function() {
6 'use strict';
7
8 /** @enum {string} */
9 var ResolverState = {
10 INITIAL: 'INITIAL',
11 ACTIVE: 'ACTIVE',
12 GRANTING_PERMISSION: 'GRANTING_PERMISSION',
13 ERROR: 'ERROR',
14 DONE: 'DONE'
15 };
16
17 /**
18 * Utility class for bundling a promise object with it's resolver methods.
19 * @param {!Promise<!print_preview.Destination>} promise A promise returning
20 * a destination.
21 * @param {function(!print_preview.Destination)} resolve Function resolving
22 * the promise.
23 * @param {function()} reject Function for rejecting the promise.
24 * @constructor @struct
25 */
26 function PromiseResolver(promise, resolve, reject) {
27 /** @type {!Promise<!print_preview.Destination>} */
28 this.promise = promise;
29 /** @type {function(!print_preview.Destination)} */
30 this.resolve = resolve;
31 /** @type {function()} */
32 this.reject = reject;
33 }
34
35 /**
36 * Create a Promise and an associated PromiseResolver.
37 * @return {!PromiseResolver}
38 */
39 PromiseResolver.create = function() {
40 var reject = null;
41 var resolve = null;
42 /** @type {!Promise<!print_preview.Destination>} */
43 var promise = new Promise(function(resolvePromise, rejectPromise) {
44 resolve = /** @type {function(!print_preview.Destination)}*/(
45 resolvePromise);
46 reject = /** @type {function()} */(rejectPromise);
47 });
48
49 return new PromiseResolver(promise, resolve, reject);
50 };
51
52 /**
53 * Overlay used to resolve a provisional extension destination. The user is
54 * prompted to allow print preview to grant a USB device access to an
55 * extension associated with the destination. If user agrees destination
56 * resolvement is attempted (which includes granting the extension USB access
57 * and requesting destination description from the extension). The overlay is
58 * hidden when destination resolving is done.
59 *
60 * @param {!print_preview.DestinationStore} destinationStore The destination
61 * store containing the destination. Used as a proxy to native layer for
62 * resolving the destination.
63 * @param {!print_preview.Destination} destination The destination that has
64 * to be resolved.
65 * @constructor
66 * @extends {print_preview.Overlay}
67 */
68 function ProvisionalDestinationResolver(destinationStore, destination) {
69 print_preview.Overlay.call(this);
70
71 /** @private {!print_preview.DestinationStore} */
72 this.destinationStore_ = destinationStore;
73 /** @private {!print_preview.Destination} */
74 this.destination_ = destination;
75
76 /** @private {ResolverState} */
77 this.state_ = ResolverState.INITIAL;
78
79 /**
80 * Promise resolver for promise returned by {@code this.run}.
81 * @private {?PromiseResolver}
82 */
83 this.promiseResolver_ = null;
84 }
85
86 /**
87 * @param {!print_preview.DestinationStore} store
88 * @param {!print_preview.Destination} destination
89 * @return {?ProvisionalDestinationResolver}
90 */
91 ProvisionalDestinationResolver.create = function(store, destination) {
92 if (destination.provisionalType !=
93 print_preview.Destination.ProvisionalType.NEEDS_USB_PERMISSION) {
94 return null;
95 }
96 return new ProvisionalDestinationResolver(store, destination);
97 };
98
99 ProvisionalDestinationResolver.prototype = {
100 __proto__: print_preview.Overlay.prototype,
101
102 /** @override */
103 enterDocument: function() {
104 print_preview.Overlay.prototype.enterDocument.call(this);
105
106 this.tracker.add(
107 this.getChildElement('.usb-permission-ok-button'),
108 'click',
109 this.startResolveDestination_.bind(this));
110 this.tracker.add(
111 this.getChildElement('.cancel'),
112 'click',
113 this.cancel.bind(this));
114
115 this.tracker.add(
116 this.destinationStore_,
117 print_preview.DestinationStore.EventType
118 .PROVISIONAL_DESTINATION_RESOLVED,
119 this.onDestinationResolved_.bind(this));
120 },
121
122 /** @override */
123 onSetVisibleInternal: function(visible) {
124 if (visible) {
125 assert(this.state_ == ResolverState.INITIAL,
126 'Showing overlay while not in initial state.');
127 assert(!this.promiseResolver_, 'Promise resolver already set.');
128 this.setState_(ResolverState.ACTIVE);
129 this.promiseResolver_ = PromiseResolver.create();
130 this.getChildElement('.default').focus();
131 } else if (this.state_ != ResolverState.DONE) {
132 assert(this.state_ != ResolverState.INITIAL, 'Hiding in initial state');
133 this.setState_(ResolverState.DONE);
134 this.promiseResolver_.reject();
135 this.promiseResolver_ = null;
136 }
137 },
138
139 /** @override */
140 createDom: function() {
141 this.setElementInternal(this.cloneTemplateInternal(
142 'extension-usb-resolver'));
143
144 var extNameEl = this.getChildElement('.usb-permission-extension-name');
145 extNameEl.title = this.destination_.extensionName;
146 extNameEl.textContent = this.destination_.extensionName;
147
148 var extIconEl = this.getChildElement('.usb-permission-extension-icon');
149 extIconEl.style.backgroundImage = '-webkit-image-set(' +
150 'url(chrome://extension-icon/' +
151 this.destination_.extensionId + '/24/1) 1x,' +
152 'url(chrome://extension-icon/' +
153 this.destination_.extensionId + '/48/1) 2x)';
154 },
155
156 /**
157 * Handler for click on OK button. It initiates destination resolving.
158 * @private
159 */
160 startResolveDestination_: function() {
161 assert(this.state_ == ResolverState.ACTIVE,
162 'Invalid state in request grant permission');
163
164 this.setState_(ResolverState.GRANTING_PERMISSION);
165 this.destinationStore_.resolveProvisionalDestination(this.destination_);
166 },
167
168 /**
169 * Handler for PROVISIONAL_DESTINATION_RESOLVED event. It finalizes the
170 * resolver state once the destination associated with the resolver gets
171 * resolved.
172 * @param {Event} event
173 * @private
174 */
175 onDestinationResolved_: function(event) {
176 if (this.state_ == ResolverState.DONE)
177 return;
178
179 if (event.provisionalId != this.destination_.id)
180 return;
181
182 if (event.destination) {
183 this.setState_(ResolverState.DONE);
184 this.promiseResolver_.resolve(event.destination);
185 this.promiseResolver_ = null;
186 this.setIsVisible(false);
187 } else {
188 this.setState_(ResolverState.ERROR);
189 }
190 },
191
192 /**
193 * Sets new resolver state and updates the UI accordingly.
194 * @param {ResolverState} state
195 * @private
196 */
197 setState_: function(state) {
198 if (this.state_ == state)
199 return;
200
201 this.state_ = state;
202 this.updateUI_();
203 },
204
205 /**
206 * Updates the resolver overlay UI to match the resolver state.
207 * @private
208 */
209 updateUI_: function() {
210 this.getChildElement('.usb-permission-ok-button').hidden =
211 this.state_ == ResolverState.ERROR;
212 this.getChildElement('.usb-permission-ok-button').disabled =
213 this.state_ != ResolverState.ACTIVE;
214
215 // If OK button is disabled, make sure Cancel button gets focus.
216 if (this.state_ != ResolverState.ACTIVE)
217 this.getChildElement('.cancel').focus();
218
219 this.getChildElement('.throbber-placeholder').classList.toggle(
220 'throbber',
221 this.state_ == ResolverState.GRANTING_PERMISSION);
222
223 this.getChildElement('.usb-permission-extension-desc').hidden =
224 this.state_ == ResolverState.ERROR;
225
226 this.getChildElement('.usb-permission-message').textContent =
227 this.state_ == ResolverState.ERROR ?
228 loadTimeData.getStringF('resolveExtensionUSBErrorMessage',
229 this.destination_.extensionName) :
230 loadTimeData.getString('resolveExtensionUSBPermissionMessage');
231 },
232
233 /**
234 * Initiates and shows the resolver overlay.
235 * @param {!HTMLElement} parent The element that should parent the resolver
236 * UI.
237 * @return {!Promise<!print_preview.Destination>} Promise that will be
238 * fulfilled when the destination resolving is finished.
239 */
240 run: function(parent) {
241 this.render(parent);
242 this.setIsVisible(true);
243
244 assert(this.promiseResolver_, 'Promise resolver not created.');
245 return this.promiseResolver_.promise;
246 }
247 };
248
249 return {
250 ProvisionalDestinationResolver: ProvisionalDestinationResolver
251 };
252 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698