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.View}
8 */
9WebInspector.InspectedPagePlaceholder = function()
10{
11    WebInspector.View.call(this);
12    this.element.classList.add("white-background");
13    WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._scheduleUpdate, this);
14    this._margins = { top: 0, right: 0, bottom: 0, left: 0 };
15    this.restoreMinimumSizeAndMargins();
16};
17
18WebInspector.InspectedPagePlaceholder.Events = {
19    Update: "Update"
20};
21
22WebInspector.InspectedPagePlaceholder.MarginValue = 3;
23
24WebInspector.InspectedPagePlaceholder.prototype = {
25    _findMargins: function()
26    {
27        var margins = { top: 0, right: 0, bottom: 0, left: 0 };
28
29        if (this._useMargins) {
30            var adjacent = { top: true, right: true, bottom: true, left: true };
31            var view = this;
32            while (view.parentView()) {
33                var parent = view.parentView();
34                // This view assumes it's always inside the main split view element, not a sidebar.
35                // Every parent which is not a split view, must be of the same size as this view.
36                if (parent instanceof WebInspector.SplitView) {
37                    var side = parent.sidebarSide();
38                    if (adjacent[side] && !parent.hasCustomResizer() && parent.isResizable())
39                        margins[side] = WebInspector.InspectedPagePlaceholder.MarginValue;
40                    adjacent[side] = false;
41                }
42                view = parent;
43            }
44        }
45
46        if (this._margins.top !== margins.top || this._margins.left !== margins.left || this._margins.right !== margins.right || this._margins.bottom !== margins.bottom) {
47            this._margins = margins;
48            this._scheduleUpdate();
49        }
50    },
51
52    onResize: function()
53    {
54        this._findMargins();
55        this._scheduleUpdate();
56    },
57
58    _scheduleUpdate: function()
59    {
60        if (this._updateId)
61            window.cancelAnimationFrame(this._updateId);
62        this._updateId = window.requestAnimationFrame(this.update.bind(this));
63    },
64
65    /**
66     * @return {!Size}
67     */
68    dipPageSize: function()
69    {
70        var rect = this._dipPageRect();
71        return new Size(Math.round(rect.width), Math.round(rect.height));
72    },
73
74    /**
75     * @return {!Size}
76     */
77    cssElementSize: function()
78    {
79        var zoomFactor = WebInspector.zoomManager.zoomFactor();
80        var rect = this.element.getBoundingClientRect();
81        var width = rect.width - (this._margins.left + this._margins.right) / zoomFactor;
82        var height = rect.height - (this._margins.top + this._margins.bottom) / zoomFactor;
83        return new Size(width, height);
84    },
85
86    restoreMinimumSizeAndMargins: function()
87    {
88        this._useMargins = true;
89        this.setMinimumSize(50, 50);
90        this._findMargins();
91    },
92
93    clearMinimumSizeAndMargins: function()
94    {
95        this._useMargins = false;
96        this.setMinimumSize(1, 1);
97        this._findMargins();
98    },
99
100    _dipPageRect: function()
101    {
102        var zoomFactor = WebInspector.zoomManager.zoomFactor();
103        var rect = this.element.getBoundingClientRect();
104        var bodyRect = document.body.getBoundingClientRect();
105
106        var left = Math.max(rect.left * zoomFactor + this._margins.left, bodyRect.left * zoomFactor);
107        var top = Math.max(rect.top * zoomFactor + this._margins.top, bodyRect.top * zoomFactor);
108        var bottom = Math.min(rect.bottom * zoomFactor - this._margins.bottom, bodyRect.bottom * zoomFactor);
109        var right = Math.min(rect.right * zoomFactor - this._margins.right, bodyRect.right * zoomFactor);
110
111        return { x: left, y: top, width: right - left, height: bottom - top };
112    },
113
114    update: function()
115    {
116        delete this._updateId;
117        var rect = this._dipPageRect();
118        var bounds = { x: Math.round(rect.x), y: Math.round(rect.y), height: Math.max(1, Math.round(rect.height)), width: Math.max(1, Math.round(rect.width)) };
119        this.dispatchEventToListeners(WebInspector.InspectedPagePlaceholder.Events.Update, bounds);
120    },
121
122    __proto__: WebInspector.View.prototype
123};
124