OLD | NEW |
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 }; | |
OLD | NEW |