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.
7 * @extends {WebInspector.VBox}
8 * @implements {WebInspector.OverridesSupport.PageResizer}
9 * @implements {WebInspector.TargetManager.Observer}
10 * @param {!WebInspector.InspectedPagePlaceholder} inspectedPagePlaceholder
12 WebInspector.ResponsiveDesignView = function(inspectedPagePlaceholder)
14 WebInspector.VBox.call(this);
15 this.setMinimumSize(150, 150);
16 this.element.classList.add("overflow-hidden");
18 this._responsiveDesignContainer = new WebInspector.VBox();
19 this._responsiveDesignContainer.registerRequiredCSS("toolbox/responsiveDesignView.css");
21 this._createToolbar();
23 this._canvasContainer = new WebInspector.View();
24 this._canvasContainer.element.classList.add("responsive-design");
25 this._canvasContainer.show(this._responsiveDesignContainer.element);
27 this._canvas = this._canvasContainer.element.createChild("canvas", "fill responsive-design-canvas");
29 this._mediaInspectorContainer = this._canvasContainer.element.createChild("div", "responsive-design-media-container");
30 this._mediaInspector = new WebInspector.MediaQueryInspector();
31 this._updateMediaQueryInspector();
33 this._warningMessage = this._canvasContainer.element.createChild("div", "responsive-design-warning hidden");
34 this._warningMessage.createChild("div", "warning-icon-small");
35 this._warningMessage.createChild("span");
36 var warningDisableButton = this._warningMessage.createChild("div", "disable-warning");
37 warningDisableButton.textContent = WebInspector.UIString("Never show");
38 warningDisableButton.addEventListener("click", this._disableOverridesWarnings.bind(this), false);
39 var warningCloseButton = this._warningMessage.createChild("div", "close-button");
40 warningCloseButton.addEventListener("click", WebInspector.overridesSupport.clearWarningMessage.bind(WebInspector.overridesSupport), false);
41 WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.OverridesWarningUpdated, this._overridesWarningUpdated, this);
42 WebInspector.settings.disableOverridesWarning.addChangeListener(this._overridesWarningUpdated, this);
44 this._slidersContainer = this._canvasContainer.element.createChild("div", "vbox responsive-design-sliders-container");
45 var genericDeviceOutline = this._slidersContainer.createChild("div", "responsive-design-generic-outline-container");
46 genericDeviceOutline.createChild("div", "responsive-design-generic-outline");
47 var widthSlider = this._slidersContainer.createChild("div", "responsive-design-slider-width");
48 widthSlider.createChild("div", "responsive-design-thumb-handle");
49 this._createResizer(widthSlider, false);
50 var heightSlider = this._slidersContainer.createChild("div", "responsive-design-slider-height");
51 heightSlider.createChild("div", "responsive-design-thumb-handle");
52 this._createResizer(heightSlider, true);
53 this._pageContainer = this._slidersContainer.createChild("div", "vbox flex-auto");
55 // Page scale controls.
56 this._pageScaleContainer = this._canvasContainer.element.createChild("div", "hbox responsive-design-page-scale-container");
57 this._decreasePageScaleButton = new WebInspector.StatusBarButton(WebInspector.UIString(""), "responsive-design-page-scale-button responsive-design-page-scale-decrease");
58 this._decreasePageScaleButton.element.tabIndex = -1;
59 this._decreasePageScaleButton.addEventListener("click", this._pageScaleButtonClicked.bind(this, false), this);
60 this._pageScaleContainer.appendChild(this._decreasePageScaleButton.element);
62 this._pageScaleLabel = this._pageScaleContainer.createChild("label", "responsive-design-page-scale-label");
63 this._pageScaleLabel.title = WebInspector.UIString("For a simpler way to change the current page scale, hold down Shift and drag with your mouse.");
64 this._pageScaleLabel.addEventListener("dblclick", this._resetPageScale.bind(this), false);
66 this._increasePageScaleButton = new WebInspector.StatusBarButton(WebInspector.UIString(""), "responsive-design-page-scale-button responsive-design-page-scale-increase");
67 this._increasePageScaleButton.element.tabIndex = -1;
68 this._increasePageScaleButton.addEventListener("click", this._pageScaleButtonClicked.bind(this, true), this);
69 this._pageScaleContainer.appendChild(this._increasePageScaleButton.element);
71 this._inspectedPagePlaceholder = inspectedPagePlaceholder;
72 inspectedPagePlaceholder.show(this.element);
74 this._enabled = false;
75 this._viewport = { scrollX: 0, scrollY: 0, contentsWidth: 0, contentsHeight: 0, pageScaleFactor: 1, minimumPageScaleFactor: 1, maximumPageScaleFactor: 1 };
76 this._drawContentsSize = true;
77 this._viewportChangedThrottler = new WebInspector.Throttler(0);
78 this._pageScaleFactorThrottler = new WebInspector.Throttler(50);
80 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
81 WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.EmulationStateChanged, this._emulationEnabledChanged, this);
82 this._mediaInspector.addEventListener(WebInspector.MediaQueryInspector.Events.CountUpdated, this._updateMediaQueryInspectorButton, this);
83 this._mediaInspector.addEventListener(WebInspector.MediaQueryInspector.Events.HeightUpdated, this.onResize, this);
84 WebInspector.targetManager.observeTargets(this);
86 this._emulationEnabledChanged();
87 this._overridesWarningUpdated();
91 WebInspector.ResponsiveDesignView.RulerWidth = 34;
92 WebInspector.ResponsiveDesignView.RulerHeight = 22;
93 WebInspector.ResponsiveDesignView.RulerTopHeight = 11;
94 WebInspector.ResponsiveDesignView.RulerBottomHeight = 9;
96 WebInspector.ResponsiveDesignView.prototype = {
99 * @param {!WebInspector.Target} target
101 targetAdded: function(target)
103 // FIXME: adapt this to multiple targets.
106 this._target = target;
107 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ViewportChanged, this._viewportChanged, this);
111 * @param {!WebInspector.Target} target
113 targetRemoved: function(target)
115 if (target !== this._target)
117 target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.ViewportChanged, this._viewportChanged, this);
120 _invalidateCache: function()
122 delete this._cachedScale;
123 delete this._cachedCssCanvasWidth;
124 delete this._cachedCssCanvasHeight;
125 delete this._cachedCssHeight;
126 delete this._cachedCssWidth;
127 delete this._cachedZoomFactor;
128 delete this._cachedViewport;
129 delete this._cachedDrawContentsSize;
130 delete this._cachedMediaInspectorHeight;
131 delete this._availableSize;
134 _emulationEnabledChanged: function()
136 var enabled = WebInspector.overridesSupport.emulationEnabled();
137 this._mediaInspector.setEnabled(enabled);
138 if (enabled && !this._enabled) {
139 this._invalidateCache();
140 this._ignoreResize = true;
141 this._enabled = true;
142 this._inspectedPagePlaceholder.clearMinimumSizeAndMargins();
143 this._inspectedPagePlaceholder.show(this._pageContainer);
144 this._responsiveDesignContainer.show(this.element);
145 delete this._ignoreResize;
147 } else if (!enabled && this._enabled) {
148 this._invalidateCache();
149 this._ignoreResize = true;
150 this._enabled = false;
152 this._inspectedPagePlaceholder.restoreMinimumSizeAndMargins();
153 this._responsiveDesignContainer.detach();
154 this._inspectedPagePlaceholder.show(this.element);
155 delete this._ignoreResize;
161 * WebInspector.OverridesSupport.PageResizer override.
162 * @param {number} dipWidth
163 * @param {number} dipHeight
164 * @param {number} scale
166 update: function(dipWidth, dipHeight, scale)
169 this._dipWidth = dipWidth ? Math.max(dipWidth, 1) : 0;
170 this._dipHeight = dipHeight ? Math.max(dipHeight, 1) : 0;
174 updatePageResizer: function()
176 WebInspector.overridesSupport.setPageResizer(this, this._availableDipSize());
182 _availableDipSize: function()
184 if (typeof this._availableSize === "undefined") {
185 var zoomFactor = WebInspector.zoomManager.zoomFactor();
186 var rect = this._canvasContainer.element.getBoundingClientRect();
187 var rulerTotalHeight = this._rulerTotalHeightDIP();
188 this._availableSize = new Size(Math.max(rect.width * zoomFactor - WebInspector.ResponsiveDesignView.RulerWidth, 1),
189 Math.max(rect.height * zoomFactor - rulerTotalHeight, 1));
191 return this._availableSize;
195 * @param {!Element} element
196 * @param {boolean} vertical
197 * @return {!WebInspector.ResizerWidget}
199 _createResizer: function(element, vertical)
201 var resizer = new WebInspector.ResizerWidget();
202 resizer.addElement(element);
203 resizer.setVertical(vertical);
204 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
205 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate, this);
206 resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
211 * @param {!WebInspector.Event} event
213 _onResizeStart: function(event)
215 this._drawContentsSize = false;
216 var available = this._availableDipSize();
217 this._slowPositionStart = null;
218 this._resizeStartSize = event.target.isVertical() ? (this._dipHeight || available.height) : (this._dipWidth || available.width);
219 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.FixedScaleRequested, true);
224 * @param {!WebInspector.Event} event
226 _onResizeUpdate: function(event)
228 if (event.data.shiftKey !== !!this._slowPositionStart)
229 this._slowPositionStart = event.data.shiftKey ? event.data.currentPosition : null;
230 var cssOffset = this._slowPositionStart ? (event.data.currentPosition - this._slowPositionStart) / 10 + this._slowPositionStart - event.data.startPosition : event.data.currentPosition - event.data.startPosition;
231 var dipOffset = Math.round(cssOffset * WebInspector.zoomManager.zoomFactor());
232 var newSize = this._resizeStartSize + dipOffset;
233 newSize = Math.round(newSize / (this._scale || 1));
234 newSize = Math.max(Math.min(newSize, WebInspector.OverridesSupport.MaxDeviceSize), 1);
236 if (event.target.isVertical())
237 requested.height = newSize;
239 requested.width = newSize;
240 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, requested);
244 * @param {!WebInspector.Event} event
246 _onResizeEnd: function(event)
248 this._drawContentsSize = true;
249 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.FixedScaleRequested, false);
250 delete this._resizeStartSize;
255 * Draws canvas of the specified css size in DevTools page space.
256 * Canvas contains grid and rulers.
257 * @param {number} cssCanvasWidth
258 * @param {number} cssCanvasHeight
259 * @param {number} rulerHeight
261 _drawCanvas: function(cssCanvasWidth, cssCanvasHeight, rulerHeight)
266 var canvas = this._canvas;
267 var context = canvas.getContext("2d");
268 canvas.style.width = cssCanvasWidth + "px";
269 canvas.style.height = cssCanvasHeight + "px";
271 var zoomFactor = WebInspector.zoomManager.zoomFactor();
272 var dipCanvasWidth = cssCanvasWidth * zoomFactor;
273 var dipCanvasHeight = cssCanvasHeight * zoomFactor;
275 var deviceScaleFactor = window.devicePixelRatio;
276 canvas.width = deviceScaleFactor * cssCanvasWidth;
277 canvas.height = deviceScaleFactor * cssCanvasHeight;
278 context.scale(canvas.width / dipCanvasWidth, canvas.height / dipCanvasHeight);
279 context.font = "11px " + WebInspector.fontFamily();
281 const backgroundColor = "rgb(102, 102, 102)";
282 const lightLineColor = "rgb(132, 132, 132)";
283 const darkLineColor = "rgb(114, 114, 114)";
284 const rulerColor = "rgb(125, 125, 125)";
285 const textColor = "rgb(186, 186, 186)";
286 const contentsSizeColor = "rgba(0, 0, 0, 0.3)";
288 var scale = (this._scale || 1) * this._viewport.pageScaleFactor;
289 var rulerScale = 0.5;
290 while (Math.abs(rulerScale * scale - 1) > Math.abs((rulerScale + 0.5) * scale - 1))
293 var gridStep = 50 * scale * rulerScale;
294 var gridSubStep = 10 * scale * rulerScale;
296 var rulerSubStep = 5 * scale * rulerScale;
297 var rulerStepCount = 20;
299 var rulerWidth = WebInspector.ResponsiveDesignView.RulerWidth;
301 var dipGridWidth = dipCanvasWidth - rulerWidth;
302 var dipGridHeight = dipCanvasHeight - rulerHeight;
303 var dipScrollX = this._viewport.scrollX * scale;
304 var dipScrollY = this._viewport.scrollY * scale;
305 context.translate(rulerWidth, rulerHeight);
307 context.fillStyle = backgroundColor;
308 context.fillRect(0, 0, dipGridWidth, dipGridHeight);
310 context.translate(0.5, 0.5);
311 context.strokeStyle = rulerColor;
312 context.fillStyle = textColor;
313 context.lineWidth = 1;
315 // Draw horizontal ruler.
318 var minXIndex = Math.ceil(dipScrollX / rulerSubStep);
319 var maxXIndex = Math.floor((dipScrollX + dipGridWidth) / rulerSubStep);
322 context.moveTo(0, -rulerHeight);
323 context.lineTo(0, 0);
327 context.translate(-dipScrollX, 0);
328 for (var index = minXIndex; index <= maxXIndex; index++) {
329 var x = index * rulerSubStep;
330 var height = WebInspector.ResponsiveDesignView.RulerHeight * 0.25;
332 if (!(index % (rulerStepCount / 4)))
333 height = WebInspector.ResponsiveDesignView.RulerHeight * 0.5;
335 if (!(index % (rulerStepCount / 2)))
336 height = rulerHeight;
338 if (!(index % rulerStepCount)) {
340 context.translate(x, 0);
341 context.fillText(Math.round(x / scale), 2, -rulerHeight + 10);
343 height = rulerHeight;
347 context.moveTo(x, - height);
348 context.lineTo(x, 0);
353 // Draw vertical ruler.
355 var minYIndex = Math.ceil(dipScrollY / rulerSubStep);
356 var maxYIndex = Math.floor((dipScrollY + dipGridHeight) / rulerSubStep);
357 context.translate(0, -dipScrollY);
358 for (var index = minYIndex; index <= maxYIndex; index++) {
359 var y = index * rulerSubStep;
360 var x = -rulerWidth * 0.25;
361 if (!(index % (rulerStepCount / 4)))
362 x = -rulerWidth * 0.5;
363 if (!(index % (rulerStepCount / 2)))
364 x = -rulerWidth * 0.75;
366 if (!(index % rulerStepCount)) {
368 context.translate(0, y);
369 context.rotate(-Math.PI / 2);
370 context.fillText(Math.round(y / scale), 2, -rulerWidth + 10);
376 context.moveTo(x, y);
377 context.lineTo(0, y);
383 drawGrid(dipScrollX, dipScrollY, darkLineColor, gridSubStep);
384 drawGrid(dipScrollX, dipScrollY, lightLineColor, gridStep);
387 * @param {number} scrollX
388 * @param {number} scrollY
389 * @param {string} color
390 * @param {number} step
392 function drawGrid(scrollX, scrollY, color, step)
394 context.strokeStyle = color;
395 var minX = Math.ceil(scrollX / step) * step;
396 var maxX = Math.floor((scrollX + dipGridWidth) / step) * step - minX;
397 var minY = Math.ceil(scrollY / step) * step;
398 var maxY = Math.floor((scrollY + dipGridHeight) / step) * step - minY;
401 context.translate(minX - scrollX, 0);
402 for (var x = 0; x <= maxX; x += step) {
404 context.moveTo(x, 0);
405 context.lineTo(x, dipGridHeight);
411 context.translate(0, minY - scrollY);
412 for (var y = 0; y <= maxY; y += step) {
414 context.moveTo(0, y);
415 context.lineTo(dipGridWidth, y);
421 context.translate(-0.5, -0.5);
423 // Draw contents size.
424 var pageScaleAvailable = WebInspector.overridesSupport.settings.emulateMobile.get() || WebInspector.overridesSupport.settings.emulateTouch.get();
425 if (this._drawContentsSize && pageScaleAvailable) {
426 context.fillStyle = contentsSizeColor;
427 var visibleContentsWidth = Math.max(0, Math.min(dipGridWidth, this._viewport.contentsWidth * scale - dipScrollX));
428 var visibleContentsHeight = Math.max(0, Math.min(dipGridHeight, this._viewport.contentsHeight * scale - dipScrollY));
429 context.fillRect(0, 0, visibleContentsWidth, visibleContentsHeight);
436 _rulerTotalHeightDIP: function()
438 var mediaInspectorHeight = this._mediaInspector.isShowing() ? this._mediaInspector.element.offsetHeight : 0;
439 if (!mediaInspectorHeight)
440 return WebInspector.ResponsiveDesignView.RulerHeight;
441 return WebInspector.ResponsiveDesignView.RulerTopHeight + WebInspector.ResponsiveDesignView.RulerBottomHeight + mediaInspectorHeight * WebInspector.zoomManager.zoomFactor();
444 _updateUI: function()
446 if (!this._enabled || !this.isShowing())
449 var zoomFactor = WebInspector.zoomManager.zoomFactor();
450 var rect = this._canvas.parentElement.getBoundingClientRect();
451 var availableDip = this._availableDipSize();
452 var cssCanvasWidth = rect.width;
453 var cssCanvasHeight = rect.height;
454 var mediaInspectorHeight = this._mediaInspector.isShowing() ? this._mediaInspector.element.offsetHeight : 0;
455 var rulerTotalHeight = this._rulerTotalHeightDIP();
457 this._mediaInspector.setAxisTransform(this._viewport.scrollX, this._scale * this._viewport.pageScaleFactor);
459 if (this._cachedZoomFactor !== zoomFactor || this._cachedMediaInspectorHeight !== mediaInspectorHeight) {
460 var cssRulerWidth = WebInspector.ResponsiveDesignView.RulerWidth / zoomFactor + "px";
461 var cssRulerHeight = (mediaInspectorHeight ? WebInspector.ResponsiveDesignView.RulerTopHeight : WebInspector.ResponsiveDesignView.RulerHeight) / zoomFactor + "px";
462 var cssCanvasOffset = rulerTotalHeight / zoomFactor + "px";
463 this._slidersContainer.style.left = cssRulerWidth;
464 this._slidersContainer.style.top = cssCanvasOffset;
465 this._warningMessage.style.height = cssCanvasOffset;
466 this._pageScaleContainer.style.top = cssCanvasOffset;
467 this._mediaInspectorContainer.style.left = cssRulerWidth;
468 this._mediaInspectorContainer.style.marginTop = cssRulerHeight;
471 var cssWidth = (this._dipWidth ? this._dipWidth : availableDip.width) / zoomFactor;
472 var cssHeight = (this._dipHeight ? this._dipHeight : availableDip.height) / zoomFactor;
473 if (this._cachedCssWidth !== cssWidth || this._cachedCssHeight !== cssHeight) {
474 this._slidersContainer.style.width = cssWidth + "px";
475 this._slidersContainer.style.height = cssHeight + "px";
476 this._inspectedPagePlaceholder.onResize();
479 var pageScaleVisible = cssWidth + this._pageScaleContainerWidth + WebInspector.ResponsiveDesignView.RulerWidth / zoomFactor <= rect.width;
480 this._pageScaleContainer.classList.toggle("hidden", !pageScaleVisible);
482 var viewportChanged = !this._cachedViewport
483 || this._cachedViewport.scrollX !== this._viewport.scrollX || this._cachedViewport.scrollY !== this._viewport.scrollY
484 || this._cachedViewport.contentsWidth !== this._viewport.contentsWidth || this._cachedViewport.contentsHeight !== this._viewport.contentsHeight
485 || this._cachedViewport.pageScaleFactor !== this._viewport.pageScaleFactor
486 || this._cachedViewport.minimumPageScaleFactor !== this._viewport.minimumPageScaleFactor
487 || this._cachedViewport.maximumPageScaleFactor !== this._viewport.maximumPageScaleFactor;
489 var canvasInvalidated = viewportChanged || this._drawContentsSize !== this._cachedDrawContentsSize || this._cachedScale !== this._scale ||
490 this._cachedCssCanvasWidth !== cssCanvasWidth || this._cachedCssCanvasHeight !== cssCanvasHeight || this._cachedZoomFactor !== zoomFactor ||
491 this._cachedMediaInspectorHeight !== mediaInspectorHeight;
493 if (canvasInvalidated)
494 this._drawCanvas(cssCanvasWidth, cssCanvasHeight, rulerTotalHeight);
496 if (viewportChanged) {
497 this._pageScaleLabel.textContent = WebInspector.UIString("%.1f", this._viewport.pageScaleFactor);
498 this._decreasePageScaleButton.title = WebInspector.UIString("Scale down (minimum %.1f)", this._viewport.minimumPageScaleFactor);
499 this._decreasePageScaleButton.setEnabled(this._viewport.pageScaleFactor > this._viewport.minimumPageScaleFactor);
500 this._increasePageScaleButton.title = WebInspector.UIString("Scale up (maximum %.1f)", this._viewport.maximumPageScaleFactor);
501 this._increasePageScaleButton.setEnabled(this._viewport.pageScaleFactor < this._viewport.maximumPageScaleFactor);
504 this._cachedScale = this._scale;
505 this._cachedCssCanvasWidth = cssCanvasWidth;
506 this._cachedCssCanvasHeight = cssCanvasHeight;
507 this._cachedCssHeight = cssHeight;
508 this._cachedCssWidth = cssWidth;
509 this._cachedZoomFactor = zoomFactor;
510 this._cachedViewport = this._viewport;
511 this._cachedDrawContentsSize = this._drawContentsSize;
512 this._cachedMediaInspectorHeight = mediaInspectorHeight;
517 if (!this._enabled || this._ignoreResize)
519 var oldSize = this._availableSize;
521 this._pageScaleContainer.classList.remove("hidden");
522 this._pageScaleContainerWidth = this._pageScaleContainer.offsetWidth;
524 delete this._availableSize;
525 var newSize = this._availableDipSize();
526 if (!newSize.isEqual(oldSize))
527 this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, newSize);
529 this._inspectedPagePlaceholder.onResize();
532 _onZoomChanged: function()
537 _createToolbar: function()
539 this._toolbarElement = this._responsiveDesignContainer.element.createChild("div", "responsive-design-toolbar");
540 this._createButtonsSection();
541 this._createDeviceSection();
542 this._toolbarElement.createChild("div", "responsive-design-separator");
543 this._createNetworkSection();
544 this._toolbarElement.createChild("div", "responsive-design-separator");
546 var moreButtonContainer = this._toolbarElement.createChild("div", "responsive-design-more-button-container");
547 var moreButton = moreButtonContainer.createChild("button", "responsive-design-more-button");
548 moreButton.title = WebInspector.UIString("More overrides");
549 moreButton.addEventListener("click", this._showEmulationInDrawer.bind(this), false);
550 moreButton.textContent = "\u2026";
553 _createButtonsSection: function()
555 var buttonsSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-buttons");
557 var resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("Reset all overrides."), "clear-status-bar-item");
558 buttonsSection.appendChild(resetButton.element);
559 resetButton.addEventListener("click", WebInspector.overridesSupport.reset, WebInspector.overridesSupport);
561 // Media Query Inspector.
562 this._toggleMediaInspectorButton = new WebInspector.StatusBarButton(WebInspector.UIString("Media queries not found"), "responsive-design-toggle-media-inspector");
563 this._toggleMediaInspectorButton.toggled = WebInspector.settings.showMediaQueryInspector.get();
564 this._toggleMediaInspectorButton.setEnabled(false);
565 this._toggleMediaInspectorButton.addEventListener("click", this._onToggleMediaInspectorButtonClick, this);
566 WebInspector.settings.showMediaQueryInspector.addChangeListener(this._updateMediaQueryInspector, this);
567 buttonsSection.appendChild(this._toggleMediaInspectorButton.element);
570 _createDeviceSection: function()
572 var deviceSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-device");
574 var separator = deviceSection.createChild("div", "responsive-design-section-decorator");
577 var deviceElement = deviceSection.createChild("div", "responsive-design-suite responsive-design-suite-top").createChild("div");
579 var fieldsetElement = deviceElement.createChild("fieldset");
580 fieldsetElement.createChild("label").textContent = WebInspector.UIString("Device");
581 var deviceSelectElement = WebInspector.OverridesUI.createDeviceSelect();
582 fieldsetElement.appendChild(deviceSelectElement);
583 deviceSelectElement.classList.add("responsive-design-device-select");
585 var detailsElement = deviceSection.createChild("div", "responsive-design-suite");
588 var screenElement = detailsElement.createChild("div", "");
589 fieldsetElement = screenElement.createChild("fieldset");
591 var emulateResolutionCheckbox = WebInspector.SettingsUI.createSettingCheckbox("", WebInspector.overridesSupport.settings.emulateResolution, true, undefined, WebInspector.UIString("Emulate screen resolution"));
592 fieldsetElement.appendChild(emulateResolutionCheckbox);
594 var resolutionButton = new WebInspector.StatusBarButton(WebInspector.UIString("Screen resolution"), "responsive-design-icon responsive-design-icon-resolution");
595 resolutionButton.setEnabled(false);
596 fieldsetElement.appendChild(resolutionButton.element);
597 var resolutionFieldset = WebInspector.SettingsUI.createSettingFieldset(WebInspector.overridesSupport.settings.emulateResolution);
598 fieldsetElement.appendChild(resolutionFieldset);
600 resolutionFieldset.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceWidth, true, 4, "3em", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013")));
601 resolutionFieldset.createTextChild("\u00D7");
602 resolutionFieldset.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceHeight, true, 4, "3em", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013")));
604 var swapButton = new WebInspector.StatusBarButton(WebInspector.UIString("Swap dimensions"), "responsive-design-icon responsive-design-icon-swap");
605 swapButton.element.tabIndex = -1;
606 swapButton.addEventListener("click", WebInspector.overridesSupport.swapDimensions, WebInspector.overridesSupport);
607 resolutionFieldset.appendChild(swapButton.element);
609 // Device pixel ratio.
610 detailsElement.createChild("div", "responsive-design-suite-separator");
612 var dprElement = detailsElement.createChild("div", "");
613 var resolutionFieldset2 = WebInspector.SettingsUI.createSettingFieldset(WebInspector.overridesSupport.settings.emulateResolution);
614 dprElement.appendChild(resolutionFieldset2);
615 var dprButton = new WebInspector.StatusBarButton(WebInspector.UIString("Device pixel ratio"), "responsive-design-icon responsive-design-icon-dpr");
616 dprButton.setEnabled(false);
617 resolutionFieldset2.appendChild(dprButton.element);
618 resolutionFieldset2.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceScaleFactor, true, 4, "1.9em", WebInspector.OverridesSupport.deviceScaleFactorValidator, true, true, WebInspector.UIString("\u2013")));
621 detailsElement.createChild("div", "responsive-design-suite-separator");
622 var fitToWindowElement = detailsElement.createChild("div", "");
623 fieldsetElement = fitToWindowElement.createChild("fieldset");
624 fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Fit"), WebInspector.overridesSupport.settings.deviceFitWindow, true, undefined, WebInspector.UIString("Zoom to fit available space")));
627 _createNetworkSection: function()
629 var networkSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-network");
631 var separator = networkSection.createChild("div", "responsive-design-section-decorator");
634 var bandwidthElement = networkSection.createChild("div", "responsive-design-suite responsive-design-suite-top").createChild("div");
635 var fieldsetElement = bandwidthElement.createChild("fieldset");
636 var networkCheckbox = fieldsetElement.createChild("label");
637 networkCheckbox.textContent = WebInspector.UIString("Network");
638 fieldsetElement.appendChild(WebInspector.OverridesUI.createNetworkConditionsSelect());
641 var userAgentElement = networkSection.createChild("div", "responsive-design-suite").createChild("div");
642 fieldsetElement = userAgentElement.createChild("fieldset");
643 fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingInputField("UA", WebInspector.overridesSupport.settings.userAgent, false, 0, "", undefined, false, false, WebInspector.UIString("No override")));
646 _onToggleMediaInspectorButtonClick: function()
648 WebInspector.settings.showMediaQueryInspector.set(!this._toggleMediaInspectorButton.toggled);
651 _updateMediaQueryInspector: function()
653 this._toggleMediaInspectorButton.toggled = WebInspector.settings.showMediaQueryInspector.get();
654 if (this._mediaInspector.isShowing() === WebInspector.settings.showMediaQueryInspector.get())
656 if (this._mediaInspector.isShowing())
657 this._mediaInspector.detach();
659 this._mediaInspector.show(this._mediaInspectorContainer);
664 * @param {!WebInspector.Event} event
666 _updateMediaQueryInspectorButton: function(event)
668 var count = /** @type {number} */ (event.data);
669 this._toggleMediaInspectorButton.setEnabled(!!count);
670 this._toggleMediaInspectorButton.title = !count ? WebInspector.UIString("Media queries not found") :
671 WebInspector.UIString((count === 1 ? "%d media query found" : "%d media queries found"), count);
674 _overridesWarningUpdated: function()
676 var message = WebInspector.settings.disableOverridesWarning.get() ? "" : WebInspector.overridesSupport.warningMessage();
677 if (this._warning === message)
679 this._warning = message;
680 this._warningMessage.classList.toggle("hidden", !message);
681 this._warningMessage.querySelector("span").textContent = message;
682 this._invalidateCache();
686 _disableOverridesWarnings: function()
688 WebInspector.settings.disableOverridesWarning.set(true);
691 _showEmulationInDrawer: function()
693 WebInspector.Revealer.reveal(WebInspector.overridesSupport);
697 * @param {!WebInspector.Event} event
699 _viewportChanged: function(event)
701 var viewport = /** @type {?PageAgent.Viewport} */ (event.data);
703 this._viewport = viewport;
704 this._viewport.minimumPageScaleFactor = Math.max(0.1, this._viewport.minimumPageScaleFactor);
705 this._viewport.minimumPageScaleFactor = Math.min(this._viewport.minimumPageScaleFactor, this._viewport.pageScaleFactor);
706 this._viewport.maximumPageScaleFactor = Math.min(10, this._viewport.maximumPageScaleFactor);
707 this._viewport.maximumPageScaleFactor = Math.max(this._viewport.maximumPageScaleFactor, this._viewport.pageScaleFactor);
708 this._viewportChangedThrottler.schedule(this._updateUIThrottled.bind(this));
713 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
715 _updateUIThrottled: function(finishCallback)
722 * @param {boolean} increase
723 * @param {!WebInspector.Event} event
725 _pageScaleButtonClicked: function(increase, event)
727 this._pageScaleFactorThrottler.schedule(updatePageScaleFactor.bind(this));
730 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
731 * @this {WebInspector.ResponsiveDesignView}
733 function updatePageScaleFactor(finishCallback)
735 if (this._target && this._viewport) {
736 var value = this._viewport.pageScaleFactor;
737 value = increase ? value * 1.1 : value / 1.1;
738 value = Math.min(this._viewport.maximumPageScaleFactor, value);
739 value = Math.max(this._viewport.minimumPageScaleFactor, value)
740 this._target.pageAgent().setPageScaleFactor(value);
746 _resetPageScale: function()
748 this._pageScaleFactorThrottler.schedule(updatePageScaleFactor.bind(this));
751 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
752 * @this {WebInspector.ResponsiveDesignView}
754 function updatePageScaleFactor(finishCallback)
756 if (this._target && this._viewport && this._viewport.minimumPageScaleFactor <= 1 && this._viewport.maximumPageScaleFactor >= 1)
757 this._target.pageAgent().setPageScaleFactor(1);
762 __proto__: WebInspector.VBox.prototype