mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-01 04:47:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
16
view/crashtests/281743-1.html
Normal file
16
view/crashtests/281743-1.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Testcase bug 281743</title>
|
||||
<style type="text/css">
|
||||
#header { position: fixed; top: 0; left: 0; z-index: 100; }
|
||||
#mainmenu { position: fixed; top: 0; left: 0; z-index: 200; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
window.onload = function(e) {
|
||||
var e = document.getElementsByTagName("style")[0];
|
||||
e.disabled = true;
|
||||
e.disabled = false;
|
||||
}
|
||||
</script>
|
||||
</head><body><div id="page"><div id="header"></div><div id="mainmenu"></div></div></body></html>
|
||||
17
view/crashtests/323497-1.html
Normal file
17
view/crashtests/323497-1.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<html><head><style>
|
||||
body {
|
||||
display: inline;
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam est nunc, eleifend et, auctor eget, bibendum vel, sapien. Curabitur orci justo, ullamcorper in, ultrices id, consectetuer eget, metus. Vestibulum ornare rutrum quam. Nullam nisl. In tincidunt, sapien vitae fringilla posuere, est ante ultricies dolor, ultricies molestie eros diam id nisi. Praesent consequat velit. Nullam interdum, dui nec laoreet venenatis, felis libero pharetra dolor, ut dictum pede lorem vel est. In hac habitasse platea dictumst. Phasellus mattis eros eu libero. Suspendisse nonummy. Nullam ultricies eros eget tortor scelerisque feugiat. Aliquam erat volutpat. Integer neque. Cras a eros sit amet purus semper accumsan. Cras adipiscing porta augue. Nunc feugiat, turpis eu vehicula ultrices, augue nisl hendrerit diam, in porttitor augue sapien sit amet tortor. Ut eu tortor quis mauris posuere cursus. Donec molestie orci vitae eros. Nulla augue augue, tincidunt quis, fermentum a, rhoncus et, lectus.
|
||||
|
||||
<select><option>a</option></select>
|
||||
|
||||
</body></html>
|
||||
12
view/crashtests/382756-1.xul
Normal file
12
view/crashtests/382756-1.xul
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<tree rows="6">
|
||||
<treechildren style="-moz-appearance: checkbox;">
|
||||
</treechildren>
|
||||
</tree>
|
||||
|
||||
</window>
|
||||
10
view/crashtests/38589-1.xul
Normal file
10
view/crashtests/38589-1.xul
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<scrollbox>
|
||||
<stack>
|
||||
<box left="50" top="50" style="opacity:0.3;">p </box>
|
||||
</stack>
|
||||
</scrollbox>
|
||||
</window>
|
||||
11
view/crashtests/387745-1.svg
Normal file
11
view/crashtests/387745-1.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<foreignObject width="500" height="500">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||
<select><option>A</option></select>
|
||||
</div>
|
||||
</foreignObject>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 221 B |
17
view/crashtests/399852.html
Normal file
17
view/crashtests/399852.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function doe2() {
|
||||
document.body.setAttribute('style', 'overflow:scroll; direction: rtl;');
|
||||
}
|
||||
setTimeout(doe2,500);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<span style="position: fixed;">
|
||||
<iframe onload="window.frames[0].focus()"></iframe>
|
||||
</span>
|
||||
<li style=" position: fixed;" contenteditable="true"></li>
|
||||
</body>
|
||||
</html>
|
||||
12
view/crashtests/429315-1.html
Normal file
12
view/crashtests/429315-1.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<SPAN>
|
||||
<SPAN style="POSITION: relative">
|
||||
<BR>
|
||||
<BR>
|
||||
<select>
|
||||
</select>
|
||||
</BODY>
|
||||
</HTML>
|
||||
1
view/crashtests/507563-1.html
Normal file
1
view/crashtests/507563-1.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<html style="-moz-transform:rotate(5deg);width:-moz-max-content"><div style="letter-spacing:-4.59pt;overflow:auto;white-space:pre;text-shadow:-125396in -1in blue;-moz-column-count:15;text-indent:4.64%;direction:rtl">
|
||||
14
view/crashtests/64049-1.html
Normal file
14
view/crashtests/64049-1.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Testcase</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body >
|
||||
|
||||
|
||||
|
||||
<iframe id="page" width=2000000 height=2000000 src="data:text/html,Q"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
9
view/crashtests/crashtests.list
Normal file
9
view/crashtests/crashtests.list
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
load 38589-1.xul
|
||||
load 64049-1.html
|
||||
load 281743-1.html
|
||||
load 323497-1.html
|
||||
load 382756-1.xul
|
||||
load 387745-1.svg
|
||||
load 399852.html
|
||||
load 429315-1.html
|
||||
load 507563-1.html
|
||||
20
view/moz.build
Normal file
20
view/moz.build
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS += [
|
||||
'nsView.h',
|
||||
'nsViewManager.h',
|
||||
]
|
||||
|
||||
# nsViewManager.cpp cannot be built in unified mode because it uses PL_ARENA_CONST_ALIGN_MASK.
|
||||
SOURCES += [
|
||||
'nsView.cpp',
|
||||
'nsViewManager.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
1127
view/nsView.cpp
Normal file
1127
view/nsView.cpp
Normal file
File diff suppressed because it is too large
Load diff
486
view/nsView.h
Normal file
486
view/nsView.h
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsView_h__
|
||||
#define nsView_h__
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWidgetInitData.h" // for nsWindowType
|
||||
#include "nsIWidgetListener.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
|
||||
class nsViewManager;
|
||||
class nsIWidget;
|
||||
class nsIFrame;
|
||||
|
||||
// Enumerated type to indicate the visibility of a layer.
|
||||
// hide - the layer is not shown.
|
||||
// show - the layer is shown irrespective of the visibility of
|
||||
// the layer's parent.
|
||||
enum nsViewVisibility {
|
||||
nsViewVisibility_kHide = 0,
|
||||
nsViewVisibility_kShow = 1
|
||||
};
|
||||
|
||||
// Public view flags
|
||||
|
||||
// Indicates that the view is using auto z-indexing
|
||||
#define NS_VIEW_FLAG_AUTO_ZINDEX 0x0004
|
||||
|
||||
// Indicates that the view is a floating view.
|
||||
#define NS_VIEW_FLAG_FLOATING 0x0008
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* View interface
|
||||
*
|
||||
* Views are NOT reference counted. Use the Destroy() member function to
|
||||
* destroy a view.
|
||||
*
|
||||
* The lifetime of the view hierarchy is bounded by the lifetime of the
|
||||
* view manager that owns the views.
|
||||
*
|
||||
* Most of the methods here are read-only. To set the corresponding properties
|
||||
* of a view, go through nsViewManager.
|
||||
*/
|
||||
|
||||
class nsView final : public nsIWidgetListener
|
||||
{
|
||||
public:
|
||||
friend class nsViewManager;
|
||||
|
||||
typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
|
||||
typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
/**
|
||||
* Get the view manager which "owns" the view.
|
||||
* This method might require some expensive traversal work in the future. If you can get the
|
||||
* view manager from somewhere else, do that instead.
|
||||
* @result the view manager
|
||||
*/
|
||||
nsViewManager* GetViewManager() const { return mViewManager; }
|
||||
|
||||
/**
|
||||
* Find the view for the given widget, if there is one.
|
||||
* @return the view the widget belongs to, or null if the widget doesn't
|
||||
* belong to any view.
|
||||
*/
|
||||
static nsView* GetViewFor(nsIWidget* aWidget);
|
||||
|
||||
/**
|
||||
* Destroy the view.
|
||||
*
|
||||
* The view destroys its child views, and destroys and releases its
|
||||
* widget (if it has one).
|
||||
*
|
||||
* Also informs the view manager that the view is destroyed by calling
|
||||
* SetRootView(NULL) if the view is the root view and calling RemoveChild()
|
||||
* otherwise.
|
||||
*/
|
||||
void Destroy();
|
||||
|
||||
/**
|
||||
* Called to get the position of a view.
|
||||
* The specified coordinates are relative to the parent view's origin, but
|
||||
* are in appunits of this.
|
||||
* This is the (0, 0) origin of the coordinate space established by this view.
|
||||
* @param x out parameter for x position
|
||||
* @param y out parameter for y position
|
||||
*/
|
||||
nsPoint GetPosition() const {
|
||||
NS_ASSERTION(!IsRoot() || (mPosX == 0 && mPosY == 0),
|
||||
"root views should always have explicit position of (0,0)");
|
||||
return nsPoint(mPosX, mPosY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to get the dimensions and position of the view's bounds.
|
||||
* The view's bounds (x,y) are relative to the origin of the parent view, but
|
||||
* are in appunits of this.
|
||||
* The view's bounds (x,y) might not be the same as the view's position,
|
||||
* if the view has content above or to the left of its origin.
|
||||
* @param aBounds out parameter for bounds
|
||||
*/
|
||||
nsRect GetBounds() const { return mDimBounds; }
|
||||
|
||||
/**
|
||||
* The bounds of this view relative to this view. So this is the same as
|
||||
* GetBounds except this is relative to this view instead of the parent view.
|
||||
*/
|
||||
nsRect GetDimensions() const {
|
||||
nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the offset between the coordinate systems of |this| and aOther.
|
||||
* Adding the return value to a point in the coordinate system of |this|
|
||||
* will transform the point to the coordinate system of aOther.
|
||||
*
|
||||
* The offset is expressed in appunits of |this|. So if you are getting the
|
||||
* offset between views in different documents that might have different
|
||||
* appunits per devpixel ratios you need to be careful how you use the
|
||||
* result.
|
||||
*
|
||||
* If aOther is null, this will return the offset of |this| from the
|
||||
* root of the viewmanager tree.
|
||||
*
|
||||
* This function is fastest when aOther is an ancestor of |this|.
|
||||
*
|
||||
* NOTE: this actually returns the offset from aOther to |this|, but
|
||||
* that offset is added to transform _coordinates_ from |this| to aOther.
|
||||
*/
|
||||
nsPoint GetOffsetTo(const nsView* aOther) const;
|
||||
|
||||
/**
|
||||
* Get the offset between the origin of |this| and the origin of aWidget.
|
||||
* Adding the return value to a point in the coordinate system of |this|
|
||||
* will transform the point to the coordinate system of aWidget.
|
||||
*
|
||||
* The offset is expressed in appunits of |this|.
|
||||
*/
|
||||
nsPoint GetOffsetToWidget(nsIWidget* aWidget) const;
|
||||
|
||||
/**
|
||||
* Takes a point aPt that is in the coordinate system of |this|'s parent view
|
||||
* and converts it to be in the coordinate system of |this| taking into
|
||||
* account the offset and any app unit per dev pixel ratio differences.
|
||||
*/
|
||||
nsPoint ConvertFromParentCoords(nsPoint aPt) const;
|
||||
|
||||
/**
|
||||
* Called to query the visibility state of a view.
|
||||
* @result current visibility state
|
||||
*/
|
||||
nsViewVisibility GetVisibility() const { return mVis; }
|
||||
|
||||
/**
|
||||
* Get whether the view "floats" above all other views,
|
||||
* which tells the compositor not to consider higher views in
|
||||
* the view hierarchy that would geometrically intersect with
|
||||
* this view. This is a hack, but it fixes some problems with
|
||||
* views that need to be drawn in front of all other views.
|
||||
* @result true if the view floats, false otherwise.
|
||||
*/
|
||||
bool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
|
||||
|
||||
/**
|
||||
* Called to query the parent of the view.
|
||||
* @result view's parent
|
||||
*/
|
||||
nsView* GetParent() const { return mParent; }
|
||||
|
||||
/**
|
||||
* The view's first child is the child which is earliest in document order.
|
||||
* @result first child
|
||||
*/
|
||||
nsView* GetFirstChild() const { return mFirstChild; }
|
||||
|
||||
/**
|
||||
* Called to query the next sibling of the view.
|
||||
* @result view's next sibling
|
||||
*/
|
||||
nsView* GetNextSibling() const { return mNextSibling; }
|
||||
|
||||
/**
|
||||
* Set the view's frame.
|
||||
*/
|
||||
void SetFrame(nsIFrame* aRootFrame) { mFrame = aRootFrame; }
|
||||
|
||||
/**
|
||||
* Retrieve the view's frame.
|
||||
*/
|
||||
nsIFrame* GetFrame() const { return mFrame; }
|
||||
|
||||
/**
|
||||
* Get the nearest widget in this view or a parent of this view and
|
||||
* the offset from the widget's origin to this view's origin
|
||||
* @param aOffset - if non-null the offset from this view's origin to the
|
||||
* widget's origin (usually positive) expressed in appunits of this will be
|
||||
* returned in aOffset.
|
||||
* @return the widget closest to this view; can be null because some view trees
|
||||
* don't have widgets at all (e.g., printing), but if any view in the view tree
|
||||
* has a widget, then it's safe to assume this will not return null
|
||||
*/
|
||||
nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
|
||||
|
||||
/**
|
||||
* Create a widget to associate with this view. This variant of
|
||||
* CreateWidget*() will look around in the view hierarchy for an
|
||||
* appropriate parent widget for the view.
|
||||
*
|
||||
* @param aWidgetInitData data used to initialize this view's widget before
|
||||
* its create is called.
|
||||
* @return error status
|
||||
*/
|
||||
nsresult CreateWidget(nsWidgetInitData *aWidgetInitData = nullptr,
|
||||
bool aEnableDragDrop = true,
|
||||
bool aResetVisibility = true);
|
||||
|
||||
/**
|
||||
* Create a widget for this view with an explicit parent widget.
|
||||
* |aParentWidget| must be nonnull. The other params are the same
|
||||
* as for |CreateWidget()|.
|
||||
*/
|
||||
nsresult CreateWidgetForParent(nsIWidget* aParentWidget,
|
||||
nsWidgetInitData *aWidgetInitData = nullptr,
|
||||
bool aEnableDragDrop = true,
|
||||
bool aResetVisibility = true);
|
||||
|
||||
/**
|
||||
* Create a popup widget for this view. Pass |aParentWidget| to
|
||||
* explicitly set the popup's parent. If it's not passed, the view
|
||||
* hierarchy will be searched for an appropriate parent widget. The
|
||||
* other params are the same as for |CreateWidget()|, except that
|
||||
* |aWidgetInitData| must be nonnull.
|
||||
*/
|
||||
nsresult CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
|
||||
nsIWidget* aParentWidget = nullptr,
|
||||
bool aEnableDragDrop = true,
|
||||
bool aResetVisibility = true);
|
||||
|
||||
/**
|
||||
* Destroys the associated widget for this view. If this method is
|
||||
* not called explicitly, the widget when be destroyed when its
|
||||
* view gets destroyed.
|
||||
*/
|
||||
void DestroyWidget();
|
||||
|
||||
/**
|
||||
* Attach/detach a top level widget from this view. When attached, the view
|
||||
* updates the widget's device context and allows the view to begin receiving
|
||||
* gecko events. The underlying base window associated with the widget will
|
||||
* continues to receive events it expects.
|
||||
*
|
||||
* An attached widget will not be destroyed when the view is destroyed,
|
||||
* allowing the recycling of a single top level widget over multiple views.
|
||||
*
|
||||
* @param aWidget The widget to attach to / detach from.
|
||||
*/
|
||||
nsresult AttachToTopLevelWidget(nsIWidget* aWidget);
|
||||
nsresult DetachFromTopLevelWidget();
|
||||
|
||||
/**
|
||||
* Returns a flag indicating whether the view owns it's widget
|
||||
* or is attached to an existing top level widget.
|
||||
*/
|
||||
bool IsAttachedToTopLevel() const { return mWidgetIsTopLevel; }
|
||||
|
||||
/**
|
||||
* In 4.0, the "cutout" nature of a view is queryable.
|
||||
* If we believe that all cutout view have a native widget, this
|
||||
* could be a replacement.
|
||||
* @param aWidget out parameter for widget that this view contains,
|
||||
* or nullptr if there is none.
|
||||
*/
|
||||
nsIWidget* GetWidget() const { return mWindow; }
|
||||
|
||||
/**
|
||||
* The widget which we have attached a listener to can also have a "previous"
|
||||
* listener set on it. This is to keep track of the last nsView when navigating
|
||||
* to a new one so that we can continue to paint that if the new one isn't ready
|
||||
* yet.
|
||||
*/
|
||||
void SetPreviousWidget(nsIWidget* aWidget) { mPreviousWindow = aWidget; }
|
||||
|
||||
/**
|
||||
* Returns true if the view has a widget associated with it.
|
||||
*/
|
||||
bool HasWidget() const { return mWindow != nullptr; }
|
||||
|
||||
void SetForcedRepaint(bool aForceRepaint) {
|
||||
mForcedRepaint = aForceRepaint;
|
||||
}
|
||||
|
||||
void SetNeedsWindowPropertiesSync();
|
||||
|
||||
/**
|
||||
* Make aWidget direct its events to this view.
|
||||
* The caller must call DetachWidgetEventHandler before this view
|
||||
* is destroyed.
|
||||
*/
|
||||
void AttachWidgetEventHandler(nsIWidget* aWidget);
|
||||
/**
|
||||
* Stop aWidget directing its events to this view.
|
||||
*/
|
||||
void DetachWidgetEventHandler(nsIWidget* aWidget);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Output debug info to FILE
|
||||
* @param out output file handle
|
||||
* @param aIndent indentation depth
|
||||
* NOTE: virtual so that debugging tools not linked into gklayout can access it
|
||||
*/
|
||||
virtual void List(FILE* out, int32_t aIndent = 0) const;
|
||||
#endif // DEBUG
|
||||
|
||||
/**
|
||||
* @result true iff this is the root view for its view manager
|
||||
*/
|
||||
bool IsRoot() const;
|
||||
|
||||
LayoutDeviceIntRect CalcWidgetBounds(nsWindowType aType);
|
||||
|
||||
// This is an app unit offset to add when converting view coordinates to
|
||||
// widget coordinates. It is the offset in view coordinates from widget
|
||||
// origin (unlike views, widgets can't extend above or to the left of their
|
||||
// origin) to view origin expressed in appunits of this.
|
||||
nsPoint ViewToWidgetOffset() const { return mViewToWidgetOffset; }
|
||||
|
||||
/**
|
||||
* Called to indicate that the position of the view has been changed.
|
||||
* The specified coordinates are in the parent view's coordinate space.
|
||||
* @param x new x position
|
||||
* @param y new y position
|
||||
*/
|
||||
void SetPosition(nscoord aX, nscoord aY);
|
||||
|
||||
/**
|
||||
* Called to indicate that the z-index of a view has been changed.
|
||||
* The z-index is relative to all siblings of the view.
|
||||
* @param aAuto Indicate that the z-index of a view is "auto". An "auto" z-index
|
||||
* means that the view does not define a new stacking context,
|
||||
* which means that the z-indicies of the view's children are
|
||||
* relative to the view's siblings.
|
||||
* @param zindex new z depth
|
||||
*/
|
||||
void SetZIndex(bool aAuto, int32_t aZIndex);
|
||||
bool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
|
||||
int32_t GetZIndex() const { return mZIndex; }
|
||||
|
||||
void SetParent(nsView *aParent) { mParent = aParent; }
|
||||
void SetNextSibling(nsView *aSibling)
|
||||
{
|
||||
NS_ASSERTION(aSibling != this, "Can't be our own sibling!");
|
||||
mNextSibling = aSibling;
|
||||
}
|
||||
|
||||
nsRegion* GetDirtyRegion() {
|
||||
if (!mDirtyRegion) {
|
||||
NS_ASSERTION(!mParent || GetFloating(),
|
||||
"Only display roots should have dirty regions");
|
||||
mDirtyRegion = new nsRegion();
|
||||
NS_ASSERTION(mDirtyRegion, "Out of memory!");
|
||||
}
|
||||
return mDirtyRegion;
|
||||
}
|
||||
|
||||
// nsIWidgetListener
|
||||
virtual nsIPresShell* GetPresShell() override;
|
||||
virtual nsView* GetView() override { return this; }
|
||||
virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
|
||||
virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override;
|
||||
virtual bool RequestWindowClose(nsIWidget* aWidget) override;
|
||||
virtual void WillPaintWindow(nsIWidget* aWidget) override;
|
||||
virtual bool PaintWindow(nsIWidget* aWidget,
|
||||
LayoutDeviceIntRegion aRegion) override;
|
||||
virtual void DidPaintWindow() override;
|
||||
virtual void DidCompositeWindow(uint64_t aTransactionId,
|
||||
const mozilla::TimeStamp& aCompositeStart,
|
||||
const mozilla::TimeStamp& aCompositeEnd) override;
|
||||
virtual void RequestRepaint() override;
|
||||
virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
|
||||
bool aUseAttachedEvents) override;
|
||||
|
||||
virtual ~nsView();
|
||||
|
||||
nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
|
||||
nsIWidget* GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const;
|
||||
|
||||
bool IsPrimaryFramePaintSuppressed();
|
||||
|
||||
private:
|
||||
explicit nsView(nsViewManager* aViewManager = nullptr,
|
||||
nsViewVisibility aVisibility = nsViewVisibility_kShow);
|
||||
|
||||
bool ForcedRepaint() { return mForcedRepaint; }
|
||||
|
||||
// Do the actual work of ResetWidgetBounds, unconditionally. Don't
|
||||
// call this method if we have no widget.
|
||||
void DoResetWidgetBounds(bool aMoveOnly, bool aInvalidateChangedSize);
|
||||
void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
|
||||
|
||||
bool IsEffectivelyVisible();
|
||||
|
||||
/**
|
||||
* Called to indicate that the dimensions of the view have been changed.
|
||||
* The x and y coordinates may be < 0, indicating that the view extends above
|
||||
* or to the left of its origin position. The term 'dimensions' indicates it
|
||||
* is relative to this view.
|
||||
*/
|
||||
void SetDimensions(const nsRect &aRect, bool aPaint = true,
|
||||
bool aResizeWidget = true);
|
||||
|
||||
/**
|
||||
* Called to indicate that the visibility of a view has been
|
||||
* changed.
|
||||
* @param visibility new visibility state
|
||||
*/
|
||||
void SetVisibility(nsViewVisibility visibility);
|
||||
|
||||
/**
|
||||
* Set/Get whether the view "floats" above all other views,
|
||||
* which tells the compositor not to consider higher views in
|
||||
* the view hierarchy that would geometrically intersect with
|
||||
* this view. This is a hack, but it fixes some problems with
|
||||
* views that need to be drawn in front of all other views.
|
||||
* @result true if the view floats, false otherwise.
|
||||
*/
|
||||
void SetFloating(bool aFloatingView);
|
||||
|
||||
// Helper function to get mouse grabbing off this view (by moving it to the
|
||||
// parent, if we can)
|
||||
void DropMouseGrabbing();
|
||||
|
||||
// Same as GetBounds but converts to parent appunits if they are different.
|
||||
nsRect GetBoundsInParentUnits() const;
|
||||
|
||||
bool HasNonEmptyDirtyRegion() {
|
||||
return mDirtyRegion && !mDirtyRegion->IsEmpty();
|
||||
}
|
||||
|
||||
void InsertChild(nsView *aChild, nsView *aSibling);
|
||||
void RemoveChild(nsView *aChild);
|
||||
|
||||
void ResetWidgetBounds(bool aRecurse, bool aForceSync);
|
||||
void AssertNoWindow();
|
||||
|
||||
void NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible);
|
||||
|
||||
// Update the cached RootViewManager for all view manager descendents.
|
||||
void InvalidateHierarchy();
|
||||
|
||||
nsViewManager *mViewManager;
|
||||
nsView *mParent;
|
||||
nsCOMPtr<nsIWidget> mWindow;
|
||||
nsCOMPtr<nsIWidget> mPreviousWindow;
|
||||
nsView *mNextSibling;
|
||||
nsView *mFirstChild;
|
||||
nsIFrame *mFrame;
|
||||
nsRegion *mDirtyRegion;
|
||||
int32_t mZIndex;
|
||||
nsViewVisibility mVis;
|
||||
// position relative our parent view origin but in our appunits
|
||||
nscoord mPosX, mPosY;
|
||||
// relative to parent, but in our appunits
|
||||
nsRect mDimBounds;
|
||||
// in our appunits
|
||||
nsPoint mViewToWidgetOffset;
|
||||
uint32_t mVFlags;
|
||||
bool mWidgetIsTopLevel;
|
||||
bool mForcedRepaint;
|
||||
bool mNeedsWindowPropertiesSync;
|
||||
};
|
||||
|
||||
#endif
|
||||
1185
view/nsViewManager.cpp
Normal file
1185
view/nsViewManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
445
view/nsViewManager.h
Normal file
445
view/nsViewManager.h
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsViewManager_h___
|
||||
#define nsViewManager_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsView.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
|
||||
class nsIWidget;
|
||||
struct nsRect;
|
||||
class nsRegion;
|
||||
class nsDeviceContext;
|
||||
class nsIPresShell;
|
||||
|
||||
class nsViewManager final
|
||||
{
|
||||
~nsViewManager();
|
||||
public:
|
||||
friend class nsView;
|
||||
|
||||
typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
|
||||
typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsViewManager)
|
||||
|
||||
nsViewManager();
|
||||
|
||||
/**
|
||||
* Initialize the ViewManager
|
||||
* Note: this instance does not hold a reference to the presshell
|
||||
* because it holds a reference to this instance.
|
||||
* @result The result of the initialization, NS_OK if no errors
|
||||
*/
|
||||
nsresult Init(nsDeviceContext* aContext);
|
||||
|
||||
/**
|
||||
* Create an ordinary view
|
||||
* @param aBounds initial bounds for view
|
||||
* XXX We should eliminate this parameter; you can set the bounds after CreateView
|
||||
* @param aParent intended parent for view. this is not actually set in the
|
||||
* nsView through this method. it is only used by the initialization
|
||||
* code to walk up the view tree, if necessary, to find resources.
|
||||
* XXX We should eliminate this parameter!
|
||||
* @param aVisibilityFlag initial visibility state of view
|
||||
* XXX We should eliminate this parameter; you can set it after CreateView
|
||||
* @result The new view. Never null.
|
||||
*/
|
||||
nsView* CreateView(const nsRect& aBounds,
|
||||
nsView* aParent,
|
||||
nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
|
||||
|
||||
/**
|
||||
* Get the root of the view tree.
|
||||
* @result the root view
|
||||
*/
|
||||
nsView* GetRootView() { return mRootView; }
|
||||
|
||||
/**
|
||||
* Set the root of the view tree. Does not destroy the current root view.
|
||||
* aView may have a parent view managed by a different view manager.
|
||||
* aView may have a widget (anything but printing) or may not (printing).
|
||||
* @param aView view to set as root
|
||||
*/
|
||||
void SetRootView(nsView *aView);
|
||||
|
||||
/**
|
||||
* Get the dimensions of the root window. The dimensions are in
|
||||
* twips
|
||||
* @param aWidth out parameter for width of window in twips
|
||||
* @param aHeight out parameter for height of window in twips
|
||||
*/
|
||||
void GetWindowDimensions(nscoord *aWidth, nscoord *aHeight);
|
||||
|
||||
/**
|
||||
* Set the dimensions of the root window.
|
||||
* Called if the root window is resized. The dimensions are in
|
||||
* twips
|
||||
* @param aWidth of window in twips
|
||||
* @param aHeight of window in twips
|
||||
*/
|
||||
void SetWindowDimensions(nscoord aWidth, nscoord aHeight,
|
||||
bool aDelayResize = false);
|
||||
|
||||
/**
|
||||
* Do any resizes that are pending.
|
||||
*/
|
||||
void FlushDelayedResize(bool aDoReflow);
|
||||
|
||||
/**
|
||||
* Called to inform the view manager that the entire area of a view
|
||||
* is dirty and needs to be redrawn.
|
||||
* @param aView view to paint. should be root view
|
||||
*/
|
||||
void InvalidateView(nsView *aView);
|
||||
|
||||
/**
|
||||
* Called to inform the view manager that some portion of a view is dirty and
|
||||
* needs to be redrawn. The rect passed in should be in the view's coordinate
|
||||
* space. Does not check for paint suppression.
|
||||
* @param aView view to paint. should be root view
|
||||
* @param rect rect to mark as damaged
|
||||
*/
|
||||
void InvalidateViewNoSuppression(nsView *aView, const nsRect &aRect);
|
||||
|
||||
/**
|
||||
* Called to inform the view manager that it should invalidate all views.
|
||||
*/
|
||||
void InvalidateAllViews();
|
||||
|
||||
/**
|
||||
* Called to dispatch an event to the appropriate view. Often called
|
||||
* as a result of receiving a mouse or keyboard event from the widget
|
||||
* event system.
|
||||
* @param aEvent event to dispatch
|
||||
* @param aViewTarget dispatch the event to this view
|
||||
* @param aStatus event handling status
|
||||
*/
|
||||
void DispatchEvent(mozilla::WidgetGUIEvent *aEvent,
|
||||
nsView* aViewTarget,
|
||||
nsEventStatus* aStatus);
|
||||
|
||||
/**
|
||||
* Given a parent view, insert another view as its child.
|
||||
* aSibling and aAbove control the "document order" for the insertion.
|
||||
* If aSibling is null, the view is inserted at the end of the document order
|
||||
* if aAfter is true, otherwise it is inserted at the beginning.
|
||||
* If aSibling is non-null, then if aAfter is true, the view is inserted
|
||||
* after the sibling in document order (appearing above the sibling unless
|
||||
* overriden by z-order).
|
||||
* If it is false, the view is inserted before the sibling.
|
||||
* The view manager generates the appopriate dirty regions.
|
||||
* @param aParent parent view
|
||||
* @param aChild child view
|
||||
* @param aSibling sibling view
|
||||
* @param aAfter after or before in the document order
|
||||
*/
|
||||
void InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling,
|
||||
bool aAfter);
|
||||
|
||||
void InsertChild(nsView *aParent, nsView *aChild, int32_t aZIndex);
|
||||
|
||||
/**
|
||||
* Remove a specific child view from its parent. This will NOT remove its placeholder
|
||||
* if there is one.
|
||||
* The view manager generates the appropriate dirty regions.
|
||||
* @param aParent parent view
|
||||
* @param aChild child view
|
||||
*/
|
||||
void RemoveChild(nsView *aChild);
|
||||
|
||||
/**
|
||||
* Move a view to the specified position, provided in parent coordinates.
|
||||
* The new position is the (0, 0) origin for the view's coordinate system.
|
||||
* The view's bounds may extend above or to the left of this point.
|
||||
* The view manager generates the appropriate dirty regions.
|
||||
* @param aView view to move
|
||||
* @param aX x value for new view position
|
||||
* @param aY y value for new view position
|
||||
*/
|
||||
void MoveViewTo(nsView *aView, nscoord aX, nscoord aY);
|
||||
|
||||
/**
|
||||
* Resize a view. In addition to setting the width and height, you can
|
||||
* set the x and y of its bounds relative to its position. Negative x and y
|
||||
* will let the view extend above and to the left of the (0,0) point in its
|
||||
* coordinate system.
|
||||
* The view manager generates the appropriate dirty regions.
|
||||
* @param aView view to move
|
||||
* @param the new bounds relative to the current position
|
||||
* @param RepaintExposedAreaOnly
|
||||
* if true Repaint only the expanded or contracted region,
|
||||
* if false Repaint the union of the old and new rectangles.
|
||||
*/
|
||||
void ResizeView(nsView *aView, const nsRect &aRect,
|
||||
bool aRepaintExposedAreaOnly = false);
|
||||
|
||||
/**
|
||||
* Set the visibility of a view. Hidden views have the effect of hiding
|
||||
* their descendants as well. This does not affect painting, so layout
|
||||
* is responsible for ensuring that content in hidden views is not
|
||||
* painted nor handling events. It does affect the visibility of widgets;
|
||||
* if a view is hidden, descendant views with widgets have their widgets
|
||||
* hidden.
|
||||
* The view manager generates the appropriate dirty regions.
|
||||
* @param aView view to change visibility state of
|
||||
* @param visible new visibility state
|
||||
*/
|
||||
void SetViewVisibility(nsView *aView, nsViewVisibility aVisible);
|
||||
|
||||
/**
|
||||
* Set the z-index of a view. Positive z-indices mean that a view
|
||||
* is above its parent in z-order. Negative z-indices mean that a
|
||||
* view is below its parent.
|
||||
* The view manager generates the appropriate dirty regions.
|
||||
* @param aAutoZIndex indicate that the z-index of a view is "auto". An "auto" z-index
|
||||
* means that the view does not define a new stacking context,
|
||||
* which means that the z-indicies of the view's children are
|
||||
* relative to the view's siblings.
|
||||
* @param aView view to change z depth of
|
||||
* @param aZindex explicit z depth
|
||||
*/
|
||||
void SetViewZIndex(nsView *aView, bool aAutoZIndex, int32_t aZindex);
|
||||
|
||||
/**
|
||||
* Set whether the view "floats" above all other views,
|
||||
* which tells the compositor not to consider higher views in
|
||||
* the view hierarchy that would geometrically intersect with
|
||||
* this view. This is a hack, but it fixes some problems with
|
||||
* views that need to be drawn in front of all other views.
|
||||
*/
|
||||
void SetViewFloating(nsView *aView, bool aFloatingView);
|
||||
|
||||
/**
|
||||
* Set the presshell associated with this manager
|
||||
* @param aPresShell - new presshell
|
||||
*/
|
||||
void SetPresShell(nsIPresShell *aPresShell) { mPresShell = aPresShell; }
|
||||
|
||||
/**
|
||||
* Get the pres shell associated with this manager
|
||||
*/
|
||||
nsIPresShell* GetPresShell() { return mPresShell; }
|
||||
|
||||
/**
|
||||
* Get the device context associated with this manager
|
||||
*/
|
||||
nsDeviceContext* GetDeviceContext() const
|
||||
{
|
||||
return mContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* A stack class for disallowing changes that would enter painting. For
|
||||
* example, popup widgets shouldn't be resized during reflow, since doing so
|
||||
* might cause synchronous painting inside reflow which is forbidden.
|
||||
* While refresh is disabled, widget geometry changes are deferred and will
|
||||
* be handled later, either from the refresh driver or from an NS_WILL_PAINT
|
||||
* event.
|
||||
* We don't want to defer widget geometry changes all the time. Resizing a
|
||||
* popup from script doesn't need to be deferred, for example, especially
|
||||
* since popup widget geometry is observable from script and expected to
|
||||
* update synchronously.
|
||||
*/
|
||||
class MOZ_STACK_CLASS AutoDisableRefresh {
|
||||
public:
|
||||
explicit AutoDisableRefresh(nsViewManager* aVM) {
|
||||
if (aVM) {
|
||||
mRootVM = aVM->IncrementDisableRefreshCount();
|
||||
}
|
||||
}
|
||||
~AutoDisableRefresh() {
|
||||
if (mRootVM) {
|
||||
mRootVM->DecrementDisableRefreshCount();
|
||||
}
|
||||
}
|
||||
private:
|
||||
AutoDisableRefresh(const AutoDisableRefresh& aOther);
|
||||
const AutoDisableRefresh& operator=(const AutoDisableRefresh& aOther);
|
||||
|
||||
RefPtr<nsViewManager> mRootVM;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class AutoDisableRefresh;
|
||||
|
||||
nsViewManager* IncrementDisableRefreshCount();
|
||||
void DecrementDisableRefreshCount();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Retrieve the widget at the root of the nearest enclosing
|
||||
* view manager whose root view has a widget.
|
||||
*/
|
||||
void GetRootWidget(nsIWidget **aWidget);
|
||||
|
||||
/**
|
||||
* Indicate whether the viewmanager is currently painting
|
||||
*
|
||||
* @param aPainting true if the viewmanager is painting
|
||||
* false otherwise
|
||||
*/
|
||||
void IsPainting(bool& aIsPainting);
|
||||
|
||||
/**
|
||||
* Retrieve the time of the last user event. User events
|
||||
* include mouse and keyboard events. The viewmanager
|
||||
* saves the time of the last user event.
|
||||
*
|
||||
* @param aTime Last user event time in microseconds
|
||||
*/
|
||||
void GetLastUserEventTime(uint32_t& aTime);
|
||||
|
||||
/**
|
||||
* Find the nearest display root view for the view aView. This is the view for
|
||||
* the nearest enclosing popup or the root view for the root document.
|
||||
*/
|
||||
static nsView* GetDisplayRootFor(nsView* aView);
|
||||
|
||||
/**
|
||||
* Flush the accumulated dirty region to the widget and update widget
|
||||
* geometry.
|
||||
*/
|
||||
void ProcessPendingUpdates();
|
||||
|
||||
/**
|
||||
* Just update widget geometry without flushing the dirty region
|
||||
*/
|
||||
void UpdateWidgetGeometry();
|
||||
|
||||
int32_t AppUnitsPerDevPixel() const
|
||||
{
|
||||
return mContext->AppUnitsPerDevPixel();
|
||||
}
|
||||
|
||||
private:
|
||||
static uint32_t gLastUserEventTime;
|
||||
|
||||
/* Update the cached RootViewManager pointer on this view manager. */
|
||||
void InvalidateHierarchy();
|
||||
void FlushPendingInvalidates();
|
||||
|
||||
void ProcessPendingUpdatesForView(nsView *aView,
|
||||
bool aFlushDirtyRegion = true);
|
||||
void ProcessPendingUpdatesRecurse(nsView* aView,
|
||||
nsTArray<nsCOMPtr<nsIWidget> >& aWidgets);
|
||||
void ProcessPendingUpdatesPaint(nsIWidget* aWidget);
|
||||
|
||||
void FlushDirtyRegionToWidget(nsView* aView);
|
||||
/**
|
||||
* Call WillPaint() on all view observers under this vm root.
|
||||
*/
|
||||
void CallWillPaintOnObservers();
|
||||
void ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget);
|
||||
void ReparentWidgets(nsView* aView, nsView *aParent);
|
||||
void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
|
||||
|
||||
void InvalidateViews(nsView *aView);
|
||||
|
||||
// aView is the view for aWidget and aRegion is relative to aWidget.
|
||||
void Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion);
|
||||
|
||||
// Utilities
|
||||
|
||||
bool IsViewInserted(nsView *aView);
|
||||
|
||||
/**
|
||||
* Intersects aRect with aView's bounds and then transforms it from aView's
|
||||
* coordinate system to the coordinate system of the widget attached to
|
||||
* aView.
|
||||
*/
|
||||
LayoutDeviceIntRect ViewToWidget(nsView* aView, const nsRect& aRect) const;
|
||||
|
||||
void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight);
|
||||
bool ShouldDelayResize() const;
|
||||
|
||||
bool IsPainting() const {
|
||||
return RootViewManager()->mPainting;
|
||||
}
|
||||
|
||||
void SetPainting(bool aPainting) {
|
||||
RootViewManager()->mPainting = aPainting;
|
||||
}
|
||||
|
||||
void InvalidateView(nsView *aView, const nsRect &aRect);
|
||||
|
||||
nsViewManager* RootViewManager() const { return mRootViewManager; }
|
||||
bool IsRootVM() const { return this == RootViewManager(); }
|
||||
|
||||
// Whether synchronous painting is allowed at the moment. For example,
|
||||
// widget geometry changes can cause synchronous painting, so they need to
|
||||
// be deferred while refresh is disabled.
|
||||
bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
|
||||
|
||||
void WillPaintWindow(nsIWidget* aWidget);
|
||||
bool PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion);
|
||||
void DidPaintWindow();
|
||||
|
||||
// Call this when you need to let the viewmanager know that it now has
|
||||
// pending updates.
|
||||
void PostPendingUpdate();
|
||||
|
||||
RefPtr<nsDeviceContext> mContext;
|
||||
nsIPresShell *mPresShell;
|
||||
|
||||
// The size for a resize that we delayed until the root view becomes
|
||||
// visible again.
|
||||
nsSize mDelayedResize;
|
||||
|
||||
nsView *mRootView;
|
||||
// mRootViewManager is a strong ref unless it equals |this|. It's
|
||||
// never null (if we have no ancestors, it will be |this|).
|
||||
nsViewManager *mRootViewManager;
|
||||
|
||||
// The following members should not be accessed directly except by
|
||||
// the root view manager. Some have accessor functions to enforce
|
||||
// this, as noted.
|
||||
|
||||
int32_t mRefreshDisableCount;
|
||||
// Use IsPainting() and SetPainting() to access mPainting.
|
||||
bool mPainting;
|
||||
bool mRecursiveRefreshPending;
|
||||
bool mHasPendingWidgetGeometryChanges;
|
||||
|
||||
//from here to public should be static and locked... MMP
|
||||
|
||||
//list of view managers
|
||||
static nsTArray<nsViewManager*> *gViewManagers;
|
||||
};
|
||||
|
||||
/**
|
||||
Invalidation model:
|
||||
|
||||
1) Callers call into the view manager and ask it to invalidate a view.
|
||||
|
||||
2) The view manager finds the "right" widget for the view, henceforth called
|
||||
the root widget.
|
||||
|
||||
3) The view manager traverses descendants of the root widget and for each
|
||||
one that needs invalidation stores the rect to invalidate on the widget's
|
||||
view (batching).
|
||||
|
||||
4) The dirty region is flushed to the right widget when
|
||||
ProcessPendingUpdates is called from the RefreshDriver.
|
||||
|
||||
It's important to note that widgets associated to views outside this view
|
||||
manager can end up being invalidated during step 3. Therefore, the end of a
|
||||
view update batch really needs to traverse the entire view tree, to ensure
|
||||
that those invalidates happen.
|
||||
|
||||
To cope with this, invalidation processing and should only happen on the
|
||||
root viewmanager.
|
||||
*/
|
||||
|
||||
#endif // nsViewManager_h___
|
||||
Loading…
Add table
Add a link
Reference in a new issue