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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
5 /** 4 /**
6 * @constructor 5 * @unrestricted
7 * @extends {WebInspector.VBox}
8 */ 6 */
9 WebInspector.DeviceModeView = function() 7 WebInspector.DeviceModeView = class extends WebInspector.VBox {
10 { 8 constructor() {
11 WebInspector.VBox.call(this, true); 9 super(true);
12 this.setMinimumSize(150, 150); 10 this.setMinimumSize(150, 150);
13 this.element.classList.add("device-mode-view"); 11 this.element.classList.add('device-mode-view');
14 this.registerRequiredCSS("emulation/deviceModeView.css"); 12 this.registerRequiredCSS('emulation/deviceModeView.css');
15 WebInspector.Tooltip.addNativeOverrideContainer(this.contentElement); 13 WebInspector.Tooltip.addNativeOverrideContainer(this.contentElement);
16 14
17 this._model = new WebInspector.DeviceModeModel(this._updateUI.bind(this)); 15 this._model = new WebInspector.DeviceModeModel(this._updateUI.bind(this));
18 this._mediaInspector = new WebInspector.MediaQueryInspector(() => this._mode l.appliedDeviceSize().width, this._model.setWidth.bind(this._model)); 16 this._mediaInspector = new WebInspector.MediaQueryInspector(
19 this._showMediaInspectorSetting = WebInspector.settings.moduleSetting("showM ediaQueryInspector"); 17 () => this._model.appliedDeviceSize().width, this._model.setWidth.bind(t his._model));
18 this._showMediaInspectorSetting = WebInspector.settings.moduleSetting('showM ediaQueryInspector');
20 this._showMediaInspectorSetting.addChangeListener(this._updateUI, this); 19 this._showMediaInspectorSetting.addChangeListener(this._updateUI, this);
21 this._showRulersSetting = WebInspector.settings.moduleSetting("emulation.sho wRulers"); 20 this._showRulersSetting = WebInspector.settings.moduleSetting('emulation.sho wRulers');
22 this._showRulersSetting.addChangeListener(this._updateUI, this); 21 this._showRulersSetting.addChangeListener(this._updateUI, this);
23 22
24 this._topRuler = new WebInspector.DeviceModeView.Ruler(true, this._model.set WidthAndScaleToFit.bind(this._model)); 23 this._topRuler = new WebInspector.DeviceModeView.Ruler(true, this._model.set WidthAndScaleToFit.bind(this._model));
25 this._topRuler.element.classList.add("device-mode-ruler-top"); 24 this._topRuler.element.classList.add('device-mode-ruler-top');
26 this._leftRuler = new WebInspector.DeviceModeView.Ruler(false, this._model.s etHeightAndScaleToFit.bind(this._model)); 25 this._leftRuler =
27 this._leftRuler.element.classList.add("device-mode-ruler-left"); 26 new WebInspector.DeviceModeView.Ruler(false, this._model.setHeightAndSca leToFit.bind(this._model));
27 this._leftRuler.element.classList.add('device-mode-ruler-left');
28 this._createUI(); 28 this._createUI();
29 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.Zo omChanged, this._zoomChanged, this); 29 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.Zo omChanged, this._zoomChanged, this);
30 }; 30 }
31 31
32 WebInspector.DeviceModeView.prototype = { 32 _createUI() {
33 _createUI: function() 33 this._toolbar =
34 { 34 new WebInspector.DeviceModeToolbar(this._model, this._showMediaInspector Setting, this._showRulersSetting);
35 this._toolbar = new WebInspector.DeviceModeToolbar(this._model, this._sh owMediaInspectorSetting, this._showRulersSetting); 35 this.contentElement.appendChild(this._toolbar.element());
36 this.contentElement.appendChild(this._toolbar.element()); 36
37 37 this._contentClip = this.contentElement.createChild('div', 'device-mode-cont ent-clip vbox');
38 this._contentClip = this.contentElement.createChild("div", "device-mode- content-clip vbox"); 38 this._responsivePresetsContainer = this._contentClip.createChild('div', 'dev ice-mode-presets-container');
39 this._responsivePresetsContainer = this._contentClip.createChild("div", "device-mode-presets-container"); 39 this._populatePresetsContainer();
40 this._populatePresetsContainer(); 40 this._mediaInspectorContainer = this._contentClip.createChild('div', 'device -mode-media-container');
41 this._mediaInspectorContainer = this._contentClip.createChild("div", "de vice-mode-media-container"); 41 this._contentArea = this._contentClip.createChild('div', 'device-mode-conten t-area');
42 this._contentArea = this._contentClip.createChild("div", "device-mode-co ntent-area"); 42
43 43 this._outlineImage = this._contentArea.createChild('img', 'device-mode-outli ne-image hidden fill');
44 this._outlineImage = this._contentArea.createChild("img", "device-mode-o utline-image hidden fill"); 44 this._outlineImage.addEventListener('load', this._onImageLoaded.bind(this, t his._outlineImage, true), false);
45 this._outlineImage.addEventListener("load", this._onImageLoaded.bind(thi s, this._outlineImage, true), false); 45 this._outlineImage.addEventListener('error', this._onImageLoaded.bind(this, this._outlineImage, false), false);
46 this._outlineImage.addEventListener("error", this._onImageLoaded.bind(th is, this._outlineImage, false), false); 46
47 47 this._screenArea = this._contentArea.createChild('div', 'device-mode-screen- area');
48 this._screenArea = this._contentArea.createChild("div", "device-mode-scr een-area"); 48 this._screenImage = this._screenArea.createChild('img', 'device-mode-screen- image hidden');
49 this._screenImage = this._screenArea.createChild("img", "device-mode-scr een-image hidden"); 49 this._screenImage.addEventListener('load', this._onImageLoaded.bind(this, th is._screenImage, true), false);
50 this._screenImage.addEventListener("load", this._onImageLoaded.bind(this , this._screenImage, true), false); 50 this._screenImage.addEventListener('error', this._onImageLoaded.bind(this, t his._screenImage, false), false);
51 this._screenImage.addEventListener("error", this._onImageLoaded.bind(thi s, this._screenImage, false), false); 51
52 52 this._bottomRightResizerElement =
53 this._bottomRightResizerElement = this._screenArea.createChild("div", "d evice-mode-resizer device-mode-bottom-right-resizer"); 53 this._screenArea.createChild('div', 'device-mode-resizer device-mode-bot tom-right-resizer');
54 this._bottomRightResizerElement.createChild("div", ""); 54 this._bottomRightResizerElement.createChild('div', '');
55 this._createResizer(this._bottomRightResizerElement, 2, 1); 55 this._createResizer(this._bottomRightResizerElement, 2, 1);
56 56
57 this._bottomLeftResizerElement = this._screenArea.createChild("div", "de vice-mode-resizer device-mode-bottom-left-resizer"); 57 this._bottomLeftResizerElement =
58 this._bottomLeftResizerElement.createChild("div", ""); 58 this._screenArea.createChild('div', 'device-mode-resizer device-mode-bot tom-left-resizer');
59 this._createResizer(this._bottomLeftResizerElement, -2, 1); 59 this._bottomLeftResizerElement.createChild('div', '');
60 60 this._createResizer(this._bottomLeftResizerElement, -2, 1);
61 this._rightResizerElement = this._screenArea.createChild("div", "device- mode-resizer device-mode-right-resizer"); 61
62 this._rightResizerElement.createChild("div", ""); 62 this._rightResizerElement = this._screenArea.createChild('div', 'device-mode -resizer device-mode-right-resizer');
63 this._createResizer(this._rightResizerElement, 2, 0); 63 this._rightResizerElement.createChild('div', '');
64 64 this._createResizer(this._rightResizerElement, 2, 0);
65 this._leftResizerElement = this._screenArea.createChild("div", "device-m ode-resizer device-mode-left-resizer"); 65
66 this._leftResizerElement.createChild("div", ""); 66 this._leftResizerElement = this._screenArea.createChild('div', 'device-mode- resizer device-mode-left-resizer');
67 this._createResizer(this._leftResizerElement, -2, 0); 67 this._leftResizerElement.createChild('div', '');
68 68 this._createResizer(this._leftResizerElement, -2, 0);
69 this._bottomResizerElement = this._screenArea.createChild("div", "device -mode-resizer device-mode-bottom-resizer"); 69
70 this._bottomResizerElement.createChild("div", ""); 70 this._bottomResizerElement = this._screenArea.createChild('div', 'device-mod e-resizer device-mode-bottom-resizer');
71 this._createResizer(this._bottomResizerElement, 0, 1); 71 this._bottomResizerElement.createChild('div', '');
72 this._bottomResizerElement.addEventListener("dblclick", this._model.setH eight.bind(this._model, 0), false); 72 this._createResizer(this._bottomResizerElement, 0, 1);
73 this._bottomResizerElement.title = WebInspector.UIString("Double-click f or full height"); 73 this._bottomResizerElement.addEventListener('dblclick', this._model.setHeigh t.bind(this._model, 0), false);
74 74 this._bottomResizerElement.title = WebInspector.UIString('Double-click for f ull height');
75 this._pageArea = this._screenArea.createChild("div", "device-mode-page-a rea"); 75
76 this._pageArea.createChild("content"); 76 this._pageArea = this._screenArea.createChild('div', 'device-mode-page-area' );
77 }, 77 this._pageArea.createChild('content');
78 78 }
79 _populatePresetsContainer: function() 79
80 { 80 _populatePresetsContainer() {
81 var sizes = [320, 375, 425, 768, 1024, 1440, 2560]; 81 var sizes = [320, 375, 425, 768, 1024, 1440, 2560];
82 var titles = [WebInspector.UIString("Mobile S"), 82 var titles = [
83 WebInspector.UIString("Mobile M"), 83 WebInspector.UIString('Mobile S'), WebInspector.UIString('Mobile M'), WebI nspector.UIString('Mobile L'),
84 WebInspector.UIString("Mobile L"), 84 WebInspector.UIString('Tablet'), WebInspector.UIString('Laptop'), WebInspe ctor.UIString('Laptop L'),
85 WebInspector.UIString("Tablet"), 85 WebInspector.UIString('4K')
86 WebInspector.UIString("Laptop"), 86 ];
87 WebInspector.UIString("Laptop L"), 87 this._presetBlocks = [];
88 WebInspector.UIString("4K")]; 88 var inner = this._responsivePresetsContainer.createChild('div', 'device-mode -presets-container-inner');
89 this._presetBlocks = []; 89 for (var i = sizes.length - 1; i >= 0; --i) {
90 var inner = this._responsivePresetsContainer.createChild("div", "device- mode-presets-container-inner"); 90 var outer = inner.createChild('div', 'fill device-mode-preset-bar-outer');
91 for (var i = sizes.length - 1; i >= 0; --i) { 91 var block = outer.createChild('div', 'device-mode-preset-bar');
92 var outer = inner.createChild("div", "fill device-mode-preset-bar-ou ter"); 92 block.createChild('span').textContent = titles[i] + ' \u2013 ' + sizes[i] + 'px';
93 var block = outer.createChild("div", "device-mode-preset-bar"); 93 block.addEventListener('click', applySize.bind(this, sizes[i]), false);
94 block.createChild("span").textContent = titles[i] + " \u2013 " + siz es[i] + "px"; 94 block.__width = sizes[i];
95 block.addEventListener("click", applySize.bind(this, sizes[i]), fals e); 95 this._presetBlocks.push(block);
96 block.__width = sizes[i]; 96 }
97 this._presetBlocks.push(block); 97
98 } 98 /**
99 99 * @param {number} width
100 /** 100 * @param {!Event} e
101 * @param {number} width 101 * @this {WebInspector.DeviceModeView}
102 * @param {!Event} e 102 */
103 * @this {WebInspector.DeviceModeView} 103 function applySize(width, e) {
104 */ 104 this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, null, nu ll);
105 function applySize(width, e) 105 this._model.setSizeAndScaleToFit(width, 0);
106 { 106 e.consume();
107 this._model.emulate(WebInspector.DeviceModeModel.Type.Responsive, nu ll, null); 107 }
108 this._model.setSizeAndScaleToFit(width, 0); 108 }
109 e.consume(); 109
110 } 110 /**
111 }, 111 * @param {!Element} element
112 112 * @param {number} widthFactor
113 * @param {number} heightFactor
114 * @return {!WebInspector.ResizerWidget}
115 */
116 _createResizer(element, widthFactor, heightFactor) {
117 var resizer = new WebInspector.ResizerWidget();
118 resizer.addElement(element);
119 var cursor = widthFactor ? 'ew-resize' : 'ns-resize';
120 if (widthFactor * heightFactor > 0)
121 cursor = 'nwse-resize';
122 if (widthFactor * heightFactor < 0)
123 cursor = 'nesw-resize';
124 resizer.setCursor(cursor);
125 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this ._onResizeStart, this);
126 resizer.addEventListener(
127 WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate.bin d(this, widthFactor, heightFactor));
128 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._ onResizeEnd, this);
129 return resizer;
130 }
131
132 /**
133 * @param {!WebInspector.Event} event
134 */
135 _onResizeStart(event) {
136 this._slowPositionStart = null;
137 /** @type {!Size} */
138 this._resizeStart = this._model.screenRect().size();
139 }
140
141 /**
142 * @param {number} widthFactor
143 * @param {number} heightFactor
144 * @param {!WebInspector.Event} event
145 */
146 _onResizeUpdate(widthFactor, heightFactor, event) {
147 if (event.data.shiftKey !== !!this._slowPositionStart)
148 this._slowPositionStart = event.data.shiftKey ? {x: event.data.currentX, y : event.data.currentY} : null;
149
150 var cssOffsetX = event.data.currentX - event.data.startX;
151 var cssOffsetY = event.data.currentY - event.data.startY;
152 if (this._slowPositionStart) {
153 cssOffsetX =
154 (event.data.currentX - this._slowPositionStart.x) / 10 + this._slowPos itionStart.x - event.data.startX;
155 cssOffsetY =
156 (event.data.currentY - this._slowPositionStart.y) / 10 + this._slowPos itionStart.y - event.data.startY;
157 }
158
159 if (widthFactor) {
160 var dipOffsetX = cssOffsetX * WebInspector.zoomManager.zoomFactor();
161 var newWidth = this._resizeStart.width + dipOffsetX * widthFactor;
162 newWidth = Math.round(newWidth / this._model.scale());
163 if (newWidth >= WebInspector.DeviceModeModel.MinDeviceSize &&
164 newWidth <= WebInspector.DeviceModeModel.MaxDeviceSize)
165 this._model.setWidth(newWidth);
166 }
167
168 if (heightFactor) {
169 var dipOffsetY = cssOffsetY * WebInspector.zoomManager.zoomFactor();
170 var newHeight = this._resizeStart.height + dipOffsetY * heightFactor;
171 newHeight = Math.round(newHeight / this._model.scale());
172 if (newHeight >= WebInspector.DeviceModeModel.MinDeviceSize &&
173 newHeight <= WebInspector.DeviceModeModel.MaxDeviceSize)
174 this._model.setHeight(newHeight);
175 }
176 }
177
178 /**
179 * @param {!WebInspector.Event} event
180 */
181 _onResizeEnd(event) {
182 delete this._resizeStart;
183 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Resized ViewInResponsiveMode);
184 }
185
186 _updateUI() {
113 /** 187 /**
114 * @param {!Element} element 188 * @param {!Element} element
115 * @param {number} widthFactor 189 * @param {!WebInspector.Rect} rect
116 * @param {number} heightFactor
117 * @return {!WebInspector.ResizerWidget}
118 */ 190 */
119 _createResizer: function(element, widthFactor, heightFactor) 191 function applyRect(element, rect) {
120 { 192 element.style.left = rect.left + 'px';
121 var resizer = new WebInspector.ResizerWidget(); 193 element.style.top = rect.top + 'px';
122 resizer.addElement(element); 194 element.style.width = rect.width + 'px';
123 var cursor = widthFactor ? "ew-resize" : "ns-resize"; 195 element.style.height = rect.height + 'px';
124 if (widthFactor * heightFactor > 0) 196 }
125 cursor = "nwse-resize"; 197
126 if (widthFactor * heightFactor < 0) 198 if (!this.isShowing())
127 cursor = "nesw-resize"; 199 return;
128 resizer.setCursor(cursor); 200
129 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this); 201 var zoomFactor = WebInspector.zoomManager.zoomFactor();
130 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate.bind(this, widthFactor, heightFactor)); 202 var callDoResize = false;
131 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, th is._onResizeEnd, this); 203 var showRulers = this._showRulersSetting.get() && this._model.type() !== Web Inspector.DeviceModeModel.Type.None;
132 return resizer; 204 var contentAreaResized = false;
133 }, 205 var updateRulers = false;
206
207 var cssScreenRect = this._model.screenRect().scale(1 / zoomFactor);
208 if (!cssScreenRect.isEqual(this._cachedCssScreenRect)) {
209 applyRect(this._screenArea, cssScreenRect);
210 updateRulers = true;
211 callDoResize = true;
212 this._cachedCssScreenRect = cssScreenRect;
213 }
214
215 var cssVisiblePageRect = this._model.visiblePageRect().scale(1 / zoomFactor) ;
216 if (!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)) {
217 applyRect(this._pageArea, cssVisiblePageRect);
218 callDoResize = true;
219 this._cachedCssVisiblePageRect = cssVisiblePageRect;
220 }
221
222 var outlineRect = this._model.outlineRect().scale(1 / zoomFactor);
223 if (!outlineRect.isEqual(this._cachedOutlineRect)) {
224 applyRect(this._outlineImage, outlineRect);
225 callDoResize = true;
226 this._cachedOutlineRect = outlineRect;
227 }
228 this._contentClip.classList.toggle('device-mode-outline-visible', !!this._mo del.outlineImage());
229
230 var resizable = this._model.type() === WebInspector.DeviceModeModel.Type.Res ponsive;
231 if (resizable !== this._cachedResizable) {
232 this._rightResizerElement.classList.toggle('hidden', !resizable);
233 this._leftResizerElement.classList.toggle('hidden', !resizable);
234 this._bottomResizerElement.classList.toggle('hidden', !resizable);
235 this._bottomRightResizerElement.classList.toggle('hidden', !resizable);
236 this._bottomLeftResizerElement.classList.toggle('hidden', !resizable);
237 this._cachedResizable = resizable;
238 }
239
240 var mediaInspectorVisible =
241 this._showMediaInspectorSetting.get() && this._model.type() !== WebInspe ctor.DeviceModeModel.Type.None;
242 if (mediaInspectorVisible !== this._cachedMediaInspectorVisible) {
243 if (mediaInspectorVisible)
244 this._mediaInspector.show(this._mediaInspectorContainer);
245 else
246 this._mediaInspector.detach();
247 contentAreaResized = true;
248 callDoResize = true;
249 this._cachedMediaInspectorVisible = mediaInspectorVisible;
250 }
251
252 if (showRulers !== this._cachedShowRulers) {
253 this._contentClip.classList.toggle('device-mode-rulers-visible', showRuler s);
254 if (showRulers) {
255 this._topRuler.show(this._contentArea);
256 this._leftRuler.show(this._contentArea);
257 } else {
258 this._topRuler.detach();
259 this._leftRuler.detach();
260 }
261 contentAreaResized = true;
262 callDoResize = true;
263 this._cachedShowRulers = showRulers;
264 }
265
266 if (this._model.scale() !== this._cachedScale) {
267 updateRulers = true;
268 callDoResize = true;
269 for (var block of this._presetBlocks)
270 block.style.width = block.__width * this._model.scale() + 'px';
271 this._cachedScale = this._model.scale();
272 }
273
274 this._toolbar.update();
275 this._loadImage(this._screenImage, this._model.screenImage());
276 this._loadImage(this._outlineImage, this._model.outlineImage());
277 this._mediaInspector.setAxisTransform(this._model.scale());
278 if (callDoResize)
279 this.doResize();
280 if (updateRulers) {
281 this._topRuler.render(this._model.scale());
282 this._leftRuler.render(this._model.scale());
283 this._topRuler.element.positionAt(
284 this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
285 this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
286 this._leftRuler.element.positionAt(
287 this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
288 this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
289 }
290 if (contentAreaResized)
291 this._contentAreaResized();
292 }
293
294 /**
295 * @param {!Element} element
296 * @param {string} srcset
297 */
298 _loadImage(element, srcset) {
299 if (element.getAttribute('srcset') === srcset)
300 return;
301 element.setAttribute('srcset', srcset);
302 if (!srcset)
303 element.classList.toggle('hidden', true);
304 }
305
306 /**
307 * @param {!Element} element
308 * @param {boolean} success
309 */
310 _onImageLoaded(element, success) {
311 element.classList.toggle('hidden', !success);
312 }
313
314 _contentAreaResized() {
315 var zoomFactor = WebInspector.zoomManager.zoomFactor();
316 var rect = this._contentArea.getBoundingClientRect();
317 var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max( rect.height * zoomFactor, 1));
318 var preferredSize = new Size(
319 Math.max((rect.width - 2 * this._handleWidth) * zoomFactor, 1),
320 Math.max((rect.height - this._handleHeight) * zoomFactor, 1));
321 this._model.setAvailableSize(availableSize, preferredSize);
322 }
323
324 _measureHandles() {
325 var hidden = this._rightResizerElement.classList.contains('hidden');
326 this._rightResizerElement.classList.toggle('hidden', false);
327 this._bottomResizerElement.classList.toggle('hidden', false);
328 this._handleWidth = this._rightResizerElement.offsetWidth;
329 this._handleHeight = this._bottomResizerElement.offsetHeight;
330 this._rightResizerElement.classList.toggle('hidden', hidden);
331 this._bottomResizerElement.classList.toggle('hidden', hidden);
332 }
333
334 _zoomChanged() {
335 delete this._handleWidth;
336 delete this._handleHeight;
337 if (this.isShowing()) {
338 this._measureHandles();
339 this._contentAreaResized();
340 }
341 }
342
343 /**
344 * @override
345 */
346 onResize() {
347 if (this.isShowing())
348 this._contentAreaResized();
349 }
350
351 /**
352 * @override
353 */
354 wasShown() {
355 this._measureHandles();
356 this._toolbar.restore();
357 }
358
359 /**
360 * @override
361 */
362 willHide() {
363 this._model.emulate(WebInspector.DeviceModeModel.Type.None, null, null);
364 }
365
366 captureScreenshot() {
367 var mainTarget = WebInspector.targetManager.mainTarget();
368 if (!mainTarget)
369 return;
370 WebInspector.DOMModel.muteHighlight();
371
372 var zoomFactor = WebInspector.zoomManager.zoomFactor();
373 var rect = this._contentArea.getBoundingClientRect();
374 var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max( rect.height * zoomFactor, 1));
375 var outlineVisible = this._model.deviceOutlineSetting().get();
376
377 if (availableSize.width < this._model.screenRect().width ||
378 availableSize.height < this._model.screenRect().height) {
379 WebInspector.inspectorView.minimize();
380 this._model.deviceOutlineSetting().set(false);
381 }
382
383 mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this));
134 384
135 /** 385 /**
136 * @param {!WebInspector.Event} event 386 * @param {?Protocol.Error} error
387 * @param {string} content
388 * @this {WebInspector.DeviceModeView}
137 */ 389 */
138 _onResizeStart: function(event) 390 function screenshotCaptured(error, content) {
139 { 391 this._model.deviceOutlineSetting().set(outlineVisible);
140 this._slowPositionStart = null; 392 var dpr = window.devicePixelRatio;
141 /** @type {!Size} */ 393 var outlineRect = this._model.outlineRect().scale(dpr);
142 this._resizeStart = this._model.screenRect().size(); 394 var screenRect = this._model.screenRect().scale(dpr);
143 }, 395 screenRect.left -= outlineRect.left;
144 396 screenRect.top -= outlineRect.top;
145 /** 397 var visiblePageRect = this._model.visiblePageRect().scale(dpr);
146 * @param {number} widthFactor 398 visiblePageRect.left += screenRect.left;
147 * @param {number} heightFactor 399 visiblePageRect.top += screenRect.top;
148 * @param {!WebInspector.Event} event 400 outlineRect.left = 0;
149 */ 401 outlineRect.top = 0;
150 _onResizeUpdate: function(widthFactor, heightFactor, event) 402
151 { 403 WebInspector.DOMModel.unmuteHighlight();
152 if (event.data.shiftKey !== !!this._slowPositionStart) 404 WebInspector.inspectorView.restore();
153 this._slowPositionStart = event.data.shiftKey ? {x: event.data.curre ntX, y: event.data.currentY} : null; 405
154 406 if (error) {
155 var cssOffsetX = event.data.currentX - event.data.startX; 407 console.error(error);
156 var cssOffsetY = event.data.currentY - event.data.startY; 408 return;
157 if (this._slowPositionStart) { 409 }
158 cssOffsetX = (event.data.currentX - this._slowPositionStart.x) / 10 + this._slowPositionStart.x - event.data.startX; 410
159 cssOffsetY = (event.data.currentY - this._slowPositionStart.y) / 10 + this._slowPositionStart.y - event.data.startY; 411 // Create a canvas to splice the images together.
412 var canvas = createElement('canvas');
413 var ctx = canvas.getContext('2d');
414 canvas.width = outlineRect.width;
415 canvas.height = outlineRect.height;
416 ctx.imageSmoothingEnabled = false;
417
418 var promise = Promise.resolve();
419 if (this._model.outlineImage())
420 promise = promise.then(paintImage.bind(null, this._model.outlineImage(), outlineRect));
421 promise = promise.then(drawBorder);
422 if (this._model.screenImage())
423 promise = promise.then(paintImage.bind(null, this._model.screenImage(), screenRect));
424 promise.then(paintScreenshot.bind(this));
425
426 /**
427 * @param {string} src
428 * @param {!WebInspector.Rect} rect
429 * @return {!Promise<undefined>}
430 */
431 function paintImage(src, rect) {
432 var callback;
433 var promise = new Promise(fulfill => callback = fulfill);
434 var image = new Image();
435 image.crossOrigin = 'Anonymous';
436 image.srcset = src;
437 image.onload = onImageLoad;
438 image.onerror = callback;
439 return promise;
440
441 function onImageLoad() {
442 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
443 callback();
160 } 444 }
161 445 }
162 if (widthFactor) { 446
163 var dipOffsetX = cssOffsetX * WebInspector.zoomManager.zoomFactor(); 447 function drawBorder() {
164 var newWidth = this._resizeStart.width + dipOffsetX * widthFactor; 448 ctx.strokeStyle = 'hsla(0, 0%, 98%, 0.5)';
165 newWidth = Math.round(newWidth / this._model.scale()); 449 ctx.lineWidth = 1;
166 if (newWidth >= WebInspector.DeviceModeModel.MinDeviceSize && newWid th <= WebInspector.DeviceModeModel.MaxDeviceSize) 450 ctx.setLineDash([10, 10]);
167 this._model.setWidth(newWidth); 451 ctx.strokeRect(screenRect.left + 1, screenRect.top + 1, screenRect.width - 2, screenRect.height - 2);
168 } 452 }
169 453
170 if (heightFactor) { 454 /**
171 var dipOffsetY = cssOffsetY * WebInspector.zoomManager.zoomFactor(); 455 * @this {WebInspector.DeviceModeView}
172 var newHeight = this._resizeStart.height + dipOffsetY * heightFactor ; 456 */
173 newHeight = Math.round(newHeight / this._model.scale()); 457 function paintScreenshot() {
174 if (newHeight >= WebInspector.DeviceModeModel.MinDeviceSize && newHe ight <= WebInspector.DeviceModeModel.MaxDeviceSize) 458 var pageImage = new Image();
175 this._model.setHeight(newHeight); 459 pageImage.src = 'data:image/png;base64,' + content;
176 } 460 ctx.drawImage(
177 }, 461 pageImage, visiblePageRect.left, visiblePageRect.top, Math.min(pageI mage.naturalWidth, screenRect.width),
178 462 Math.min(pageImage.naturalHeight, screenRect.height));
179 /** 463 var url = mainTarget && mainTarget.inspectedURL();
180 * @param {!WebInspector.Event} event 464 var fileName = url ? url.trimURL().removeURLFragment() : '';
181 */ 465 if (this._model.type() === WebInspector.DeviceModeModel.Type.Device)
182 _onResizeEnd: function(event) 466 fileName += WebInspector.UIString('(%s)', this._model.device().title);
183 { 467 // Trigger download.
184 delete this._resizeStart; 468 var link = createElement('a');
185 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Res izedViewInResponsiveMode); 469 link.download = fileName + '.png';
186 }, 470 link.href = canvas.toDataURL('image/png');
187 471 link.click();
188 _updateUI: function() 472 }
189 { 473 }
190 /** 474 }
191 * @param {!Element} element
192 * @param {!WebInspector.Rect} rect
193 */
194 function applyRect(element, rect)
195 {
196 element.style.left = rect.left + "px";
197 element.style.top = rect.top + "px";
198 element.style.width = rect.width + "px";
199 element.style.height = rect.height + "px";
200 }
201
202 if (!this.isShowing())
203 return;
204
205 var zoomFactor = WebInspector.zoomManager.zoomFactor();
206 var callDoResize = false;
207 var showRulers = this._showRulersSetting.get() && this._model.type() !== WebInspector.DeviceModeModel.Type.None;
208 var contentAreaResized = false;
209 var updateRulers = false;
210
211 var cssScreenRect = this._model.screenRect().scale(1 / zoomFactor);
212 if (!cssScreenRect.isEqual(this._cachedCssScreenRect)) {
213 applyRect(this._screenArea, cssScreenRect);
214 updateRulers = true;
215 callDoResize = true;
216 this._cachedCssScreenRect = cssScreenRect;
217 }
218
219 var cssVisiblePageRect = this._model.visiblePageRect().scale(1 / zoomFac tor);
220 if (!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)) {
221 applyRect(this._pageArea, cssVisiblePageRect);
222 callDoResize = true;
223 this._cachedCssVisiblePageRect = cssVisiblePageRect;
224 }
225
226 var outlineRect = this._model.outlineRect().scale(1 / zoomFactor);
227 if (!outlineRect.isEqual(this._cachedOutlineRect)) {
228 applyRect(this._outlineImage, outlineRect);
229 callDoResize = true;
230 this._cachedOutlineRect = outlineRect;
231 }
232 this._contentClip.classList.toggle("device-mode-outline-visible", !!this ._model.outlineImage());
233
234 var resizable = this._model.type() === WebInspector.DeviceModeModel.Type .Responsive;
235 if (resizable !== this._cachedResizable) {
236 this._rightResizerElement.classList.toggle("hidden", !resizable);
237 this._leftResizerElement.classList.toggle("hidden", !resizable);
238 this._bottomResizerElement.classList.toggle("hidden", !resizable);
239 this._bottomRightResizerElement.classList.toggle("hidden", !resizabl e);
240 this._bottomLeftResizerElement.classList.toggle("hidden", !resizable );
241 this._cachedResizable = resizable;
242 }
243
244 var mediaInspectorVisible = this._showMediaInspectorSetting.get() && thi s._model.type() !== WebInspector.DeviceModeModel.Type.None;
245 if (mediaInspectorVisible !== this._cachedMediaInspectorVisible) {
246 if (mediaInspectorVisible)
247 this._mediaInspector.show(this._mediaInspectorContainer);
248 else
249 this._mediaInspector.detach();
250 contentAreaResized = true;
251 callDoResize = true;
252 this._cachedMediaInspectorVisible = mediaInspectorVisible;
253 }
254
255 if (showRulers !== this._cachedShowRulers) {
256 this._contentClip.classList.toggle("device-mode-rulers-visible", sho wRulers);
257 if (showRulers) {
258 this._topRuler.show(this._contentArea);
259 this._leftRuler.show(this._contentArea);
260 } else {
261 this._topRuler.detach();
262 this._leftRuler.detach();
263 }
264 contentAreaResized = true;
265 callDoResize = true;
266 this._cachedShowRulers = showRulers;
267 }
268
269 if (this._model.scale() !== this._cachedScale) {
270 updateRulers = true;
271 callDoResize = true;
272 for (var block of this._presetBlocks)
273 block.style.width = block.__width * this._model.scale() + "px";
274 this._cachedScale = this._model.scale();
275 }
276
277 this._toolbar.update();
278 this._loadImage(this._screenImage, this._model.screenImage());
279 this._loadImage(this._outlineImage, this._model.outlineImage());
280 this._mediaInspector.setAxisTransform(this._model.scale());
281 if (callDoResize)
282 this.doResize();
283 if (updateRulers) {
284 this._topRuler.render(this._model.scale());
285 this._leftRuler.render(this._model.scale());
286 this._topRuler.element.positionAt(this._cachedCssScreenRect ? this._ cachedCssScreenRect.left : 0, this._cachedCssScreenRect ? this._cachedCssScreenR ect.top : 0);
287 this._leftRuler.element.positionAt(this._cachedCssScreenRect ? this. _cachedCssScreenRect.left : 0, this._cachedCssScreenRect ? this._cachedCssScreen Rect.top : 0);
288 }
289 if (contentAreaResized)
290 this._contentAreaResized();
291 },
292
293 /**
294 * @param {!Element} element
295 * @param {string} srcset
296 */
297 _loadImage: function(element, srcset)
298 {
299 if (element.getAttribute("srcset") === srcset)
300 return;
301 element.setAttribute("srcset", srcset);
302 if (!srcset)
303 element.classList.toggle("hidden", true);
304 },
305
306 /**
307 * @param {!Element} element
308 * @param {boolean} success
309 */
310 _onImageLoaded: function(element, success)
311 {
312 element.classList.toggle("hidden", !success);
313 },
314
315 _contentAreaResized: function()
316 {
317 var zoomFactor = WebInspector.zoomManager.zoomFactor();
318 var rect = this._contentArea.getBoundingClientRect();
319 var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math. max(rect.height * zoomFactor, 1));
320 var preferredSize = new Size(Math.max((rect.width - 2 * this._handleWidt h) * zoomFactor, 1), Math.max((rect.height - this._handleHeight) * zoomFactor, 1 ));
321 this._model.setAvailableSize(availableSize, preferredSize);
322 },
323
324 _measureHandles: function()
325 {
326 var hidden = this._rightResizerElement.classList.contains("hidden");
327 this._rightResizerElement.classList.toggle("hidden", false);
328 this._bottomResizerElement.classList.toggle("hidden", false);
329 this._handleWidth = this._rightResizerElement.offsetWidth;
330 this._handleHeight = this._bottomResizerElement.offsetHeight;
331 this._rightResizerElement.classList.toggle("hidden", hidden);
332 this._bottomResizerElement.classList.toggle("hidden", hidden);
333 },
334
335 _zoomChanged: function()
336 {
337 delete this._handleWidth;
338 delete this._handleHeight;
339 if (this.isShowing()) {
340 this._measureHandles();
341 this._contentAreaResized();
342 }
343 },
344
345 /**
346 * @override
347 */
348 onResize: function()
349 {
350 if (this.isShowing())
351 this._contentAreaResized();
352 },
353
354 /**
355 * @override
356 */
357 wasShown: function()
358 {
359 this._measureHandles();
360 this._toolbar.restore();
361 },
362
363 /**
364 * @override
365 */
366 willHide: function()
367 {
368 this._model.emulate(WebInspector.DeviceModeModel.Type.None, null, null);
369 },
370
371 captureScreenshot: function()
372 {
373 var mainTarget = WebInspector.targetManager.mainTarget();
374 if (!mainTarget)
375 return;
376 WebInspector.DOMModel.muteHighlight();
377
378 var zoomFactor = WebInspector.zoomManager.zoomFactor();
379 var rect = this._contentArea.getBoundingClientRect();
380 var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math. max(rect.height * zoomFactor, 1));
381 var outlineVisible = this._model.deviceOutlineSetting().get();
382
383 if (availableSize.width < this._model.screenRect().width ||
384 availableSize.height < this._model.screenRect().height) {
385 WebInspector.inspectorView.minimize();
386 this._model.deviceOutlineSetting().set(false);
387 }
388
389 mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this));
390
391 /**
392 * @param {?Protocol.Error} error
393 * @param {string} content
394 * @this {WebInspector.DeviceModeView}
395 */
396 function screenshotCaptured(error, content)
397 {
398 this._model.deviceOutlineSetting().set(outlineVisible);
399 var dpr = window.devicePixelRatio;
400 var outlineRect = this._model.outlineRect().scale(dpr);
401 var screenRect = this._model.screenRect().scale(dpr);
402 screenRect.left -= outlineRect.left;
403 screenRect.top -= outlineRect.top;
404 var visiblePageRect = this._model.visiblePageRect().scale(dpr);
405 visiblePageRect.left += screenRect.left;
406 visiblePageRect.top += screenRect.top;
407 outlineRect.left = 0;
408 outlineRect.top = 0;
409
410 WebInspector.DOMModel.unmuteHighlight();
411 WebInspector.inspectorView.restore();
412
413 if (error) {
414 console.error(error);
415 return;
416 }
417
418 // Create a canvas to splice the images together.
419 var canvas = createElement("canvas");
420 var ctx = canvas.getContext("2d");
421 canvas.width = outlineRect.width;
422 canvas.height = outlineRect.height;
423 ctx.imageSmoothingEnabled = false;
424
425 var promise = Promise.resolve();
426 if (this._model.outlineImage())
427 promise = promise.then(paintImage.bind(null, this._model.outline Image(), outlineRect));
428 promise = promise.then(drawBorder);
429 if (this._model.screenImage())
430 promise = promise.then(paintImage.bind(null, this._model.screenI mage(), screenRect));
431 promise.then(paintScreenshot.bind(this));
432
433 /**
434 * @param {string} src
435 * @param {!WebInspector.Rect} rect
436 * @return {!Promise<undefined>}
437 */
438 function paintImage(src, rect)
439 {
440 var callback;
441 var promise = new Promise(fulfill => callback = fulfill);
442 var image = new Image();
443 image.crossOrigin = "Anonymous";
444 image.srcset = src;
445 image.onload = onImageLoad;
446 image.onerror = callback;
447 return promise;
448
449 function onImageLoad()
450 {
451 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.h eight);
452 callback();
453 }
454 }
455
456 function drawBorder()
457 {
458 ctx.strokeStyle = "hsla(0, 0%, 98%, 0.5)";
459 ctx.lineWidth = 1;
460 ctx.setLineDash([10, 10]);
461 ctx.strokeRect(screenRect.left + 1, screenRect.top + 1, screenRe ct.width - 2, screenRect.height - 2);
462 }
463
464 /**
465 * @this {WebInspector.DeviceModeView}
466 */
467 function paintScreenshot()
468 {
469 var pageImage = new Image();
470 pageImage.src = "data:image/png;base64," + content;
471 ctx.drawImage(pageImage,
472 visiblePageRect.left,
473 visiblePageRect.top,
474 Math.min(pageImage.naturalWidth, screenRect.width) ,
475 Math.min(pageImage.naturalHeight, screenRect.heigh t));
476 var url = mainTarget && mainTarget.inspectedURL();
477 var fileName = url ? url.trimURL().removeURLFragment() : "";
478 if (this._model.type() === WebInspector.DeviceModeModel.Type.Dev ice)
479 fileName += WebInspector.UIString("(%s)", this._model.device ().title);
480 // Trigger download.
481 var link = createElement("a");
482 link.download = fileName + ".png";
483 link.href = canvas.toDataURL("image/png");
484 link.click();
485 }
486 }
487 },
488
489 __proto__: WebInspector.VBox.prototype
490 }; 475 };
491 476
492 /** 477 /**
493 * @constructor 478 * @unrestricted
494 * @extends {WebInspector.VBox}
495 * @param {boolean} horizontal
496 * @param {function(number)} applyCallback
497 */ 479 */
498 WebInspector.DeviceModeView.Ruler = function(horizontal, applyCallback) 480 WebInspector.DeviceModeView.Ruler = class extends WebInspector.VBox {
499 { 481 /**
500 WebInspector.VBox.call(this); 482 * @param {boolean} horizontal
501 this.element.classList.add("device-mode-ruler"); 483 * @param {function(number)} applyCallback
502 this._contentElement = this.element.createChild("div", "device-mode-ruler-co ntent").createChild("div", "device-mode-ruler-inner"); 484 */
485 constructor(horizontal, applyCallback) {
486 super();
487 this.element.classList.add('device-mode-ruler');
488 this._contentElement =
489 this.element.createChild('div', 'device-mode-ruler-content').createChild ('div', 'device-mode-ruler-inner');
503 this._horizontal = horizontal; 490 this._horizontal = horizontal;
504 this._scale = 1; 491 this._scale = 1;
505 this._count = 0; 492 this._count = 0;
506 this._throttler = new WebInspector.Throttler(0); 493 this._throttler = new WebInspector.Throttler(0);
507 this._applyCallback = applyCallback; 494 this._applyCallback = applyCallback;
495 }
496
497 /**
498 * @param {number} scale
499 */
500 render(scale) {
501 this._scale = scale;
502 this._throttler.schedule(this._update.bind(this));
503 }
504
505 /**
506 * @override
507 */
508 onResize() {
509 this._throttler.schedule(this._update.bind(this));
510 }
511
512 /**
513 * @return {!Promise.<?>}
514 */
515 _update() {
516 var zoomFactor = WebInspector.zoomManager.zoomFactor();
517 var size = this._horizontal ? this._contentElement.offsetWidth : this._conte ntElement.offsetHeight;
518
519 if (this._scale !== this._renderedScale || zoomFactor !== this._renderedZoom Factor) {
520 this._contentElement.removeChildren();
521 this._count = 0;
522 this._renderedScale = this._scale;
523 this._renderedZoomFactor = zoomFactor;
524 }
525
526 var dipSize = size * zoomFactor / this._scale;
527 var count = Math.ceil(dipSize / 5);
528 var step = 1;
529 if (this._scale < 0.8)
530 step = 2;
531 if (this._scale < 0.6)
532 step = 4;
533 if (this._scale < 0.4)
534 step = 8;
535 if (this._scale < 0.2)
536 step = 16;
537 if (this._scale < 0.1)
538 step = 32;
539
540 for (var i = count; i < this._count; i++) {
541 if (!(i % step))
542 this._contentElement.lastChild.remove();
543 }
544
545 for (var i = this._count; i < count; i++) {
546 if (i % step)
547 continue;
548 var marker = this._contentElement.createChild('div', 'device-mode-ruler-ma rker');
549 if (i) {
550 if (this._horizontal)
551 marker.style.left = (5 * i) * this._scale / zoomFactor + 'px';
552 else
553 marker.style.top = (5 * i) * this._scale / zoomFactor + 'px';
554 if (!(i % 20)) {
555 var text = marker.createChild('div', 'device-mode-ruler-text');
556 text.textContent = i * 5;
557 text.addEventListener('click', this._onMarkerClick.bind(this, i * 5), false);
558 }
559 }
560 if (!(i % 10))
561 marker.classList.add('device-mode-ruler-marker-large');
562 else if (!(i % 5))
563 marker.classList.add('device-mode-ruler-marker-medium');
564 }
565
566 this._count = count;
567 return Promise.resolve();
568 }
569
570 /**
571 * @param {number} size
572 */
573 _onMarkerClick(size) {
574 this._applyCallback.call(null, size);
575 }
508 }; 576 };
509
510 WebInspector.DeviceModeView.Ruler.prototype = {
511 /**
512 * @param {number} scale
513 */
514 render: function(scale)
515 {
516 this._scale = scale;
517 this._throttler.schedule(this._update.bind(this));
518 },
519
520 /**
521 * @override
522 */
523 onResize: function()
524 {
525 this._throttler.schedule(this._update.bind(this));
526 },
527
528 /**
529 * @return {!Promise.<?>}
530 */
531 _update: function()
532 {
533 var zoomFactor = WebInspector.zoomManager.zoomFactor();
534 var size = this._horizontal ? this._contentElement.offsetWidth : this._c ontentElement.offsetHeight;
535
536 if (this._scale !== this._renderedScale || zoomFactor !== this._rendered ZoomFactor) {
537 this._contentElement.removeChildren();
538 this._count = 0;
539 this._renderedScale = this._scale;
540 this._renderedZoomFactor = zoomFactor;
541 }
542
543 var dipSize = size * zoomFactor / this._scale;
544 var count = Math.ceil(dipSize / 5);
545 var step = 1;
546 if (this._scale < 0.8)
547 step = 2;
548 if (this._scale < 0.6)
549 step = 4;
550 if (this._scale < 0.4)
551 step = 8;
552 if (this._scale < 0.2)
553 step = 16;
554 if (this._scale < 0.1)
555 step = 32;
556
557 for (var i = count; i < this._count; i++) {
558 if (!(i % step))
559 this._contentElement.lastChild.remove();
560 }
561
562 for (var i = this._count; i < count; i++) {
563 if (i % step)
564 continue;
565 var marker = this._contentElement.createChild("div", "device-mode-ru ler-marker");
566 if (i) {
567 if (this._horizontal)
568 marker.style.left = (5 * i) * this._scale / zoomFactor + "px ";
569 else
570 marker.style.top = (5 * i) * this._scale / zoomFactor + "px" ;
571 if (!(i % 20)) {
572 var text = marker.createChild("div", "device-mode-ruler-text ");
573 text.textContent = i * 5;
574 text.addEventListener("click", this._onMarkerClick.bind(this , i * 5), false);
575 }
576 }
577 if (!(i % 10))
578 marker.classList.add("device-mode-ruler-marker-large");
579 else if (!(i % 5))
580 marker.classList.add("device-mode-ruler-marker-medium");
581 }
582
583 this._count = count;
584 return Promise.resolve();
585 },
586
587 /**
588 * @param {number} size
589 */
590 _onMarkerClick: function(size)
591 {
592 this._applyCallback.call(null, size);
593 },
594
595 __proto__: WebInspector.VBox.prototype
596 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698