| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @constructor | |
| 7 * @extends {WebInspector.VBox} | |
| 8 * @implements {WebInspector.OverridesSupport.PageResizer} | |
| 9 * @param {!WebInspector.InspectedPagePlaceholder} inspectedPagePlaceholder | |
| 10 */ | |
| 11 WebInspector.ResponsiveDesignView = function(inspectedPagePlaceholder) | |
| 12 { | |
| 13 WebInspector.VBox.call(this); | |
| 14 this.registerRequiredCSS("responsiveDesignView.css"); | |
| 15 | |
| 16 this._container = new WebInspector.View(); | |
| 17 this._container.element.classList.add("responsive-design"); | |
| 18 | |
| 19 this._canvas = this._container.element.createChild("canvas", "fill"); | |
| 20 this._resetButton = this._container.element.createChild("div", "responsive-d
esign-reset-button"); | |
| 21 this._resetButton.addEventListener("click", this._reset.bind(this), false); | |
| 22 this._resetButton.title = WebInspector.UIString("Fit available space"); | |
| 23 | |
| 24 this._slidersContainer = this._container.element.createChild("div", "vbox re
sponsive-design-sliders-container"); | |
| 25 var hbox = this._slidersContainer.createChild("div", "hbox flex-auto"); | |
| 26 this._heightSliderContainer = this._slidersContainer.createChild("div", "hbo
x responsive-design-slider-height"); | |
| 27 this._pageContainer = hbox.createChild("div", "vbox flex-auto"); | |
| 28 this._widthSliderContainer = hbox.createChild("div", "vbox responsive-design
-slider-width"); | |
| 29 | |
| 30 this._widthSlider = this._widthSliderContainer.createChild("div", "responsiv
e-design-slider-thumb"); | |
| 31 this._createResizer(this._widthSlider, false); | |
| 32 this._widthZeroButton = this._widthSlider.createChild("div", "responsive-des
ign-zero-button"); | |
| 33 this._widthZeroButton.addEventListener("click", this._zeroButtonClicked.bind
(this, false)); | |
| 34 this._heightSlider = this._heightSliderContainer.createChild("div", "respons
ive-design-slider-thumb"); | |
| 35 this._createResizer(this._heightSlider, true); | |
| 36 this._heightZeroButton = this._heightSlider.createChild("div", "responsive-d
esign-zero-button"); | |
| 37 this._heightZeroButton.addEventListener("click", this._zeroButtonClicked.bin
d(this, true)); | |
| 38 | |
| 39 this._inspectedPagePlaceholder = inspectedPagePlaceholder; | |
| 40 inspectedPagePlaceholder.show(this.element); | |
| 41 | |
| 42 this._enabled = false; | |
| 43 | |
| 44 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.Zo
omChanged, this._onZoomChanged, this); | |
| 45 WebInspector.dockController.addEventListener(WebInspector.DockController.Eve
nts.DockSideChanged, this._updateOverridesSupportOnDockSideChange, this); | |
| 46 this._updateOverridesSupportOnDockSideChange(); | |
| 47 }; | |
| 48 | |
| 49 // Measured in DIP. | |
| 50 WebInspector.ResponsiveDesignView.SliderWidth = 19; | |
| 51 WebInspector.ResponsiveDesignView.RulerWidth = 23; | |
| 52 | |
| 53 WebInspector.ResponsiveDesignView.prototype = { | |
| 54 _updateOverridesSupportOnDockSideChange: function() | |
| 55 { | |
| 56 WebInspector.overridesSupport.setPageResizer(WebInspector.dockController
.dockSide() !== WebInspector.DockController.State.Undocked ? this : null); | |
| 57 }, | |
| 58 | |
| 59 /** | |
| 60 * WebInspector.OverridesSupport.PageResizer override. | |
| 61 * @param {number} dipWidth | |
| 62 * @param {number} dipHeight | |
| 63 * @param {number} scale | |
| 64 */ | |
| 65 enable: function(dipWidth, dipHeight, scale) | |
| 66 { | |
| 67 if (!this._enabled) { | |
| 68 this._ignoreResize = true; | |
| 69 this._enabled = true; | |
| 70 this._inspectedPagePlaceholder.clearMinimumSizeAndMargins(); | |
| 71 this._inspectedPagePlaceholder.show(this._pageContainer); | |
| 72 this._container.show(this.element); | |
| 73 delete this._ignoreResize; | |
| 74 } | |
| 75 | |
| 76 this._scale = scale; | |
| 77 this._dipWidth = dipWidth; | |
| 78 this._dipHeight = dipHeight; | |
| 79 this._updateUI(); | |
| 80 }, | |
| 81 | |
| 82 /** | |
| 83 * WebInspector.OverridesSupport.PageResizer override. | |
| 84 */ | |
| 85 disable: function() | |
| 86 { | |
| 87 if (!this._enabled) | |
| 88 return; | |
| 89 | |
| 90 this._ignoreResize = true; | |
| 91 this._enabled = false; | |
| 92 this._scale = 0; | |
| 93 this._inspectedPagePlaceholder.restoreMinimumSizeAndMargins(); | |
| 94 this._container.detach(); | |
| 95 this._inspectedPagePlaceholder.show(this.element); | |
| 96 delete this._ignoreResize; | |
| 97 }, | |
| 98 | |
| 99 /** | |
| 100 * WebInspector.OverridesSupport.PageResizer override. | |
| 101 * @return {!Size} | |
| 102 */ | |
| 103 availableDipSize: function() | |
| 104 { | |
| 105 if (typeof this._availableSize === "undefined") { | |
| 106 var zoomFactor = WebInspector.zoomManager.zoomFactor(); | |
| 107 var rect = this.element.getBoundingClientRect(); | |
| 108 this._availableSize = new Size(rect.width * zoomFactor - WebInspecto
r.ResponsiveDesignView.SliderWidth - WebInspector.ResponsiveDesignView.RulerWidt
h, | |
| 109 rect.height * zoomFactor - WebInspect
or.ResponsiveDesignView.SliderWidth - WebInspector.ResponsiveDesignView.RulerWid
th); | |
| 110 } | |
| 111 return this._availableSize; | |
| 112 }, | |
| 113 | |
| 114 /** | |
| 115 * @param {!Element} element | |
| 116 * @param {boolean} vertical | |
| 117 * @return {!WebInspector.ResizerWidget} | |
| 118 */ | |
| 119 _createResizer: function(element, vertical) | |
| 120 { | |
| 121 var resizer = new WebInspector.ResizerWidget(); | |
| 122 resizer.addElement(element); | |
| 123 resizer.setVertical(vertical); | |
| 124 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart,
this._onResizeStart, this); | |
| 125 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate,
this._onResizeUpdate, this); | |
| 126 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, th
is._onResizeEnd, this); | |
| 127 return resizer; | |
| 128 }, | |
| 129 | |
| 130 /** | |
| 131 * @param {!WebInspector.Event} event | |
| 132 */ | |
| 133 _onResizeStart: function(event) | |
| 134 { | |
| 135 var available = this.availableDipSize(); | |
| 136 this._resizeStartSize = event.target.isVertical() ? (this._dipHeight ||
available.height) : (this._dipWidth || available.width); | |
| 137 }, | |
| 138 | |
| 139 /** | |
| 140 * @param {!WebInspector.Event} event | |
| 141 */ | |
| 142 _onResizeUpdate: function(event) | |
| 143 { | |
| 144 var cssOffset = event.data.currentPosition - event.data.startPosition; | |
| 145 var dipOffset = cssOffset * WebInspector.zoomManager.zoomFactor(); | |
| 146 var newSize = this._resizeStartSize + dipOffset; | |
| 147 var requested = new Size(this._dipWidth, this._dipHeight); | |
| 148 if (event.target.isVertical()) | |
| 149 requested.height = Number.constrain(newSize, 1, this.availableDipSiz
e().height); | |
| 150 else | |
| 151 requested.width = Number.constrain(newSize, 1, this.availableDipSize
().width); | |
| 152 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.
Events.ResizeRequested, requested); | |
| 153 }, | |
| 154 | |
| 155 /** | |
| 156 * @param {!WebInspector.Event} event | |
| 157 */ | |
| 158 _onResizeEnd: function(event) | |
| 159 { | |
| 160 delete this._resizeStartSize; | |
| 161 }, | |
| 162 | |
| 163 /** | |
| 164 * @param {boolean} isHeight | |
| 165 */ | |
| 166 _zeroButtonClicked: function(isHeight) | |
| 167 { | |
| 168 var size = new Size(this._dipWidth, this._dipHeight); | |
| 169 var available = this.availableDipSize(); | |
| 170 if (isHeight) | |
| 171 size.height = this._dipHeight ? 0 : available.height; | |
| 172 else | |
| 173 size.width = this._dipWidth ? 0 : available.width; | |
| 174 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.
Events.ResizeRequested, size); | |
| 175 }, | |
| 176 | |
| 177 /** | |
| 178 * Draws canvas of the specified css size in DevTools page space. | |
| 179 * Canvas contains grid and rulers. | |
| 180 * @param {number} cssCanvasWidth | |
| 181 * @param {number} cssCanvasHeight | |
| 182 */ | |
| 183 _drawCanvas: function(cssCanvasWidth, cssCanvasHeight) | |
| 184 { | |
| 185 if (!this._enabled) | |
| 186 return; | |
| 187 | |
| 188 var canvas = this._canvas; | |
| 189 var context = canvas.getContext("2d"); | |
| 190 canvas.style.width = cssCanvasWidth + "px"; | |
| 191 canvas.style.height = cssCanvasHeight + "px"; | |
| 192 | |
| 193 var zoomFactor = WebInspector.zoomManager.zoomFactor(); | |
| 194 var dipCanvasWidth = cssCanvasWidth * zoomFactor; | |
| 195 var dipCanvasHeight = cssCanvasHeight * zoomFactor; | |
| 196 | |
| 197 var deviceScaleFactor = window.devicePixelRatio; | |
| 198 canvas.width = deviceScaleFactor * cssCanvasWidth; | |
| 199 canvas.height = deviceScaleFactor * cssCanvasHeight; | |
| 200 context.scale(canvas.width / dipCanvasWidth, canvas.height / dipCanvasHe
ight); | |
| 201 | |
| 202 context.font = "10px " + WebInspector.monospaceFontFamily(); | |
| 203 | |
| 204 const gridSubStep = 10; | |
| 205 const gridStep = 50; | |
| 206 const rulerBackgroundColor = "rgb(54, 54, 54)"; | |
| 207 const backgroundColor = "rgb(102, 102, 102)"; | |
| 208 const lightLineColor = "rgb(132, 132, 132)"; | |
| 209 const darkLineColor = "rgb(114, 114, 114)"; | |
| 210 const textColor = "rgb(180, 180, 180)"; | |
| 211 | |
| 212 var scale = this._scale || 1; | |
| 213 var rulerWidth = WebInspector.ResponsiveDesignView.RulerWidth; | |
| 214 var dipGridWidth = dipCanvasWidth / scale - rulerWidth; | |
| 215 var dipGridHeight = dipCanvasHeight / scale - rulerWidth; | |
| 216 rulerWidth /= scale; | |
| 217 context.scale(scale, scale); | |
| 218 context.translate(rulerWidth, rulerWidth); | |
| 219 | |
| 220 context.fillStyle = rulerBackgroundColor; | |
| 221 context.fillRect(0, -rulerWidth, dipGridWidth, rulerWidth); | |
| 222 context.fillRect(-rulerWidth, 0, rulerWidth, dipGridHeight); | |
| 223 | |
| 224 context.fillStyle = backgroundColor; | |
| 225 context.fillRect(0, 0, dipGridWidth, dipGridHeight); | |
| 226 | |
| 227 context.translate(0.5, 0.5); | |
| 228 context.fillStyle = textColor; | |
| 229 context.lineWidth = 1; | |
| 230 | |
| 231 { | |
| 232 // Draw vertical lines. | |
| 233 for (var x = 0; x < dipGridWidth; x += gridSubStep) { | |
| 234 var color = darkLineColor; | |
| 235 var y = -rulerWidth / 6; | |
| 236 if (!(x % (2 * gridSubStep))) | |
| 237 y = -rulerWidth / 3; | |
| 238 if (!(x % gridStep)) { | |
| 239 if (x) { | |
| 240 context.save(); | |
| 241 context.translate(x, 0); | |
| 242 context.fillText(x, 2, -rulerWidth / 2); | |
| 243 context.restore(); | |
| 244 } | |
| 245 y = -rulerWidth; | |
| 246 color = lightLineColor; | |
| 247 } | |
| 248 context.strokeStyle = color; | |
| 249 | |
| 250 context.beginPath(); | |
| 251 context.moveTo(x, y); | |
| 252 context.lineTo(x, dipGridHeight); | |
| 253 context.stroke(); | |
| 254 } | |
| 255 } | |
| 256 | |
| 257 { | |
| 258 // Draw horizontal lines. | |
| 259 for (var y = 0; y < dipGridHeight; y += gridSubStep) { | |
| 260 var color = darkLineColor; | |
| 261 var x = -rulerWidth / 6; | |
| 262 if (!(y % (2 * gridSubStep))) | |
| 263 x = -rulerWidth / 3; | |
| 264 if (!(y % gridStep)) { | |
| 265 if (y) { | |
| 266 context.save(); | |
| 267 context.translate(0, y); | |
| 268 context.rotate(-Math.PI / 2); | |
| 269 context.fillText(y, 2, -rulerWidth / 2); | |
| 270 context.restore(); | |
| 271 } | |
| 272 x = -rulerWidth; | |
| 273 color = lightLineColor; | |
| 274 } | |
| 275 context.strokeStyle = color; | |
| 276 | |
| 277 context.beginPath(); | |
| 278 context.moveTo(x, y); | |
| 279 context.lineTo(dipGridWidth, y); | |
| 280 context.stroke(); | |
| 281 } | |
| 282 context.restore(); | |
| 283 } | |
| 284 }, | |
| 285 | |
| 286 _updateUI: function() | |
| 287 { | |
| 288 if (!this._enabled) | |
| 289 return; | |
| 290 | |
| 291 var zoomFactor = WebInspector.zoomManager.zoomFactor(); | |
| 292 var rect = this._canvas.parentElement.getBoundingClientRect(); | |
| 293 var availableDip = this.availableDipSize(); | |
| 294 var cssCanvasWidth = rect.width; | |
| 295 var cssCanvasHeight = rect.height; | |
| 296 | |
| 297 this._widthSlider.classList.toggle("hidden", !!this._scale); | |
| 298 this._heightSlider.classList.toggle("hidden", !!this._scale); | |
| 299 this._widthSlider.classList.toggle("reversed", !this._dipWidth); | |
| 300 this._heightSlider.classList.toggle("reversed", !this._dipHeight); | |
| 301 | |
| 302 if (this._cachedZoomFactor !== zoomFactor) { | |
| 303 var cssRulerWidth = WebInspector.ResponsiveDesignView.RulerWidth / z
oomFactor + "px"; | |
| 304 this._resetButton.style.width = cssRulerWidth; | |
| 305 this._resetButton.style.height = cssRulerWidth; | |
| 306 this._slidersContainer.style.left = cssRulerWidth; | |
| 307 this._slidersContainer.style.top = cssRulerWidth; | |
| 308 | |
| 309 var cssSliderWidth = WebInspector.ResponsiveDesignView.SliderWidth /
zoomFactor + "px"; | |
| 310 this._heightSliderContainer.style.flexBasis = cssSliderWidth; | |
| 311 this._heightSliderContainer.style.marginBottom = "-" + cssSliderWidt
h; | |
| 312 this._widthSliderContainer.style.flexBasis = cssSliderWidth; | |
| 313 this._widthSliderContainer.style.marginRight = "-" + cssSliderWidth; | |
| 314 } | |
| 315 | |
| 316 var cssWidth = this._dipWidth ? (this._dipWidth / zoomFactor + "px") : (
availableDip.width / zoomFactor + "px"); | |
| 317 var cssHeight = this._dipHeight ? (this._dipHeight / zoomFactor + "px")
: (availableDip.height / zoomFactor + "px"); | |
| 318 if (this._cachedCssWidth !== cssWidth || this._cachedCssHeight !== cssHe
ight) { | |
| 319 this._slidersContainer.style.width = cssWidth; | |
| 320 this._slidersContainer.style.height = cssHeight; | |
| 321 this._inspectedPagePlaceholder.onResize(); | |
| 322 } | |
| 323 | |
| 324 if (this._cachedScale !== this._scale || this._cachedCssCanvasWidth !==
cssCanvasWidth || this._cachedCssCanvasHeight !== cssCanvasHeight || this._cache
dZoomFactor !== zoomFactor) | |
| 325 this._drawCanvas(cssCanvasWidth, cssCanvasHeight); | |
| 326 | |
| 327 this._cachedScale = this._scale; | |
| 328 this._cachedCssCanvasWidth = cssCanvasWidth; | |
| 329 this._cachedCssCanvasHeight = cssCanvasHeight; | |
| 330 this._cachedCssHeight = cssHeight; | |
| 331 this._cachedCssWidth = cssWidth; | |
| 332 this._cachedZoomFactor = zoomFactor; | |
| 333 }, | |
| 334 | |
| 335 onResize: function() | |
| 336 { | |
| 337 if (!this._enabled || this._ignoreResize) | |
| 338 return; | |
| 339 delete this._availableSize; | |
| 340 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.
Events.AvailableSizeChanged); | |
| 341 this._updateUI(); | |
| 342 }, | |
| 343 | |
| 344 _onZoomChanged: function() | |
| 345 { | |
| 346 this._updateUI(); | |
| 347 }, | |
| 348 | |
| 349 /** | |
| 350 * Resets emulated size to available space. | |
| 351 */ | |
| 352 _reset: function() | |
| 353 { | |
| 354 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.
Events.ResizeRequested, this.availableDipSize()); | |
| 355 }, | |
| 356 | |
| 357 __proto__: WebInspector.VBox.prototype | |
| 358 }; | |
| OLD | NEW |