diff options
author | Pale Moon <git-repo@palemoon.org> | 2016-09-01 13:39:08 +0200 |
---|---|---|
committer | Pale Moon <git-repo@palemoon.org> | 2016-09-01 13:39:08 +0200 |
commit | 3d8ce1a11a7347cc94a937719c4bc8df46fb8d14 (patch) | |
tree | 8c26ca375a6312751c00a27e1653fb6f189f0463 /layout/xul | |
parent | e449bdb1ec3a82f204bffdd9c3c54069d086eee3 (diff) | |
download | palemoon-gre-3d8ce1a11a7347cc94a937719c4bc8df46fb8d14.tar.gz |
Base import of Tycho code (warning: huge commit)
Diffstat (limited to 'layout/xul')
-rw-r--r-- | layout/xul/BoxObject.cpp (renamed from layout/xul/base/src/nsBoxObject.cpp) | 304 | ||||
-rw-r--r-- | layout/xul/BoxObject.h | 92 | ||||
-rw-r--r-- | layout/xul/ContainerBoxObject.cpp | 75 | ||||
-rw-r--r-- | layout/xul/ContainerBoxObject.h | 31 | ||||
-rw-r--r-- | layout/xul/ListBoxObject.cpp | 238 | ||||
-rw-r--r-- | layout/xul/ListBoxObject.h | 54 | ||||
-rw-r--r-- | layout/xul/MenuBoxObject.cpp | 151 | ||||
-rw-r--r-- | layout/xul/MenuBoxObject.h | 38 | ||||
-rw-r--r-- | layout/xul/PopupBoxObject.cpp (renamed from layout/xul/base/src/nsPopupBoxObject.cpp) | 265 | ||||
-rw-r--r-- | layout/xul/PopupBoxObject.h | 106 | ||||
-rw-r--r-- | layout/xul/ScrollBoxObject.cpp | 394 | ||||
-rw-r--r-- | layout/xul/ScrollBoxObject.h | 64 | ||||
-rw-r--r-- | layout/xul/base/public/moz.build | 29 | ||||
-rw-r--r-- | layout/xul/base/public/nsIMenuBoxObject.idl | 28 | ||||
-rw-r--r-- | layout/xul/base/public/nsIPopupBoxObject.idl | 181 | ||||
-rw-r--r-- | layout/xul/base/public/nsIScrollBoxObject.idl | 50 | ||||
-rw-r--r-- | layout/xul/base/public/nsIScrollbarMediator.h | 26 | ||||
-rw-r--r-- | layout/xul/base/reftest/reftest.list | 5 | ||||
-rw-r--r-- | layout/xul/base/src/Makefile.in | 34 | ||||
-rw-r--r-- | layout/xul/base/src/nsBoxObject.h | 55 | ||||
-rw-r--r-- | layout/xul/base/src/nsContainerBoxObject.cpp | 101 | ||||
-rw-r--r-- | layout/xul/base/src/nsLeafBoxFrame.h | 92 | ||||
-rw-r--r-- | layout/xul/base/src/nsListBoxObject.cpp | 219 | ||||
-rw-r--r-- | layout/xul/base/src/nsMenuBoxObject.cpp | 159 | ||||
-rw-r--r-- | layout/xul/base/src/nsPopupSetFrame.h | 61 | ||||
-rw-r--r-- | layout/xul/base/src/nsScrollBoxObject.cpp | 328 | ||||
-rw-r--r-- | layout/xul/base/src/nsScrollbarFrame.cpp | 192 | ||||
-rw-r--r-- | layout/xul/base/src/nsScrollbarFrame.h | 90 | ||||
-rw-r--r-- | layout/xul/base/src/nsSplitterFrame.h | 83 | ||||
-rw-r--r-- | layout/xul/base/test/Makefile.in | 30 | ||||
-rw-r--r-- | layout/xul/base/test/moz.build | 6 | ||||
-rw-r--r-- | layout/xul/crashtests/131008-1.xul (renamed from layout/xul/base/src/crashtests/131008-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/137216-1.xul (renamed from layout/xul/base/src/crashtests/137216-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/140218-1.xml (renamed from layout/xul/base/src/crashtests/140218-1.xml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/151826-1.xul (renamed from layout/xul/base/src/crashtests/151826-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/168724-1.xul (renamed from layout/xul/base/src/crashtests/168724-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/189814-1.xul (renamed from layout/xul/base/src/crashtests/189814-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/237787-1.xul (renamed from layout/xul/base/src/crashtests/237787-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/265161-1.xul (renamed from layout/xul/base/src/crashtests/265161-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/289410-1.xul (renamed from layout/xul/base/src/crashtests/289410-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/290743.html | 6 | ||||
-rw-r--r-- | layout/xul/crashtests/291702-1.xul (renamed from layout/xul/base/src/crashtests/291702-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/291702-2.xul (renamed from layout/xul/base/src/crashtests/291702-2.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/291702-3.xul (renamed from layout/xul/base/src/crashtests/291702-3.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/294371-1.xul (renamed from layout/xul/base/src/crashtests/294371-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/311457-1.html (renamed from layout/xul/base/src/crashtests/311457-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/321056-1.xhtml (renamed from layout/xul/base/src/crashtests/321056-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/322786-1.xul (renamed from layout/xul/base/src/crashtests/322786-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/325377.xul (renamed from layout/xul/base/src/crashtests/325377.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/326834-1-inner.xul (renamed from layout/xul/base/src/crashtests/326834-1-inner.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/326834-1.html (renamed from layout/xul/base/src/crashtests/326834-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/326879-1.xul (renamed from layout/xul/base/src/crashtests/326879-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/327776-1.xul (renamed from layout/xul/base/src/crashtests/327776-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/328135-1.xul (renamed from layout/xul/base/src/crashtests/328135-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/329327-1.xul (renamed from layout/xul/base/src/crashtests/329327-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/329407-1.xml (renamed from layout/xul/base/src/crashtests/329407-1.xml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/329477-1.xhtml (renamed from layout/xul/base/src/crashtests/329477-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/336962-1.xul (renamed from layout/xul/base/src/crashtests/336962-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/344228-1.xul (renamed from layout/xul/base/src/crashtests/344228-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/346083-1.xul (renamed from layout/xul/base/src/crashtests/346083-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/346281-1.xul (renamed from layout/xul/base/src/crashtests/346281-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/350460.xul (renamed from layout/xul/base/src/crashtests/350460.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/360642-1.xul (renamed from layout/xul/base/src/crashtests/360642-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/365151.xul (renamed from layout/xul/base/src/crashtests/365151.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/366112-1.xul (renamed from layout/xul/base/src/crashtests/366112-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/369942-1.xhtml (renamed from layout/xul/base/src/crashtests/369942-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/374102-1.xul (renamed from layout/xul/base/src/crashtests/374102-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/376137-1.html (renamed from layout/xul/base/src/crashtests/376137-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/376137-2.html (renamed from layout/xul/base/src/crashtests/376137-2.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/377592-1.svg (renamed from layout/xul/base/src/crashtests/377592-1.svg) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/378961.html | 9 | ||||
-rw-r--r-- | layout/xul/crashtests/381862.html (renamed from layout/xul/base/src/crashtests/381862.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/382746-1.xul (renamed from layout/xul/base/src/crashtests/382746-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/382899-1.xul (renamed from layout/xul/base/src/crashtests/382899-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/383236-1.xul (renamed from layout/xul/base/src/crashtests/383236-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384037-1.xhtml (renamed from layout/xul/base/src/crashtests/384037-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384105-1-inner.xul (renamed from layout/xul/base/src/crashtests/384105-1-inner.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384105-1.html (renamed from layout/xul/base/src/crashtests/384105-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384373-1.xul | 10 | ||||
-rw-r--r-- | layout/xul/crashtests/384373-2.xul | 4 | ||||
-rw-r--r-- | layout/xul/crashtests/384373.html | 23 | ||||
-rw-r--r-- | layout/xul/crashtests/384491-1.xhtml (renamed from layout/xul/base/src/crashtests/384491-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384871-1-inner.xul (renamed from layout/xul/base/src/crashtests/384871-1-inner.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/384871-1.html (renamed from layout/xul/base/src/crashtests/384871-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/386642.xul | 31 | ||||
-rw-r--r-- | layout/xul/crashtests/387033-1.xhtml (renamed from layout/xul/base/src/crashtests/387033-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/387080-1.xul (renamed from layout/xul/base/src/crashtests/387080-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/391974-1-inner.xul (renamed from layout/xul/base/src/crashtests/391974-1-inner.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/391974-1.html (renamed from layout/xul/base/src/crashtests/391974-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/394120-1.xhtml (renamed from layout/xul/base/src/crashtests/394120-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/397293.xhtml (renamed from layout/xul/base/src/crashtests/397293.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/397304-1.html (renamed from layout/xul/base/src/crashtests/397304-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/398326-1.xhtml (renamed from layout/xul/base/src/crashtests/398326-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/399013.xul (renamed from layout/xul/base/src/crashtests/399013.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/400779-1.xhtml (renamed from layout/xul/base/src/crashtests/400779-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/402912-1.xhtml (renamed from layout/xul/base/src/crashtests/402912-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/404192.xhtml | 12 | ||||
-rw-r--r-- | layout/xul/crashtests/407152.xul | 7 | ||||
-rw-r--r-- | layout/xul/crashtests/408904-1.xul (renamed from layout/xul/base/src/crashtests/408904-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/412479-1.xhtml (renamed from layout/xul/base/src/crashtests/412479-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/415394-1.xhtml (renamed from layout/xul/base/src/crashtests/415394-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/417509.xul | 7 | ||||
-rw-r--r-- | layout/xul/crashtests/420424-1.xul (renamed from layout/xul/base/src/crashtests/420424-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/430356-1.xhtml (renamed from layout/xul/base/src/crashtests/430356-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/431738.xhtml (renamed from layout/xul/base/src/crashtests/431738.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/432058-1.xul (renamed from layout/xul/base/src/crashtests/432058-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/432068-1.xul (renamed from layout/xul/base/src/crashtests/432068-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/432068-2.xul (renamed from layout/xul/base/src/crashtests/432068-2.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/433296-1.xul (renamed from layout/xul/base/src/crashtests/433296-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/433429.xul (renamed from layout/xul/base/src/crashtests/433429.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/434458-1.xul (renamed from layout/xul/base/src/crashtests/434458-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/452185.html (renamed from layout/xul/base/src/crashtests/452185.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/452185.xml (renamed from layout/xul/base/src/crashtests/452185.xml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/460900-1.xul (renamed from layout/xul/base/src/crashtests/460900-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/464149-1.xul (renamed from layout/xul/base/src/crashtests/464149-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/464407-1.xhtml (renamed from layout/xul/base/src/crashtests/464407-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/467080.xul (renamed from layout/xul/base/src/crashtests/467080.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/467481-1.xul (renamed from layout/xul/base/src/crashtests/467481-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/470063-1.html (renamed from layout/xul/base/src/crashtests/470063-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/470272.html (renamed from layout/xul/base/src/crashtests/470272.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/472189.xul (renamed from layout/xul/base/src/crashtests/472189.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/475133.html (renamed from layout/xul/base/src/crashtests/475133.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/488210-1.xhtml (renamed from layout/xul/base/src/crashtests/488210-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/495728-1.xul (renamed from layout/xul/base/src/crashtests/495728-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/508927-1.xul (renamed from layout/xul/base/src/crashtests/508927-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/508927-2.xul (renamed from layout/xul/base/src/crashtests/508927-2.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/514300-1.xul (renamed from layout/xul/base/src/crashtests/514300-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/536931-1.xhtml (renamed from layout/xul/base/src/crashtests/536931-1.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/538308-1.xul (renamed from layout/xul/base/src/crashtests/538308-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/557174-1.xml (renamed from layout/xul/base/src/crashtests/557174-1.xml) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/564705-1.xul (renamed from layout/xul/base/src/crashtests/564705-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/583957-1.html (renamed from layout/xul/base/src/crashtests/583957-1.html) | 0 | ||||
-rw-r--r-- | layout/xul/crashtests/crashtests.list (renamed from layout/xul/base/src/crashtests/crashtests.list) | 7 | ||||
-rw-r--r-- | layout/xul/crashtests/menulist-focused.xhtml (renamed from layout/xul/base/src/crashtests/menulist-focused.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/grid/Makefile.in | 29 | ||||
-rw-r--r-- | layout/xul/grid/moz.build | 14 | ||||
-rw-r--r-- | layout/xul/grid/nsGrid.cpp | 16 | ||||
-rw-r--r-- | layout/xul/grid/nsGridCell.h | 6 | ||||
-rw-r--r-- | layout/xul/grid/nsGridLayout2.cpp | 8 | ||||
-rw-r--r-- | layout/xul/grid/nsGridLayout2.h | 45 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowGroupFrame.cpp | 10 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowGroupFrame.h | 11 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowGroupLayout.cpp | 19 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowGroupLayout.h | 22 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLayout.cpp | 14 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLayout.h | 21 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLeafFrame.cpp | 9 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLeafFrame.h | 11 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLeafLayout.cpp | 10 | ||||
-rw-r--r-- | layout/xul/grid/nsGridRowLeafLayout.h | 24 | ||||
-rw-r--r-- | layout/xul/grid/reftests/reftest.list | 34 | ||||
-rw-r--r-- | layout/xul/moz.build (renamed from layout/xul/base/src/moz.build) | 91 | ||||
-rw-r--r-- | layout/xul/nsBox.cpp (renamed from layout/xul/base/src/nsBox.cpp) | 70 | ||||
-rw-r--r-- | layout/xul/nsBox.h (renamed from layout/xul/base/src/nsBox.h) | 52 | ||||
-rw-r--r-- | layout/xul/nsBoxFrame.cpp (renamed from layout/xul/base/src/nsBoxFrame.cpp) | 348 | ||||
-rw-r--r-- | layout/xul/nsBoxFrame.h (renamed from layout/xul/base/src/nsBoxFrame.h) | 145 | ||||
-rw-r--r-- | layout/xul/nsBoxLayout.cpp (renamed from layout/xul/base/src/nsBoxLayout.cpp) | 2 | ||||
-rw-r--r-- | layout/xul/nsBoxLayout.h (renamed from layout/xul/base/src/nsBoxLayout.h) | 6 | ||||
-rw-r--r-- | layout/xul/nsBoxLayoutState.cpp (renamed from layout/xul/base/src/nsBoxLayoutState.cpp) | 0 | ||||
-rw-r--r-- | layout/xul/nsBoxLayoutState.h (renamed from layout/xul/base/src/nsBoxLayoutState.h) | 16 | ||||
-rw-r--r-- | layout/xul/nsButtonBoxFrame.cpp (renamed from layout/xul/base/src/nsButtonBoxFrame.cpp) | 108 | ||||
-rw-r--r-- | layout/xul/nsButtonBoxFrame.h (renamed from layout/xul/base/src/nsButtonBoxFrame.h) | 23 | ||||
-rw-r--r-- | layout/xul/nsDeckFrame.cpp (renamed from layout/xul/base/src/nsDeckFrame.cpp) | 51 | ||||
-rw-r--r-- | layout/xul/nsDeckFrame.h (renamed from layout/xul/base/src/nsDeckFrame.h) | 29 | ||||
-rw-r--r-- | layout/xul/nsDocElementBoxFrame.cpp (renamed from layout/xul/base/src/nsDocElementBoxFrame.cpp) | 51 | ||||
-rw-r--r-- | layout/xul/nsGroupBoxFrame.cpp (renamed from layout/xul/base/src/nsGroupBoxFrame.cpp) | 75 | ||||
-rw-r--r-- | layout/xul/nsIBoxObject.idl (renamed from layout/xul/base/public/nsIBoxObject.idl) | 0 | ||||
-rw-r--r-- | layout/xul/nsIBrowserBoxObject.idl (renamed from layout/xul/base/public/nsIBrowserBoxObject.idl) | 4 | ||||
-rw-r--r-- | layout/xul/nsIContainerBoxObject.idl (renamed from layout/xul/base/public/nsIContainerBoxObject.idl) | 12 | ||||
-rw-r--r-- | layout/xul/nsIListBoxObject.idl (renamed from layout/xul/base/public/nsIListBoxObject.idl) | 18 | ||||
-rw-r--r-- | layout/xul/nsIMenuBoxObject.idl (renamed from layout/xul/base/public/nsIIFrameBoxObject.idl) | 12 | ||||
-rw-r--r-- | layout/xul/nsIRootBox.h (renamed from layout/xul/base/src/nsIRootBox.h) | 0 | ||||
-rw-r--r-- | layout/xul/nsIScrollBoxObject.idl (renamed from layout/xul/base/public/nsIEditorBoxObject.idl) | 10 | ||||
-rw-r--r-- | layout/xul/nsIScrollbarMediator.h | 68 | ||||
-rw-r--r-- | layout/xul/nsISliderListener.idl (renamed from layout/xul/base/public/nsISliderListener.idl) | 0 | ||||
-rw-r--r-- | layout/xul/nsImageBoxFrame.cpp (renamed from layout/xul/base/src/nsImageBoxFrame.cpp) | 170 | ||||
-rw-r--r-- | layout/xul/nsImageBoxFrame.h (renamed from layout/xul/base/src/nsImageBoxFrame.h) | 71 | ||||
-rw-r--r-- | layout/xul/nsLeafBoxFrame.cpp (renamed from layout/xul/base/src/nsLeafBoxFrame.cpp) | 80 | ||||
-rw-r--r-- | layout/xul/nsLeafBoxFrame.h | 97 | ||||
-rw-r--r-- | layout/xul/nsListBoxBodyFrame.cpp (renamed from layout/xul/base/src/nsListBoxBodyFrame.cpp) | 294 | ||||
-rw-r--r-- | layout/xul/nsListBoxBodyFrame.h (renamed from layout/xul/base/src/nsListBoxBodyFrame.h) | 64 | ||||
-rw-r--r-- | layout/xul/nsListBoxLayout.cpp (renamed from layout/xul/base/src/nsListBoxLayout.cpp) | 10 | ||||
-rw-r--r-- | layout/xul/nsListBoxLayout.h (renamed from layout/xul/base/src/nsListBoxLayout.h) | 8 | ||||
-rw-r--r-- | layout/xul/nsListItemFrame.cpp (renamed from layout/xul/base/src/nsListItemFrame.cpp) | 13 | ||||
-rw-r--r-- | layout/xul/nsListItemFrame.h (renamed from layout/xul/base/src/nsListItemFrame.h) | 11 | ||||
-rw-r--r-- | layout/xul/nsMenuBarFrame.cpp (renamed from layout/xul/base/src/nsMenuBarFrame.cpp) | 74 | ||||
-rw-r--r-- | layout/xul/nsMenuBarFrame.h (renamed from layout/xul/base/src/nsMenuBarFrame.h) | 46 | ||||
-rw-r--r-- | layout/xul/nsMenuBarListener.cpp (renamed from layout/xul/base/src/nsMenuBarListener.cpp) | 72 | ||||
-rw-r--r-- | layout/xul/nsMenuBarListener.h (renamed from layout/xul/base/src/nsMenuBarListener.h) | 20 | ||||
-rw-r--r-- | layout/xul/nsMenuFrame.cpp (renamed from layout/xul/base/src/nsMenuFrame.cpp) | 336 | ||||
-rw-r--r-- | layout/xul/nsMenuFrame.h (renamed from layout/xul/base/src/nsMenuFrame.h) | 122 | ||||
-rw-r--r-- | layout/xul/nsMenuParent.h (renamed from layout/xul/base/src/nsMenuParent.h) | 0 | ||||
-rw-r--r-- | layout/xul/nsMenuPopupFrame.cpp (renamed from layout/xul/base/src/nsMenuPopupFrame.cpp) | 515 | ||||
-rw-r--r-- | layout/xul/nsMenuPopupFrame.h (renamed from layout/xul/base/src/nsMenuPopupFrame.h) | 173 | ||||
-rw-r--r-- | layout/xul/nsPIBoxObject.h (renamed from layout/xul/base/public/nsPIBoxObject.h) | 2 | ||||
-rw-r--r-- | layout/xul/nsPIListBoxObject.h (renamed from layout/xul/base/src/nsPIListBoxObject.h) | 0 | ||||
-rw-r--r-- | layout/xul/nsPopupSetFrame.cpp (renamed from layout/xul/base/src/nsPopupSetFrame.cpp) | 115 | ||||
-rw-r--r-- | layout/xul/nsPopupSetFrame.h | 64 | ||||
-rw-r--r-- | layout/xul/nsProgressMeterFrame.cpp (renamed from layout/xul/base/src/nsProgressMeterFrame.cpp) | 52 | ||||
-rw-r--r-- | layout/xul/nsProgressMeterFrame.h (renamed from layout/xul/base/src/nsProgressMeterFrame.h) | 16 | ||||
-rw-r--r-- | layout/xul/nsRepeatService.cpp (renamed from layout/xul/base/src/nsRepeatService.cpp) | 2 | ||||
-rw-r--r-- | layout/xul/nsRepeatService.h (renamed from layout/xul/base/src/nsRepeatService.h) | 4 | ||||
-rw-r--r-- | layout/xul/nsResizerFrame.cpp (renamed from layout/xul/base/src/nsResizerFrame.cpp) | 118 | ||||
-rw-r--r-- | layout/xul/nsResizerFrame.h (renamed from layout/xul/base/src/nsResizerFrame.h) | 16 | ||||
-rw-r--r-- | layout/xul/nsRootBoxFrame.cpp (renamed from layout/xul/base/src/nsRootBoxFrame.cpp) | 135 | ||||
-rw-r--r-- | layout/xul/nsScrollBoxFrame.cpp (renamed from layout/xul/base/src/nsScrollBoxFrame.cpp) | 63 | ||||
-rw-r--r-- | layout/xul/nsScrollbarButtonFrame.cpp (renamed from layout/xul/base/src/nsScrollbarButtonFrame.cpp) | 172 | ||||
-rw-r--r-- | layout/xul/nsScrollbarButtonFrame.h (renamed from layout/xul/base/src/nsScrollbarButtonFrame.h) | 41 | ||||
-rw-r--r-- | layout/xul/nsScrollbarFrame.cpp | 298 | ||||
-rw-r--r-- | layout/xul/nsScrollbarFrame.h | 110 | ||||
-rw-r--r-- | layout/xul/nsSliderFrame.cpp (renamed from layout/xul/base/src/nsSliderFrame.cpp) | 275 | ||||
-rw-r--r-- | layout/xul/nsSliderFrame.h (renamed from layout/xul/base/src/nsSliderFrame.h) | 108 | ||||
-rw-r--r-- | layout/xul/nsSplitterFrame.cpp (renamed from layout/xul/base/src/nsSplitterFrame.cpp) | 97 | ||||
-rw-r--r-- | layout/xul/nsSplitterFrame.h | 83 | ||||
-rw-r--r-- | layout/xul/nsSprocketLayout.cpp (renamed from layout/xul/base/src/nsSprocketLayout.cpp) | 54 | ||||
-rw-r--r-- | layout/xul/nsSprocketLayout.h (renamed from layout/xul/base/src/nsSprocketLayout.h) | 10 | ||||
-rw-r--r-- | layout/xul/nsStackFrame.cpp (renamed from layout/xul/base/src/nsStackFrame.cpp) | 8 | ||||
-rw-r--r-- | layout/xul/nsStackFrame.h (renamed from layout/xul/base/src/nsStackFrame.h) | 8 | ||||
-rw-r--r-- | layout/xul/nsStackLayout.cpp (renamed from layout/xul/base/src/nsStackLayout.cpp) | 22 | ||||
-rw-r--r-- | layout/xul/nsStackLayout.h (renamed from layout/xul/base/src/nsStackLayout.h) | 10 | ||||
-rw-r--r-- | layout/xul/nsTextBoxFrame.cpp (renamed from layout/xul/base/src/nsTextBoxFrame.cpp) | 265 | ||||
-rw-r--r-- | layout/xul/nsTextBoxFrame.h (renamed from layout/xul/base/src/nsTextBoxFrame.h) | 44 | ||||
-rw-r--r-- | layout/xul/nsTitleBarFrame.cpp (renamed from layout/xul/base/src/nsTitleBarFrame.cpp) | 58 | ||||
-rw-r--r-- | layout/xul/nsTitleBarFrame.h (renamed from layout/xul/base/src/nsTitleBarFrame.h) | 20 | ||||
-rw-r--r-- | layout/xul/nsXULLabelFrame.cpp (renamed from layout/xul/base/src/nsXULLabelFrame.cpp) | 23 | ||||
-rw-r--r-- | layout/xul/nsXULLabelFrame.h (renamed from layout/xul/base/src/nsXULLabelFrame.h) | 22 | ||||
-rw-r--r-- | layout/xul/nsXULPopupManager.cpp (renamed from layout/xul/base/src/nsXULPopupManager.cpp) | 555 | ||||
-rw-r--r-- | layout/xul/nsXULPopupManager.h (renamed from layout/xul/base/public/nsXULPopupManager.h) | 60 | ||||
-rw-r--r-- | layout/xul/nsXULTooltipListener.cpp (renamed from layout/xul/base/src/nsXULTooltipListener.cpp) | 34 | ||||
-rw-r--r-- | layout/xul/nsXULTooltipListener.h (renamed from layout/xul/base/src/nsXULTooltipListener.h) | 4 | ||||
-rw-r--r-- | layout/xul/reftest/image-scaling-min-height-1-ref.xul (renamed from layout/xul/base/reftest/image-scaling-min-height-1-ref.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/image-scaling-min-height-1.xul (renamed from layout/xul/base/reftest/image-scaling-min-height-1.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/image-size-ref.xul (renamed from layout/xul/base/reftest/image-size-ref.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/image-size.xul (renamed from layout/xul/base/reftest/image-size.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/image4x3.png (renamed from layout/xul/base/reftest/image4x3.png) | bin | 176 -> 176 bytes | |||
-rw-r--r-- | layout/xul/reftest/popup-explicit-size-ref.xul (renamed from layout/xul/base/reftest/popup-explicit-size-ref.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/popup-explicit-size.xul (renamed from layout/xul/base/reftest/popup-explicit-size.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/reftest.list | 6 | ||||
-rw-r--r-- | layout/xul/reftest/textbox-multiline-noresize.xul (renamed from layout/xul/base/reftest/textbox-multiline-noresize.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/textbox-multiline-ref.xul (renamed from layout/xul/base/reftest/textbox-multiline-ref.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/textbox-multiline-resize.xul (renamed from layout/xul/base/reftest/textbox-multiline-resize.xul) | 0 | ||||
-rw-r--r-- | layout/xul/reftest/textbox-text-transform-ref.xul | 6 | ||||
-rw-r--r-- | layout/xul/reftest/textbox-text-transform.xul | 6 | ||||
-rw-r--r-- | layout/xul/test/Makefile.in | 34 | ||||
-rw-r--r-- | layout/xul/test/browser.ini | 8 | ||||
-rw-r--r-- | layout/xul/test/chrome.ini | 24 | ||||
-rw-r--r-- | layout/xul/test/mochitest.ini | 10 | ||||
-rw-r--r-- | layout/xul/test/moz.build | 6 | ||||
-rw-r--r-- | layout/xul/test/test_bug381167.xhtml (renamed from layout/xul/base/test/test_bug381167.xhtml) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_bug386386.html | 1 | ||||
-rw-r--r-- | layout/xul/test/test_bug393970.xul (renamed from layout/xul/base/test/test_bug393970.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_bug467442.xul | 54 | ||||
-rw-r--r-- | layout/xul/test/test_bug477754.xul (renamed from layout/xul/base/test/test_bug477754.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_bug511075.html (renamed from layout/xul/base/test/test_bug511075.html) | 1 | ||||
-rw-r--r-- | layout/xul/test/test_bug563416.html | 2 | ||||
-rw-r--r-- | layout/xul/test/test_bug987230.xul | 115 | ||||
-rw-r--r-- | layout/xul/test/test_popupSizeTo.xul (renamed from layout/xul/base/test/test_popupSizeTo.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_popupZoom.xul | 57 | ||||
-rw-r--r-- | layout/xul/test/test_resizer.xul (renamed from layout/xul/base/test/test_resizer.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_resizer_incontent.xul (renamed from layout/xul/base/test/test_resizer_incontent.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_splitter.xul (renamed from layout/xul/base/test/test_splitter.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_stack.xul (renamed from layout/xul/base/test/test_stack.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/test_windowminmaxsize.xul (renamed from layout/xul/base/test/test_windowminmaxsize.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/window_resizer.xul (renamed from layout/xul/base/test/window_resizer.xul) | 0 | ||||
-rw-r--r-- | layout/xul/test/window_resizer_element.xul (renamed from layout/xul/base/test/window_resizer_element.xul) | 0 | ||||
-rw-r--r-- | layout/xul/tree/Makefile.in | 31 | ||||
-rw-r--r-- | layout/xul/tree/TreeBoxObject.cpp | 695 | ||||
-rw-r--r-- | layout/xul/tree/TreeBoxObject.h | 128 | ||||
-rw-r--r-- | layout/xul/tree/crashtests/585815-iframe.xul | 3 | ||||
-rw-r--r-- | layout/xul/tree/crashtests/730441-1.xul | 2 | ||||
-rw-r--r-- | layout/xul/tree/crashtests/730441-2.xul | 2 | ||||
-rw-r--r-- | layout/xul/tree/crashtests/730441-3.xul | 2 | ||||
-rw-r--r-- | layout/xul/tree/crashtests/crashtests.list | 2 | ||||
-rw-r--r-- | layout/xul/tree/moz.build | 22 | ||||
-rw-r--r-- | layout/xul/tree/nsITreeBoxObject.idl | 8 | ||||
-rw-r--r-- | layout/xul/tree/nsITreeContentView.idl | 3 | ||||
-rw-r--r-- | layout/xul/tree/nsITreeView.idl | 4 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeBodyFrame.cpp | 711 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeBodyFrame.h | 84 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeBoxObject.cpp | 497 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeBoxObject.h | 38 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeColFrame.cpp | 21 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeColFrame.h | 23 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeColumns.cpp | 78 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeColumns.h | 54 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeContentView.cpp | 42 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeContentView.h | 8 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeImageListener.cpp | 3 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeImageListener.h | 9 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeSelection.cpp | 31 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeSelection.h | 9 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeStyleCache.cpp | 77 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeStyleCache.h | 97 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeUtils.cpp | 19 |
294 files changed, 7587 insertions, 5781 deletions
diff --git a/layout/xul/base/src/nsBoxObject.cpp b/layout/xul/BoxObject.cpp index 86dc7ebbe..d2a941385 100644 --- a/layout/xul/base/src/nsBoxObject.cpp +++ b/layout/xul/BoxObject.cpp @@ -3,13 +3,13 @@ * 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/. */ -#include "nsBoxObject.h" +#include "mozilla/dom/BoxObject.h" #include "nsCOMPtr.h" #include "nsIDocument.h" #include "nsIPresShell.h" #include "nsPresContext.h" #include "nsIContent.h" -#include "nsIFrame.h" +#include "nsContainerFrame.h" #include "nsIDocShell.h" #include "nsReadableUtils.h" #include "nsDOMClassInfoID.h" @@ -23,32 +23,33 @@ #include "nsISupportsPrimitives.h" #include "nsSupportsPrimitives.h" #include "mozilla/dom/Element.h" - -using namespace mozilla::dom; +#include "nsComponentManagerUtils.h" +#include "mozilla/dom/BoxObjectBinding.h" // Implementation ///////////////////////////////////////////////////////////////// +namespace mozilla { +namespace dom { + // Static member variable initialization // Implement our nsISupports methods +NS_IMPL_CYCLE_COLLECTION_CLASS(BoxObject) +NS_IMPL_CYCLE_COLLECTING_ADDREF(BoxObject) +NS_IMPL_CYCLE_COLLECTING_RELEASE(BoxObject) -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsBoxObject) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBoxObject) - -DOMCI_DATA(BoxObject, nsBoxObject) - -// QueryInterface implementation for nsBoxObject -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsBoxObject) +// QueryInterface implementation for BoxObject +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BoxObject) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsIBoxObject) NS_INTERFACE_MAP_ENTRY(nsPIBoxObject) NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BoxObject) NS_INTERFACE_MAP_END static PLDHashOperator PropertyTraverser(const nsAString& aKey, nsISupports* aProperty, void* userArg) { - nsCycleCollectionTraversalCallback *cb = + nsCycleCollectionTraversalCallback *cb = static_cast<nsCycleCollectionTraversalCallback*>(userArg); cb->NoteXPCOMChild(aProperty); @@ -56,25 +57,32 @@ PropertyTraverser(const nsAString& aKey, nsISupports* aProperty, void* userArg) return PL_DHASH_NEXT; } -NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsBoxObject) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBoxObject) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BoxObject) + // XXX jmorton: why aren't we unlinking mPropertyTable? + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BoxObject) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS if (tmp->mPropertyTable) { tmp->mPropertyTable->EnumerateRead(PropertyTraverser, &cb); } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BoxObject) + // Constructors/Destructors -nsBoxObject::nsBoxObject(void) - :mContent(nullptr) +BoxObject::BoxObject() + : mContent(nullptr) { } -nsBoxObject::~nsBoxObject(void) +BoxObject::~BoxObject() { } NS_IMETHODIMP -nsBoxObject::GetElement(nsIDOMElement** aResult) +BoxObject::GetElement(nsIDOMElement** aResult) { if (mContent) { return CallQueryInterface(mContent, aResult); @@ -87,26 +95,26 @@ nsBoxObject::GetElement(nsIDOMElement** aResult) // nsPIBoxObject ////////////////////////////////////////////////////////////////////////// nsresult -nsBoxObject::Init(nsIContent* aContent) +BoxObject::Init(nsIContent* aContent) { mContent = aContent; return NS_OK; } void -nsBoxObject::Clear() +BoxObject::Clear() { mPropertyTable = nullptr; mContent = nullptr; } void -nsBoxObject::ClearCachedValues() +BoxObject::ClearCachedValues() { } nsIFrame* -nsBoxObject::GetFrame(bool aFlushLayout) +BoxObject::GetFrame(bool aFlushLayout) { nsIPresShell* shell = GetPresShell(aFlushLayout); if (!shell) @@ -129,7 +137,7 @@ nsBoxObject::GetFrame(bool aFlushLayout) } nsIPresShell* -nsBoxObject::GetPresShell(bool aFlushLayout) +BoxObject::GetPresShell(bool aFlushLayout) { if (!mContent) { return nullptr; @@ -147,11 +155,11 @@ nsBoxObject::GetPresShell(bool aFlushLayout) return doc->GetShell(); } -nsresult -nsBoxObject::GetOffsetRect(nsIntRect& aRect) +nsresult +BoxObject::GetOffsetRect(nsIntRect& aRect) { aRect.SetRect(0, 0, 0, 0); - + if (!mContent) return NS_ERROR_NOT_INITIALIZED; @@ -162,7 +170,7 @@ nsBoxObject::GetOffsetRect(nsIntRect& aRect) nsPoint origin = frame->GetPositionIgnoringScrolling(); // Find the frame parent whose content is the document element. - Element *docElement = mContent->GetCurrentDoc()->GetRootElement(); + Element* docElement = mContent->GetComposedDoc()->GetRootElement(); nsIFrame* parent = frame->GetParent(); for (;;) { // If we've hit the document element, break here @@ -182,7 +190,7 @@ nsBoxObject::GetOffsetRect(nsIntRect& aRect) origin += next->GetPositionOfChildIgnoringScrolling(parent); parent = next; } - + // For the origin, add in the border for the frame const nsStyleBorder* border = frame->StyleBorder(); origin.x += border->GetComputedBorderWidth(NS_SIDE_LEFT); @@ -195,7 +203,7 @@ nsBoxObject::GetOffsetRect(nsIntRect& aRect) aRect.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x); aRect.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y); - + // Get the union of all rectangles in this and continuation frames. // It doesn't really matter what we use as aRelativeTo here, since // we only care about the size. Using 'parent' might make things @@ -209,10 +217,10 @@ nsBoxObject::GetOffsetRect(nsIntRect& aRect) } nsresult -nsBoxObject::GetScreenPosition(nsIntPoint& aPoint) +BoxObject::GetScreenPosition(nsIntPoint& aPoint) { aPoint.x = aPoint.y = 0; - + if (!mContent) return NS_ERROR_NOT_INITIALIZED; @@ -222,12 +230,12 @@ nsBoxObject::GetScreenPosition(nsIntPoint& aPoint) aPoint.x = rect.x; aPoint.y = rect.y; } - + return NS_OK; } NS_IMETHODIMP -nsBoxObject::GetX(int32_t* aResult) +BoxObject::GetX(int32_t* aResult) { nsIntRect rect; GetOffsetRect(rect); @@ -235,8 +243,8 @@ nsBoxObject::GetX(int32_t* aResult) return NS_OK; } -NS_IMETHODIMP -nsBoxObject::GetY(int32_t* aResult) +NS_IMETHODIMP +BoxObject::GetY(int32_t* aResult) { nsIntRect rect; GetOffsetRect(rect); @@ -245,7 +253,7 @@ nsBoxObject::GetY(int32_t* aResult) } NS_IMETHODIMP -nsBoxObject::GetWidth(int32_t* aResult) +BoxObject::GetWidth(int32_t* aResult) { nsIntRect rect; GetOffsetRect(rect); @@ -253,8 +261,8 @@ nsBoxObject::GetWidth(int32_t* aResult) return NS_OK; } -NS_IMETHODIMP -nsBoxObject::GetHeight(int32_t* aResult) +NS_IMETHODIMP +BoxObject::GetHeight(int32_t* aResult) { nsIntRect rect; GetOffsetRect(rect); @@ -263,31 +271,27 @@ nsBoxObject::GetHeight(int32_t* aResult) } NS_IMETHODIMP -nsBoxObject::GetScreenX(int32_t *_retval) +BoxObject::GetScreenX(int32_t *_retval) { nsIntPoint position; nsresult rv = GetScreenPosition(position); if (NS_FAILED(rv)) return rv; - *_retval = position.x; - return NS_OK; } NS_IMETHODIMP -nsBoxObject::GetScreenY(int32_t *_retval) +BoxObject::GetScreenY(int32_t *_retval) { nsIntPoint position; nsresult rv = GetScreenPosition(position); if (NS_FAILED(rv)) return rv; - *_retval = position.y; - return NS_OK; } NS_IMETHODIMP -nsBoxObject::GetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports** aResult) +BoxObject::GetPropertyAsSupports(const char16_t* aPropertyName, nsISupports** aResult) { NS_ENSURE_ARG(aPropertyName && *aPropertyName); if (!mPropertyTable) { @@ -300,14 +304,12 @@ nsBoxObject::GetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports** } NS_IMETHODIMP -nsBoxObject::SetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports* aValue) +BoxObject::SetPropertyAsSupports(const char16_t* aPropertyName, nsISupports* aValue) { NS_ENSURE_ARG(aPropertyName && *aPropertyName); - - if (!mPropertyTable) { - mPropertyTable = new nsInterfaceHashtable<nsStringHashKey,nsISupports>; - if (!mPropertyTable) return NS_ERROR_OUT_OF_MEMORY; - mPropertyTable->Init(8); + + if (!mPropertyTable) { + mPropertyTable = new nsInterfaceHashtable<nsStringHashKey,nsISupports>(4); } nsDependentString propertyName(aPropertyName); @@ -316,7 +318,7 @@ nsBoxObject::SetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports* } NS_IMETHODIMP -nsBoxObject::GetProperty(const PRUnichar* aPropertyName, PRUnichar** aResult) +BoxObject::GetProperty(const char16_t* aPropertyName, char16_t** aResult) { nsCOMPtr<nsISupports> data; nsresult rv = GetPropertyAsSupports(aPropertyName,getter_AddRefs(data)); @@ -328,14 +330,15 @@ nsBoxObject::GetProperty(const PRUnichar* aPropertyName, PRUnichar** aResult) } nsCOMPtr<nsISupportsString> supportsStr = do_QueryInterface(data); - if (!supportsStr) + if (!supportsStr) { return NS_ERROR_FAILURE; - + } + return supportsStr->ToString(aResult); } NS_IMETHODIMP -nsBoxObject::SetProperty(const PRUnichar* aPropertyName, const PRUnichar* aPropertyValue) +BoxObject::SetProperty(const char16_t* aPropertyName, const char16_t* aPropertyValue) { NS_ENSURE_ARG(aPropertyName && *aPropertyName); @@ -346,7 +349,7 @@ nsBoxObject::SetProperty(const PRUnichar* aPropertyName, const PRUnichar* aPrope } else { propertyValue.SetIsVoid(true); } - + nsCOMPtr<nsISupportsString> supportsStr(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); NS_ENSURE_TRUE(supportsStr, NS_ERROR_OUT_OF_MEMORY); supportsStr->SetData(propertyValue); @@ -355,7 +358,7 @@ nsBoxObject::SetProperty(const PRUnichar* aPropertyName, const PRUnichar* aPrope } NS_IMETHODIMP -nsBoxObject::RemoveProperty(const PRUnichar* aPropertyName) +BoxObject::RemoveProperty(const char16_t* aPropertyName) { NS_ENSURE_ARG(aPropertyName && *aPropertyName); @@ -366,8 +369,8 @@ nsBoxObject::RemoveProperty(const PRUnichar* aPropertyName) return NS_OK; } -NS_IMETHODIMP -nsBoxObject::GetParentBox(nsIDOMElement * *aParentBox) +NS_IMETHODIMP +BoxObject::GetParentBox(nsIDOMElement * *aParentBox) { *aParentBox = nullptr; nsIFrame* frame = GetFrame(false); @@ -381,8 +384,8 @@ nsBoxObject::GetParentBox(nsIDOMElement * *aParentBox) return NS_OK; } -NS_IMETHODIMP -nsBoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild) +NS_IMETHODIMP +BoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild) { *aFirstVisibleChild = nullptr; nsIFrame* frame = GetFrame(false); @@ -396,7 +399,7 @@ nsBoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild) } NS_IMETHODIMP -nsBoxObject::GetLastChild(nsIDOMElement * *aLastVisibleChild) +BoxObject::GetLastChild(nsIDOMElement * *aLastVisibleChild) { *aLastVisibleChild = nullptr; nsIFrame* frame = GetFrame(false); @@ -405,7 +408,7 @@ nsBoxObject::GetLastChild(nsIDOMElement * *aLastVisibleChild) } NS_IMETHODIMP -nsBoxObject::GetNextSibling(nsIDOMElement **aNextOrdinalSibling) +BoxObject::GetNextSibling(nsIDOMElement **aNextOrdinalSibling) { *aNextOrdinalSibling = nullptr; nsIFrame* frame = GetFrame(false); @@ -419,7 +422,7 @@ nsBoxObject::GetNextSibling(nsIDOMElement **aNextOrdinalSibling) } NS_IMETHODIMP -nsBoxObject::GetPreviousSibling(nsIDOMElement **aPreviousOrdinalSibling) +BoxObject::GetPreviousSibling(nsIDOMElement **aPreviousOrdinalSibling) { *aPreviousOrdinalSibling = nullptr; nsIFrame* frame = GetFrame(false); @@ -430,8 +433,8 @@ nsBoxObject::GetPreviousSibling(nsIDOMElement **aPreviousOrdinalSibling) } nsresult -nsBoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, - nsIDOMElement** aResult) +BoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, + nsIDOMElement** aResult) { *aResult = nullptr; nsIFrame* nextFrame = aParentFrame->GetFirstPrincipalChild(); @@ -442,7 +445,7 @@ nsBoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, prevFrame = nextFrame; nextFrame = nextFrame->GetNextSibling(); } - + if (!prevFrame) return NS_OK; // get the content for the box and query to a dom element nsCOMPtr<nsIDOMElement> el = do_QueryInterface(prevFrame->GetContent()); @@ -450,15 +453,170 @@ nsBoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, return NS_OK; } +nsIContent* +BoxObject::GetParentObject() const +{ + return mContent; +} + +JSObject* +BoxObject::WrapObject(JSContext* aCx) +{ + return BoxObjectBinding::Wrap(aCx, this); +} + +Element* +BoxObject::GetElement() const +{ + return mContent && mContent->IsElement() ? mContent->AsElement() : nullptr; +} + +int32_t +BoxObject::X() +{ + int32_t ret = 0; + GetX(&ret); + return ret; +} + +int32_t +BoxObject::Y() +{ + int32_t ret = 0; + GetY(&ret); + return ret; +} + +int32_t +BoxObject::GetScreenX(ErrorResult& aRv) +{ + int32_t ret = 0; + aRv = GetScreenX(&ret); + return ret; +} + +int32_t +BoxObject::GetScreenY(ErrorResult& aRv) +{ + int32_t ret = 0; + aRv = GetScreenY(&ret); + return ret; +} + +int32_t +BoxObject::Width() +{ + int32_t ret = 0; + GetWidth(&ret); + return ret; +} + +int32_t +BoxObject::Height() +{ + int32_t ret = 0; + GetHeight(&ret); + return ret; +} + +already_AddRefed<nsISupports> +BoxObject::GetPropertyAsSupports(const nsAString& propertyName) +{ + nsCOMPtr<nsISupports> ret; + GetPropertyAsSupports(PromiseFlatString(propertyName).get(), getter_AddRefs(ret)); + return ret.forget(); +} + +void +BoxObject::SetPropertyAsSupports(const nsAString& propertyName, nsISupports* value) +{ + SetPropertyAsSupports(PromiseFlatString(propertyName).get(), value); +} + +void +BoxObject::GetProperty(const nsAString& propertyName, nsString& aRetVal, ErrorResult& aRv) +{ + nsCOMPtr<nsISupports> data(GetPropertyAsSupports(propertyName)); + if (!data) { + return; + } + + nsCOMPtr<nsISupportsString> supportsStr(do_QueryInterface(data)); + if (!supportsStr) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + supportsStr->GetData(aRetVal); +} + +void +BoxObject::SetProperty(const nsAString& propertyName, const nsAString& propertyValue) +{ + SetProperty(PromiseFlatString(propertyName).get(), PromiseFlatString(propertyValue).get()); +} + +void +BoxObject::RemoveProperty(const nsAString& propertyName) +{ + RemoveProperty(PromiseFlatString(propertyName).get()); +} + +already_AddRefed<Element> +BoxObject::GetParentBox() +{ + nsCOMPtr<nsIDOMElement> el; + GetParentBox(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +already_AddRefed<Element> +BoxObject::GetFirstChild() +{ + nsCOMPtr<nsIDOMElement> el; + GetFirstChild(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +already_AddRefed<Element> +BoxObject::GetLastChild() +{ + nsCOMPtr<nsIDOMElement> el; + GetLastChild(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +already_AddRefed<Element> +BoxObject::GetNextSibling() +{ + nsCOMPtr<nsIDOMElement> el; + GetNextSibling(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +already_AddRefed<Element> +BoxObject::GetPreviousSibling() +{ + nsCOMPtr<nsIDOMElement> el; + GetPreviousSibling(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +} // namespace dom +} // namespace mozilla + // Creation Routine /////////////////////////////////////////////////////////////////////// +using namespace mozilla::dom; + nsresult NS_NewBoxObject(nsIBoxObject** aResult) { - *aResult = new nsBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); + NS_ADDREF(*aResult = new BoxObject()); return NS_OK; } - diff --git a/layout/xul/BoxObject.h b/layout/xul/BoxObject.h new file mode 100644 index 000000000..2516db12f --- /dev/null +++ b/layout/xul/BoxObject.h @@ -0,0 +1,92 @@ +/* -*- 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 mozilla_dom_BoxObject_h__ +#define mozilla_dom_BoxObject_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" +#include "nsCOMPtr.h" +#include "nsIBoxObject.h" +#include "nsPIBoxObject.h" +#include "nsPoint.h" +#include "nsAutoPtr.h" +#include "nsHashKeys.h" +#include "nsInterfaceHashtable.h" +#include "nsCycleCollectionParticipant.h" +#include "nsWrapperCache.h" + +class nsIFrame; +class nsIDocShell; +struct nsIntRect; +class nsIPresShell; + +namespace mozilla { +namespace dom { + +class Element; + +class BoxObject : public nsPIBoxObject, + public nsWrapperCache +{ + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BoxObject) + NS_DECL_NSIBOXOBJECT + +public: + BoxObject(); + + // nsPIBoxObject + virtual nsresult Init(nsIContent* aContent) override; + virtual void Clear() override; + virtual void ClearCachedValues() override; + + nsIFrame* GetFrame(bool aFlushLayout); + nsIPresShell* GetPresShell(bool aFlushLayout); + nsresult GetOffsetRect(nsIntRect& aRect); + nsresult GetScreenPosition(nsIntPoint& aPoint); + + // Given a parent frame and a child frame, find the frame whose + // next sibling is the given child frame and return its element + static nsresult GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, + nsIDOMElement** aResult); + + // WebIDL (wraps old impls) + nsIContent* GetParentObject() const; + virtual JSObject* WrapObject(JSContext* aCx) override; + + Element* GetElement() const; + + int32_t X(); + int32_t Y(); + int32_t GetScreenX(ErrorResult& aRv); + int32_t GetScreenY(ErrorResult& aRv); + int32_t Width(); + int32_t Height(); + + already_AddRefed<nsISupports> GetPropertyAsSupports(const nsAString& propertyName); + void SetPropertyAsSupports(const nsAString& propertyName, nsISupports* value); + void GetProperty(const nsAString& propertyName, nsString& aRetVal, ErrorResult& aRv); + void SetProperty(const nsAString& propertyName, const nsAString& propertyValue); + void RemoveProperty(const nsAString& propertyName); + + already_AddRefed<Element> GetParentBox(); + already_AddRefed<Element> GetFirstChild(); + already_AddRefed<Element> GetLastChild(); + already_AddRefed<Element> GetNextSibling(); + already_AddRefed<Element> GetPreviousSibling(); + +protected: + virtual ~BoxObject(); + + nsAutoPtr<nsInterfaceHashtable<nsStringHashKey,nsISupports> > mPropertyTable; //[OWNER] + + nsIContent* mContent; // [WEAK] +}; + +} +} + +#endif diff --git a/layout/xul/ContainerBoxObject.cpp b/layout/xul/ContainerBoxObject.cpp new file mode 100644 index 000000000..1093f0361 --- /dev/null +++ b/layout/xul/ContainerBoxObject.cpp @@ -0,0 +1,75 @@ +/* -*- 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/. */ + +#include "mozilla/dom/ContainerBoxObject.h" +#include "mozilla/dom/ContainerBoxObjectBinding.h" +#include "nsCOMPtr.h" +#include "nsIDocShell.h" +#include "nsIContent.h" +#include "nsIDocument.h" +#include "nsIFrame.h" +#include "nsSubDocumentFrame.h" + +namespace mozilla { +namespace dom { + +ContainerBoxObject::ContainerBoxObject() +{ +} + +ContainerBoxObject::~ContainerBoxObject() +{ +} + +JSObject* +ContainerBoxObject::WrapObject(JSContext* aCx) +{ + return ContainerBoxObjectBinding::Wrap(aCx, this); +} + +already_AddRefed<nsIDocShell> +ContainerBoxObject::GetDocShell() +{ + nsSubDocumentFrame *subDocFrame = do_QueryFrame(GetFrame(false)); + if (subDocFrame) { + // Ok, the frame for mContent is an nsSubDocumentFrame, it knows how + // to reach the docshell, so ask it... + nsCOMPtr<nsIDocShell> ret; + subDocFrame->GetDocShell(getter_AddRefs(ret)); + return ret.forget(); + } + + if (!mContent) { + return nullptr; + } + + // No nsSubDocumentFrame available for mContent, try if there's a mapping + // between mContent's document to mContent's subdocument. + + nsIDocument *doc = mContent->GetComposedDoc(); + + if (!doc) { + return nullptr; + } + + nsIDocument *sub_doc = doc->GetSubDocumentFor(mContent); + + if (!sub_doc) { + return nullptr; + } + + nsCOMPtr<nsIDocShell> result = sub_doc->GetDocShell(); + return result.forget(); +} + +} // namespace dom +} // namespace mozilla + +nsresult +NS_NewContainerBoxObject(nsIBoxObject** aResult) +{ + NS_ADDREF(*aResult = new mozilla::dom::ContainerBoxObject()); + return NS_OK; +} diff --git a/layout/xul/ContainerBoxObject.h b/layout/xul/ContainerBoxObject.h new file mode 100644 index 000000000..b843e52c6 --- /dev/null +++ b/layout/xul/ContainerBoxObject.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_ContainerBoxObject_h +#define mozilla_dom_ContainerBoxObject_h + +#include "mozilla/dom/BoxObject.h" + +namespace mozilla { +namespace dom { + +class ContainerBoxObject final : public BoxObject +{ +public: + ContainerBoxObject(); + + virtual JSObject* WrapObject(JSContext* aCx) override; + + already_AddRefed<nsIDocShell> GetDocShell(); + +private: + ~ContainerBoxObject(); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ContainerBoxObject_h diff --git a/layout/xul/ListBoxObject.cpp b/layout/xul/ListBoxObject.cpp new file mode 100644 index 000000000..67be900aa --- /dev/null +++ b/layout/xul/ListBoxObject.cpp @@ -0,0 +1,238 @@ +/* -*- 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/. */ + +#include "mozilla/dom/ListBoxObject.h" +#include "nsCOMPtr.h" +#include "nsIFrame.h" +#include "nsGkAtoms.h" +#include "nsIScrollableFrame.h" +#include "nsListBoxBodyFrame.h" +#include "ChildIterator.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/ListBoxObjectBinding.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_ISUPPORTS_INHERITED(ListBoxObject, BoxObject, nsIListBoxObject, + nsPIListBoxObject) + +ListBoxObject::ListBoxObject() + : mListBoxBody(nullptr) +{ +} + +ListBoxObject::~ListBoxObject() +{ +} + +JSObject* ListBoxObject::WrapObject(JSContext* aCx) +{ + return ListBoxObjectBinding::Wrap(aCx, this); +} + +// nsIListBoxObject +NS_IMETHODIMP +ListBoxObject::GetRowCount(int32_t *aResult) +{ + *aResult = GetRowCount(); + return NS_OK; +} + +NS_IMETHODIMP +ListBoxObject::GetItemAtIndex(int32_t index, nsIDOMElement **_retval) +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + return body->GetItemAtIndex(index, _retval); + } + return NS_OK; + } + +NS_IMETHODIMP +ListBoxObject::GetIndexOfItem(nsIDOMElement* aElement, int32_t *aResult) +{ + *aResult = 0; + + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + return body->GetIndexOfItem(aElement, aResult); + } + return NS_OK; +} + +// ListBoxObject + +int32_t +ListBoxObject::GetRowCount() +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + return body->GetRowCount(); + } + return 0; +} + +int32_t +ListBoxObject::GetNumberOfVisibleRows() +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + return body->GetNumberOfVisibleRows(); + } + return 0; +} + +int32_t +ListBoxObject::GetIndexOfFirstVisibleRow() +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + return body->GetIndexOfFirstVisibleRow(); + } + return 0; +} + +void +ListBoxObject::EnsureIndexIsVisible(int32_t aRowIndex) +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + body->EnsureIndexIsVisible(aRowIndex); + } +} + +void +ListBoxObject::ScrollToIndex(int32_t aRowIndex) +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + body->ScrollToIndex(aRowIndex); + } +} + +void +ListBoxObject::ScrollByLines(int32_t aNumLines) +{ + nsListBoxBodyFrame* body = GetListBoxBody(true); + if (body) { + body->ScrollByLines(aNumLines); + } +} + +already_AddRefed<Element> +ListBoxObject::GetItemAtIndex(int32_t index) +{ + nsCOMPtr<nsIDOMElement> el; + GetItemAtIndex(index, getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +int32_t +ListBoxObject::GetIndexOfItem(Element& aElement) +{ + int32_t ret; + nsCOMPtr<nsIDOMElement> el(do_QueryInterface(&aElement)); + GetIndexOfItem(el, &ret); + return ret; +} + +////////////////////// + +static nsIContent* +FindBodyContent(nsIContent* aParent) +{ + if (aParent->Tag() == nsGkAtoms::listboxbody) { + return aParent; + } + + mozilla::dom::FlattenedChildIterator iter(aParent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { + nsIContent* result = FindBodyContent(child); + if (result) { + return result; + } + } + + return nullptr; +} + +nsListBoxBodyFrame* +ListBoxObject::GetListBoxBody(bool aFlush) +{ + if (mListBoxBody) { + return mListBoxBody; + } + + nsIPresShell* shell = GetPresShell(false); + if (!shell) { + return nullptr; + } + + nsIFrame* frame = aFlush ? + GetFrame(false) /* does Flush_Frames */ : + mContent->GetPrimaryFrame(); + if (!frame) { + return nullptr; + } + + // Iterate over our content model children looking for the body. + nsCOMPtr<nsIContent> content = FindBodyContent(frame->GetContent()); + + if (!content) { + return nullptr; + } + + // this frame will be a nsGFXScrollFrame + frame = content->GetPrimaryFrame(); + if (!frame) { + return nullptr; + } + + nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); + if (!scrollFrame) { + return nullptr; + } + + // this frame will be the one we want + nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame(); + if (!yeahBaby) { + return nullptr; + } + + // It's a frame. Refcounts are irrelevant. + nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby); + NS_ENSURE_TRUE(listBoxBody && + listBoxBody->SetBoxObject(this), + nullptr); + mListBoxBody = listBoxBody; + return mListBoxBody; +} + +void +ListBoxObject::Clear() +{ + ClearCachedValues(); + BoxObject::Clear(); +} + +void +ListBoxObject::ClearCachedValues() +{ + mListBoxBody = nullptr; +} + +} +} + +// Creation Routine /////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewListBoxObject(nsIBoxObject** aResult) +{ + NS_ADDREF(*aResult = new mozilla::dom::ListBoxObject()); + return NS_OK; +} diff --git a/layout/xul/ListBoxObject.h b/layout/xul/ListBoxObject.h new file mode 100644 index 000000000..f0aacc3a9 --- /dev/null +++ b/layout/xul/ListBoxObject.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_ListBoxObject_h +#define mozilla_dom_ListBoxObject_h + +#include "mozilla/dom/BoxObject.h" +#include "nsPIListBoxObject.h" + +namespace mozilla { +namespace dom { + +class ListBoxObject final : public BoxObject, + public nsPIListBoxObject +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSILISTBOXOBJECT + + ListBoxObject(); + + virtual JSObject* WrapObject(JSContext* aCx) override; + + // nsPIListBoxObject + virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush) override; + + // nsPIBoxObject + virtual void Clear() override; + virtual void ClearCachedValues() override; + + // ListBoxObject.webidl + int32_t GetRowCount(); + int32_t GetNumberOfVisibleRows(); + int32_t GetIndexOfFirstVisibleRow(); + void EnsureIndexIsVisible(int32_t rowIndex); + void ScrollToIndex(int32_t rowIndex); + void ScrollByLines(int32_t numLines); + already_AddRefed<Element> GetItemAtIndex(int32_t index); + int32_t GetIndexOfItem(Element& item); + +protected: + nsListBoxBodyFrame *mListBoxBody; + +private: + ~ListBoxObject(); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ListBoxObject_h diff --git a/layout/xul/MenuBoxObject.cpp b/layout/xul/MenuBoxObject.cpp new file mode 100644 index 000000000..85a15312e --- /dev/null +++ b/layout/xul/MenuBoxObject.cpp @@ -0,0 +1,151 @@ +/* -*- 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/. */ + +#include "mozilla/dom/MenuBoxObject.h" +#include "mozilla/dom/MenuBoxObjectBinding.h" + +#include "mozilla/dom/KeyboardEvent.h" +#include "mozilla/dom/Element.h" +#include "nsIDOMKeyEvent.h" +#include "nsIFrame.h" +#include "nsMenuBarFrame.h" +#include "nsMenuBarListener.h" +#include "nsMenuFrame.h" +#include "nsMenuPopupFrame.h" + +namespace mozilla { +namespace dom { + +MenuBoxObject::MenuBoxObject() +{ +} + +MenuBoxObject::~MenuBoxObject() +{ +} + +JSObject* MenuBoxObject::WrapObject(JSContext* aCx) +{ + return MenuBoxObjectBinding::Wrap(aCx, this); +} + +void MenuBoxObject::OpenMenu(bool aOpenFlag) +{ + nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); + if (pm) { + nsIFrame* frame = GetFrame(false); + if (frame) { + if (aOpenFlag) { + nsCOMPtr<nsIContent> content = mContent; + pm->ShowMenu(content, false, false); + } + else { + nsMenuFrame* menu = do_QueryFrame(frame); + if (menu) { + nsMenuPopupFrame* popupFrame = menu->GetPopup(); + if (popupFrame) + pm->HidePopup(popupFrame->GetContent(), false, true, false, false); + } + } + } + } +} + +already_AddRefed<Element> +MenuBoxObject::GetActiveChild() +{ + nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); + if (menu) { + nsCOMPtr<nsIDOMElement> el; + menu->GetActiveChild(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); + } + return nullptr; +} + +void MenuBoxObject::SetActiveChild(Element* arg) +{ + nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); + if (menu) { + nsCOMPtr<nsIDOMElement> el(do_QueryInterface(arg)); + menu->SetActiveChild(el); + } +} + +bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent) +{ + nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); + if (!pm) { + return false; + } + + // if event has already been handled, bail + bool eventHandled = false; + keyEvent.GetDefaultPrevented(&eventHandled); + if (eventHandled) { + return false; + } + + if (nsMenuBarListener::IsAccessKeyPressed(&keyEvent)) + return false; + + nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); + if (!menu) { + return false; + } + + nsMenuPopupFrame* popupFrame = menu->GetPopup(); + if (!popupFrame) { + return false; + } + + uint32_t keyCode = keyEvent.KeyCode(); + switch (keyCode) { + case nsIDOMKeyEvent::DOM_VK_UP: + case nsIDOMKeyEvent::DOM_VK_DOWN: + case nsIDOMKeyEvent::DOM_VK_HOME: + case nsIDOMKeyEvent::DOM_VK_END: + { + nsNavigationDirection theDirection; + theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode); + return pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection); + } + default: + return pm->HandleShortcutNavigation(&keyEvent, popupFrame); + } +} + +bool MenuBoxObject::OpenedWithKey() +{ + nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false)); + if (!menuframe) { + return false; + } + + nsIFrame* frame = menuframe->GetParent(); + while (frame) { + nsMenuBarFrame* menubar = do_QueryFrame(frame); + if (menubar) { + return menubar->IsActiveByKeyboard(); + } + frame = frame->GetParent(); + } + return false; +} + +} // namespace dom +} // namespace mozilla + +// Creation Routine /////////////////////////////////////////////////////////////////////// + +using namespace mozilla::dom; + +nsresult +NS_NewMenuBoxObject(nsIBoxObject** aResult) +{ + NS_ADDREF(*aResult = new MenuBoxObject()); + return NS_OK; +} diff --git a/layout/xul/MenuBoxObject.h b/layout/xul/MenuBoxObject.h new file mode 100644 index 000000000..2c742a41c --- /dev/null +++ b/layout/xul/MenuBoxObject.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_MenuBoxObject_h +#define mozilla_dom_MenuBoxObject_h + +#include "mozilla/dom/BoxObject.h" + +namespace mozilla { +namespace dom { + +class KeyboardEvent; + +class MenuBoxObject final : public BoxObject +{ +public: + + MenuBoxObject(); + + virtual JSObject* WrapObject(JSContext* aCx) override; + + void OpenMenu(bool aOpenFlag); + already_AddRefed<Element> GetActiveChild(); + void SetActiveChild(Element* arg); + bool HandleKeyPress(KeyboardEvent& keyEvent); + bool OpenedWithKey(); + +private: + ~MenuBoxObject(); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_MenuBoxObject_h diff --git a/layout/xul/base/src/nsPopupBoxObject.cpp b/layout/xul/PopupBoxObject.cpp index 93233752d..e821bde9f 100644 --- a/layout/xul/base/src/nsPopupBoxObject.cpp +++ b/layout/xul/PopupBoxObject.cpp @@ -2,38 +2,50 @@ /* 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/. */ + #include "nsCOMPtr.h" -#include "nsIPopupBoxObject.h" #include "nsIRootBox.h" -#include "nsBoxObject.h" #include "nsIPresShell.h" -#include "nsFrameManager.h" #include "nsIContent.h" -#include "nsIDOMElement.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsMenuPopupFrame.h" -#include "nsClientRect.h" #include "nsView.h" - -class nsPopupBoxObject : public nsBoxObject, - public nsIPopupBoxObject +#include "mozilla/AppUnits.h" +#include "mozilla/dom/DOMRect.h" +#include "mozilla/dom/PopupBoxObject.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" +#include "mozilla/dom/PopupBoxObjectBinding.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_ADDREF_INHERITED(PopupBoxObject, BoxObject) +NS_IMPL_RELEASE_INHERITED(PopupBoxObject, BoxObject) +NS_INTERFACE_MAP_BEGIN(PopupBoxObject) +NS_INTERFACE_MAP_END_INHERITING(BoxObject) + +PopupBoxObject::PopupBoxObject() { -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIPOPUPBOXOBJECT +} - nsPopupBoxObject() {} -protected: - virtual ~nsPopupBoxObject() {} +PopupBoxObject::~PopupBoxObject() +{ +} - nsPopupSetFrame* GetPopupSetFrame(); -}; +nsIContent* PopupBoxObject::GetParentObject() const +{ + return BoxObject::GetParentObject(); +} -NS_IMPL_ISUPPORTS_INHERITED1(nsPopupBoxObject, nsBoxObject, nsIPopupBoxObject) +JSObject* PopupBoxObject::WrapObject(JSContext* aCx) +{ + return PopupBoxObjectBinding::Wrap(aCx, this); +} nsPopupSetFrame* -nsPopupBoxObject::GetPopupSetFrame() +PopupBoxObject::GetPopupSetFrame() { nsIRootBox* rootBox = nsIRootBox::GetRootBox(GetPresShell(false)); if (!rootBox) @@ -42,27 +54,23 @@ nsPopupBoxObject::GetPopupSetFrame() return rootBox->GetPopupSetFrame(); } -NS_IMETHODIMP -nsPopupBoxObject::HidePopup() +void +PopupBoxObject::HidePopup(bool aCancel) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (pm && mContent) - pm->HidePopup(mContent, false, true, false); - - return NS_OK; + if (pm && mContent) { + pm->HidePopup(mContent, false, true, false, aCancel); + } } -NS_IMETHODIMP -nsPopupBoxObject::ShowPopup(nsIDOMElement* aAnchorElement, - nsIDOMElement* aPopupElement, - int32_t aXPos, int32_t aYPos, - const PRUnichar *aPopupType, - const PRUnichar *aAnchorAlignment, - const PRUnichar *aPopupAlignment) +void +PopupBoxObject::ShowPopup(Element* aAnchorElement, + Element& aPopupElement, + int32_t aXPos, int32_t aYPos, + const nsAString& aPopupType, + const nsAString& aAnchorAlignment, + const nsAString& aPopupAlignment) { - NS_ENSURE_TRUE(aPopupElement, NS_ERROR_INVALID_ARG); - // srcContent can be null. - nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm && mContent) { nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement)); @@ -70,19 +78,18 @@ nsPopupBoxObject::ShowPopup(nsIDOMElement* aAnchorElement, nsAutoString anchor(aAnchorAlignment); nsAutoString align(aPopupAlignment); pm->ShowPopupWithAnchorAlign(mContent, anchorContent, anchor, align, - aXPos, aYPos, popupType.EqualsLiteral("context")); + aXPos, aYPos, + popupType.EqualsLiteral("context")); } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::OpenPopup(nsIDOMElement* aAnchorElement, - const nsAString& aPosition, - int32_t aXPos, int32_t aYPos, - bool aIsContextMenu, - bool aAttributesOverride, - nsIDOMEvent* aTriggerEvent) +void +PopupBoxObject::OpenPopup(Element* aAnchorElement, + const nsAString& aPosition, + int32_t aXPos, int32_t aYPos, + bool aIsContextMenu, + bool aAttributesOverride, + Event* aTriggerEvent) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm && mContent) { @@ -90,55 +97,48 @@ nsPopupBoxObject::OpenPopup(nsIDOMElement* aAnchorElement, pm->ShowPopup(mContent, anchorContent, aPosition, aXPos, aYPos, aIsContextMenu, aAttributesOverride, false, aTriggerEvent); } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos, - bool aIsContextMenu, - nsIDOMEvent* aTriggerEvent) +void +PopupBoxObject::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos, + bool aIsContextMenu, + Event* aTriggerEvent) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm && mContent) pm->ShowPopupAtScreen(mContent, aXPos, aYPos, aIsContextMenu, aTriggerEvent); - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::MoveTo(int32_t aLeft, int32_t aTop) +void +PopupBoxObject::MoveTo(int32_t aLeft, int32_t aTop) { nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; if (menuPopupFrame) { menuPopupFrame->MoveTo(aLeft, aTop, true); } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::MoveToAnchor(nsIDOMElement* aAnchorElement, - const nsAString& aPosition, - int32_t aXPos, int32_t aYPos, - bool aAttributesOverride) +void +PopupBoxObject::MoveToAnchor(Element* aAnchorElement, + const nsAString& aPosition, + int32_t aXPos, int32_t aYPos, + bool aAttributesOverride) { if (mContent) { nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement)); nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(mContent->GetPrimaryFrame()); - if (menuPopupFrame && menuPopupFrame->PopupState() == ePopupOpenAndVisible) { + if (menuPopupFrame && menuPopupFrame->IsVisible()) { menuPopupFrame->MoveToAnchor(anchorContent, aPosition, aXPos, aYPos, aAttributesOverride); } } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight) +void +PopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight) { if (!mContent) - return NS_OK; + return; nsAutoString width, height; width.AppendInt(aWidth); @@ -153,57 +153,47 @@ nsPopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight) content->SetAttr(kNameSpaceID_None, nsGkAtoms::width, width, heightSame); content->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true); - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::GetAutoPosition(bool* aShouldAutoPosition) +bool +PopupBoxObject::AutoPosition() { - *aShouldAutoPosition = true; - nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; if (menuPopupFrame) { - *aShouldAutoPosition = menuPopupFrame->GetAutoPosition(); + return menuPopupFrame->GetAutoPosition(); } - - return NS_OK; + return true; } -NS_IMETHODIMP -nsPopupBoxObject::SetAutoPosition(bool aShouldAutoPosition) +void +PopupBoxObject::SetAutoPosition(bool aShouldAutoPosition) { nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; if (menuPopupFrame) { menuPopupFrame->SetAutoPosition(aShouldAutoPosition); } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::EnableRollup(bool aShouldRollup) +void +PopupBoxObject::EnableRollup(bool aShouldRollup) { // this does nothing now - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::SetConsumeRollupEvent(uint32_t aConsume) +void +PopupBoxObject::SetConsumeRollupEvent(uint32_t aConsume) { nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false)); if (menuPopupFrame) { menuPopupFrame->SetConsumeRollupEvent(aConsume); } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator) +void +PopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator) { if (!mContent) - return NS_OK; + return; // Use ignorekeys="true" on the popup instead of using this function. if (aEnableKeyboardNavigator) @@ -211,12 +201,10 @@ nsPopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator) else mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys, NS_LITERAL_STRING("true"), true); - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::GetPopupState(nsAString& aState) +void +PopupBoxObject::GetPopupState(nsString& aState) { // set this here in case there's no frame for the popup aState.AssignLiteral("closed"); @@ -224,13 +212,14 @@ nsPopupBoxObject::GetPopupState(nsAString& aState) nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; if (menuPopupFrame) { switch (menuPopupFrame->PopupState()) { + case ePopupShown: + aState.AssignLiteral("open"); + break; case ePopupShowing: - case ePopupOpen: + case ePopupOpening: + case ePopupVisible: aState.AssignLiteral("showing"); break; - case ePopupOpenAndVisible: - aState.AssignLiteral("open"); - break; case ePopupHiding: case ePopupInvisible: aState.AssignLiteral("hiding"); @@ -242,54 +231,37 @@ nsPopupBoxObject::GetPopupState(nsAString& aState) break; } } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::GetTriggerNode(nsIDOMNode** aTriggerNode) +nsINode* +PopupBoxObject::GetTriggerNode() const { - *aTriggerNode = nullptr; - nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; - nsIContent* triggerContent = nsMenuPopupFrame::GetTriggerContent(menuPopupFrame); - if (triggerContent) - CallQueryInterface(triggerContent, aTriggerNode); - - return NS_OK; + return nsMenuPopupFrame::GetTriggerContent(menuPopupFrame); } -NS_IMETHODIMP -nsPopupBoxObject::GetAnchorNode(nsIDOMElement** aAnchor) +Element* +PopupBoxObject::GetAnchorNode() const { - *aAnchor = nullptr; - nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr; - if (!menuPopupFrame) - return NS_OK; + if (!menuPopupFrame) { + return nullptr; + } nsIContent* anchor = menuPopupFrame->GetAnchor(); - if (anchor) - CallQueryInterface(anchor, aAnchor); - - return NS_OK; + return anchor && anchor->IsElement() ? anchor->AsElement() : nullptr; } -NS_IMETHODIMP -nsPopupBoxObject::GetOuterScreenRect(nsIDOMClientRect** aRect) +already_AddRefed<DOMRect> +PopupBoxObject::GetOuterScreenRect() { - nsClientRect* rect = new nsClientRect(mContent); - - NS_ADDREF(*aRect = rect); - - nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false)); - if (!menuPopupFrame) - return NS_OK; + nsRefPtr<DOMRect> rect = new DOMRect(mContent); // Return an empty rectangle if the popup is not open. - nsPopupState state = menuPopupFrame->PopupState(); - if (state != ePopupOpen && state != ePopupOpenAndVisible) - return NS_OK; + nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false)); + if (!menuPopupFrame || !menuPopupFrame->IsOpen()) { + return rect.forget(); + } nsView* view = menuPopupFrame->GetView(); if (view) { @@ -302,19 +274,18 @@ nsPopupBoxObject::GetOuterScreenRect(nsIDOMClientRect** aRect) rect->SetLayoutRect(screenRect.ToAppUnits(pp)); } } - - return NS_OK; + return rect.forget(); } -NS_IMETHODIMP -nsPopupBoxObject::GetAlignmentPosition(nsAString& positionStr) +void +PopupBoxObject::GetAlignmentPosition(nsString& positionStr) { positionStr.Truncate(); // This needs to flush layout. nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(true)); if (!menuPopupFrame) - return NS_OK; + return; int8_t position = menuPopupFrame->GetAlignmentPosition(); switch (position) { @@ -352,35 +323,33 @@ nsPopupBoxObject::GetAlignmentPosition(nsAString& positionStr) // Leave as an empty string. break; } - - return NS_OK; } -NS_IMETHODIMP -nsPopupBoxObject::GetAlignmentOffset(int32_t *aAlignmentOffset) +int32_t +PopupBoxObject::AlignmentOffset() { - nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(true)); + nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false)); if (!menuPopupFrame) - return NS_OK; + return 0; - int32_t pp = nsDeviceContext::AppUnitsPerCSSPixel(); + int32_t pp = mozilla::AppUnitsPerCSSPixel(); // Note that the offset might be along either the X or Y axis, but for the // sake of simplicity we use a point with only the X axis set so we can // use ToNearestPixels(). nsPoint appOffset(menuPopupFrame->GetAlignmentOffset(), 0); nsIntPoint popupOffset = appOffset.ToNearestPixels(pp); - *aAlignmentOffset = popupOffset.x; - return NS_OK; + return popupOffset.x; } +} // namespace dom +} // namespace mozilla + // Creation Routine /////////////////////////////////////////////////////////////////////// nsresult NS_NewPopupBoxObject(nsIBoxObject** aResult) { - *aResult = new nsPopupBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; + *aResult = new mozilla::dom::PopupBoxObject(); NS_ADDREF(*aResult); return NS_OK; } diff --git a/layout/xul/PopupBoxObject.h b/layout/xul/PopupBoxObject.h new file mode 100644 index 000000000..fde650f2d --- /dev/null +++ b/layout/xul/PopupBoxObject.h @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_PopupBoxObject_h +#define mozilla_dom_PopupBoxObject_h + +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" +#include "nsCycleCollectionParticipant.h" +#include "nsWrapperCache.h" +#include "mozilla/dom/BoxObject.h" +#include "nsString.h" + +struct JSContext; +class nsPopupSetFrame; + +namespace mozilla { +namespace dom { + +class DOMRect; +class Element; +class Event; + +class PopupBoxObject final : public BoxObject +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + // also in PopupBoxObject.webidl + static const uint32_t ROLLUP_DEFAULT = 0; /* widget/platform default */ + static const uint32_t ROLLUP_CONSUME = 1; /* consume the rollup event */ + static const uint32_t ROLLUP_NO_CONSUME = 2; /* don't consume the rollup event */ + + PopupBoxObject(); + + nsIContent* GetParentObject() const; + virtual JSObject* WrapObject(JSContext* aCx) override; + + void ShowPopup(Element* aAnchorElement, + Element& aPopupElement, + int32_t aXPos, + int32_t aYPos, + const nsAString& aPopupType, + const nsAString& aAnchorAlignment, + const nsAString& aPopupAlignment); + + void HidePopup(bool aCancel); + + bool AutoPosition(); + + void SetAutoPosition(bool aShouldAutoPosition); + + void EnableKeyboardNavigator(bool aEnableKeyboardNavigator); + + void EnableRollup(bool aShouldRollup); + + void SetConsumeRollupEvent(uint32_t aConsume); + + void SizeTo(int32_t aWidth, int32_t aHeight); + + void MoveTo(int32_t aLeft, int32_t aTop); + + void OpenPopup(Element* aAnchorElement, + const nsAString& aPosition, + int32_t aXPos, + int32_t aYPos, + bool aIsContextMenu, bool aAttributesOverride, + Event* aTriggerEvent); + + void OpenPopupAtScreen(int32_t aXPos, + int32_t aYPos, + bool aIsContextMenu, + Event* aTriggerEvent); + + void GetPopupState(nsString& aState); + + nsINode* GetTriggerNode() const; + + Element* GetAnchorNode() const; + + already_AddRefed<DOMRect> GetOuterScreenRect(); + + void MoveToAnchor(Element* aAnchorElement, + const nsAString& aPosition, + int32_t aXPos, + int32_t aYPos, + bool aAttributesOverride); + + void GetAlignmentPosition(nsString& positionStr); + + int32_t AlignmentOffset(); + +private: + ~PopupBoxObject(); + +protected: + nsPopupSetFrame* GetPopupSetFrame(); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_PopupBoxObject_h diff --git a/layout/xul/ScrollBoxObject.cpp b/layout/xul/ScrollBoxObject.cpp new file mode 100644 index 000000000..2b42ee476 --- /dev/null +++ b/layout/xul/ScrollBoxObject.cpp @@ -0,0 +1,394 @@ +/* -*- 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/. */ + +#include "mozilla/dom/ScrollBoxObject.h" +#include "mozilla/dom/ScrollBoxObjectBinding.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/ToJSValue.h" +#include "nsCOMPtr.h" +#include "nsIPresShell.h" +#include "nsIContent.h" +#include "nsIDOMElement.h" +#include "nsPresContext.h" +#include "nsBox.h" +#include "nsIScrollableFrame.h" + +namespace mozilla { +namespace dom { + +ScrollBoxObject::ScrollBoxObject() +{ +} + +ScrollBoxObject::~ScrollBoxObject() +{ +} + +JSObject* ScrollBoxObject::WrapObject(JSContext* aCx) +{ + return ScrollBoxObjectBinding::Wrap(aCx, this); +} + +nsIScrollableFrame* ScrollBoxObject::GetScrollFrame() +{ + return do_QueryFrame(GetFrame(false)); +} + +/* void scrollTo (long x, long y); */ +void ScrollBoxObject::ScrollTo(int32_t x, int32_t y, ErrorResult& aRv) +{ + nsIScrollableFrame* sf = GetScrollFrame(); + if (!sf) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + sf->ScrollToCSSPixels(CSSIntPoint(x, y)); +} + +/* void scrollBy (long dx, long dy); */ +void ScrollBoxObject::ScrollBy(int32_t dx, int32_t dy, ErrorResult& aRv) +{ + CSSIntPoint pt; + GetPosition(pt, aRv); + + if (aRv.Failed()) { + return; + } + + ScrollTo(pt.x + dx, pt.y + dy, aRv); +} + +/* void scrollByLine (long dlines); */ +void ScrollBoxObject::ScrollByLine(int32_t dlines, ErrorResult& aRv) +{ + nsIScrollableFrame* sf = GetScrollFrame(); + if (!sf) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + sf->ScrollBy(nsIntPoint(0, dlines), nsIScrollableFrame::LINES, + nsIScrollableFrame::SMOOTH); +} + +// XUL <scrollbox> elements have a single box child element. +// Get a pointer to that box. +// Note that now that the <scrollbox> is just a regular box +// with 'overflow:hidden', the boxobject's frame is an nsXULScrollFrame, +// the <scrollbox>'s box frame is the scrollframe's "scrolled frame", and +// the <scrollbox>'s child box is a child of that. +static nsIFrame* GetScrolledBox(BoxObject* aScrollBox) { + nsIFrame* frame = aScrollBox->GetFrame(false); + if (!frame) { + return nullptr; + } + + nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); + if (!scrollFrame) { + NS_WARNING("ScrollBoxObject attached to something that's not a scroll frame!"); + return nullptr; + } + + nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame(); + if (!scrolledFrame) + return nullptr; + return nsBox::GetChildBox(scrolledFrame); +} + +/* void scrollByIndex (long dindexes); */ +void ScrollBoxObject::ScrollByIndex(int32_t dindexes, ErrorResult& aRv) +{ + nsIScrollableFrame* sf = GetScrollFrame(); + if (!sf) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + nsIFrame* scrolledBox = GetScrolledBox(this); + if (!scrolledBox) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + nsRect rect; + + // now get the scrolled boxes first child. + nsIFrame* child = nsBox::GetChildBox(scrolledBox); + + bool horiz = scrolledBox->IsHorizontal(); + nsPoint cp = sf->GetScrollPosition(); + nscoord diff = 0; + int32_t curIndex = 0; + bool isLTR = scrolledBox->IsNormalDirection(); + + int32_t frameWidth = 0; + if (!isLTR && horiz) { + GetWidth(&frameWidth); + nsCOMPtr<nsIPresShell> shell = GetPresShell(false); + if (!shell) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return; + } + frameWidth = nsPresContext::CSSPixelsToAppUnits(frameWidth); + } + + // first find out what index we are currently at + while(child) { + rect = child->GetRect(); + if (horiz) { + // In the left-to-right case we break from the loop when the center of + // the current child rect is greater than the scrolled position of + // the left edge of the scrollbox + // In the right-to-left case we break when the center of the current + // child rect is less than the scrolled position of the right edge of + // the scrollbox. + diff = rect.x + rect.width/2; // use the center, to avoid rounding errors + if ((isLTR && diff > cp.x) || + (!isLTR && diff < cp.x + frameWidth)) { + break; + } + } else { + diff = rect.y + rect.height/2;// use the center, to avoid rounding errors + if (diff > cp.y) { + break; + } + } + child = nsBox::GetNextBox(child); + curIndex++; + } + + int32_t count = 0; + + if (dindexes == 0) + return; + + if (dindexes > 0) { + while(child) { + child = nsBox::GetNextBox(child); + if (child) { + rect = child->GetRect(); + } + count++; + if (count >= dindexes) { + break; + } + } + + } else if (dindexes < 0) { + child = nsBox::GetChildBox(scrolledBox); + while(child) { + rect = child->GetRect(); + if (count >= curIndex + dindexes) { + break; + } + + count++; + child = nsBox::GetNextBox(child); + + } + } + + nscoord csspixel = nsPresContext::CSSPixelsToAppUnits(1); + if (horiz) { + // In the left-to-right case we scroll so that the left edge of the + // selected child is scrolled to the left edge of the scrollbox. + // In the right-to-left case we scroll so that the right edge of the + // selected child is scrolled to the right edge of the scrollbox. + + nsPoint pt(isLTR ? rect.x : rect.x + rect.width - frameWidth, + cp.y); + + // Use a destination range that ensures the left edge (or right edge, + // for RTL) will indeed be visible. Also ensure that the top edge + // is visible. + nsRect range(pt.x, pt.y, csspixel, 0); + if (isLTR) { + range.x -= csspixel; + } + sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range); + } else { + // Use a destination range that ensures the top edge will be visible. + nsRect range(cp.x, rect.y - csspixel, 0, csspixel); + sf->ScrollTo(nsPoint(cp.x, rect.y), nsIScrollableFrame::INSTANT, &range); + } +} + +/* void scrollToLine (in long line); */ +void ScrollBoxObject::ScrollToLine(int32_t line, ErrorResult& aRv) +{ + nsIScrollableFrame* sf = GetScrollFrame(); + if (!sf) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + nscoord y = sf->GetLineScrollAmount().height * line; + nsRect range(0, y - nsPresContext::CSSPixelsToAppUnits(1), + 0, nsPresContext::CSSPixelsToAppUnits(1)); + sf->ScrollTo(nsPoint(0, y), nsIScrollableFrame::INSTANT, &range); +} + +/* void scrollToElement (Element child); */ +void ScrollBoxObject::ScrollToElement(Element& child, ErrorResult& aRv) +{ + nsCOMPtr<nsIPresShell> shell = GetPresShell(false); + if (!shell) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return; + } + + shell->ScrollContentIntoView(&child, + nsIPresShell::ScrollAxis( + nsIPresShell::SCROLL_TOP, + nsIPresShell::SCROLL_ALWAYS), + nsIPresShell::ScrollAxis( + nsIPresShell::SCROLL_LEFT, + nsIPresShell::SCROLL_ALWAYS), + nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY | + nsIPresShell::SCROLL_OVERFLOW_HIDDEN); +} + +/* void scrollToIndex (long index); */ +void ScrollBoxObject::ScrollToIndex(int32_t index, ErrorResult& aRv) +{ + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); +} + +int32_t ScrollBoxObject::GetPositionX(ErrorResult& aRv) +{ + CSSIntPoint pt; + GetPosition(pt, aRv); + return pt.x; +} + +int32_t ScrollBoxObject::GetPositionY(ErrorResult& aRv) +{ + CSSIntPoint pt; + GetPosition(pt, aRv); + return pt.y; +} + +int32_t ScrollBoxObject::GetScrolledWidth(ErrorResult& aRv) +{ + nsRect scrollRect; + GetScrolledSize(scrollRect, aRv); + return scrollRect.width; +} + +int32_t ScrollBoxObject::GetScrolledHeight(ErrorResult& aRv) +{ + nsRect scrollRect; + GetScrolledSize(scrollRect, aRv); + return scrollRect.height; +} + +/* private helper */ +void ScrollBoxObject::GetPosition(CSSIntPoint& aPos, ErrorResult& aRv) +{ + nsIScrollableFrame* sf = GetScrollFrame(); + if (!sf) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + aPos = sf->GetScrollPositionCSSPixels(); +} + +/* private helper */ +void ScrollBoxObject::GetScrolledSize(nsRect& aRect, ErrorResult& aRv) +{ + nsIFrame* scrolledBox = GetScrolledBox(this); + if (!scrolledBox) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + aRect = scrolledBox->GetRect(); + aRect.width = nsPresContext::AppUnitsToIntCSSPixels(aRect.width); + aRect.height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height); +} + +void ScrollBoxObject::GetPosition(JSContext* cx, + JS::Handle<JSObject*> x, + JS::Handle<JSObject*> y, + ErrorResult& aRv) +{ + CSSIntPoint pt; + GetPosition(pt, aRv); + JS::Rooted<JS::Value> v(cx); + if (!ToJSValue(cx, pt.x, &v) || + !JS_SetProperty(cx, x, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + if (!ToJSValue(cx, pt.y, &v) || + !JS_SetProperty(cx, y, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } +} + +void ScrollBoxObject::GetScrolledSize(JSContext* cx, + JS::Handle<JSObject*> width, + JS::Handle<JSObject*> height, + ErrorResult& aRv) +{ + nsRect rect; + GetScrolledSize(rect, aRv); + JS::Rooted<JS::Value> v(cx); + if (!ToJSValue(cx, rect.width, &v) || + !JS_SetProperty(cx, width, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + if (!ToJSValue(cx, rect.height, &v) || + !JS_SetProperty(cx, height, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } +} + +/* void ensureElementIsVisible (in nsIDOMElement child); */ +void ScrollBoxObject::EnsureElementIsVisible(Element& child, ErrorResult& aRv) +{ + nsCOMPtr<nsIPresShell> shell = GetPresShell(false); + if (!shell) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return; + } + + shell->ScrollContentIntoView(&child, + nsIPresShell::ScrollAxis(), + nsIPresShell::ScrollAxis(), + nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY | + nsIPresShell::SCROLL_OVERFLOW_HIDDEN); +} + +/* void ensureIndexIsVisible (long index); */ +void ScrollBoxObject::EnsureIndexIsVisible(int32_t index, ErrorResult& aRv) +{ + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); +} + +/* void ensureLineIsVisible (long line); */ +void ScrollBoxObject::EnsureLineIsVisible(int32_t line, ErrorResult& aRv) +{ + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); +} + +} // namespace dom +} // namespace mozilla + +// Creation Routine /////////////////////////////////////////////////////////////////////// + +using namespace mozilla::dom; + +nsresult +NS_NewScrollBoxObject(nsIBoxObject** aResult) +{ + NS_ADDREF(*aResult = new ScrollBoxObject()); + return NS_OK; +} diff --git a/layout/xul/ScrollBoxObject.h b/layout/xul/ScrollBoxObject.h new file mode 100644 index 000000000..7e80c2435 --- /dev/null +++ b/layout/xul/ScrollBoxObject.h @@ -0,0 +1,64 @@ +/* -*- 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 mozilla_dom_ScrollBoxObject_h +#define mozilla_dom_ScrollBoxObject_h + +#include "mozilla/dom/BoxObject.h" +#include "Units.h" + +class nsIScrollableFrame; +struct nsRect; + +namespace mozilla { +namespace dom { + +class ScrollBoxObject final : public BoxObject +{ +public: + ScrollBoxObject(); + + virtual JSObject* WrapObject(JSContext* aCx) override; + + virtual nsIScrollableFrame* GetScrollFrame(); + + void ScrollTo(int32_t x, int32_t y, ErrorResult& aRv); + void ScrollBy(int32_t dx, int32_t dy, ErrorResult& aRv); + void ScrollByLine(int32_t dlines, ErrorResult& aRv); + void ScrollByIndex(int32_t dindexes, ErrorResult& aRv); + void ScrollToLine(int32_t line, ErrorResult& aRv); + void ScrollToElement(Element& child, ErrorResult& aRv); + void ScrollToIndex(int32_t index, ErrorResult& aRv); + int32_t GetPositionX(ErrorResult& aRv); + int32_t GetPositionY(ErrorResult& aRv); + int32_t GetScrolledWidth(ErrorResult& aRv); + int32_t GetScrolledHeight(ErrorResult& aRv); + void EnsureElementIsVisible(Element& child, ErrorResult& aRv); + void EnsureIndexIsVisible(int32_t index, ErrorResult& aRv); + void EnsureLineIsVisible(int32_t line, ErrorResult& aRv); + + // Deprecated APIs from old IDL + void GetPosition(JSContext* cx, + JS::Handle<JSObject*> x, + JS::Handle<JSObject*> y, + ErrorResult& aRv); + + void GetScrolledSize(JSContext* cx, + JS::Handle<JSObject*> width, + JS::Handle<JSObject*> height, + ErrorResult& aRv); + +protected: + void GetScrolledSize(nsRect& aRect, ErrorResult& aRv); + void GetPosition(CSSIntPoint& aPos, ErrorResult& aRv); + +private: + ~ScrollBoxObject(); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ScrollBoxObject_h diff --git a/layout/xul/base/public/moz.build b/layout/xul/base/public/moz.build deleted file mode 100644 index f4963b000..000000000 --- a/layout/xul/base/public/moz.build +++ /dev/null @@ -1,29 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; 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/. - -XPIDL_SOURCES += [ - 'nsIBoxObject.idl', - 'nsIBrowserBoxObject.idl', - 'nsIContainerBoxObject.idl', - 'nsIEditorBoxObject.idl', - 'nsIIFrameBoxObject.idl', - 'nsIListBoxObject.idl', - 'nsIMenuBoxObject.idl', - 'nsIPopupBoxObject.idl', - 'nsIScrollBoxObject.idl', - 'nsISliderListener.idl', -] - -XPIDL_MODULE = 'layout_xul' - -MODULE = 'layout' - -EXPORTS += [ - 'nsIScrollbarMediator.h', - 'nsPIBoxObject.h', - 'nsXULPopupManager.h', -] - diff --git a/layout/xul/base/public/nsIMenuBoxObject.idl b/layout/xul/base/public/nsIMenuBoxObject.idl deleted file mode 100644 index 3a3e85409..000000000 --- a/layout/xul/base/public/nsIMenuBoxObject.idl +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- 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/. */ - -#include "nsIBoxObject.idl" - -interface nsIDOMElement; -interface nsIDOMKeyEvent; - -[scriptable, uuid(689ebf3d-0184-450a-9bfa-5a26be0e7a8c)] -interface nsIMenuBoxObject : nsISupports -{ - void openMenu(in boolean openFlag); - - attribute nsIDOMElement activeChild; - - boolean handleKeyPress(in nsIDOMKeyEvent keyEvent); - - // true if the menu or menubar was opened via a keypress. - readonly attribute boolean openedWithKey; -}; - -%{C++ -nsresult -NS_NewMenuBoxObject(nsIBoxObject** aResult); - -%} diff --git a/layout/xul/base/public/nsIPopupBoxObject.idl b/layout/xul/base/public/nsIPopupBoxObject.idl deleted file mode 100644 index a6b79cd5a..000000000 --- a/layout/xul/base/public/nsIPopupBoxObject.idl +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- 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/. */ - -#include "nsIBoxObject.idl" - -interface nsIDOMElement; -interface nsIDOMNode; -interface nsIDOMEvent; -interface nsIDOMClientRect; - -[scriptable, uuid(b1192cac-467b-42ca-88d6-fcdec5bb4ef7)] -interface nsIPopupBoxObject : nsISupports -{ - /** - * This method is deprecated. Use openPopup or openPopupAtScreen instead. - */ - void showPopup(in nsIDOMElement srcContent, in nsIDOMElement popupContent, - in long xpos, in long ypos, - in wstring popupType, in wstring anchorAlignment, - in wstring popupAlignment); - - /** - * Hide the popup if it is open. - */ - void hidePopup(); - - /** - * Allow the popup to automatically position itself. - */ - attribute boolean autoPosition; - - /** - * If keyboard navigation is enabled, the keyboard may be used to navigate - * the menuitems on the popup. Enabling keyboard navigation is the default - * behaviour and will install capturing key event listeners on the popup - * that do not propagate key events to the contents. If you wish to place - * elements in a popup which accept key events, such as textboxes, keyboard - * navigation should be disabled. - * - * Setting ignorekeys="true" on the popup element also disables keyboard - * navigation, and is recommended over calling this method. - */ - void enableKeyboardNavigator(in boolean enableKeyboardNavigator); - - /** - * Enable automatic popup dismissal. This only has effect when called - * on an open popup. - */ - void enableRollup(in boolean enableRollup); - - /** - * Control whether the event that caused the popup to be automatically - * dismissed ("rolled up") should be consumed, or dispatched as a - * normal event. This should be set immediately before calling showPopup() - * if non-default behavior is desired. - */ - const uint32_t ROLLUP_DEFAULT = 0; /* widget/platform default */ - const uint32_t ROLLUP_CONSUME = 1; /* consume the rollup event */ - const uint32_t ROLLUP_NO_CONSUME = 2; /* don't consume the rollup event */ - void setConsumeRollupEvent(in uint32_t consume); - - /** - * Size the popup to the given dimensions - */ - void sizeTo(in long width, in long height); - - /** - * Move the popup to a point on screen in CSS pixels. - */ - void moveTo(in long left, in long top); - - /** - * Open the popup relative to a specified node at a specific location. - * - * The popup may be either anchored to another node or opened freely. - * To anchor a popup to a node, supply an anchor node and set the position - * to a string indicating the manner in which the popup should be anchored. - * Possible values for position are: - * before_start, before_end, after_start, after_end, - * start_before, start_after, end_before, end_after, - * overlap, after_pointer - * - * The anchor node does not need to be in the same document as the popup. - * - * If the attributesOverride argument is true, the popupanchor, popupalign - * and position attributes on the popup node override the position value - * argument. If attributesOverride is false, the attributes are only used - * if position is empty. - * - * For an anchored popup, the x and y arguments may be used to offset the - * popup from its anchored position by some distance, measured in CSS pixels. - * x increases to the right and y increases down. Negative values may also - * be used to move to the left and upwards respectively. - * - * Unanchored popups may be created by supplying null as the anchor node. - * An unanchored popup appears at the position specified by x and y, - * relative to the viewport of the document containing the popup node. In - * this case, position and attributesOverride are ignored. - * - * @param anchorElement the node to anchor the popup to, may be null - * @param position manner is which to anchor the popup to node - * @param x horizontal offset - * @param y vertical offset - * @param isContextMenu true for context menus, false for other popups - * @param attributesOverride true if popup node attributes override position - * @param triggerEvent the event that triggered this popup (mouse click for example) - */ - void openPopup(in nsIDOMElement anchorElement, - in AString position, - in long x, in long y, - in boolean isContextMenu, - in boolean attributesOverride, - in nsIDOMEvent triggerEvent); - - /** - * Open the popup at a specific screen position specified by x and y. This - * position may be adjusted if it would cause the popup to be off of the - * screen. The x and y coordinates are measured in CSS pixels, and like all - * screen coordinates, are given relative to the top left of the primary - * screen. - * - * @param isContextMenu true for context menus, false for other popups - * @param x horizontal screen position - * @param y vertical screen position - * @param triggerEvent the event that triggered this popup (mouse click for example) - */ - void openPopupAtScreen(in long x, in long y, - in boolean isContextMenu, - in nsIDOMEvent triggerEvent); - - /** - * Returns the state of the popup: - * closed - the popup is closed - * open - the popup is open - * showing - the popup is in the process of being shown - * hiding - the popup is in the process of being hidden - */ - readonly attribute AString popupState; - - /** - * The node that triggered the popup. If the popup is not open, will return - * null. - */ - readonly attribute nsIDOMNode triggerNode; - - /** - * Retrieve the anchor that was specified to openPopup or for menupopups in a - * menu, the parent menu. - */ - readonly attribute nsIDOMElement anchorNode; - - /** - * Retrieve the screen rectangle of the popup, including the area occupied by - * any titlebar or borders present. - */ - nsIDOMClientRect getOuterScreenRect(); - - /** - * Move an open popup to the given anchor position. The arguments have the same - * meaning as the corresponding argument to openPopup. This method has no effect - * on popups that are not open. - */ - void moveToAnchor(in nsIDOMElement anchorElement, - in AString position, - in long x, in long y, - in boolean attributesOverride); - - /** Returns the alignment position where the popup has appeared relative to its - * anchor node or point, accounting for any flipping that occurred. - */ - readonly attribute AString alignmentPosition; - readonly attribute long alignmentOffset; -}; - -%{C++ -nsresult -NS_NewPopupBoxObject(nsIBoxObject** aResult); - -%} diff --git a/layout/xul/base/public/nsIScrollBoxObject.idl b/layout/xul/base/public/nsIScrollBoxObject.idl deleted file mode 100644 index 5acb3a945..000000000 --- a/layout/xul/base/public/nsIScrollBoxObject.idl +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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/. */ - -#include "nsIBoxObject.idl" - -interface nsIDOMElement; - - -[scriptable, uuid(56E2ADA8-4631-11d4-BA11-001083023C1E)] -interface nsIScrollBoxObject : nsISupports -{ - /** - * Scroll to the given coordinates, in css pixels. - * (0,0) will put the top left corner of the scrolled element's padding-box - * at the top left corner of the scrollport (which is its inner-border-box). - * Values will be clamped to legal values. - */ - void scrollTo(in long x, in long y); - - /** - * Scroll the given amount of device pixels to the right and down. - * Values will be clamped to make the resuling position legal. - */ - void scrollBy(in long dx, in long dy); - - void scrollByLine(in long dlines); - void scrollByIndex(in long dindexes); - void scrollToLine(in long line); - void scrollToElement(in nsIDOMElement child); - void scrollToIndex(in long index); - - /** - * Get the current scroll position in css pixels. - * @see scrollTo for the definition of x and y. - */ - void getPosition(out long x, out long y); - - void getScrolledSize(out long width, out long height); - void ensureElementIsVisible(in nsIDOMElement child); - void ensureIndexIsVisible(in long index); - void ensureLineIsVisible(in long line); -}; - -%{C++ -nsresult -NS_NewScrollBoxObject(nsIBoxObject** aResult); - -%} diff --git a/layout/xul/base/public/nsIScrollbarMediator.h b/layout/xul/base/public/nsIScrollbarMediator.h deleted file mode 100644 index 873341666..000000000 --- a/layout/xul/base/public/nsIScrollbarMediator.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- 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 nsIScrollbarMediator_h___ -#define nsIScrollbarMediator_h___ - -#include "nsQueryFrame.h" - -class nsScrollbarFrame; - -class nsIScrollbarMediator -{ -public: - NS_DECL_QUERYFRAME_TARGET(nsIScrollbarMediator) - - // The aScrollbar argument denotes the scrollbar that's firing the notification. - NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) = 0; - NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) = 0; - - NS_IMETHOD VisibilityChanged(bool aVisible) = 0; -}; - -#endif - diff --git a/layout/xul/base/reftest/reftest.list b/layout/xul/base/reftest/reftest.list deleted file mode 100644 index 7452737be..000000000 --- a/layout/xul/base/reftest/reftest.list +++ /dev/null @@ -1,5 +0,0 @@ -fails-if(Android||B2G) == textbox-multiline-noresize.xul textbox-multiline-ref.xul # reference is blank on Android (due to no native theme support?) -!= textbox-multiline-resize.xul textbox-multiline-ref.xul -== popup-explicit-size.xul popup-explicit-size-ref.xul -random-if(Android) == image-size.xul image-size-ref.xul -== image-scaling-min-height-1.xul image-scaling-min-height-1-ref.xul diff --git a/layout/xul/base/src/Makefile.in b/layout/xul/base/src/Makefile.in deleted file mode 100644 index 25bd6f144..000000000 --- a/layout/xul/base/src/Makefile.in +++ /dev/null @@ -1,34 +0,0 @@ -# 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/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -LIBRARY_NAME = gkxulbase_s -MSVC_ENABLE_PGO := 1 -LIBXUL_LIBRARY = 1 -FAIL_ON_WARNINGS = 1 - -include $(topsrcdir)/config/config.mk - -# we don't want the shared lib, but we want to force the creation of a static lib. -FORCE_STATIC_LIB = 1 - -include $(topsrcdir)/config/rules.mk - -LOCAL_INCLUDES = \ - -I$(srcdir) \ - -I$(srcdir)/../../../base \ - -I$(srcdir)/../../../../content/base/src \ - -I$(srcdir)/../../../../content/events/src \ - -I$(srcdir)/../../../generic \ - -I$(srcdir)/../../../style \ - $(NULL) - -DEFINES += -D_IMPL_NS_LAYOUT - diff --git a/layout/xul/base/src/nsBoxObject.h b/layout/xul/base/src/nsBoxObject.h deleted file mode 100644 index c93222104..000000000 --- a/layout/xul/base/src/nsBoxObject.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- 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 nsBoxObject_h_ -#define nsBoxObject_h_ - -#include "mozilla/Attributes.h" -#include "nsCOMPtr.h" -#include "nsIBoxObject.h" -#include "nsPIBoxObject.h" -#include "nsPoint.h" -#include "nsAutoPtr.h" -#include "nsHashKeys.h" -#include "nsInterfaceHashtable.h" -#include "nsCycleCollectionParticipant.h" - -class nsIFrame; -class nsIDocShell; -struct nsIntRect; -class nsIPresShell; - -class nsBoxObject : public nsPIBoxObject -{ - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(nsBoxObject) - NS_DECL_NSIBOXOBJECT - -public: - nsBoxObject(); - virtual ~nsBoxObject(); - - // nsPIBoxObject - virtual nsresult Init(nsIContent* aContent) MOZ_OVERRIDE; - virtual void Clear() MOZ_OVERRIDE; - virtual void ClearCachedValues() MOZ_OVERRIDE; - - nsIFrame* GetFrame(bool aFlushLayout); - nsIPresShell* GetPresShell(bool aFlushLayout); - nsresult GetOffsetRect(nsIntRect& aRect); - nsresult GetScreenPosition(nsIntPoint& aPoint); - - // Given a parent frame and a child frame, find the frame whose - // next sibling is the given child frame and return its element - static nsresult GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, - nsIDOMElement** aResult); - -protected: - - nsAutoPtr<nsInterfaceHashtable<nsStringHashKey,nsISupports> > mPropertyTable; //[OWNER] - - nsIContent* mContent; // [WEAK] -}; - -#endif diff --git a/layout/xul/base/src/nsContainerBoxObject.cpp b/layout/xul/base/src/nsContainerBoxObject.cpp deleted file mode 100644 index 2e5e1aa43..000000000 --- a/layout/xul/base/src/nsContainerBoxObject.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- 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/. */ - -#include "nsCOMPtr.h" -#include "nsIContainerBoxObject.h" -#include "nsIBrowserBoxObject.h" -#include "nsIEditorBoxObject.h" -#include "nsIIFrameBoxObject.h" -#include "nsBoxObject.h" -#include "nsIDocShell.h" -#include "nsIContent.h" -#include "nsIDocument.h" -#include "nsIFrame.h" -#include "nsSubDocumentFrame.h" - -/** - * nsContainerBoxObject implements deprecated nsIBrowserBoxObject, - * nsIEditorBoxObject and nsIIFrameBoxObject interfaces only because of the - * backward compatibility. - */ - -class nsContainerBoxObject : public nsBoxObject, - public nsIBrowserBoxObject, - public nsIEditorBoxObject, - public nsIIFrameBoxObject -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSICONTAINERBOXOBJECT - NS_DECL_NSIBROWSERBOXOBJECT - NS_DECL_NSIEDITORBOXOBJECT - NS_DECL_NSIIFRAMEBOXOBJECT -}; - -NS_INTERFACE_MAP_BEGIN(nsContainerBoxObject) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIContainerBoxObject, nsIBrowserBoxObject) - NS_INTERFACE_MAP_ENTRY(nsIBrowserBoxObject) - NS_INTERFACE_MAP_ENTRY(nsIEditorBoxObject) - NS_INTERFACE_MAP_ENTRY(nsIIFrameBoxObject) -NS_INTERFACE_MAP_END_INHERITING(nsBoxObject) - -NS_IMPL_ADDREF_INHERITED(nsContainerBoxObject, nsBoxObject) -NS_IMPL_RELEASE_INHERITED(nsContainerBoxObject, nsBoxObject) - -NS_IMETHODIMP nsContainerBoxObject::GetDocShell(nsIDocShell** aResult) -{ - *aResult = nullptr; - - nsIFrame *frame = GetFrame(false); - - if (frame) { - nsSubDocumentFrame *subDocFrame = do_QueryFrame(frame); - if (subDocFrame) { - // Ok, the frame for mContent is an nsSubDocumentFrame, it knows how - // to reach the docshell, so ask it... - - return subDocFrame->GetDocShell(aResult); - } - } - - if (!mContent) { - return NS_OK; - } - - // No nsSubDocumentFrame available for mContent, try if there's a mapping - // between mContent's document to mContent's subdocument. - - // XXXbz sXBL/XBL2 issue -- ownerDocument or currentDocument? - nsIDocument *doc = mContent->GetDocument(); - - if (!doc) { - return NS_OK; - } - - nsIDocument *sub_doc = doc->GetSubDocumentFor(mContent); - - if (!sub_doc) { - return NS_OK; - } - - nsCOMPtr<nsISupports> container = sub_doc->GetContainer(); - - if (!container) { - return NS_OK; - } - - return CallQueryInterface(container, aResult); -} - -nsresult -NS_NewContainerBoxObject(nsIBoxObject** aResult) -{ - *aResult = new nsContainerBoxObject(); - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; -} - diff --git a/layout/xul/base/src/nsLeafBoxFrame.h b/layout/xul/base/src/nsLeafBoxFrame.h deleted file mode 100644 index 791e63145..000000000 --- a/layout/xul/base/src/nsLeafBoxFrame.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- 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 nsLeafBoxFrame_h___ -#define nsLeafBoxFrame_h___ - -#include "mozilla/Attributes.h" -#include "nsLeafFrame.h" -#include "nsBox.h" - -class nsAccessKeyInfo; - -class nsLeafBoxFrame : public nsLeafFrame -{ -public: - NS_DECL_FRAMEARENA_HELPERS - - friend nsIFrame* NS_NewLeafBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - - virtual nsSize GetPrefSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nscoord GetFlex(nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nscoord GetBoxAscent(nsBoxLayoutState& aState) MOZ_OVERRIDE; - - virtual nsIAtom* GetType() const MOZ_OVERRIDE; - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE - { - // This is bogus, but it's what we've always done. - // Note that nsLeafFrame is also eReplacedContainsBlock. - return nsLeafFrame::IsFrameOfType(aFlags & - ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock | nsIFrame::eXULBox)); - } - -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; -#endif - - // nsIHTMLReflow overrides - - virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - - // Our auto size is that provided by nsFrame, not nsLeafFrame - virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, - nsSize aCBSize, nscoord aAvailableWidth, - nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; - - NS_IMETHOD Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) MOZ_OVERRIDE; - - NS_IMETHOD CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE; - - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* asPrevInFlow) MOZ_OVERRIDE; - - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; - - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; - - virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; } - -protected: - - NS_IMETHOD DoLayout(nsBoxLayoutState& aState) MOZ_OVERRIDE; - -#ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; -#endif - - virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; - - nsLeafBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext); - -private: - - void UpdateMouseThrough(); - - -}; // class nsLeafBoxFrame - -#endif /* nsLeafBoxFrame_h___ */ diff --git a/layout/xul/base/src/nsListBoxObject.cpp b/layout/xul/base/src/nsListBoxObject.cpp deleted file mode 100644 index da6616afd..000000000 --- a/layout/xul/base/src/nsListBoxObject.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- 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/. */ - -#include "nsCOMPtr.h" -#include "nsPIListBoxObject.h" -#include "nsBoxObject.h" -#include "nsIFrame.h" -#include "nsBindingManager.h" -#include "nsIDOMElement.h" -#include "nsIDOMNodeList.h" -#include "nsGkAtoms.h" -#include "nsIScrollableFrame.h" -#include "nsListBoxBodyFrame.h" - -class nsListBoxObject : public nsPIListBoxObject, public nsBoxObject -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSILISTBOXOBJECT - - // nsPIListBoxObject - virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush); - - nsListBoxObject(); - - // nsPIBoxObject - virtual void Clear(); - virtual void ClearCachedValues(); - -protected: - nsListBoxBodyFrame *mListBoxBody; -}; - -NS_IMPL_ISUPPORTS_INHERITED2(nsListBoxObject, nsBoxObject, nsIListBoxObject, - nsPIListBoxObject) - -nsListBoxObject::nsListBoxObject() - : mListBoxBody(nullptr) -{ -} - -////////////////////////////////////////////////////////////////////////// -//// nsIListBoxObject - -NS_IMETHODIMP -nsListBoxObject::GetRowCount(int32_t *aResult) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->GetRowCount(aResult); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::GetNumberOfVisibleRows(int32_t *aResult) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->GetNumberOfVisibleRows(aResult); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::GetIndexOfFirstVisibleRow(int32_t *aResult) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->GetIndexOfFirstVisibleRow(aResult); - return NS_OK; -} - -NS_IMETHODIMP nsListBoxObject::EnsureIndexIsVisible(int32_t aRowIndex) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->EnsureIndexIsVisible(aRowIndex); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::ScrollToIndex(int32_t aRowIndex) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->ScrollToIndex(aRowIndex); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::ScrollByLines(int32_t aNumLines) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->ScrollByLines(aNumLines); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::GetItemAtIndex(int32_t index, nsIDOMElement **_retval) -{ - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->GetItemAtIndex(index, _retval); - return NS_OK; -} - -NS_IMETHODIMP -nsListBoxObject::GetIndexOfItem(nsIDOMElement* aElement, int32_t *aResult) -{ - *aResult = 0; - - nsListBoxBodyFrame* body = GetListBoxBody(true); - if (body) - return body->GetIndexOfItem(aElement, aResult); - return NS_OK; -} - -////////////////////// - -static void -FindBodyContent(nsIContent* aParent, nsIContent** aResult) -{ - if (aParent->Tag() == nsGkAtoms::listboxbody) { - *aResult = aParent; - NS_IF_ADDREF(*aResult); - } - else { - nsCOMPtr<nsIDOMNodeList> kids; - aParent->OwnerDoc()->BindingManager()->GetXBLChildNodesFor(aParent, getter_AddRefs(kids)); - if (!kids) return; - - uint32_t i; - kids->GetLength(&i); - // start from the end, cuz we're smart and we know the listboxbody is probably at the end - while (i > 0) { - nsCOMPtr<nsIDOMNode> childNode; - kids->Item(--i, getter_AddRefs(childNode)); - nsCOMPtr<nsIContent> childContent(do_QueryInterface(childNode)); - FindBodyContent(childContent, aResult); - if (*aResult) - break; - } - } -} - -nsListBoxBodyFrame* -nsListBoxObject::GetListBoxBody(bool aFlush) -{ - if (mListBoxBody) { - return mListBoxBody; - } - - nsIPresShell* shell = GetPresShell(false); - if (!shell) { - return nullptr; - } - - nsIFrame* frame = aFlush ? - GetFrame(false) /* does Flush_Frames */ : - mContent->GetPrimaryFrame(); - if (!frame) - return nullptr; - - // Iterate over our content model children looking for the body. - nsCOMPtr<nsIContent> content; - FindBodyContent(frame->GetContent(), getter_AddRefs(content)); - - if (!content) - return nullptr; - - // this frame will be a nsGFXScrollFrame - frame = content->GetPrimaryFrame(); - if (!frame) - return nullptr; - nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); - if (!scrollFrame) - return nullptr; - - // this frame will be the one we want - nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame(); - if (!yeahBaby) - return nullptr; - - // It's a frame. Refcounts are irrelevant. - nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby); - NS_ENSURE_TRUE(listBoxBody && - listBoxBody->SetBoxObject(this), - nullptr); - mListBoxBody = listBoxBody; - return mListBoxBody; -} - -void -nsListBoxObject::Clear() -{ - ClearCachedValues(); - - nsBoxObject::Clear(); -} - -void -nsListBoxObject::ClearCachedValues() -{ - mListBoxBody = nullptr; -} - -// Creation Routine /////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewListBoxObject(nsIBoxObject** aResult) -{ - *aResult = new nsListBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; -} diff --git a/layout/xul/base/src/nsMenuBoxObject.cpp b/layout/xul/base/src/nsMenuBoxObject.cpp deleted file mode 100644 index a773059b5..000000000 --- a/layout/xul/base/src/nsMenuBoxObject.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* -*- 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/. */ -#include "nsISupportsUtils.h" -#include "nsIMenuBoxObject.h" -#include "nsBoxObject.h" -#include "nsIFrame.h" -#include "nsGUIEvent.h" -#include "nsMenuBarFrame.h" -#include "nsMenuBarListener.h" -#include "nsMenuFrame.h" -#include "nsMenuPopupFrame.h" - -class nsMenuBoxObject : public nsIMenuBoxObject, - public nsBoxObject -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIMENUBOXOBJECT - - nsMenuBoxObject(); - virtual ~nsMenuBoxObject(); -}; - -nsMenuBoxObject::nsMenuBoxObject() -{ -} - -nsMenuBoxObject::~nsMenuBoxObject() -{ -} - -NS_IMPL_ISUPPORTS_INHERITED1(nsMenuBoxObject, nsBoxObject, nsIMenuBoxObject) - -/* void openMenu (in boolean openFlag); */ -NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag) -{ - nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (pm) { - nsIFrame* frame = GetFrame(false); - if (frame) { - if (aOpenFlag) { - nsCOMPtr<nsIContent> content = mContent; - pm->ShowMenu(content, false, false); - } - else { - nsMenuFrame* menu = do_QueryFrame(frame); - if (menu) { - nsMenuPopupFrame* popupFrame = menu->GetPopup(); - if (popupFrame) - pm->HidePopup(popupFrame->GetContent(), false, true, false); - } - } - } - } - - return NS_OK; -} - -NS_IMETHODIMP nsMenuBoxObject::GetActiveChild(nsIDOMElement** aResult) -{ - *aResult = nullptr; - nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); - if (menu) - return menu->GetActiveChild(aResult); - return NS_OK; -} - -NS_IMETHODIMP nsMenuBoxObject::SetActiveChild(nsIDOMElement* aResult) -{ - nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); - if (menu) - return menu->SetActiveChild(aResult); - return NS_OK; -} - -/* boolean handleKeyPress (in nsIDOMKeyEvent keyEvent); */ -NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, bool* aHandledFlag) -{ - *aHandledFlag = false; - NS_ENSURE_ARG(aKeyEvent); - - nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (!pm) - return NS_OK; - - // if event has already been handled, bail - bool eventHandled = false; - aKeyEvent->GetDefaultPrevented(&eventHandled); - if (eventHandled) - return NS_OK; - - if (nsMenuBarListener::IsAccessKeyPressed(aKeyEvent)) - return NS_OK; - - nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); - if (!menu) - return NS_OK; - - nsMenuPopupFrame* popupFrame = menu->GetPopup(); - if (!popupFrame) - return NS_OK; - - uint32_t keyCode; - aKeyEvent->GetKeyCode(&keyCode); - switch (keyCode) { - case NS_VK_UP: - case NS_VK_DOWN: - case NS_VK_HOME: - case NS_VK_END: - { - nsNavigationDirection theDirection; - theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode); - *aHandledFlag = - pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection); - return NS_OK; - } - default: - *aHandledFlag = pm->HandleShortcutNavigation(aKeyEvent, popupFrame); - return NS_OK; - } -} - -NS_IMETHODIMP -nsMenuBoxObject::GetOpenedWithKey(bool* aOpenedWithKey) -{ - *aOpenedWithKey = false; - - nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false)); - if (!menuframe) - return NS_OK; - - nsIFrame* frame = menuframe->GetParent(); - while (frame) { - nsMenuBarFrame* menubar = do_QueryFrame(frame); - if (menubar) { - *aOpenedWithKey = menubar->IsActiveByKeyboard(); - return NS_OK; - } - frame = frame->GetParent(); - } - - return NS_OK; -} - - -// Creation Routine /////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewMenuBoxObject(nsIBoxObject** aResult) -{ - *aResult = new nsMenuBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; -} - diff --git a/layout/xul/base/src/nsPopupSetFrame.h b/layout/xul/base/src/nsPopupSetFrame.h deleted file mode 100644 index 96d373643..000000000 --- a/layout/xul/base/src/nsPopupSetFrame.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- 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 nsPopupSetFrame_h__ -#define nsPopupSetFrame_h__ - -#include "mozilla/Attributes.h" -#include "nsIAtom.h" -#include "nsBoxFrame.h" - -nsIFrame* NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - -class nsPopupSetFrame : public nsBoxFrame -{ -public: - NS_DECL_FRAMEARENA_HELPERS - - nsPopupSetFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext) {} - - ~nsPopupSetFrame() {} - - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) MOZ_OVERRIDE; - NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) MOZ_OVERRIDE; - NS_IMETHOD InsertFrames(ChildListID aListID, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList) MOZ_OVERRIDE; - NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) MOZ_OVERRIDE; - - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - - // Used to destroy our popup frames. - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - - virtual nsIAtom* GetType() const MOZ_OVERRIDE; - -#ifdef DEBUG - void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE; - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE - { - return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult); - } -#endif - -protected: - void AddPopupFrameList(nsFrameList& aPopupFrameList); - void RemovePopupFrame(nsIFrame* aPopup); - - nsFrameList mPopupList; -}; - -#endif diff --git a/layout/xul/base/src/nsScrollBoxObject.cpp b/layout/xul/base/src/nsScrollBoxObject.cpp deleted file mode 100644 index 41a1b3975..000000000 --- a/layout/xul/base/src/nsScrollBoxObject.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* -*- 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/. */ - -#include "nsCOMPtr.h" -#include "nsIScrollBoxObject.h" -#include "nsBoxObject.h" -#include "nsIPresShell.h" -#include "nsIContent.h" -#include "nsIDOMElement.h" -#include "nsPresContext.h" -#include "nsIFrame.h" -#include "nsIScrollableFrame.h" - -class nsScrollBoxObject : public nsIScrollBoxObject, public nsBoxObject -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSISCROLLBOXOBJECT - - nsScrollBoxObject(); - virtual ~nsScrollBoxObject(); - - virtual nsIScrollableFrame* GetScrollFrame() { - return do_QueryFrame(GetFrame(false)); - } - - /* additional members */ -}; - -/* Implementation file */ - -NS_INTERFACE_MAP_BEGIN(nsScrollBoxObject) - NS_INTERFACE_MAP_ENTRY(nsIScrollBoxObject) -NS_INTERFACE_MAP_END_INHERITING(nsBoxObject) - -NS_IMPL_ADDREF_INHERITED(nsScrollBoxObject, nsBoxObject) -NS_IMPL_RELEASE_INHERITED(nsScrollBoxObject, nsBoxObject) - -nsScrollBoxObject::nsScrollBoxObject() -{ - /* member initializers and constructor code */ -} - -nsScrollBoxObject::~nsScrollBoxObject() -{ - /* destructor code */ -} - -/* void scrollTo (in long x, in long y); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollTo(int32_t x, int32_t y) -{ - nsIScrollableFrame* sf = GetScrollFrame(); - if (!sf) - return NS_ERROR_FAILURE; - sf->ScrollToCSSPixels(nsIntPoint(x, y)); - return NS_OK; -} - -/* void scrollBy (in long dx, in long dy); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollBy(int32_t dx, int32_t dy) -{ - int32_t x, y; - nsresult rv = GetPosition(&x, &y); - if (NS_FAILED(rv)) - return rv; - - return ScrollTo(x + dx, y + dy); -} - -/* void scrollByLine (in long dlines); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollByLine(int32_t dlines) -{ - nsIScrollableFrame* sf = GetScrollFrame(); - if (!sf) - return NS_ERROR_FAILURE; - - sf->ScrollBy(nsIntPoint(0, dlines), nsIScrollableFrame::LINES, - nsIScrollableFrame::SMOOTH); - return NS_OK; -} - -// XUL <scrollbox> elements have a single box child element. -// Get a pointer to that box. -// Note that now that the <scrollbox> is just a regular box -// with 'overflow:hidden', the boxobject's frame is an nsXULScrollFrame, -// the <scrollbox>'s box frame is the scrollframe's "scrolled frame", and -// the <scrollbox>'s child box is a child of that. -static nsIFrame* GetScrolledBox(nsBoxObject* aScrollBox) { - nsIFrame* frame = aScrollBox->GetFrame(false); - if (!frame) - return nullptr; - nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); - if (!scrollFrame) { - NS_WARNING("nsIScrollBoxObject attached to something that's not a scroll frame!"); - return nullptr; - } - nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame(); - if (!scrolledFrame) - return nullptr; - return scrolledFrame->GetChildBox(); -} - -/* void scrollByIndex (in long dindexes); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollByIndex(int32_t dindexes) -{ - nsIScrollableFrame* sf = GetScrollFrame(); - if (!sf) - return NS_ERROR_FAILURE; - nsIFrame* scrolledBox = GetScrolledBox(this); - if (!scrolledBox) - return NS_ERROR_FAILURE; - - nsRect rect; - - // now get the scrolled boxes first child. - nsIFrame* child = scrolledBox->GetChildBox(); - - bool horiz = scrolledBox->IsHorizontal(); - nsPoint cp = sf->GetScrollPosition(); - nscoord diff = 0; - int32_t curIndex = 0; - bool isLTR = scrolledBox->IsNormalDirection(); - - int32_t frameWidth = 0; - if (!isLTR && horiz) { - GetWidth(&frameWidth); - nsCOMPtr<nsIPresShell> shell = GetPresShell(false); - if (!shell) { - return NS_ERROR_UNEXPECTED; - } - frameWidth = nsPresContext::CSSPixelsToAppUnits(frameWidth); - } - - // first find out what index we are currently at - while(child) { - rect = child->GetRect(); - if (horiz) { - // In the left-to-right case we break from the loop when the center of - // the current child rect is greater than the scrolled position of - // the left edge of the scrollbox - // In the right-to-left case we break when the center of the current - // child rect is less than the scrolled position of the right edge of - // the scrollbox. - diff = rect.x + rect.width/2; // use the center, to avoid rounding errors - if ((isLTR && diff > cp.x) || - (!isLTR && diff < cp.x + frameWidth)) { - break; - } - } else { - diff = rect.y + rect.height/2;// use the center, to avoid rounding errors - if (diff > cp.y) { - break; - } - } - child = child->GetNextBox(); - curIndex++; - } - - int32_t count = 0; - - if (dindexes == 0) - return NS_OK; - - if (dindexes > 0) { - while(child) { - child = child->GetNextBox(); - if (child) - rect = child->GetRect(); - count++; - if (count >= dindexes) - break; - } - - } else if (dindexes < 0) { - child = scrolledBox->GetChildBox(); - while(child) { - rect = child->GetRect(); - if (count >= curIndex + dindexes) - break; - - count++; - child = child->GetNextBox(); - - } - } - - nscoord csspixel = nsPresContext::CSSPixelsToAppUnits(1); - if (horiz) { - // In the left-to-right case we scroll so that the left edge of the - // selected child is scrolled to the left edge of the scrollbox. - // In the right-to-left case we scroll so that the right edge of the - // selected child is scrolled to the right edge of the scrollbox. - - nsPoint pt(isLTR ? rect.x : rect.x + rect.width - frameWidth, - cp.y); - - // Use a destination range that ensures the left edge (or right edge, - // for RTL) will indeed be visible. Also ensure that the top edge - // is visible. - nsRect range(pt.x, pt.y, csspixel, 0); - if (isLTR) { - range.x -= csspixel; - } - sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range); - } else { - // Use a destination range that ensures the top edge will be visible. - nsRect range(cp.x, rect.y - csspixel, 0, csspixel); - sf->ScrollTo(nsPoint(cp.x, rect.y), nsIScrollableFrame::INSTANT, &range); - } - - return NS_OK; -} - -/* void scrollToLine (in long line); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollToLine(int32_t line) -{ - nsIScrollableFrame* sf = GetScrollFrame(); - if (!sf) - return NS_ERROR_FAILURE; - - nscoord y = sf->GetLineScrollAmount().height * line; - nsRect range(0, y - nsPresContext::CSSPixelsToAppUnits(1), - 0, nsPresContext::CSSPixelsToAppUnits(1)); - sf->ScrollTo(nsPoint(0, y), nsIScrollableFrame::INSTANT, &range); - return NS_OK; -} - -/* void scrollToElement (in nsIDOMElement child); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child) -{ - NS_ENSURE_ARG_POINTER(child); - - nsCOMPtr<nsIPresShell> shell = GetPresShell(false); - if (!shell) { - return NS_ERROR_UNEXPECTED; - } - - nsCOMPtr<nsIContent> content = do_QueryInterface(child); - shell->ScrollContentIntoView(content, - nsIPresShell::ScrollAxis( - nsIPresShell::SCROLL_TOP, - nsIPresShell::SCROLL_ALWAYS), - nsIPresShell::ScrollAxis( - nsIPresShell::SCROLL_LEFT, - nsIPresShell::SCROLL_ALWAYS), - nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY | - nsIPresShell::SCROLL_OVERFLOW_HIDDEN); - return NS_OK; -} - -/* void scrollToIndex (in long index); */ -NS_IMETHODIMP nsScrollBoxObject::ScrollToIndex(int32_t index) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* void getPosition (out long x, out long y); */ -NS_IMETHODIMP nsScrollBoxObject::GetPosition(int32_t *x, int32_t *y) -{ - nsIScrollableFrame* sf = GetScrollFrame(); - if (!sf) - return NS_ERROR_FAILURE; - - nsIntPoint pt = sf->GetScrollPositionCSSPixels(); - *x = pt.x; - *y = pt.y; - - return NS_OK; -} - -/* void getScrolledSize (out long width, out long height); */ -NS_IMETHODIMP nsScrollBoxObject::GetScrolledSize(int32_t *width, int32_t *height) -{ - nsIFrame* scrolledBox = GetScrolledBox(this); - if (!scrolledBox) - return NS_ERROR_FAILURE; - - nsRect scrollRect = scrolledBox->GetRect(); - - *width = nsPresContext::AppUnitsToIntCSSPixels(scrollRect.width); - *height = nsPresContext::AppUnitsToIntCSSPixels(scrollRect.height); - - return NS_OK; -} - -/* void ensureElementIsVisible (in nsIDOMElement child); */ -NS_IMETHODIMP nsScrollBoxObject::EnsureElementIsVisible(nsIDOMElement *child) -{ - NS_ENSURE_ARG_POINTER(child); - - nsCOMPtr<nsIPresShell> shell = GetPresShell(false); - if (!shell) { - return NS_ERROR_UNEXPECTED; - } - - nsCOMPtr<nsIContent> content = do_QueryInterface(child); - shell->ScrollContentIntoView(content, - nsIPresShell::ScrollAxis(), - nsIPresShell::ScrollAxis(), - nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY | - nsIPresShell::SCROLL_OVERFLOW_HIDDEN); - return NS_OK; -} - -/* void ensureIndexIsVisible (in long index); */ -NS_IMETHODIMP nsScrollBoxObject::EnsureIndexIsVisible(int32_t index) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* void ensureLineIsVisible (in long line); */ -NS_IMETHODIMP nsScrollBoxObject::EnsureLineIsVisible(int32_t line) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -NS_NewScrollBoxObject(nsIBoxObject** aResult) -{ - *aResult = new nsScrollBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; -} - diff --git a/layout/xul/base/src/nsScrollbarFrame.cpp b/layout/xul/base/src/nsScrollbarFrame.cpp deleted file mode 100644 index ae8c52875..000000000 --- a/layout/xul/base/src/nsScrollbarFrame.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -*- 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/. */ - -// -// Eric Vaughan -// Netscape Communications -// -// See documentation in associated header file -// - -#include "nsScrollbarFrame.h" -#include "nsScrollbarButtonFrame.h" -#include "nsGkAtoms.h" -#include "nsIScrollableFrame.h" -#include "nsIScrollbarMediator.h" -#include "mozilla/LookAndFeel.h" -#include "nsThemeConstants.h" -#include "nsRenderingContext.h" - -using namespace mozilla; - -// -// NS_NewScrollbarFrame -// -// Creates a new scrollbar frame and returns it -// -nsIFrame* -NS_NewScrollbarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) -{ - return new (aPresShell) nsScrollbarFrame (aPresShell, aContext); -} - -NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarFrame) - -NS_QUERYFRAME_HEAD(nsScrollbarFrame) - NS_QUERYFRAME_ENTRY(nsScrollbarFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) - -void -nsScrollbarFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) -{ - nsBoxFrame::Init(aContent, aParent, aPrevInFlow); - - // We want to be a reflow root since we use reflows to move the - // slider. Any reflow inside the scrollbar frame will be a reflow to - // move the slider and will thus not change anything outside of the - // scrollbar or change the size of the scrollbar frame. - mState |= NS_FRAME_REFLOW_ROOT; -} - -NS_IMETHODIMP -nsScrollbarFrame::Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) -{ - nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - NS_ENSURE_SUCCESS(rv, rv); - - // nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our - // desired size agrees. - if (aReflowState.availableWidth == 0) { - aDesiredSize.width = 0; - } - if (aReflowState.availableHeight == 0) { - aDesiredSize.height = 0; - } - - return NS_OK; -} - -nsIAtom* -nsScrollbarFrame::GetType() const -{ - return nsGkAtoms::scrollbarFrame; -} - -NS_IMETHODIMP -nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) -{ - nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, - aModType); - - // if the current position changes, notify any nsGfxScrollFrame - // parent we may have - if (aAttribute != nsGkAtoms::curpos) - return rv; - - nsIScrollableFrame* scrollable = do_QueryFrame(GetParent()); - if (!scrollable) - return rv; - - nsCOMPtr<nsIContent> kungFuDeathGrip(mContent); - scrollable->CurPosAttributeChanged(mContent); - return rv; -} - -NS_IMETHODIMP -nsScrollbarFrame::HandlePress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsScrollbarFrame::HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus, - bool aControlHeld) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsScrollbarFrame::HandleDrag(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsScrollbarFrame::HandleRelease(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) -{ - return NS_OK; -} - -void -nsScrollbarFrame::SetScrollbarMediatorContent(nsIContent* aMediator) -{ - mScrollbarMediator = aMediator; -} - -nsIScrollbarMediator* -nsScrollbarFrame::GetScrollbarMediator() -{ - if (!mScrollbarMediator) - return nullptr; - nsIFrame* f = mScrollbarMediator->GetPrimaryFrame(); - - // check if the frame is a scroll frame. If so, get the scrollable frame - // inside it. - nsIScrollableFrame* scrollFrame = do_QueryFrame(f); - if (scrollFrame) { - f = scrollFrame->GetScrolledFrame(); - } - - nsIScrollbarMediator* sbm = do_QueryFrame(f); - return sbm; -} - -NS_IMETHODIMP -nsScrollbarFrame::GetMargin(nsMargin& aMargin) -{ - aMargin.SizeTo(0,0,0,0); - - if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { - nsPresContext* presContext = PresContext(); - nsITheme* theme = presContext->GetTheme(); - if (theme) { - nsIntSize size; - bool isOverridable; - nsRefPtr<nsRenderingContext> rc = - presContext->PresShell()->GetReferenceRenderingContext(); - theme->GetMinimumWidgetSize(rc, this, NS_THEME_SCROLLBAR, &size, - &isOverridable); - if (IsHorizontal()) { - aMargin.top = -presContext->DevPixelsToAppUnits(size.height); - } - else { - if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { - aMargin.right = -presContext->DevPixelsToAppUnits(size.width); - } - else { - aMargin.left = -presContext->DevPixelsToAppUnits(size.width); - } - } - return NS_OK; - } - } - - return nsBox::GetMargin(aMargin); -} diff --git a/layout/xul/base/src/nsScrollbarFrame.h b/layout/xul/base/src/nsScrollbarFrame.h deleted file mode 100644 index 1942f6e19..000000000 --- a/layout/xul/base/src/nsScrollbarFrame.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- 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/. */ - -// -// nsScrollbarFrame -// - -#ifndef nsScrollbarFrame_h__ -#define nsScrollbarFrame_h__ - -#include "mozilla/Attributes.h" -#include "nsBoxFrame.h" - -class nsIScrollbarMediator; - -nsIFrame* NS_NewScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - -class nsScrollbarFrame : public nsBoxFrame -{ -public: - nsScrollbarFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext), mScrollbarMediator(nullptr) {} - - NS_DECL_QUERYFRAME_TARGET(nsScrollbarFrame) - -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { - return MakeFrameName(NS_LITERAL_STRING("ScrollbarFrame"), aResult); - } -#endif - - // nsIFrame overrides - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; - - NS_DECL_QUERYFRAME - NS_DECL_FRAMEARENA_HELPERS - - NS_IMETHOD HandlePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus, - bool aControlHeld) MOZ_OVERRIDE; - - NS_IMETHOD HandleDrag(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD HandleRelease(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - - NS_IMETHOD Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) MOZ_OVERRIDE; - - virtual nsIAtom* GetType() const MOZ_OVERRIDE; - - void SetScrollbarMediatorContent(nsIContent* aMediator); - nsIScrollbarMediator* GetScrollbarMediator(); - - // nsBox methods - - /** - * Treat scrollbars as clipping their children; overflowing children - * will not be allowed to set an overflow rect on this - * frame. This means that when the scroll code decides to hide a - * scrollframe by setting its height or width to zero, that will - * hide the children too. - */ - virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; } - - NS_IMETHOD GetMargin(nsMargin& aMargin) MOZ_OVERRIDE; - -private: - nsCOMPtr<nsIContent> mScrollbarMediator; -}; // class nsScrollbarFrame - -#endif diff --git a/layout/xul/base/src/nsSplitterFrame.h b/layout/xul/base/src/nsSplitterFrame.h deleted file mode 100644 index c2bb828b1..000000000 --- a/layout/xul/base/src/nsSplitterFrame.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- 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/. */ - -// -// nsSplitterFrame -// - -#ifndef nsSplitterFrame_h__ -#define nsSplitterFrame_h__ - - -#include "mozilla/Attributes.h" -#include "nsBoxFrame.h" - -class nsSplitterFrameInner; - -nsIFrame* NS_NewSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - -class nsSplitterFrame : public nsBoxFrame -{ -public: - NS_DECL_FRAMEARENA_HELPERS - - nsSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { - return MakeFrameName(NS_LITERAL_STRING("SplitterFrame"), aResult); - } -#endif - - // nsIFrame overrides - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; - - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - - NS_IMETHOD GetCursor(const nsPoint& aPoint, - nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; - - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - - NS_IMETHOD HandlePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus, - bool aControlHeld) MOZ_OVERRIDE; - - NS_IMETHOD HandleDrag(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD HandleRelease(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; - - virtual void GetInitialOrientation(bool& aIsHorizontal) MOZ_OVERRIDE; - -private: - - friend class nsSplitterFrameInner; - nsSplitterFrameInner* mInner; - -}; // class nsSplitterFrame - -#endif diff --git a/layout/xul/base/test/Makefile.in b/layout/xul/base/test/Makefile.in deleted file mode 100644 index c9fe036a8..000000000 --- a/layout/xul/base/test/Makefile.in +++ /dev/null @@ -1,30 +0,0 @@ -# -# 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/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ -relativesrcdir = @relativesrcdir@ - -include $(DEPTH)/config/autoconf.mk - -MOCHITEST_FILES = test_bug511075.html \ - test_splitter.xul \ - test_resizer_incontent.xul \ - $(NULL) - -MOCHITEST_CHROME_FILES = test_bug381167.xhtml \ - test_bug393970.xul \ - test_bug477754.xul \ - test_popupSizeTo.xul \ - test_stack.xul \ - test_resizer.xul \ - window_resizer.xul \ - window_resizer_element.xul \ - test_windowminmaxsize.xul \ - $(NULL) - -include $(topsrcdir)/config/rules.mk diff --git a/layout/xul/base/test/moz.build b/layout/xul/base/test/moz.build deleted file mode 100644 index 895d11993..000000000 --- a/layout/xul/base/test/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; 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/. - diff --git a/layout/xul/base/src/crashtests/131008-1.xul b/layout/xul/crashtests/131008-1.xul index d505f8696..d505f8696 100644 --- a/layout/xul/base/src/crashtests/131008-1.xul +++ b/layout/xul/crashtests/131008-1.xul diff --git a/layout/xul/base/src/crashtests/137216-1.xul b/layout/xul/crashtests/137216-1.xul index a3fc043c8..a3fc043c8 100644 --- a/layout/xul/base/src/crashtests/137216-1.xul +++ b/layout/xul/crashtests/137216-1.xul diff --git a/layout/xul/base/src/crashtests/140218-1.xml b/layout/xul/crashtests/140218-1.xml index 311afc218..311afc218 100644 --- a/layout/xul/base/src/crashtests/140218-1.xml +++ b/layout/xul/crashtests/140218-1.xml diff --git a/layout/xul/base/src/crashtests/151826-1.xul b/layout/xul/crashtests/151826-1.xul index 1115dae72..1115dae72 100644 --- a/layout/xul/base/src/crashtests/151826-1.xul +++ b/layout/xul/crashtests/151826-1.xul diff --git a/layout/xul/base/src/crashtests/168724-1.xul b/layout/xul/crashtests/168724-1.xul index 8456406c2..8456406c2 100644 --- a/layout/xul/base/src/crashtests/168724-1.xul +++ b/layout/xul/crashtests/168724-1.xul diff --git a/layout/xul/base/src/crashtests/189814-1.xul b/layout/xul/crashtests/189814-1.xul index 79462348c..79462348c 100644 --- a/layout/xul/base/src/crashtests/189814-1.xul +++ b/layout/xul/crashtests/189814-1.xul diff --git a/layout/xul/base/src/crashtests/237787-1.xul b/layout/xul/crashtests/237787-1.xul index 96cebca9f..96cebca9f 100644 --- a/layout/xul/base/src/crashtests/237787-1.xul +++ b/layout/xul/crashtests/237787-1.xul diff --git a/layout/xul/base/src/crashtests/265161-1.xul b/layout/xul/crashtests/265161-1.xul index 75a995790..75a995790 100644 --- a/layout/xul/base/src/crashtests/265161-1.xul +++ b/layout/xul/crashtests/265161-1.xul diff --git a/layout/xul/base/src/crashtests/289410-1.xul b/layout/xul/crashtests/289410-1.xul index 0de792f2c..0de792f2c 100644 --- a/layout/xul/base/src/crashtests/289410-1.xul +++ b/layout/xul/crashtests/289410-1.xul diff --git a/layout/xul/crashtests/290743.html b/layout/xul/crashtests/290743.html new file mode 100644 index 000000000..fd273d8bf --- /dev/null +++ b/layout/xul/crashtests/290743.html @@ -0,0 +1,6 @@ +<html>
+<head><title>Testcase bug 290743 - This display:-moz-grid testcase freezes Mozilla</title></head>
+<body style="display:-moz-grid;">
+<input type="radio"><input type="radio">
+</body>
+</html>
\ No newline at end of file diff --git a/layout/xul/base/src/crashtests/291702-1.xul b/layout/xul/crashtests/291702-1.xul index 4c052630d..4c052630d 100644 --- a/layout/xul/base/src/crashtests/291702-1.xul +++ b/layout/xul/crashtests/291702-1.xul diff --git a/layout/xul/base/src/crashtests/291702-2.xul b/layout/xul/crashtests/291702-2.xul index 53d8a51f7..53d8a51f7 100644 --- a/layout/xul/base/src/crashtests/291702-2.xul +++ b/layout/xul/crashtests/291702-2.xul diff --git a/layout/xul/base/src/crashtests/291702-3.xul b/layout/xul/crashtests/291702-3.xul index b34404f36..b34404f36 100644 --- a/layout/xul/base/src/crashtests/291702-3.xul +++ b/layout/xul/crashtests/291702-3.xul diff --git a/layout/xul/base/src/crashtests/294371-1.xul b/layout/xul/crashtests/294371-1.xul index ca5b54914..ca5b54914 100644 --- a/layout/xul/base/src/crashtests/294371-1.xul +++ b/layout/xul/crashtests/294371-1.xul diff --git a/layout/xul/base/src/crashtests/311457-1.html b/layout/xul/crashtests/311457-1.html index e5b6ecdd6..e5b6ecdd6 100644 --- a/layout/xul/base/src/crashtests/311457-1.html +++ b/layout/xul/crashtests/311457-1.html diff --git a/layout/xul/base/src/crashtests/321056-1.xhtml b/layout/xul/crashtests/321056-1.xhtml index a7ba11793..a7ba11793 100644 --- a/layout/xul/base/src/crashtests/321056-1.xhtml +++ b/layout/xul/crashtests/321056-1.xhtml diff --git a/layout/xul/base/src/crashtests/322786-1.xul b/layout/xul/crashtests/322786-1.xul index 79bb092c4..79bb092c4 100644 --- a/layout/xul/base/src/crashtests/322786-1.xul +++ b/layout/xul/crashtests/322786-1.xul diff --git a/layout/xul/base/src/crashtests/325377.xul b/layout/xul/crashtests/325377.xul index 8ea30473d..8ea30473d 100644 --- a/layout/xul/base/src/crashtests/325377.xul +++ b/layout/xul/crashtests/325377.xul diff --git a/layout/xul/base/src/crashtests/326834-1-inner.xul b/layout/xul/crashtests/326834-1-inner.xul index 0fbdca7ab..0fbdca7ab 100644 --- a/layout/xul/base/src/crashtests/326834-1-inner.xul +++ b/layout/xul/crashtests/326834-1-inner.xul diff --git a/layout/xul/base/src/crashtests/326834-1.html b/layout/xul/crashtests/326834-1.html index ca531caa6..ca531caa6 100644 --- a/layout/xul/base/src/crashtests/326834-1.html +++ b/layout/xul/crashtests/326834-1.html diff --git a/layout/xul/base/src/crashtests/326879-1.xul b/layout/xul/crashtests/326879-1.xul index 84d74c30c..84d74c30c 100644 --- a/layout/xul/base/src/crashtests/326879-1.xul +++ b/layout/xul/crashtests/326879-1.xul diff --git a/layout/xul/base/src/crashtests/327776-1.xul b/layout/xul/crashtests/327776-1.xul index af889493c..af889493c 100644 --- a/layout/xul/base/src/crashtests/327776-1.xul +++ b/layout/xul/crashtests/327776-1.xul diff --git a/layout/xul/base/src/crashtests/328135-1.xul b/layout/xul/crashtests/328135-1.xul index 77a467909..77a467909 100644 --- a/layout/xul/base/src/crashtests/328135-1.xul +++ b/layout/xul/crashtests/328135-1.xul diff --git a/layout/xul/base/src/crashtests/329327-1.xul b/layout/xul/crashtests/329327-1.xul index fcfed07c4..fcfed07c4 100644 --- a/layout/xul/base/src/crashtests/329327-1.xul +++ b/layout/xul/crashtests/329327-1.xul diff --git a/layout/xul/base/src/crashtests/329407-1.xml b/layout/xul/crashtests/329407-1.xml index 0d41c0185..0d41c0185 100644 --- a/layout/xul/base/src/crashtests/329407-1.xml +++ b/layout/xul/crashtests/329407-1.xml diff --git a/layout/xul/base/src/crashtests/329477-1.xhtml b/layout/xul/crashtests/329477-1.xhtml index fcbd3da87..fcbd3da87 100644 --- a/layout/xul/base/src/crashtests/329477-1.xhtml +++ b/layout/xul/crashtests/329477-1.xhtml diff --git a/layout/xul/base/src/crashtests/336962-1.xul b/layout/xul/crashtests/336962-1.xul index 5ad4ad22b..5ad4ad22b 100644 --- a/layout/xul/base/src/crashtests/336962-1.xul +++ b/layout/xul/crashtests/336962-1.xul diff --git a/layout/xul/base/src/crashtests/344228-1.xul b/layout/xul/crashtests/344228-1.xul index d6015707b..d6015707b 100644 --- a/layout/xul/base/src/crashtests/344228-1.xul +++ b/layout/xul/crashtests/344228-1.xul diff --git a/layout/xul/base/src/crashtests/346083-1.xul b/layout/xul/crashtests/346083-1.xul index e04d610a4..e04d610a4 100644 --- a/layout/xul/base/src/crashtests/346083-1.xul +++ b/layout/xul/crashtests/346083-1.xul diff --git a/layout/xul/base/src/crashtests/346281-1.xul b/layout/xul/crashtests/346281-1.xul index 4ef670155..4ef670155 100644 --- a/layout/xul/base/src/crashtests/346281-1.xul +++ b/layout/xul/crashtests/346281-1.xul diff --git a/layout/xul/base/src/crashtests/350460.xul b/layout/xul/crashtests/350460.xul index b13de6c97..b13de6c97 100644 --- a/layout/xul/base/src/crashtests/350460.xul +++ b/layout/xul/crashtests/350460.xul diff --git a/layout/xul/base/src/crashtests/360642-1.xul b/layout/xul/crashtests/360642-1.xul index 5e37020a5..5e37020a5 100644 --- a/layout/xul/base/src/crashtests/360642-1.xul +++ b/layout/xul/crashtests/360642-1.xul diff --git a/layout/xul/base/src/crashtests/365151.xul b/layout/xul/crashtests/365151.xul index 074c8d398..074c8d398 100644 --- a/layout/xul/base/src/crashtests/365151.xul +++ b/layout/xul/crashtests/365151.xul diff --git a/layout/xul/base/src/crashtests/366112-1.xul b/layout/xul/crashtests/366112-1.xul index 4a03ea2cf..4a03ea2cf 100644 --- a/layout/xul/base/src/crashtests/366112-1.xul +++ b/layout/xul/crashtests/366112-1.xul diff --git a/layout/xul/base/src/crashtests/369942-1.xhtml b/layout/xul/crashtests/369942-1.xhtml index a05705843..a05705843 100644 --- a/layout/xul/base/src/crashtests/369942-1.xhtml +++ b/layout/xul/crashtests/369942-1.xhtml diff --git a/layout/xul/base/src/crashtests/374102-1.xul b/layout/xul/crashtests/374102-1.xul index 7e85f0d21..7e85f0d21 100644 --- a/layout/xul/base/src/crashtests/374102-1.xul +++ b/layout/xul/crashtests/374102-1.xul diff --git a/layout/xul/base/src/crashtests/376137-1.html b/layout/xul/crashtests/376137-1.html index 23b39d900..23b39d900 100644 --- a/layout/xul/base/src/crashtests/376137-1.html +++ b/layout/xul/crashtests/376137-1.html diff --git a/layout/xul/base/src/crashtests/376137-2.html b/layout/xul/crashtests/376137-2.html index 160c61ed3..160c61ed3 100644 --- a/layout/xul/base/src/crashtests/376137-2.html +++ b/layout/xul/crashtests/376137-2.html diff --git a/layout/xul/base/src/crashtests/377592-1.svg b/layout/xul/crashtests/377592-1.svg index 7371708f2..7371708f2 100644 --- a/layout/xul/base/src/crashtests/377592-1.svg +++ b/layout/xul/crashtests/377592-1.svg diff --git a/layout/xul/crashtests/378961.html b/layout/xul/crashtests/378961.html new file mode 100644 index 000000000..b4da857ff --- /dev/null +++ b/layout/xul/crashtests/378961.html @@ -0,0 +1,9 @@ +<html>
+<head>
+<title>Testcase bug 378961 - Crash [@ nsSplitterFrameInner::RemoveListener] when dragging splitter and DOMAttrModified event removing window</title>
+</head>
+<body>
+<iframe src="data:application/vnd.mozilla.xul+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3C%3Fxml-stylesheet%20href%3D%22chrome%3A//global/skin%22%20type%3D%22text/css%22%3F%3E%0A%3Cwindow%20xmlns%3D%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%20orient%3D%22horizontal%22%3E%0A%3Ctextbox/%3E%3Csplitter/%3E%3Cbox/%3E%0A%0A%3Cscript%20xmlns%3D%22http%3A//www.w3.org/1999/xhtml%22%3E%0Afunction%20doe%28%29%20%7B%0Awindow.frameElement.parentNode.removeChild%28window.frameElement%29%3B%0A%7D%0Adocument.addEventListener%28%27DOMAttrModified%27%2C%20doe%2C%20true%29%3B%0A%3C/script%3E%0A%3C/window%3E" style="width: 500px;height:200px;"></iframe>
+
+</body>
+</html>
diff --git a/layout/xul/base/src/crashtests/381862.html b/layout/xul/crashtests/381862.html index e26fa357e..e26fa357e 100644 --- a/layout/xul/base/src/crashtests/381862.html +++ b/layout/xul/crashtests/381862.html diff --git a/layout/xul/base/src/crashtests/382746-1.xul b/layout/xul/crashtests/382746-1.xul index 9bb14f24f..9bb14f24f 100644 --- a/layout/xul/base/src/crashtests/382746-1.xul +++ b/layout/xul/crashtests/382746-1.xul diff --git a/layout/xul/base/src/crashtests/382899-1.xul b/layout/xul/crashtests/382899-1.xul index 7dab931f7..7dab931f7 100644 --- a/layout/xul/base/src/crashtests/382899-1.xul +++ b/layout/xul/crashtests/382899-1.xul diff --git a/layout/xul/base/src/crashtests/383236-1.xul b/layout/xul/crashtests/383236-1.xul index 244df65f1..244df65f1 100644 --- a/layout/xul/base/src/crashtests/383236-1.xul +++ b/layout/xul/crashtests/383236-1.xul diff --git a/layout/xul/base/src/crashtests/384037-1.xhtml b/layout/xul/crashtests/384037-1.xhtml index 04bac671c..04bac671c 100644 --- a/layout/xul/base/src/crashtests/384037-1.xhtml +++ b/layout/xul/crashtests/384037-1.xhtml diff --git a/layout/xul/base/src/crashtests/384105-1-inner.xul b/layout/xul/crashtests/384105-1-inner.xul index 4ea6e0391..4ea6e0391 100644 --- a/layout/xul/base/src/crashtests/384105-1-inner.xul +++ b/layout/xul/crashtests/384105-1-inner.xul diff --git a/layout/xul/base/src/crashtests/384105-1.html b/layout/xul/crashtests/384105-1.html index fe468a906..fe468a906 100644 --- a/layout/xul/base/src/crashtests/384105-1.html +++ b/layout/xul/crashtests/384105-1.html diff --git a/layout/xul/crashtests/384373-1.xul b/layout/xul/crashtests/384373-1.xul new file mode 100644 index 000000000..603b53cde --- /dev/null +++ b/layout/xul/crashtests/384373-1.xul @@ -0,0 +1,10 @@ +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+onerror="var x=document.getElementsByTagName('*');x[Math.floor(Math.random()*x.length)].focus()"
+onblur="event.originalTarget.parentNode.parentNode.removeChild(event.originalTarget.parentNode)">
+<script xmlns="http://www.w3.org/1999/xhtml">setTimeout(function() {window.location.reload()}, 200);</script>
+
+<broadcasterset style="display: block;">
+ <broadcaster style="display: block;"></broadcaster>
+</broadcasterset>
+<preferences></preferences>
+</window>
\ No newline at end of file diff --git a/layout/xul/crashtests/384373-2.xul b/layout/xul/crashtests/384373-2.xul new file mode 100644 index 000000000..1d56394e3 --- /dev/null +++ b/layout/xul/crashtests/384373-2.xul @@ -0,0 +1,4 @@ +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onerror="document.getElementsByTagName('*')[1].focus()" onfocus="event.target.parentNode.removeChild(event.target)">
+<broadcaster style="display: block;"/>
+<preferences/>
+</window>
\ No newline at end of file diff --git a/layout/xul/crashtests/384373.html b/layout/xul/crashtests/384373.html new file mode 100644 index 000000000..c3bc92f16 --- /dev/null +++ b/layout/xul/crashtests/384373.html @@ -0,0 +1,23 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"><head> + <meta charset="utf-8"> + <title>Testcase for bug 384373</title> +<script> +function reload() { + this.location.reload(); +} +// Run the test for 1 second +setTimeout(function() { + document.body.getBoundingClientRect(); + document.documentElement.removeChild(document.body); + document.documentElement.className = ""; + }, 2000); +</script> +</head> +<body onload="document.body.getBoundingClientRect()"> + +<iframe src="384373-1.xul"></iframe> +<iframe onload="this.contentWindow.setTimeout(reload,500)" src="384373-2.xul"></iframe> + +</body> +</html> diff --git a/layout/xul/base/src/crashtests/384491-1.xhtml b/layout/xul/crashtests/384491-1.xhtml index 2eb065f8d..2eb065f8d 100644 --- a/layout/xul/base/src/crashtests/384491-1.xhtml +++ b/layout/xul/crashtests/384491-1.xhtml diff --git a/layout/xul/base/src/crashtests/384871-1-inner.xul b/layout/xul/crashtests/384871-1-inner.xul index 62efdb260..62efdb260 100644 --- a/layout/xul/base/src/crashtests/384871-1-inner.xul +++ b/layout/xul/crashtests/384871-1-inner.xul diff --git a/layout/xul/base/src/crashtests/384871-1.html b/layout/xul/crashtests/384871-1.html index 6bb2a9e07..6bb2a9e07 100644 --- a/layout/xul/base/src/crashtests/384871-1.html +++ b/layout/xul/crashtests/384871-1.html diff --git a/layout/xul/crashtests/386642.xul b/layout/xul/crashtests/386642.xul new file mode 100644 index 000000000..50db21a09 --- /dev/null +++ b/layout/xul/crashtests/386642.xul @@ -0,0 +1,31 @@ +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Bug 386642 Crash [@ IsCanvasFrame] while opening context menu or changing styles"> +<toolbarbutton type="menu" id="a"> +<menupopup id="b"/> +</toolbarbutton> + +<style xmlns="http://www.w3.org/1999/xhtml"> +.one image { +display: -moz-box; +} +image{ +display: none; +} + +</style> +<script><![CDATA[ +var gg=0; +function doe() { + var a = document.getElementById('a'); + if (!a.hasAttribute('class')) { + a.setAttribute('class', 'one'); + } else { + a.removeAttribute('class'); + } +document.getElementById('b').hidePopup(); +} + +doe(); +setInterval(doe, 200); +]]></script> +</window> diff --git a/layout/xul/base/src/crashtests/387033-1.xhtml b/layout/xul/crashtests/387033-1.xhtml index 58325b1a7..58325b1a7 100644 --- a/layout/xul/base/src/crashtests/387033-1.xhtml +++ b/layout/xul/crashtests/387033-1.xhtml diff --git a/layout/xul/base/src/crashtests/387080-1.xul b/layout/xul/crashtests/387080-1.xul index 4eb9bd784..4eb9bd784 100644 --- a/layout/xul/base/src/crashtests/387080-1.xul +++ b/layout/xul/crashtests/387080-1.xul diff --git a/layout/xul/base/src/crashtests/391974-1-inner.xul b/layout/xul/crashtests/391974-1-inner.xul index f13aa2110..f13aa2110 100644 --- a/layout/xul/base/src/crashtests/391974-1-inner.xul +++ b/layout/xul/crashtests/391974-1-inner.xul diff --git a/layout/xul/base/src/crashtests/391974-1.html b/layout/xul/crashtests/391974-1.html index c72a1a73c..c72a1a73c 100644 --- a/layout/xul/base/src/crashtests/391974-1.html +++ b/layout/xul/crashtests/391974-1.html diff --git a/layout/xul/base/src/crashtests/394120-1.xhtml b/layout/xul/crashtests/394120-1.xhtml index 9df447862..9df447862 100644 --- a/layout/xul/base/src/crashtests/394120-1.xhtml +++ b/layout/xul/crashtests/394120-1.xhtml diff --git a/layout/xul/base/src/crashtests/397293.xhtml b/layout/xul/crashtests/397293.xhtml index cfd181921..cfd181921 100644 --- a/layout/xul/base/src/crashtests/397293.xhtml +++ b/layout/xul/crashtests/397293.xhtml diff --git a/layout/xul/base/src/crashtests/397304-1.html b/layout/xul/crashtests/397304-1.html index 3501f0581..3501f0581 100644 --- a/layout/xul/base/src/crashtests/397304-1.html +++ b/layout/xul/crashtests/397304-1.html diff --git a/layout/xul/base/src/crashtests/398326-1.xhtml b/layout/xul/crashtests/398326-1.xhtml index a265ae4e0..a265ae4e0 100644 --- a/layout/xul/base/src/crashtests/398326-1.xhtml +++ b/layout/xul/crashtests/398326-1.xhtml diff --git a/layout/xul/base/src/crashtests/399013.xul b/layout/xul/crashtests/399013.xul index a2349aff8..a2349aff8 100644 --- a/layout/xul/base/src/crashtests/399013.xul +++ b/layout/xul/crashtests/399013.xul diff --git a/layout/xul/base/src/crashtests/400779-1.xhtml b/layout/xul/crashtests/400779-1.xhtml index c0f5d493c..c0f5d493c 100644 --- a/layout/xul/base/src/crashtests/400779-1.xhtml +++ b/layout/xul/crashtests/400779-1.xhtml diff --git a/layout/xul/base/src/crashtests/402912-1.xhtml b/layout/xul/crashtests/402912-1.xhtml index b2cb98dc5..b2cb98dc5 100644 --- a/layout/xul/base/src/crashtests/402912-1.xhtml +++ b/layout/xul/crashtests/402912-1.xhtml diff --git a/layout/xul/crashtests/404192.xhtml b/layout/xul/crashtests/404192.xhtml new file mode 100644 index 000000000..4ad5af348 --- /dev/null +++ b/layout/xul/crashtests/404192.xhtml @@ -0,0 +1,12 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="reftest-wait">
+<xul:titlebar id="a" style="overflow: auto;"/>
+
+<script>
+function doe() {
+document.getElementsByTagName('*')[1].focus();
+document.getElementsByTagName('*')[0].focus();
+document.documentElement.removeAttribute("class");
+}
+setTimeout(doe, 200);
+</script>
+</html>
diff --git a/layout/xul/crashtests/407152.xul b/layout/xul/crashtests/407152.xul new file mode 100644 index 000000000..0a5adf69e --- /dev/null +++ b/layout/xul/crashtests/407152.xul @@ -0,0 +1,7 @@ +<triple xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" style="display: block;"> +<box style="display: block; position: relative; -moz-binding: url(data:text/xml;charset=utf-8,%3Cbindings%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22%3E%0A%3Cbinding%20id%3D%22a%22%3E%0A%3Cimplementation%3E%0A%3Cfield%20name%3D%22_field%22%3Ethis.ownerDocument.getBoxObjectFor%28this.ownerDocument.documentElement%29%3B%3C/field%3E%0A%3C/implementation%3E%0A%3Ccontent%3E%0A%3C/binding%3E%0A%3C/bindings%3E);"> +<box style="position: fixed; -moz-binding: url(data:text/xml;charset=utf-8,%3Cbindings%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22%3E%0A%3Cbinding%20id%3D%22a%22%3E%0A%3Ccontent%3E%0A%3Cchildren%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22/%3E%3C/content%3E%3C/binding%3E%3C/bindings%3E);"/> +<iframe/> +</box> +<scrollbox onoverflow="document.documentElement.removeAttribute('style')"/> +</triple>
\ No newline at end of file diff --git a/layout/xul/base/src/crashtests/408904-1.xul b/layout/xul/crashtests/408904-1.xul index 59f215c73..59f215c73 100644 --- a/layout/xul/base/src/crashtests/408904-1.xul +++ b/layout/xul/crashtests/408904-1.xul diff --git a/layout/xul/base/src/crashtests/412479-1.xhtml b/layout/xul/crashtests/412479-1.xhtml index b1086a816..b1086a816 100644 --- a/layout/xul/base/src/crashtests/412479-1.xhtml +++ b/layout/xul/crashtests/412479-1.xhtml diff --git a/layout/xul/base/src/crashtests/415394-1.xhtml b/layout/xul/crashtests/415394-1.xhtml index 7dc24dc9f..7dc24dc9f 100644 --- a/layout/xul/base/src/crashtests/415394-1.xhtml +++ b/layout/xul/crashtests/415394-1.xhtml diff --git a/layout/xul/crashtests/417509.xul b/layout/xul/crashtests/417509.xul new file mode 100644 index 000000000..81703ada3 --- /dev/null +++ b/layout/xul/crashtests/417509.xul @@ -0,0 +1,7 @@ +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<span id="a" datasources="" xmlns="http://www.w3.org/1999/xhtml"/> +<script xmlns="http://www.w3.org/1999/xhtml"> +document.documentElement.appendChild(document.getElementById('a')); + +</script> +</window>
\ No newline at end of file diff --git a/layout/xul/base/src/crashtests/420424-1.xul b/layout/xul/crashtests/420424-1.xul index e60841706..e60841706 100644 --- a/layout/xul/base/src/crashtests/420424-1.xul +++ b/layout/xul/crashtests/420424-1.xul diff --git a/layout/xul/base/src/crashtests/430356-1.xhtml b/layout/xul/crashtests/430356-1.xhtml index 6e5717ae9..6e5717ae9 100644 --- a/layout/xul/base/src/crashtests/430356-1.xhtml +++ b/layout/xul/crashtests/430356-1.xhtml diff --git a/layout/xul/base/src/crashtests/431738.xhtml b/layout/xul/crashtests/431738.xhtml index 9ce917a3f..9ce917a3f 100644 --- a/layout/xul/base/src/crashtests/431738.xhtml +++ b/layout/xul/crashtests/431738.xhtml diff --git a/layout/xul/base/src/crashtests/432058-1.xul b/layout/xul/crashtests/432058-1.xul index a7f63adf8..a7f63adf8 100644 --- a/layout/xul/base/src/crashtests/432058-1.xul +++ b/layout/xul/crashtests/432058-1.xul diff --git a/layout/xul/base/src/crashtests/432068-1.xul b/layout/xul/crashtests/432068-1.xul index 02c3114e6..02c3114e6 100644 --- a/layout/xul/base/src/crashtests/432068-1.xul +++ b/layout/xul/crashtests/432068-1.xul diff --git a/layout/xul/base/src/crashtests/432068-2.xul b/layout/xul/crashtests/432068-2.xul index c75984bae..c75984bae 100644 --- a/layout/xul/base/src/crashtests/432068-2.xul +++ b/layout/xul/crashtests/432068-2.xul diff --git a/layout/xul/base/src/crashtests/433296-1.xul b/layout/xul/crashtests/433296-1.xul index 10fd0ec7b..10fd0ec7b 100644 --- a/layout/xul/base/src/crashtests/433296-1.xul +++ b/layout/xul/crashtests/433296-1.xul diff --git a/layout/xul/base/src/crashtests/433429.xul b/layout/xul/crashtests/433429.xul index a52bce68f..a52bce68f 100644 --- a/layout/xul/base/src/crashtests/433429.xul +++ b/layout/xul/crashtests/433429.xul diff --git a/layout/xul/base/src/crashtests/434458-1.xul b/layout/xul/crashtests/434458-1.xul index fbec2a413..fbec2a413 100644 --- a/layout/xul/base/src/crashtests/434458-1.xul +++ b/layout/xul/crashtests/434458-1.xul diff --git a/layout/xul/base/src/crashtests/452185.html b/layout/xul/crashtests/452185.html index d4981ffdf..d4981ffdf 100644 --- a/layout/xul/base/src/crashtests/452185.html +++ b/layout/xul/crashtests/452185.html diff --git a/layout/xul/base/src/crashtests/452185.xml b/layout/xul/crashtests/452185.xml index 655c43a8d..655c43a8d 100644 --- a/layout/xul/base/src/crashtests/452185.xml +++ b/layout/xul/crashtests/452185.xml diff --git a/layout/xul/base/src/crashtests/460900-1.xul b/layout/xul/crashtests/460900-1.xul index bff7c5c36..bff7c5c36 100644 --- a/layout/xul/base/src/crashtests/460900-1.xul +++ b/layout/xul/crashtests/460900-1.xul diff --git a/layout/xul/base/src/crashtests/464149-1.xul b/layout/xul/crashtests/464149-1.xul index 556656f02..556656f02 100644 --- a/layout/xul/base/src/crashtests/464149-1.xul +++ b/layout/xul/crashtests/464149-1.xul diff --git a/layout/xul/base/src/crashtests/464407-1.xhtml b/layout/xul/crashtests/464407-1.xhtml index 83666a6a4..83666a6a4 100644 --- a/layout/xul/base/src/crashtests/464407-1.xhtml +++ b/layout/xul/crashtests/464407-1.xhtml diff --git a/layout/xul/base/src/crashtests/467080.xul b/layout/xul/crashtests/467080.xul index bc579b0ee..bc579b0ee 100644 --- a/layout/xul/base/src/crashtests/467080.xul +++ b/layout/xul/crashtests/467080.xul diff --git a/layout/xul/base/src/crashtests/467481-1.xul b/layout/xul/crashtests/467481-1.xul index 56fbd4441..56fbd4441 100644 --- a/layout/xul/base/src/crashtests/467481-1.xul +++ b/layout/xul/crashtests/467481-1.xul diff --git a/layout/xul/base/src/crashtests/470063-1.html b/layout/xul/crashtests/470063-1.html index 11c01b30e..11c01b30e 100644 --- a/layout/xul/base/src/crashtests/470063-1.html +++ b/layout/xul/crashtests/470063-1.html diff --git a/layout/xul/base/src/crashtests/470272.html b/layout/xul/crashtests/470272.html index f23de269b..f23de269b 100644 --- a/layout/xul/base/src/crashtests/470272.html +++ b/layout/xul/crashtests/470272.html diff --git a/layout/xul/base/src/crashtests/472189.xul b/layout/xul/crashtests/472189.xul index e276d8fc7..e276d8fc7 100644 --- a/layout/xul/base/src/crashtests/472189.xul +++ b/layout/xul/crashtests/472189.xul diff --git a/layout/xul/base/src/crashtests/475133.html b/layout/xul/crashtests/475133.html index ea4ee6325..ea4ee6325 100644 --- a/layout/xul/base/src/crashtests/475133.html +++ b/layout/xul/crashtests/475133.html diff --git a/layout/xul/base/src/crashtests/488210-1.xhtml b/layout/xul/crashtests/488210-1.xhtml index 9c8e2640c..9c8e2640c 100644 --- a/layout/xul/base/src/crashtests/488210-1.xhtml +++ b/layout/xul/crashtests/488210-1.xhtml diff --git a/layout/xul/base/src/crashtests/495728-1.xul b/layout/xul/crashtests/495728-1.xul index ee8498d05..ee8498d05 100644 --- a/layout/xul/base/src/crashtests/495728-1.xul +++ b/layout/xul/crashtests/495728-1.xul diff --git a/layout/xul/base/src/crashtests/508927-1.xul b/layout/xul/crashtests/508927-1.xul index 98faff4a6..98faff4a6 100644 --- a/layout/xul/base/src/crashtests/508927-1.xul +++ b/layout/xul/crashtests/508927-1.xul diff --git a/layout/xul/base/src/crashtests/508927-2.xul b/layout/xul/crashtests/508927-2.xul index 5bf4f9a0c..5bf4f9a0c 100644 --- a/layout/xul/base/src/crashtests/508927-2.xul +++ b/layout/xul/crashtests/508927-2.xul diff --git a/layout/xul/base/src/crashtests/514300-1.xul b/layout/xul/crashtests/514300-1.xul index d0d655011..d0d655011 100644 --- a/layout/xul/base/src/crashtests/514300-1.xul +++ b/layout/xul/crashtests/514300-1.xul diff --git a/layout/xul/base/src/crashtests/536931-1.xhtml b/layout/xul/crashtests/536931-1.xhtml index 6f3fc1396..6f3fc1396 100644 --- a/layout/xul/base/src/crashtests/536931-1.xhtml +++ b/layout/xul/crashtests/536931-1.xhtml diff --git a/layout/xul/base/src/crashtests/538308-1.xul b/layout/xul/crashtests/538308-1.xul index a96f3fa4e..a96f3fa4e 100644 --- a/layout/xul/base/src/crashtests/538308-1.xul +++ b/layout/xul/crashtests/538308-1.xul diff --git a/layout/xul/base/src/crashtests/557174-1.xml b/layout/xul/crashtests/557174-1.xml index 02850a2db..02850a2db 100644 --- a/layout/xul/base/src/crashtests/557174-1.xml +++ b/layout/xul/crashtests/557174-1.xml diff --git a/layout/xul/base/src/crashtests/564705-1.xul b/layout/xul/crashtests/564705-1.xul index b0f29bef7..b0f29bef7 100644 --- a/layout/xul/base/src/crashtests/564705-1.xul +++ b/layout/xul/crashtests/564705-1.xul diff --git a/layout/xul/base/src/crashtests/583957-1.html b/layout/xul/crashtests/583957-1.html index 85b51bf0c..85b51bf0c 100644 --- a/layout/xul/base/src/crashtests/583957-1.html +++ b/layout/xul/crashtests/583957-1.html diff --git a/layout/xul/base/src/crashtests/crashtests.list b/layout/xul/crashtests/crashtests.list index f7651798b..849128735 100644 --- a/layout/xul/base/src/crashtests/crashtests.list +++ b/layout/xul/crashtests/crashtests.list @@ -7,6 +7,7 @@ load 189814-1.xul load 237787-1.xul load 265161-1.xul load 289410-1.xul +load 290743.html load 291702-1.xul load 291702-2.xul load 291702-3.xul @@ -35,14 +36,17 @@ load 374102-1.xul load 376137-1.html load 376137-2.html load 377592-1.svg +load 378961.html load 381862.html load 382746-1.xul load 382899-1.xul load 383236-1.xul load 384037-1.xhtml load 384105-1.html +asserts(0-12) load 384373.html # bug 623436 load 384491-1.xhtml load 384871-1.html +load 386642.xul load 387033-1.xhtml load 387080-1.xul load 391974-1.html @@ -53,9 +57,12 @@ load 398326-1.xhtml load 399013.xul load 400779-1.xhtml load 402912-1.xhtml +load 404192.xhtml +load 407152.xul load 408904-1.xul load 412479-1.xhtml asserts(4) load 415394-1.xhtml # Bug 163838 +load 417509.xul load 420424-1.xul load 430356-1.xhtml load 431738.xhtml diff --git a/layout/xul/base/src/crashtests/menulist-focused.xhtml b/layout/xul/crashtests/menulist-focused.xhtml index 7a09a838d..7a09a838d 100644 --- a/layout/xul/base/src/crashtests/menulist-focused.xhtml +++ b/layout/xul/crashtests/menulist-focused.xhtml diff --git a/layout/xul/grid/Makefile.in b/layout/xul/grid/Makefile.in deleted file mode 100644 index 964a8fb1d..000000000 --- a/layout/xul/grid/Makefile.in +++ /dev/null @@ -1,29 +0,0 @@ -# -# 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/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -LIBXUL_LIBRARY = 1 -FAIL_ON_WARNINGS = 1 - -LOCAL_INCLUDES = \ - -I$(srcdir) \ - -I$(srcdir)/../base/src \ - -I$(srcdir)/../../generic \ - -I$(srcdir)/../../style \ - -I$(srcdir)/../../forms \ - $(NULL) - -# we don't want the shared lib, but we want to force the creation of a static lib. -FORCE_STATIC_LIB = 1 - -include $(topsrcdir)/config/rules.mk - -DEFINES += -D_IMPL_NS_LAYOUT diff --git a/layout/xul/grid/moz.build b/layout/xul/grid/moz.build index d2cfd5d2e..db81bc13f 100644 --- a/layout/xul/grid/moz.build +++ b/layout/xul/grid/moz.build @@ -4,8 +4,6 @@ # 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/. -MODULE = 'layout' - EXPORTS += [ 'nsGrid.h', 'nsGridCell.h', @@ -18,7 +16,7 @@ EXPORTS += [ 'nsIGridPart.h', ] -CPP_SOURCES += [ +UNIFIED_SOURCES += [ 'nsGrid.cpp', 'nsGridCell.cpp', 'nsGridLayout2.cpp', @@ -30,5 +28,13 @@ CPP_SOURCES += [ 'nsGridRowLeafLayout.cpp', ] -LIBRARY_NAME = 'gkxulgrid_s' +FAIL_ON_WARNINGS = True + +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '..', + '../../forms', + '../../generic', + '../../style', +] diff --git a/layout/xul/grid/nsGrid.cpp b/layout/xul/grid/nsGrid.cpp index 0cf96a826..847d9ec79 100644 --- a/layout/xul/grid/nsGrid.cpp +++ b/layout/xul/grid/nsGrid.cpp @@ -255,7 +255,7 @@ nsGrid::FindRowsAndColumns(nsIFrame** aRows, nsIFrame** aColumns) nsIFrame* child = nullptr; // if we have <grid></grid> then mBox will be null (bug 125689) if (mBox) - child = mBox->GetChildBox(); + child = nsBox::GetChildBox(mBox); while(child) { @@ -287,7 +287,7 @@ nsGrid::FindRowsAndColumns(nsIFrame** aRows, nsIFrame** aColumns) child = oldBox; } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } } @@ -419,7 +419,7 @@ nsGrid::PopulateCellMap(nsGridRow* aRows, nsGridRow* aColumns, int32_t aRowCount child = row->mBox; if (child) { - child = child->GetChildBox(); + child = nsBox::GetChildBox(child); j = 0; @@ -438,7 +438,7 @@ nsGrid::PopulateCellMap(nsGridRow* aRows, nsGridRow* aColumns, int32_t aRowCount else GetCellAt(i,j)->SetBoxInColumn(child); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); j++; } @@ -1115,13 +1115,13 @@ nsGrid::GetRowFlex(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) // the grid. 3) Then we are not flexible box = GetScrollBox(box); - nsIFrame* parent = box->GetParentBox(); + nsIFrame* parent = nsBox::GetParentBox(box); nsIFrame* parentsParent=nullptr; while(parent) { parent = GetScrollBox(parent); - parentsParent = parent->GetParentBox(); + parentsParent = nsBox::GetParentBox(parent); // if our parents parent is not a grid // the get its flex. If its 0 then we are @@ -1248,7 +1248,7 @@ nsGrid::GetScrollBox(nsIFrame* aChild) return nullptr; // get parent - nsIFrame* parent = aChild->GetParentBox(); + nsIFrame* parent = nsBox::GetParentBox(aChild); // walk up until we find a scrollframe or a part // if it's a scrollframe return it. @@ -1265,7 +1265,7 @@ nsGrid::GetScrollBox(nsIFrame* aChild) if (parentGridRow) break; - parent = parent->GetParentBox(); + parent = nsBox::GetParentBox(parent); } return aChild; diff --git a/layout/xul/grid/nsGridCell.h b/layout/xul/grid/nsGridCell.h index 74769bedd..21012bf63 100644 --- a/layout/xul/grid/nsGridCell.h +++ b/layout/xul/grid/nsGridCell.h @@ -13,6 +13,8 @@ #ifndef nsGridCell_h___ #define nsGridCell_h___ +#include "mozilla/Attributes.h" + class nsBoxLayoutState; struct nsSize; class nsIFrame; @@ -25,11 +27,11 @@ class nsIFrame; * biggest sizes. */ -class nsGridCell +class nsGridCell final { public: nsGridCell(); - virtual ~nsGridCell(); + ~nsGridCell(); nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState); nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState); diff --git a/layout/xul/grid/nsGridLayout2.cpp b/layout/xul/grid/nsGridLayout2.cpp index 3b5d6733a..0e1bb41eb 100644 --- a/layout/xul/grid/nsGridLayout2.cpp +++ b/layout/xul/grid/nsGridLayout2.cpp @@ -32,6 +32,10 @@ nsGridLayout2::nsGridLayout2(nsIPresShell* aPresShell):nsStackLayout() { } +nsGridLayout2::~nsGridLayout2() +{ +} + // static void nsGridLayout2::AddOffset(nsBoxLayoutState& aState, nsIFrame* aChild, nsSize& aSize) @@ -57,9 +61,9 @@ nsGridLayout2::Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) } void -nsGridLayout2::IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) +nsGridLayout2::IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) { - nsStackLayout::IntrinsicWidthsDirty(aBox, aBoxLayoutState); + nsStackLayout::IntrinsicISizesDirty(aBox, aBoxLayoutState); // XXXldb We really don't need to do all the work that NeedsRebuild // does; we just need to mark intrinsic widths dirty on the // (row/column)(s/-groups). diff --git a/layout/xul/grid/nsGridLayout2.h b/layout/xul/grid/nsGridLayout2.h index 6b32aa7dc..1b4feabe9 100644 --- a/layout/xul/grid/nsGridLayout2.h +++ b/layout/xul/grid/nsGridLayout2.h @@ -23,8 +23,8 @@ class nsGridCell; /** * The nsBoxLayout implementation for a grid. */ -class nsGridLayout2 : public nsStackLayout, - public nsIGridPart +class nsGridLayout2 final : public nsStackLayout, + public nsIGridPart { public: @@ -32,40 +32,41 @@ public: NS_DECL_ISUPPORTS_INHERITED - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; - virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return nullptr; } - virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return this; } - virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE; - virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE { + virtual nsGridRowGroupLayout* CastToRowGroupLayout() override { return nullptr; } + virtual nsGridLayout2* CastToGridLayout() override { return this; } + virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) override; + virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) override { NS_NOTREACHED("Should not be called"); return nullptr; } - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE { aRowCount++; } - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE { } - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; - virtual Type GetType() MOZ_OVERRIDE { return eGrid; } + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) override { aRowCount++; } + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) override { } + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) override; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) override; + virtual Type GetType() override { return eGrid; } virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aPrevBox, - const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE; + const nsFrameList::Slice& aNewChildren) override; virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, - const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE; + const nsFrameList::Slice& aNewChildren) override; virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, - nsIFrame* aChildList) MOZ_OVERRIDE; + nsIFrame* aChildList) override; virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, - nsIFrame* aChildList) MOZ_OVERRIDE; + nsIFrame* aChildList) override; - virtual nsIGridPart* AsGridPart() MOZ_OVERRIDE { return this; } + virtual nsIGridPart* AsGridPart() override { return this; } static void AddOffset(nsBoxLayoutState& aState, nsIFrame* aChild, nsSize& aSize); protected: - nsGridLayout2(nsIPresShell* aShell); + explicit nsGridLayout2(nsIPresShell* aShell); + virtual ~nsGridLayout2(); nsGrid mGrid; private: diff --git a/layout/xul/grid/nsGridRowGroupFrame.cpp b/layout/xul/grid/nsGridRowGroupFrame.cpp index 9faf35e87..6ddbeff51 100644 --- a/layout/xul/grid/nsGridRowGroupFrame.cpp +++ b/layout/xul/grid/nsGridRowGroupFrame.cpp @@ -23,11 +23,7 @@ NS_NewGridRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { nsCOMPtr<nsBoxLayout> layout = NS_NewGridRowGroupLayout(); - if (!layout) { - return nullptr; - } - - return new (aPresShell) nsGridRowGroupFrame(aPresShell, aContext, layout); + return new (aPresShell) nsGridRowGroupFrame(aContext, layout); } NS_IMPL_FRAMEARENA_HELPERS(nsGridRowGroupFrame) @@ -52,11 +48,11 @@ nsGridRowGroupFrame::GetFlex(nsBoxLayoutState& aState) // ok we are flexible add up our children nscoord totalFlex = 0; - nsIFrame* child = GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(this); while (child) { totalFlex += child->GetFlex(aState); - child = child->GetNextBox(); + child = GetNextBox(child); } mFlex = totalFlex; diff --git a/layout/xul/grid/nsGridRowGroupFrame.h b/layout/xul/grid/nsGridRowGroupFrame.h index d1621298b..ce937f747 100644 --- a/layout/xul/grid/nsGridRowGroupFrame.h +++ b/layout/xul/grid/nsGridRowGroupFrame.h @@ -28,19 +28,18 @@ class nsGridRowGroupFrame : public nsBoxFrame public: NS_DECL_FRAMEARENA_HELPERS -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("nsGridRowGroup"), aResult); } #endif - nsGridRowGroupFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, + nsGridRowGroupFrame(nsStyleContext* aContext, nsBoxLayout* aLayoutManager): - nsBoxFrame(aPresShell, aContext, false, aLayoutManager) {} + nsBoxFrame(aContext, false, aLayoutManager) {} - virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) override; }; // class nsGridRowGroupFrame diff --git a/layout/xul/grid/nsGridRowGroupLayout.cpp b/layout/xul/grid/nsGridRowGroupLayout.cpp index dfbc49478..b98371d54 100644 --- a/layout/xul/grid/nsGridRowGroupLayout.cpp +++ b/layout/xul/grid/nsGridRowGroupLayout.cpp @@ -18,6 +18,7 @@ #include "nsGridRowGroupLayout.h" #include "nsCOMPtr.h" #include "nsIScrollableFrame.h" +#include "nsBox.h" #include "nsBoxLayoutState.h" #include "nsGridLayout2.h" #include "nsGridRow.h" @@ -153,10 +154,10 @@ nsGridRowGroupLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) if (aBox) { // mark us dirty // XXXldb We probably don't want to walk up the ancestor chain - // calling MarkIntrinsicWidthsDirty for every row group. + // calling MarkIntrinsicISizesDirty for every row group. aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY); - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while(child) { @@ -168,7 +169,7 @@ nsGridRowGroupLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) if (monument) monument->DirtyRows(deepChild, aState); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } } } @@ -180,7 +181,7 @@ nsGridRowGroupLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32 if (aBox) { int32_t startCount = aRowCount; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while(child) { @@ -190,12 +191,12 @@ nsGridRowGroupLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32 nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild); if (monument) { monument->CountRowsColumns(deepChild, aRowCount, aComputedColumnCount); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); deepChild = child; continue; } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); // if not a monument. Then count it. It will be a bogus row aRowCount++; @@ -215,7 +216,7 @@ nsGridRowGroupLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows) int32_t rowCount = 0; if (aBox) { - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while(child) { @@ -225,14 +226,14 @@ nsGridRowGroupLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows) nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild); if (monument) { rowCount += monument->BuildRows(deepChild, &aRows[rowCount]); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); deepChild = child; continue; } aRows[rowCount].Init(child, true); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); // if not a monument. Then count it. It will be a bogus row rowCount++; diff --git a/layout/xul/grid/nsGridRowGroupLayout.h b/layout/xul/grid/nsGridRowGroupLayout.h index 956532e15..88bb4d939 100644 --- a/layout/xul/grid/nsGridRowGroupLayout.h +++ b/layout/xul/grid/nsGridRowGroupLayout.h @@ -25,22 +25,22 @@ public: friend already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout(); - virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return this; } - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE; - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; - virtual int32_t GetRowCount() MOZ_OVERRIDE { return mRowCount; } - virtual Type GetType() MOZ_OVERRIDE { return eRowGroup; } + virtual nsGridRowGroupLayout* CastToRowGroupLayout() override { return this; } + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) override; + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) override; + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) override; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) override; + virtual int32_t GetRowCount() override { return mRowCount; } + virtual Type GetType() override { return eRowGroup; } protected: nsGridRowGroupLayout(); virtual ~nsGridRowGroupLayout(); - virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) override; static void AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal); private: diff --git a/layout/xul/grid/nsGridRowLayout.cpp b/layout/xul/grid/nsGridRowLayout.cpp index 2d9461eaf..51d8b702b 100644 --- a/layout/xul/grid/nsGridRowLayout.cpp +++ b/layout/xul/grid/nsGridRowLayout.cpp @@ -21,6 +21,10 @@ nsGridRowLayout::nsGridRowLayout():nsSprocketLayout() { } +nsGridRowLayout::~nsGridRowLayout() +{ +} + void nsGridRowLayout::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aPrevBox, @@ -60,7 +64,7 @@ nsGridRowLayout::GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) // get the parent if (aBox) - aBox = aBox->GetParentBox(); + aBox = nsBox::GetParentBox(aBox); if (aBox) { @@ -89,7 +93,7 @@ nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequ } int32_t index = -1; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); int32_t count = 0; while(child) { @@ -108,7 +112,7 @@ nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequ } else count++; - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } // if we didn't find ourselves then the tree isn't properly formed yet @@ -143,10 +147,10 @@ nsGridRowLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) aBox = nsGrid::GetScrollBox(aBox); // see if we have a next to see if we are last - nsIFrame* next = aBox->GetNextBox(); + nsIFrame* next = nsBox::GetNextBox(aBox); // get the parent first child to see if we are first - nsIFrame* child = parent->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(parent); margin = part->GetTotalMargin(parent, aIsHorizontal); diff --git a/layout/xul/grid/nsGridRowLayout.h b/layout/xul/grid/nsGridRowLayout.h index 187944fd3..22a6f12c9 100644 --- a/layout/xul/grid/nsGridRowLayout.h +++ b/layout/xul/grid/nsGridRowLayout.h @@ -34,25 +34,26 @@ class nsGridRowLayout : public nsSprocketLayout, public: NS_DECL_ISUPPORTS_INHERITED - virtual nsGridRowGroupLayout* CastToRowGroupLayout() MOZ_OVERRIDE { return nullptr; } - virtual nsGridLayout2* CastToGridLayout() MOZ_OVERRIDE { return nullptr; } - virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) MOZ_OVERRIDE; - virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) MOZ_OVERRIDE; + virtual nsGridRowGroupLayout* CastToRowGroupLayout() override { return nullptr; } + virtual nsGridLayout2* CastToGridLayout() override { return nullptr; } + virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr) override; + virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) override; virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aPrevBox, - const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE; + const nsFrameList::Slice& aNewChildren) override; virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, - const nsFrameList::Slice& aNewChildren) MOZ_OVERRIDE; - virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) MOZ_OVERRIDE; - virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) MOZ_OVERRIDE; - virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) MOZ_OVERRIDE; + const nsFrameList::Slice& aNewChildren) override; + virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) override; + virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) override; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) override; - virtual nsIGridPart* AsGridPart() MOZ_OVERRIDE { return this; } + virtual nsIGridPart* AsGridPart() override { return this; } protected: virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState)=0; nsGridRowLayout(); + virtual ~nsGridRowLayout(); }; #endif diff --git a/layout/xul/grid/nsGridRowLeafFrame.cpp b/layout/xul/grid/nsGridRowLeafFrame.cpp index c418c0742..ee4e0f327 100644 --- a/layout/xul/grid/nsGridRowLeafFrame.cpp +++ b/layout/xul/grid/nsGridRowLeafFrame.cpp @@ -23,12 +23,7 @@ NS_NewGridRowLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { nsCOMPtr<nsBoxLayout> layout = NS_NewGridRowLeafLayout(); - if (!layout) { - return nullptr; - } - - return new (aPresShell) nsGridRowLeafFrame(aPresShell, aContext, false, - layout); + return new (aPresShell) nsGridRowLeafFrame(aContext, false, layout); } NS_IMPL_FRAMEARENA_HELPERS(nsGridRowLeafFrame) @@ -37,7 +32,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsGridRowLeafFrame) * Our border and padding could be affected by our columns or rows. * Let's go check it out. */ -NS_IMETHODIMP +nsresult nsGridRowLeafFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding) { // if our columns have made our padding larger add it in. diff --git a/layout/xul/grid/nsGridRowLeafFrame.h b/layout/xul/grid/nsGridRowLeafFrame.h index cd3defc61..0db102dc7 100644 --- a/layout/xul/grid/nsGridRowLeafFrame.h +++ b/layout/xul/grid/nsGridRowLeafFrame.h @@ -32,20 +32,19 @@ public: friend nsIFrame* NS_NewGridRowLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("nsGridRowLeaf"), aResult); } #endif - nsGridRowLeafFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, + nsGridRowLeafFrame(nsStyleContext* aContext, bool aIsRoot, nsBoxLayout* aLayoutManager): - nsBoxFrame(aPresShell, aContext, aIsRoot, aLayoutManager) {} + nsBoxFrame(aContext, aIsRoot, aLayoutManager) {} - NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding) MOZ_OVERRIDE; + virtual nsresult GetBorderAndPadding(nsMargin& aBorderAndPadding) override; }; // class nsGridRowLeafFrame diff --git a/layout/xul/grid/nsGridRowLeafLayout.cpp b/layout/xul/grid/nsGridRowLeafLayout.cpp index 94ca4b651..75965b318 100644 --- a/layout/xul/grid/nsGridRowLeafLayout.cpp +++ b/layout/xul/grid/nsGridRowLeafLayout.cpp @@ -114,7 +114,7 @@ nsGridRowLeafLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsBoxSize* start = nullptr; nsBoxSize* last = nullptr; nsBoxSize* current = nullptr; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); for (int i=0; i < count; i++) { column = grid->GetColumnAt(i,isHorizontal); @@ -206,7 +206,7 @@ nsGridRowLeafLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, } if (child && !column->mIsBogus) - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } aBoxSizes = start; @@ -289,7 +289,7 @@ nsGridRowLeafLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) if (aBox) { // mark us dirty // XXXldb We probably don't want to walk up the ancestor chain - // calling MarkIntrinsicWidthsDirty for every row. + // calling MarkIntrinsicISizesDirty for every row. aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY); } @@ -299,12 +299,12 @@ void nsGridRowLeafLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) { if (aBox) { - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); // count the children int32_t columnCount = 0; while(child) { - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); columnCount++; } diff --git a/layout/xul/grid/nsGridRowLeafLayout.h b/layout/xul/grid/nsGridRowLeafLayout.h index 9f35874e4..75cba7310 100644 --- a/layout/xul/grid/nsGridRowLeafLayout.h +++ b/layout/xul/grid/nsGridRowLeafLayout.h @@ -22,32 +22,32 @@ */ // XXXldb This needs a better name that indicates that it's for any grid // row. -class nsGridRowLeafLayout : public nsGridRowLayout +class nsGridRowLeafLayout final : public nsGridRowLayout { public: friend already_AddRefed<nsBoxLayout> NS_NewGridRowLeafLayout(); - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) MOZ_OVERRIDE; - virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) MOZ_OVERRIDE; - virtual Type GetType() MOZ_OVERRIDE { return eRowLeaf; } + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) override; + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) override; + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) override; + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows) override; + virtual Type GetType() override { return eRowLeaf; } protected: virtual void PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState, nsBoxSize*& aBoxSizes, nscoord& aMinSize, - nscoord& aMaxSize, int32_t& aFlexes) MOZ_OVERRIDE; + nscoord& aMaxSize, int32_t& aFlexes) override; virtual void ComputeChildSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nscoord& aGivenSize, nsBoxSize* aBoxSizes, - nsComputedBoxSize*& aComputedBoxSizes) MOZ_OVERRIDE; + nsComputedBoxSize*& aComputedBoxSizes) override; nsGridRowLeafLayout(); diff --git a/layout/xul/grid/reftests/reftest.list b/layout/xul/grid/reftests/reftest.list index 80f7925a0..15c3c0b79 100644 --- a/layout/xul/grid/reftests/reftest.list +++ b/layout/xul/grid/reftests/reftest.list @@ -1,18 +1,18 @@ -== row-sizing-1.xul row-sizing-1-ref.xul -== column-sizing-1.xul column-sizing-1-ref.xul -== row-or-column-sizing-1.xul row-or-column-sizing-2.xul -== row-or-column-sizing-1.xul row-or-column-sizing-3.xul -== row-or-column-sizing-1.xul row-or-column-sizing-4.xul -== z-order-1.xul z-order-1-ref.xul -== z-order-2.xul z-order-2-ref.xul -== not-full-basic.xul not-full-basic-ref.xhtml -== not-full-grid-pack-align.xul not-full-basic-ref.xhtml -== not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior? -== not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml -== not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml -== not-full-row-leaf-align.xul not-full-basic-ref.xhtml -== not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml -== not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml +skip-if(B2G&&browserIsRemote) == row-sizing-1.xul row-sizing-1-ref.xul +skip-if(B2G&&browserIsRemote) == column-sizing-1.xul column-sizing-1-ref.xul +skip-if(B2G&&browserIsRemote) == row-or-column-sizing-1.xul row-or-column-sizing-2.xul +skip-if(B2G&&browserIsRemote) == row-or-column-sizing-1.xul row-or-column-sizing-3.xul +skip-if(B2G&&browserIsRemote) == row-or-column-sizing-1.xul row-or-column-sizing-4.xul +skip-if(B2G&&browserIsRemote) == z-order-1.xul z-order-1-ref.xul +skip-if(B2G&&browserIsRemote) == z-order-2.xul z-order-2-ref.xul +skip-if(B2G&&browserIsRemote) == not-full-basic.xul not-full-basic-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-grid-pack-align.xul not-full-basic-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior? +skip-if(B2G&&browserIsRemote) == not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-row-leaf-align.xul not-full-basic-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml +skip-if(B2G&&browserIsRemote) == not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml skip-if(B2G) fails-if(Android&&browserIsRemote) == scrollable-columns.xul scrollable-columns-ref.xhtml # bug 650597, 732569 -fails == scrollable-rows.xul scrollable-rows-ref.xhtml -== sizing-2d.xul sizing-2d-ref.xul +fails skip-if(B2G&&browserIsRemote) == scrollable-rows.xul scrollable-rows-ref.xhtml +skip-if(B2G&&browserIsRemote) == sizing-2d.xul sizing-2d-ref.xul diff --git a/layout/xul/base/src/moz.build b/layout/xul/moz.build index 5fb54ba5b..1031963c9 100644 --- a/layout/xul/base/src/moz.build +++ b/layout/xul/moz.build @@ -4,9 +4,42 @@ # 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/. -MODULE = 'layout' +if CONFIG['ENABLE_TESTS']: + MOCHITEST_MANIFESTS += ['test/mochitest.ini'] + MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini'] + BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] -CPP_SOURCES += [ +XPIDL_SOURCES += [ + 'nsIBoxObject.idl', + 'nsIBrowserBoxObject.idl', + 'nsIContainerBoxObject.idl', + 'nsIListBoxObject.idl', + 'nsIMenuBoxObject.idl', + 'nsIScrollBoxObject.idl', + 'nsISliderListener.idl', +] + +XPIDL_MODULE = 'layout_xul' + +EXPORTS += [ + 'nsBox.h', + 'nsIScrollbarMediator.h', + 'nsPIBoxObject.h', + 'nsPIListBoxObject.h', + 'nsXULPopupManager.h', +] + +EXPORTS.mozilla.dom += [ + 'BoxObject.h', + 'ContainerBoxObject.h', + 'ListBoxObject.h', + 'MenuBoxObject.h', + 'PopupBoxObject.h', + 'ScrollBoxObject.h', +] + +UNIFIED_SOURCES += [ + 'BoxObject.cpp', 'nsBox.cpp', 'nsBoxFrame.cpp', 'nsBoxLayout.cpp', @@ -14,9 +47,9 @@ CPP_SOURCES += [ 'nsButtonBoxFrame.cpp', 'nsRepeatService.cpp', 'nsRootBoxFrame.cpp', - 'nsScrollBoxFrame.cpp', 'nsScrollbarButtonFrame.cpp', 'nsScrollbarFrame.cpp', + 'nsScrollBoxFrame.cpp', 'nsSliderFrame.cpp', 'nsSprocketLayout.cpp', 'nsStackFrame.cpp', @@ -25,31 +58,45 @@ CPP_SOURCES += [ ] if CONFIG['MOZ_XUL']: - CPP_SOURCES += [ - 'nsScrollBoxObject.cpp', - 'nsContainerBoxObject.cpp', - 'nsMenuBoxObject.cpp', - 'nsPopupBoxObject.cpp', - 'nsListBoxObject.cpp', - 'nsBoxObject.cpp', - 'nsImageBoxFrame.cpp', + UNIFIED_SOURCES += [ + 'ContainerBoxObject.cpp', + 'ListBoxObject.cpp', + 'MenuBoxObject.cpp', + 'nsDeckFrame.cpp', 'nsDocElementBoxFrame.cpp', - 'nsLeafBoxFrame.cpp', - 'nsTextBoxFrame.cpp', 'nsGroupBoxFrame.cpp', - 'nsSplitterFrame.cpp', - 'nsDeckFrame.cpp', - 'nsProgressMeterFrame.cpp', - 'nsMenuPopupFrame.cpp', - 'nsMenuFrame.cpp', + 'nsImageBoxFrame.cpp', + 'nsLeafBoxFrame.cpp', + 'nsListBoxBodyFrame.cpp', + 'nsListBoxLayout.cpp', + 'nsListItemFrame.cpp', 'nsMenuBarFrame.cpp', 'nsMenuBarListener.cpp', + 'nsMenuFrame.cpp', + 'nsMenuPopupFrame.cpp', 'nsPopupSetFrame.cpp', - 'nsTitleBarFrame.cpp', + 'nsProgressMeterFrame.cpp', 'nsResizerFrame.cpp', - 'nsListBoxBodyFrame.cpp', - 'nsListItemFrame.cpp', - 'nsListBoxLayout.cpp', + 'nsSplitterFrame.cpp', + 'nsTextBoxFrame.cpp', + 'nsTitleBarFrame.cpp', 'nsXULLabelFrame.cpp', 'nsXULPopupManager.cpp', + 'PopupBoxObject.cpp', + 'ScrollBoxObject.cpp', ] + +if CONFIG['MOZ_XUL']: + DIRS += ['tree', 'grid'] + +FAIL_ON_WARNINGS = True + +MSVC_ENABLE_PGO = True + +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '../base', + '../generic', + '../style', + '/dom/base', +] diff --git a/layout/xul/base/src/nsBox.cpp b/layout/xul/nsBox.cpp index 84e03f8f5..38c8b9706 100644 --- a/layout/xul/base/src/nsBox.cpp +++ b/layout/xul/nsBox.cpp @@ -10,9 +10,8 @@ #include "nsCOMPtr.h" #include "nsIContent.h" #include "nsContainerFrame.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" -#include "nsFrameManager.h" #include "nsIDOMNode.h" #include "nsIDOMMozNamedAttrMap.h" #include "nsIDOMAttr.h" @@ -60,7 +59,7 @@ nsBox::ListBox(nsAutoString& aResult) aResult.AppendASCII(addr); aResult.Append(name); - aResult.AppendLiteral(" "); + aResult.Append(' '); nsIContent* content = GetContent(); @@ -85,7 +84,7 @@ nsBox::ListBox(nsAutoString& aResult) } } -NS_IMETHODIMP +nsresult nsBox::DumpBox(FILE* aFile) { nsAutoString s; @@ -139,7 +138,7 @@ nsBox::BeginLayout(nsBoxLayoutState& aState) // If the parent is dirty, all the children are dirty (nsHTMLReflowState // does this too). nsIFrame* box; - for (box = GetChildBox(); box; box = box->GetNextBox()) + for (box = GetChildBox(this); box; box = GetNextBox(box)) box->AddStateBits(NS_FRAME_IS_DIRTY); } @@ -202,7 +201,7 @@ nsBox::Shutdown() NS_IF_RELEASE(gTheme); } -NS_IMETHODIMP +nsresult nsBox::RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) { return NS_OK; @@ -245,7 +244,7 @@ nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect, bool aRemoveOver flags |= stateFlags; if ((flags & NS_FRAME_NO_MOVE_FRAME) == NS_FRAME_NO_MOVE_FRAME) - SetSize(nsSize(aRect.width, aRect.height)); + SetSize(aRect.Size()); else SetRect(aRect); @@ -284,7 +283,7 @@ nsBox::GetLayoutFlags(uint32_t& aFlags) } -NS_IMETHODIMP +nsresult nsIFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding) { aBorderAndPadding.SizeTo(0, 0, 0, 0); @@ -302,7 +301,7 @@ nsIFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding) return rv; } -NS_IMETHODIMP +nsresult nsBox::GetBorder(nsMargin& aMargin) { aMargin.SizeTo(0,0,0,0); @@ -328,7 +327,7 @@ nsBox::GetBorder(nsMargin& aMargin) return NS_OK; } -NS_IMETHODIMP +nsresult nsBox::GetPadding(nsMargin& aMargin) { const nsStyleDisplay *disp = StyleDisplay(); @@ -358,7 +357,7 @@ nsBox::GetPadding(nsMargin& aMargin) return NS_OK; } -NS_IMETHODIMP +nsresult nsBox::GetMargin(nsMargin& aMargin) { aMargin.SizeTo(0,0,0,0); @@ -683,18 +682,15 @@ nsIFrame::AddCSSMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize, nsITheme *theme = aState.PresContext()->GetTheme(); if (theme && theme->ThemeSupportsWidget(aState.PresContext(), aBox, display->mAppearance)) { nsIntSize size; - nsRenderingContext* rendContext = aState.GetRenderingContext(); - if (rendContext) { - theme->GetMinimumWidgetSize(rendContext, aBox, - display->mAppearance, &size, &canOverride); - if (size.width) { - aSize.width = aState.PresContext()->DevPixelsToAppUnits(size.width); - aWidthSet = true; - } - if (size.height) { - aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height); - aHeightSet = true; - } + theme->GetMinimumWidgetSize(aState.PresContext(), aBox, + display->mAppearance, &size, &canOverride); + if (size.width) { + aSize.width = aState.PresContext()->DevPixelsToAppUnits(size.width); + aWidthSet = true; + } + if (size.height) { + aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height); + aHeightSet = true; } } } @@ -925,6 +921,28 @@ nsBox::BoundsCheck(const nsSize& aMinSize, const nsSize& aPrefSize, const nsSize BoundsCheck(aMinSize.height, aPrefSize.height, aMaxSize.height)); } +/*static*/ nsIFrame* +nsBox::GetChildBox(const nsIFrame* aFrame) +{ + // box layout ends at box-wrapped frames, so don't allow these frames + // to report child boxes. + return aFrame->IsBoxFrame() ? aFrame->GetFirstPrincipalChild() : nullptr; +} + +/*static*/ nsIFrame* +nsBox::GetNextBox(const nsIFrame* aFrame) +{ + return aFrame->GetParent() && + aFrame->GetParent()->IsBoxFrame() ? aFrame->GetNextSibling() : nullptr; +} + +/*static*/ nsIFrame* +nsBox::GetParentBox(const nsIFrame* aFrame) +{ + return aFrame->GetParent() && + aFrame->GetParent()->IsBoxFrame() ? aFrame->GetParent() : nullptr; +} + #ifdef DEBUG_LAYOUT nsresult nsBox::SetDebug(nsBoxLayoutState& aState, bool aDebug) @@ -940,7 +958,7 @@ nsBox::GetDebugBoxAt( const nsPoint& aPoint, if (!thisRect.Contains(aPoint)) return NS_ERROR_FAILURE; - nsIFrame* child = GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(this); nsIFrame* hit = nullptr; *aBox = nullptr; @@ -950,7 +968,7 @@ nsBox::GetDebugBoxAt( const nsPoint& aPoint, if (NS_SUCCEEDED(rv) && hit) { *aBox = hit; } - child = child->GetNextBox(); + child = GetNextBox(child); } // found a child @@ -962,7 +980,7 @@ nsBox::GetDebugBoxAt( const nsPoint& aPoint, } -NS_IMETHODIMP +nsresult nsBox::GetDebug(bool& aDebug) { aDebug = false; diff --git a/layout/xul/base/src/nsBox.h b/layout/xul/nsBox.h index 2329565c9..a3dbfcfee 100644 --- a/layout/xul/base/src/nsBox.h +++ b/layout/xul/nsBox.h @@ -11,10 +11,6 @@ class nsITheme; -#define NS_STATE_IS_ROOT NS_FRAME_STATE_BIT(24) -#define NS_STATE_SET_TO_DEBUG NS_FRAME_STATE_BIT(26) -#define NS_STATE_DEBUG_WAS_SET NS_FRAME_STATE_BIT(27) - class nsBox : public nsIFrame { public: @@ -23,35 +19,35 @@ public: static void Shutdown(); - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; - virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) override; - virtual bool IsCollapsed() MOZ_OVERRIDE; + virtual bool IsCollapsed() override; virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, - bool aRemoveOverflowAreas = false) MOZ_OVERRIDE; + bool aRemoveOverflowAreas = false) override; - NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding) MOZ_OVERRIDE; - NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding) MOZ_OVERRIDE; - NS_IMETHOD GetMargin(nsMargin& aMargin) MOZ_OVERRIDE; + virtual nsresult GetBorder(nsMargin& aBorderAndPadding) override; + virtual nsresult GetPadding(nsMargin& aBorderAndPadding) override; + virtual nsresult GetMargin(nsMargin& aMargin) override; - virtual Valignment GetVAlign() const MOZ_OVERRIDE { return vAlign_Top; } - virtual Halignment GetHAlign() const MOZ_OVERRIDE { return hAlign_Left; } + virtual Valignment GetVAlign() const override { return vAlign_Top; } + virtual Halignment GetHAlign() const override { return hAlign_Left; } - NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) MOZ_OVERRIDE; + virtual nsresult RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) override; #ifdef DEBUG_LAYOUT NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIFrame** aBox); - NS_IMETHOD GetDebug(bool& aDebug) MOZ_OVERRIDE; - NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug) MOZ_OVERRIDE; + virtual nsresult GetDebug(bool& aDebug) override; + virtual nsresult SetDebug(nsBoxLayoutState& aState, bool aDebug) override; - NS_IMETHOD DumpBox(FILE* out) MOZ_OVERRIDE; - NS_HIDDEN_(void) PropagateDebug(nsBoxLayoutState& aState); + virtual nsresult DumpBox(FILE* out) override; + void PropagateDebug(nsBoxLayoutState& aState); #endif nsBox(); @@ -64,7 +60,7 @@ rollbox. virtual bool DoesClipChildren(); virtual bool ComputesOwnOverflowArea() = 0; - NS_HIDDEN_(nsresult) SyncLayout(nsBoxLayoutState& aBoxLayoutState); + nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState); bool DoesNeedRecalc(const nsSize& aSize); bool DoesNeedRecalc(nscoord aCoord); @@ -81,6 +77,10 @@ rollbox. static nsSize BoundsCheck(const nsSize& aMinSize, const nsSize& aPrefSize, const nsSize& aMaxSize); static nscoord BoundsCheck(nscoord aMinSize, nscoord aPrefSize, nscoord aMaxSize); + static nsIFrame* GetChildBox(const nsIFrame* aFrame); + static nsIFrame* GetNextBox(const nsIFrame* aFrame); + static nsIFrame* GetParentBox(const nsIFrame* aFrame); + protected: #ifdef DEBUG_LAYOUT @@ -91,13 +91,13 @@ protected: virtual void GetLayoutFlags(uint32_t& aFlags); - NS_HIDDEN_(nsresult) BeginLayout(nsBoxLayoutState& aState); + nsresult BeginLayout(nsBoxLayoutState& aState); NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState); - NS_HIDDEN_(nsresult) EndLayout(nsBoxLayoutState& aState); + nsresult EndLayout(nsBoxLayoutState& aState); #ifdef DEBUG_LAYOUT virtual void GetBoxName(nsAutoString& aName); - NS_HIDDEN_(void) PropagateDebug(nsBoxLayoutState& aState); + void PropagateDebug(nsBoxLayoutState& aState); #endif static bool gGotTheme; diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 2fdc39044..5728c80cd 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -31,14 +31,18 @@ // any number of syblings around the box. Basically any children in the reflow chain must have their caches cleared // so when asked for there current size they can relayout themselves. -#include "nsBoxLayoutState.h" #include "nsBoxFrame.h" + +#include "gfxUtils.h" +#include "mozilla/gfx/2D.h" +#include "nsBoxLayoutState.h" #include "mozilla/dom/Touch.h" +#include "mozilla/Move.h" #include "nsStyleContext.h" #include "nsPlaceholderFrame.h" #include "nsPresContext.h" #include "nsCOMPtr.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsIContent.h" #include "nsHTMLParts.h" @@ -56,18 +60,22 @@ #include "nsIDOMElement.h" #include "nsITheme.h" #include "nsTransform2D.h" -#include "nsEventStateManager.h" -#include "nsEventDispatcher.h" +#include "mozilla/EventStateManager.h" #include "nsIDOMEvent.h" #include "nsDisplayList.h" #include "mozilla/Preferences.h" +#include "nsThemeConstants.h" +#include "nsLayoutUtils.h" #include <algorithm> // Needed for Print Preview #include "nsIURI.h" +#include "mozilla/TouchEvents.h" + using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::gfx; //define DEBUG_REDRAW @@ -89,19 +97,24 @@ nsIFrame* nsBoxFrame::mDebugChild = nullptr; nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot, nsBoxLayout* aLayoutManager) { - return new (aPresShell) nsBoxFrame(aPresShell, aContext, aIsRoot, aLayoutManager); + return new (aPresShell) nsBoxFrame(aContext, aIsRoot, aLayoutManager); } nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsBoxFrame(aPresShell, aContext); + return new (aPresShell) nsBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsBoxFrame) -nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, +#ifdef DEBUG +NS_QUERYFRAME_HEAD(nsBoxFrame) + NS_QUERYFRAME_ENTRY(nsBoxFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) +#endif + +nsBoxFrame::nsBoxFrame(nsStyleContext* aContext, bool aIsRoot, nsBoxLayout* aLayoutManager) : nsContainerFrame(aContext) @@ -119,7 +132,7 @@ nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout> layout = aLayoutManager; if (layout == nullptr) { - NS_NewSprocketLayout(aPresShell, layout); + NS_NewSprocketLayout(PresContext()->PresShell(), layout); } SetLayoutManager(layout); @@ -129,22 +142,16 @@ nsBoxFrame::~nsBoxFrame() { } -NS_IMETHODIMP +void nsBoxFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - nsresult r = nsContainerFrame::SetInitialChildList(aListID, aChildList); - if (r == NS_OK) { - // initialize our list of infos. - nsBoxLayoutState state(PresContext()); - CheckBoxOrder(); - if (mLayoutManager) - mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild()); - } else { - NS_WARNING("Warning add child failed!!\n"); - } - - return r; + nsContainerFrame::SetInitialChildList(aListID, aChildList); + // initialize our list of infos. + nsBoxLayoutState state(PresContext()); + CheckBoxOrder(); + if (mLayoutManager) + mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild()); } /* virtual */ void @@ -161,9 +168,9 @@ nsBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) * Initialize us. This is a good time to get the alignment of the box */ void -nsBoxFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsBoxFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsContainerFrame::Init(aContent, aParent, aPrevInFlow); @@ -171,7 +178,7 @@ nsBoxFrame::Init(nsIContent* aContent, AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); } - MarkIntrinsicWidthsDirty(); + MarkIntrinsicISizesDirty(); CacheAttributes(); @@ -541,16 +548,15 @@ nsBoxFrame::GetInitialAutoStretch(bool& aStretch) return true; } -NS_IMETHODIMP +void nsBoxFrame::DidReflow(nsPresContext* aPresContext, const nsHTMLReflowState* aReflowState, nsDidReflowStatus aStatus) { nsFrameState preserveBits = mState & (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN); - nsresult rv = nsFrame::DidReflow(aPresContext, aReflowState, aStatus); + nsFrame::DidReflow(aPresContext, aReflowState, aStatus); mState |= preserveBits; - return rv; } bool @@ -574,7 +580,7 @@ static void printSize(char * aDesc, nscoord aSize) #endif /* virtual */ nscoord -nsBoxFrame::GetMinWidth(nsRenderingContext *aRenderingContext) +nsBoxFrame::GetMinISize(nsRenderingContext *aRenderingContext) { nscoord result; DISPLAY_MIN_WIDTH(this, result); @@ -596,7 +602,7 @@ nsBoxFrame::GetMinWidth(nsRenderingContext *aRenderingContext) } /* virtual */ nscoord -nsBoxFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) +nsBoxFrame::GetPrefISize(nsRenderingContext *aRenderingContext) { nscoord result; DISPLAY_PREF_WIDTH(this, result); @@ -617,7 +623,7 @@ nsBoxFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) return result; } -NS_IMETHODIMP +void nsBoxFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -625,6 +631,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, { // If you make changes to this method, please keep nsLeafBoxFrame::Reflow // in sync, if the changes are applicable there. + + DO_GLOBAL_REFLOW_COUNT("nsBoxFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); NS_ASSERTION(aReflowState.ComputedWidth() >=0 && @@ -634,8 +642,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, printf("\n-------------Starting BoxFrame Reflow ----------------------------\n"); printf("%p ** nsBF::Reflow %d ", this, myCounter++); - printSize("AW", aReflowState.availableWidth); - printSize("AH", aReflowState.availableHeight); + printSize("AW", aReflowState.AvailableWidth()); + printSize("AH", aReflowState.AvailableHeight()); printSize("CW", aReflowState.ComputedWidth()); printSize("CH", aReflowState.ComputedHeight()); @@ -649,43 +657,46 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, nsBoxLayoutState state(aPresContext, aReflowState.rendContext, &aReflowState, aReflowState.mReflowDepth); - nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight()); + WritingMode wm = aReflowState.GetWritingMode(); + LogicalSize computedSize(wm, aReflowState.ComputedISize(), + aReflowState.ComputedBSize()); - nsMargin m; - m = aReflowState.mComputedBorderPadding; + LogicalMargin m = aReflowState.ComputedLogicalBorderPadding(); // GetBorderAndPadding(m); - nsSize prefSize(0,0); + LogicalSize prefSize(wm); // if we are told to layout intrinsic then get our preferred size. - NS_ASSERTION(computedSize.width != NS_INTRINSICSIZE, - "computed width should always be computed"); - if (computedSize.height == NS_INTRINSICSIZE) { - prefSize = GetPrefSize(state); + NS_ASSERTION(computedSize.ISize(wm) != NS_INTRINSICSIZE, + "computed inline size should always be computed"); + if (computedSize.BSize(wm) == NS_INTRINSICSIZE) { + nsSize physicalPrefSize = GetPrefSize(state); nsSize minSize = GetMinSize(state); nsSize maxSize = GetMaxSize(state); // XXXbz isn't GetPrefSize supposed to bounds-check for us? - prefSize = BoundsCheck(minSize, prefSize, maxSize); + physicalPrefSize = BoundsCheck(minSize, physicalPrefSize, maxSize); + prefSize = LogicalSize(wm, physicalPrefSize); } // get our desiredSize - computedSize.width += m.left + m.right; + computedSize.ISize(wm) += m.IStart(wm) + m.IEnd(wm); - if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) { - computedSize.height = prefSize.height; + if (aReflowState.ComputedBSize() == NS_INTRINSICSIZE) { + computedSize.BSize(wm) = prefSize.BSize(wm); // prefSize is border-box but min/max constraints are content-box. - nscoord verticalBorderPadding = - aReflowState.mComputedBorderPadding.TopBottom(); - nscoord contentHeight = computedSize.height - verticalBorderPadding; + nscoord blockDirBorderPadding = + aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm); + nscoord contentBSize = computedSize.BSize(wm) - blockDirBorderPadding; // Note: contentHeight might be negative, but that's OK because min-height // is never negative. - computedSize.height = aReflowState.ApplyMinMaxHeight(contentHeight) + - verticalBorderPadding; + computedSize.BSize(wm) = aReflowState.ApplyMinMaxHeight(contentBSize) + + blockDirBorderPadding; } else { - computedSize.height += m.top + m.bottom; + computedSize.BSize(wm) += m.BStart(wm) + m.BEnd(wm); } - nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height); + nsSize physicalSize = computedSize.GetPhysicalSize(wm); + nsRect r(mRect.x, mRect.y, physicalSize.width, physicalSize.height); SetBounds(state, r); @@ -695,7 +706,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, // ok our child could have gotten bigger. So lets get its bounds // get the ascent - nscoord ascent = mRect.height; + LogicalSize boxSize = GetLogicalSize(wm); + nscoord ascent = boxSize.BSize(wm); // getting the ascent could be a lot of work. Don't get it if // we are the root. The viewport doesn't care about it. @@ -703,15 +715,14 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, ascent = GetBoxAscent(state); } - aDesiredSize.width = mRect.width; - aDesiredSize.height = mRect.height; - aDesiredSize.ascent = ascent; + aDesiredSize.SetSize(wm, boxSize); + aDesiredSize.SetBlockStartAscent(ascent); aDesiredSize.mOverflowAreas = GetOverflowAreas(); #ifdef DO_NOISY_REFLOW { - printf("%p ** nsBF(done) W:%d H:%d ", this, aDesiredSize.width, aDesiredSize.height); + printf("%p ** nsBF(done) W:%d H:%d ", this, aDesiredSize.Width(), aDesiredSize.Height()); if (maxElementSize) { printf("MW:%d\n", *maxElementWidth); @@ -725,7 +736,6 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); - return NS_OK; } nsSize @@ -902,14 +912,16 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& aState) if (HasAbsolutelyPositionedChildren()) { // Set up a |reflowState| to pass into ReflowAbsoluteFrames + WritingMode wm = GetWritingMode(); nsHTMLReflowState reflowState(aState.PresContext(), this, aState.GetRenderingContext(), - nsSize(mRect.width, NS_UNCONSTRAINEDSIZE)); + LogicalSize(wm, GetLogicalSize().ISize(wm), + NS_UNCONSTRAINEDSIZE)); // Set up a |desiredSize| to pass into ReflowAbsoluteFrames - nsHTMLReflowMetrics desiredSize; - desiredSize.width = mRect.width; - desiredSize.height = mRect.height; + nsHTMLReflowMetrics desiredSize(reflowState); + desiredSize.Width() = mRect.width; + desiredSize.Height() = mRect.height; // get the ascent (cribbed from ::Reflow) nscoord ascent = mRect.height; @@ -919,14 +931,16 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& aState) if (!(mState & NS_STATE_IS_ROOT)) { ascent = GetBoxAscent(aState); } - desiredSize.ascent = ascent; + desiredSize.SetBlockStartAscent(ascent); desiredSize.mOverflowAreas = GetOverflowAreas(); + AddStateBits(NS_FRAME_IN_REFLOW); // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames // (just a dummy value; hopefully that's OK) nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; ReflowAbsoluteFrames(aState.PresContext(), desiredSize, reflowState, reflowStatus); + RemoveStateBits(NS_FRAME_IN_REFLOW); } return rv; @@ -945,7 +959,7 @@ nsBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) } #ifdef DEBUG_LAYOUT -NS_IMETHODIMP +nsresult nsBoxFrame::SetDebug(nsBoxLayoutState& aState, bool aDebug) { // see if our state matches the given debug state @@ -963,7 +977,7 @@ nsBoxFrame::SetDebug(nsBoxLayoutState& aState, bool aDebug) SetDebugOnChildList(aState, mFirstChild, aDebug); - MarkIntrinsicWidthsDirty(); + MarkIntrinsicISizesDirty(); } return NS_OK; @@ -971,7 +985,7 @@ nsBoxFrame::SetDebug(nsBoxLayoutState& aState, bool aDebug) #endif /* virtual */ void -nsBoxFrame::MarkIntrinsicWidthsDirty() +nsBoxFrame::MarkIntrinsicISizesDirty() { SizeNeedsRecalc(mPrefSize); SizeNeedsRecalc(mMinSize); @@ -981,14 +995,14 @@ nsBoxFrame::MarkIntrinsicWidthsDirty() if (mLayoutManager) { nsBoxLayoutState state(PresContext()); - mLayoutManager->IntrinsicWidthsDirty(this, state); + mLayoutManager->IntrinsicISizesDirty(this, state); } // Don't call base class method, since everything it does is within an // IsBoxWrapped check. } -NS_IMETHODIMP +void nsBoxFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { @@ -1010,10 +1024,9 @@ nsBoxFrame::RemoveFrame(ChildListID aListID, PresContext()->PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); - return NS_OK; } -NS_IMETHODIMP +void nsBoxFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) @@ -1048,11 +1061,10 @@ nsBoxFrame::InsertFrames(ChildListID aListID, PresContext()->PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); - return NS_OK; } -NS_IMETHODIMP +void nsBoxFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { @@ -1084,10 +1096,9 @@ nsBoxFrame::AppendFrames(ChildListID aListID, FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); } - return NS_OK; } -/* virtual */ nsIFrame* +/* virtual */ nsContainerFrame* nsBoxFrame::GetContentInsertionFrame() { if (GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) @@ -1095,7 +1106,7 @@ nsBoxFrame::GetContentInsertionFrame() return nsContainerFrame::GetContentInsertionFrame(); } -NS_IMETHODIMP +nsresult nsBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -1214,7 +1225,7 @@ nsBoxFrame::AttributeChanged(int32_t aNameSpaceID, } else if (aAttribute == nsGkAtoms::ordinal) { nsBoxLayoutState state(PresContext()); - nsIFrame* parent = GetParentBox(); + nsIFrame* parent = GetParentBox(this); // If our parent is not a box, there's not much we can do... but in that // case our ordinal doesn't matter anyway, so that's ok. // Also don't bother with popup frames since they are kept on the @@ -1234,6 +1245,13 @@ nsBoxFrame::AttributeChanged(int32_t aNameSpaceID, else if (aAttribute == nsGkAtoms::accesskey) { RegUnregAccessKey(true); } + else if (aAttribute == nsGkAtoms::rows && + tag == nsGkAtoms::tree) { + // Reflow ourselves and all our children if "rows" changes, since + // nsTreeBodyFrame's layout reads this from its parent (this frame). + PresContext()->PresShell()-> + FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); + } return rv; } @@ -1274,7 +1292,7 @@ nsDisplayXULDebug::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { static_cast<nsBoxFrame*>(mFrame)-> - PaintXULDebugOverlay(*aCtx, ToReferenceFrame()); + PaintXULDebugOverlay(*aCtx->GetDrawTarget(), ToReferenceFrame()); } static void @@ -1290,19 +1308,30 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - // forcelayer is only supported on XUL elements with box layout - bool forceLayer = - GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::layer) && - GetContent()->IsXUL(); + bool forceLayer = false; + uint32_t flags = 0; + mozilla::layers::FrameMetrics::ViewID scrollTargetId = + mozilla::layers::FrameMetrics::NULL_SCROLL_ID; - // Check for frames that are marked as a part of the region used - // in calculating glass margins on Windows. if (GetContent()->IsXUL()) { - const nsStyleDisplay* styles = StyleDisplay(); - if (styles && styles->mAppearance == NS_THEME_WIN_EXCLUDE_GLASS) { - nsRect rect = nsRect(aBuilder->ToReferenceFrame(this), GetSize()); - aBuilder->AddExcludedGlassRegion(rect); + // forcelayer is only supported on XUL elements with box layout + if (GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::layer)) { + forceLayer = true; + } else { + nsIFrame* parent = GetParentBox(this); + if (parent && parent->GetType() == nsGkAtoms::sliderFrame) { + aBuilder->GetScrollbarInfo(&scrollTargetId, &flags); + forceLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID); + nsLayoutUtils::SetScrollbarThumbLayerization(this, forceLayer); } + } + // Check for frames that are marked as a part of the region used + // in calculating glass margins on Windows. + const nsStyleDisplay* styles = StyleDisplay(); + if (styles && styles->mAppearance == NS_THEME_WIN_EXCLUDE_GLASS) { + aBuilder->AddWindowExcludeGlassRegion( + nsRect(aBuilder->ToReferenceFrame(this), GetSize())); + } } nsDisplayListCollection tempLists; @@ -1337,9 +1366,10 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, masterList.AppendToTop(tempLists.Content()); masterList.AppendToTop(tempLists.PositionedDescendants()); masterList.AppendToTop(tempLists.Outlines()); + // Wrap the list to make it its own layer aLists.Content()->AppendNewToTop(new (aBuilder) - nsDisplayOwnLayer(aBuilder, this, &masterList)); + nsDisplayOwnLayer(aBuilder, this, &masterList, flags, scrollTargetId)); } } @@ -1401,51 +1431,47 @@ nsBoxFrame::PaintXULDebugBackground(nsRenderingContext& aRenderingContext, inner.Deflate(border); //nsRect borderRect(inner); - nscolor color; - if (isHorizontal) { - color = NS_RGB(0,0,255); - } else { - color = NS_RGB(255,0,0); - } + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); + + ColorPattern color(ToDeviceColor(isHorizontal ? Color(0.f, 0.f, 1.f, 1.f) : + Color(1.f, 0.f, 0.f, 1.f))); - aRenderingContext.SetColor(color); + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); //left nsRect r(inner); r.width = debugBorder.left; - aRenderingContext.FillRect(r); + drawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); // top r = inner; r.height = debugBorder.top; - aRenderingContext.FillRect(r); + drawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); //right r = inner; r.x = r.x + r.width - debugBorder.right; r.width = debugBorder.right; - aRenderingContext.FillRect(r); + drawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); //bottom r = inner; r.y = r.y + r.height - debugBorder.bottom; r.height = debugBorder.bottom; - aRenderingContext.FillRect(r); - + drawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); // if we have dirty children or we are dirty // place a green border around us. if (NS_SUBTREE_DIRTY(this)) { - nsRect dirtyr(inner); - aRenderingContext.SetColor(NS_RGB(0,255,0)); - aRenderingContext.DrawRect(dirtyr); - aRenderingContext.SetColor(color); + nsRect dirty(inner); + ColorPattern green(ToDeviceColor(Color(0.f, 1.f, 0.f, 1.f))); + drawTarget->StrokeRect(NSRectToRect(dirty, appUnitsPerDevPixel), green); } } void -nsBoxFrame::PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, - nsPoint aPt) +nsBoxFrame::PaintXULDebugOverlay(DrawTarget& aDrawTarget, nsPoint aPt) +{ nsMargin border; GetBorder(border); @@ -1460,7 +1486,7 @@ nsBoxFrame::PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, nscoord onePixel = GetPresContext()->IntScaledPixelsToTwips(1); - kid = GetChildBox(); + kid = nsBox::GetChildBox(this); while (nullptr != kid) { bool isHorizontal = IsHorizontal(); @@ -1488,17 +1514,15 @@ nsBoxFrame::PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, nscoord flex = kid->GetFlex(state); if (!kid->IsCollapsed()) { - aRenderingContext.SetColor(NS_RGB(255,255,255)); - if (isHorizontal) borderSize = cr.width; else borderSize = cr.height; - - DrawSpacer(GetPresContext(), aRenderingContext, isHorizontal, flex, x, y, borderSize, spacerSize); + + DrawSpacer(GetPresContext(), aDrawTarget, isHorizontal, flex, x, y, borderSize, spacerSize); } - kid = kid->GetNextBox(); + kid = GetNextBox(kid); } } #endif @@ -1511,8 +1535,8 @@ nsBoxFrame::GetBoxName(nsAutoString& aName) } #endif -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("Box"), aResult); @@ -1526,7 +1550,7 @@ nsBoxFrame::GetType() const } #ifdef DEBUG_LAYOUT -NS_IMETHODIMP +nsresult nsBoxFrame::GetDebug(bool& aDebug) { aDebug = (mState & NS_STATE_CURRENTLY_IN_DEBUG); @@ -1570,25 +1594,34 @@ nsBoxFrame::GetDebug(bool& aDebug) #ifdef DEBUG_LAYOUT void -nsBoxFrame::DrawLine(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2) +nsBoxFrame::DrawLine(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2) { - if (aHorizontal) - aRenderingContext.DrawLine(x1,y1,x2,y2); - else - aRenderingContext.DrawLine(y1,x1,y2,x2); + nsPoint p1(x1, y1); + nsPoint p2(x2, y2); + if (!aHorizontal) { + Swap(p1.x, p1.y); + Swap(p2.x, p2.y); + } + ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f))); + StrokeLineWithSnapping(p1, p2, PresContext()->AppUnitsPerDevPixel(), + aDrawTarget, color); } void -nsBoxFrame::FillRect(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height) +nsBoxFrame::FillRect(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height) { - if (aHorizontal) - aRenderingContext.FillRect(x,y,width,height); - else - aRenderingContext.FillRect(y,x,height,width); + Rect rect = NSRectToSnappedRect(aHorizontal ? nsRect(x, y, width, height) : + nsRect(y, x, height, width), + PresContext()->AppUnitsPerDevPixel(), + aDrawTarget); + ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f))); + aDrawTarget.FillRect(rect, white); } void -nsBoxFrame::DrawSpacer(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize) +nsBoxFrame::DrawSpacer(nsPresContext* aPresContext, DrawTarget& aDrawTarget, + bool aHorizontal, int32_t flex, nscoord x, nscoord y, + nscoord size, nscoord spacerSize) { nscoord onePixel = aPresContext->IntScaledPixelsToTwips(1); @@ -1608,21 +1641,19 @@ nsBoxFrame::DrawSpacer(nsPresContext* aPresContext, nsRenderingContext& aRenderi int halfCoilSize = coilSize/2; if (flex == 0) { - DrawLine(aRenderingContext, aHorizontal, x,y + spacerSize/2, x + size, y + spacerSize/2); + DrawLine(aDrawTarget, aHorizontal, x,y + spacerSize/2, x + size, y + spacerSize/2); } else { for (int i=0; i < coils; i++) { - DrawLine(aRenderingContext, aHorizontal, offset, center+halfSpacer, offset+halfCoilSize, center-halfSpacer); - DrawLine(aRenderingContext, aHorizontal, offset+halfCoilSize, center-halfSpacer, offset+coilSize, center+halfSpacer); + DrawLine(aDrawTarget, aHorizontal, offset, center+halfSpacer, offset+halfCoilSize, center-halfSpacer); + DrawLine(aDrawTarget, aHorizontal, offset+halfCoilSize, center-halfSpacer, offset+coilSize, center+halfSpacer); offset += coilSize; } } - FillRect(aRenderingContext, aHorizontal, x + size - spacerSize/2, y, spacerSize/2, spacerSize); - FillRect(aRenderingContext, aHorizontal, x, y, spacerSize/2, spacerSize); - - //DrawKnob(aPresContext, aRenderingContext, x + size - spacerSize, y, spacerSize); + FillRect(aDrawTarget, aHorizontal, x + size - spacerSize/2, y, spacerSize/2, spacerSize); + FillRect(aDrawTarget, aHorizontal, x, y, spacerSize/2, spacerSize); } void @@ -1715,7 +1746,7 @@ nsBoxFrame::DisplayDebugInfoFor(nsIFrame* aBox, //printf("%%%%%% inside box %%%%%%%\n"); int count = 0; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); nsMargin m; nsMargin m2; @@ -1804,7 +1835,7 @@ nsBoxFrame::DisplayDebugInfoFor(nsIFrame* aBox, return NS_OK; } - child = child->GetNextBox(); + child = GetNextBox(child); count++; } } else { @@ -1818,11 +1849,11 @@ nsBoxFrame::DisplayDebugInfoFor(nsIFrame* aBox, void nsBoxFrame::SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug) { - nsIFrame* child = GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(this); while (child) { child->SetDebug(aState, aDebug); - child = child->GetNextBox(); + child = GetNextBox(child); } } @@ -1867,7 +1898,7 @@ nsBoxFrame::RegUnregAccessKey(bool aDoReg) // With a valid PresContext we can get the ESM // and register the access key - nsEventStateManager *esm = PresContext()->EventStateManager(); + EventStateManager* esm = PresContext()->EventStateManager(); uint32_t key = accessKey.First(); if (aDoReg) @@ -1898,8 +1929,8 @@ void nsBoxFrame::CheckBoxOrder() { if (SupportsOrdinalsInChildren() && - !nsLayoutUtils::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) { - nsLayoutUtils::SortFrameList<IsBoxOrdinalLEQ>(mFrames); + !nsIFrame::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) { + nsIFrame::SortFrameList<IsBoxOrdinalLEQ>(mFrames); } } @@ -1919,7 +1950,7 @@ nsBoxFrame::LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, const nsRect return NS_OK; } -NS_IMETHODIMP +nsresult nsBoxFrame::RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) { if (!SupportsOrdinalsInChildren()) @@ -1939,7 +1970,7 @@ nsBoxFrame::RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) newPrevSib = child; } - child = child->GetNextBox(); + child = GetNextBox(child); } if (aChild->GetPrevSibling() == newPrevSib) { @@ -1989,7 +2020,11 @@ public: nsIFrame* aTargetFrame) : nsDisplayWrapList(aBuilder, aFrame, aList), mTargetFrame(aTargetFrame) {} virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); + HitTestState* aState, + nsTArray<nsIFrame*> *aOutFrames) override; + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override { + return false; + } NS_DISPLAY_DECL_NAME("XULEventRedirector", TYPE_XUL_EVENT_REDIRECTOR) private: nsIFrame* mTargetFrame; @@ -2029,15 +2064,16 @@ void nsDisplayXULEventRedirector::HitTest(nsDisplayListBuilder* aBuilder, class nsXULEventRedirectorWrapper : public nsDisplayWrapper { public: - nsXULEventRedirectorWrapper(nsIFrame* aTargetFrame) + explicit nsXULEventRedirectorWrapper(nsIFrame* aTargetFrame) : mTargetFrame(aTargetFrame) {} virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame, nsDisplayList* aList) { + nsIFrame* aFrame, + nsDisplayList* aList) override { return new (aBuilder) nsDisplayXULEventRedirector(aBuilder, aFrame, aList, mTargetFrame); } virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder, - nsDisplayItem* aItem) { + nsDisplayItem* aItem) override { return new (aBuilder) nsDisplayXULEventRedirector(aBuilder, aItem->Frame(), aItem, mTargetFrame); @@ -2056,31 +2092,31 @@ nsBoxFrame::WrapListsInRedirector(nsDisplayListBuilder* aBuilder, } bool -nsBoxFrame::GetEventPoint(nsGUIEvent* aEvent, nsPoint &aPoint) { - nsIntPoint refPoint; +nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsPoint &aPoint) { + LayoutDeviceIntPoint refPoint; bool res = GetEventPoint(aEvent, refPoint); - aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, refPoint, this); + aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo( + aEvent, refPoint, this); return res; } bool -nsBoxFrame::GetEventPoint(nsGUIEvent* aEvent, nsIntPoint &aPoint) { +nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, LayoutDeviceIntPoint& aPoint) { NS_ENSURE_TRUE(aEvent, false); - if (aEvent->eventStructType == NS_TOUCH_EVENT) { - nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent); + WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent(); + if (touchEvent) { // return false if there is more than one touch on the page, or if // we can't find a touch point if (touchEvent->touches.Length() != 1) { return false; } - nsIDOMTouch *touch = touchEvent->touches.SafeElementAt(0); + dom::Touch* touch = touchEvent->touches.SafeElementAt(0); if (!touch) { return false; } - Touch* domtouch = static_cast<Touch*>(touch); - aPoint = domtouch->mRefPoint; + aPoint = touch->mRefPoint; } else { aPoint = aEvent->refPoint; } diff --git a/layout/xul/base/src/nsBoxFrame.h b/layout/xul/nsBoxFrame.h index a22358565..dc4741517 100644 --- a/layout/xul/base/src/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -21,21 +21,11 @@ class nsBoxLayoutState; -// flags from box -#define NS_STATE_BOX_CHILD_RESERVED NS_FRAME_STATE_BIT(20) -#define NS_STATE_STACK_NOT_POSITIONED NS_FRAME_STATE_BIT(21) -//#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22) moved to nsIFrame.h -#define NS_STATE_AUTO_STRETCH NS_FRAME_STATE_BIT(23) -//#define NS_STATE_IS_ROOT NS_FRAME_STATE_BIT(24) moved to nsBox.h -#define NS_STATE_CURRENTLY_IN_DEBUG NS_FRAME_STATE_BIT(25) -//#define NS_STATE_SET_TO_DEBUG NS_FRAME_STATE_BIT(26) moved to nsBox.h -//#define NS_STATE_DEBUG_WAS_SET NS_FRAME_STATE_BIT(27) moved to nsBox.h -#define NS_STATE_MENU_HAS_POPUP_LIST NS_FRAME_STATE_BIT(28) /* used on nsMenuFrame */ -#define NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK NS_FRAME_STATE_BIT(29) -#define NS_STATE_EQUAL_SIZE NS_FRAME_STATE_BIT(30) -//#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31) moved to nsIFrame.h -#define NS_FRAME_MOUSE_THROUGH_ALWAYS NS_FRAME_STATE_BIT(60) -#define NS_FRAME_MOUSE_THROUGH_NEVER NS_FRAME_STATE_BIT(61) +namespace mozilla { +namespace gfx { +class DrawTarget; +} +} nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, @@ -46,8 +36,15 @@ nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, class nsBoxFrame : public nsContainerFrame { +protected: + typedef mozilla::gfx::DrawTarget DrawTarget; + public: NS_DECL_FRAMEARENA_HELPERS +#ifdef DEBUG + NS_DECL_QUERYFRAME_TARGET(nsBoxFrame) + NS_DECL_QUERYFRAME +#endif friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, @@ -59,68 +56,65 @@ public: // gets the rect inside our border and debug border. If you wish to paint inside a box // call this method to get the rect so you don't draw on the debug border or outer border. - virtual void SetLayoutManager(nsBoxLayout* aLayout) MOZ_OVERRIDE { mLayoutManager = aLayout; } - virtual nsBoxLayout* GetLayoutManager() MOZ_OVERRIDE { return mLayoutManager; } + virtual void SetLayoutManager(nsBoxLayout* aLayout) override { mLayoutManager = aLayout; } + virtual nsBoxLayout* GetLayoutManager() override { return mLayoutManager; } - NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) MOZ_OVERRIDE; + virtual nsresult RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) override; - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; #ifdef DEBUG_LAYOUT - NS_IMETHOD SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug) MOZ_OVERRIDE; - NS_IMETHOD GetDebug(bool& aDebug) MOZ_OVERRIDE; + virtual nsresult SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug) override; + virtual nsresult GetDebug(bool& aDebug) override; #endif - virtual Valignment GetVAlign() const MOZ_OVERRIDE { return mValign; } - virtual Halignment GetHAlign() const MOZ_OVERRIDE { return mHalign; } - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual Valignment GetVAlign() const override { return mValign; } + virtual Halignment GetHAlign() const override { return mHalign; } + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; - virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; } + virtual bool ComputesOwnOverflowArea() override { return false; } // ----- child and sibling operations --- // ----- public methods ------- - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* asPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; - virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; - virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual void MarkIntrinsicISizesDirty() override; + virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; + virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; - NS_IMETHOD Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) MOZ_OVERRIDE; + virtual void Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) override; - NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) MOZ_OVERRIDE; + virtual void SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) override; + virtual void AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) override; + virtual void InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) override; + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; - NS_IMETHOD InsertFrames(ChildListID aListID, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList) MOZ_OVERRIDE; + virtual nsContainerFrame* GetContentInsertionFrame() override; - NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) MOZ_OVERRIDE; + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; - virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE; + virtual nsIAtom* GetType() const override; - NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) MOZ_OVERRIDE; - - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; - - virtual nsIAtom* GetType() const MOZ_OVERRIDE; - - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + virtual bool IsFrameOfType(uint32_t aFlags) const override { // record that children that are ignorable whitespace should be excluded // (When content was loaded via the XUL content sink, it's already @@ -137,19 +131,19 @@ public: nsIFrame::eExcludesIgnorableWhitespace)); } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif - NS_IMETHOD DidReflow(nsPresContext* aPresContext, - const nsHTMLReflowState* aReflowState, - nsDidReflowStatus aStatus) MOZ_OVERRIDE; + virtual void DidReflow(nsPresContext* aPresContext, + const nsHTMLReflowState* aReflowState, + nsDidReflowStatus aStatus) override; - virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE; + virtual bool HonorPrintBackgroundSettings() override; virtual ~nsBoxFrame(); - nsBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot = false, nsBoxLayout* aLayoutManager = nullptr); + explicit nsBoxFrame(nsStyleContext* aContext, bool aIsRoot = false, nsBoxLayout* aLayoutManager = nullptr); // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame // can override it @@ -159,7 +153,7 @@ public: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; #ifdef DEBUG_LAYOUT virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug); @@ -186,10 +180,10 @@ public: protected: #ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; + virtual void GetBoxName(nsAutoString& aName) override; void PaintXULDebugBackground(nsRenderingContext& aRenderingContext, nsPoint aPt); - void PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, + void PaintXULDebugOverlay(DrawTarget& aRenderingContext, nsPoint aPt); #endif @@ -200,7 +194,7 @@ protected: virtual bool GetInitialVAlignment(Valignment& aValign); virtual bool GetInitialAutoStretch(bool& aStretch); - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; nsSize mPrefSize; nsSize mMinSize; @@ -212,15 +206,16 @@ protected: // Get the point associated with this event. Returns true if a single valid // point was found. Otherwise false. - bool GetEventPoint(nsGUIEvent *aEvent, nsPoint &aPoint); + bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint); // Gets the event coordinates relative to the widget offset associated with // this frame. Return true if a single valid point was found. - bool GetEventPoint(nsGUIEvent *aEvent, nsIntPoint &aPoint); + bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, + mozilla::LayoutDeviceIntPoint& aPoint); protected: void RegUnregAccessKey(bool aDoReg); - NS_HIDDEN_(void) CheckBoxOrder(); + void CheckBoxOrder(); private: @@ -239,9 +234,9 @@ private: void GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, char* value); void GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* value); - void DrawSpacer(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize); - void DrawLine(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2); - void FillRect(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height); + void DrawSpacer(nsPresContext* aPresContext, DrawTarget& aDrawTarget, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize); + void DrawLine(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2); + void FillRect(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height); #endif virtual void UpdateMouseThrough(); diff --git a/layout/xul/base/src/nsBoxLayout.cpp b/layout/xul/nsBoxLayout.cpp index 223cef7f5..4783f0269 100644 --- a/layout/xul/base/src/nsBoxLayout.cpp +++ b/layout/xul/nsBoxLayout.cpp @@ -91,4 +91,4 @@ nsBoxLayout::AddSmallestSize(nsSize& aSize, const nsSize& aSize2) aSize.height = aSize2.height; } -NS_IMPL_ISUPPORTS1(nsBoxLayout, nsBoxLayout) +NS_IMPL_ISUPPORTS(nsBoxLayout, nsBoxLayout) diff --git a/layout/xul/base/src/nsBoxLayout.h b/layout/xul/nsBoxLayout.h index 201ee61fe..77c1011f8 100644 --- a/layout/xul/base/src/nsBoxLayout.h +++ b/layout/xul/nsBoxLayout.h @@ -23,10 +23,12 @@ class nsIGridPart; class nsBoxLayout : public nsISupports { +protected: + virtual ~nsBoxLayout() {} + public: nsBoxLayout() {} - virtual ~nsBoxLayout() {} NS_DECL_ISUPPORTS @@ -45,7 +47,7 @@ public: const nsFrameList::Slice& aNewChildren) {} virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) {} virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) {} - virtual void IntrinsicWidthsDirty(nsIFrame* aBox, nsBoxLayoutState& aState) {} + virtual void IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& aState) {} virtual void AddBorderAndPadding(nsIFrame* aBox, nsSize& aSize); virtual void AddMargin(nsIFrame* aChild, nsSize& aSize); diff --git a/layout/xul/base/src/nsBoxLayoutState.cpp b/layout/xul/nsBoxLayoutState.cpp index 603020e0b..603020e0b 100644 --- a/layout/xul/base/src/nsBoxLayoutState.cpp +++ b/layout/xul/nsBoxLayoutState.cpp diff --git a/layout/xul/base/src/nsBoxLayoutState.h b/layout/xul/nsBoxLayoutState.h index 0cd9da5ab..cf07e6409 100644 --- a/layout/xul/base/src/nsBoxLayoutState.h +++ b/layout/xul/nsBoxLayoutState.h @@ -19,7 +19,7 @@ class nsRenderingContext; class nsCalculatedBoxInfo; -struct nsHTMLReflowMetrics; +class nsHTMLReflowMetrics; struct nsHTMLReflowState; class nsString; class nsHTMLReflowCommand; @@ -27,12 +27,12 @@ class nsHTMLReflowCommand; class MOZ_STACK_CLASS nsBoxLayoutState { public: - nsBoxLayoutState(nsPresContext* aPresContext, - nsRenderingContext* aRenderingContext = nullptr, - // see OuterReflowState() below - const nsHTMLReflowState* aOuterReflowState = nullptr, - uint16_t aReflowDepth = 0) NS_HIDDEN; - nsBoxLayoutState(const nsBoxLayoutState& aState) NS_HIDDEN; + explicit nsBoxLayoutState(nsPresContext* aPresContext, + nsRenderingContext* aRenderingContext = nullptr, + // see OuterReflowState() below + const nsHTMLReflowState* aOuterReflowState = nullptr, + uint16_t aReflowDepth = 0); + nsBoxLayoutState(const nsBoxLayoutState& aState); nsPresContext* PresContext() const { return mPresContext; } nsIPresShell* PresShell() const { return mPresContext->PresShell(); } @@ -51,7 +51,7 @@ public: nsRenderingContext* GetRenderingContext() const { return mRenderingContext; } struct AutoReflowDepth { - AutoReflowDepth(nsBoxLayoutState& aState) + explicit AutoReflowDepth(nsBoxLayoutState& aState) : mState(aState) { ++mState.mReflowDepth; } ~AutoReflowDepth() { --mState.mReflowDepth; } nsBoxLayoutState& mState; diff --git a/layout/xul/base/src/nsButtonBoxFrame.cpp b/layout/xul/nsButtonBoxFrame.cpp index 7c0572f4f..c3777c070 100644 --- a/layout/xul/base/src/nsButtonBoxFrame.cpp +++ b/layout/xul/nsButtonBoxFrame.cpp @@ -8,16 +8,19 @@ #include "nsIDOMNodeList.h" #include "nsIDOMXULButtonElement.h" #include "nsGkAtoms.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsPresContext.h" #include "nsIPresShell.h" -#include "nsGUIEvent.h" -#include "nsEventStateManager.h" #include "nsIDOMElement.h" #include "nsDisplayList.h" #include "nsContentUtils.h" #include "mozilla/dom/Element.h" +#include "mozilla/EventStateManager.h" +#include "mozilla/EventStates.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TextEvents.h" +using namespace mozilla; // // NS_NewXULButtonFrame @@ -27,7 +30,7 @@ nsIFrame* NS_NewButtonBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsButtonBoxFrame(aPresShell, aContext); + return new (aPresShell) nsButtonBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsButtonBoxFrame) @@ -43,9 +46,9 @@ nsButtonBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } -NS_IMETHODIMP +nsresult nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); @@ -54,65 +57,73 @@ nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext, } switch (aEvent->message) { - case NS_KEY_DOWN: - if (NS_KEY_EVENT == aEvent->eventStructType) { - nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; - if (NS_VK_SPACE == keyEvent->keyCode) { - nsEventStateManager *esm = aPresContext->EventStateManager(); - // :hover:active state - esm->SetContentState(mContent, NS_EVENT_STATE_HOVER); - esm->SetContentState(mContent, NS_EVENT_STATE_ACTIVE); - } + case NS_KEY_DOWN: { + WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); + if (!keyEvent) { + break; + } + if (NS_VK_SPACE == keyEvent->keyCode) { + EventStateManager* esm = aPresContext->EventStateManager(); + // :hover:active state + esm->SetContentState(mContent, NS_EVENT_STATE_HOVER); + esm->SetContentState(mContent, NS_EVENT_STATE_ACTIVE); } break; + } -// On mac, Return fires the defualt button, not the focused one. +// On mac, Return fires the default button, not the focused one. #ifndef XP_MACOSX - case NS_KEY_PRESS: - if (NS_KEY_EVENT == aEvent->eventStructType) { - nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; - if (NS_VK_RETURN == keyEvent->keyCode) { - nsCOMPtr<nsIDOMXULButtonElement> buttonEl(do_QueryInterface(mContent)); - if (buttonEl) { - MouseClicked(aPresContext, aEvent); - *aEventStatus = nsEventStatus_eConsumeNoDefault; - } + case NS_KEY_PRESS: { + WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); + if (!keyEvent) { + break; + } + if (NS_VK_RETURN == keyEvent->keyCode) { + nsCOMPtr<nsIDOMXULButtonElement> buttonEl(do_QueryInterface(mContent)); + if (buttonEl) { + MouseClicked(aPresContext, aEvent); + *aEventStatus = nsEventStatus_eConsumeNoDefault; } } break; + } #endif - case NS_KEY_UP: - if (NS_KEY_EVENT == aEvent->eventStructType) { - nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; - if (NS_VK_SPACE == keyEvent->keyCode) { - // only activate on keyup if we're already in the :hover:active state - NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?"); - nsEventStates buttonState = mContent->AsElement()->State(); - if (buttonState.HasAllStates(NS_EVENT_STATE_ACTIVE | - NS_EVENT_STATE_HOVER)) { - // return to normal state - nsEventStateManager *esm = aPresContext->EventStateManager(); - esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE); - esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); - MouseClicked(aPresContext, aEvent); - } + case NS_KEY_UP: { + WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); + if (!keyEvent) { + break; + } + if (NS_VK_SPACE == keyEvent->keyCode) { + // only activate on keyup if we're already in the :hover:active state + NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?"); + EventStates buttonState = mContent->AsElement()->State(); + if (buttonState.HasAllStates(NS_EVENT_STATE_ACTIVE | + NS_EVENT_STATE_HOVER)) { + // return to normal state + EventStateManager* esm = aPresContext->EventStateManager(); + esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE); + esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); + MouseClicked(aPresContext, aEvent); } } break; + } - case NS_MOUSE_CLICK: - if (NS_IS_MOUSE_LEFT_CLICK(aEvent)) { - MouseClicked(aPresContext, aEvent); + case NS_MOUSE_CLICK: { + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); + if (mouseEvent->IsLeftClickEvent()) { + MouseClicked(aPresContext, mouseEvent); } break; + } } return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } void -nsButtonBoxFrame::DoMouseClick(nsGUIEvent* aEvent, bool aTrustEvent) +nsButtonBoxFrame::DoMouseClick(WidgetGUIEvent* aEvent, bool aTrustEvent) { // Don't execute if we're disabled. if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, @@ -125,10 +136,11 @@ nsButtonBoxFrame::DoMouseClick(nsGUIEvent* aEvent, bool aTrustEvent) bool isAlt = false; bool isMeta = false; if(aEvent) { - isShift = ((nsInputEvent*)(aEvent))->IsShift(); - isControl = ((nsInputEvent*)(aEvent))->IsControl(); - isAlt = ((nsInputEvent*)(aEvent))->IsAlt(); - isMeta = ((nsInputEvent*)(aEvent))->IsMeta(); + WidgetInputEvent* inputEvent = aEvent->AsInputEvent(); + isShift = inputEvent->IsShift(); + isControl = inputEvent->IsControl(); + isAlt = inputEvent->IsAlt(); + isMeta = inputEvent->IsMeta(); } // Have the content handle the event, propagating it according to normal DOM rules. diff --git a/layout/xul/base/src/nsButtonBoxFrame.h b/layout/xul/nsButtonBoxFrame.h index 5b66473a6..05a1d3b67 100644 --- a/layout/xul/base/src/nsButtonBoxFrame.h +++ b/layout/xul/nsButtonBoxFrame.h @@ -15,24 +15,25 @@ public: friend nsIFrame* NS_NewButtonBoxFrame(nsIPresShell* aPresShell); - nsButtonBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) - :nsBoxFrame(aPresShell, aContext, false) { + explicit nsButtonBoxFrame(nsStyleContext* aContext) + :nsBoxFrame(aContext, false) { UpdateMouseThrough(); } virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - virtual void MouseClicked (nsPresContext* aPresContext, nsGUIEvent* aEvent) + virtual void MouseClicked(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent) { DoMouseClick(aEvent, false); } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("ButtonBoxFrame"), aResult); } #endif @@ -41,8 +42,8 @@ public: * Our implementation of MouseClicked. * @param aTrustEvent if true and aEvent as null, then assume the event was trusted */ - void DoMouseClick(nsGUIEvent* aEvent, bool aTrustEvent); - void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } + void DoMouseClick(mozilla::WidgetGUIEvent* aEvent, bool aTrustEvent); + void UpdateMouseThrough() override { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } }; // class nsButtonBoxFrame #endif /* nsButtonBoxFrame_h___ */ diff --git a/layout/xul/base/src/nsDeckFrame.cpp b/layout/xul/nsDeckFrame.cpp index ecf0d1256..0aa59e8d2 100644 --- a/layout/xul/base/src/nsDeckFrame.cpp +++ b/layout/xul/nsDeckFrame.cpp @@ -15,7 +15,7 @@ #include "nsPresContext.h" #include "nsIContent.h" #include "nsCOMPtr.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsHTMLParts.h" #include "nsIPresShell.h" @@ -25,6 +25,7 @@ #include "nsStackLayout.h" #include "nsDisplayList.h" #include "nsContainerFrame.h" +#include "nsContentUtils.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" @@ -33,7 +34,7 @@ nsIFrame* NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsDeckFrame(aPresShell, aContext); + return new (aPresShell) nsDeckFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame) @@ -43,11 +44,11 @@ NS_QUERYFRAME_HEAD(nsDeckFrame) NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) -nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) - : nsBoxFrame(aPresShell, aContext), mIndex(0) +nsDeckFrame::nsDeckFrame(nsStyleContext* aContext) + : nsBoxFrame(aContext), mIndex(0) { nsCOMPtr<nsBoxLayout> layout; - NS_NewStackLayout(aPresShell, layout); + NS_NewStackLayout(PresContext()->PresShell(), layout); SetLayoutManager(layout); } @@ -57,7 +58,7 @@ nsDeckFrame::GetType() const return nsGkAtoms::deckFrame; } -NS_IMETHODIMP +nsresult nsDeckFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -75,9 +76,9 @@ nsDeckFrame::AttributeChanged(int32_t aNameSpaceID, } void -nsDeckFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsDeckFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); @@ -155,6 +156,34 @@ nsDeckFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } void +nsDeckFrame::RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) +{ + nsIFrame* currentFrame = GetSelectedBox(); + if (currentFrame && + aOldFrame && + currentFrame != aOldFrame) { + // If the frame we're removing is at an index that's less + // than mIndex, that means we're going to be shifting indexes + // by 1. + // + // We attempt to keep the same child displayed by automatically + // updating our internal notion of the current index. + int32_t removedIndex = mFrames.IndexOf(aOldFrame); + MOZ_ASSERT(removedIndex >= 0, + "A deck child was removed that was not in mFrames."); + if (removedIndex < mIndex) { + mIndex--; + // This is going to cause us to handle the index change in IndexedChanged, + // but since the new index will match mIndex, it's essentially a noop. + nsContentUtils::AddScriptRunner(new nsSetAttrRunnable( + mContent, nsGkAtoms::selectedIndex, mIndex)); + } + } + nsBoxFrame::RemoveFrame(aListID, aOldFrame); +} + +void nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) @@ -182,7 +211,7 @@ nsDeckFrame::DoLayout(nsBoxLayoutState& aState) nsresult rv = nsBoxFrame::DoLayout(aState); // run though each child. Hide all but the selected one - nsIFrame* box = GetChildBox(); + nsIFrame* box = nsBox::GetChildBox(this); nscoord count = 0; while (box) @@ -191,7 +220,7 @@ nsDeckFrame::DoLayout(nsBoxLayoutState& aState) if (count != mIndex) HideBox(box); - box = box->GetNextBox(); + box = GetNextBox(box); count++; } diff --git a/layout/xul/base/src/nsDeckFrame.h b/layout/xul/nsDeckFrame.h index f0c6f7d54..5639bcac7 100644 --- a/layout/xul/base/src/nsDeckFrame.h +++ b/layout/xul/nsDeckFrame.h @@ -27,34 +27,37 @@ public: friend nsIFrame* NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - NS_IMETHOD DoLayout(nsBoxLayoutState& aState) MOZ_OVERRIDE; + NS_IMETHOD DoLayout(nsBoxLayoutState& aState) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; + + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - virtual nsIAtom* GetType() const MOZ_OVERRIDE; + virtual nsIAtom* GetType() const override; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("Deck"), aResult); } #endif - nsDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + explicit nsDeckFrame(nsStyleContext* aContext); nsIFrame* GetSelectedBox(); diff --git a/layout/xul/base/src/nsDocElementBoxFrame.cpp b/layout/xul/nsDocElementBoxFrame.cpp index 88bd4f834..086692cfa 100644 --- a/layout/xul/base/src/nsDocElementBoxFrame.cpp +++ b/layout/xul/nsDocElementBoxFrame.cpp @@ -7,7 +7,6 @@ #include "nsCSSRendering.h" #include "nsIDocument.h" #include "nsPageFrame.h" -#include "nsGUIEvent.h" #include "nsIDOMEvent.h" #include "nsStyleConsts.h" #include "nsGkAtoms.h" @@ -15,36 +14,39 @@ #include "nsBoxFrame.h" #include "nsStackLayout.h" #include "nsIAnonymousContentCreator.h" -#include "nsINodeInfo.h" +#include "mozilla/dom/NodeInfo.h" #include "nsIServiceManager.h" #include "nsNodeInfoManager.h" #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsContentList.h" +#include "mozilla/dom/Element.h" //#define DEBUG_REFLOW +using namespace mozilla::dom; + class nsDocElementBoxFrame : public nsBoxFrame, public nsIAnonymousContentCreator { public: - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - nsDocElementBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext) - :nsBoxFrame(aShell, aContext, true) {} + explicit nsDocElementBoxFrame(nsStyleContext* aContext) + :nsBoxFrame(aContext, true) {} NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements); - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, - uint32_t aFilter); + virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override; + virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, + uint32_t aFilter) override; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const override { // Override nsBoxFrame. if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) @@ -52,20 +54,20 @@ public: return nsBoxFrame::IsFrameOfType(aFlags); } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif private: - nsCOMPtr<nsIContent> mPopupgroupContent; - nsCOMPtr<nsIContent> mTooltipContent; + nsCOMPtr<Element> mPopupgroupContent; + nsCOMPtr<Element> mTooltipContent; }; //---------------------------------------------------------------------- -nsIFrame* +nsContainerFrame* NS_NewDocElementBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsDocElementBoxFrame (aPresShell, aContext); + return new (aPresShell) nsDocElementBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsDocElementBoxFrame) @@ -81,7 +83,7 @@ nsDocElementBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) nsresult nsDocElementBoxFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) { - nsIDocument* doc = mContent->GetDocument(); + nsIDocument* doc = mContent->GetComposedDoc(); if (!doc) { // The page is currently being torn down. Why bother. return NS_ERROR_FAILURE; @@ -89,7 +91,7 @@ nsDocElementBoxFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) nsNodeInfoManager *nodeInfoManager = doc->NodeInfoManager(); // create the top-secret popupgroup node. shhhhh! - nsCOMPtr<nsINodeInfo> nodeInfo; + nsRefPtr<NodeInfo> nodeInfo; nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::popupgroup, nullptr, kNameSpaceID_XUL, nsIDOMNode::ELEMENT_NODE); @@ -121,19 +123,24 @@ nsDocElementBoxFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) } void -nsDocElementBoxFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsDocElementBoxFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mPopupgroupContent); - aElements.MaybeAppendElement(mTooltipContent); + if (mPopupgroupContent) { + aElements.AppendElement(mPopupgroupContent); + } + + if (mTooltipContent) { + aElements.AppendElement(mTooltipContent); + } } NS_QUERYFRAME_HEAD(nsDocElementBoxFrame) NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsDocElementBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("DocElementBox"), aResult); diff --git a/layout/xul/base/src/nsGroupBoxFrame.cpp b/layout/xul/nsGroupBoxFrame.cpp index 159ca121c..a82b2037a 100644 --- a/layout/xul/base/src/nsGroupBoxFrame.cpp +++ b/layout/xul/nsGroupBoxFrame.cpp @@ -6,31 +6,37 @@ // YY need to pass isMultiple before create called #include "nsBoxFrame.h" + +#include "mozilla/gfx/2D.h" #include "nsCSSRendering.h" +#include "nsLayoutUtils.h" #include "nsRenderingContext.h" #include "nsStyleContext.h" #include "nsDisplayList.h" +using namespace mozilla; +using namespace mozilla::gfx; + class nsGroupBoxFrame : public nsBoxFrame { public: NS_DECL_FRAMEARENA_HELPERS - nsGroupBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext) {} + explicit nsGroupBoxFrame(nsStyleContext* aContext): + nsBoxFrame(aContext) {} - NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding); + virtual nsresult GetBorderAndPadding(nsMargin& aBorderAndPadding) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const { +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("GroupBoxFrame"), aResult); } #endif - virtual bool HonorPrintBackgroundSettings() { return false; } + virtual bool HonorPrintBackgroundSettings() override { return false; } void PaintBorderBackground(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect); @@ -38,10 +44,10 @@ public: // make sure we our kids get our orient and align instead of us. // our child box has no content node so it will search for a parent with one. // that will be us. - virtual void GetInitialOrientation(bool& aHorizontal) { aHorizontal = false; } - virtual bool GetInitialHAlignment(Halignment& aHalign) { aHalign = hAlign_Left; return true; } - virtual bool GetInitialVAlignment(Valignment& aValign) { aValign = vAlign_Top; return true; } - virtual bool GetInitialAutoStretch(bool& aStretch) { aStretch = true; return true; } + virtual void GetInitialOrientation(bool& aHorizontal) override { aHorizontal = false; } + virtual bool GetInitialHAlignment(Halignment& aHalign) override { aHalign = hAlign_Left; return true; } + virtual bool GetInitialVAlignment(Valignment& aValign) override { aValign = vAlign_Top; return true; } + virtual bool GetInitialAutoStretch(bool& aStretch) override { aStretch = true; return true; } nsIFrame* GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect); }; @@ -54,7 +60,7 @@ public: nsBoxFrame(aShell, aContext) {} -#ifdef DEBUG +#ifdef DEBUG_FRAME_DUMP NS_IMETHOD GetFrameName(nsString& aResult) const { return MakeFrameName("GroupBoxFrameInner", aResult); } @@ -69,7 +75,7 @@ public: nsIFrame* NS_NewGroupBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsGroupBoxFrame(aPresShell, aContext); + return new (aPresShell) nsGroupBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsGroupBoxFrame) @@ -88,11 +94,11 @@ public: #endif virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) { + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override { aOutFrames->AppendElement(mFrame); } virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx); + nsRenderingContext* aCtx) override; NS_DISPLAY_DECL_NAME("XULGroupBackground", TYPE_XUL_GROUP_BACKGROUND) }; @@ -123,7 +129,11 @@ nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect) { - int skipSides = 0; + + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + + Sides skipSides; const nsStyleBorder* borderStyleData = StyleBorder(); const nsMargin& border = borderStyleData->GetComputedBorder(); nscoord yoff = 0; @@ -152,6 +162,7 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES); if (groupBox) { + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); // we should probably use PaintBorderEdges to do this but for now just use clipping // to achieve the same effect. @@ -161,13 +172,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = groupRect.x - rect.x; clipRect.height = border.top; - aRenderingContext.PushState(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.PopState(); - + gfx->Restore(); // draw right side clipRect = rect; @@ -175,14 +184,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = rect.XMost() - groupRect.XMost(); clipRect.height = border.top; - aRenderingContext.PushState(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.PopState(); - - + gfx->Restore(); // draw bottom @@ -190,12 +196,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.y += border.top; clipRect.height = mRect.height - (yoff + border.top); - aRenderingContext.PushState(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.PopState(); + gfx->Restore(); } else { nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, @@ -208,21 +213,21 @@ nsIFrame* nsGroupBoxFrame::GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect) { // first child is our grouped area - nsIFrame* box = GetChildBox(); + nsIFrame* box = nsBox::GetChildBox(this); // no area fail. if (!box) return nullptr; // get the first child in the grouped area, that is the caption - box = box->GetChildBox(); + box = nsBox::GetChildBox(box); // nothing in the area? fail if (!box) return nullptr; // now get the caption itself. It is in the caption frame. - nsIFrame* child = box->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(box); if (child) { // convert to our coordinates. @@ -235,7 +240,7 @@ nsGroupBoxFrame::GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect return child; } -NS_IMETHODIMP +nsresult nsGroupBoxFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding) { aBorderAndPadding.SizeTo(0,0,0,0); diff --git a/layout/xul/base/public/nsIBoxObject.idl b/layout/xul/nsIBoxObject.idl index 64b1a46f8..64b1a46f8 100644 --- a/layout/xul/base/public/nsIBoxObject.idl +++ b/layout/xul/nsIBoxObject.idl diff --git a/layout/xul/base/public/nsIBrowserBoxObject.idl b/layout/xul/nsIBrowserBoxObject.idl index f4f508a32..f3eee9159 100644 --- a/layout/xul/base/public/nsIBrowserBoxObject.idl +++ b/layout/xul/nsIBrowserBoxObject.idl @@ -6,10 +6,10 @@ #include "nsIContainerBoxObject.idl" /** - * @deprecated Please consider using nsIContainerBoxObject. + * @deprecated Please consider using ContainerBoxObject. */ -[scriptable, uuid(db436f2f-c656-4754-b0fa-99bc353bd63f)] +[uuid(db436f2f-c656-4754-b0fa-99bc353bd63f)] interface nsIBrowserBoxObject : nsIContainerBoxObject { }; diff --git a/layout/xul/base/public/nsIContainerBoxObject.idl b/layout/xul/nsIContainerBoxObject.idl index 3d546cf6f..f2eab0fbd 100644 --- a/layout/xul/base/public/nsIContainerBoxObject.idl +++ b/layout/xul/nsIContainerBoxObject.idl @@ -5,16 +5,10 @@ #include "nsISupports.idl" -interface nsIDocShell; -interface nsIBoxObject; +// DEPRECATED: This file exists for shim purposes only, +// see ContainerBoxObject.webidl -[scriptable, uuid(35d4c04b-3bd3-4375-92e2-a818b4b4acb6)] +[uuid(35d4c04b-3bd3-4375-92e2-a818b4b4acb6)] interface nsIContainerBoxObject : nsISupports { - readonly attribute nsIDocShell docShell; }; - -%{C++ -nsresult -NS_NewContainerBoxObject(nsIBoxObject** aResult); -%} diff --git a/layout/xul/base/public/nsIListBoxObject.idl b/layout/xul/nsIListBoxObject.idl index 7d44f24cc..198f76919 100644 --- a/layout/xul/base/public/nsIListBoxObject.idl +++ b/layout/xul/nsIListBoxObject.idl @@ -3,27 +3,17 @@ * 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/. */ -#include "nsIBoxObject.idl" +#include "nsISupports.idl" + +// DEPRECATED: see ListBoxObject.webidl interface nsIDOMElement; -[scriptable, uuid(AA9DEF4E-2E59-412d-A6DF-B76F52167795)] +[uuid(AA9DEF4E-2E59-412d-A6DF-B76F52167795)] interface nsIListBoxObject : nsISupports { long getRowCount(); - long getNumberOfVisibleRows(); - long getIndexOfFirstVisibleRow(); - - void ensureIndexIsVisible(in long rowIndex); - void scrollToIndex(in long rowIndex); - void scrollByLines(in long numLines); nsIDOMElement getItemAtIndex(in long index); long getIndexOfItem(in nsIDOMElement item); }; - -%{C++ -nsresult -NS_NewListBoxObject(nsIBoxObject** aResult); - -%} diff --git a/layout/xul/base/public/nsIIFrameBoxObject.idl b/layout/xul/nsIMenuBoxObject.idl index 966fce996..63c7811c4 100644 --- a/layout/xul/base/public/nsIIFrameBoxObject.idl +++ b/layout/xul/nsIMenuBoxObject.idl @@ -3,14 +3,12 @@ * 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/. */ -#include "nsIContainerBoxObject.idl" +#include "nsISupports.idl" -/** - * @deprecated Please consider using nsIContainerBoxObject. - */ +// DEPRECATED: This file exists for shim purposes only, +// see MenuBoxObject.webidl -[scriptable, uuid(30114c44-d398-44a5-9e01-b48b711291cd)] -interface nsIIFrameBoxObject : nsIContainerBoxObject +[uuid(689ebf3d-0184-450a-9bfa-5a26be0e7a8c)] +interface nsIMenuBoxObject : nsISupports { }; - diff --git a/layout/xul/base/src/nsIRootBox.h b/layout/xul/nsIRootBox.h index 9311f547e..9311f547e 100644 --- a/layout/xul/base/src/nsIRootBox.h +++ b/layout/xul/nsIRootBox.h diff --git a/layout/xul/base/public/nsIEditorBoxObject.idl b/layout/xul/nsIScrollBoxObject.idl index c5e54e409..fc16f61b1 100644 --- a/layout/xul/base/public/nsIEditorBoxObject.idl +++ b/layout/xul/nsIScrollBoxObject.idl @@ -3,14 +3,10 @@ * 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/. */ -#include "nsIContainerBoxObject.idl" +#include "nsISupports.idl" -/** - * @deprecated Please consider using nsIContainerBoxObject. - */ -[scriptable, uuid(e3800a23-5b83-49aa-b18c-efa1ac5416e0)] -interface nsIEditorBoxObject : nsIContainerBoxObject +[uuid(56E2ADA8-4631-11d4-BA11-001083023C1E)] +interface nsIScrollBoxObject : nsISupports { }; - diff --git a/layout/xul/nsIScrollbarMediator.h b/layout/xul/nsIScrollbarMediator.h new file mode 100644 index 000000000..f67300816 --- /dev/null +++ b/layout/xul/nsIScrollbarMediator.h @@ -0,0 +1,68 @@ +/* -*- 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 nsIScrollbarMediator_h___ +#define nsIScrollbarMediator_h___ + +#include "nsQueryFrame.h" +#include "nsCoord.h" + +class nsScrollbarFrame; +class nsIDOMEventTarget; +class nsIFrame; + +class nsIScrollbarMediator : public nsQueryFrame +{ +public: + NS_DECL_QUERYFRAME_TARGET(nsIScrollbarMediator) + + /** + * The aScrollbar argument denotes the scrollbar that's firing the notification. + * aScrollbar is never null. + * aDirection is either -1, 0, or 1. + */ + + /** + * One of the following three methods is called when the scrollbar's button is + * clicked. + * @note These methods might destroy the frame, pres shell, and other objects. + */ + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; + /** + * RepeatButtonScroll is called when the scrollbar's button is held down. When the + * button is first clicked the increment is set; RepeatButtonScroll adds this + * increment to the current position. + * @note This method might destroy the frame, pres shell, and other objects. + */ + virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) = 0; + /** + * aOldPos and aNewPos are scroll positions. + * The scroll positions start with zero at the left edge; implementors that want + * zero at the right edge for RTL content will need to adjust accordingly. + * (See ScrollFrameHelper::ThumbMoved in nsGfxScrollFrame.cpp.) + * @note This method might destroy the frame, pres shell, and other objects. + */ + virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, + nscoord aOldPos, + nscoord aNewPos) = 0; + virtual void VisibilityChanged(bool aVisible) = 0; + + /** + * Obtain the frame for the horizontal or vertical scrollbar, or null + * if there is no such box. + */ + virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0; + /** + * Show or hide scrollbars on 2 fingers touch. + * Subclasses should call their ScrollbarActivity's corresponding methods. + */ + virtual void ScrollbarActivityStarted() const = 0; + virtual void ScrollbarActivityStopped() const = 0; +}; + +#endif + diff --git a/layout/xul/base/public/nsISliderListener.idl b/layout/xul/nsISliderListener.idl index 9605782f0..9605782f0 100644 --- a/layout/xul/base/public/nsISliderListener.idl +++ b/layout/xul/nsISliderListener.idl diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index 4f707bb71..9a99dbff3 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -12,6 +12,7 @@ #include "nsImageBoxFrame.h" #include "nsGkAtoms.h" +#include "nsRenderingContext.h" #include "nsStyleContext.h" #include "nsStyleConsts.h" #include "nsCOMPtr.h" @@ -31,7 +32,7 @@ #include "prprf.h" #include "nsCSSRendering.h" #include "nsIDOMHTMLImageElement.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsTextFragment.h" #include "nsIDOMHTMLMapElement.h" #include "nsTransform2D.h" @@ -41,16 +42,21 @@ #include "nsIURI.h" #include "nsNetUtil.h" #include "nsThreadUtils.h" -#include "nsGUIEvent.h" -#include "nsEventDispatcher.h" #include "nsDisplayList.h" #include "ImageLayers.h" #include "ImageContainer.h" +#include "nsIContent.h" #include "nsContentUtils.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/EventDispatcher.h" + #define ONLOAD_CALLED_TOO_EARLY 1 +using namespace mozilla; +using namespace mozilla::gfx; +using namespace mozilla::image; using namespace mozilla::layers; class nsImageBoxFrameEvent : public nsRunnable @@ -59,7 +65,7 @@ public: nsImageBoxFrameEvent(nsIContent *content, uint32_t message) : mContent(content), mMessage(message) {} - NS_IMETHOD Run(); + NS_IMETHOD Run() override; private: nsCOMPtr<nsIContent> mContent; @@ -80,10 +86,10 @@ nsImageBoxFrameEvent::Run() } nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event(true, mMessage); + WidgetEvent event(true, mMessage); event.mFlags.mBubbles = false; - nsEventDispatcher::Dispatch(mContent, pres_context, &event, nullptr, &status); + EventDispatcher::Dispatch(mContent, pres_context, &event, nullptr, &status); return NS_OK; } @@ -114,12 +120,12 @@ FireImageDOMEvent(nsIContent* aContent, uint32_t aMessage) nsIFrame* NS_NewImageBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsImageBoxFrame (aPresShell, aContext); + return new (aPresShell) nsImageBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsImageBoxFrame) -NS_IMETHODIMP +nsresult nsImageBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -138,8 +144,8 @@ nsImageBoxFrame::AttributeChanged(int32_t aNameSpaceID, return rv; } -nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsLeafBoxFrame(aShell, aContext), +nsImageBoxFrame::nsImageBoxFrame(nsStyleContext* aContext): + nsLeafBoxFrame(aContext), mIntrinsicSize(0,0), mRequestRegistered(false), mLoadFlags(nsIRequest::LOAD_NORMAL), @@ -147,7 +153,7 @@ nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext) mSuppressStyleCheck(false), mFireEventOnDecode(false) { - MarkIntrinsicWidthsDirty(); + MarkIntrinsicISizesDirty(); } nsImageBoxFrame::~nsImageBoxFrame() @@ -156,10 +162,10 @@ nsImageBoxFrame::~nsImageBoxFrame() /* virtual */ void -nsImageBoxFrame::MarkIntrinsicWidthsDirty() +nsImageBoxFrame::MarkIntrinsicISizesDirty() { SizeNeedsRecalc(mImageSize); - nsLeafBoxFrame::MarkIntrinsicWidthsDirty(); + nsLeafBoxFrame::MarkIntrinsicISizesDirty(); } void @@ -181,9 +187,9 @@ nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) void -nsImageBoxFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsImageBoxFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { if (!mListener) { nsImageBoxListener *listener = new nsImageBoxListener(); @@ -218,7 +224,7 @@ nsImageBoxFrame::UpdateImage() mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src); mUseSrcAttr = !src.IsEmpty(); if (mUseSrcAttr) { - nsIDocument* doc = mContent->GetDocument(); + nsIDocument* doc = mContent->GetComposedDoc(); if (!doc) { // No need to do anything here... return; @@ -233,8 +239,9 @@ nsImageBoxFrame::UpdateImage() if (uri && nsContentUtils::CanLoadImage(uri, mContent, doc, mContent->NodePrincipal())) { nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(), - doc->GetDocumentURI(), mListener, mLoadFlags, - getter_AddRefs(mImageRequest)); + doc->GetDocumentURI(), doc->GetReferrerPolicy(), + mListener, mLoadFlags, + EmptyString(), getter_AddRefs(mImageRequest)); if (mImageRequest) { nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, @@ -311,7 +318,7 @@ nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aLists.Content()->AppendToTop(&list); } -void +DrawResult nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt, uint32_t aFlags) @@ -321,23 +328,32 @@ nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, rect += aPt; - if (!mImageRequest) - return; + if (!mImageRequest) { + // This probably means we're drawn by a native theme. + return DrawResult::SUCCESS; + } // don't draw if the image is not dirty + // XXX(seth): Can this actually happen anymore? nsRect dirty; - if (!dirty.IntersectRect(aDirtyRect, rect)) - return; + if (!dirty.IntersectRect(aDirtyRect, rect)) { + return DrawResult::TEMPORARY_ERROR; + } nsCOMPtr<imgIContainer> imgCon; mImageRequest->GetImage(getter_AddRefs(imgCon)); if (imgCon) { bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0); - nsLayoutUtils::DrawSingleImage(&aRenderingContext, imgCon, + return + nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), + PresContext(), imgCon, nsLayoutUtils::GetGraphicsFilterForFrame(this), - rect, dirty, nullptr, aFlags, hasSubRect ? &mSubRect : nullptr); + rect, dirty, nullptr, aFlags, nullptr, + hasSubRect ? &mSubRect : nullptr); } + + return DrawResult::NOT_READY; } void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, @@ -349,8 +365,35 @@ void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, if (aBuilder->IsPaintingToWindow()) flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; - static_cast<nsImageBoxFrame*>(mFrame)-> + DrawResult result = static_cast<nsImageBoxFrame*>(mFrame)-> PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags); + + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); +} + +nsDisplayItemGeometry* +nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder* aBuilder) +{ + return new nsDisplayItemGenericImageGeometry(this, aBuilder); +} + +void +nsDisplayXULImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, + const nsDisplayItemGeometry* aGeometry, + nsRegion* aInvalidRegion) +{ + auto boxFrame = static_cast<nsImageBoxFrame*>(mFrame); + auto geometry = + static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry); + + if (aBuilder->ShouldSyncDecodeImages() && + boxFrame->mImageRequest && + geometry->ShouldInvalidateToSyncDecodeImages()) { + bool snap; + aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap)); + } + + nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); } void @@ -375,14 +418,18 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) imgCon->GetHeight(&imageHeight); NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!"); + if (imageWidth > 0 && imageHeight > 0) { + // We're actually using the ImageContainer. Let our frame know that it + // should consider itself to have painted successfully. + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, + DrawResult::SUCCESS); + } - gfxMatrix transform; - transform.Translate(destRect.TopLeft() + aOffset); - transform.Scale(destRect.Width()/imageWidth, - destRect.Height()/imageHeight); - aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform)); - - aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight)); + gfxPoint p = destRect.TopLeft() + aOffset; + Matrix transform = Matrix::Translation(p.x, p.y); + transform.PreScale(destRect.Width() / imageWidth, + destRect.Height() / imageHeight); + aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform)); } already_AddRefed<ImageContainer> @@ -406,8 +453,7 @@ nsImageBoxFrame::GetContainer(LayerManager* aManager) } nsRefPtr<ImageContainer> container; - nsresult rv = imgCon->GetImageContainer(aManager, getter_AddRefs(container)); - NS_ENSURE_SUCCESS(rv, nullptr); + imgCon->GetImageContainer(aManager, getter_AddRefs(container)); return container.forget(); } @@ -474,7 +520,7 @@ nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState) GetImageSize(); if (!mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0)) - size = nsSize(mSubRect.width, mSubRect.height); + size = mSubRect.Size(); else size = mImageSize; @@ -567,8 +613,8 @@ nsImageBoxFrame::GetType() const return nsGkAtoms::imageBoxFrame; } -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsImageBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("ImageBox"), aResult); @@ -576,16 +622,18 @@ nsImageBoxFrame::GetFrameName(nsAString& aResult) const #endif nsresult -nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) +nsImageBoxFrame::Notify(imgIRequest* aRequest, + int32_t aType, + const nsIntRect* aData) { if (aType == imgINotificationObserver::SIZE_AVAILABLE) { nsCOMPtr<imgIContainer> image; aRequest->GetImage(getter_AddRefs(image)); - return OnStartContainer(aRequest, image); + return OnSizeAvailable(aRequest, image); } if (aType == imgINotificationObserver::DECODE_COMPLETE) { - return OnStopDecode(aRequest); + return OnDecodeComplete(aRequest); } if (aType == imgINotificationObserver::LOAD_COMPLETE) { @@ -593,7 +641,7 @@ nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* a aRequest->GetImageStatus(&imgStatus); nsresult status = imgStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK; - return OnStopRequest(aRequest, status); + return OnLoadComplete(aRequest, status); } if (aType == imgINotificationObserver::IS_ANIMATED) { @@ -601,25 +649,25 @@ nsImageBoxFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* a } if (aType == imgINotificationObserver::FRAME_UPDATE) { - return FrameChanged(aRequest); + return OnFrameUpdate(aRequest); } return NS_OK; } -nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request, - imgIContainer *image) +nsresult +nsImageBoxFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage) { - NS_ENSURE_ARG_POINTER(image); + NS_ENSURE_ARG_POINTER(aImage); // Ensure the animation (if any) is started. Note: There is no // corresponding call to Decrement for this. This Increment will be // 'cleaned up' by the Request when it is destroyed, but only then. - request->IncrementAnimationConsumers(); + aRequest->IncrementAnimationConsumers(); nscoord w, h; - image->GetWidth(&w); - image->GetHeight(&h); + aImage->GetWidth(&w); + aImage->GetHeight(&h); mIntrinsicSize.SizeTo(nsPresContext::CSSPixelsToAppUnits(w), nsPresContext::CSSPixelsToAppUnits(h)); @@ -632,13 +680,14 @@ nsresult nsImageBoxFrame::OnStartContainer(imgIRequest *request, return NS_OK; } -nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request) +nsresult +nsImageBoxFrame::OnDecodeComplete(imgIRequest* aRequest) { if (mFireEventOnDecode) { mFireEventOnDecode = false; uint32_t reqStatus; - request->GetImageStatus(&reqStatus); + aRequest->GetImageStatus(&reqStatus); if (!(reqStatus & imgIRequest::STATUS_ERROR)) { FireImageDOMEvent(mContent, NS_LOAD); } else { @@ -656,17 +705,18 @@ nsresult nsImageBoxFrame::OnStopDecode(imgIRequest *request) return NS_OK; } -nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request, - nsresult aStatus) +nsresult +nsImageBoxFrame::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus) { uint32_t reqStatus; - request->GetImageStatus(&reqStatus); + aRequest->GetImageStatus(&reqStatus); // We want to give the decoder a chance to find errors. If we haven't found // an error yet and we've already started decoding, we must only fire these // events after we finish decoding. if (NS_SUCCEEDED(aStatus) && !(reqStatus & imgIRequest::STATUS_ERROR) && - reqStatus & imgIRequest::STATUS_DECODE_STARTED) { + (reqStatus & imgIRequest::STATUS_DECODE_STARTED) && + !(reqStatus & imgIRequest::STATUS_DECODE_COMPLETE)) { mFireEventOnDecode = true; } else { if (NS_SUCCEEDED(aStatus)) { @@ -684,7 +734,8 @@ nsresult nsImageBoxFrame::OnStopRequest(imgIRequest *request, return NS_OK; } -nsresult nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest) +nsresult +nsImageBoxFrame::OnImageIsAnimated(imgIRequest* aRequest) { // Register with our refresh driver, if we're animated. nsLayoutUtils::RegisterImageRequest(PresContext(), aRequest, @@ -693,7 +744,8 @@ nsresult nsImageBoxFrame::OnImageIsAnimated(imgIRequest *aRequest) return NS_OK; } -nsresult nsImageBoxFrame::FrameChanged(imgIRequest *aRequest) +nsresult +nsImageBoxFrame::OnFrameUpdate(imgIRequest* aRequest) { if ((0 == mRect.width) || (0 == mRect.height)) { return NS_OK; @@ -704,7 +756,7 @@ nsresult nsImageBoxFrame::FrameChanged(imgIRequest *aRequest) return NS_OK; } -NS_IMPL_ISUPPORTS2(nsImageBoxListener, imgINotificationObserver, imgIOnloadBlocker) +NS_IMPL_ISUPPORTS(nsImageBoxListener, imgINotificationObserver, imgIOnloadBlocker) nsImageBoxListener::nsImageBoxListener() { diff --git a/layout/xul/base/src/nsImageBoxFrame.h b/layout/xul/nsImageBoxFrame.h index 0f4e5c5ca..717316c7c 100644 --- a/layout/xul/base/src/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -19,12 +19,11 @@ class nsImageBoxFrame; class nsDisplayXULImage; -class nsImageBoxListener : public imgINotificationObserver, - public imgIOnloadBlocker +class nsImageBoxListener final : public imgINotificationObserver, + public imgIOnloadBlocker { public: nsImageBoxListener(); - virtual ~nsImageBoxListener(); NS_DECL_ISUPPORTS NS_DECL_IMGINOTIFICATIONOBSERVER @@ -33,41 +32,44 @@ public: void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; } private: + virtual ~nsImageBoxListener(); + nsImageBoxFrame *mFrame; }; -class nsImageBoxFrame : public nsLeafBoxFrame +class nsImageBoxFrame final : public nsLeafBoxFrame { public: + typedef mozilla::image::DrawResult DrawResult; typedef mozilla::layers::LayerManager LayerManager; friend class nsDisplayXULImage; NS_DECL_FRAMEARENA_HELPERS - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; + virtual void MarkIntrinsicISizesDirty() override; nsresult Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData); friend nsIFrame* NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* asPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* asPrevInFlow) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - virtual nsIAtom* GetType() const MOZ_OVERRIDE; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; + virtual nsIAtom* GetType() const override; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif /** @@ -85,26 +87,26 @@ public: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; virtual ~nsImageBoxFrame(); - void PaintImage(nsRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsPoint aPt, uint32_t aFlags); + DrawResult PaintImage(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsPoint aPt, uint32_t aFlags); already_AddRefed<mozilla::layers::ImageContainer> GetContainer(LayerManager* aManager); protected: - nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsImageBoxFrame(nsStyleContext* aContext); virtual void GetImageSize(); private: - nsresult OnStartContainer(imgIRequest *request, imgIContainer *image); - nsresult OnStopDecode(imgIRequest *request); - nsresult OnStopRequest(imgIRequest *request, nsresult status); + nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage); + nsresult OnDecodeComplete(imgIRequest* aRequest); + nsresult OnLoadComplete(imgIRequest* aRequest, nsresult aStatus); nsresult OnImageIsAnimated(imgIRequest* aRequest); - nsresult FrameChanged(imgIRequest *aRequest); + nsresult OnFrameUpdate(imgIRequest* aRequest); nsRect mSubRect; ///< If set, indicates that only the portion of the image specified by the rect should be used. nsSize mIntrinsicSize; @@ -138,18 +140,21 @@ public: #endif virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager, - nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; - virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE; - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE + nsDisplayListBuilder* aBuilder) override; + virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) override; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override { *aSnap = true; return nsRect(ToReferenceFrame(), Frame()->GetSize()); } - + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override; + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, + const nsDisplayItemGeometry* aGeometry, + nsRegion* aInvalidRegion) override; // Doesn't handle HitTest because nsLeafBoxFrame already creates an // event receiver for us virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx) MOZ_OVERRIDE; + nsRenderingContext* aCtx) override; NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE) }; diff --git a/layout/xul/base/src/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp index 2aeac994c..1c373300d 100644 --- a/layout/xul/base/src/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -17,7 +17,7 @@ #include "nsPresContext.h" #include "nsStyleContext.h" #include "nsIContent.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsBoxLayoutState.h" #include "nsWidgetsCID.h" #include "nsViewManager.h" @@ -25,6 +25,8 @@ #include "nsDisplayList.h" #include <algorithm> +using namespace mozilla; + // // NS_NewLeafBoxFrame // @@ -33,12 +35,12 @@ nsIFrame* NS_NewLeafBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsLeafBoxFrame(aPresShell, aContext); + return new (aPresShell) nsLeafBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame) -nsLeafBoxFrame::nsLeafBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext) +nsLeafBoxFrame::nsLeafBoxFrame(nsStyleContext* aContext) : nsLeafFrame(aContext) { } @@ -56,10 +58,9 @@ nsLeafBoxFrame::GetBoxName(nsAutoString& aName) * Initialize us. This is a good time to get the alignment of the box */ void -nsLeafBoxFrame::Init( - nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsLeafBoxFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsLeafFrame::Init(aContent, aParent, aPrevInFlow); @@ -70,7 +71,7 @@ nsLeafBoxFrame::Init( UpdateMouseThrough(); } -NS_IMETHODIMP +nsresult nsLeafBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -123,7 +124,7 @@ nsLeafBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } /* virtual */ nscoord -nsLeafBoxFrame::GetMinWidth(nsRenderingContext *aRenderingContext) +nsLeafBoxFrame::GetMinISize(nsRenderingContext *aRenderingContext) { nscoord result; DISPLAY_MIN_WIDTH(this, result); @@ -143,7 +144,7 @@ nsLeafBoxFrame::GetMinWidth(nsRenderingContext *aRenderingContext) } /* virtual */ nscoord -nsLeafBoxFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) +nsLeafBoxFrame::GetPrefISize(nsRenderingContext *aRenderingContext) { nscoord result; DISPLAY_PREF_WIDTH(this, result); @@ -163,24 +164,29 @@ nsLeafBoxFrame::GetPrefWidth(nsRenderingContext *aRenderingContext) } nscoord -nsLeafBoxFrame::GetIntrinsicWidth() +nsLeafBoxFrame::GetIntrinsicISize() { // No intrinsic width return 0; } -nsSize +LogicalSize nsLeafBoxFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, - nsSize aCBSize, nscoord aAvailableWidth, - nsSize aMargin, nsSize aBorder, - nsSize aPadding, bool aShrinkWrap) + WritingMode aWM, + const LogicalSize& aCBSize, + nscoord aAvailableISize, + const LogicalSize& aMargin, + const LogicalSize& aBorder, + const LogicalSize& aPadding, + bool aShrinkWrap) { // Important: NOT calling our direct superclass here! - return nsFrame::ComputeAutoSize(aRenderingContext, aCBSize, aAvailableWidth, + return nsFrame::ComputeAutoSize(aRenderingContext, aWM, + aCBSize, aAvailableISize, aMargin, aBorder, aPadding, aShrinkWrap); } -NS_IMETHODIMP +void nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -190,6 +196,8 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, // We aren't able to share an implementation because of the frame // class hierarchy. If you make changes here, please keep // nsBoxFrame::Reflow in sync. + + DO_GLOBAL_REFLOW_COUNT("nsLeafBoxFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); NS_ASSERTION(aReflowState.ComputedWidth() >=0 && @@ -213,8 +221,8 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, default:printf("<unknown>%d", aReflowState.reason);break; } - printSize("AW", aReflowState.availableWidth); - printSize("AH", aReflowState.availableHeight); + printSize("AW", aReflowState.AvailableWidth()); + printSize("AH", aReflowState.AvailableHeight()); printSize("CW", aReflowState.ComputedWidth()); printSize("CH", aReflowState.ComputedHeight()); @@ -230,7 +238,7 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight()); nsMargin m; - m = aReflowState.mComputedBorderPadding; + m = aReflowState.ComputedPhysicalBorderPadding(); //GetBorderAndPadding(m); @@ -267,11 +275,11 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, // XXXbz the width handling here seems to be wrong, since // mComputedMin/MaxWidth is a content-box size, whole // computedSize.width is a border-box size... - if (computedSize.width > aReflowState.mComputedMaxWidth) - computedSize.width = aReflowState.mComputedMaxWidth; + if (computedSize.width > aReflowState.ComputedMaxWidth()) + computedSize.width = aReflowState.ComputedMaxWidth(); - if (computedSize.width < aReflowState.mComputedMinWidth) - computedSize.width = aReflowState.mComputedMinWidth; + if (computedSize.width < aReflowState.ComputedMinWidth()) + computedSize.width = aReflowState.ComputedMinWidth(); // Now adjust computedSize.height for our min and max computed // height. The only problem is that those are content-box sizes, @@ -279,8 +287,8 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, // m.TopBottom() before adjusting, then readd it. computedSize.height = std::max(0, computedSize.height - m.TopBottom()); computedSize.height = NS_CSS_MINMAX(computedSize.height, - aReflowState.mComputedMinHeight, - aReflowState.mComputedMaxHeight); + aReflowState.ComputedMinHeight(), + aReflowState.ComputedMaxHeight()); computedSize.height += m.TopBottom(); nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height); @@ -291,16 +299,16 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, Layout(state); // ok our child could have gotten bigger. So lets get its bounds - aDesiredSize.width = mRect.width; - aDesiredSize.height = mRect.height; - aDesiredSize.ascent = GetBoxAscent(state); + aDesiredSize.Width() = mRect.width; + aDesiredSize.Height() = mRect.height; + aDesiredSize.SetBlockStartAscent(GetBoxAscent(state)); // the overflow rect is set in SetBounds() above aDesiredSize.mOverflowAreas = GetOverflowAreas(); #ifdef DO_NOISY_REFLOW { - printf("%p ** nsLBF(done) W:%d H:%d ", this, aDesiredSize.width, aDesiredSize.height); + printf("%p ** nsLBF(done) W:%d H:%d ", this, aDesiredSize.Width(), aDesiredSize.Height()); if (maxElementWidth) { printf("MW:%d\n", *maxElementWidth); @@ -310,12 +318,10 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, } #endif - - return NS_OK; } -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsLeafBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("LeafBox"), aResult); @@ -328,10 +334,10 @@ nsLeafBoxFrame::GetType() const return nsGkAtoms::leafBoxFrame; } -NS_IMETHODIMP +nsresult nsLeafBoxFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo) { - MarkIntrinsicWidthsDirty(); + MarkIntrinsicISizesDirty(); return nsLeafFrame::CharacterDataChanged(aInfo); } @@ -366,7 +372,7 @@ nsLeafBoxFrame::GetBoxAscent(nsBoxLayoutState& aState) } /* virtual */ void -nsLeafBoxFrame::MarkIntrinsicWidthsDirty() +nsLeafBoxFrame::MarkIntrinsicISizesDirty() { // Don't call base class method, since everything it does is within an // IsBoxWrapped check. diff --git a/layout/xul/nsLeafBoxFrame.h b/layout/xul/nsLeafBoxFrame.h new file mode 100644 index 000000000..7631ae353 --- /dev/null +++ b/layout/xul/nsLeafBoxFrame.h @@ -0,0 +1,97 @@ +/* -*- 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 nsLeafBoxFrame_h___ +#define nsLeafBoxFrame_h___ + +#include "mozilla/Attributes.h" +#include "nsLeafFrame.h" +#include "nsBox.h" + +class nsAccessKeyInfo; + +class nsLeafBoxFrame : public nsLeafFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + friend nsIFrame* NS_NewLeafBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + + virtual nsSize GetPrefSize(nsBoxLayoutState& aState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aState) override; + virtual nsSize GetMaxSize(nsBoxLayoutState& aState) override; + virtual nscoord GetFlex(nsBoxLayoutState& aState) override; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aState) override; + + virtual nsIAtom* GetType() const override; + virtual bool IsFrameOfType(uint32_t aFlags) const override + { + // This is bogus, but it's what we've always done. + // Note that nsLeafFrame is also eReplacedContainsBlock. + return nsLeafFrame::IsFrameOfType(aFlags & + ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock | nsIFrame::eXULBox)); + } + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; +#endif + + // nsIHTMLReflow overrides + + virtual void MarkIntrinsicISizesDirty() override; + virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; + virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; + + // Our auto size is that provided by nsFrame, not nsLeafFrame + virtual mozilla::LogicalSize + ComputeAutoSize(nsRenderingContext *aRenderingContext, + mozilla::WritingMode aWritingMode, + const mozilla::LogicalSize& aCBSize, + nscoord aAvailableISize, + const mozilla::LogicalSize& aMargin, + const mozilla::LogicalSize& aBorder, + const mozilla::LogicalSize& aPadding, + bool aShrinkWrap) override; + + virtual void Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) override; + + virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) override; + + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* asPrevInFlow) override; + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override; + + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; + + virtual bool ComputesOwnOverflowArea() override { return false; } + +protected: + + NS_IMETHOD DoLayout(nsBoxLayoutState& aState) override; + +#ifdef DEBUG_LAYOUT + virtual void GetBoxName(nsAutoString& aName) override; +#endif + + virtual nscoord GetIntrinsicISize() override; + + explicit nsLeafBoxFrame(nsStyleContext* aContext); + +private: + + void UpdateMouseThrough(); + + +}; // class nsLeafBoxFrame + +#endif /* nsLeafBoxFrame_h___ */ diff --git a/layout/xul/base/src/nsListBoxBodyFrame.cpp b/layout/xul/nsListBoxBodyFrame.cpp index 2a4caf42a..32b84ee72 100644 --- a/layout/xul/base/src/nsListBoxBodyFrame.cpp +++ b/layout/xul/nsListBoxBodyFrame.cpp @@ -7,12 +7,13 @@ #include "nsListBoxLayout.h" +#include "mozilla/MathAlgorithms.h" #include "nsCOMPtr.h" #include "nsGridRowGroupLayout.h" #include "nsIServiceManager.h" #include "nsGkAtoms.h" #include "nsIContent.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsIDocument.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMElement.h" @@ -28,18 +29,21 @@ #include "nsAutoPtr.h" #include "nsStyleSet.h" #include "nsPIBoxObject.h" -#include "nsINodeInfo.h" #include "nsLayoutUtils.h" #include "nsPIListBoxObject.h" #include "nsContentUtils.h" -#include "nsChildIterator.h" +#include "ChildIterator.h" #include "nsRenderingContext.h" +#include "prtime.h" #include <algorithm> #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif +using namespace mozilla; +using namespace mozilla::dom; + /////////////// nsListScrollSmoother ////////////////// /* A mediator used to smooth out scrolling. It works by seeing if @@ -62,13 +66,15 @@ // do we wait before checking again? #define SMOOTH_INTERVAL 100 -class nsListScrollSmoother : public nsITimerCallback +class nsListScrollSmoother final : public nsITimerCallback { +private: + virtual ~nsListScrollSmoother(); + public: NS_DECL_ISUPPORTS - nsListScrollSmoother(nsListBoxBodyFrame* aOuter); - virtual ~nsListScrollSmoother(); + explicit nsListScrollSmoother(nsListBoxBodyFrame* aOuter); // nsITimerCallback NS_DECL_NSITIMERCALLBACK @@ -129,14 +135,13 @@ nsListScrollSmoother::Stop() } } -NS_IMPL_ISUPPORTS1(nsListScrollSmoother, nsITimerCallback) +NS_IMPL_ISUPPORTS(nsListScrollSmoother, nsITimerCallback) /////////////// nsListBoxBodyFrame ////////////////// -nsListBoxBodyFrame::nsListBoxBodyFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, +nsListBoxBodyFrame::nsListBoxBodyFrame(nsStyleContext* aContext, nsBoxLayout* aLayoutManager) - : nsBoxFrame(aPresShell, aContext, false, aLayoutManager), + : nsBoxFrame(aContext, false, aLayoutManager), mTopFrame(nullptr), mBottomFrame(nullptr), mLinkupFrame(nullptr), @@ -176,12 +181,14 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) ////////// nsIFrame ///////////////// void -nsListBoxBodyFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsListBoxBodyFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); - nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this); + // Don't call nsLayoutUtils::GetScrollableFrameFor since we are not its + // scrollframe child yet. + nsIScrollableFrame* scrollFrame = do_QueryFrame(aParent); if (scrollFrame) { nsIFrame* verticalScrollbar = scrollFrame->GetScrollbarBox(true); nsScrollbarFrame* scrollbarFrame = do_QueryFrame(verticalScrollbar); @@ -214,7 +221,7 @@ nsListBoxBodyFrame::DestroyFrom(nsIFrame* aDestructRoot) nsBoxFrame::DestroyFrom(aDestructRoot); } -NS_IMETHODIMP +nsresult nsListBoxBodyFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -233,10 +240,10 @@ nsListBoxBodyFrame::AttributeChanged(int32_t aNameSpaceID, } /* virtual */ void -nsListBoxBodyFrame::MarkIntrinsicWidthsDirty() +nsListBoxBodyFrame::MarkIntrinsicISizesDirty() { mStringWidth = -1; - nsBoxFrame::MarkIntrinsicWidthsDirty(); + nsBoxFrame::MarkIntrinsicISizesDirty(); } /////////// nsBox /////////////// @@ -318,43 +325,89 @@ nsListBoxBodyFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState) ///////////// nsIScrollbarMediator /////////////// -NS_IMETHODIMP -nsListBoxBodyFrame::PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) -{ - if (mScrolling || mRowHeight == 0) - return NS_OK; +void +nsListBoxBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + aScrollbar->SetIncrementToPage(aDirection); + nsWeakFrame weakFrame(this); + int32_t newPos = aScrollbar->MoveToNewPosition(); + if (!weakFrame.IsAlive()) { + return; + } + UpdateIndex(newPos); +} - nscoord oldTwipIndex, newTwipIndex; - oldTwipIndex = mCurrentIndex*mRowHeight; - newTwipIndex = nsPresContext::CSSPixelsToAppUnits(aNewIndex); - int32_t twipDelta = newTwipIndex > oldTwipIndex ? newTwipIndex - oldTwipIndex : oldTwipIndex - newTwipIndex; +void +nsListBoxBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + aScrollbar->SetIncrementToWhole(aDirection); + nsWeakFrame weakFrame(this); + int32_t newPos = aScrollbar->MoveToNewPosition(); + if (!weakFrame.IsAlive()) { + return; + } + UpdateIndex(newPos); +} - int32_t rowDelta = twipDelta / mRowHeight; - int32_t remainder = twipDelta % mRowHeight; - if (remainder > (mRowHeight/2)) - rowDelta++; +void +nsListBoxBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + aScrollbar->SetIncrementToLine(aDirection); + nsWeakFrame weakFrame(this); + int32_t newPos = aScrollbar->MoveToNewPosition(); + if (!weakFrame.IsAlive()) { + return; + } + UpdateIndex(newPos); +} - if (rowDelta == 0) - return NS_OK; +void +nsListBoxBodyFrame::RepeatButtonScroll(nsScrollbarFrame* aScrollbar) +{ + nsWeakFrame weakFrame(this); + int32_t newPos = aScrollbar->MoveToNewPosition(); + if (!weakFrame.IsAlive()) { + return; + } + UpdateIndex(newPos); +} - // update the position to be row based. +int32_t +nsListBoxBodyFrame::ToRowIndex(nscoord aPos) const +{ + return NS_roundf(float(std::max(aPos, 0)) / mRowHeight); +} - int32_t newIndex = newTwipIndex > oldTwipIndex ? mCurrentIndex + rowDelta : mCurrentIndex - rowDelta; - //aNewIndex = newIndex*mRowHeight/mOnePixel; +void +nsListBoxBodyFrame::ThumbMoved(nsScrollbarFrame* aScrollbar, + nscoord aOldPos, + nscoord aNewPos) +{ + if (mScrolling || mRowHeight == 0) + return; + + int32_t newIndex = ToRowIndex(aNewPos); + if (newIndex == mCurrentIndex) { + return; + } + int32_t rowDelta = newIndex - mCurrentIndex; nsListScrollSmoother* smoother = GetSmoother(); // if we can't scroll the rows in time then start a timer. We will eat // events until the user stops moving and the timer stops. - if (smoother->IsRunning() || rowDelta*mTimePerRow > USER_TIME_THRESHOLD) { + if (smoother->IsRunning() || Abs(rowDelta)*mTimePerRow > USER_TIME_THRESHOLD) { smoother->Stop(); - smoother->mDelta = newTwipIndex > oldTwipIndex ? rowDelta : -rowDelta; + smoother->mDelta = rowDelta; smoother->Start(); - return NS_OK; + return; } smoother->Stop(); @@ -364,17 +417,16 @@ nsListBoxBodyFrame::PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIn if (mCurrentIndex < 0) { mCurrentIndex = 0; - return NS_OK; + return; } - - return InternalPositionChanged(newTwipIndex < oldTwipIndex, rowDelta); + InternalPositionChanged(rowDelta < 0, Abs(rowDelta)); } -NS_IMETHODIMP +void nsListBoxBodyFrame::VisibilityChanged(bool aVisible) { if (mRowHeight == 0) - return NS_OK; + return; int32_t lastPageTopRow = GetRowCount() - (GetAvailableHeight() / mRowHeight); if (lastPageTopRow < 0) @@ -384,27 +436,28 @@ nsListBoxBodyFrame::VisibilityChanged(bool aVisible) mCurrentIndex = lastPageTopRow; InternalPositionChanged(true, delta); } +} - return NS_OK; +nsIFrame* +nsListBoxBodyFrame::GetScrollbarBox(bool aVertical) +{ + nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this); + return scrollFrame ? scrollFrame->GetScrollbarBox(true) : nullptr; } -NS_IMETHODIMP -nsListBoxBodyFrame::ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) +void +nsListBoxBodyFrame::UpdateIndex(int32_t aNewPos) { - if (aOldIndex == aNewIndex) - return NS_OK; - if (aNewIndex < aOldIndex) - mCurrentIndex--; - else mCurrentIndex++; - if (mCurrentIndex < 0) { - mCurrentIndex = 0; - return NS_OK; + int32_t newIndex = ToRowIndex(nsPresContext::CSSPixelsToAppUnits(aNewPos)); + if (newIndex == mCurrentIndex) { + return; } - InternalPositionChanged(aNewIndex < aOldIndex, 1); - - return NS_OK; + bool up = newIndex < mCurrentIndex; + int32_t indexDelta = Abs(newIndex - mCurrentIndex); + mCurrentIndex = newIndex; + InternalPositionChanged(up, indexDelta); } - + ///////////// nsIReflowCallback /////////////// bool @@ -441,27 +494,18 @@ nsListBoxBodyFrame::ReflowCallbackCanceled() mReflowCallbackPosted = false; } -///////// nsIListBoxObject /////////////// - -nsresult -nsListBoxBodyFrame::GetRowCount(int32_t* aResult) -{ - *aResult = GetRowCount(); - return NS_OK; -} +///////// ListBoxObject /////////////// -nsresult -nsListBoxBodyFrame::GetNumberOfVisibleRows(int32_t *aResult) +int32_t +nsListBoxBodyFrame::GetNumberOfVisibleRows() { - *aResult= mRowHeight ? GetAvailableHeight() / mRowHeight : 0; - return NS_OK; + return mRowHeight ? GetAvailableHeight() / mRowHeight : 0; } -nsresult -nsListBoxBodyFrame::GetIndexOfFirstVisibleRow(int32_t *aResult) +int32_t +nsListBoxBodyFrame::GetIndexOfFirstVisibleRow() { - *aResult = mCurrentIndex; - return NS_OK; + return mCurrentIndex; } nsresult @@ -507,9 +551,8 @@ nsListBoxBodyFrame::EnsureIndexIsVisible(int32_t aRowIndex) nsresult nsListBoxBodyFrame::ScrollByLines(int32_t aNumLines) { - int32_t scrollIndex, visibleRows; - GetIndexOfFirstVisibleRow(&scrollIndex); - GetNumberOfVisibleRows(&visibleRows); + int32_t scrollIndex = GetIndexOfFirstVisibleRow(), + visibleRows = GetNumberOfVisibleRows(); scrollIndex += aNumLines; @@ -535,11 +578,8 @@ nsListBoxBodyFrame::GetIndexOfItem(nsIDOMElement* aItem, int32_t* _retval) *_retval = 0; nsCOMPtr<nsIContent> itemContent(do_QueryInterface(aItem)); - ChildIterator iter, last; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last; - ++iter) { - nsIContent *child = (*iter); + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { // we hit a list row, count it if (child->Tag() == nsGkAtoms::listitem) { // is this it? @@ -562,13 +602,10 @@ nsListBoxBodyFrame::GetItemAtIndex(int32_t aIndex, nsIDOMElement** aItem) *aItem = nullptr; if (aIndex < 0) return NS_OK; - + int32_t itemCount = 0; - ChildIterator iter, last; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last; - ++iter) { - nsIContent *child = (*iter); + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { // we hit a list row, check if it is the one we are looking for if (child->Tag() == nsGkAtoms::listitem) { // is this it? @@ -643,7 +680,7 @@ nsListBoxBodyFrame::GetYPosition() } nscoord -nsListBoxBodyFrame::ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState) +nsListBoxBodyFrame::ComputeIntrinsicISize(nsBoxLayoutState& aBoxLayoutState) { if (mStringWidth != -1) return mStringWidth; @@ -670,14 +707,8 @@ nsListBoxBodyFrame::ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState) if (styleContext->StyleMargin()->GetMargin(margin)) width += margin.LeftRight(); - - ChildIterator iter, last; - uint32_t i = 0; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last && i < 100; - ++iter, ++i) { - nsIContent *child = (*iter); - + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { if (child->Tag() == nsGkAtoms::listitem) { nsRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext(); if (rendContext) { @@ -693,10 +724,10 @@ nsListBoxBodyFrame::ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState) nsRefPtr<nsFontMetrics> fm; nsLayoutUtils::GetFontMetricsForStyleContext(styleContext, getter_AddRefs(fm)); - rendContext->SetFont(fm); nscoord textWidth = - nsLayoutUtils::GetStringWidth(this, rendContext, value.get(), value.Length()); + nsLayoutUtils::AppUnitWidthOfStringBidi(value, this, *fm, + *rendContext); textWidth += width; if (textWidth > largestWidth) @@ -714,13 +745,11 @@ void nsListBoxBodyFrame::ComputeTotalRowCount() { mRowCount = 0; - - ChildIterator iter, last; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last; - ++iter) { - if ((*iter)->Tag() == nsGkAtoms::listitem) + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { + if (child->Tag() == nsGkAtoms::listitem) { ++mRowCount; + } } } @@ -767,7 +796,7 @@ nsListBoxBodyFrame::ScrollToIndex(int32_t aRowIndex) // This change has to happen immediately. // Flush any pending reflow commands. // XXXbz why, exactly? - mContent->GetDocument()->FlushPendingNotifications(Flush_Layout); + mContent->GetComposedDoc()->FlushPendingNotifications(Flush_Layout); return NS_OK; } @@ -840,7 +869,7 @@ nsListBoxBodyFrame::DoInternalPositionChanged(bool aUp, int32_t aDelta) PRTime start = PR_Now(); nsWeakFrame weakThis(this); - mContent->GetDocument()->FlushPendingNotifications(Flush_Layout); + mContent->GetComposedDoc()->FlushPendingNotifications(Flush_Layout); if (!weakThis.IsAlive()) { return NS_OK; } @@ -1385,16 +1414,17 @@ nsListBoxBodyFrame::OnContentRemoved(nsPresContext* aPresContext, // of the scrollbar is to stay locked to the bottom. Since we are // removing visible content, the first visible row will have to move // down by one, and we will have to insert a new frame at the top. - + // if the last content node has a frame, we are scrolled to the bottom - ChildIterator iter, last; - ChildIterator::Init(mContent, &iter, &last); - if (iter != last) { - iter = last; - --iter; - nsIContent *lastChild = *iter; + nsIContent* lastChild = nullptr; + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { + lastChild = child; + } + + if (lastChild) { nsIFrame* lastChildFrame = lastChild->GetPrimaryFrame(); - + if (lastChildFrame) { mTopFrame = nullptr; mRowsToPrepend = 1; @@ -1431,15 +1461,12 @@ nsListBoxBodyFrame::GetListItemContentAt(int32_t aIndex, nsIContent** aContent) *aContent = nullptr; int32_t itemsFound = 0; - ChildIterator iter, last; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last; - ++iter) { - nsIContent *kid = (*iter); - if (kid->Tag() == nsGkAtoms::listitem) { + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { + if (child->Tag() == nsGkAtoms::listitem) { ++itemsFound; if (itemsFound-1 == aIndex) { - *aContent = kid; + *aContent = child; NS_IF_ADDREF(*aContent); return; } @@ -1453,21 +1480,17 @@ nsListBoxBodyFrame::GetListItemNextSibling(nsIContent* aListItem, nsIContent** a *aContent = nullptr; aSiblingIndex = -1; nsIContent *prevKid = nullptr; - ChildIterator iter, last; - for (ChildIterator::Init(mContent, &iter, &last); - iter != last; - ++iter) { - nsIContent *kid = (*iter); - - if (kid->Tag() == nsGkAtoms::listitem) { + FlattenedChildIterator iter(mContent); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { + if (child->Tag() == nsGkAtoms::listitem) { ++aSiblingIndex; if (prevKid == aListItem) { - *aContent = kid; + *aContent = child; NS_IF_ADDREF(*aContent); return; } } - prevKid = kid; + prevKid = child; } aSiblingIndex = -1; // no match, so there is no next sibling @@ -1484,8 +1507,7 @@ nsListBoxBodyFrame::RemoveChildFrame(nsBoxLayoutState &aState, nsAccessibilityService* accService = nsIPresShell::AccService(); if (accService) { nsIContent* content = aFrame->GetContent(); - accService->ContentRemoved(PresContext()->PresShell(), content->GetParent(), - content); + accService->ContentRemoved(PresContext()->PresShell(), content); } #endif @@ -1503,11 +1525,7 @@ nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { nsCOMPtr<nsBoxLayout> layout = NS_NewListBoxLayout(); - if (!layout) { - return nullptr; - } - - return new (aPresShell) nsListBoxBodyFrame(aPresShell, aContext, layout); + return new (aPresShell) nsListBoxBodyFrame(aContext, layout); } NS_IMPL_FRAMEARENA_HELPERS(nsListBoxBodyFrame) diff --git a/layout/xul/base/src/nsListBoxBodyFrame.h b/layout/xul/nsListBoxBodyFrame.h index 85f965667..57c901efe 100644 --- a/layout/xul/base/src/nsListBoxBodyFrame.h +++ b/layout/xul/nsListBoxBodyFrame.h @@ -9,7 +9,6 @@ #include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsBoxFrame.h" -#include "nsIListBoxObject.h" #include "nsIScrollbarMediator.h" #include "nsIReflowCallback.h" #include "nsBoxLayoutState.h" @@ -21,11 +20,11 @@ class nsListScrollSmoother; nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -class nsListBoxBodyFrame : public nsBoxFrame, - public nsIScrollbarMediator, - public nsIReflowCallback +class nsListBoxBodyFrame final : public nsBoxFrame, + public nsIScrollbarMediator, + public nsIReflowCallback { - nsListBoxBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, + nsListBoxBodyFrame(nsStyleContext* aContext, nsBoxLayout* aLayoutManager); virtual ~nsListBoxBodyFrame(); @@ -34,10 +33,9 @@ public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - // non-virtual nsIListBoxObject - nsresult GetRowCount(int32_t *aResult); - nsresult GetNumberOfVisibleRows(int32_t *aResult); - nsresult GetIndexOfFirstVisibleRow(int32_t *aResult); + // non-virtual ListBoxObject + int32_t GetNumberOfVisibleRows(); + int32_t GetIndexOfFirstVisibleRow(); nsresult EnsureIndexIsVisible(int32_t aRowIndex); nsresult ScrollToIndex(int32_t aRowIndex); nsresult ScrollByLines(int32_t aNumLines); @@ -48,27 +46,36 @@ public: nsStyleContext* aContext); // nsIFrame - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) override; // nsIScrollbarMediator - NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) MOZ_OVERRIDE; - NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; - NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE; + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override; + virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, + int32_t aOldPos, + int32_t aNewPos) override; + virtual void VisibilityChanged(bool aVisible) override; + virtual nsIFrame* GetScrollbarBox(bool aVertical) override; + virtual void ScrollbarActivityStarted() const override {} + virtual void ScrollbarActivityStopped() const override {} + // nsIReflowCallback - virtual bool ReflowFinished() MOZ_OVERRIDE; - virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; + virtual bool ReflowFinished() override; + virtual void ReflowCallbackCanceled() override; - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; + virtual void MarkIntrinsicISizesDirty() override; - virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; // size calculation int32_t GetRowCount(); @@ -77,7 +84,7 @@ public: void SetRowHeight(nscoord aRowHeight); nscoord GetYPosition(); nscoord GetAvailableHeight(); - nscoord ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState); + nscoord ComputeIntrinsicISize(nsBoxLayoutState& aBoxLayoutState); // scrolling nsresult InternalPositionChangedCallback(); @@ -89,6 +96,8 @@ public: nsresult DoInternalPositionChanged(bool aUp, int32_t aDelta); nsListScrollSmoother* GetSmoother(); void VerticalScroll(int32_t aDelta); + // Update the scroll index given a position, in CSS pixels + void UpdateIndex(int32_t aNewPos); // frames nsIFrame* GetFirstFrame(); @@ -119,9 +128,9 @@ public: return true; } - virtual bool SupportsOrdinalsInChildren() MOZ_OVERRIDE; + virtual bool SupportsOrdinalsInChildren() override; - virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; } + virtual bool ComputesOwnOverflowArea() override { return true; } protected: class nsPositionChangedEvent; @@ -135,7 +144,7 @@ protected: mFrame(aFrame), mUp(aUp), mDelta(aDelta) {} - NS_IMETHOD Run() MOZ_OVERRIDE + NS_IMETHOD Run() override { if (!mFrame) { return NS_OK; @@ -156,6 +165,7 @@ protected: }; void ComputeTotalRowCount(); + int32_t ToRowIndex(nscoord aPos) const; void RemoveChildFrame(nsBoxLayoutState &aState, nsIFrame *aChild); nsTArray< nsRefPtr<nsPositionChangedEvent> > mPendingPositionChangeEvents; diff --git a/layout/xul/base/src/nsListBoxLayout.cpp b/layout/xul/nsListBoxLayout.cpp index 029e4754b..97939ef78 100644 --- a/layout/xul/base/src/nsListBoxLayout.cpp +++ b/layout/xul/nsListBoxLayout.cpp @@ -10,7 +10,7 @@ #include "nsBoxLayoutState.h" #include "nsIScrollableFrame.h" #include "nsIReflowCallback.h" -#include "nsINameSpaceManager.h" +#include "mozilla/dom/NameSpaceConstants.h" #include "nsGkAtoms.h" #include "nsContentUtils.h" @@ -38,7 +38,7 @@ nsListBoxLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) } if (nsContentUtils::HasNonEmptyAttr(frame->GetContent(), kNameSpaceID_None, nsGkAtoms::sizemode)) { - nscoord width = frame->ComputeIntrinsicWidth(aBoxLayoutState); + nscoord width = frame->ComputeIntrinsicISize(aBoxLayoutState); if (width > pref.width) pref.width = width; } @@ -64,7 +64,7 @@ nsListBoxLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) } if (nsContentUtils::HasNonEmptyAttr(frame->GetContent(), kNameSpaceID_None, nsGkAtoms::sizemode)) { - nscoord width = frame->ComputeIntrinsicWidth(aBoxLayoutState); + nscoord width = frame->ComputeIntrinsicISize(aBoxLayoutState); if (width > minSize.width) minSize.width = width; } @@ -136,7 +136,7 @@ nsListBoxLayout::LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState) } // run through all our currently created children - nsIFrame* box = body->GetChildBox(); + nsIFrame* box = nsBox::GetChildBox(body); // if the reason is resize or initial we must relayout. nscoord rowHeight = body->GetRowHeightAppUnits(); @@ -185,7 +185,7 @@ nsListBoxLayout::LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState) yOffset += size; availableHeight -= size; - box = box->GetNextBox(); + box = nsBox::GetNextBox(box); } // We have enough available height left to add some more rows diff --git a/layout/xul/base/src/nsListBoxLayout.h b/layout/xul/nsListBoxLayout.h index c0685c58b..999a26fcb 100644 --- a/layout/xul/base/src/nsListBoxLayout.h +++ b/layout/xul/nsListBoxLayout.h @@ -19,10 +19,10 @@ public: nsListBoxLayout(); // nsBoxLayout - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) override; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; protected: NS_IMETHOD LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState); diff --git a/layout/xul/base/src/nsListItemFrame.cpp b/layout/xul/nsListItemFrame.cpp index 6255ecacf..69d36b1df 100644 --- a/layout/xul/base/src/nsListItemFrame.cpp +++ b/layout/xul/nsListItemFrame.cpp @@ -5,18 +5,19 @@ #include "nsListItemFrame.h" +#include <algorithm> + #include "nsCOMPtr.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsDisplayList.h" #include "nsBoxLayout.h" -#include <algorithm> +#include "nsIContent.h" -nsListItemFrame::nsListItemFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, +nsListItemFrame::nsListItemFrame(nsStyleContext* aContext, bool aIsRoot, nsBoxLayout* aLayoutManager) - : nsGridRowLeafFrame(aPresShell, aContext, aIsRoot, aLayoutManager) + : nsGridRowLeafFrame(aContext, aIsRoot, aLayoutManager) { } @@ -62,7 +63,7 @@ NS_NewListItemFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) return nullptr; } - return new (aPresShell) nsListItemFrame(aPresShell, aContext, false, layout); + return new (aPresShell) nsListItemFrame(aContext, false, layout); } NS_IMPL_FRAMEARENA_HELPERS(nsListItemFrame) diff --git a/layout/xul/base/src/nsListItemFrame.h b/layout/xul/nsListItemFrame.h index f28a79a52..95f874ac0 100644 --- a/layout/xul/base/src/nsListItemFrame.h +++ b/layout/xul/nsListItemFrame.h @@ -21,15 +21,14 @@ public: // unless allowevents="true" is specified on the listitem virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - virtual nsSize GetPrefSize(nsBoxLayoutState& aState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aState) override; protected: - nsListItemFrame(nsIPresShell* aPresShell, - nsStyleContext *aContext, - bool aIsRoot = false, - nsBoxLayout* aLayoutManager = nullptr); + explicit nsListItemFrame(nsStyleContext *aContext, + bool aIsRoot = false, + nsBoxLayout* aLayoutManager = nullptr); virtual ~nsListItemFrame(); }; // class nsListItemFrame diff --git a/layout/xul/base/src/nsMenuBarFrame.cpp b/layout/xul/nsMenuBarFrame.cpp index f57ed5dc4..a5029ec05 100644 --- a/layout/xul/base/src/nsMenuBarFrame.cpp +++ b/layout/xul/nsMenuBarFrame.cpp @@ -10,12 +10,11 @@ #include "nsPresContext.h" #include "nsStyleContext.h" #include "nsCSSRendering.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsIDocument.h" #include "nsGkAtoms.h" #include "nsMenuFrame.h" #include "nsMenuPopupFrame.h" -#include "nsGUIEvent.h" #include "nsUnicharUtils.h" #include "nsPIDOMWindow.h" #include "nsIInterfaceRequestorUtils.h" @@ -26,7 +25,9 @@ #endif #include "nsContentUtils.h" #include "nsUTF8Utils.h" +#include "mozilla/TextEvents.h" +using namespace mozilla; // // NS_NewMenuBarFrame @@ -36,7 +37,7 @@ nsIFrame* NS_NewMenuBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsMenuBarFrame (aPresShell, aContext); + return new (aPresShell) nsMenuBarFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsMenuBarFrame) @@ -48,8 +49,8 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) // // nsMenuBarFrame cntr // -nsMenuBarFrame::nsMenuBarFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext), +nsMenuBarFrame::nsMenuBarFrame(nsStyleContext* aContext): + nsBoxFrame(aContext), mMenuBarListener(nullptr), mStayActive(false), mIsActive(false), @@ -59,9 +60,9 @@ nsMenuBarFrame::nsMenuBarFrame(nsIPresShell* aShell, nsStyleContext* aContext): } // cntr void -nsMenuBarFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsMenuBarFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); @@ -71,14 +72,14 @@ nsMenuBarFrame::Init(nsIContent* aContent, // Hook up the menu bar as a key listener on the whole document. It will see every // key press that occurs, but after everyone else does. - mTarget = aContent->GetDocument(); + mTarget = aContent->GetComposedDoc(); // Also hook up the listener to the window listening for focus events. This is so we can keep proper // state as the user alt-tabs through processes. - mTarget->AddEventListener(NS_LITERAL_STRING("keypress"), mMenuBarListener, false); - mTarget->AddEventListener(NS_LITERAL_STRING("keydown"), mMenuBarListener, false); - mTarget->AddEventListener(NS_LITERAL_STRING("keyup"), mMenuBarListener, false); + mTarget->AddSystemEventListener(NS_LITERAL_STRING("keypress"), mMenuBarListener, false); + mTarget->AddSystemEventListener(NS_LITERAL_STRING("keydown"), mMenuBarListener, false); + mTarget->AddSystemEventListener(NS_LITERAL_STRING("keyup"), mMenuBarListener, false); // mousedown event should be handled in all phase mTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), mMenuBarListener, true); @@ -148,12 +149,7 @@ nsMenuBarFrame::ToggleMenuActiveState() if (firstFrame) { // Activate the menu bar SetActive(true); - -#ifdef MOZ_WIDGET_GTK2 - firstFrame->OpenMenu(true); -#else firstFrame->SelectMenu(true); -#endif // Track this item for keyboard navigation. mCurrentMenu = firstFrame; @@ -163,16 +159,6 @@ nsMenuBarFrame::ToggleMenuActiveState() return nullptr; } -static void -GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aFrame, nsIFrame* aChild, - nsIFrame** aResult) -{ - nsIContent* child = nullptr; - if (aChild) - child = aChild->GetContent(); - aShell->FrameConstructor()->GetInsertionPoint(aFrame, child, aResult); -} - nsMenuFrame* nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) { @@ -180,8 +166,8 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) aKeyEvent->GetCharCode(&charCode); nsAutoTArray<uint32_t, 10> accessKeys; - nsEvent* nativeEvent = nsContentUtils::GetNativeEvent(aKeyEvent); - nsKeyEvent* nativeKeyEvent = static_cast<nsKeyEvent*>(nativeEvent); + WidgetKeyboardEvent* nativeKeyEvent = + aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent(); if (nativeKeyEvent) nsContentUtils::GetAccessKeyCandidates(nativeKeyEvent, accessKeys); if (accessKeys.IsEmpty() && charCode) @@ -191,14 +177,15 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) return nullptr; // no character was pressed so just return // Enumerate over our list of frames. - nsIFrame* immediateParent = nullptr; - GetInsertionPoint(PresContext()->PresShell(), this, nullptr, &immediateParent); + auto insertion = PresContext()->PresShell()->FrameConstructor()-> + GetInsertionPoint(GetContent(), nullptr); + nsContainerFrame* immediateParent = insertion.mParentFrame; if (!immediateParent) immediateParent = this; // Find a most preferred accesskey which should be returned. nsIFrame* foundMenu = nullptr; - uint32_t foundIndex = accessKeys.NoIndex; + size_t foundIndex = accessKeys.NoIndex; nsIFrame* currFrame = immediateParent->GetFirstPrincipalChild(); while (currFrame) { @@ -211,10 +198,10 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) current->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, shortcutKey); if (!shortcutKey.IsEmpty()) { ToLowerCase(shortcutKey); - const PRUnichar* start = shortcutKey.BeginReading(); - const PRUnichar* end = shortcutKey.EndReading(); + const char16_t* start = shortcutKey.BeginReading(); + const char16_t* end = shortcutKey.EndReading(); uint32_t ch = UTF16CharEnumerator::NextChar(&start, end); - uint32_t index = accessKeys.IndexOf(ch); + size_t index = accessKeys.IndexOf(ch); if (index != accessKeys.NoIndex && (foundIndex == accessKeys.NoIndex || index < foundIndex)) { foundMenu = currFrame; @@ -241,7 +228,7 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) if (pm) { nsIFrame* popup = pm->GetTopPopup(ePopupTypeAny); if (popup) - pm->HidePopup(popup->GetContent(), true, true, true); + pm->HidePopup(popup->GetContent(), true, true, true, false); } SetCurrentMenuItem(nullptr); @@ -294,7 +281,7 @@ public: { } - NS_IMETHOD Run() + NS_IMETHOD Run() override { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (!pm) @@ -311,7 +298,7 @@ public: if (mOldMenu) { nsWeakFrame weakMenuBar(menubar); - pm->HidePopup(mOldMenu, false, false, false); + pm->HidePopup(mOldMenu, false, false, false, false); // clear the flag again if (mNewMenu && weakMenuBar.IsAlive()) menubar->SetStayActive(false); @@ -342,7 +329,8 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem, if (pm && pm->HasContextMenu(nullptr)) return NS_OK; - nsIContent* aOldMenu = nullptr, *aNewMenu = nullptr; + nsIContent* aOldMenu = nullptr; + nsIContent* aNewMenu = nullptr; // Unset the current child. bool wasOpen = false; @@ -376,7 +364,7 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem, } nsMenuFrame* -nsMenuBarFrame::Enter(nsGUIEvent* aEvent) +nsMenuBarFrame::Enter(WidgetGUIEvent* aEvent) { if (!mCurrentMenu) return nullptr; @@ -424,9 +412,9 @@ nsMenuBarFrame::DestroyFrom(nsIFrame* aDestructRoot) if (pm) pm->SetActiveMenuBar(this, false); - mTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"), mMenuBarListener, false); - mTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), mMenuBarListener, false); - mTarget->RemoveEventListener(NS_LITERAL_STRING("keyup"), mMenuBarListener, false); + mTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keypress"), mMenuBarListener, false); + mTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"), mMenuBarListener, false); + mTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keyup"), mMenuBarListener, false); mTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), mMenuBarListener, true); mTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), mMenuBarListener, false); diff --git a/layout/xul/base/src/nsMenuBarFrame.h b/layout/xul/nsMenuBarFrame.h index ae1dbd36f..d9a2deafc 100644 --- a/layout/xul/base/src/nsMenuBarFrame.h +++ b/layout/xul/nsMenuBarFrame.h @@ -22,42 +22,42 @@ class nsIContent; nsIFrame* NS_NewMenuBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -class nsMenuBarFrame : public nsBoxFrame, public nsMenuParent +class nsMenuBarFrame final : public nsBoxFrame, public nsMenuParent { public: NS_DECL_QUERYFRAME_TARGET(nsMenuBarFrame) NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - nsMenuBarFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsMenuBarFrame(nsStyleContext* aContext); // nsMenuParent interface - virtual nsMenuFrame* GetCurrentMenuItem() MOZ_OVERRIDE; - NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE; - virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE; - NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE; + virtual nsMenuFrame* GetCurrentMenuItem() override; + NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) override; + virtual void CurrentMenuIsBeingDestroyed() override; + NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) override; - NS_IMETHOD SetActive(bool aActiveFlag) MOZ_OVERRIDE; + NS_IMETHOD SetActive(bool aActiveFlag) override; - virtual bool IsMenuBar() MOZ_OVERRIDE { return true; } - virtual bool IsContextMenu() MOZ_OVERRIDE { return false; } - virtual bool IsActive() MOZ_OVERRIDE { return mIsActive; } - virtual bool IsMenu() MOZ_OVERRIDE { return false; } - virtual bool IsOpen() MOZ_OVERRIDE { return true; } // menubars are considered always open + virtual bool IsMenuBar() override { return true; } + virtual bool IsContextMenu() override { return false; } + virtual bool IsActive() override { return mIsActive; } + virtual bool IsMenu() override { return false; } + virtual bool IsOpen() override { return true; } // menubars are considered always open bool IsMenuOpen() { return mCurrentMenu && mCurrentMenu->IsOpen(); } void InstallKeyboardNavigator(); void RemoveKeyboardNavigator(); - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - virtual void LockMenuUntilClosed(bool aLock) MOZ_OVERRIDE {} - virtual bool IsMenuLocked() MOZ_OVERRIDE { return false; } + virtual void LockMenuUntilClosed(bool aLock) override {} + virtual bool IsMenuLocked() override { return false; } // Non-interface helpers @@ -76,16 +76,16 @@ public: // indicate that a menu on the menubar was closed. Returns true if the caller // may deselect the menuitem. - virtual bool MenuClosed() MOZ_OVERRIDE; + virtual bool MenuClosed() override; // Called when Enter is pressed while the menubar is focused. If the current // menu is open, let the child handle the key. - nsMenuFrame* Enter(nsGUIEvent* aEvent); + nsMenuFrame* Enter(mozilla::WidgetGUIEvent* aEvent); // Used to handle ALT+key combos nsMenuFrame* FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent); - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + virtual bool IsFrameOfType(uint32_t aFlags) const override { // Override bogus IsFrameOfType in nsBoxFrame. if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) @@ -93,8 +93,8 @@ public: return nsBoxFrame::IsFrameOfType(aFlags); } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("MenuBar"), aResult); } diff --git a/layout/xul/base/src/nsMenuBarListener.cpp b/layout/xul/nsMenuBarListener.cpp index 91788ee07..94f3d8fbc 100644 --- a/layout/xul/base/src/nsMenuBarListener.cpp +++ b/layout/xul/nsMenuBarListener.cpp @@ -7,7 +7,6 @@ #include "nsMenuBarFrame.h" #include "nsMenuPopupFrame.h" #include "nsIDOMEvent.h" -#include "nsGUIEvent.h" // Drag & Drop, Clipboard #include "nsIServiceManager.h" @@ -19,7 +18,9 @@ #include "nsIDOMElement.h" #include "nsContentUtils.h" +#include "mozilla/BasicEvents.h" #include "mozilla/Preferences.h" +#include "mozilla/TextEvents.h" using namespace mozilla; @@ -27,18 +28,12 @@ using namespace mozilla; * nsMenuBarListener implementation */ -NS_IMPL_ISUPPORTS1(nsMenuBarListener, nsIDOMEventListener) - -#define MODIFIER_SHIFT 1 -#define MODIFIER_CONTROL 2 -#define MODIFIER_ALT 4 -#define MODIFIER_META 8 -#define MODIFIER_OS 16 +NS_IMPL_ISUPPORTS(nsMenuBarListener, nsIDOMEventListener) //////////////////////////////////////////////////////////////////////// int32_t nsMenuBarListener::mAccessKey = -1; -uint32_t nsMenuBarListener::mAccessKeyMask = 0; +Modifiers nsMenuBarListener::mAccessKeyMask = 0; bool nsMenuBarListener::mAccessKeyFocuses = false; nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBar) @@ -52,6 +47,13 @@ nsMenuBarListener::~nsMenuBarListener() { } +void +nsMenuBarListener::InitializeStatics() +{ + Preferences::AddBoolVarCache(&mAccessKeyFocuses, + "ui.key.menuAccessKeyFocuses"); +} + nsresult nsMenuBarListener::GetMenuAccessKey(int32_t* aAccessKey) { @@ -89,8 +91,6 @@ void nsMenuBarListener::InitAccessKey() mAccessKeyMask = MODIFIER_META; else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_WIN) mAccessKeyMask = MODIFIER_OS; - - mAccessKeyFocuses = Preferences::GetBool("ui.key.menuAccessKeyFocuses"); } void @@ -101,7 +101,7 @@ nsMenuBarListener::ToggleMenuActiveState() if (pm && closemenu) { nsMenuPopupFrame* popupFrame = closemenu->GetPopup(); if (popupFrame) - pm->HidePopup(popupFrame->GetContent(), false, false, true); + pm->HidePopup(popupFrame->GetContent(), false, false, true, false); } } @@ -197,8 +197,8 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) bool hasAccessKeyCandidates = charCode != 0; if (!hasAccessKeyCandidates) { - nsEvent* nativeEvent = nsContentUtils::GetNativeEvent(aKeyEvent); - nsKeyEvent* nativeKeyEvent = static_cast<nsKeyEvent*>(nativeEvent); + WidgetKeyboardEvent* nativeKeyEvent = + aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent(); if (nativeKeyEvent) { nsAutoTArray<uint32_t, 10> keys; nsContentUtils::GetAccessKeyCandidates(nativeKeyEvent, keys); @@ -233,13 +233,17 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) #ifndef XP_MACOSX // Also need to handle F10 specially on Non-Mac platform. else if (keyCode == NS_VK_F10) { - if ((GetModifiers(keyEvent) & ~MODIFIER_CONTROL) == 0) { + if ((GetModifiersForAccessKey(keyEvent) & ~MODIFIER_CONTROL) == 0) { // The F10 key just went down by itself or with ctrl pressed. // In Windows, both of these activate the menu bar. mMenuBarFrame->SetActiveByKeyboard(); ToggleMenuActiveState(); if (mMenuBarFrame->IsActive()) { +#ifdef MOZ_WIDGET_GTK + // In GTK, this also opens the first menu. + mMenuBarFrame->GetCurrentMenuItem()->OpenMenu(true); +#endif aKeyEvent->StopPropagation(); aKeyEvent->PreventDefault(); return NS_OK; // consume the event @@ -258,42 +262,24 @@ nsMenuBarListener::IsAccessKeyPressed(nsIDOMKeyEvent* aKeyEvent) { InitAccessKey(); // No other modifiers are allowed to be down except for Shift. - uint32_t modifiers = GetModifiers(aKeyEvent); + uint32_t modifiers = GetModifiersForAccessKey(aKeyEvent); return (mAccessKeyMask != MODIFIER_SHIFT && (modifiers & mAccessKeyMask) && (modifiers & ~(mAccessKeyMask | MODIFIER_SHIFT)) == 0); } -uint32_t -nsMenuBarListener::GetModifiers(nsIDOMKeyEvent* aKeyEvent) +Modifiers +nsMenuBarListener::GetModifiersForAccessKey(nsIDOMKeyEvent* aKeyEvent) { - uint32_t modifiers = 0; - nsInputEvent* inputEvent = - static_cast<nsInputEvent*>(aKeyEvent->GetInternalNSEvent()); + WidgetInputEvent* inputEvent = + aKeyEvent->GetInternalNSEvent()->AsInputEvent(); MOZ_ASSERT(inputEvent); - if (inputEvent->IsShift()) { - modifiers |= MODIFIER_SHIFT; - } - - if (inputEvent->IsControl()) { - modifiers |= MODIFIER_CONTROL; - } - - if (inputEvent->IsAlt()) { - modifiers |= MODIFIER_ALT; - } - - if (inputEvent->IsMeta()) { - modifiers |= MODIFIER_META; - } - - if (inputEvent->IsOS()) { - modifiers |= MODIFIER_OS; - } - - return modifiers; + static const Modifiers kPossibleModifiersForAccessKey = + (MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_META | + MODIFIER_OS); + return (inputEvent->modifiers & kPossibleModifiersForAccessKey); } //////////////////////////////////////////////////////////////////////// @@ -325,7 +311,7 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) // enhanced 102-key keyboards if we don't check this. bool isAccessKeyDownEvent = ((theChar == (uint32_t)mAccessKey) && - (GetModifiers(keyEvent) & ~mAccessKeyMask) == 0); + (GetModifiersForAccessKey(keyEvent) & ~mAccessKeyMask) == 0); if (!mAccessKeyDown) { // If accesskey isn't being pressed and the key isn't the accesskey, diff --git a/layout/xul/base/src/nsMenuBarListener.h b/layout/xul/nsMenuBarListener.h index 7cda4b65e..cbab21e3f 100644 --- a/layout/xul/base/src/nsMenuBarListener.h +++ b/layout/xul/nsMenuBarListener.h @@ -6,6 +6,7 @@ #define nsMenuBarListener_h__ #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "nsIDOMEventListener.h" // X.h defines KeyPress @@ -18,17 +19,16 @@ class nsIDOMKeyEvent; /** editor Implementation of the DragListener interface */ -class nsMenuBarListener : public nsIDOMEventListener +class nsMenuBarListener final : public nsIDOMEventListener { public: /** default constructor */ - nsMenuBarListener(nsMenuBarFrame* aMenuBar); - /** default destructor - */ - virtual ~nsMenuBarListener(); + explicit nsMenuBarListener(nsMenuBarFrame* aMenuBar); + + static void InitializeStatics(); - NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE; + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override; nsresult KeyUp(nsIDOMEvent* aMouseEvent); nsresult KeyDown(nsIDOMEvent* aMouseEvent); @@ -43,9 +43,13 @@ public: static bool IsAccessKeyPressed(nsIDOMKeyEvent* event); protected: + /** default destructor + */ + virtual ~nsMenuBarListener(); + static void InitAccessKey(); - static uint32_t GetModifiers(nsIDOMKeyEvent* event); + static mozilla::Modifiers GetModifiersForAccessKey(nsIDOMKeyEvent* event); // This should only be called by the nsMenuBarListener during event dispatch, // thus ensuring that this doesn't get destroyed during the process. @@ -58,7 +62,7 @@ protected: bool mAccessKeyDownCanceled; static bool mAccessKeyFocuses; // Does the access key by itself focus the menubar? static int32_t mAccessKey; // See nsIDOMKeyEvent.h for sample values - static uint32_t mAccessKeyMask;// Modifier mask for the access key + static mozilla::Modifiers mAccessKeyMask;// Modifier mask for the access key }; diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp index 5390736a1..e7f429403 100644 --- a/layout/xul/base/src/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -13,7 +13,7 @@ #include "nsIPresShell.h" #include "nsStyleContext.h" #include "nsCSSRendering.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsMenuPopupFrame.h" #include "nsMenuBarFrame.h" #include "nsIDocument.h" @@ -25,23 +25,25 @@ #include "nsIServiceManager.h" #include "nsCSSFrameConstructor.h" #include "nsIDOMKeyEvent.h" -#include "nsEventDispatcher.h" #include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsUnicharUtils.h" #include "nsIStringBundle.h" -#include "nsGUIEvent.h" #include "nsContentUtils.h" #include "nsDisplayList.h" #include "nsIReflowCallback.h" #include "nsISound.h" -#include "nsEventStateManager.h" #include "nsIDOMXULMenuListElement.h" #include "mozilla/Attributes.h" +#include "mozilla/EventDispatcher.h" +#include "mozilla/EventStateManager.h" #include "mozilla/Likely.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/MouseEvents.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/TextEvents.h" +#include "mozilla/dom/Element.h" #include <algorithm> using namespace mozilla; @@ -74,7 +76,7 @@ public: { } - NS_IMETHOD Run() + NS_IMETHOD Run() override { nsAutoString domEventToFire; @@ -93,15 +95,15 @@ public: } nsCOMPtr<nsIDOMEvent> event; - if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(mMenu, mPresContext, nullptr, - NS_LITERAL_STRING("Events"), - getter_AddRefs(event)))) { + if (NS_SUCCEEDED(EventDispatcher::CreateEvent(mMenu, mPresContext, nullptr, + NS_LITERAL_STRING("Events"), + getter_AddRefs(event)))) { event->InitEvent(domEventToFire, true, true); event->SetTrusted(true); - nsEventDispatcher::DispatchDOMEvent(mMenu, nullptr, event, - mPresContext, nullptr); + EventDispatcher::DispatchDOMEvent(mMenu, nullptr, event, + mPresContext, nullptr); } return NS_OK; @@ -121,7 +123,7 @@ public: { } - NS_IMETHOD Run() + NS_IMETHOD Run() override { nsMenuFrame* frame = static_cast<nsMenuFrame*>(mFrame.GetFrame()); NS_ENSURE_STATE(frame); @@ -153,7 +155,7 @@ protected: nsIFrame* NS_NewMenuFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - nsMenuFrame* it = new (aPresShell) nsMenuFrame (aPresShell, aContext); + nsMenuFrame* it = new (aPresShell) nsMenuFrame(aContext); it->SetIsMenu(true); return it; } @@ -161,7 +163,7 @@ NS_NewMenuFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) nsIFrame* NS_NewMenuItemFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - nsMenuFrame* it = new (aPresShell) nsMenuFrame (aPresShell, aContext); + nsMenuFrame* it = new (aPresShell) nsMenuFrame(aContext); it->SetIsMenu(false); return it; } @@ -172,53 +174,42 @@ NS_QUERYFRAME_HEAD(nsMenuFrame) NS_QUERYFRAME_ENTRY(nsMenuFrame) NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) -nsMenuFrame::nsMenuFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext), +nsMenuFrame::nsMenuFrame(nsStyleContext* aContext): + nsBoxFrame(aContext), mIsMenu(false), mChecked(false), mIgnoreAccelTextChange(false), mType(eMenuType_Normal), - mMenuParent(nullptr), mBlinkState(0) { } -void -nsMenuFrame::SetParent(nsIFrame* aParent) -{ - nsBoxFrame::SetParent(aParent); - InitMenuParent(aParent); -} - -void -nsMenuFrame::InitMenuParent(nsIFrame* aParent) +nsMenuParent* +nsMenuFrame::GetMenuParent() const { - while (aParent) { - nsMenuPopupFrame* popup = do_QueryFrame(aParent); + nsContainerFrame* parent = GetParent(); + for (; parent; parent = parent->GetParent()) { + nsMenuPopupFrame* popup = do_QueryFrame(parent); if (popup) { - mMenuParent = popup; - break; + return popup; } - - nsMenuBarFrame* menubar = do_QueryFrame(aParent); + nsMenuBarFrame* menubar = do_QueryFrame(parent); if (menubar) { - mMenuParent = menubar; - break; + return menubar; } - - aParent = aParent->GetParent(); } + return nullptr; } -class nsASyncMenuInitialization MOZ_FINAL : public nsIReflowCallback +class nsASyncMenuInitialization final : public nsIReflowCallback { public: - nsASyncMenuInitialization(nsIFrame* aFrame) + explicit nsASyncMenuInitialization(nsIFrame* aFrame) : mWeakFrame(aFrame) { } - virtual bool ReflowFinished() + virtual bool ReflowFinished() override { bool shouldFlush = false; nsMenuFrame* menu = do_QueryFrame(mWeakFrame.GetFrame()); @@ -230,7 +221,7 @@ public: return shouldFlush; } - virtual void ReflowCallbackCanceled() + virtual void ReflowCallbackCanceled() override { delete this; } @@ -239,17 +230,15 @@ public: }; void -nsMenuFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsMenuFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); // Set up a mediator which can be used for callbacks on this frame. mTimerMediator = new nsMenuTimerMediator(this); - InitMenuParent(aParent); - BuildAcceleratorText(false); nsIReflowCallback* cb = new nsASyncMenuInitialization(this); PresContext()->PresShell()->PostReflowCallback(cb); @@ -325,7 +314,7 @@ nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList) } } -NS_IMETHODIMP +void nsMenuFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { @@ -333,7 +322,7 @@ nsMenuFrame::SetInitialChildList(ChildListID aListID, if (aListID == kPrincipalList || aListID == kPopupList) { SetPopupFrame(aChildList); } - return nsBoxFrame::SetInitialChildList(aListID, aChildList); + nsBoxFrame::SetInitialChildList(aListID, aChildList); } void @@ -357,9 +346,10 @@ nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot) mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive, false); // are we our menu parent's current menu item? - if (mMenuParent && mMenuParent->GetCurrentMenuItem() == this) { + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent && menuParent->GetCurrentMenuItem() == this) { // yes; tell it that we're going away - mMenuParent->CurrentMenuIsBeingDestroyed(); + menuParent->CurrentMenuIsBeingDestroyed(); } nsFrameList* popupList = GetPopupList(); @@ -387,14 +377,17 @@ nsMenuFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, WrapListsInRedirector(aBuilder, set, aLists); } -NS_IMETHODIMP -nsMenuFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsresult +nsMenuFrame::HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); - if (nsEventStatus_eConsumeNoDefault == *aEventStatus || - (mMenuParent && mMenuParent->IsMenuLocked())) { + if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { + return NS_OK; + } + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent && menuParent->IsMenuLocked()) { return NS_OK; } @@ -405,7 +398,7 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, bool onmenu = IsOnMenu(); if (aEvent->message == NS_KEY_PRESS && !IsDisabled()) { - nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; + WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); uint32_t keyCode = keyEvent->keyCode; #ifdef XP_MACOSX // On mac, open menulist on either up/down arrow or space (w/o Cmd pressed) @@ -423,15 +416,14 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, } #endif } - else if (aEvent->eventStructType == NS_MOUSE_EVENT && - aEvent->message == NS_MOUSE_BUTTON_DOWN && - static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton && + else if (aEvent->message == NS_MOUSE_BUTTON_DOWN && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton && !IsDisabled() && IsMenu()) { // The menu item was selected. Bring up the menu. // We have children. // Don't prevent the default action here, since that will also cancel // potential drag starts. - if (!mMenuParent || mMenuParent->IsMenuBar()) { + if (!menuParent || menuParent->IsMenuBar()) { ToggleMenuState(); } else { @@ -442,14 +434,12 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, } else if ( #ifndef NSCONTEXTMENUISMOUSEUP - (aEvent->eventStructType == NS_MOUSE_EVENT && - aEvent->message == NS_MOUSE_BUTTON_UP && - static_cast<nsMouseEvent*>(aEvent)->button == - nsMouseEvent::eRightButton) && + (aEvent->message == NS_MOUSE_BUTTON_UP && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eRightButton) && #else - aEvent->message == NS_CONTEXTMENU && + aEvent->message == NS_CONTEXTMENU && #endif - onmenu && !IsMenu() && !IsDisabled()) { + onmenu && !IsMenu() && !IsDisabled()) { // if this menu is a context menu it accepts right-clicks...fire away! // Make sure we cancel default processing of the context menu event so // that it doesn't bubble and get seen again by the popuplistener and show @@ -460,14 +450,13 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, // on others we get it on a mouse down. For the ones where we get it on a // mouse down, we must continue listening for the right button up event to // dismiss the menu. - if (mMenuParent->IsContextMenu()) { + if (menuParent->IsContextMenu()) { *aEventStatus = nsEventStatus_eConsumeNoDefault; Execute(aEvent); } } - else if (aEvent->eventStructType == NS_MOUSE_EVENT && - aEvent->message == NS_MOUSE_BUTTON_UP && - static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton && + else if (aEvent->message == NS_MOUSE_BUTTON_UP && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton && !IsMenu() && !IsDisabled()) { // Execute the execute event handler. *aEventStatus = nsEventStatus_eConsumeNoDefault; @@ -481,33 +470,33 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, } // Deactivate the menu. - if (mMenuParent) { - bool onmenubar = mMenuParent->IsMenuBar(); - if (!(onmenubar && mMenuParent->IsActive())) { + if (menuParent) { + bool onmenubar = menuParent->IsMenuBar(); + if (!(onmenubar && menuParent->IsActive())) { if (IsMenu() && !onmenubar && IsOpen()) { // Submenus don't get closed up immediately. } - else if (this == mMenuParent->GetCurrentMenuItem()) { - mMenuParent->ChangeMenuItem(nullptr, false); + else if (this == menuParent->GetCurrentMenuItem()) { + menuParent->ChangeMenuItem(nullptr, false); } } } } else if (aEvent->message == NS_MOUSE_MOVE && - (onmenu || (mMenuParent && mMenuParent->IsMenuBar()))) { + (onmenu || (menuParent && menuParent->IsMenuBar()))) { if (gEatMouseMove) { gEatMouseMove = false; return NS_OK; } // Let the menu parent know we're the new item. - mMenuParent->ChangeMenuItem(this, false); + menuParent->ChangeMenuItem(this, false); NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_OK); - NS_ENSURE_TRUE(mMenuParent, NS_OK); + NS_ENSURE_TRUE(menuParent, NS_OK); // we need to check if we really became the current menu // item or not - nsMenuFrame *realCurrentItem = mMenuParent->GetCurrentMenuItem(); + nsMenuFrame *realCurrentItem = menuParent->GetCurrentMenuItem(); if (realCurrentItem != this) { // we didn't (presumably because a context menu was active) return NS_OK; @@ -517,7 +506,7 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext, // A timer is used so that it doesn't open if the user moves the mouse quickly // past the menu. This conditional check ensures that only menus have this // behaviour - if (!IsDisabled() && IsMenu() && !IsOpen() && !mOpenTimer && !mMenuParent->IsMenuBar()) { + if (!IsDisabled() && IsMenu() && !IsOpen() && !mOpenTimer && !menuParent->IsMenuBar()) { int32_t menuDelay = LookAndFeel::GetInt(LookAndFeel::eIntID_SubmenuDelay, 300); // ms @@ -548,11 +537,12 @@ nsMenuFrame::PopupOpened() if (!weakFrame.IsAlive()) return; - if (mMenuParent) { - mMenuParent->SetActive(true); + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent) { + menuParent->SetActive(true); // Make sure the current menu which is being toggled on // the menubar is highlighted - mMenuParent->SetCurrentMenuItem(this); + menuParent->SetCurrentMenuItem(this); } } @@ -566,14 +556,15 @@ nsMenuFrame::PopupClosed(bool aDeselectMenu) return; // if the popup is for a menu on a menubar, inform menubar to deactivate - if (mMenuParent && mMenuParent->MenuClosed()) { + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent && menuParent->MenuClosed()) { if (aDeselectMenu) { SelectMenu(false); } else { // We are not deselecting the parent menu while closing the popup, so send // a DOMMenuItemActive event to the menu to indicate that the menu is // becoming active again. - nsMenuFrame *current = mMenuParent->GetCurrentMenuItem(); + nsMenuFrame *current = menuParent->GetCurrentMenuItem(); if (current) { // However, if the menu is a descendant on a menubar, and the menubar // has the 'stay active' flag set, it means that the menubar is switching @@ -636,8 +627,10 @@ nsMenuFrame::SelectMenu(bool aActivateFlag) // cancel the close timer if selecting a menu within the popup to be closed nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (pm) - pm->CancelMenuTimer(mMenuParent); + if (pm) { + nsMenuParent* menuParent = GetMenuParent(); + pm->CancelMenuTimer(menuParent); + } nsCOMPtr<nsIRunnable> event = new nsMenuActivateEvent(mContent, PresContext(), aActivateFlag); @@ -647,7 +640,7 @@ nsMenuFrame::SelectMenu(bool aActivateFlag) return NS_OK; } -NS_IMETHODIMP +nsresult nsMenuFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -670,6 +663,27 @@ nsMenuFrame::AttributeChanged(int32_t aNameSpaceID, return NS_OK; } +nsIContent* +nsMenuFrame::GetAnchor() +{ + mozilla::dom::Element* anchor = nullptr; + + nsAutoString id; + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::anchor, id); + if (!id.IsEmpty()) { + nsIDocument* doc = mContent->OwnerDoc(); + + anchor = + doc->GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid, id); + if (!anchor) { + anchor = doc->GetElementById(id); + } + } + + // Always return the menu's content if the anchor wasn't set or wasn't found. + return anchor && anchor->GetPrimaryFrame() ? anchor : mContent; +} + void nsMenuFrame::OpenMenu(bool aSelectFirstItem) { @@ -694,23 +708,16 @@ nsMenuFrame::CloseMenu(bool aDeselectMenu) // Close the menu asynchronously nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm && HasPopup()) - pm->HidePopup(GetPopup()->GetContent(), false, aDeselectMenu, true); + pm->HidePopup(GetPopup()->GetContent(), false, aDeselectMenu, true, false); } bool nsMenuFrame::IsSizedToPopup(nsIContent* aContent, bool aRequireAlways) { - bool sizeToPopup; - if (aContent->Tag() == nsGkAtoms::select) - sizeToPopup = true; - else { - nsAutoString sizedToPopup; - aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::sizetopopup, sizedToPopup); - sizeToPopup = sizedToPopup.EqualsLiteral("always") || - (!aRequireAlways && sizedToPopup.EqualsLiteral("pref")); - } - - return sizeToPopup; + nsAutoString sizedToPopup; + aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::sizetopopup, sizedToPopup); + return sizedToPopup.EqualsLiteral("always") || + (!aRequireAlways && sizedToPopup.EqualsLiteral("pref")); } nsSize @@ -734,14 +741,14 @@ nsMenuFrame::DoLayout(nsBoxLayoutState& aState) nsMenuPopupFrame* popupFrame = GetPopup(); if (popupFrame) { bool sizeToPopup = IsSizedToPopup(mContent, false); - popupFrame->LayoutPopup(aState, this, sizeToPopup); + popupFrame->LayoutPopup(aState, this, GetAnchor()->GetPrimaryFrame(), sizeToPopup); } return rv; } #ifdef DEBUG_LAYOUT -NS_IMETHODIMP +nsresult nsMenuFrame::SetDebug(nsBoxLayoutState& aState, bool aDebug) { // see if our state matches the given debug state @@ -785,17 +792,18 @@ nsMenuFrame::SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, bool aDebug) // In either case, do nothing if the item is disabled. // nsMenuFrame* -nsMenuFrame::Enter(nsGUIEvent *aEvent) +nsMenuFrame::Enter(WidgetGUIEvent* aEvent) { if (IsDisabled()) { #ifdef XP_WIN // behavior on Windows - close the popup chain - if (mMenuParent) { + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) { nsIFrame* popup = pm->GetTopPopup(ePopupTypeAny); if (popup) - pm->HidePopup(popup->GetContent(), true, true, true); + pm->HidePopup(popup->GetContent(), true, true, true, false); } } #endif // #ifdef XP_WIN @@ -805,7 +813,8 @@ nsMenuFrame::Enter(nsGUIEvent *aEvent) if (!IsOpen()) { // The enter key press applies to us. - if (!IsMenu() && mMenuParent) + nsMenuParent* menuParent = GetMenuParent(); + if (!IsMenu() && menuParent) Execute(aEvent); // Execute our event handler else return this; @@ -830,8 +839,9 @@ nsMenuFrame::IsMenu() nsMenuListType nsMenuFrame::GetParentMenuListType() { - if (mMenuParent && mMenuParent->IsMenu()) { - nsMenuPopupFrame* popupFrame = static_cast<nsMenuPopupFrame*>(mMenuParent); + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent && menuParent->IsMenu()) { + nsMenuPopupFrame* popupFrame = static_cast<nsMenuPopupFrame*>(menuParent); nsIFrame* parentMenu = popupFrame->GetParent(); if (parentMenu) { nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(parentMenu->GetContent()); @@ -852,12 +862,13 @@ nsMenuFrame::Notify(nsITimer* aTimer) if (aTimer == mOpenTimer.get()) { mOpenTimer = nullptr; - if (!IsOpen() && mMenuParent) { + nsMenuParent* menuParent = GetMenuParent(); + if (!IsOpen() && menuParent) { // make sure we didn't open a context menu in the meantime // (i.e. the user right-clicked while hovering over a submenu). nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) { - if ((!pm->HasContextMenu(nullptr) || mMenuParent->IsContextMenu()) && + if ((!pm->HasContextMenu(nullptr) || menuParent->IsContextMenu()) && mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::menuactive, nsGkAtoms::_true, eCaseMatters)) { OpenMenu(false); @@ -881,13 +892,15 @@ nsMenuFrame::Notify(nsITimer* aTimer) } } break; - default: - if (mMenuParent) { - mMenuParent->LockMenuUntilClosed(false); + default: { + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent) { + menuParent->LockMenuUntilClosed(false); } PassMenuCommandEventToPopupManager(); StopBlinking(); break; + } } } @@ -973,11 +986,11 @@ nsMenuFrame::UpdateMenuSpecialState(nsPresContext* aPresContext) // get the first sibling in this menu popup. This frame may be it, and if we're // being called at creation time, this frame isn't yet in the parent's child list. // All I'm saying is that this may fail, but it's most likely alright. - nsIFrame* sib = GetParent()->GetFirstPrincipalChild(); - + nsIFrame* firstMenuItem = nsXULPopupManager::GetNextMenuItem(GetParent(), nullptr, true); + nsIFrame* sib = firstMenuItem; while (sib) { + nsMenuFrame* menu = do_QueryFrame(sib); if (sib != this) { - nsMenuFrame* menu = do_QueryFrame(sib); if (menu && menu->GetMenuType() == eMenuType_Radio && menu->IsChecked() && menu->GetRadioGroupName() == mGroupName) { /* uncheck the old item */ @@ -987,8 +1000,10 @@ nsMenuFrame::UpdateMenuSpecialState(nsPresContext* aPresContext) return; } } - - sib = sib->GetNextSibling(); + sib = nsXULPopupManager::GetNextMenuItem(GetParent(), menu, true); + if (sib == firstMenuItem) { + break; + } } } @@ -1019,10 +1034,12 @@ nsMenuFrame::BuildAcceleratorText(bool aNotify) return; // Turn the document into a DOM document so we can use getElementById - nsIDocument *document = mContent->GetDocument(); + nsIDocument *document = mContent->GetUncomposedDoc(); if (!document) return; + //XXXsmaug If mContent is in shadow dom, should we use + // ShadowRoot::GetElementById()? nsIContent *keyElement = document->GetElementById(keyValue); if (!keyElement) { #ifdef DEBUG @@ -1076,22 +1093,6 @@ nsMenuFrame::BuildAcceleratorText(bool aNotify) } } - static int32_t accelKey = 0; - - if (!accelKey) - { - // Compiled-in defaults, in case we can't get LookAndFeel -- - // command for mac, control for all other platforms. -#ifdef XP_MACOSX - accelKey = nsIDOMKeyEvent::DOM_VK_META; -#else - accelKey = nsIDOMKeyEvent::DOM_VK_CONTROL; -#endif - - // Get the accelerator key value from prefs, overriding the default: - accelKey = Preferences::GetInt("ui.key.accelKey", accelKey); - } - nsAutoString modifiers; keyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiers); @@ -1126,24 +1127,23 @@ nsMenuFrame::BuildAcceleratorText(bool aNotify) else if (PL_strcmp(token, "control") == 0) accelText += controlText; else if (PL_strcmp(token, "accel") == 0) { - switch (accelKey) - { - case nsIDOMKeyEvent::DOM_VK_META: + switch (WidgetInputEvent::AccelModifier()) { + case MODIFIER_META: accelText += metaText; break; - - case nsIDOMKeyEvent::DOM_VK_WIN: + case MODIFIER_OS: accelText += osText; break; - - case nsIDOMKeyEvent::DOM_VK_ALT: + case MODIFIER_ALT: accelText += altText; break; - - case nsIDOMKeyEvent::DOM_VK_CONTROL: - default: + case MODIFIER_CONTROL: accelText += controlText; break; + default: + MOZ_CRASH( + "Handle the new result of WidgetInputEvent::AccelModifier()"); + break; } } @@ -1164,7 +1164,7 @@ nsMenuFrame::BuildAcceleratorText(bool aNotify) } void -nsMenuFrame::Execute(nsGUIEvent *aEvent) +nsMenuFrame::Execute(WidgetGUIEvent* aEvent) { // flip "checked" state if we're a checkbox menu, or an un-checked radio menu bool needToFlipChecked = false; @@ -1196,7 +1196,7 @@ nsMenuFrame::ShouldBlink() } void -nsMenuFrame::StartBlinking(nsGUIEvent *aEvent, bool aFlipChecked) +nsMenuFrame::StartBlinking(WidgetGUIEvent* aEvent, bool aFlipChecked) { StopBlinking(); CreateMenuCommandEvent(aEvent, aFlipChecked); @@ -1212,9 +1212,10 @@ nsMenuFrame::StartBlinking(nsGUIEvent *aEvent, bool aFlipChecked) if (!weakFrame.IsAlive()) return; - if (mMenuParent) { + nsMenuParent* menuParent = GetMenuParent(); + if (menuParent) { // Make this menu ignore events from now on. - mMenuParent->LockMenuUntilClosed(true); + menuParent->LockMenuUntilClosed(true); } // Set up a timer to blink back on. @@ -1235,7 +1236,7 @@ nsMenuFrame::StopBlinking() } void -nsMenuFrame::CreateMenuCommandEvent(nsGUIEvent *aEvent, bool aFlipChecked) +nsMenuFrame::CreateMenuCommandEvent(WidgetGUIEvent* aEvent, bool aFlipChecked) { // Create a trusted event if the triggering event was trusted, or if // we're called from chrome code (since at least one of our caller @@ -1244,18 +1245,18 @@ nsMenuFrame::CreateMenuCommandEvent(nsGUIEvent *aEvent, bool aFlipChecked) nsContentUtils::IsCallerChrome(); bool shift = false, control = false, alt = false, meta = false; - if (aEvent && (aEvent->eventStructType == NS_MOUSE_EVENT || - aEvent->eventStructType == NS_KEY_EVENT)) { - shift = static_cast<nsInputEvent *>(aEvent)->IsShift(); - control = static_cast<nsInputEvent *>(aEvent)->IsControl(); - alt = static_cast<nsInputEvent *>(aEvent)->IsAlt(); - meta = static_cast<nsInputEvent *>(aEvent)->IsMeta(); + WidgetInputEvent* inputEvent = aEvent ? aEvent->AsInputEvent() : nullptr; + if (inputEvent) { + shift = inputEvent->IsShift(); + control = inputEvent->IsControl(); + alt = inputEvent->IsAlt(); + meta = inputEvent->IsMeta(); } // Because the command event is firing asynchronously, a flag is needed to // indicate whether user input is being handled. This ensures that a popup // window won't get blocked. - bool userinput = nsEventStateManager::IsHandlingUserInput(); + bool userinput = EventStateManager::IsHandlingUserInput(); mDelayedMenuCommandEvent = new nsXULMenuCommandEvent(mContent, isTrusted, shift, control, alt, meta, @@ -1266,13 +1267,14 @@ void nsMenuFrame::PassMenuCommandEventToPopupManager() { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); - if (pm && mMenuParent && mDelayedMenuCommandEvent) { + nsMenuParent* menuParent = GetMenuParent(); + if (pm && menuParent && mDelayedMenuCommandEvent) { pm->ExecuteMenu(mContent, mDelayedMenuCommandEvent); } mDelayedMenuCommandEvent = nullptr; } -NS_IMETHODIMP +void nsMenuFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { @@ -1284,12 +1286,12 @@ nsMenuFrame::RemoveFrame(ChildListID aListID, PresContext()->PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); - return NS_OK; + return; } - return nsBoxFrame::RemoveFrame(aListID, aOldFrame); + nsBoxFrame::RemoveFrame(aListID, aOldFrame); } -NS_IMETHODIMP +void nsMenuFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) @@ -1309,16 +1311,16 @@ nsMenuFrame::InsertFrames(ChildListID aListID, } if (aFrameList.IsEmpty()) - return NS_OK; + return; if (MOZ_UNLIKELY(aPrevFrame && aPrevFrame == GetPopup())) { aPrevFrame = nullptr; } - return nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); + nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); } -NS_IMETHODIMP +void nsMenuFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { @@ -1337,9 +1339,9 @@ nsMenuFrame::AppendFrames(ChildListID aListID, } if (aFrameList.IsEmpty()) - return NS_OK; + return; - return nsBoxFrame::AppendFrames(aListID, aFrameList); + nsBoxFrame::AppendFrames(aListID, aFrameList); } bool @@ -1455,7 +1457,7 @@ nsIScrollableFrame* nsMenuFrame::GetScrollTargetFrame() } // nsMenuTimerMediator implementation. -NS_IMPL_ISUPPORTS1(nsMenuTimerMediator, nsITimerCallback) +NS_IMPL_ISUPPORTS(nsMenuTimerMediator, nsITimerCallback) /** * Constructs a wrapper around an nsMenuFrame. diff --git a/layout/xul/base/src/nsMenuFrame.h b/layout/xul/nsMenuFrame.h index d88807daa..0dc31c949 100644 --- a/layout/xul/base/src/nsMenuFrame.h +++ b/layout/xul/nsMenuFrame.h @@ -55,11 +55,10 @@ class nsMenuFrame; * to it. The callback is delegated to the contained nsMenuFrame as long as * the contained nsMenuFrame has not been destroyed. */ -class nsMenuTimerMediator MOZ_FINAL : public nsITimerCallback +class nsMenuTimerMediator final : public nsITimerCallback { public: - nsMenuTimerMediator(nsMenuFrame* aFrame); - ~nsMenuTimerMediator(); + explicit nsMenuTimerMediator(nsMenuFrame* aFrame); NS_DECL_ISUPPORTS NS_DECL_NSITIMERCALLBACK @@ -67,66 +66,71 @@ public: void ClearFrame(); private: + ~nsMenuTimerMediator(); // Pointer to the wrapped frame. nsMenuFrame* mFrame; }; -class nsMenuFrame : public nsBoxFrame +class nsMenuFrame final : public nsBoxFrame { public: - nsMenuFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsMenuFrame(nsStyleContext* aContext); NS_DECL_QUERYFRAME_TARGET(nsMenuFrame) NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; #ifdef DEBUG_LAYOUT - NS_IMETHOD SetDebug(nsBoxLayoutState& aState, bool aDebug) MOZ_OVERRIDE; + virtual nsresult SetDebug(nsBoxLayoutState& aState, bool aDebug) override; #endif // The following methods are all overridden so that the menupopup // can be stored in a separate list, so that it doesn't impact reflow of the // actual menu item at all. - virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE; - virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE; - NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual const nsFrameList& GetChildList(ChildListID aList) const override; + virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; // Overridden to prevent events from going to children of the menu. virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; // this method can destroy the frame - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; - - NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) MOZ_OVERRIDE; - - NS_IMETHOD InsertFrames(ChildListID aListID, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList) MOZ_OVERRIDE; - - NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) MOZ_OVERRIDE; - - virtual nsIAtom* GetType() const MOZ_OVERRIDE { return nsGkAtoms::menuFrame; } + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + virtual void SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) override; + virtual void AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) override; + virtual void InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) override; + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; + + virtual nsIAtom* GetType() const override { return nsGkAtoms::menuFrame; } NS_IMETHOD SelectMenu(bool aActivateFlag); - virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE; + virtual nsIScrollableFrame* GetScrollTargetFrame() override; + + // Retrieve the element that the menu should be anchored to. By default this is + // the menu itself. However, the anchor attribute may refer to the value of an + // anonid within the menu's binding, or, if not found, the id of an element in + // the document. + nsIContent* GetAnchor(); /** * NOTE: OpenMenu will open the menu asynchronously. @@ -144,11 +148,11 @@ public: // one in its parent popup. This will carry out the command attached to // the menuitem. If the menu should be opened, this frame will be returned, // otherwise null will be returned. - nsMenuFrame* Enter(nsGUIEvent* aEvent); + nsMenuFrame* Enter(mozilla::WidgetGUIEvent* aEvent); - virtual void SetParent(nsIFrame* aParent) MOZ_OVERRIDE; + // Return the nearest menu bar or menupopup ancestor frame. + nsMenuParent* GetMenuParent() const; - virtual nsMenuParent *GetMenuParent() { return mMenuParent; } const nsAString& GetRadioGroupName() { return mGroupName; } nsMenuType GetMenuType() { return mType; } nsMenuPopupFrame* GetPopup(); @@ -164,8 +168,16 @@ public: // nsMenuFrame methods - bool IsOnMenuBar() { return mMenuParent && mMenuParent->IsMenuBar(); } - bool IsOnActiveMenuBar() { return IsOnMenuBar() && mMenuParent->IsActive(); } + bool IsOnMenuBar() const + { + nsMenuParent* menuParent = GetMenuParent(); + return menuParent && menuParent->IsMenuBar(); + } + bool IsOnActiveMenuBar() const + { + nsMenuParent* menuParent = GetMenuParent(); + return menuParent && menuParent->IsMenuBar() && menuParent->IsActive(); + } virtual bool IsOpen(); virtual bool IsMenu(); nsMenuListType GetParentMenuListType(); @@ -184,11 +196,15 @@ public: // returns true if this is a menu on another menu popup. A menu is a submenu // if it has a parent popup or menupopup. - bool IsOnMenu() { return mMenuParent && mMenuParent->IsMenu(); } + bool IsOnMenu() const + { + nsMenuParent* menuParent = GetMenuParent(); + return menuParent && menuParent->IsMenu(); + } void SetIsMenu(bool aIsMenu) { mIsMenu = aIsMenu; } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("Menu"), aResult); } @@ -218,11 +234,6 @@ protected: */ void DestroyPopupList(); - // set mMenuParent to the nearest enclosing menu bar or menupopup frame of - // aParent (or aParent itself). This is called when initializing the frame, - // so aParent should be the expected parent of this frame. - void InitMenuParent(nsIFrame* aParent); - // Update the menu's type (normal, checkbox, radio). // This method can destroy the frame. void UpdateMenuType(nsPresContext* aPresContext); @@ -234,35 +245,34 @@ protected: void BuildAcceleratorText(bool aNotify); // Called to execute our command handler. This method can destroy the frame. - void Execute(nsGUIEvent *aEvent); + void Execute(mozilla::WidgetGUIEvent *aEvent); // This method can destroy the frame - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; virtual ~nsMenuFrame() { } bool SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize); bool ShouldBlink(); - void StartBlinking(nsGUIEvent *aEvent, bool aFlipChecked); + void StartBlinking(mozilla::WidgetGUIEvent* aEvent, bool aFlipChecked); void StopBlinking(); - void CreateMenuCommandEvent(nsGUIEvent *aEvent, bool aFlipChecked); + void CreateMenuCommandEvent(mozilla::WidgetGUIEvent* aEvent, + bool aFlipChecked); void PassMenuCommandEventToPopupManager(); protected: #ifdef DEBUG_LAYOUT nsresult SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, bool aDebug); #endif - NS_HIDDEN_(nsresult) Notify(nsITimer* aTimer); + nsresult Notify(nsITimer* aTimer); bool mIsMenu; // Whether or not we can even have children or not. bool mChecked; // are we checked? bool mIgnoreAccelTextChange; // temporarily set while determining the accelerator key nsMenuType mType; - nsMenuParent* mMenuParent; // Our parent menu. - // Reference to the mediator which wraps this frame. nsRefPtr<nsMenuTimerMediator> mTimerMediator; diff --git a/layout/xul/base/src/nsMenuParent.h b/layout/xul/nsMenuParent.h index cc96d82a5..cc96d82a5 100644 --- a/layout/xul/base/src/nsMenuParent.h +++ b/layout/xul/nsMenuParent.h diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index 8cd5cd1d0..ce4cc2a4e 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -11,14 +11,14 @@ #include "nsPresContext.h" #include "nsStyleContext.h" #include "nsCSSRendering.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsViewManager.h" #include "nsWidgetsCID.h" #include "nsMenuFrame.h" #include "nsMenuBarFrame.h" #include "nsPopupSetFrame.h" -#include "nsEventDispatcher.h" #include "nsPIDOMWindow.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMScreen.h" #include "nsIPresShell.h" #include "nsFrameManager.h" @@ -27,16 +27,13 @@ #include "nsIComponentManager.h" #include "nsBoxLayoutState.h" #include "nsIScrollableFrame.h" -#include "nsGUIEvent.h" #include "nsIRootBox.h" -#include "nsIDocShellTreeItem.h" +#include "nsIDocShell.h" #include "nsReadableUtils.h" #include "nsUnicharUtils.h" #include "nsLayoutUtils.h" #include "nsContentUtils.h" #include "nsCSSFrameConstructor.h" -#include "nsEventStateManager.h" -#include "nsIPopupBoxObject.h" #include "nsPIWindowRoot.h" #include "nsIReflowCallback.h" #include "nsBindingManager.h" @@ -46,14 +43,26 @@ #include "nsIScreenManager.h" #include "nsIServiceManager.h" #include "nsThemeConstants.h" +#include "nsTransitionManager.h" #include "nsDisplayList.h" +#include "mozilla/EventDispatcher.h" +#include "mozilla/EventStateManager.h" +#include "mozilla/EventStates.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/PopupBoxObject.h" #include <algorithm> using namespace mozilla; +using mozilla::dom::PopupBoxObject; int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1; +uint32_t nsMenuPopupFrame::sTimeoutOfIncrementalSearch = 1000; + +const char* kPrefIncrementalSearchTimeout = + "ui.menu.incremental_search.timeout"; // NS_NewMenuPopupFrame // @@ -62,7 +71,7 @@ int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1; nsIFrame* NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsMenuPopupFrame (aPresShell, aContext); + return new (aPresShell) nsMenuPopupFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsMenuPopupFrame) @@ -74,8 +83,8 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) // // nsMenuPopupFrame ctor // -nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContext) - :nsBoxFrame(aShell, aContext), +nsMenuPopupFrame::nsMenuPopupFrame(nsStyleContext* aContext) + :nsBoxFrame(aContext), mCurrentMenu(nullptr), mPrefSize(-1, -1), mLastClientOffset(0, 0), @@ -84,8 +93,8 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex mPopupAlignment(POPUPALIGNMENT_NONE), mPopupAnchor(POPUPALIGNMENT_NONE), mPosition(POPUPPOSITION_UNKNOWN), - mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT), - mFlipBoth(false), + mConsumeRollupEvent(PopupBoxObject::ROLLUP_DEFAULT), + mFlip(FlipType_Default), mIsOpenChanged(false), mIsContextMenu(false), mAdjustOffsetForContextMenu(false), @@ -94,7 +103,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex mShouldAutoPosition(true), mInContentShell(true), mIsMenuLocked(false), - mIsDragPopup(false), + mMouseTransparent(false), mHFlip(false), mVFlip(false) { @@ -104,13 +113,14 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex return; sDefaultLevelIsTop = Preferences::GetBool("ui.panel.default_level_parent", false); + Preferences::AddUintVarCache(&sTimeoutOfIncrementalSearch, + kPrefIncrementalSearchTimeout, 1000); } // ctor - void -nsMenuPopupFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsMenuPopupFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); @@ -139,18 +149,10 @@ nsMenuPopupFrame::Init(nsIContent* aContent, mPopupType = ePopupTypeTooltip; } - if (mPopupType == ePopupTypePanel && - aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, - nsGkAtoms::drag, eIgnoreCase)) { - mIsDragPopup = true; - } - - nsCOMPtr<nsISupports> cont = PresContext()->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont); - int32_t type = -1; - if (dsti && NS_SUCCEEDED(dsti->GetItemType(&type)) && - type == nsIDocShellTreeItem::typeChrome) + nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell(); + if (dsti && dsti->ItemType() == nsIDocShellTreeItem::typeChrome) { mInContentShell = false; + } // To improve performance, create the widget for the popup only if it is not // a leaf. Leaf popups such as menus will create their widgets later when @@ -243,7 +245,20 @@ nsMenuPopupFrame::CreateWidgetForView(nsView* aView) widgetData.clipSiblings = true; widgetData.mPopupHint = mPopupType; widgetData.mNoAutoHide = IsNoAutoHide(); - widgetData.mIsDragPopup = mIsDragPopup; + + if (!mInContentShell) { + // A drag popup may be used for non-static translucent drag feedback + if (mPopupType == ePopupTypePanel && + mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, + nsGkAtoms::drag, eIgnoreCase)) { + widgetData.mIsDragPopup = true; + } + + // If mousethrough="always" is set directly on the popup, then the widget + // should ignore mouse events, passing them through to the content behind. + mMouseTransparent = GetStateBits() & NS_FRAME_MOUSE_THROUGH_ALWAYS; + widgetData.mMouseTransparent = mMouseTransparent; + } nsAutoString title; if (mContent && widgetData.mNoAutoHide) { @@ -262,15 +277,12 @@ nsMenuPopupFrame::CreateWidgetForView(nsView* aView) } nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(this, this); - bool viewHasTransparentContent = !mInContentShell && - (eTransparencyTransparent == - mode); nsIContent* parentContent = GetContent()->GetParent(); nsIAtom *tag = nullptr; if (parentContent) tag = parentContent->Tag(); widgetData.mSupportTranslucency = mode == eTransparencyTransparent; - widgetData.mDropShadow = !(viewHasTransparentContent || tag == nsGkAtoms::menulist); + widgetData.mDropShadow = !(mode == eTransparencyTransparent || tag == nsGkAtoms::menulist); widgetData.mPopupLevel = PopupLevel(widgetData.mNoAutoHide); // panels which have a parent level need a parent widget. This allows them to @@ -278,8 +290,7 @@ nsMenuPopupFrame::CreateWidgetForView(nsView* aView) // should be in front of it. nsCOMPtr<nsIWidget> parentWidget; if (widgetData.mPopupLevel != ePopupLevelTop) { - nsCOMPtr<nsISupports> cont = PresContext()->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont); + nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell(); if (!dsti) return NS_ERROR_FAILURE; @@ -326,34 +337,52 @@ nsMenuPopupFrame::GetShadowStyle() return NS_STYLE_WINDOW_SHADOW_DEFAULT; } -// this class is used for dispatching popupshown events asynchronously. -class nsXULPopupShownEvent : public nsRunnable +NS_IMETHODIMP nsXULPopupShownEvent::Run() { -public: - nsXULPopupShownEvent(nsIContent *aPopup, nsPresContext* aPresContext) - : mPopup(aPopup), mPresContext(aPresContext) - { + nsMenuPopupFrame* popup = do_QueryFrame(mPopup->GetPrimaryFrame()); + // Set the state to visible if the popup is still open. + if (popup && popup->IsOpen()) { + popup->SetPopupState(ePopupShown); } - NS_IMETHOD Run() - { - nsMouseEvent event(true, NS_XUL_POPUP_SHOWN, nullptr, nsMouseEvent::eReal); - return nsEventDispatcher::Dispatch(mPopup, mPresContext, &event); + WidgetMouseEvent event(true, NS_XUL_POPUP_SHOWN, nullptr, + WidgetMouseEvent::eReal); + return EventDispatcher::Dispatch(mPopup, mPresContext, &event); +} + +NS_IMETHODIMP nsXULPopupShownEvent::HandleEvent(nsIDOMEvent* aEvent) +{ + nsMenuPopupFrame* popup = do_QueryFrame(mPopup->GetPrimaryFrame()); + if (popup) { + // ResetPopupShownDispatcher will delete the reference to this, so keep + // another one until Run is finished. + nsRefPtr<nsXULPopupShownEvent> event = this; + // Only call Run if it the dispatcher was assigned. This avoids calling the + // Run method if the transitionend event fires multiple times. + if (popup->ClearPopupShownDispatcher()) { + return Run(); + } } -private: - nsCOMPtr<nsIContent> mPopup; - nsRefPtr<nsPresContext> mPresContext; -}; + CancelListener(); + return NS_OK; +} -NS_IMETHODIMP +void nsXULPopupShownEvent::CancelListener() +{ + mPopup->RemoveSystemEventListener(NS_LITERAL_STRING("transitionend"), this, false); +} + +NS_IMPL_ISUPPORTS_INHERITED(nsXULPopupShownEvent, nsRunnable, nsIDOMEventListener); + +void nsMenuPopupFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { // unless the list is empty, indicate that children have been generated. if (aChildList.NotEmpty()) mGeneratedChildren = true; - return nsBoxFrame::SetInitialChildList(aListID, aChildList); + nsBoxFrame::SetInitialChildList(aListID, aChildList); } bool @@ -379,7 +408,8 @@ nsMenuPopupFrame::IsLeaf() const } void -nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, bool aSizedToPopup) +nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, + nsIFrame* aAnchor, bool aSizedToPopup) { if (!mGeneratedChildren) return; @@ -392,13 +422,15 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, b // if the popup is not open, only do layout while showing or if the menu // is sized to the popup shouldPosition = (mPopupState == ePopupShowing); - if (!shouldPosition && !aSizedToPopup) + if (!shouldPosition && !aSizedToPopup) { + RemoveStateBits(NS_FRAME_FIRST_REFLOW); return; + } } // if the popup has just been opened, make sure the scrolled window is at 0,0 if (mIsOpenChanged) { - nsIScrollableFrame *scrollframe = do_QueryFrame(GetChildBox()); + nsIScrollableFrame *scrollframe = do_QueryFrame(nsBox::GetChildBox(this)); if (scrollframe) { nsWeakFrame weakFrame(this); scrollframe->ScrollTo(nsPoint(0,0), nsIScrollableFrame::INSTANT); @@ -427,7 +459,7 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, b } if (shouldPosition) { - SetPopupPosition(aParentMenu, false); + SetPopupPosition(aAnchor, false, aSizedToPopup); } nsRect bounds(GetRect()); @@ -444,7 +476,7 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, b // so set the preferred size accordingly mPrefSize = newsize; if (isOpen) { - SetPopupPosition(nullptr, false); + SetPopupPosition(nullptr, false, aSizedToPopup); } } } @@ -466,14 +498,33 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, b rect.x = rect.y = 0; viewManager->ResizeView(view, rect); + if (mPopupState == ePopupOpening) { + mPopupState = ePopupVisible; + } + viewManager->SetViewVisibility(view, nsViewVisibility_kShow); - mPopupState = ePopupOpenAndVisible; nsContainerFrame::SyncFrameViewProperties(pc, this, nullptr, view, 0); } // finally, if the popup just opened, send a popupshown event if (mIsOpenChanged) { mIsOpenChanged = false; + +#ifndef MOZ_WIDGET_GTK + // If the animate attribute is set to open, check for a transition and wait + // for it to finish before firing the popupshown event. + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::animate, + nsGkAtoms::open, eCaseMatters) && + nsLayoutUtils::HasCurrentAnimations(mContent, + nsGkAtoms::transitionsProperty)) { + mPopupShownDispatcher = new nsXULPopupShownEvent(mContent, pc); + mContent->AddSystemEventListener(NS_LITERAL_STRING("transitionend"), + mPopupShownDispatcher, false, false); + return; + } +#endif + + // If there are no transitions, fire the popupshown event right away. nsCOMPtr<nsIRunnable> event = new nsXULPopupShownEvent(GetContent(), pc); NS_DispatchToCurrentThread(event); } @@ -581,8 +632,13 @@ nsMenuPopupFrame::InitializePopup(nsIContent* aAnchorContent, position.Assign(aPosition); } - mFlipBoth = flip.EqualsLiteral("both"); - mSlide = flip.EqualsLiteral("slide"); + if (flip.EqualsLiteral("none")) { + mFlip = FlipType_None; + } else if (flip.EqualsLiteral("both")) { + mFlip = FlipType_Both; + } else if (flip.EqualsLiteral("slide")) { + mFlip = FlipType_Slide; + } position.CompressWhitespace(); int32_t spaceIdx = position.FindChar(' '); @@ -685,8 +741,7 @@ nsMenuPopupFrame::InitializePopupAtScreen(nsIContent* aTriggerContent, mTriggerContent = aTriggerContent; mScreenXPos = aXPos; mScreenYPos = aYPos; - mFlipBoth = false; - mSlide = false; + mFlip = FlipType_Default; mPopupAnchor = POPUPALIGNMENT_NONE; mPopupAlignment = POPUPALIGNMENT_NONE; mIsContextMenu = aIsContextMenu; @@ -703,8 +758,7 @@ nsMenuPopupFrame::InitializePopupWithAnchorAlign(nsIContent* aAnchorContent, mPopupState = ePopupShowing; mAdjustOffsetForContextMenu = false; - mFlipBoth = false; - mSlide = false; + mFlip = FlipType_Default; // this popup opening function is provided for backwards compatibility // only. It accepts either coordinates or an anchor and alignment value @@ -736,7 +790,7 @@ nsMenuPopupFrame::ShowPopup(bool aIsContextMenu, bool aSelectFirstItem) InvalidateFrameSubtree(); if (mPopupState == ePopupShowing) { - mPopupState = ePopupOpen; + mPopupState = ePopupOpening; mIsOpenChanged = true; nsMenuFrame* menuFrame = do_QueryFrame(GetParent()); @@ -768,6 +822,8 @@ nsMenuPopupFrame::HidePopup(bool aDeselectMenu, nsPopupState aNewState) NS_ASSERTION(aNewState == ePopupClosed || aNewState == ePopupInvisible, "popup being set to unexpected state"); + ClearPopupShownDispatcher(); + // don't hide the popup when it isn't open if (mPopupState == ePopupClosed || mPopupState == ePopupShowing) return; @@ -825,10 +881,10 @@ nsMenuPopupFrame::HidePopup(bool aDeselectMenu, nsPopupState aNewState) // mouse_enter/mouse_exit event will be fired to clear current hover state, we should clear it manually. // This code may not the best solution, but we can leave it here until we find the better approach. NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?"); - nsEventStates state = mContent->AsElement()->State(); + EventStates state = mContent->AsElement()->State(); if (state.HasState(NS_EVENT_STATE_HOVER)) { - nsEventStateManager *esm = PresContext()->EventStateManager(); + EventStateManager* esm = PresContext()->EventStateManager(); esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); } @@ -859,12 +915,8 @@ nsMenuPopupFrame::GetRootViewForPopup(nsIFrame* aStartFrame) // window type of eWindowType_popup - in other words a popup window // widget. If we find one, this is the view we want. nsIWidget* widget = view->GetWidget(); - if (widget) { - nsWindowType wtype; - widget->GetWindowType(wtype); - if (wtype == eWindowType_popup) { - return view; - } + if (widget && widget->WindowType() == eWindowType_popup) { + return view; } nsView* temp = view->GetParent(); @@ -981,7 +1033,7 @@ nsMenuPopupFrame::AdjustPositionForAnchorAlign(nsRect& anchorRect, break; default: { - FlipStyle anchorEdge = mFlipBoth ? FlipStyle_Inside : FlipStyle_None; + FlipStyle anchorEdge = mFlip == FlipType_Both ? FlipStyle_Inside : FlipStyle_None; aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge; if (((popupAnchor > 0) == (popupAlign > 0)) || (popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT)) @@ -1002,13 +1054,10 @@ nsMenuPopupFrame::SlideOrResize(nscoord& aScreenPoint, nscoord aSize, { // The popup may be positioned such that either the left/top or bottom/right // is outside the screen - but never both. - if (aScreenPoint < aScreenBegin) { - *aOffset = aScreenBegin - aScreenPoint; - aScreenPoint = aScreenBegin; - } else if (aScreenPoint + aSize > aScreenEnd) { - *aOffset = aScreenPoint + aSize - aScreenEnd; - aScreenPoint = std::max(aScreenEnd - aSize, 0); - } + nscoord newPos = + std::max(aScreenBegin, std::min(aScreenEnd - aSize, aScreenPoint)); + *aOffset = newPos - aScreenPoint; + aScreenPoint = newPos; return std::min(aSize, aScreenEnd - aScreenPoint); } @@ -1120,7 +1169,7 @@ nsMenuPopupFrame::FlipOrResize(nscoord& aScreenPoint, nscoord aSize, } nsresult -nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) +nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aSizedToPopup) { if (!mShouldAutoPosition) return NS_OK; @@ -1152,21 +1201,29 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) } } - bool sizedToPopup = false; - if (aAnchorFrame->GetContent()) { - // the popup should be the same size as the anchor menu, for example, a menulist. - sizedToPopup = nsMenuFrame::IsSizedToPopup(aAnchorFrame->GetContent(), false); + // In order to deal with transforms, we need the root prescontext: + nsPresContext* rootPresContext = presContext->GetRootPresContext(); + + // If we can't reach a root pres context, don't bother continuing: + if (!rootPresContext) { + return NS_OK; } - // the dimensions of the anchor in its app units - nsRect parentRect = aAnchorFrame->GetScreenRectInAppUnits(); + // And then we need its root frame for a reference + nsIFrame* referenceFrame = rootPresContext->FrameManager()->GetRootFrame(); - // the anchor may be in a different document with a different scale, - // so adjust the size so that it is in the app units of the popup instead - // of the anchor. - parentRect = parentRect.ConvertAppUnitsRoundOut( - aAnchorFrame->PresContext()->AppUnitsPerDevPixel(), - presContext->AppUnitsPerDevPixel()); + // the dimensions of the anchor + nsRect parentRect = aAnchorFrame->GetRectRelativeToSelf(); + // Relative to the root + parentRect = nsLayoutUtils::TransformFrameRectToAncestor(aAnchorFrame, + parentRect, + referenceFrame); + // Relative to the screen + parentRect.MoveBy(referenceFrame->GetScreenRectInAppUnits().TopLeft()); + // In its own app units + parentRect = + parentRect.ConvertAppUnitsRoundOut(rootPresContext->AppUnitsPerDevPixel(), + presContext->AppUnitsPerDevPixel()); // Set the popup's size to the preferred size. Below, this size will be // adjusted to fit on the screen or within the content area. If the anchor @@ -1174,7 +1231,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) // width. The preferred size should already be set by the parent frame. NS_ASSERTION(mPrefSize.width >= 0 || mPrefSize.height >= 0, "preferred size of popup not set"); - mRect.width = sizedToPopup ? parentRect.width : mPrefSize.width; + mRect.width = aSizedToPopup ? parentRect.width : mPrefSize.width; mRect.height = mPrefSize.height; // the screen position in app units where the popup should appear @@ -1196,6 +1253,9 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) nsDeviceContext* devContext = presContext->DeviceContext(); nscoord offsetForContextMenu = 0; + bool isNoAutoHide = IsNoAutoHide(); + nsPopupLevel popupLevel = PopupLevel(isNoAutoHide); + if (IsAnchored()) { // if we are anchored, there are certain things we don't want to do when // repositioning the popup to fit on the screen, such as end up positioned @@ -1236,7 +1296,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) // the window is moved. Popups at the parent level follow the parent // window as it is moved and remained anchored, so we want to maintain the // anchoring instead. - if (IsNoAutoHide() && PopupLevel(true) != ePopupLevelParent) { + if (isNoAutoHide && popupLevel != ePopupLevelParent) { // Account for the margin that will end up being added to the screen coordinate // the next time SetPopupPosition is called. mScreenXPos = presContext->AppUnitsToIntCSSPixels(screenPoint.x - margin.left); @@ -1246,9 +1306,9 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) else { // the popup is positioned at a screen coordinate. // first convert the screen position in mScreenXPos and mScreenYPos from - // CSS pixels into device pixels, ignoring any scaling as mScreenXPos and - // mScreenYPos are unscaled screen coordinates. - int32_t factor = devContext->UnscaledAppUnitsPerDevPixel(); + // CSS pixels into device pixels, ignoring any zoom as mScreenXPos and + // mScreenYPos are unzoomed screen coordinates. + int32_t factor = devContext->AppUnitsPerDevPixelAtUnitFullZoom(); // context menus should be offset by two pixels so that they don't appear // directly where the cursor is. Otherwise, it is too easy to have the @@ -1259,7 +1319,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) offsetForContextMenu = presContext->DevPixelsToAppUnits(offsetForContextMenuDev); } - // next, convert into app units accounting for the scaling + // next, convert into app units accounting for the zoom screenPoint.x = presContext->DevPixelsToAppUnits( nsPresContext::CSSPixelsToAppUnits(mScreenXPos) / factor); screenPoint.y = presContext->DevPixelsToAppUnits( @@ -1274,24 +1334,13 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) vFlip = FlipStyle_Outside; } - // If a panel is being moved, don't constrain or flip it. But always do this for + // If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for // content shells, so that the popup doesn't extend outside the containing frame. - if (mInContentShell || !aIsMove || mPopupType != ePopupTypePanel) { - nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect); - - // ensure that anchorRect is on screen - if (!anchorRect.IntersectRect(anchorRect, screenRect)) { - anchorRect.width = anchorRect.height = 0; - // if the anchor isn't within the screen, move it to the edge of the screen. - if (anchorRect.x < screenRect.x) - anchorRect.x = screenRect.x; - if (anchorRect.XMost() > screenRect.XMost()) - anchorRect.x = screenRect.XMost(); - if (anchorRect.y < screenRect.y) - anchorRect.y = screenRect.y; - if (anchorRect.YMost() > screenRect.YMost()) - anchorRect.y = screenRect.YMost(); - } + if (mInContentShell || (mFlip != FlipType_None && (!aIsMove || mPopupType != ePopupTypePanel))) { + nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect, popupLevel); + + // Ensure that anchorRect is on screen. + anchorRect = anchorRect.Intersect(screenRect); // shrink the the popup down if it is larger than the screen size if (mRect.width > screenRect.width) @@ -1305,8 +1354,14 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) // We might want to "slide" an arrow if the panel is of the correct type - // but we can only slide on one axis - the other axis must be "flipped or // resized" as normal. - bool slideHorizontal = mSlide && mPosition <= POPUPPOSITION_AFTEREND; - bool slideVertical = mSlide && mPosition >= POPUPPOSITION_STARTBEFORE; + bool slideHorizontal = false, slideVertical = false; + if (mFlip == FlipType_Slide) { + int8_t position = GetAlignmentPosition(); + slideHorizontal = position >= POPUPPOSITION_BEFORESTART && + position <= POPUPPOSITION_AFTEREND; + slideVertical = position >= POPUPPOSITION_STARTBEFORE && + position <= POPUPPOSITION_ENDAFTER; + } // Next, check if there is enough space to show the popup at full size when // positioned at screenPoint. If not, flip the popups to the opposite side @@ -1336,14 +1391,15 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) "Popup is offscreen"); } + // snap the popup's position in screen coordinates to device pixels, + // see bug 622507, bug 961431 + screenPoint.x = presContext->RoundAppUnitsToNearestDevPixels(screenPoint.x); + screenPoint.y = presContext->RoundAppUnitsToNearestDevPixels(screenPoint.y); + // determine the x and y position of the view by subtracting the desired // screen position from the screen position of the root frame. nsPoint viewPoint = screenPoint - rootScreenRect.TopLeft(); - // snap the view's position to device pixels, see bug 622507 - viewPoint.x = presContext->RoundAppUnitsToNearestDevPixels(viewPoint.x); - viewPoint.y = presContext->RoundAppUnitsToNearestDevPixels(viewPoint.y); - nsView* view = GetView(); NS_ASSERTION(view, "popup with no view"); @@ -1364,7 +1420,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove) // Now that we've positioned the view, sync up the frame's origin. nsBoxFrame::SetPosition(viewPoint - GetParent()->GetOffsetTo(rootFrame)); - if (sizedToPopup) { + if (aSizedToPopup) { nsBoxLayoutState state(PresContext()); // XXXndeakin can parentSize.width still extend outside? SetBounds(state, nsRect(mRect.x, mRect.y, parentRect.width, mRect.height)); @@ -1381,7 +1437,8 @@ nsMenuPopupFrame::GetCurrentMenuItem() nsRect nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, - const nsRect& aRootScreenRect) + const nsRect& aRootScreenRect, + nsPopupLevel aPopupLevel) { nsIntRect screenRectPixels; nsPresContext* presContext = PresContext(); @@ -1404,8 +1461,11 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, nsPresContext::AppUnitsToIntCSSPixels(rect.y), width, height, getter_AddRefs(screen)); if (screen) { + // Non-top-level popups (which will always be panels) + // should never overlap the OS bar: + bool dontOverlapOSBar = aPopupLevel != ePopupLevelTop; // get the total screen area if the popup is allowed to overlap it. - if (mMenuCanOverlapOSBar && !mInContentShell) + if (!dontOverlapOSBar && mMenuCanOverlapOSBar && !mInContentShell) screen->GetRect(&screenRectPixels.x, &screenRectPixels.y, &screenRectPixels.width, &screenRectPixels.height); else @@ -1414,9 +1474,6 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, } } - // keep a 3 pixel margin to the right and bottom of the screen for the WinXP dropshadow - screenRectPixels.SizeTo(screenRectPixels.width - 3, screenRectPixels.height - 3); - nsRect screenRect = screenRectPixels.ToAppUnits(presContext->AppUnitsPerDevPixel()); if (mInContentShell) { // for content shells, clip to the client area rather than the screen area @@ -1426,7 +1483,9 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, return screenRect; } -void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide, int8_t aVerticalSide, nsIntPoint& aChange) +void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide, + int8_t aVerticalSide, + LayoutDeviceIntPoint& aChange) { int8_t popupAlign(mPopupAlignment); if (IsDirectionRTL()) { @@ -1456,24 +1515,33 @@ void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide, int8_t aVerticalSi } } -bool nsMenuPopupFrame::ConsumeOutsideClicks() +ConsumeOutsideClicksResult nsMenuPopupFrame::ConsumeOutsideClicks() { // If the popup has explicitly set a consume mode, honor that. - if (mConsumeRollupEvent != nsIPopupBoxObject::ROLLUP_DEFAULT) - return (mConsumeRollupEvent == nsIPopupBoxObject::ROLLUP_CONSUME); + if (mConsumeRollupEvent != PopupBoxObject::ROLLUP_DEFAULT) { + return (mConsumeRollupEvent == PopupBoxObject::ROLLUP_CONSUME) ? + ConsumeOutsideClicks_True : ConsumeOutsideClicks_ParentOnly; + } if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::consumeoutsideclicks, - nsGkAtoms::_true, eCaseMatters)) - return true; + nsGkAtoms::_true, eCaseMatters)) { + return ConsumeOutsideClicks_True; + } if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::consumeoutsideclicks, - nsGkAtoms::_false, eCaseMatters)) - return false; + nsGkAtoms::_false, eCaseMatters)) { + return ConsumeOutsideClicks_ParentOnly; + } + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::consumeoutsideclicks, + nsGkAtoms::never, eCaseMatters)) { + return ConsumeOutsideClicks_Never; + } nsCOMPtr<nsIContent> parentContent = mContent->GetParent(); if (parentContent) { - nsINodeInfo *ni = parentContent->NodeInfo(); - if (ni->Equals(nsGkAtoms::menulist, kNameSpaceID_XUL)) - return true; // Consume outside clicks for combo boxes on all platforms + dom::NodeInfo *ni = parentContent->NodeInfo(); + if (ni->Equals(nsGkAtoms::menulist, kNameSpaceID_XUL)) { + return ConsumeOutsideClicks_True; // Consume outside clicks for combo boxes on all platforms + } #if defined(XP_WIN) // Don't consume outside clicks for menus in Windows if (ni->Equals(nsGkAtoms::menu, kNameSpaceID_XUL) || @@ -1485,18 +1553,19 @@ bool nsMenuPopupFrame::ConsumeOutsideClicks() nsGkAtoms::menu, eCaseMatters) || parentContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, nsGkAtoms::menuButton, eCaseMatters)))) { - return false; + return ConsumeOutsideClicks_Never; } #endif if (ni->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL)) { // Don't consume outside clicks for autocomplete widget if (parentContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, - nsGkAtoms::autocomplete, eCaseMatters)) - return false; + nsGkAtoms::autocomplete, eCaseMatters)) { + return ConsumeOutsideClicks_Never; + } } } - return true; + return ConsumeOutsideClicks_True; } // XXXroc this is megalame. Fossicking around for a frame of the right @@ -1603,7 +1672,7 @@ nsMenuPopupFrame::ChangeMenuItem(nsMenuFrame* aMenuItem, } nsMenuFrame* -nsMenuPopupFrame::Enter(nsGUIEvent* aEvent) +nsMenuPopupFrame::Enter(WidgetGUIEvent* aEvent) { mIncrementalString.Truncate(); @@ -1624,9 +1693,9 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction doAction = false; // Enumerate over our list of frames. - nsIFrame* immediateParent = nullptr; - PresContext()->PresShell()-> - FrameConstructor()->GetInsertionPoint(this, nullptr, &immediateParent); + auto insertion = PresContext()->PresShell()-> + FrameConstructor()->GetInsertionPoint(GetContent(), nullptr); + nsContainerFrame* immediateParent = insertion.mParentFrame; if (!immediateParent) immediateParent = this; @@ -1647,7 +1716,7 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction aKeyEvent->GetTimeStamp(&keyTime); if (charCode == 0) { - if (keyCode == NS_VK_BACK) { + if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) { if (!isMenu && !mIncrementalString.IsEmpty()) { mIncrementalString.SetLength(mIncrementalString.Length() - 1); return nullptr; @@ -1663,11 +1732,15 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction return nullptr; } else { - PRUnichar uniChar = ToLowerCase(static_cast<PRUnichar>(charCode)); - if (isMenu || // Menu supports only first-letter navigation - keyTime - lastKeyTime > INC_TYP_INTERVAL) // Interval too long, treat as new typing + char16_t uniChar = ToLowerCase(static_cast<char16_t>(charCode)); + if (isMenu) { + // Menu supports only first-letter navigation mIncrementalString = uniChar; - else { + } else if (sTimeoutOfIncrementalSearch && + keyTime - lastKeyTime > sTimeoutOfIncrementalSearch) { + // Interval too long, treat as new typing + mIncrementalString = uniChar; + } else { mIncrementalString.Append(uniChar); } } @@ -1685,13 +1758,13 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction lastKeyTime = keyTime; - nsIFrame* currFrame; // NOTE: If you crashed here due to a bogus |immediateParent| it is // possible that the menu whose shortcut is being looked up has // been destroyed already. One strategy would be to // setTimeout(<func>,0) as detailed in: // <http://bugzilla.mozilla.org/show_bug.cgi?id=126675#c32> - currFrame = immediateParent->GetFirstPrincipalChild(); + nsIFrame* firstMenuItem = nsXULPopupManager::GetNextMenuItem(immediateParent, nullptr, true); + nsIFrame* currFrame = firstMenuItem; int32_t menuAccessKey = -1; nsMenuBarListener::GetMenuAccessKey(&menuAccessKey); @@ -1700,64 +1773,64 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction // -- before current and after current -- by the current item while (currFrame) { nsIContent* current = currFrame->GetContent(); - - // See if it's a menu item. - if (nsXULPopupManager::IsValidMenuItem(PresContext(), current, true)) { - nsAutoString textKey; - if (menuAccessKey >= 0) { - // Get the shortcut attribute. - current->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, textKey); - } - if (textKey.IsEmpty()) { // No shortcut, try first letter - isShortcut = false; - current->GetAttr(kNameSpaceID_None, nsGkAtoms::label, textKey); - if (textKey.IsEmpty()) // No label, try another attribute (value) - current->GetAttr(kNameSpaceID_None, nsGkAtoms::value, textKey); - } - else - isShortcut = true; - - if (StringBeginsWith(textKey, incrementalString, - nsCaseInsensitiveStringComparator())) { - // mIncrementalString is a prefix of textKey - nsMenuFrame* menu = do_QueryFrame(currFrame); - if (menu) { - // There is one match - matchCount++; - if (isShortcut) { - // There is one shortcut-key match - matchShortcutCount++; - // Record the matched item. If there is only one matched shortcut item, do it - frameShortcut = menu; - } - if (!foundActive) { - // It's a first candidate item located before/on the current item - if (!frameBefore) - frameBefore = menu; - } - else { - // It's a first candidate item located after the current item - if (!frameAfter) - frameAfter = menu; - } + nsAutoString textKey; + if (menuAccessKey >= 0) { + // Get the shortcut attribute. + current->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, textKey); + } + if (textKey.IsEmpty()) { // No shortcut, try first letter + isShortcut = false; + current->GetAttr(kNameSpaceID_None, nsGkAtoms::label, textKey); + if (textKey.IsEmpty()) // No label, try another attribute (value) + current->GetAttr(kNameSpaceID_None, nsGkAtoms::value, textKey); + } + else + isShortcut = true; + + if (StringBeginsWith(textKey, incrementalString, + nsCaseInsensitiveStringComparator())) { + // mIncrementalString is a prefix of textKey + nsMenuFrame* menu = do_QueryFrame(currFrame); + if (menu) { + // There is one match + matchCount++; + if (isShortcut) { + // There is one shortcut-key match + matchShortcutCount++; + // Record the matched item. If there is only one matched shortcut item, do it + frameShortcut = menu; + } + if (!foundActive) { + // It's a first candidate item located before/on the current item + if (!frameBefore) + frameBefore = menu; + } + else { + // It's a first candidate item located after the current item + if (!frameAfter) + frameAfter = menu; } - else - return nullptr; } + else + return nullptr; + } - // Get the active status - if (current->AttrValueIs(kNameSpaceID_None, nsGkAtoms::menuactive, - nsGkAtoms::_true, eCaseMatters)) { - foundActive = true; - if (stringLength > 1) { - // If there is more than one char typed, the current item has highest priority, - // otherwise the item next to current has highest priority - if (currFrame == frameBefore) - return frameBefore; - } + // Get the active status + if (current->AttrValueIs(kNameSpaceID_None, nsGkAtoms::menuactive, + nsGkAtoms::_true, eCaseMatters)) { + foundActive = true; + if (stringLength > 1) { + // If there is more than one char typed, the current item has highest priority, + // otherwise the item next to current has highest priority + if (currFrame == frameBefore) + return frameBefore; } } - currFrame = currFrame->GetNextSibling(); + + nsMenuFrame* menu = do_QueryFrame(currFrame); + currFrame = nsXULPopupManager::GetNextMenuItem(immediateParent, menu, true); + if (currFrame == firstMenuItem) + break; } doAction = (isMenu && (matchCount == 1 || matchShortcutCount == 1)); @@ -1814,25 +1887,12 @@ nsMenuPopupFrame::GetWidget() void nsMenuPopupFrame::AttachedDismissalListener() { - mConsumeRollupEvent = nsIPopupBoxObject::ROLLUP_DEFAULT; -} - -void -nsMenuPopupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) -{ - // don't pass events to drag popups - if (aBuilder->IsForEventDelivery() && mIsDragPopup) { - return; - } - - nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + mConsumeRollupEvent = PopupBoxObject::ROLLUP_DEFAULT; } // helpers ///////////////////////////////////////////////////////////// -NS_IMETHODIMP +nsresult nsMenuPopupFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -1868,7 +1928,7 @@ nsMenuPopupFrame::MoveToAttributePosition() // Move the widget around when the user sets the |left| and |top| attributes. // Note that this is not the best way to move the widget, as it results in lots // of FE notifications and is likely to be slow as molasses. Use |moveTo| on - // nsIPopupBoxObject if possible. + // PopupBoxObject if possible. nsAutoString left, top; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::left, left); mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::top, top); @@ -1890,6 +1950,8 @@ nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot) new nsUnsetAttrRunnable(menu->GetContent(), nsGkAtoms::open)); } + ClearPopupShownDispatcher(); + nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) pm->PopupDestroyed(this); @@ -1932,7 +1994,7 @@ nsMenuPopupFrame::MoveTo(int32_t aLeft, int32_t aTop, bool aUpdateAttrs) mScreenXPos = aLeft - presContext->AppUnitsToIntCSSPixels(margin.left); mScreenYPos = aTop - presContext->AppUnitsToIntCSSPixels(margin.top); - SetPopupPosition(nullptr, true); + SetPopupPosition(nullptr, true, false); nsCOMPtr<nsIContent> popup = mContent; if (aUpdateAttrs && (popup->HasAttr(kNameSpaceID_None, nsGkAtoms::left) || @@ -1952,15 +2014,16 @@ nsMenuPopupFrame::MoveToAnchor(nsIContent* aAnchorContent, int32_t aXPos, int32_t aYPos, bool aAttributesOverride) { - NS_ASSERTION(mPopupState == ePopupOpenAndVisible, "popup must be open to move it"); + NS_ASSERTION(IsVisible(), "popup must be visible to move it"); + nsPopupState oldstate = mPopupState; InitializePopup(aAnchorContent, mTriggerContent, aPosition, aXPos, aYPos, aAttributesOverride); // InitializePopup changed the state so reset it. - mPopupState = ePopupOpenAndVisible; + mPopupState = oldstate; // Pass false here so that flipping and adjusting to fit on the screen happen. - SetPopupPosition(nullptr, false); + SetPopupPosition(nullptr, false, false); } bool diff --git a/layout/xul/base/src/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h index 22e49d8b3..338a867db 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.h +++ b/layout/xul/nsMenuPopupFrame.h @@ -27,10 +27,15 @@ class nsIWidget; // state changes as follows: // ePopupClosed - initial state // ePopupShowing - during the period when the popupshowing event fires -// ePopupOpen - between the popupshowing event and being visible. Creation -// of the child frames, layout and reflow occurs in this state. -// ePopupOpenAndVisible - layout is done and the popup's view and widget are -// made visible. The popupshown event fires. +// ePopupOpening - between the popupshowing event and being visible. Creation +// of the child frames, layout and reflow occurs in this +// state. The popup is stored in the popup manager's list of +// open popups during this state. +// ePopupVisible - layout is done and the popup's view and widget are made +// visible. The popup is visible on screen but may be +// transitioning. The popupshown event has not yet fired. +// ePopupShown - the popup has been shown and is fully ready. This state is +// assigned just before the popupshown event fires. // When closing a popup: // ePopupHidden - during the period when the popuphiding event fires and // the popup is removed. @@ -42,9 +47,11 @@ enum nsPopupState { // popupshowing event has been fired. ePopupShowing, // state while a popup is open but the widget is not yet visible - ePopupOpen, + ePopupOpening, + // state while a popup is visible and waiting for the popupshown event + ePopupVisible, // state while a popup is open and visible on screen - ePopupOpenAndVisible, + ePopupShown, // state from when a popup is requested to be hidden to when it is closed. ePopupHiding, // state which indicates that the popup was hidden without firing the @@ -56,6 +63,12 @@ enum nsPopupState { ePopupInvisible }; +enum ConsumeOutsideClicksResult { + ConsumeOutsideClicks_ParentOnly = 0, // Only consume clicks on the parent anchor + ConsumeOutsideClicks_True = 1, // Always consume clicks + ConsumeOutsideClicks_Never = 2 // Never consume clicks +}; + // How a popup may be flipped. Flipping to the outside edge is like how // a submenu would work. The entire popup is flipped to the opposite side // of the anchor. @@ -65,6 +78,14 @@ enum FlipStyle { FlipStyle_Inside = 2 }; +// Values for the flip attribute +enum FlipType { + FlipType_Default = 0, + FlipType_None = 1, // don't try to flip or translate to stay onscreen + FlipType_Both = 2, // flip in both directions + FlipType_Slide = 3 // allow the arrow to "slide" instead of resizing +}; + // values are selected so that the direction can be flipped just by // changing the sign #define POPUPALIGNMENT_NONE 0 @@ -95,8 +116,6 @@ enum FlipStyle { #define POPUPPOSITION_HFLIP(v) (v ^ 1) #define POPUPPOSITION_VFLIP(v) (v ^ 2) -#define INC_TYP_INTERVAL 1000 // 1s. If the interval between two keypresses is shorter than this, - // treat as a continue typing // XXX, kyle.yuan@sun.com, there are 4 definitions for the same purpose: // nsMenuPopupFrame.h, nsListControlFrame.cpp, listbox.xml, tree.xml // need to find a good place to put them together. @@ -110,29 +129,52 @@ class nsViewManager; class nsView; class nsMenuPopupFrame; -class nsMenuPopupFrame : public nsBoxFrame, public nsMenuParent +// this class is used for dispatching popupshown events asynchronously. +class nsXULPopupShownEvent : public nsRunnable, public nsIDOMEventListener +{ +public: + nsXULPopupShownEvent(nsIContent *aPopup, nsPresContext* aPresContext) + : mPopup(aPopup), mPresContext(aPresContext) + { + } + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIRUNNABLE + NS_DECL_NSIDOMEVENTLISTENER + + void CancelListener(); + +protected: + virtual ~nsXULPopupShownEvent() { } + +private: + nsCOMPtr<nsIContent> mPopup; + nsRefPtr<nsPresContext> mPresContext; +}; + +class nsMenuPopupFrame final : public nsBoxFrame, public nsMenuParent { public: NS_DECL_QUERYFRAME_TARGET(nsMenuPopupFrame) NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsMenuPopupFrame(nsStyleContext* aContext); // nsMenuParent interface - virtual nsMenuFrame* GetCurrentMenuItem() MOZ_OVERRIDE; - NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) MOZ_OVERRIDE; - virtual void CurrentMenuIsBeingDestroyed() MOZ_OVERRIDE; - NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) MOZ_OVERRIDE; + virtual nsMenuFrame* GetCurrentMenuItem() override; + NS_IMETHOD SetCurrentMenuItem(nsMenuFrame* aMenuItem) override; + virtual void CurrentMenuIsBeingDestroyed() override; + NS_IMETHOD ChangeMenuItem(nsMenuFrame* aMenuItem, bool aSelectFirstItem) override; // as popups are opened asynchronously, the popup pending state is used to // prevent multiple requests from attempting to open the same popup twice nsPopupState PopupState() { return mPopupState; } void SetPopupState(nsPopupState aPopupState) { mPopupState = aPopupState; } - NS_IMETHOD SetActive(bool aActiveFlag) MOZ_OVERRIDE { return NS_OK; } // We don't care. - virtual bool IsActive() MOZ_OVERRIDE { return false; } - virtual bool IsMenuBar() MOZ_OVERRIDE { return false; } + NS_IMETHOD SetActive(bool aActiveFlag) override { return NS_OK; } // We don't care. + virtual bool IsActive() override { return false; } + virtual bool IsMenuBar() override { return false; } /* * When this popup is open, should clicks outside of it be consumed? @@ -150,14 +192,14 @@ public: * Unix Eat No Eat * */ - bool ConsumeOutsideClicks(); + ConsumeOutsideClicksResult ConsumeOutsideClicks(); - virtual bool IsContextMenu() MOZ_OVERRIDE { return mIsContextMenu; } + virtual bool IsContextMenu() override { return mIsContextMenu; } - virtual bool MenuClosed() MOZ_OVERRIDE { return true; } + virtual bool MenuClosed() override { return true; } - virtual void LockMenuUntilClosed(bool aLock) MOZ_OVERRIDE; - virtual bool IsMenuLocked() MOZ_OVERRIDE { return mIsMenuLocked; } + virtual void LockMenuUntilClosed(bool aLock) override; + virtual bool IsMenuLocked() override { return mIsMenuLocked; } nsIWidget* GetWidget(); @@ -165,15 +207,15 @@ public: void AttachedDismissalListener(); // Overridden methods - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; // returns true if the popup is a panel with the noautohide attribute set to // true. These panels do not roll up automatically. @@ -189,13 +231,14 @@ public: nsresult CreateWidgetForView(nsView* aView); uint8_t GetShadowStyle(); - NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) MOZ_OVERRIDE; + virtual void SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) override; - virtual bool IsLeaf() const MOZ_OVERRIDE; + virtual bool IsLeaf() const override; // layout, position and display the popup as needed - void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, bool aSizedToPopup); + void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, + nsIFrame* aAnchor, bool aSizedToPopup); nsView* GetRootViewForPopup(nsIFrame* aStartFrame); @@ -204,7 +247,7 @@ public: // point if a screen position (mScreenXPos and mScreenYPos) are set. The popup // will be adjusted so that it is on screen. If aIsMove is true, then the popup // is being moved, and should not be flipped. - nsresult SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove); + nsresult SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aSizedToPopup); bool HasGeneratedChildren() { return mGeneratedChildren; } void SetGeneratedChildren() { mGeneratedChildren = true; } @@ -215,13 +258,17 @@ public: // that menu, or null if no menu should be opened. Also, calling Enter will // reset the current incremental search string, calculated in // FindMenuWithShortcut. - nsMenuFrame* Enter(nsGUIEvent* aEvent); + nsMenuFrame* Enter(mozilla::WidgetGUIEvent* aEvent); nsPopupType PopupType() const { return mPopupType; } - bool IsMenu() MOZ_OVERRIDE { return mPopupType == ePopupTypeMenu; } - bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; } + bool IsMenu() override { return mPopupType == ePopupTypeMenu; } + bool IsOpen() override { return mPopupState == ePopupOpening || + mPopupState == ePopupVisible || + mPopupState == ePopupShown; } + bool IsVisible() { return mPopupState == ePopupVisible || + mPopupState == ePopupShown; } - bool IsDragPopup() { return mIsDragPopup; } + bool IsMouseTransparent() { return mMouseTransparent; } static nsIContent* GetTriggerContent(nsMenuPopupFrame* aMenuPopupFrame); void ClearTriggerContent() { mTriggerContent = nullptr; } @@ -268,10 +315,10 @@ public: void ClearIncrementalString() { mIncrementalString.Truncate(); } - virtual nsIAtom* GetType() const MOZ_OVERRIDE { return nsGkAtoms::menuPopupFrame; } + virtual nsIAtom* GetType() const override { return nsGkAtoms::menuPopupFrame; } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("MenuPopup"), aResult); } @@ -301,7 +348,11 @@ public: // area of the screen the popup should be displayed on. Content popups, // however, will also be constrained by the content area, given by // aRootScreenRect. All coordinates are in app units. - nsRect GetConstraintRect(const nsRect& aAnchorRect, const nsRect& aRootScreenRect); + // For non-toplevel popups (which will always be panels), we will also + // constrain them to the available screen rect, ie they will not fall + // underneath the taskbar, dock or other fixed OS elements. + nsRect GetConstraintRect(const nsRect& aAnchorRect, const nsRect& aRootScreenRect, + nsPopupLevel aPopupLevel); // Determines whether the given edges of the popup may be moved, where // aHorizontalSide and aVerticalSide are one of the NS_SIDE_* constants, or @@ -313,7 +364,9 @@ public: // Later, when bug 357725 is implemented, we can make this adjust aChange by // the amount that the side can be resized, so that minimums and maximums // can be taken into account. - void CanAdjustEdges(int8_t aHorizontalSide, int8_t aVerticalSide, nsIntPoint& aChange); + void CanAdjustEdges(int8_t aHorizontalSide, + int8_t aVerticalSide, + mozilla::LayoutDeviceIntPoint& aChange); // Return true if the popup is positioned relative to an anchor. bool IsAnchored() const { return mScreenXPos == -1 && mScreenYPos == -1; } @@ -325,10 +378,6 @@ public: // This position is in CSS pixels. nsIntPoint ScreenPosition() const { return nsIntPoint(mScreenXPos, mScreenYPos); } - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; - nsIntPoint GetLastClientOffset() const { return mLastClientOffset; } // Return the alignment of the popup @@ -336,13 +385,27 @@ public: // Return the offset applied to the alignment of the popup nscoord GetAlignmentOffset() const { return mAlignmentOffset; } + + // Clear the mPopupShownDispatcher, remove the listener and return true if + // mPopupShownDispatcher was non-null. + bool ClearPopupShownDispatcher() + { + if (mPopupShownDispatcher) { + mPopupShownDispatcher->CancelListener(); + mPopupShownDispatcher = nullptr; + return true; + } + + return false; + } + protected: // returns the popup's level. nsPopupLevel PopupLevel(bool aIsNoAutoHide) const; // redefine to tell the box system not to move the views. - virtual void GetLayoutFlags(uint32_t& aFlags) MOZ_OVERRIDE; + virtual void GetLayoutFlags(uint32_t& aFlags) override; void InitPositionFromAnchorAlign(const nsAString& aAnchor, const nsAString& aAlign); @@ -425,6 +488,8 @@ protected: nsMenuFrame* mCurrentMenu; // The current menu that is active. + nsRefPtr<nsXULPopupShownEvent> mPopupShownDispatcher; + // A popup's preferred size may be different than its actual size stored in // mRect in the case where the popup was resized because it was too large // for the screen. The preferred size mPrefSize holds the full size the popup @@ -457,10 +522,9 @@ protected: int8_t mPopupAnchor; int8_t mPosition; - // One of nsIPopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME - int8_t mConsumeRollupEvent; - bool mFlipBoth; // flip in both directions - bool mSlide; // allow the arrow to "slide" instead of resizing + // One of PopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME + uint8_t mConsumeRollupEvent; + FlipType mFlip; // Whether to flip bool mIsOpenChanged; // true if the open state changed since the last layout bool mIsContextMenu; // true for context menus @@ -472,13 +536,16 @@ protected: bool mShouldAutoPosition; // Should SetPopupPosition be allowed to auto position popup? bool mInContentShell; // True if the popup is in a content shell bool mIsMenuLocked; // Should events inside this menu be ignored? - bool mIsDragPopup; // True if this is a popup used for drag feedback + bool mMouseTransparent; // True if this is a popup is transparent to mouse events // the flip modes that were used when the popup was opened bool mHFlip; bool mVFlip; static int8_t sDefaultLevelIsTop; + + // If 0, never timed out. Otherwise, the value is in milliseconds. + static uint32_t sTimeoutOfIncrementalSearch; }; // class nsMenuPopupFrame #endif diff --git a/layout/xul/base/public/nsPIBoxObject.h b/layout/xul/nsPIBoxObject.h index 94f0b71ce..46ec6ea38 100644 --- a/layout/xul/base/public/nsPIBoxObject.h +++ b/layout/xul/nsPIBoxObject.h @@ -6,6 +6,8 @@ #ifndef nsPIBoxObject_h___ #define nsPIBoxObject_h___ +#include "nsIBoxObject.h" + // {2b8bb262-1b0f-4572-ba87-5d4ae4954445} #define NS_PIBOXOBJECT_IID \ { 0x2b8bb262, 0x1b0f, 0x4572, \ diff --git a/layout/xul/base/src/nsPIListBoxObject.h b/layout/xul/nsPIListBoxObject.h index c7b9928f0..c7b9928f0 100644 --- a/layout/xul/base/src/nsPIListBoxObject.h +++ b/layout/xul/nsPIListBoxObject.h diff --git a/layout/xul/base/src/nsPopupSetFrame.cpp b/layout/xul/nsPopupSetFrame.cpp index f20d1e6d5..f1d243aa5 100644 --- a/layout/xul/base/src/nsPopupSetFrame.cpp +++ b/layout/xul/nsPopupSetFrame.cpp @@ -17,15 +17,15 @@ nsIFrame* NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsPopupSetFrame (aPresShell, aContext); + return new (aPresShell) nsPopupSetFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame) void -nsPopupSetFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsPopupSetFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); @@ -43,54 +43,67 @@ nsPopupSetFrame::GetType() const return nsGkAtoms::popupSetFrame; } -NS_IMETHODIMP +void nsPopupSetFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { if (aListID == kPopupList) { AddPopupFrameList(aFrameList); - return NS_OK; + return; } - return nsBoxFrame::AppendFrames(aListID, aFrameList); + nsBoxFrame::AppendFrames(aListID, aFrameList); } -NS_IMETHODIMP +void nsPopupSetFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { if (aListID == kPopupList) { RemovePopupFrame(aOldFrame); - return NS_OK; + return; } - return nsBoxFrame::RemoveFrame(aListID, aOldFrame); + nsBoxFrame::RemoveFrame(aListID, aOldFrame); } -NS_IMETHODIMP +void nsPopupSetFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) { if (aListID == kPopupList) { AddPopupFrameList(aFrameList); - return NS_OK; + return; } - return nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); + nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); } -NS_IMETHODIMP +void nsPopupSetFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { if (aListID == kPopupList) { - // XXXmats this asserts because we don't implement - // GetChildList(kPopupList) so nsCSSFrameConstructor - // believes it's empty and calls us multiple times. - //NS_ASSERTION(mPopupList.IsEmpty(), - // "SetInitialChildList on non-empty child list"); + NS_ASSERTION(mPopupList.IsEmpty(), + "SetInitialChildList on non-empty child list"); AddPopupFrameList(aChildList); - return NS_OK; + return; } - return nsBoxFrame::SetInitialChildList(aListID, aChildList); + nsBoxFrame::SetInitialChildList(aListID, aChildList); +} + +const nsFrameList& +nsPopupSetFrame::GetChildList(ChildListID aListID) const +{ + if (kPopupList == aListID) { + return mPopupList; + } + return nsBoxFrame::GetChildList(aListID); +} + +void +nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const +{ + nsBoxFrame::GetChildLists(aLists); + mPopupList.AppendIfNonempty(aLists, kPopupList); } void @@ -117,7 +130,7 @@ nsPopupSetFrame::DoLayout(nsBoxLayoutState& aState) // lay out all of our currently open popups. for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) { nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get()); - popupChild->LayoutPopup(aState, nullptr, false); + popupChild->LayoutPopup(aState, nullptr, nullptr, false); } return rv; @@ -145,61 +158,3 @@ nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList) #endif mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList); } - -#ifdef DEBUG -void -nsPopupSetFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const -{ - ListGeneric(out, aIndent, aFlags); - - // Output the children - bool outputOneList = false; - ChildListIterator lists(this); - for (; !lists.IsDone(); lists.Next()) { - if (outputOneList) { - IndentBy(out, aIndent); - } - outputOneList = true; - fprintf(out, "%s<\n", mozilla::layout::ChildListName(lists.CurrentID())); - nsFrameList::Enumerator childFrames(lists.CurrentList()); - for (; !childFrames.AtEnd(); childFrames.Next()) { - nsIFrame* kid = childFrames.get(); - // Verify the child frame's parent frame pointer is correct - NS_ASSERTION(kid->GetParent() == this, "bad parent frame pointer"); - - // Have the child frame list - kid->List(out, aIndent + 1, aFlags); - } - IndentBy(out, aIndent); - fputs(">\n", out); - } - - // XXXmats the above is copy-pasted from nsContainerFrame::List which is lame, - // clean this up after bug 399111 is implemented. - - if (!mPopupList.IsEmpty()) { - fputs("<\n", out); - ++aIndent; - IndentBy(out, aIndent); - fputs(mozilla::layout::ChildListName(kPopupList), out); - fputs(" for ", out); - ListTag(out); - fputs(" <\n", out); - ++aIndent; - for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) { - e.get()->List(out, aIndent, aFlags); - } - --aIndent; - IndentBy(out, aIndent); - fputs(">\n", out); - --aIndent; - IndentBy(out, aIndent); - fputs(">\n", out); - outputOneList = true; - } - - if (!outputOneList) { - fputs("<>\n", out); - } -} -#endif diff --git a/layout/xul/nsPopupSetFrame.h b/layout/xul/nsPopupSetFrame.h new file mode 100644 index 000000000..5b6249b08 --- /dev/null +++ b/layout/xul/nsPopupSetFrame.h @@ -0,0 +1,64 @@ +/* -*- 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 nsPopupSetFrame_h__ +#define nsPopupSetFrame_h__ + +#include "mozilla/Attributes.h" +#include "nsIAtom.h" +#include "nsBoxFrame.h" + +nsIFrame* NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + +class nsPopupSetFrame : public nsBoxFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + explicit nsPopupSetFrame(nsStyleContext* aContext): + nsBoxFrame(aContext) {} + + ~nsPopupSetFrame() {} + + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + + virtual void SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) override; + virtual void AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) override; + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; + virtual void InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) override; + + virtual const nsFrameList& GetChildList(ChildListID aList) const override; + virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; + + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; + + // Used to destroy our popup frames. + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; + + virtual nsIAtom* GetType() const override; + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override + { + return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult); + } +#endif + +protected: + void AddPopupFrameList(nsFrameList& aPopupFrameList); + void RemovePopupFrame(nsIFrame* aPopup); + + nsFrameList mPopupList; +}; + +#endif diff --git a/layout/xul/base/src/nsProgressMeterFrame.cpp b/layout/xul/nsProgressMeterFrame.cpp index c235a1165..4b84f83cf 100644 --- a/layout/xul/base/src/nsProgressMeterFrame.cpp +++ b/layout/xul/nsProgressMeterFrame.cpp @@ -15,12 +15,46 @@ #include "nsIContent.h" #include "nsPresContext.h" #include "nsGkAtoms.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsCOMPtr.h" #include "nsBoxLayoutState.h" #include "nsIReflowCallback.h" #include "nsContentUtils.h" #include "mozilla/Attributes.h" + +class nsReflowFrameRunnable : public nsRunnable +{ +public: + nsReflowFrameRunnable(nsIFrame* aFrame, + nsIPresShell::IntrinsicDirty aIntrinsicDirty, + nsFrameState aBitToAdd); + + NS_DECL_NSIRUNNABLE + + nsWeakFrame mWeakFrame; + nsIPresShell::IntrinsicDirty mIntrinsicDirty; + nsFrameState mBitToAdd; +}; + +nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame, + nsIPresShell::IntrinsicDirty aIntrinsicDirty, + nsFrameState aBitToAdd) + : mWeakFrame(aFrame), + mIntrinsicDirty(aIntrinsicDirty), + mBitToAdd(aBitToAdd) +{ +} + +NS_IMETHODIMP +nsReflowFrameRunnable::Run() +{ + if (mWeakFrame.IsAlive()) { + mWeakFrame->PresContext()->PresShell()-> + FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd); + } + return NS_OK; +} + // // NS_NewToolbarFrame // @@ -29,7 +63,7 @@ nsIFrame* NS_NewProgressMeterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsProgressMeterFrame(aPresShell, aContext); + return new (aPresShell) nsProgressMeterFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame) @@ -43,12 +77,12 @@ nsProgressMeterFrame :: ~nsProgressMeterFrame ( ) { } -class nsAsyncProgressMeterInit MOZ_FINAL : public nsIReflowCallback +class nsAsyncProgressMeterInit final : public nsIReflowCallback { public: - nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {} + explicit nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {} - virtual bool ReflowFinished() + virtual bool ReflowFinished() override { bool shouldFlush = false; nsIFrame* frame = mWeakFrame.GetFrame(); @@ -61,7 +95,7 @@ public: return shouldFlush; } - virtual void ReflowCallbackCanceled() + virtual void ReflowCallbackCanceled() override { delete this; } @@ -82,7 +116,7 @@ nsProgressMeterFrame::DoLayout(nsBoxLayoutState& aState) return nsBoxFrame::DoLayout(aState); } -NS_IMETHODIMP +nsresult nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -141,8 +175,8 @@ nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID, return NS_OK; } -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsProgressMeterFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult); diff --git a/layout/xul/base/src/nsProgressMeterFrame.h b/layout/xul/nsProgressMeterFrame.h index e3ac168c3..31e2a99d1 100644 --- a/layout/xul/base/src/nsProgressMeterFrame.h +++ b/layout/xul/nsProgressMeterFrame.h @@ -27,19 +27,19 @@ public: friend nsIFrame* NS_NewProgressMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif protected: - nsProgressMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) : - nsBoxFrame(aPresShell, aContext), mNeedsReflowCallback(true) {} + explicit nsProgressMeterFrame(nsStyleContext* aContext) : + nsBoxFrame(aContext), mNeedsReflowCallback(true) {} virtual ~nsProgressMeterFrame(); bool mNeedsReflowCallback; diff --git a/layout/xul/base/src/nsRepeatService.cpp b/layout/xul/nsRepeatService.cpp index e54ead684..919763d4d 100644 --- a/layout/xul/base/src/nsRepeatService.cpp +++ b/layout/xul/nsRepeatService.cpp @@ -83,4 +83,4 @@ NS_IMETHODIMP nsRepeatService::Notify(nsITimer *timer) return NS_OK; } -NS_IMPL_ISUPPORTS1(nsRepeatService, nsITimerCallback) +NS_IMPL_ISUPPORTS(nsRepeatService, nsITimerCallback) diff --git a/layout/xul/base/src/nsRepeatService.h b/layout/xul/nsRepeatService.h index cda383e20..81321a472 100644 --- a/layout/xul/base/src/nsRepeatService.h +++ b/layout/xul/nsRepeatService.h @@ -22,7 +22,7 @@ class nsITimer; -class nsRepeatService : public nsITimerCallback +class nsRepeatService final : public nsITimerCallback { public: @@ -44,10 +44,10 @@ public: static void Shutdown(); NS_DECL_ISUPPORTS - virtual ~nsRepeatService(); protected: nsRepeatService(); + virtual ~nsRepeatService(); private: Callback mCallback; diff --git a/layout/xul/base/src/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 4c3d7fe4b..2880b6a5a 100644 --- a/layout/xul/base/src/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -10,7 +10,7 @@ #include "nsIDocument.h" #include "nsIDOMNodeList.h" #include "nsGkAtoms.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsIDOMElementCSSInlineStyle.h" #include "nsIDOMCSSStyleDeclaration.h" @@ -20,8 +20,7 @@ #include "nsIDocShellTreeOwner.h" #include "nsIBaseWindow.h" #include "nsPIDOMWindow.h" -#include "nsGUIEvent.h" -#include "nsEventDispatcher.h" +#include "mozilla/MouseEvents.h" #include "nsContentUtils.h" #include "nsMenuPopupFrame.h" #include "nsIScreenManager.h" @@ -39,19 +38,19 @@ using namespace mozilla; nsIFrame* NS_NewResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsResizerFrame(aPresShell, aContext); + return new (aPresShell) nsResizerFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsResizerFrame) -nsResizerFrame::nsResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) -:nsTitleBarFrame(aPresShell, aContext) +nsResizerFrame::nsResizerFrame(nsStyleContext* aContext) +:nsTitleBarFrame(aContext) { } -NS_IMETHODIMP +nsresult nsResizerFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); @@ -65,10 +64,9 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, switch (aEvent->message) { case NS_TOUCH_START: case NS_MOUSE_BUTTON_DOWN: { - if (aEvent->eventStructType == NS_TOUCH_EVENT || - (aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton)) - { + if (aEvent->mClass == eTouchEventClass || + (aEvent->mClass == eMouseEventClass && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton)) { nsCOMPtr<nsIBaseWindow> window; nsIPresShell* presShell = aPresContext->GetPresShell(); nsIContent* contentToResize = @@ -91,7 +89,8 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, break; } - mMouseDownRect = rect.ToNearestPixels(aPresContext->AppUnitsPerDevPixel()); + mMouseDownRect = + LayoutDeviceIntRect::FromAppUnitsToNearest(rect, aPresContext->AppUnitsPerDevPixel()); doDefault = false; } else { @@ -116,7 +115,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, } // remember current mouse coordinates - nsIntPoint refPoint; + LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; mMouseDownPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); @@ -131,11 +130,9 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, case NS_TOUCH_END: case NS_MOUSE_BUTTON_UP: { - - if (aEvent->eventStructType == NS_TOUCH_EVENT || - (aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton)) - { + if (aEvent->mClass == eTouchEventClass || + (aEvent->mClass == eMouseEventClass && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton)) { // we're done tracking. mTrackingMouseMove = false; @@ -166,11 +163,11 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, // retrieve the offset of the mousemove event relative to the mousedown. // The difference is how much the resize needs to be - nsIntPoint refPoint; + LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - nsIntPoint screenPoint(refPoint + aEvent->widget->WidgetToScreenOffset()); - nsIntPoint mouseMove(screenPoint - mMouseDownPoint); + LayoutDeviceIntPoint screenPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint mouseMove(screenPoint - mMouseDownPoint); // Determine which direction to resize by checking the dir attribute. // For windows and menus, ensure that it can be resized in that direction. @@ -186,7 +183,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, break; // don't do anything if there's nothing to resize } - nsIntRect rect = mMouseDownRect; + LayoutDeviceIntRect rect = mMouseDownRect; // Check if there are any size constraints on this window. widget::SizeConstraints sizeConstraints; @@ -215,7 +212,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, NSToIntRound(frameRect.y / scale), 1, 1, getter_AddRefs(screen)); if (screen) { - nsIntRect screenRect; + LayoutDeviceIntRect screenRect; screen->GetRect(&screenRect.x, &screenRect.y, &screenRect.width, &screenRect.height); rect.IntersectRect(rect, screenRect); @@ -227,12 +224,13 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, nsIFrame* rootFrame = aPresContext->PresShell()->FrameManager()->GetRootFrame(); nsRect rootScreenRect = rootFrame->GetScreenRectInAppUnits(); - nsRect screenRect = menuPopupFrame->GetConstraintRect(frameRect, rootScreenRect); + nsPopupLevel popupLevel = menuPopupFrame->PopupLevel(); + nsRect screenRect = menuPopupFrame->GetConstraintRect(frameRect, rootScreenRect, popupLevel); // round using ToInsidePixels as it's better to be a pixel too small // than be too large. If the popup is too large it could get flipped // to the opposite side of the anchor point while resizing. nsIntRect screenRectPixels = screenRect.ToInsidePixels(aPresContext->AppUnitsPerDevPixel()); - rect.IntersectRect(rect, screenRectPixels); + rect.IntersectRect(rect, LayoutDevicePixel::FromUntyped(screenRectPixels)); } if (contentToResize) { @@ -240,7 +238,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, // direction, don't allow the new size to be less that the resizer's // size. This ensures that content isn't resized too small as to make // the resizer invisible. - nsRect appUnitsRect = rect.ToAppUnits(aPresContext->AppUnitsPerDevPixel()); + nsRect appUnitsRect = LayoutDevicePixel::ToUntyped(rect).ToAppUnits(aPresContext->AppUnitsPerDevPixel()); if (appUnitsRect.width < mRect.width && mouseMove.x) appUnitsRect.width = mRect.width; if (appUnitsRect.height < mRect.height && mouseMove.y) @@ -256,8 +254,8 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, // convert the new rectangle into outer window coordinates nsIntPoint clientOffset = widget->GetClientOffset(); - rect.x -= clientOffset.x; - rect.y -= clientOffset.y; + rect.x -= clientOffset.x; + rect.y -= clientOffset.y; } SizeInfo sizeInfo, originalSizeInfo; @@ -274,6 +272,9 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, (oldRect.x != rect.x || oldRect.y != rect.y) && (!menuPopupFrame->IsAnchored() || menuPopupFrame->PopupLevel() != ePopupLevelParent)) { + + rect.x = aPresContext->DevPixelsToIntCSSPixels(rect.x); + rect.y = aPresContext->DevPixelsToIntCSSPixels(rect.y); menuPopupFrame->MoveTo(rect.x, rect.y, true); } } @@ -286,17 +287,15 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, } break; - case NS_MOUSE_CLICK: - if (NS_IS_MOUSE_LEFT_CLICK(aEvent)) - { - MouseClicked(aPresContext, aEvent); + case NS_MOUSE_CLICK: { + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); + if (mouseEvent->IsLeftClickEvent()) { + MouseClicked(aPresContext, mouseEvent); } break; - + } case NS_MOUSE_DOUBLECLICK: - if (aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton) - { + if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { nsCOMPtr<nsIBaseWindow> window; nsIPresShell* presShell = aPresContext->GetPresShell(); nsIContent* contentToResize = @@ -342,16 +341,8 @@ nsResizerFrame::GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWi } // don't allow resizing windows in content shells - bool isChromeShell = false; - nsCOMPtr<nsISupports> cont = aPresShell->GetPresContext()->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont); - if (dsti) { - int32_t type = -1; - isChromeShell = (NS_SUCCEEDED(dsti->GetItemType(&type)) && - type == nsIDocShellTreeItem::typeChrome); - } - - if (!isChromeShell) { + nsCOMPtr<nsIDocShellTreeItem> dsti = aPresShell->GetPresContext()->GetDocShell(); + if (!dsti || dsti->ItemType() != nsIDocShellTreeItem::typeChrome) { // don't allow resizers in content shells, except for the viewport // scrollbar which doesn't have a parent nsIContent* nonNativeAnon = mContent->FindFirstNonChromeOnlyAccessContent(); @@ -461,15 +452,6 @@ nsResizerFrame::ResizeContent(nsIContent* aContent, const Direction& aDirection, } /* static */ void -nsResizerFrame::SizeInfoDtorFunc(void *aObject, nsIAtom *aPropertyName, - void *aPropertyValue, void *aData) -{ - nsResizerFrame::SizeInfo *propertyValue = - static_cast<nsResizerFrame::SizeInfo*>(aPropertyValue); - delete propertyValue; -} - -/* static */ void nsResizerFrame::MaybePersistOriginalSize(nsIContent* aContent, const SizeInfo& aSizeInfo) { @@ -481,7 +463,7 @@ nsResizerFrame::MaybePersistOriginalSize(nsIContent* aContent, nsAutoPtr<SizeInfo> sizeInfo(new SizeInfo(aSizeInfo)); rv = aContent->SetProperty(nsGkAtoms::_moz_original_size, sizeInfo.get(), - &SizeInfoDtorFunc); + nsINode::DeleteProperty<nsResizerFrame::SizeInfo>); if (NS_SUCCEEDED(rv)) sizeInfo.forget(); } @@ -521,26 +503,34 @@ nsResizerFrame::GetDirection() {-1, 1}, {1, 1} }; - if (!GetContent()) + if (!GetContent()) { return directions[0]; // default: topleft + } int32_t index = GetContent()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::dir, strings, eCaseMatters); - if(index < 0) + if (index < 0) { return directions[0]; // default: topleft - else if (index >= 8 && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { + } + + if (index >= 8) { // Directions 8 and higher are RTL-aware directions and should reverse the // horizontal component if RTL. - Direction direction = directions[index]; - direction.mHorizontal *= -1; - return direction; + WritingMode wm = GetWritingMode(); + if (!(wm.IsVertical() ? wm.IsVerticalLR() : wm.IsBidiLTR())) { + Direction direction = directions[index]; + direction.mHorizontal *= -1; + return direction; + } } + return directions[index]; } void -nsResizerFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent) +nsResizerFrame::MouseClicked(nsPresContext* aPresContext, + WidgetMouseEvent* aEvent) { // Execute the oncommand event handler. nsContentUtils::DispatchXULCommand(mContent, diff --git a/layout/xul/base/src/nsResizerFrame.h b/layout/xul/nsResizerFrame.h index 4efbbc01c..e69f5a7c8 100644 --- a/layout/xul/base/src/nsResizerFrame.h +++ b/layout/xul/nsResizerFrame.h @@ -6,6 +6,7 @@ #define nsResizerFrame_h___ #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "nsTitleBarFrame.h" class nsIBaseWindow; @@ -24,13 +25,14 @@ public: friend nsIFrame* NS_NewResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - nsResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + explicit nsResizerFrame(nsStyleContext* aContext); - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent) MOZ_OVERRIDE; + virtual void MouseClicked(nsPresContext* aPresContext, + mozilla::WidgetMouseEvent* aEvent) override; protected: nsIContent* GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWindow); @@ -64,8 +66,8 @@ protected: static void RestoreOriginalSize(nsIContent* aContent); protected: - nsIntRect mMouseDownRect; - nsIntPoint mMouseDownPoint; + LayoutDeviceIntRect mMouseDownRect; + LayoutDeviceIntPoint mMouseDownPoint; }; // class nsResizerFrame #endif /* nsResizerFrame_h___ */ diff --git a/layout/xul/base/src/nsRootBoxFrame.cpp b/layout/xul/nsRootBoxFrame.cpp index 6dde1c845..11fb77b20 100644 --- a/layout/xul/base/src/nsRootBoxFrame.cpp +++ b/layout/xul/nsRootBoxFrame.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsHTMLParts.h" -#include "nsGUIEvent.h" #include "nsStyleConsts.h" #include "nsGkAtoms.h" #include "nsIPresShell.h" @@ -14,6 +13,9 @@ #include "nsIContent.h" #include "nsXULTooltipListener.h" #include "nsFrameManager.h" +#include "mozilla/BasicEvents.h" + +using namespace mozilla; // Interface IDs @@ -44,46 +46,46 @@ public: friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - nsRootBoxFrame(nsIPresShell* aShell, nsStyleContext *aContext); + explicit nsRootBoxFrame(nsStyleContext* aContext); NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - virtual nsPopupSetFrame* GetPopupSetFrame(); - virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet); - virtual nsIContent* GetDefaultTooltip(); - virtual void SetDefaultTooltip(nsIContent* aTooltip); - virtual nsresult AddTooltipSupport(nsIContent* aNode); - virtual nsresult RemoveTooltipSupport(nsIContent* aNode); - - NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList); - NS_IMETHOD InsertFrames(ChildListID aListID, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList); - NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame); - - NS_IMETHOD Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + virtual nsPopupSetFrame* GetPopupSetFrame() override; + virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) override; + virtual nsIContent* GetDefaultTooltip() override; + virtual void SetDefaultTooltip(nsIContent* aTooltip) override; + virtual nsresult AddTooltipSupport(nsIContent* aNode) override; + virtual nsresult RemoveTooltipSupport(nsIContent* aNode) override; + + virtual void AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) override; + virtual void InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) override; + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; + + virtual void Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) override; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; /** * Get the "type" of the frame * * @see nsGkAtoms::rootFrame */ - virtual nsIAtom* GetType() const; + virtual nsIAtom* GetType() const override; - virtual bool IsFrameOfType(uint32_t aFlags) const + virtual bool IsFrameOfType(uint32_t aFlags) const override { // Override bogus IsFrameOfType in nsBoxFrame. if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) @@ -91,8 +93,8 @@ public: return nsBoxFrame::IsFrameOfType(aFlags); } -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif nsPopupSetFrame* mPopupSetFrame; @@ -103,93 +105,68 @@ protected: //---------------------------------------------------------------------- -nsIFrame* +nsContainerFrame* NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsRootBoxFrame (aPresShell, aContext); + return new (aPresShell) nsRootBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame) -nsRootBoxFrame::nsRootBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsBoxFrame(aShell, aContext, true) +nsRootBoxFrame::nsRootBoxFrame(nsStyleContext* aContext): + nsBoxFrame(aContext, true) { mPopupSetFrame = nullptr; nsCOMPtr<nsBoxLayout> layout; - NS_NewStackLayout(aShell, layout); + NS_NewStackLayout(PresContext()->PresShell(), layout); SetLayoutManager(layout); } -NS_IMETHODIMP +void nsRootBoxFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { - nsresult rv; - - NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID"); - NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame"); - if (aListID != kPrincipalList) { - // We only support the principal child list. - rv = NS_ERROR_INVALID_ARG; - } else if (!mFrames.IsEmpty()) { - // We only allow a single child frame. - rv = NS_ERROR_FAILURE; - } else { - rv = nsBoxFrame::AppendFrames(aListID, aFrameList); - } - - return rv; + MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list ID"); + MOZ_ASSERT(mFrames.IsEmpty(), "already have a child frame"); + nsBoxFrame::AppendFrames(aListID, aFrameList); } -NS_IMETHODIMP +void nsRootBoxFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) { - nsresult rv; - // Because we only support a single child frame inserting is the same // as appending. - NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame"); - if (aPrevFrame) { - rv = NS_ERROR_UNEXPECTED; - } else { - rv = AppendFrames(aListID, aFrameList); - } - - return rv; + MOZ_ASSERT(!aPrevFrame, "unexpected previous sibling frame"); + AppendFrames(aListID, aFrameList); } -NS_IMETHODIMP +void nsRootBoxFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { - nsresult rv; - NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID"); - if (aListID != kPrincipalList) { - // We only support the principal child list. - rv = NS_ERROR_INVALID_ARG; - } else if (aOldFrame == mFrames.FirstChild()) { - rv = nsBoxFrame::RemoveFrame(aListID, aOldFrame); + if (aOldFrame == mFrames.FirstChild()) { + nsBoxFrame::RemoveFrame(aListID, aOldFrame); } else { - rv = NS_ERROR_FAILURE; + MOZ_CRASH("unknown aOldFrame"); } - - return rv; } #ifdef DEBUG_REFLOW int32_t gReflows = 0; #endif -NS_IMETHODIMP +void nsRootBoxFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { + DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame"); + #ifdef DEBUG_REFLOW gReflows++; printf("----Reflow %d----\n", gReflows); @@ -210,10 +187,10 @@ nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } -NS_IMETHODIMP -nsRootBoxFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsresult +nsRootBoxFrame::HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -297,8 +274,8 @@ NS_QUERYFRAME_HEAD(nsRootBoxFrame) NS_QUERYFRAME_ENTRY(nsIRootBox) NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsRootBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("RootBox"), aResult); diff --git a/layout/xul/base/src/nsScrollBoxFrame.cpp b/layout/xul/nsScrollBoxFrame.cpp index 83857afb1..47e7f1b93 100644 --- a/layout/xul/base/src/nsScrollBoxFrame.cpp +++ b/layout/xul/nsScrollBoxFrame.cpp @@ -6,10 +6,13 @@ #include "nsCOMPtr.h" #include "nsPresContext.h" #include "nsGkAtoms.h" -#include "nsGUIEvent.h" #include "nsButtonBoxFrame.h" #include "nsITimer.h" #include "nsRepeatService.h" +#include "mozilla/MouseEvents.h" +#include "nsIContent.h" + +using namespace mozilla; class nsAutoRepeatBoxFrame : public nsButtonBoxFrame { @@ -19,27 +22,27 @@ public: friend nsIFrame* NS_NewAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - virtual void DestroyFrom(nsIFrame* aDestructRoot); + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType); + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + virtual nsresult HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - NS_IMETHOD HandlePress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + NS_IMETHOD HandlePress(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - NS_IMETHOD HandleRelease(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus); + NS_IMETHOD HandleRelease(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; protected: - nsAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext): - nsButtonBoxFrame(aPresShell, aContext) {} + explicit nsAutoRepeatBoxFrame(nsStyleContext* aContext): + nsButtonBoxFrame(aContext) {} void StartRepeat() { if (IsActivatedOnHover()) { @@ -65,15 +68,15 @@ protected: nsIFrame* NS_NewAutoRepeatBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsAutoRepeatBoxFrame (aPresShell, aContext); + return new (aPresShell) nsAutoRepeatBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsAutoRepeatBoxFrame) -NS_IMETHODIMP -nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsresult +nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -101,20 +104,22 @@ nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext, mTrustedEvent = false; break; - case NS_MOUSE_CLICK: - if (NS_IS_MOUSE_LEFT_CLICK(aEvent)) { + case NS_MOUSE_CLICK: { + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); + if (mouseEvent->IsLeftClickEvent()) { // skip button frame handling to prevent click handling - return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); + return nsBoxFrame::HandleEvent(aPresContext, mouseEvent, aEventStatus); } break; + } } return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } NS_IMETHODIMP -nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, +nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { if (!IsActivatedOnHover()) { @@ -127,8 +132,8 @@ nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext, } NS_IMETHODIMP -nsAutoRepeatBoxFrame::HandleRelease(nsPresContext* aPresContext, - nsGUIEvent* aEvent, +nsAutoRepeatBoxFrame::HandleRelease(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { if (!IsActivatedOnHover()) { @@ -137,7 +142,7 @@ nsAutoRepeatBoxFrame::HandleRelease(nsPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP +nsresult nsAutoRepeatBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) diff --git a/layout/xul/base/src/nsScrollbarButtonFrame.cpp b/layout/xul/nsScrollbarButtonFrame.cpp index 7e57a65ab..22117a8cc 100644 --- a/layout/xul/base/src/nsScrollbarButtonFrame.cpp +++ b/layout/xul/nsScrollbarButtonFrame.cpp @@ -14,14 +14,14 @@ #include "nsPresContext.h" #include "nsIContent.h" #include "nsCOMPtr.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsSliderFrame.h" #include "nsScrollbarFrame.h" #include "nsIScrollbarMediator.h" #include "nsRepeatService.h" -#include "nsGUIEvent.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/MouseEvents.h" using namespace mozilla; @@ -33,14 +33,14 @@ using namespace mozilla; nsIFrame* NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsScrollbarButtonFrame(aPresShell, aContext); + return new (aPresShell) nsScrollbarButtonFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame) -NS_IMETHODIMP -nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, +nsresult +nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); @@ -78,20 +78,19 @@ nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext, return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } - bool -nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { // Get the desired action for the scrollbar button. LookAndFeel::IntID tmpAction; - uint16_t button = static_cast<nsMouseEvent*>(aEvent)->button; - if (button == nsMouseEvent::eLeftButton) { + uint16_t button = aEvent->AsMouseEvent()->button; + if (button == WidgetMouseEvent::eLeftButton) { tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction; - } else if (button == nsMouseEvent::eMiddleButton) { + } else if (button == WidgetMouseEvent::eMiddleButton) { tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction; - } else if (button == nsMouseEvent::eRightButton) { + } else if (button == WidgetMouseEvent::eRightButton) { tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction; } else { return false; @@ -109,10 +108,7 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, if (scrollbar == nullptr) return false; - - // get the scrollbars content node - nsIContent* content = scrollbar->GetContent(); - + static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment, &nsGkAtoms::decrement, nullptr }; @@ -120,58 +116,72 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, nsGkAtoms::type, strings, eCaseMatters); int32_t direction; - if (index == 0) + if (index == 0) direction = 1; else if (index == 1) direction = -1; else return false; - // Whether or not to repeat the click action. - bool repeat = true; - // Use smooth scrolling by default. - bool smoothScroll = true; - switch (pressedButtonAction) { + bool repeat = pressedButtonAction != 2; + // set this attribute so we can style it later + nsWeakFrame weakFrame(this); + mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true); + + nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED); + + if (!weakFrame.IsAlive()) { + return false; + } + + nsScrollbarFrame* sb = do_QueryFrame(scrollbar); + if (sb) { + nsIScrollbarMediator* m = sb->GetScrollbarMediator(); + switch (pressedButtonAction) { case 0: - mIncrement = direction * nsSliderFrame::GetIncrement(content); + sb->SetIncrementToLine(direction); + if (m) { + m->ScrollByLine(sb, direction); + } break; case 1: - mIncrement = direction * nsSliderFrame::GetPageIncrement(content); + sb->SetIncrementToPage(direction); + if (m) { + m->ScrollByPage(sb, direction); + } break; case 2: - if (direction == -1) - mIncrement = -nsSliderFrame::GetCurrentPosition(content); - else - mIncrement = nsSliderFrame::GetMaxPosition(content) - - nsSliderFrame::GetCurrentPosition(content); - // Don't repeat or use smooth scrolling if scrolling to beginning or end - // of a page. - repeat = smoothScroll = false; + sb->SetIncrementToWhole(direction); + if (m) { + m->ScrollByWhole(sb, direction); + } break; case 3: default: // We were told to ignore this click, or someone assigned a non-standard // value to the button's action. return false; + } + if (!weakFrame.IsAlive()) { + return false; + } + if (!m) { + sb->MoveToNewPosition(); + if (!weakFrame.IsAlive()) { + return false; + } + } } - // set this attribute so we can style it later - nsWeakFrame weakFrame(this); - mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true); - - nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED); - - if (weakFrame.IsAlive()) { - DoButtonAction(smoothScroll); - } - if (repeat) + if (repeat) { StartRepeat(); + } return true; } NS_IMETHODIMP -nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { nsIPresShell::SetCapturingContent(nullptr, 0); // we're not active anymore @@ -182,72 +192,32 @@ nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext, void nsScrollbarButtonFrame::Notify() { - // Since this is only going to get called if we're scrolling a page length - // or a line increment, we will always use smooth scrolling. if (mCursorOnThis || LookAndFeel::GetInt( LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) { - DoButtonAction(true); + // get the scrollbar control + nsIFrame* scrollbar; + GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar); + nsScrollbarFrame* sb = do_QueryFrame(scrollbar); + if (sb) { + nsIScrollbarMediator* m = sb->GetScrollbarMediator(); + if (m) { + m->RepeatButtonScroll(sb); + } else { + sb->MoveToNewPosition(); + } + } } } void -nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent) +nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent) { nsButtonBoxFrame::MouseClicked(aPresContext, aEvent); //MouseClicked(); } -void -nsScrollbarButtonFrame::DoButtonAction(bool aSmoothScroll) -{ - // get the scrollbar control - nsIFrame* scrollbar; - GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar); - - if (scrollbar == nullptr) - return; - - // get the scrollbars content node - nsCOMPtr<nsIContent> content = scrollbar->GetContent(); - - // get the current pos - int32_t curpos = nsSliderFrame::GetCurrentPosition(content); - int32_t oldpos = curpos; - - // get the max pos - int32_t maxpos = nsSliderFrame::GetMaxPosition(content); - - // increment the given amount - if (mIncrement) - curpos += mIncrement; - - // make sure the current position is between the current and max positions - if (curpos < 0) - curpos = 0; - else if (curpos > maxpos) - curpos = maxpos; - - nsScrollbarFrame* sb = do_QueryFrame(scrollbar); - if (sb) { - nsIScrollbarMediator* m = sb->GetScrollbarMediator(); - if (m) { - m->ScrollbarButtonPressed(sb, oldpos, curpos); - return; - } - } - - // set the current position of the slider. - nsAutoString curposStr; - curposStr.AppendInt(curpos); - - if (aSmoothScroll) - content->SetAttr(kNameSpaceID_None, nsGkAtoms::smooth, NS_LITERAL_STRING("true"), false); - content->SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, curposStr, true); - if (aSmoothScroll) - content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::smooth, false); -} - nsresult nsScrollbarButtonFrame::GetChildWithTag(nsPresContext* aPresContext, nsIAtom* atom, nsIFrame* start, diff --git a/layout/xul/base/src/nsScrollbarButtonFrame.h b/layout/xul/nsScrollbarButtonFrame.h index 6f73bb628..dbc468568 100644 --- a/layout/xul/base/src/nsScrollbarButtonFrame.h +++ b/layout/xul/nsScrollbarButtonFrame.h @@ -25,42 +25,48 @@ class nsScrollbarButtonFrame : public nsButtonBoxFrame public: NS_DECL_FRAMEARENA_HELPERS - nsScrollbarButtonFrame(nsIPresShell* aPresShell, nsStyleContext* aContext): - nsButtonBoxFrame(aPresShell, aContext), mCursorOnThis(false) {} + explicit nsScrollbarButtonFrame(nsStyleContext* aContext): + nsButtonBoxFrame(aContext), mCursorOnThis(false) {} // Overrides - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; friend nsIFrame* NS_NewScrollbarButtonFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; static nsresult GetChildWithTag(nsPresContext* aPresContext, nsIAtom* atom, nsIFrame* start, nsIFrame*& result); static nsresult GetParentWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result); bool HandleButtonPress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus); + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus); NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus, - bool aControlHeld) MOZ_OVERRIDE { return NS_OK; } + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, + bool aControlHeld) override + { + return NS_OK; + } NS_IMETHOD HandleDrag(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE { return NS_OK; } + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override + { + return NS_OK; + } NS_IMETHOD HandleRelease(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; protected: - virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent) MOZ_OVERRIDE; - void DoButtonAction(bool aSmoothScroll); + virtual void MouseClicked(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent) override; void StartRepeat() { nsRepeatService::GetInstance()->Start(Notify, this); @@ -73,7 +79,6 @@ protected: static_cast<nsScrollbarButtonFrame*>(aData)->Notify(); } - int32_t mIncrement; bool mCursorOnThis; }; diff --git a/layout/xul/nsScrollbarFrame.cpp b/layout/xul/nsScrollbarFrame.cpp new file mode 100644 index 000000000..126791837 --- /dev/null +++ b/layout/xul/nsScrollbarFrame.cpp @@ -0,0 +1,298 @@ +/* -*- 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/. */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsScrollbarFrame.h" +#include "nsSliderFrame.h" +#include "nsScrollbarButtonFrame.h" +#include "nsGkAtoms.h" +#include "nsIScrollableFrame.h" +#include "nsIScrollbarMediator.h" +#include "mozilla/LookAndFeel.h" +#include "nsThemeConstants.h" +#include "nsIContent.h" +#include "nsIDOMMutationEvent.h" + +using namespace mozilla; + +// +// NS_NewScrollbarFrame +// +// Creates a new scrollbar frame and returns it +// +nsIFrame* +NS_NewScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) +{ + return new (aPresShell) nsScrollbarFrame(aContext); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarFrame) + +NS_QUERYFRAME_HEAD(nsScrollbarFrame) + NS_QUERYFRAME_ENTRY(nsScrollbarFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) + +void +nsScrollbarFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) +{ + nsBoxFrame::Init(aContent, aParent, aPrevInFlow); + + // We want to be a reflow root since we use reflows to move the + // slider. Any reflow inside the scrollbar frame will be a reflow to + // move the slider and will thus not change anything outside of the + // scrollbar or change the size of the scrollbar frame. + mState |= NS_FRAME_REFLOW_ROOT; +} + +void +nsScrollbarFrame::Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + + // nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure our + // desired size agrees. + if (aReflowState.AvailableWidth() == 0) { + aDesiredSize.Width() = 0; + } + if (aReflowState.AvailableHeight() == 0) { + aDesiredSize.Height() = 0; + } +} + +nsIAtom* +nsScrollbarFrame::GetType() const +{ + return nsGkAtoms::scrollbarFrame; +} + +nsresult +nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) +{ + nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, + aModType); + + // if the current position changes, notify any nsGfxScrollFrame + // parent we may have + if (aAttribute != nsGkAtoms::curpos) + return rv; + + nsIScrollableFrame* scrollable = do_QueryFrame(GetParent()); + if (!scrollable) + return rv; + + nsCOMPtr<nsIContent> kungFuDeathGrip(mContent); + scrollable->CurPosAttributeChanged(mContent); + return rv; +} + +NS_IMETHODIMP +nsScrollbarFrame::HandlePress(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsScrollbarFrame::HandleMultiplePress(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, + bool aControlHeld) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsScrollbarFrame::HandleDrag(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsScrollbarFrame::HandleRelease(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) +{ + return NS_OK; +} + +void +nsScrollbarFrame::SetScrollbarMediatorContent(nsIContent* aMediator) +{ + mScrollbarMediator = aMediator; +} + +nsIScrollbarMediator* +nsScrollbarFrame::GetScrollbarMediator() +{ + if (!mScrollbarMediator) { + return nullptr; + } + nsIFrame* f = mScrollbarMediator->GetPrimaryFrame(); + nsIScrollableFrame* scrollFrame = do_QueryFrame(f); + nsIScrollbarMediator* sbm; + + if (scrollFrame) { + nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame(); + sbm = do_QueryFrame(scrolledFrame); + if (sbm) { + return sbm; + } + } + sbm = do_QueryFrame(f); + if (f && !sbm) { + f = f->PresContext()->PresShell()->GetRootScrollFrame(); + if (f && f->GetContent() == mScrollbarMediator) { + return do_QueryFrame(f); + } + } + return sbm; +} + +nsresult +nsScrollbarFrame::GetMargin(nsMargin& aMargin) +{ + aMargin.SizeTo(0,0,0,0); + + if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { + nsPresContext* presContext = PresContext(); + nsITheme* theme = presContext->GetTheme(); + if (theme) { + nsIntSize size; + bool isOverridable; + theme->GetMinimumWidgetSize(presContext, this, NS_THEME_SCROLLBAR, &size, + &isOverridable); + if (IsHorizontal()) { + aMargin.top = -presContext->DevPixelsToAppUnits(size.height); + } + else { + if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { + aMargin.right = -presContext->DevPixelsToAppUnits(size.width); + } + else { + aMargin.left = -presContext->DevPixelsToAppUnits(size.width); + } + } + return NS_OK; + } + } + + return nsBox::GetMargin(aMargin); +} + +void +nsScrollbarFrame::SetIncrementToLine(int32_t aDirection) +{ + // get the scrollbar's content node + nsIContent* content = GetContent(); + mSmoothScroll = true; + mIncrement = aDirection * nsSliderFrame::GetIncrement(content); +} + +void +nsScrollbarFrame::SetIncrementToPage(int32_t aDirection) +{ + // get the scrollbar's content node + nsIContent* content = GetContent(); + mSmoothScroll = true; + mIncrement = aDirection * nsSliderFrame::GetPageIncrement(content); +} + +void +nsScrollbarFrame::SetIncrementToWhole(int32_t aDirection) +{ + // get the scrollbar's content node + nsIContent* content = GetContent(); + if (aDirection == -1) + mIncrement = -nsSliderFrame::GetCurrentPosition(content); + else + mIncrement = nsSliderFrame::GetMaxPosition(content) - + nsSliderFrame::GetCurrentPosition(content); + // Don't repeat or use smooth scrolling if scrolling to beginning or end + // of a page. + mSmoothScroll = false; +} + +int32_t +nsScrollbarFrame::MoveToNewPosition() +{ + // get the scrollbar's content node + nsCOMPtr<nsIContent> content = GetContent(); + + // get the current pos + int32_t curpos = nsSliderFrame::GetCurrentPosition(content); + + // get the max pos + int32_t maxpos = nsSliderFrame::GetMaxPosition(content); + + // increment the given amount + if (mIncrement) { + curpos += mIncrement; + } + + // make sure the current position is between the current and max positions + if (curpos < 0) { + curpos = 0; + } else if (curpos > maxpos) { + curpos = maxpos; + } + + // set the current position of the slider. + nsAutoString curposStr; + curposStr.AppendInt(curpos); + + nsWeakFrame weakFrame(this); + if (mSmoothScroll) { + content->SetAttr(kNameSpaceID_None, nsGkAtoms::smooth, NS_LITERAL_STRING("true"), false); + } + content->SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, curposStr, false); + // notify the nsScrollbarFrame of the change + AttributeChanged(kNameSpaceID_None, nsGkAtoms::curpos, nsIDOMMutationEvent::MODIFICATION); + if (!weakFrame.IsAlive()) { + return curpos; + } + // notify all nsSliderFrames of the change + nsIFrame::ChildListIterator childLists(this); + for (; !childLists.IsDone(); childLists.Next()) { + nsFrameList::Enumerator childFrames(childLists.CurrentList()); + for (; !childFrames.AtEnd(); childFrames.Next()) { + nsIFrame* f = childFrames.get(); + nsSliderFrame* sliderFrame = do_QueryFrame(f); + if (sliderFrame) { + sliderFrame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::curpos, nsIDOMMutationEvent::MODIFICATION); + if (!weakFrame.IsAlive()) { + return curpos; + } + } + } + } + // See if we have appearance information for a theme. + const nsStyleDisplay* disp = StyleDisplay(); + nsPresContext* presContext = PresContext(); + if (disp->mAppearance) { + nsITheme *theme = presContext->GetTheme(); + if (theme && theme->ThemeSupportsWidget(presContext, this, disp->mAppearance)) { + bool repaint; + theme->WidgetStateChanged(this, disp->mAppearance, nsGkAtoms::curpos, &repaint); + } + } + content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::smooth, false); + return curpos; +} diff --git a/layout/xul/nsScrollbarFrame.h b/layout/xul/nsScrollbarFrame.h new file mode 100644 index 000000000..098167cbb --- /dev/null +++ b/layout/xul/nsScrollbarFrame.h @@ -0,0 +1,110 @@ +/* -*- 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/. */ + +// +// nsScrollbarFrame +// + +#ifndef nsScrollbarFrame_h__ +#define nsScrollbarFrame_h__ + +#include "mozilla/Attributes.h" +#include "nsBoxFrame.h" + +class nsIScrollbarMediator; + +nsIFrame* NS_NewScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + +class nsScrollbarFrame : public nsBoxFrame +{ +public: + explicit nsScrollbarFrame(nsStyleContext* aContext): + nsBoxFrame(aContext), mScrollbarMediator(nullptr) {} + + NS_DECL_QUERYFRAME_TARGET(nsScrollbarFrame) + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { + return MakeFrameName(NS_LITERAL_STRING("ScrollbarFrame"), aResult); + } +#endif + + // nsIFrame overrides + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; + + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS + + NS_IMETHOD HandlePress(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, + bool aControlHeld) override; + + NS_IMETHOD HandleDrag(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + NS_IMETHOD HandleRelease(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + + virtual void Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) override; + + virtual nsIAtom* GetType() const override; + + void SetScrollbarMediatorContent(nsIContent* aMediator); + nsIScrollbarMediator* GetScrollbarMediator(); + + // nsBox methods + + /** + * Treat scrollbars as clipping their children; overflowing children + * will not be allowed to set an overflow rect on this + * frame. This means that when the scroll code decides to hide a + * scrollframe by setting its height or width to zero, that will + * hide the children too. + */ + virtual bool DoesClipChildren() override { return true; } + + virtual nsresult GetMargin(nsMargin& aMargin) override; + + /** + * The following three methods set the value of mIncrement when a + * scrollbar button is pressed. + */ + void SetIncrementToLine(int32_t aDirection); + void SetIncrementToPage(int32_t aDirection); + void SetIncrementToWhole(int32_t aDirection); + /** + * MoveToNewPosition() adds mIncrement to the current position and + * updates the curpos attribute. + * @returns The new position after clamping, in CSS Pixels + * @note This method might destroy the frame, pres shell, and other objects. + */ + int32_t MoveToNewPosition(); + int32_t GetIncrement() { return mIncrement; } + +protected: + int32_t mIncrement; // Amount to scroll, in CSSPixels + bool mSmoothScroll; + +private: + nsCOMPtr<nsIContent> mScrollbarMediator; +}; // class nsScrollbarFrame + +#endif diff --git a/layout/xul/base/src/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 82f3dcd67..4093da5c8 100644 --- a/layout/xul/base/src/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -15,12 +15,11 @@ #include "nsPresContext.h" #include "nsIContent.h" #include "nsCOMPtr.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsHTMLParts.h" #include "nsIPresShell.h" #include "nsCSSRendering.h" -#include "nsEventListenerManager.h" #include "nsIDOMMouseEvent.h" #include "nsScrollbarButtonFrame.h" #include "nsISliderListener.h" @@ -30,12 +29,12 @@ #include "nsBoxLayoutState.h" #include "nsSprocketLayout.h" #include "nsIServiceManager.h" -#include "nsGUIEvent.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "nsDisplayList.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/MouseEvents.h" #include <algorithm> using namespace mozilla; @@ -56,15 +55,20 @@ GetContentOfBox(nsIFrame *aBox) nsIFrame* NS_NewSliderFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsSliderFrame(aPresShell, aContext); + return new (aPresShell) nsSliderFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsSliderFrame) -nsSliderFrame::nsSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext): - nsBoxFrame(aPresShell, aContext), +NS_QUERYFRAME_HEAD(nsSliderFrame) + NS_QUERYFRAME_ENTRY(nsSliderFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) + +nsSliderFrame::nsSliderFrame(nsStyleContext* aContext): + nsBoxFrame(aContext), mCurPos(0), mChange(0), + mDragFinished(true), mUserChanged(false) { } @@ -75,9 +79,9 @@ nsSliderFrame::~nsSliderFrame() } void -nsSliderFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsSliderFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); @@ -92,42 +96,36 @@ nsSliderFrame::Init(nsIContent* aContent, mCurPos = GetCurrentPosition(aContent); } -NS_IMETHODIMP +void nsSliderFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { - nsresult rv = nsBoxFrame::RemoveFrame(aListID, aOldFrame); + nsBoxFrame::RemoveFrame(aListID, aOldFrame); if (mFrames.IsEmpty()) RemoveListener(); - - return rv; } -NS_IMETHODIMP +void nsSliderFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) { bool wasEmpty = mFrames.IsEmpty(); - nsresult rv = nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); + nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList); if (wasEmpty) AddListener(); - - return rv; } -NS_IMETHODIMP +void nsSliderFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { // if we have no children and on was added then make sure we add the // listener bool wasEmpty = mFrames.IsEmpty(); - nsresult rv = nsBoxFrame::AppendFrames(aListID, aFrameList); + nsBoxFrame::AppendFrames(aListID, aFrameList); if (wasEmpty) AddListener(); - - return rv; } int32_t @@ -217,7 +215,7 @@ public: bool mDragBeginning; }; -NS_IMETHODIMP +nsresult nsSliderFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -251,19 +249,25 @@ nsSliderFrame::AttributeChanged(int32_t aNameSpaceID, if (current < min || current > max) { - if (current < min || max < min) - current = min; - else if (current > max) - current = max; + int32_t direction = 0; + if (current < min || max < min) { + current = min; + direction = -1; + } else if (current > max) { + current = max; + direction = 1; + } // set the new position and notify observers nsScrollbarFrame* scrollbarFrame = do_QueryFrame(scrollbarBox); if (scrollbarFrame) { nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator(); + scrollbarFrame->SetIncrementToWhole(direction); if (mediator) { - mediator->PositionChanged(scrollbarFrame, GetCurrentPosition(scrollbar), current); + mediator->ScrollByWhole(scrollbarFrame, direction); } } + // 'this' might be destroyed here nsContentUtils::AddScriptRunner( new nsSetAttrRunnable(scrollbar, nsGkAtoms::curpos, current)); @@ -304,7 +308,7 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { // if we are too small to have a thumb don't paint it. - nsIFrame* thumb = GetChildBox(); + nsIFrame* thumb = nsBox::GetChildBox(this); if (thumb) { nsRect thumbRect(thumb->GetRect()); @@ -326,7 +330,7 @@ NS_IMETHODIMP nsSliderFrame::DoLayout(nsBoxLayoutState& aState) { // get the thumb should be our only child - nsIFrame* thumbBox = GetChildBox(); + nsIFrame* thumbBox = nsBox::GetChildBox(this); if (!thumbBox) { SyncLayout(aState); @@ -410,10 +414,10 @@ nsSliderFrame::DoLayout(nsBoxLayoutState& aState) } -NS_IMETHODIMP +nsresult nsSliderFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); @@ -424,6 +428,11 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, return NS_OK; } + if (!mDragFinished && !isDraggingThumb()) { + StopDrag(); + return NS_OK; + } + nsIFrame* scrollbarBox = GetScrollbar(); nsCOMPtr<nsIContent> scrollbar; scrollbar = GetContentOfBox(scrollbarBox); @@ -439,12 +448,15 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, break; } if (mChange) { - // We're in the process of moving the thumb to the mouse, - // but the mouse just moved. Make sure to update our - // destination point. + // On Linux the destination point is determined by the initial click + // on the scrollbar track and doesn't change until the mouse button + // is released. +#ifndef MOZ_WIDGET_GTK + // On the other platforms we need to update the destination point now. mDestinationPoint = eventPoint; StopRepeat(); StartRepeat(); +#endif break; } @@ -477,7 +489,7 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, isMouseOutsideThumb = true; } } - if (aEvent->eventStructType == NS_TOUCH_EVENT) { + if (aEvent->mClass == eTouchEventClass) { *aEventStatus = nsEventStatus_eConsumeNoDefault; } if (isMouseOutsideThumb) @@ -494,13 +506,7 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, case NS_TOUCH_END: case NS_MOUSE_BUTTON_UP: if (ShouldScrollForEvent(aEvent)) { - // stop capturing - AddListener(); - DragThumb(false); - if (mChange) { - StopRepeat(); - mChange = 0; - } + StopDrag(); //we MUST call nsFrame HandleEvent for mouse ups to maintain the selection state and capture state. return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } @@ -530,7 +536,13 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_OK); DragThumb(true); - if (aEvent->eventStructType == NS_TOUCH_EVENT) { + +#ifdef MOZ_WIDGET_GTK + nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent(); + thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true); +#endif + + if (aEvent->mClass == eTouchEventClass) { *aEventStatus = nsEventStatus_eConsumeNoDefault; } @@ -541,6 +553,21 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, mDragStart = pos - mThumbStart; } +#ifdef MOZ_WIDGET_GTK + else if (ShouldScrollForEvent(aEvent) && + aEvent->mClass == eMouseEventClass && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eRightButton) { + // HandlePress and HandleRelease are usually called via + // nsFrame::HandleEvent, but only for the left mouse button. + if (aEvent->message == NS_MOUSE_BUTTON_DOWN) { + HandlePress(aPresContext, aEvent, aEventStatus); + } else if (aEvent->message == NS_MOUSE_BUTTON_UP) { + HandleRelease(aPresContext, aEvent, aEventStatus); + } + + return NS_OK; + } +#endif // XXX hack until handle release is actually called in nsframe. // if (aEvent->message == NS_MOUSE_EXIT_SYNTH || aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) @@ -602,10 +629,6 @@ nsSliderFrame::PageUpDown(nscoord change) nsCOMPtr<nsIContent> scrollbar; scrollbar = GetContentOfBox(scrollbarBox); - if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, - nsGkAtoms::reverse, eCaseMatters)) - change = -change; - nscoord pageIncrement = GetPageIncrement(scrollbar); int32_t curpos = GetCurrentPosition(scrollbar); int32_t minpos = GetMinPosition(scrollbar); @@ -665,6 +688,18 @@ nsSliderFrame::CurrentPositionChanged() else newThumbRect.y = clientRect.y + NSToCoordRound(pos * mRatio); + // avoid putting the scroll thumb at subpixel positions which cause needless invalidations + nscoord appUnitsPerPixel = PresContext()->AppUnitsPerDevPixel(); + nsRect snappedThumbRect = newThumbRect.ToNearestPixels(appUnitsPerPixel).ToAppUnits(appUnitsPerPixel); + if (IsHorizontal()) { + newThumbRect.x = snappedThumbRect.x; + newThumbRect.width = snappedThumbRect.width; + } else { + newThumbRect.y = snappedThumbRect.y; + newThumbRect.height = snappedThumbRect.height; + } + newThumbRect = newThumbRect.Intersect(clientRect); + // set the rect thumbFrame->SetRect(newThumbRect); @@ -755,6 +790,7 @@ nsSliderFrame::SetCurrentPositionInternal(nsIContent* aScrollbar, int32_t aNewPo { nsCOMPtr<nsIContent> scrollbar = aScrollbar; nsIFrame* scrollbarBox = GetScrollbar(); + nsWeakFrame weakFrame(this); mUserChanged = true; @@ -763,21 +799,23 @@ nsSliderFrame::SetCurrentPositionInternal(nsIContent* aScrollbar, int32_t aNewPo // See if we have a mediator. nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator(); if (mediator) { - nsRefPtr<nsPresContext> context = PresContext(); nsCOMPtr<nsIContent> content = GetContent(); - mediator->PositionChanged(scrollbarFrame, GetCurrentPosition(scrollbar), aNewPos); - // 'mediator' might be dangling now... - UpdateAttribute(scrollbar, aNewPos, false, aIsSmooth); - nsIFrame* frame = content->GetPrimaryFrame(); - if (frame && frame->GetType() == nsGkAtoms::sliderFrame) { - static_cast<nsSliderFrame*>(frame)->CurrentPositionChanged(); + nscoord oldPos = nsPresContext::CSSPixelsToAppUnits(GetCurrentPosition(scrollbar)); + nscoord newPos = nsPresContext::CSSPixelsToAppUnits(aNewPos); + mediator->ThumbMoved(scrollbarFrame, oldPos, newPos); + if (!weakFrame.IsAlive()) { + return; } + CurrentPositionChanged(); mUserChanged = false; return; } } UpdateAttribute(scrollbar, aNewPos, true, aIsSmooth); + if (!weakFrame.IsAlive()) { + return; + } mUserChanged = false; #ifdef DEBUG_SLIDER @@ -792,15 +830,12 @@ nsSliderFrame::GetType() const return nsGkAtoms::sliderFrame; } -NS_IMETHODIMP +void nsSliderFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - nsresult r = nsBoxFrame::SetInitialChildList(aListID, aChildList); - + nsBoxFrame::SetInitialChildList(aListID, aChildList); AddListener(); - - return r; } nsresult @@ -823,7 +858,7 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent) nsGkAtoms::_true, eCaseMatters)) return NS_OK; - nsGUIEvent *event = static_cast<nsGUIEvent*>(aEvent->GetInternalNSEvent()); + WidgetGUIEvent* event = aEvent->GetInternalNSEvent()->AsGUIEvent(); if (!ShouldScrollForEvent(event)) { return NS_OK; @@ -868,6 +903,11 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent) return NS_OK; } +#ifdef MOZ_WIDGET_GTK + nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent(); + thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true); +#endif + if (isHorizontal) mThumbStart = thumbFrame->GetPosition().x; else @@ -882,9 +922,32 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent) return NS_OK; } +nsresult +nsSliderFrame::StopDrag() +{ + AddListener(); + DragThumb(false); + +#ifdef MOZ_WIDGET_GTK + nsIFrame* thumbFrame = mFrames.FirstChild(); + if (thumbFrame) { + nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent(); + thumb->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true); + } +#endif + + if (mChange) { + StopRepeat(); + mChange = 0; + } + return NS_OK; +} + void nsSliderFrame::DragThumb(bool aGrabMouseEvents) { + mDragFinished = !aGrabMouseEvents; + // inform the parent <scale> that a drag is beginning or ending nsIFrame* parent = GetParent(); if (parent) { @@ -938,7 +1001,7 @@ nsSliderFrame::RemoveListener() } bool -nsSliderFrame::ShouldScrollForEvent(nsGUIEvent* aEvent) +nsSliderFrame::ShouldScrollForEvent(WidgetGUIEvent* aEvent) { switch (aEvent->message) { case NS_TOUCH_START: @@ -946,9 +1009,15 @@ nsSliderFrame::ShouldScrollForEvent(nsGUIEvent* aEvent) return true; case NS_MOUSE_BUTTON_DOWN: case NS_MOUSE_BUTTON_UP: { - uint16_t button = static_cast<nsMouseEvent*>(aEvent)->button; - return (button == nsMouseEvent::eLeftButton) || - (button == nsMouseEvent::eMiddleButton && gMiddlePref); + uint16_t button = aEvent->AsMouseEvent()->button; +#ifdef MOZ_WIDGET_GTK + return (button == WidgetMouseEvent::eLeftButton) || + (button == WidgetMouseEvent::eRightButton && GetScrollToClick()) || + (button == WidgetMouseEvent::eMiddleButton && gMiddlePref && !GetScrollToClick()); +#else + return (button == WidgetMouseEvent::eLeftButton) || + (button == WidgetMouseEvent::eMiddleButton && gMiddlePref); +#endif } default: return false; @@ -956,7 +1025,7 @@ nsSliderFrame::ShouldScrollForEvent(nsGUIEvent* aEvent) } bool -nsSliderFrame::ShouldScrollToClickForEvent(nsGUIEvent* aEvent) +nsSliderFrame::ShouldScrollToClickForEvent(WidgetGUIEvent* aEvent) { if (!ShouldScrollForEvent(aEvent)) { return false; @@ -970,15 +1039,15 @@ nsSliderFrame::ShouldScrollToClickForEvent(nsGUIEvent* aEvent) return false; } -#ifdef XP_MACOSX - // On Mac, clicking the scrollbar thumb should never scroll to click. +#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) + // On Mac and Linux, clicking the scrollbar thumb should never scroll to click. if (IsEventOverThumb(aEvent)) { return false; } #endif - nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(aEvent); - if (mouseEvent->button == nsMouseEvent::eLeftButton) { + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); + if (mouseEvent->button == WidgetMouseEvent::eLeftButton) { #ifdef XP_MACOSX bool invertPref = mouseEvent->IsAlt(); #else @@ -987,11 +1056,17 @@ nsSliderFrame::ShouldScrollToClickForEvent(nsGUIEvent* aEvent) return GetScrollToClick() != invertPref; } +#ifdef MOZ_WIDGET_GTK + if (mouseEvent->button == WidgetMouseEvent::eRightButton) { + return !GetScrollToClick(); + } +#endif + return true; } bool -nsSliderFrame::IsEventOverThumb(nsGUIEvent* aEvent) +nsSliderFrame::IsEventOverThumb(WidgetGUIEvent* aEvent) { nsIFrame* thumbFrame = mFrames.FirstChild(); if (!thumbFrame) { @@ -1014,8 +1089,8 @@ nsSliderFrame::IsEventOverThumb(nsGUIEvent* aEvent) NS_IMETHODIMP nsSliderFrame::HandlePress(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { if (!ShouldScrollForEvent(aEvent) || ShouldScrollToClickForEvent(aEvent)) { return NS_OK; @@ -1046,16 +1121,35 @@ nsSliderFrame::HandlePress(nsPresContext* aPresContext, mChange = change; DragThumb(true); + // On Linux we want to keep scrolling in the direction indicated by |change| + // until the mouse is released. On the other platforms we want to stop + // scrolling as soon as the scrollbar thumb has reached the current mouse + // position. +#ifdef MOZ_WIDGET_GTK + nsRect clientRect; + GetClientRect(clientRect); + + // Set the destination point to the very end of the scrollbar so that + // scrolling doesn't stop halfway through. + if (change > 0) { + mDestinationPoint = nsPoint(clientRect.width, clientRect.height); + } + else { + mDestinationPoint = nsPoint(0, 0); + } +#else mDestinationPoint = eventPoint; +#endif StartRepeat(); - PageUpDown(change); + PageScroll(change); + return NS_OK; } NS_IMETHODIMP nsSliderFrame::HandleRelease(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { StopRepeat(); @@ -1112,7 +1206,8 @@ nsSliderFrame::EnsureOrient() } -void nsSliderFrame::Notify(void) +void +nsSliderFrame::Notify(void) { bool stop = false; @@ -1149,9 +1244,29 @@ void nsSliderFrame::Notify(void) if (stop) { StopRepeat(); } else { - PageUpDown(mChange); + PageScroll(mChange); + } +} + +void +nsSliderFrame::PageScroll(nscoord aChange) +{ + if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, + nsGkAtoms::reverse, eCaseMatters)) { + aChange = -aChange; + } + nsIFrame* scrollbar = GetScrollbar(); + nsScrollbarFrame* sb = do_QueryFrame(scrollbar); + if (sb) { + nsIScrollbarMediator* m = sb->GetScrollbarMediator(); + sb->SetIncrementToPage(aChange); + if (m) { + m->ScrollByPage(sb, aChange); + return; } + } + PageUpDown(aChange); } -NS_IMPL_ISUPPORTS1(nsSliderMediator, - nsIDOMEventListener) +NS_IMPL_ISUPPORTS(nsSliderMediator, + nsIDOMEventListener) diff --git a/layout/xul/base/src/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index 49aa6d156..79fb3867a 100644 --- a/layout/xul/base/src/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -20,7 +20,7 @@ class nsSliderFrame; nsIFrame* NS_NewSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -class nsSliderMediator : public nsIDOMEventListener +class nsSliderMediator final : public nsIDOMEventListener { public: @@ -28,75 +28,78 @@ public: nsSliderFrame* mSlider; - nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; } - virtual ~nsSliderMediator() {} + explicit nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; } virtual void SetSlider(nsSliderFrame* aSlider) { mSlider = aSlider; } - NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE; + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override; + +protected: + virtual ~nsSliderMediator() {} }; class nsSliderFrame : public nsBoxFrame { public: NS_DECL_FRAMEARENA_HELPERS + NS_DECL_QUERYFRAME_TARGET(nsSliderFrame) + NS_DECL_QUERYFRAME friend class nsSliderMediator; - nsSliderFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsSliderFrame(nsStyleContext* aContext); virtual ~nsSliderFrame(); -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("SliderFrame"), aResult); } #endif - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) override; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; // nsIFrame overrides - NS_IMETHOD AppendFrames(ChildListID aListID, - nsFrameList& aFrameList) MOZ_OVERRIDE; - - NS_IMETHOD InsertFrames(ChildListID aListID, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList) MOZ_OVERRIDE; - - NS_IMETHOD RemoveFrame(ChildListID aListID, - nsIFrame* aOldFrame) MOZ_OVERRIDE; - - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* asPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* asPrevInFlow) override; - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - NS_IMETHOD SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) MOZ_OVERRIDE; + virtual nsIAtom* GetType() const override; - virtual nsIAtom* GetType() const MOZ_OVERRIDE; + // nsContainerFrame overrides + virtual void SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) override; + virtual void AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) override; + virtual void InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) override; + virtual void RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) override; nsresult StartDrag(nsIDOMEvent* aEvent); + nsresult StopDrag(); static int32_t GetCurrentPosition(nsIContent* content); static int32_t GetMinPosition(nsIContent* content); @@ -107,29 +110,35 @@ public: void EnsureOrient(); NS_IMETHOD HandlePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus, - bool aControlHeld) MOZ_OVERRIDE { return NS_OK; } + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, + bool aControlHeld) override + { + return NS_OK; + } NS_IMETHOD HandleDrag(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE { return NS_OK; } + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override + { + return NS_OK; + } NS_IMETHOD HandleRelease(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; private: bool GetScrollToClick(); nsIFrame* GetScrollbar(); - bool ShouldScrollForEvent(nsGUIEvent* aEvent); - bool ShouldScrollToClickForEvent(nsGUIEvent* aEvent); - bool IsEventOverThumb(nsGUIEvent* aEvent); + bool ShouldScrollForEvent(mozilla::WidgetGUIEvent* aEvent); + bool ShouldScrollToClickForEvent(mozilla::WidgetGUIEvent* aEvent); + bool IsEventOverThumb(mozilla::WidgetGUIEvent* aEvent); void PageUpDown(nscoord change); void SetCurrentThumbPosition(nsIContent* aScrollbar, nscoord aNewPos, bool aIsSmooth, @@ -154,6 +163,7 @@ private: static void Notify(void* aData) { (static_cast<nsSliderFrame*>(aData))->Notify(); } + void PageScroll(nscoord aChange); nsPoint mDestinationPoint; nsRefPtr<nsSliderMediator> mMediator; @@ -167,6 +177,8 @@ private: nscoord mChange; + bool mDragFinished; + // true if an attribute change has been caused by the user manipulating the // slider. This allows notifications to tell how a slider's current position // was changed. diff --git a/layout/xul/base/src/nsSplitterFrame.cpp b/layout/xul/nsSplitterFrame.cpp index 8d3659d61..47c0168d9 100644 --- a/layout/xul/base/src/nsSplitterFrame.cpp +++ b/layout/xul/nsSplitterFrame.cpp @@ -17,7 +17,7 @@ #include "nsPresContext.h" #include "nsRenderingContext.h" #include "nsIDocument.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsScrollbarButtonFrame.h" #include "nsIDOMEventListener.h" #include "nsIDOMMouseEvent.h" @@ -28,7 +28,6 @@ #include "nsBoxLayoutState.h" #include "nsIServiceManager.h" #include "nsContainerFrame.h" -#include "nsGUIEvent.h" #include "nsAutoPtr.h" #include "nsContentCID.h" #include "nsStyleSet.h" @@ -36,6 +35,9 @@ #include "nsDisplayList.h" #include "nsContentUtils.h" #include "mozilla/dom/Element.h" +#include "mozilla/MouseEvents.h" + +using namespace mozilla; class nsSplitterInfo { public: @@ -48,19 +50,21 @@ public: int32_t index; }; -class nsSplitterFrameInner : public nsIDOMEventListener +class nsSplitterFrameInner final : public nsIDOMEventListener { +protected: + virtual ~nsSplitterFrameInner(); + public: NS_DECL_ISUPPORTS NS_DECL_NSIDOMEVENTLISTENER - nsSplitterFrameInner(nsSplitterFrame* aSplitter) + explicit nsSplitterFrameInner(nsSplitterFrame* aSplitter) { mOuter = aSplitter; mPressed = false; } - virtual ~nsSplitterFrameInner(); void Disconnect() { mOuter = nullptr; } @@ -68,8 +72,8 @@ public: nsresult MouseUp(nsIDOMEvent* aMouseEvent); nsresult MouseMove(nsIDOMEvent* aMouseEvent); - void MouseDrag(nsPresContext* aPresContext, nsGUIEvent* aEvent); - void MouseUp(nsPresContext* aPresContext, nsGUIEvent* aEvent); + void MouseDrag(nsPresContext* aPresContext, WidgetGUIEvent* aEvent); + void MouseUp(nsPresContext* aPresContext, WidgetGUIEvent* aEvent); void AdjustChildren(nsPresContext* aPresContext); void AdjustChildren(nsPresContext* aPresContext, nsSplitterInfo* aChildInfos, int32_t aCount, bool aIsHorizontal); @@ -122,7 +126,7 @@ public: }; -NS_IMPL_ISUPPORTS1(nsSplitterFrameInner, nsIDOMEventListener) +NS_IMPL_ISUPPORTS(nsSplitterFrameInner, nsIDOMEventListener) nsSplitterFrameInner::ResizeType nsSplitterFrameInner::GetResizeBefore() @@ -194,13 +198,13 @@ nsSplitterFrameInner::GetState() nsIFrame* NS_NewSplitterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsSplitterFrame(aPresShell, aContext); + return new (aPresShell) nsSplitterFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsSplitterFrame) -nsSplitterFrame::nsSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) -: nsBoxFrame(aPresShell, aContext), +nsSplitterFrame::nsSplitterFrame(nsStyleContext* aContext) +: nsBoxFrame(aContext), mInner(0) { } @@ -218,7 +222,7 @@ nsSplitterFrame::DestroyFrom(nsIFrame* aDestructRoot) } -NS_IMETHODIMP +nsresult nsSplitterFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) { @@ -234,7 +238,7 @@ nsSplitterFrame::GetCursor(const nsPoint& aPoint, */ } -NS_IMETHODIMP +nsresult nsSplitterFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -260,9 +264,9 @@ nsSplitterFrame::AttributeChanged(int32_t aNameSpaceID, * Initialize us. If we are in a box get our alignment so we know what direction we are */ void -nsSplitterFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsSplitterFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { MOZ_ASSERT(!mInner); mInner = new nsSplitterFrameInner(this); @@ -303,7 +307,7 @@ nsSplitterFrame::DoLayout(nsBoxLayoutState& aState) { if (GetStateBits() & NS_FRAME_FIRST_REFLOW) { - mInner->mParentBox = GetParentBox(); + mInner->mParentBox = nsBox::GetParentBox(this); mInner->UpdateState(); } @@ -314,7 +318,7 @@ nsSplitterFrame::DoLayout(nsBoxLayoutState& aState) void nsSplitterFrame::GetInitialOrientation(bool& aIsHorizontal) { - nsIFrame* box = GetParentBox(); + nsIFrame* box = nsBox::GetParentBox(this); if (box) { aIsHorizontal = !box->IsHorizontal(); } @@ -324,16 +328,16 @@ nsSplitterFrame::GetInitialOrientation(bool& aIsHorizontal) NS_IMETHODIMP nsSplitterFrame::HandlePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { return NS_OK; } NS_IMETHODIMP nsSplitterFrame::HandleMultiplePress(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, bool aControlHeld) { return NS_OK; @@ -341,16 +345,16 @@ nsSplitterFrame::HandleMultiplePress(nsPresContext* aPresContext, NS_IMETHODIMP nsSplitterFrame::HandleDrag(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { return NS_OK; } NS_IMETHODIMP nsSplitterFrame::HandleRelease(nsPresContext* aPresContext, - nsGUIEvent * aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { return NS_OK; } @@ -372,10 +376,10 @@ nsSplitterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } -NS_IMETHODIMP -nsSplitterFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +nsresult +nsSplitterFrame::HandleEvent(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -390,9 +394,7 @@ nsSplitterFrame::HandleEvent(nsPresContext* aPresContext, break; case NS_MOUSE_BUTTON_UP: - if (aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == - nsMouseEvent::eLeftButton) { + if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { mInner->MouseUp(aPresContext, aEvent); } break; @@ -403,7 +405,8 @@ nsSplitterFrame::HandleEvent(nsPresContext* aPresContext, } void -nsSplitterFrameInner::MouseUp(nsPresContext* aPresContext, nsGUIEvent* aEvent) +nsSplitterFrameInner::MouseUp(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent) { if (mDragging && mOuter) { AdjustChildren(aPresContext); @@ -435,7 +438,8 @@ nsSplitterFrameInner::MouseUp(nsPresContext* aPresContext, nsGUIEvent* aEvent) } void -nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext, nsGUIEvent* aEvent) +nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext, + WidgetGUIEvent* aEvent) { if (mDragging && mOuter) { @@ -600,7 +604,7 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) if (!mouseEvent) return NS_OK; - uint16_t button = 0; + int16_t button = 0; mouseEvent->GetButton(&button); // only if left button @@ -612,7 +616,7 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) nsGkAtoms::_true, eCaseMatters)) return NS_OK; - mParentBox = mOuter->GetParentBox(); + mParentBox = nsBox::GetParentBox(mOuter); if (!mParentBox) return NS_OK; @@ -630,10 +634,9 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) if (childIndex == childCount - 1 && GetResizeAfter() != Grow) return NS_OK; - nsRefPtr<nsRenderingContext> rc = - outerPresContext->PresShell()->GetReferenceRenderingContext(); - NS_ENSURE_TRUE(rc, NS_ERROR_FAILURE); - nsBoxLayoutState state(outerPresContext, rc); + nsRenderingContext rc( + outerPresContext->PresShell()->CreateReferenceRenderingContext()); + nsBoxLayoutState state(outerPresContext, &rc); mCurrentPos = 0; mPressed = true; @@ -655,7 +658,7 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) mChildInfosBeforeCount = 0; mChildInfosAfterCount = 0; - nsIFrame* childBox = mParentBox->GetChildBox(); + nsIFrame* childBox = nsBox::GetChildBox(mParentBox); while (nullptr != childBox) { @@ -710,7 +713,7 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) } } - childBox = childBox->GetNextBox(); + childBox = nsBox::GetNextBox(childBox); count++; } @@ -898,13 +901,13 @@ nsSplitterFrameInner::AdjustChildren(nsPresContext* aPresContext) static nsIFrame* GetChildBoxForContent(nsIFrame* aParentBox, nsIContent* aContent) { - nsIFrame* childBox = aParentBox->GetChildBox(); + nsIFrame* childBox = nsBox::GetChildBox(aParentBox); while (nullptr != childBox) { if (childBox->GetContent() == aContent) { return childBox; } - childBox = childBox->GetNextBox(); + childBox = nsBox::GetNextBox(childBox); } return nullptr; } @@ -919,11 +922,11 @@ nsSplitterFrameInner::AdjustChildren(nsPresContext* aPresContext, nsSplitterInfo nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); // first set all the widths. - nsIFrame* child = mOuter->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(mOuter); while(child) { SetPreferredSize(state, child, onePixel, aIsHorizontal, nullptr); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } // now set our changed widths. diff --git a/layout/xul/nsSplitterFrame.h b/layout/xul/nsSplitterFrame.h new file mode 100644 index 000000000..22f708a76 --- /dev/null +++ b/layout/xul/nsSplitterFrame.h @@ -0,0 +1,83 @@ +/* -*- 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/. */ + +// +// nsSplitterFrame +// + +#ifndef nsSplitterFrame_h__ +#define nsSplitterFrame_h__ + + +#include "mozilla/Attributes.h" +#include "nsBoxFrame.h" + +class nsSplitterFrameInner; + +nsIFrame* NS_NewSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + +class nsSplitterFrame : public nsBoxFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + explicit nsSplitterFrame(nsStyleContext* aContext); + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { + return MakeFrameName(NS_LITERAL_STRING("SplitterFrame"), aResult); + } +#endif + + // nsIFrame overrides + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; + + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + + virtual nsresult GetCursor(const nsPoint& aPoint, + nsIFrame::Cursor& aCursor) override; + + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; + + NS_IMETHOD HandlePress(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus, + bool aControlHeld) override; + + NS_IMETHOD HandleDrag(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + NS_IMETHOD HandleRelease(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override; + + virtual void GetInitialOrientation(bool& aIsHorizontal) override; + +private: + + friend class nsSplitterFrameInner; + nsSplitterFrameInner* mInner; + +}; // class nsSplitterFrame + +#endif diff --git a/layout/xul/base/src/nsSprocketLayout.cpp b/layout/xul/nsSprocketLayout.cpp index 3c4224083..8fd67b2ad 100644 --- a/layout/xul/base/src/nsSprocketLayout.cpp +++ b/layout/xul/nsSprocketLayout.cpp @@ -173,11 +173,11 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) // See if we are collapsed. If we are, then simply iterate over all our // children and give them a rect of 0 width and height. if (aBox->IsCollapsed()) { - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while(child) { nsBoxFrame::LayoutChildAt(aState, child, nsRect(0,0,0,0)); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } return NS_OK; } @@ -203,7 +203,7 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) // The frame state contains cached knowledge about our box, such as our orientation // and direction. - nsFrameState frameState = 0; + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); // Build a list of our children's desired sizes and computed sizes @@ -302,7 +302,7 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) nsComputedBoxSize* childComputedBoxSize = computedBoxSizes; nsBoxSize* childBoxSize = boxSizes; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); int32_t count = 0; while (child || (childBoxSize && childBoxSize->bogus)) @@ -556,7 +556,7 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) childComputedBoxSize = childComputedBoxSize->next; childBoxSize = childBoxSize->next; - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); count++; } @@ -611,7 +611,7 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) // we really did have to change the positions because of packing (typically for 'center' // or 'end' pack values). if (x != origX || y != origY) { - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); // reposition all our children while (child) @@ -620,7 +620,7 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) childRect.x += (x - origX); childRect.y += (y - origY); child->SetBounds(aState, childRect); - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } } @@ -642,7 +642,7 @@ nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsB nscoord biggestMinWidth = 0; nscoord smallestMaxWidth = NS_INTRINSICSIZE; - nsFrameState frameState = 0; + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); //if (frameState & NS_STATE_CURRENTLY_IN_DEBUG) @@ -668,7 +668,7 @@ nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsB // so we can just optimize it out this way. // set flexes - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); aFlexes = 0; nsBoxSize* currentBox = nullptr; @@ -705,12 +705,12 @@ nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsB if (flex > 0) aFlexes++; - child = child->GetNextBox(); + child = GetNextBox(child); } #endif // get pref, min, max - child = aBox->GetChildBox(); + child = nsBox::GetChildBox(aBox); currentBox = aBoxSizes; nsBoxSize* last = nullptr; @@ -829,7 +829,7 @@ nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsB currentBox->collapsed = collapsed; aFlexes += currentBox->flex; - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); last = currentBox; currentBox = currentBox->next; @@ -888,7 +888,7 @@ nsSprocketLayout::ComputeChildsNextPosition(nsIFrame* aBox, { // Get the position along the box axis for the child. // The out-of-axis position is not set. - nsFrameState frameState = 0; + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); if (IsHorizontal(aBox)) { @@ -911,7 +911,7 @@ void nsSprocketLayout::AlignChildren(nsIFrame* aBox, nsBoxLayoutState& aState) { - nsFrameState frameState = 0; + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); bool isHorizontal = (frameState & NS_STATE_IS_HORIZONTAL) != 0; nsRect clientRect; @@ -936,7 +936,7 @@ nsSprocketLayout::AlignChildren(nsIFrame* aBox, halign = aBox->GetHAlign(); } - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { nsMargin margin; @@ -997,7 +997,7 @@ nsSprocketLayout::AlignChildren(nsIFrame* aBox, child->SetBounds(aState, childRect); } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } } @@ -1305,8 +1305,8 @@ nsSprocketLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) // run through all the children and get their min, max, and preferred sizes // return us the size of the box - nsIFrame* child = aBox->GetChildBox(); - nsFrameState frameState = 0; + nsIFrame* child = nsBox::GetChildBox(aBox); + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE); int32_t count = 0; @@ -1334,7 +1334,7 @@ nsSprocketLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) count++; } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } if (isEqual) { @@ -1362,8 +1362,8 @@ nsSprocketLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) // run through all the children and get their min, max, and preferred sizes // return us the size of the box - nsIFrame* child = aBox->GetChildBox(); - nsFrameState frameState = 0; + nsIFrame* child = nsBox::GetChildBox(aBox); + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE); int32_t count = 0; @@ -1402,7 +1402,7 @@ nsSprocketLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) count++; } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } @@ -1431,8 +1431,8 @@ nsSprocketLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) // run through all the children and get their min, max, and preferred sizes // return us the size of the box - nsIFrame* child = aBox->GetChildBox(); - nsFrameState frameState = 0; + nsIFrame* child = nsBox::GetChildBox(aBox); + nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE); int32_t count = 0; @@ -1462,7 +1462,7 @@ nsSprocketLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) count++; } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } if (isEqual) { @@ -1496,7 +1496,7 @@ nsSprocketLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) // run through all the children and get their min, max, and preferred sizes // return us the size of the box - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { @@ -1520,7 +1520,7 @@ nsSprocketLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) } //} - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } nsMargin borderPadding; diff --git a/layout/xul/base/src/nsSprocketLayout.h b/layout/xul/nsSprocketLayout.h index 41e515484..9b9d108e1 100644 --- a/layout/xul/base/src/nsSprocketLayout.h +++ b/layout/xul/nsSprocketLayout.h @@ -68,12 +68,12 @@ public: friend nsresult NS_NewSprocketLayout(nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout>& aNewLayout); static void Shutdown(); - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) override; - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; nsSprocketLayout(); diff --git a/layout/xul/base/src/nsStackFrame.cpp b/layout/xul/nsStackFrame.cpp index bd34b6fc7..3ef80e401 100644 --- a/layout/xul/base/src/nsStackFrame.cpp +++ b/layout/xul/nsStackFrame.cpp @@ -24,16 +24,16 @@ nsIFrame* NS_NewStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsStackFrame(aPresShell, aContext); + return new (aPresShell) nsStackFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsStackFrame) -nsStackFrame::nsStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext): - nsBoxFrame(aPresShell, aContext) +nsStackFrame::nsStackFrame(nsStyleContext* aContext): + nsBoxFrame(aContext) { nsCOMPtr<nsBoxLayout> layout; - NS_NewStackLayout(aPresShell, layout); + NS_NewStackLayout(PresContext()->PresShell(), layout); SetLayoutManager(layout); } diff --git a/layout/xul/base/src/nsStackFrame.h b/layout/xul/nsStackFrame.h index 80917d6f9..b90a16b21 100644 --- a/layout/xul/base/src/nsStackFrame.h +++ b/layout/xul/nsStackFrame.h @@ -25,8 +25,8 @@ public: friend nsIFrame* NS_NewStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("Stack"), aResult); } @@ -34,10 +34,10 @@ public: virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; protected: - nsStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + explicit nsStackFrame(nsStyleContext* aContext); }; // class nsStackFrame diff --git a/layout/xul/base/src/nsStackLayout.cpp b/layout/xul/nsStackLayout.cpp index 764fea461..b4f243cd3 100644 --- a/layout/xul/base/src/nsStackLayout.cpp +++ b/layout/xul/nsStackLayout.cpp @@ -17,7 +17,7 @@ #include "nsBoxFrame.h" #include "nsGkAtoms.h" #include "nsIContent.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" using namespace mozilla; @@ -63,7 +63,7 @@ nsStackLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) { nsSize prefSize (0, 0); - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { if (child->StyleXUL()->mStretchStack) { nsSize pref = child->GetPrefSize(aState); @@ -76,7 +76,7 @@ nsStackLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) AddLargestSize(prefSize, pref); } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } AddBorderAndPadding(aBox, prefSize); @@ -89,7 +89,7 @@ nsStackLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) { nsSize minSize (0, 0); - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { if (child->StyleXUL()->mStretchStack) { nsSize min = child->GetMinSize(aState); @@ -102,7 +102,7 @@ nsStackLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) AddLargestSize(minSize, min); } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } AddBorderAndPadding(aBox, minSize); @@ -115,7 +115,7 @@ nsStackLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) { nsSize maxSize (NS_INTRINSICSIZE, NS_INTRINSICSIZE); - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { if (child->StyleXUL()->mStretchStack) { nsSize min = child->GetMinSize(aState); @@ -131,7 +131,7 @@ nsStackLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) AddSmallestSize(maxSize, max); } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } AddBorderAndPadding(aBox, maxSize); @@ -145,7 +145,7 @@ nsStackLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) { nscoord vAscent = 0; - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); while (child) { nscoord ascent = child->GetBoxAscent(aState); nsMargin margin; @@ -154,7 +154,7 @@ nsStackLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) if (ascent > vAscent) vAscent = ascent; - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } return vAscent; @@ -260,7 +260,7 @@ nsStackLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) bool grow; do { - nsIFrame* child = aBox->GetChildBox(); + nsIFrame* child = nsBox::GetChildBox(aBox); grow = false; while (child) @@ -357,7 +357,7 @@ nsStackLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) } } - child = child->GetNextBox(); + child = nsBox::GetNextBox(child); } } while (grow); diff --git a/layout/xul/base/src/nsStackLayout.h b/layout/xul/nsStackLayout.h index e5d2b1edb..d45e2f823 100644 --- a/layout/xul/base/src/nsStackLayout.h +++ b/layout/xul/nsStackLayout.h @@ -32,12 +32,12 @@ public: nsStackLayout(); - NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) MOZ_OVERRIDE; + NS_IMETHOD Layout(nsIFrame* aBox, nsBoxLayoutState& aState) override; - virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; // get the child offsets for aChild and set them in aMargin. Returns a // bitfield mask of the SPECIFIED_LEFT, SPECIFIED_RIGHT, SPECIFIED_TOP and diff --git a/layout/xul/base/src/nsTextBoxFrame.cpp b/layout/xul/nsTextBoxFrame.cpp index 8f745c678..e3c52bdc9 100644 --- a/layout/xul/base/src/nsTextBoxFrame.cpp +++ b/layout/xul/nsTextBoxFrame.cpp @@ -1,10 +1,14 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- 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/. */ #include "nsTextBoxFrame.h" +#include "gfx2DGlue.h" +#include "gfxUtils.h" +#include "mozilla/gfx/2D.h" +#include "nsFontMetrics.h" #include "nsReadableUtils.h" #include "nsCOMPtr.h" #include "nsGkAtoms.h" @@ -12,18 +16,17 @@ #include "nsRenderingContext.h" #include "nsStyleContext.h" #include "nsIContent.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsBoxLayoutState.h" #include "nsMenuBarListener.h" #include "nsXPIDLString.h" #include "nsIServiceManager.h" #include "nsIDOMElement.h" #include "nsIDOMXULLabelElement.h" -#include "nsEventStateManager.h" +#include "mozilla/EventStateManager.h" #include "nsITheme.h" #include "nsUnicharUtils.h" #include "nsContentUtils.h" -#include "nsCxPusher.h" #include "nsDisplayList.h" #include "nsCSSRendering.h" #include "nsIReflowCallback.h" @@ -36,12 +39,11 @@ #include "nsAccessibilityService.h" #endif -#ifdef IBMBIDI #include "nsBidiUtils.h" #include "nsBidiPresUtils.h" -#endif // IBMBIDI using namespace mozilla; +using namespace mozilla::gfx; class nsAccessKeyInfo { @@ -59,7 +61,7 @@ bool nsTextBoxFrame::gInsertSeparatorPrefInitialized = false; nsIFrame* NS_NewTextBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsTextBoxFrame (aPresShell, aContext); + return new (aPresShell) nsTextBoxFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsTextBoxFrame) @@ -68,7 +70,7 @@ NS_QUERYFRAME_HEAD(nsTextBoxFrame) NS_QUERYFRAME_ENTRY(nsTextBoxFrame) NS_QUERYFRAME_TAIL_INHERITING(nsTextBoxFrameSuper) -NS_IMETHODIMP +nsresult nsTextBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -95,11 +97,11 @@ nsTextBoxFrame::AttributeChanged(int32_t aNameSpaceID, return NS_OK; } -nsTextBoxFrame::nsTextBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): - nsLeafBoxFrame(aShell, aContext), mAccessKeyInfo(nullptr), mCropType(CropRight), +nsTextBoxFrame::nsTextBoxFrame(nsStyleContext* aContext): + nsLeafBoxFrame(aContext), mAccessKeyInfo(nullptr), mCropType(CropRight), mNeedsReflowCallback(false) { - MarkIntrinsicWidthsDirty(); + MarkIntrinsicISizesDirty(); } nsTextBoxFrame::~nsTextBoxFrame() @@ -109,9 +111,9 @@ nsTextBoxFrame::~nsTextBoxFrame() void -nsTextBoxFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsTextBoxFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsTextBoxFrameSuper::Init(aContent, aParent, aPrevInFlow); @@ -140,7 +142,7 @@ nsTextBoxFrame::AlwaysAppendAccessKey() const char* prefName = "intl.menuitems.alwaysappendaccesskeys"; nsAdoptingString val = Preferences::GetLocalizedString(prefName); - gAlwaysAppendAccessKey = val.Equals(NS_LITERAL_STRING("true")); + gAlwaysAppendAccessKey = val.EqualsLiteral("true"); } return gAlwaysAppendAccessKey; } @@ -159,14 +161,14 @@ nsTextBoxFrame::InsertSeparatorBeforeAccessKey() return gInsertSeparatorBeforeAccessKey; } -class nsAsyncAccesskeyUpdate MOZ_FINAL : public nsIReflowCallback +class nsAsyncAccesskeyUpdate final : public nsIReflowCallback { public: - nsAsyncAccesskeyUpdate(nsIFrame* aFrame) : mWeakFrame(aFrame) + explicit nsAsyncAccesskeyUpdate(nsIFrame* aFrame) : mWeakFrame(aFrame) { } - virtual bool ReflowFinished() + virtual bool ReflowFinished() override { bool shouldFlush = false; nsTextBoxFrame* frame = @@ -178,7 +180,7 @@ public: return shouldFlush; } - virtual void ReflowCallbackCanceled() + virtual void ReflowCallbackCanceled() override { delete this; } @@ -194,15 +196,8 @@ nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis) NS_ENSURE_TRUE(aWeakThis.IsAlive(), false); if (labelElement) { // Accesskey may be stored on control. - // Because this method is called by the reflow callback, current context - // may not be the right one. Pushing the context of mContent so that - // if nsIDOMXULLabelElement is implemented in XBL, we don't get a - // security exception. - nsCxPusher cx; - if (cx.Push(mContent)) { - labelElement->GetAccessKey(accesskey); - NS_ENSURE_TRUE(aWeakThis.IsAlive(), false); - } + labelElement->GetAccessKey(accesskey); + NS_ENSURE_TRUE(aWeakThis.IsAlive(), false); } else { mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accesskey); @@ -210,7 +205,7 @@ nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis) if (!accesskey.Equals(mAccessKey)) { // Need to get clean mTitle. - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle); + RecomputeTitle(); mAccessKey = accesskey; UpdateAccessTitle(); PresContext()->PresShell()-> @@ -260,7 +255,7 @@ nsTextBoxFrame::UpdateAttributes(nsIAtom* aAttribute, } if (aAttribute == nullptr || aAttribute == nsGkAtoms::value) { - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle); + RecomputeTitle(); doUpdateTitle = true; } @@ -293,13 +288,16 @@ public: #endif virtual void Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); + nsRenderingContext* aCtx) override; + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, + bool* aSnap) override; NS_DISPLAY_DECL_NAME("XULTextBox", TYPE_XUL_TEXT_BOX) - virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override; - virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; } + virtual void DisableComponentAlpha() override { + mDisableSubpixelAA = true; + } void PaintTextToContext(nsRenderingContext* aCtx, nsPoint aOffset, @@ -392,6 +390,8 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, const nscolor* aOverrideColor) { nsPresContext* presContext = PresContext(); + int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); // paint the title nscolor overColor; @@ -406,6 +406,8 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, // A mask of all possible decorations. uint8_t decorMask = NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK; + bool vertical = GetWritingMode().IsVertical(); + nsIFrame* f = this; do { // find decoration colors nsStyleContext* context = f->StyleContext(); @@ -466,7 +468,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, presContext->AppUnitsToGfxUnits(aTextRect.y)); gfxFloat width = presContext->AppUnitsToGfxUnits(aTextRect.width); gfxFloat ascentPixel = presContext->AppUnitsToGfxUnits(ascent); - gfxFloat xInFrame = PresContext()->AppUnitsToGfxUnits(mTextDrawRect.x); + Float xInFrame = Float(PresContext()->AppUnitsToGfxUnits(mTextDrawRect.x)); gfxRect dirtyRect(presContext->AppUnitsToGfxUnits(aDirtyRect)); // Underlines are drawn before overlines, and both before the text @@ -481,45 +483,46 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size); if ((decorations & NS_FONT_DECORATION_UNDERLINE) && underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) { - nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, underColor, + nsCSSRendering::PaintDecorationLine(this, *drawTarget, + ToRect(dirtyRect), underColor, pt, xInFrame, gfxSize(width, sizePixel), ascentPixel, offsetPixel, - NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, underStyle); + NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, underStyle, + vertical); } if ((decorations & NS_FONT_DECORATION_OVERLINE) && overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) { - nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, overColor, + nsCSSRendering::PaintDecorationLine(this, *drawTarget, + ToRect(dirtyRect), overColor, pt, xInFrame, gfxSize(width, sizePixel), ascentPixel, ascentPixel, - NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, overStyle); + NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, overStyle, + vertical); } } - nsRefPtr<nsRenderingContext> refContext = - PresContext()->PresShell()->GetReferenceRenderingContext(); - - aRenderingContext.SetFont(fontMet); - refContext->SetFont(fontMet); + nsRenderingContext refContext( + PresContext()->PresShell()->CreateReferenceRenderingContext()); - CalculateUnderline(*refContext); + CalculateUnderline(refContext, *fontMet); - aRenderingContext.SetColor(aOverrideColor ? *aOverrideColor : StyleColor()->mColor); + nscolor c = aOverrideColor ? *aOverrideColor : StyleColor()->mColor; + ColorPattern color(ToDeviceColor(c)); + aRenderingContext.ThebesContext()->SetColor(c); -#ifdef IBMBIDI nsresult rv = NS_ERROR_FAILURE; if (mState & NS_FRAME_IS_BIDI) { presContext->SetBidiEnabled(); - const nsStyleVisibility* vis = StyleVisibility(); - nsBidiDirection direction = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? NSBIDI_RTL : NSBIDI_LTR; + nsBidiLevel level = nsBidiPresUtils::BidiLevelFromStyle(StyleContext()); if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { // We let the RenderText function calculate the mnemonic's // underline position for us. nsBidiPositionResolve posResolve; posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex; - rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, + rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level, presContext, aRenderingContext, - *refContext, + refContext, *fontMet, aTextRect.x, baseline, &posResolve, 1); @@ -528,39 +531,41 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, } else { - rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, + rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level, presContext, aRenderingContext, - *refContext, + refContext, *fontMet, aTextRect.x, baseline); } } - if (NS_FAILED(rv) ) -#endif // IBMBIDI - { - aRenderingContext.SetTextRunRTL(false); + if (NS_FAILED(rv)) { + fontMet->SetTextRunRTL(false); if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { // In the simple (non-BiDi) case, we calculate the mnemonic's // underline position by getting the text metric. // XXX are attribute values always two byte? if (mAccessKeyInfo->mAccesskeyIndex > 0) - mAccessKeyInfo->mBeforeWidth = - refContext->GetWidth(mCroppedTitle.get(), - mAccessKeyInfo->mAccesskeyIndex); + mAccessKeyInfo->mBeforeWidth = nsLayoutUtils:: + AppUnitWidthOfString(mCroppedTitle.get(), + mAccessKeyInfo->mAccesskeyIndex, + *fontMet, refContext); else mAccessKeyInfo->mBeforeWidth = 0; } fontMet->DrawString(mCroppedTitle.get(), mCroppedTitle.Length(), aTextRect.x, baseline, &aRenderingContext, - refContext.get()); + &refContext); } if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { - aRenderingContext.FillRect(aTextRect.x + mAccessKeyInfo->mBeforeWidth, - aTextRect.y + mAccessKeyInfo->mAccessOffset, - mAccessKeyInfo->mAccessWidth, - mAccessKeyInfo->mAccessUnderlineSize); + nsRect r(aTextRect.x + mAccessKeyInfo->mBeforeWidth, + aTextRect.y + mAccessKeyInfo->mAccessOffset, + mAccessKeyInfo->mAccessWidth, + mAccessKeyInfo->mAccessUnderlineSize); + Rect devPxRect = + NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget); + drawTarget->FillRect(devPxRect, color); } // Strikeout is drawn on top of the text, per @@ -570,29 +575,30 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, fontMet->GetStrikeout(offset, size); gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset); gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size); - nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, strikeColor, + nsCSSRendering::PaintDecorationLine(this, *drawTarget, ToRect(dirtyRect), + strikeColor, pt, xInFrame, gfxSize(width, sizePixel), ascentPixel, offsetPixel, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, - strikeStyle); + strikeStyle, vertical); } } void -nsTextBoxFrame::CalculateUnderline(nsRenderingContext& aRenderingContext) +nsTextBoxFrame::CalculateUnderline(nsRenderingContext& aRenderingContext, + nsFontMetrics& aFontMetrics) { if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { // Calculate all fields of mAccessKeyInfo which // are the same for both BiDi and non-BiDi frames. - const PRUnichar *titleString = mCroppedTitle.get(); - aRenderingContext.SetTextRunRTL(false); - mAccessKeyInfo->mAccessWidth = - aRenderingContext.GetWidth(titleString[mAccessKeyInfo-> - mAccesskeyIndex]); + const char16_t *titleString = mCroppedTitle.get(); + aFontMetrics.SetTextRunRTL(false); + mAccessKeyInfo->mAccessWidth = nsLayoutUtils:: + AppUnitWidthOfString(titleString[mAccessKeyInfo->mAccesskeyIndex], + aFontMetrics, aRenderingContext); nscoord offset, baseline; - nsFontMetrics* metrics = aRenderingContext.FontMetrics(); - metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize); - baseline = metrics->MaxAscent(); + aFontMetrics.GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize); + baseline = aFontMetrics.MaxAscent(); mAccessKeyInfo->mAccessOffset = baseline - offset; } } @@ -609,19 +615,16 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, nsRefPtr<nsFontMetrics> fm; nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); - aRenderingContext.SetFont(fm); // see if the text will completely fit in the width given - nscoord titleWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, - mTitle.get(), mTitle.Length()); - + nscoord titleWidth = + nsLayoutUtils::AppUnitWidthOfStringBidi(mTitle, this, *fm, + aRenderingContext); if (titleWidth <= aWidth) { mCroppedTitle = mTitle; -#ifdef IBMBIDI if (HasRTLChars(mTitle)) { mState |= NS_FRAME_IS_BIDI; } -#endif // IBMBIDI return titleWidth; // fits, done. } @@ -631,8 +634,9 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, // see if the width is even smaller than the ellipsis // if so, clear the text (XXX set as many '.' as we can?). - aRenderingContext.SetTextRunRTL(false); - titleWidth = aRenderingContext.GetWidth(kEllipsis); + fm->SetTextRunRTL(false); + titleWidth = nsLayoutUtils::AppUnitWidthOfString(kEllipsis, *fm, + aRenderingContext); if (titleWidth > aWidth) { mCroppedTitle.SetLength(0); @@ -658,18 +662,17 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, int length = mTitle.Length(); int i; for (i = 0; i < length; ++i) { - PRUnichar ch = mTitle.CharAt(i); + char16_t ch = mTitle.CharAt(i); // still in LTR mode - cwidth = aRenderingContext.GetWidth(ch); + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, *fm, + aRenderingContext); if (twidth + cwidth > aWidth) break; twidth += cwidth; -#ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch) ) { mState |= NS_FRAME_IS_BIDI; } -#endif // IBMBIDI } if (i == 0) @@ -689,17 +692,16 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, int length = mTitle.Length(); int i; for (i=length-1; i >= 0; --i) { - PRUnichar ch = mTitle.CharAt(i); - cwidth = aRenderingContext.GetWidth(ch); + char16_t ch = mTitle.CharAt(i); + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, *fm, + aRenderingContext); if (twidth + cwidth > aWidth) break; twidth += cwidth; -#ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch) ) { mState |= NS_FRAME_IS_BIDI; } -#endif // IBMBIDI } if (i == length-1) @@ -714,8 +716,8 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, case CropCenter: { nscoord stringWidth = - nsLayoutUtils::GetStringWidth(this, &aRenderingContext, - mTitle.get(), mTitle.Length()); + nsLayoutUtils::AppUnitWidthOfStringBidi(mTitle, this, *fm, + aRenderingContext); if (stringWidth <= aWidth) { // the entire string will fit in the maximum width mCroppedTitle.Insert(mTitle, 0); @@ -725,42 +727,41 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, // determine how much of the string will fit in the max width nscoord charWidth = 0; nscoord totalWidth = 0; - PRUnichar ch; + char16_t ch; int leftPos, rightPos; nsAutoString leftString, rightString; rightPos = mTitle.Length() - 1; - aRenderingContext.SetTextRunRTL(false); + fm->SetTextRunRTL(false); for (leftPos = 0; leftPos <= rightPos;) { // look at the next character on the left end ch = mTitle.CharAt(leftPos); - charWidth = aRenderingContext.GetWidth(ch); + charWidth = nsLayoutUtils::AppUnitWidthOfString(ch, *fm, + aRenderingContext); totalWidth += charWidth; if (totalWidth > aWidth) // greater than the allowable width break; leftString.Insert(ch, leftString.Length()); -#ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch)) mState |= NS_FRAME_IS_BIDI; -#endif // look at the next character on the right end if (rightPos > leftPos) { // haven't looked at this character yet ch = mTitle.CharAt(rightPos); - charWidth = aRenderingContext.GetWidth(ch); + charWidth = + nsLayoutUtils::AppUnitWidthOfString(ch, *fm, + aRenderingContext); totalWidth += charWidth; if (totalWidth > aWidth) // greater than the allowable width break; rightString.Insert(ch, 0); -#ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch)) mState |= NS_FRAME_IS_BIDI; -#endif } // look at the next two characters @@ -773,8 +774,8 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, break; } - return nsLayoutUtils::GetStringWidth(this, &aRenderingContext, - mCroppedTitle.get(), mCroppedTitle.Length()); + return nsLayoutUtils::AppUnitWidthOfStringBidi(mCroppedTitle, this, *fm, + aRenderingContext); } #define OLD_ELLIPSIS NS_LITERAL_STRING("...") @@ -820,8 +821,8 @@ nsTextBoxFrame::UpdateAccessTitle() } else { // Try to check with // our default ellipsis (for non-localized addons) or ':' - const PRUnichar kLastChar = mTitle.Last(); - if (kLastChar == PRUnichar(0x2026) || kLastChar == PRUnichar(':')) + const char16_t kLastChar = mTitle.Last(); + if (kLastChar == char16_t(0x2026) || kLastChar == char16_t(':')) offset--; } @@ -884,6 +885,43 @@ nsTextBoxFrame::UpdateAccessIndex() } } +void +nsTextBoxFrame::RecomputeTitle() +{ + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle); + + // This doesn't handle language-specific uppercasing/lowercasing + // rules, unlike textruns. + uint8_t textTransform = StyleText()->mTextTransform; + if (textTransform == NS_STYLE_TEXT_TRANSFORM_UPPERCASE) { + ToUpperCase(mTitle); + } else if (textTransform == NS_STYLE_TEXT_TRANSFORM_LOWERCASE) { + ToLowerCase(mTitle); + } + // We can't handle NS_STYLE_TEXT_TRANSFORM_CAPITALIZE because we + // have no clue about word boundaries here. We also don't handle + // NS_STYLE_TEXT_TRANSFORM_FULLWIDTH. +} + +void +nsTextBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) +{ + if (!aOldStyleContext) { + // We're just being initialized + return; + } + + const nsStyleText* oldTextStyle = aOldStyleContext->PeekStyleText(); + // We should really have oldTextStyle here, since we asked for our + // nsStyleText during Init(), but if it's not there for some reason + // just assume the worst and recompute mTitle. + if (!oldTextStyle || + oldTextStyle->mTextTransform != StyleText()->mTextTransform) { + RecomputeTitle(); + UpdateAccessTitle(); + } +} + NS_IMETHODIMP nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState) { @@ -949,10 +987,10 @@ nsTextBoxFrame::ComputesOwnOverflowArea() } /* virtual */ void -nsTextBoxFrame::MarkIntrinsicWidthsDirty() +nsTextBoxFrame::MarkIntrinsicISizesDirty() { mNeedsRecalc = true; - nsTextBoxFrameSuper::MarkIntrinsicWidthsDirty(); + nsTextBoxFrameSuper::MarkIntrinsicISizesDirty(); } void @@ -964,10 +1002,9 @@ nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext, nsRefPtr<nsFontMetrics> fontMet; nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); aSize.height = fontMet->MaxHeight(); - aRenderingContext.SetFont(fontMet); aSize.width = - nsLayoutUtils::GetStringWidth(this, &aRenderingContext, - aString.get(), aString.Length()); + nsLayoutUtils::AppUnitWidthOfStringBidi(aString, this, *fontMet, + aRenderingContext); aAscent = fontMet->MaxAscent(); } @@ -1090,8 +1127,8 @@ nsTextBoxFrame::GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) return ascent; } -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsTextBoxFrame::GetFrameName(nsAString& aResult) const { MakeFrameName(NS_LITERAL_STRING("TextBox"), aResult); @@ -1129,7 +1166,7 @@ nsTextBoxFrame::RegUnregAccessKey(bool aDoReg) // With a valid PresContext we can get the ESM // and (un)register the access key - nsEventStateManager *esm = PresContext()->EventStateManager(); + EventStateManager* esm = PresContext()->EventStateManager(); uint32_t key = accessKey.First(); if (aDoReg) diff --git a/layout/xul/base/src/nsTextBoxFrame.h b/layout/xul/nsTextBoxFrame.h index d0286bcb7..db221571d 100644 --- a/layout/xul/base/src/nsTextBoxFrame.h +++ b/layout/xul/nsTextBoxFrame.h @@ -10,6 +10,7 @@ class nsAccessKeyInfo; class nsAsyncAccesskeyUpdate; +class nsFontMetrics; typedef nsLeafBoxFrame nsTextBoxFrameSuper; class nsTextBoxFrame : public nsTextBoxFrameSuper @@ -19,28 +20,28 @@ public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; - virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) override; + virtual void MarkIntrinsicISizesDirty() override; enum CroppingStyle { CropNone, CropLeft, CropRight, CropCenter }; friend nsIFrame* NS_NewTextBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* asPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* asPrevInFlow) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif void UpdateAttributes(nsIAtom* aAttribute, @@ -49,7 +50,7 @@ public: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; virtual ~nsTextBoxFrame(); @@ -60,10 +61,12 @@ public: nsRect GetComponentAlphaBounds(); - virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE; + virtual bool ComputesOwnOverflowArea() override; void GetCroppedTitle(nsString& aTitle) const { aTitle = mCroppedTitle; } + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; + protected: friend class nsAsyncAccesskeyUpdate; friend class nsDisplayXULTextBox; @@ -73,18 +76,23 @@ protected: void UpdateAccessTitle(); void UpdateAccessIndex(); + // Recompute our title, ignoring the access key but taking into + // account text-transform. + void RecomputeTitle(); + // REVIEW: SORRY! Couldn't resist devirtualizing these void LayoutTitle(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, const nsRect& aRect); - void CalculateUnderline(nsRenderingContext& aRenderingContext); + void CalculateUnderline(nsRenderingContext& aRenderingContext, + nsFontMetrics& aFontMetrics); void CalcTextSize(nsBoxLayoutState& aBoxLayoutState); void CalcDrawRect(nsRenderingContext &aRenderingContext); - nsTextBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext); + explicit nsTextBoxFrame(nsStyleContext* aContext); nscoord CalculateTitleForWidth(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, diff --git a/layout/xul/base/src/nsTitleBarFrame.cpp b/layout/xul/nsTitleBarFrame.cpp index 3b712c1f7..fea19176e 100644 --- a/layout/xul/base/src/nsTitleBarFrame.cpp +++ b/layout/xul/nsTitleBarFrame.cpp @@ -12,12 +12,13 @@ #include "nsIWidget.h" #include "nsMenuPopupFrame.h" #include "nsPresContext.h" -#include "nsIDocShellTreeItem.h" +#include "nsIDocShell.h" #include "nsPIDOMWindow.h" -#include "nsGUIEvent.h" -#include "nsEventDispatcher.h" #include "nsDisplayList.h" #include "nsContentUtils.h" +#include "mozilla/MouseEvents.h" + +using namespace mozilla; // // NS_NewTitleBarFrame @@ -27,13 +28,13 @@ nsIFrame* NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsTitleBarFrame(aPresShell, aContext); + return new (aPresShell) nsTitleBarFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame) -nsTitleBarFrame::nsTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) -:nsBoxFrame(aPresShell, aContext, false) +nsTitleBarFrame::nsTitleBarFrame(nsStyleContext* aContext) +:nsBoxFrame(aContext, false) { mTrackingMouseMove = false; UpdateMouseThrough(); @@ -53,10 +54,10 @@ nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } -NS_IMETHODIMP +nsresult nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) + WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -68,17 +69,11 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, switch (aEvent->message) { case NS_MOUSE_BUTTON_DOWN: { - if (aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == - nsMouseEvent::eLeftButton) - { + if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { // titlebar has no effect in non-chrome shells - nsCOMPtr<nsISupports> cont = aPresContext->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont); + nsCOMPtr<nsIDocShellTreeItem> dsti = aPresContext->GetDocShell(); if (dsti) { - int32_t type = -1; - if (NS_SUCCEEDED(dsti->GetItemType(&type)) && - type == nsIDocShellTreeItem::typeChrome) { + if (dsti->ItemType() == nsIDocShellTreeItem::typeChrome) { // we're tracking. mTrackingMouseMove = true; @@ -98,10 +93,8 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, case NS_MOUSE_BUTTON_UP: { - if(mTrackingMouseMove && aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast<nsMouseEvent*>(aEvent)->button == - nsMouseEvent::eLeftButton) - { + if (mTrackingMouseMove && + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { // we're done tracking. mTrackingMouseMove = false; @@ -117,7 +110,7 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, case NS_MOUSE_MOVE: { if(mTrackingMouseMove) { - nsIntPoint nsMoveBy = aEvent->refPoint - mLastPoint; + LayoutDeviceIntPoint nsMoveBy = aEvent->refPoint - mLastPoint; nsIFrame* parent = GetParent(); while (parent) { @@ -134,7 +127,10 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget(); nsIntRect bounds; widget->GetScreenBounds(bounds); - menuPopupFrame->MoveTo(bounds.x + nsMoveBy.x, bounds.y + nsMoveBy.y, false); + + int32_t newx = aPresContext->DevPixelsToIntCSSPixels(bounds.x + nsMoveBy.x); + int32_t newy = aPresContext->DevPixelsToIntCSSPixels(bounds.y + nsMoveBy.y); + menuPopupFrame->MoveTo(newx, newy, false); } else { nsIPresShell* presShell = aPresContext->PresShell(); @@ -151,14 +147,13 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, } break; - - - case NS_MOUSE_CLICK: - if (NS_IS_MOUSE_LEFT_CLICK(aEvent)) - { - MouseClicked(aPresContext, aEvent); + case NS_MOUSE_CLICK: { + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); + if (mouseEvent->IsLeftClickEvent()) { + MouseClicked(aPresContext, mouseEvent); } break; + } } if ( doDefault ) @@ -168,7 +163,8 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, } void -nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent) +nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, + WidgetMouseEvent* aEvent) { // Execute the oncommand event handler. nsContentUtils::DispatchXULCommand(mContent, diff --git a/layout/xul/base/src/nsTitleBarFrame.h b/layout/xul/nsTitleBarFrame.h index 36b4ebf0e..16766bb31 100644 --- a/layout/xul/base/src/nsTitleBarFrame.h +++ b/layout/xul/nsTitleBarFrame.h @@ -6,6 +6,7 @@ #define nsTitleBarFrame_h___ #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "nsBoxFrame.h" class nsTitleBarFrame : public nsBoxFrame @@ -15,23 +16,24 @@ public: friend nsIFrame* NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); - nsTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + explicit nsTitleBarFrame(nsStyleContext* aContext); virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; - virtual void MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent); + virtual void MouseClicked(nsPresContext* aPresContext, + mozilla::WidgetMouseEvent* aEvent); - void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } + void UpdateMouseThrough() override { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } protected: - bool mTrackingMouseMove; - nsIntPoint mLastPoint; + bool mTrackingMouseMove; + mozilla::LayoutDeviceIntPoint mLastPoint; }; // class nsTitleBarFrame diff --git a/layout/xul/base/src/nsXULLabelFrame.cpp b/layout/xul/nsXULLabelFrame.cpp index d2d944472..26619b181 100644 --- a/layout/xul/base/src/nsXULLabelFrame.cpp +++ b/layout/xul/nsXULLabelFrame.cpp @@ -5,18 +5,19 @@ /* derived class of nsBlockFrame used for xul:label elements */ +#include "mozilla/EventStateManager.h" #include "nsXULLabelFrame.h" #include "nsHTMLParts.h" -#include "nsINameSpaceManager.h" -#include "nsEventStateManager.h" +#include "nsNameSpaceManager.h" + +using namespace mozilla; nsIFrame* NS_NewXULLabelFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { nsXULLabelFrame* it = new (aPresShell) nsXULLabelFrame(aContext); - if (it) - it->SetFlags(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT); + it->SetFlags(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT); return it; } @@ -48,7 +49,7 @@ nsXULLabelFrame::RegUnregAccessKey(bool aDoReg) // With a valid PresContext we can get the ESM // and register the access key - nsEventStateManager *esm = PresContext()->EventStateManager(); + EventStateManager* esm = PresContext()->EventStateManager(); uint32_t key = accessKey.First(); if (aDoReg) @@ -63,9 +64,9 @@ nsXULLabelFrame::RegUnregAccessKey(bool aDoReg) // nsIFrame void -nsXULLabelFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsXULLabelFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBlockFrame::Init(aContent, aParent, aPrevInFlow); @@ -81,7 +82,7 @@ nsXULLabelFrame::DestroyFrom(nsIFrame* aDestructRoot) nsBlockFrame::DestroyFrom(aDestructRoot); } -NS_IMETHODIMP +nsresult nsXULLabelFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -106,8 +107,8 @@ nsXULLabelFrame::GetType() const ///////////////////////////////////////////////////////////////////////////// // Diagnostics -#ifdef DEBUG -NS_IMETHODIMP +#ifdef DEBUG_FRAME_DUMP +nsresult nsXULLabelFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("XULLabel"), aResult); diff --git a/layout/xul/base/src/nsXULLabelFrame.h b/layout/xul/nsXULLabelFrame.h index 4f13124cb..e97fc3fca 100644 --- a/layout/xul/base/src/nsXULLabelFrame.h +++ b/layout/xul/nsXULLabelFrame.h @@ -24,29 +24,29 @@ public: nsStyleContext *aContext); // nsIFrame - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; /** * Get the "type" of the frame * * @see nsGkAtoms::XULLabelFrame */ - virtual nsIAtom* GetType() const MOZ_OVERRIDE; + virtual nsIAtom* GetType() const override; -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; #endif protected: - nsXULLabelFrame(nsStyleContext *aContext) : nsBlockFrame(aContext) {} + explicit nsXULLabelFrame(nsStyleContext *aContext) : nsBlockFrame(aContext) {} nsresult RegUnregAccessKey(bool aDoReg); }; diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index 181282673..9a8378978 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -8,18 +8,15 @@ #include "nsMenuFrame.h" #include "nsMenuPopupFrame.h" #include "nsMenuBarFrame.h" -#include "nsIPopupBoxObject.h" #include "nsMenuBarListener.h" #include "nsContentUtils.h" #include "nsIDOMDocument.h" -#include "nsDOMEvent.h" #include "nsIDOMEvent.h" #include "nsIDOMXULElement.h" #include "nsIXULDocument.h" #include "nsIXULTemplateBuilder.h" -#include "nsEventDispatcher.h" -#include "nsEventStateManager.h" #include "nsCSSFrameConstructor.h" +#include "nsGlobalWindow.h" #include "nsLayoutUtils.h" #include "nsViewManager.h" #include "nsIComponentManager.h" @@ -29,6 +26,7 @@ #include "nsPIDOMWindow.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIBaseWindow.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMMouseEvent.h" #include "nsCaret.h" #include "nsIDocument.h" @@ -36,28 +34,39 @@ #include "nsFrameManager.h" #include "nsIObserverService.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent() +#include "mozilla/EventDispatcher.h" +#include "mozilla/EventStateManager.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/MouseEvents.h" #include "mozilla/Services.h" using namespace mozilla; using namespace mozilla::dom; +static_assert(nsIDOMKeyEvent::DOM_VK_HOME == nsIDOMKeyEvent::DOM_VK_END + 1 && + nsIDOMKeyEvent::DOM_VK_LEFT == nsIDOMKeyEvent::DOM_VK_END + 2 && + nsIDOMKeyEvent::DOM_VK_UP == nsIDOMKeyEvent::DOM_VK_END + 3 && + nsIDOMKeyEvent::DOM_VK_RIGHT == nsIDOMKeyEvent::DOM_VK_END + 4 && + nsIDOMKeyEvent::DOM_VK_DOWN == nsIDOMKeyEvent::DOM_VK_END + 5, + "nsXULPopupManager assumes some keyCode values are consecutive"); + const nsNavigationDirection DirectionFromKeyCodeTable[2][6] = { { - eNavigationDirection_Last, // NS_VK_END - eNavigationDirection_First, // NS_VK_HOME - eNavigationDirection_Start, // NS_VK_LEFT - eNavigationDirection_Before, // NS_VK_UP - eNavigationDirection_End, // NS_VK_RIGHT - eNavigationDirection_After // NS_VK_DOWN + eNavigationDirection_Last, // nsIDOMKeyEvent::DOM_VK_END + eNavigationDirection_First, // nsIDOMKeyEvent::DOM_VK_HOME + eNavigationDirection_Start, // nsIDOMKeyEvent::DOM_VK_LEFT + eNavigationDirection_Before, // nsIDOMKeyEvent::DOM_VK_UP + eNavigationDirection_End, // nsIDOMKeyEvent::DOM_VK_RIGHT + eNavigationDirection_After // nsIDOMKeyEvent::DOM_VK_DOWN }, { - eNavigationDirection_Last, // NS_VK_END - eNavigationDirection_First, // NS_VK_HOME - eNavigationDirection_End, // NS_VK_LEFT - eNavigationDirection_Before, // NS_VK_UP - eNavigationDirection_Start, // NS_VK_RIGHT - eNavigationDirection_After // NS_VK_DOWN + eNavigationDirection_Last, // nsIDOMKeyEvent::DOM_VK_END + eNavigationDirection_First, // nsIDOMKeyEvent::DOM_VK_HOME + eNavigationDirection_End, // nsIDOMKeyEvent::DOM_VK_LEFT + eNavigationDirection_Before, // nsIDOMKeyEvent::DOM_VK_UP + eNavigationDirection_Start, // nsIDOMKeyEvent::DOM_VK_RIGHT + eNavigationDirection_After // nsIDOMKeyEvent::DOM_VK_DOWN } }; @@ -100,10 +109,10 @@ void nsMenuChainItem::Detach(nsMenuChainItem** aRoot) } } -NS_IMPL_ISUPPORTS3(nsXULPopupManager, - nsIDOMEventListener, - nsITimerCallback, - nsIObserver) +NS_IMPL_ISUPPORTS(nsXULPopupManager, + nsIDOMEventListener, + nsITimerCallback, + nsIObserver) nsXULPopupManager::nsXULPopupManager() : mRangeOffset(0), @@ -143,7 +152,7 @@ nsXULPopupManager::Shutdown() NS_IMETHODIMP nsXULPopupManager::Observe(nsISupports *aSubject, const char *aTopic, - const PRUnichar *aData) + const char16_t *aData) { if (!nsCRT::strcmp(aTopic, "xpcom-shutdown")) { if (mKeyListener) { @@ -171,7 +180,8 @@ nsXULPopupManager::GetInstance() } bool -nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp) +nsXULPopupManager::Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) { bool consume = false; @@ -192,22 +202,83 @@ nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp) *aLastRolledUp = first->Content(); } - consume = item->Frame()->ConsumeOutsideClicks(); - - // if a number of popups to close has been specified, determine the last - // popup to close - nsIContent* lastPopup = nullptr; - if (aCount != UINT32_MAX) { - nsMenuChainItem* last = item; - while (--aCount && last->GetParent()) { - last = last->GetParent(); + ConsumeOutsideClicksResult consumeResult = item->Frame()->ConsumeOutsideClicks(); + consume = (consumeResult == ConsumeOutsideClicks_True); + + bool rollup = true; + + // If norolluponanchor is true, then don't rollup when clicking the anchor. + // This would be used to allow adjusting the caret position in an + // autocomplete field without hiding the popup for example. + bool noRollupOnAnchor = (!consume && pos && + item->Frame()->GetContent()->AttrValueIs(kNameSpaceID_None, + nsGkAtoms::norolluponanchor, nsGkAtoms::_true, eCaseMatters)); + + // When ConsumeOutsideClicks_ParentOnly is used, always consume the click + // when the click was over the anchor. This way, clicking on a menu doesn't + // reopen the menu. + if ((consumeResult == ConsumeOutsideClicks_ParentOnly || noRollupOnAnchor) && pos) { + nsCOMPtr<nsIContent> anchor = item->Frame()->GetAnchor(); + + // Check if the anchor has indicated another node to use for checking + // for roll-up. That way, we can anchor a popup on anonymous content or + // an individual icon, while clicking elsewhere within a button or other + // container doesn't result in us re-opening the popup. + if (anchor) { + nsAutoString consumeAnchor; + anchor->GetAttr(kNameSpaceID_None, nsGkAtoms::consumeanchor, + consumeAnchor); + if (!consumeAnchor.IsEmpty()) { + nsIDocument* doc = anchor->GetOwnerDocument(); + nsIContent* newAnchor = doc->GetElementById(consumeAnchor); + if (newAnchor) { + anchor = newAnchor; + } + } } - if (last) { - lastPopup = last->Content(); + + if (anchor && anchor->GetPrimaryFrame()) { + // It's possible that some other element is above the anchor at the same + // position, but the only thing that would happen is that the mouse + // event will get consumed, so here only a quick coordinates check is + // done rather than a slower complete check of what is at that location. + if (anchor->GetPrimaryFrame()->GetScreenRect().Contains(*pos)) { + if (consumeResult == ConsumeOutsideClicks_ParentOnly) { + consume = true; + } + + if (noRollupOnAnchor) { + rollup = false; + } + } } } - HidePopup(item->Content(), true, true, false, lastPopup); + if (rollup) { + // if a number of popups to close has been specified, determine the last + // popup to close + nsIContent* lastPopup = nullptr; + if (aCount != UINT32_MAX) { + nsMenuChainItem* last = item; + while (--aCount && last->GetParent()) { + last = last->GetParent(); + } + if (last) { + lastPopup = last->Content(); + } + } + + nsPresContext* presContext = item->Frame()->PresContext(); + nsRefPtr<nsViewManager> viewManager = presContext->PresShell()->GetViewManager(); + + HidePopup(item->Content(), true, true, false, true, lastPopup); + + if (aFlush) { + // The popup's visibility doesn't update until the minimize animation has + // finished, so call UpdateWidgetGeometry to update it right away. + viewManager->UpdateWidgetGeometry(); + } + } } return consume; @@ -305,11 +376,15 @@ nsXULPopupManager::AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow) // When the parent window is moved, adjust any child popups. Dismissable // menus and panels are expected to roll up when a window is moved, so there // is no need to check these popups, only the noautohide popups. + + // The items are added to a list so that they can be adjusted bottom to top. + nsTArray<nsMenuPopupFrame *> list; + nsMenuChainItem* item = mNoHidePanels; while (item) { // only move popups that are within the same window and where auto // positioning has not been disabled - nsMenuPopupFrame* frame= item->Frame(); + nsMenuPopupFrame* frame = item->Frame(); if (frame->GetAutoPosition()) { nsIContent* popup = frame->GetContent(); if (popup) { @@ -319,7 +394,7 @@ nsXULPopupManager::AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow) if (window) { window = window->GetPrivateRoot(); if (window == aWindow) { - frame->SetPopupPosition(nullptr, true); + list.AppendElement(frame); } } } @@ -328,6 +403,17 @@ nsXULPopupManager::AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow) item = item->GetParent(); } + + for (int32_t l = list.Length() - 1; l >= 0; l--) { + list[l]->SetPopupPosition(nullptr, true, false); + } +} + +void nsXULPopupManager::AdjustPopupsOnWindowChange(nsIPresShell* aPresShell) +{ + if (aPresShell->GetDocument()) { + AdjustPopupsOnWindowChange(aPresShell->GetDocument()->GetWindow()); + } } static @@ -338,7 +424,7 @@ nsMenuPopupFrame* GetPopupToMoveOrResize(nsIFrame* aFrame) return nullptr; // no point moving or resizing hidden popups - if (menuPopupFrame->PopupState() != ePopupOpenAndVisible) + if (!menuPopupFrame->IsVisible()) return nullptr; nsIWidget* widget = menuPopupFrame->GetWidget(); @@ -355,28 +441,32 @@ nsXULPopupManager::PopupMoved(nsIFrame* aFrame, nsIntPoint aPnt) if (!menuPopupFrame) return; - // Convert desired point to CSS pixels for comparison - nsPresContext* presContext = menuPopupFrame->PresContext(); - aPnt.x = presContext->DevPixelsToIntCSSPixels(aPnt.x); - aPnt.y = presContext->DevPixelsToIntCSSPixels(aPnt.y); + nsView* view = menuPopupFrame->GetView(); + if (!view) + return; // Don't do anything if the popup is already at the specified location. This // prevents recursive calls when a popup is positioned. - nsIntPoint currentPnt = menuPopupFrame->ScreenPosition(); + nsIntRect curDevSize = view->CalcWidgetBounds(eWindowType_popup); nsIWidget* widget = menuPopupFrame->GetWidget(); - if ((aPnt.x != currentPnt.x || aPnt.y != currentPnt.y) || (widget && - widget->GetClientOffset() != menuPopupFrame->GetLastClientOffset())) { - // Update the popup's position using SetPopupPosition if the popup is - // anchored and at the parent level as these maintain their position - // relative to the parent window. Otherwise, just update the popup to - // the specified screen coordinates. - if (menuPopupFrame->IsAnchored() && - menuPopupFrame->PopupLevel() == ePopupLevelParent) { - menuPopupFrame->SetPopupPosition(nullptr, true); - } - else { - menuPopupFrame->MoveTo(aPnt.x, aPnt.y, false); - } + if (curDevSize.x == aPnt.x && curDevSize.y == aPnt.y && + (!widget || widget->GetClientOffset() == menuPopupFrame->GetLastClientOffset())) { + return; + } + + // Update the popup's position using SetPopupPosition if the popup is + // anchored and at the parent level as these maintain their position + // relative to the parent window. Otherwise, just update the popup to + // the specified screen coordinates. + if (menuPopupFrame->IsAnchored() && + menuPopupFrame->PopupLevel() == ePopupLevelParent) { + menuPopupFrame->SetPopupPosition(nullptr, true, false); + } + else { + nsPresContext* presContext = menuPopupFrame->PresContext(); + aPnt.x = presContext->DevPixelsToIntCSSPixels(aPnt.x); + aPnt.y = presContext->DevPixelsToIntCSSPixels(aPnt.y); + menuPopupFrame->MoveTo(aPnt.x, aPnt.y, false); } } @@ -447,7 +537,7 @@ void nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, nsIContent** aTriggerContent) { - mCachedMousePoint = nsIntPoint(0, 0); + mCachedMousePoint = LayoutDeviceIntPoint(0, 0); if (aTriggerContent) { *aTriggerContent = nullptr; @@ -469,11 +559,11 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, // get the event coordinates relative to the root frame of the document // containing the popup. NS_ASSERTION(aPopup, "Expected a popup node"); - nsEvent* event = aEvent->GetInternalNSEvent(); + WidgetEvent* event = aEvent->GetInternalNSEvent(); if (event) { - if (event->eventStructType == NS_MOUSE_EVENT || - event->eventStructType == NS_KEY_EVENT) { - mCachedModifiers = static_cast<nsInputEvent*>(event)->modifiers; + WidgetInputEvent* inputEvent = event->AsInputEvent(); + if (inputEvent) { + mCachedModifiers = inputEvent->modifiers; } nsIDocument* doc = aPopup->GetCurrentDoc(); if (doc) { @@ -486,10 +576,10 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, return; nsIFrame* rootDocumentRootFrame = rootDocPresContext-> PresShell()->FrameManager()->GetRootFrame(); - if ((event->eventStructType == NS_MOUSE_EVENT || - event->eventStructType == NS_MOUSE_SCROLL_EVENT || - event->eventStructType == NS_WHEEL_EVENT) && - !(static_cast<nsGUIEvent *>(event))->widget) { + if ((event->mClass == eMouseEventClass || + event->mClass == eMouseScrollEventClass || + event->mClass == eWheelEventClass) && + !event->AsGUIEvent()->widget) { // no widget, so just use the client point if available nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent); nsIntPoint clientPt; @@ -508,8 +598,8 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, else if (rootDocumentRootFrame) { nsPoint pnt = nsLayoutUtils::GetEventCoordinatesRelativeTo(event, rootDocumentRootFrame); - mCachedMousePoint = nsIntPoint(rootDocPresContext->AppUnitsToDevPixels(pnt.x), - rootDocPresContext->AppUnitsToDevPixels(pnt.y)); + mCachedMousePoint = LayoutDeviceIntPoint(rootDocPresContext->AppUnitsToDevPixels(pnt.x), + rootDocPresContext->AppUnitsToDevPixels(pnt.y)); } } } @@ -582,7 +672,7 @@ nsXULPopupManager::ShowMenu(nsIContent *aMenu, // there is no trigger event for menus InitTriggerEvent(nullptr, nullptr, nullptr); - popupFrame->InitializePopup(aMenu, nullptr, position, 0, 0, true); + popupFrame->InitializePopup(menuFrame->GetAnchor(), nullptr, position, 0, 0, true); if (aAsynchronous) { nsCOMPtr<nsIRunnable> event = @@ -648,8 +738,8 @@ nsXULPopupManager::ShowTooltipAtScreen(nsIContent* aPopup, InitTriggerEvent(nullptr, nullptr, nullptr); nsPresContext* pc = popupFrame->PresContext(); - mCachedMousePoint = nsIntPoint(pc->CSSPixelsToDevPixels(aXPos), - pc->CSSPixelsToDevPixels(aYPos)); + mCachedMousePoint = LayoutDeviceIntPoint(pc->CSSPixelsToDevPixels(aXPos), + pc->CSSPixelsToDevPixels(aYPos)); // coordinates are relative to the root widget nsPresContext* rootPresContext = pc->GetRootPresContext(); @@ -685,8 +775,8 @@ nsXULPopupManager::ShowPopupWithAnchorAlign(nsIContent* aPopup, } static void -CheckCaretDrawingState() { - +CheckCaretDrawingState() +{ // There is 1 caret per document, we need to find the focused // document and erase its caret. nsIFocusManager* fm = nsFocusManager::GetFocusManager(); @@ -710,7 +800,7 @@ CheckCaretDrawingState() { nsRefPtr<nsCaret> caret = presShell->GetCaret(); if (!caret) return; - caret->CheckCaretDrawingState(); + caret->SchedulePaint(); } } @@ -784,6 +874,7 @@ nsXULPopupManager::HidePopup(nsIContent* aPopup, bool aHideChain, bool aDeselectMenu, bool aAsynchronous, + bool aIsCancel, nsIContent* aLastPopup) { // if the popup is on the nohide panels list, remove it but don't close any @@ -876,16 +967,63 @@ nsXULPopupManager::HidePopup(nsIContent* aPopup, if (aAsynchronous) { nsCOMPtr<nsIRunnable> event = new nsXULPopupHidingEvent(popupToHide, nextPopup, lastPopup, - type, deselectMenu); + type, deselectMenu, aIsCancel); NS_DispatchToCurrentThread(event); } else { FirePopupHidingEvent(popupToHide, nextPopup, lastPopup, - popupFrame->PresContext(), type, deselectMenu); + popupFrame->PresContext(), type, deselectMenu, aIsCancel); } } } +// This is used to hide the popup after a transition finishes. +class TransitionEnder : public nsIDOMEventListener +{ +protected: + virtual ~TransitionEnder() { } + +public: + + nsCOMPtr<nsIContent> mContent; + bool mDeselectMenu; + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(TransitionEnder) + + TransitionEnder(nsIContent* aContent, bool aDeselectMenu) + : mContent(aContent), mDeselectMenu(aDeselectMenu) + { + } + + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override + { + mContent->RemoveSystemEventListener(NS_LITERAL_STRING("transitionend"), this, false); + + nsMenuPopupFrame* popupFrame = do_QueryFrame(mContent->GetPrimaryFrame()); + + // Now hide the popup. There could be other properties transitioning, but + // we'll assume they all end at the same time and just hide the popup upon + // the first one ending. + nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); + if (pm && popupFrame) { + pm->HidePopupCallback(mContent, popupFrame, nullptr, nullptr, + popupFrame->PopupType(), mDeselectMenu); + } + + return NS_OK; + } +}; + +NS_IMPL_CYCLE_COLLECTING_ADDREF(TransitionEnder) +NS_IMPL_CYCLE_COLLECTING_RELEASE(TransitionEnder) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransitionEnder) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION(TransitionEnder, mContent); + void nsXULPopupManager::HidePopupCallback(nsIContent* aPopup, nsMenuPopupFrame* aPopupFrame, @@ -932,11 +1070,13 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup, aPopupFrame->HidePopup(aDeselectMenu, ePopupClosed); ENSURE_TRUE(weakFrame.IsAlive()); - // send the popuphidden event synchronously. This event has no default behaviour. + // send the popuphidden event synchronously. This event has no default + // behaviour. nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event(true, NS_XUL_POPUP_HIDDEN, nullptr, nsMouseEvent::eReal); - nsEventDispatcher::Dispatch(aPopup, aPopupFrame->PresContext(), - &event, nullptr, &status); + WidgetMouseEvent event(true, NS_XUL_POPUP_HIDDEN, nullptr, + WidgetMouseEvent::eReal); + EventDispatcher::Dispatch(aPopup, aPopupFrame->PresContext(), + &event, nullptr, &status); ENSURE_TRUE(weakFrame.IsAlive()); // if there are more popups to close, look for the next one @@ -974,7 +1114,7 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup, FirePopupHidingEvent(popupToHide, nextPopup, aLastPopup, popupFrame->PresContext(), - foundMenu->PopupType(), aDeselectMenu); + foundMenu->PopupType(), aDeselectMenu, false); } } } @@ -984,7 +1124,7 @@ nsXULPopupManager::HidePopup(nsIFrame* aFrame) { nsMenuPopupFrame* popup = do_QueryFrame(aFrame); if (popup) - HidePopup(aFrame->GetContent(), false, true, false); + HidePopup(aFrame->GetContent(), false, true, false, false); } void @@ -1036,8 +1176,7 @@ nsXULPopupManager::HidePopupsInList(const nsTArray<nsMenuPopupFrame *> &aFrames, bool nsXULPopupManager::IsChildOfDocShell(nsIDocument* aDoc, nsIDocShellTreeItem* aExpected) { - nsCOMPtr<nsISupports> doc = aDoc->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(doc)); + nsCOMPtr<nsIDocShellTreeItem> docShellItem(aDoc->GetDocShell()); while(docShellItem) { if (docShellItem == aExpected) return true; @@ -1170,7 +1309,8 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup, mOpeningPopup = aPopup; nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event(true, NS_XUL_POPUP_SHOWING, nullptr, nsMouseEvent::eReal); + WidgetMouseEvent event(true, NS_XUL_POPUP_SHOWING, nullptr, + WidgetMouseEvent::eReal); // coordinates are relative to the root widget nsPresContext* rootPresContext = @@ -1185,9 +1325,9 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup, event.refPoint = mCachedMousePoint; event.modifiers = mCachedModifiers; - nsEventDispatcher::Dispatch(popup, presContext, &event, nullptr, &status); + EventDispatcher::Dispatch(popup, presContext, &event, nullptr, &status); - mCachedMousePoint = nsIntPoint(0, 0); + mCachedMousePoint = LayoutDeviceIntPoint(0, 0); mOpeningPopup = nullptr; mCachedModifiers = 0; @@ -1243,13 +1383,15 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup, nsIContent* aLastPopup, nsPresContext *aPresContext, nsPopupType aPopupType, - bool aDeselectMenu) + bool aDeselectMenu, + bool aIsCancel) { nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell(); nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event(true, NS_XUL_POPUP_HIDING, nullptr, nsMouseEvent::eReal); - nsEventDispatcher::Dispatch(aPopup, aPresContext, &event, nullptr, &status); + WidgetMouseEvent event(true, NS_XUL_POPUP_HIDING, nullptr, + WidgetMouseEvent::eReal); + EventDispatcher::Dispatch(aPopup, aPresContext, &event, nullptr, &status); // when a panel is closed, blur whatever has focus inside the popup if (aPopupType == ePopupTypePanel && @@ -1278,9 +1420,48 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup, // from hiding. if (status == nsEventStatus_eConsumeNoDefault && !popupFrame->IsInContentShell()) { - popupFrame->SetPopupState(ePopupOpenAndVisible); + // XXXndeakin + // If an attempt was made to hide this popup before the popupshown event + // fired, then ePopupShown is set here even though it should be + // ePopupVisible. This probably isn't worth the hassle of handling. + popupFrame->SetPopupState(ePopupShown); } else { + // If the popup has an animate attribute and it is not set to false, check + // if it has a closing transition and wait for it to finish. The transition + // may still occur either way, but the view will be hidden and you won't be + // able to see it. If there is a next popup, indicating that mutliple popups + // are rolling up, don't wait and hide the popup right away since the effect + // would likely be undesirable. Transitions are currently disabled on Linux + // due to rendering issues on certain configurations. +#ifndef MOZ_WIDGET_GTK + if (!aNextPopup && aPopup->HasAttr(kNameSpaceID_None, nsGkAtoms::animate)) { + // If animate="false" then don't transition at all. If animate="cancel", + // only show the transition if cancelling the popup or rolling up. + // Otherwise, always show the transition. + nsAutoString animate; + aPopup->GetAttr(kNameSpaceID_None, nsGkAtoms::animate, animate); + + if (!animate.EqualsLiteral("false") && + (!animate.EqualsLiteral("cancel") || aIsCancel)) { + presShell->FlushPendingNotifications(Flush_Layout); + + // Get the frame again in case the flush caused it to go away + popupFrame = do_QueryFrame(aPopup->GetPrimaryFrame()); + if (!popupFrame) + return; + + if (nsLayoutUtils::HasCurrentAnimations(aPopup, + nsGkAtoms::transitionsProperty)) { + nsRefPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu); + aPopup->AddSystemEventListener(NS_LITERAL_STRING("transitionend"), + ender, false, false); + return; + } + } + } +#endif + HidePopupCallback(aPopup, popupFrame, aNextPopup, aLastPopup, aPopupType, aDeselectMenu); } @@ -1359,21 +1540,20 @@ nsXULPopupManager::GetVisiblePopups(nsTArray<nsIFrame *>& aPopups) { aPopups.Clear(); + // Iterate over both lists of popups nsMenuChainItem* item = mPopups; - while (item) { - if (item->Frame()->PopupState() == ePopupOpenAndVisible) - aPopups.AppendElement(static_cast<nsIFrame*>(item->Frame())); - item = item->GetParent(); - } + for (int32_t list = 0; list < 2; list++) { + while (item) { + // Skip panels which are not visible as well as popups that + // are transparent to mouse events. + if (item->Frame()->IsVisible() && !item->Frame()->IsMouseTransparent()) { + aPopups.AppendElement(item->Frame()); + } - item = mNoHidePanels; - while (item) { - // skip panels which are not open and visible as well as draggable popups, - // as those don't respond to events. - if (item->Frame()->PopupState() == ePopupOpenAndVisible && !item->Frame()->IsDragPopup()) { - aPopups.AppendElement(static_cast<nsIFrame*>(item->Frame())); + item = item->GetParent(); } - item = item->GetParent(); + + item = mNoHidePanels; } } @@ -1440,24 +1620,23 @@ nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) if (widget && widget->GetLastRollup() == aPopup->GetContent()) return false; - nsCOMPtr<nsISupports> cont = aPopup->PresContext()->GetContainer(); - nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont); + nsCOMPtr<nsIDocShellTreeItem> dsti = aPopup->PresContext()->GetDocShell(); nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(dsti); if (!baseWin) return false; - int32_t type = -1; - if (NS_FAILED(dsti->GetItemType(&type))) + nsCOMPtr<nsIDocShellTreeItem> root; + dsti->GetRootTreeItem(getter_AddRefs(root)); + if (!root) { return false; + } + + nsCOMPtr<nsIDOMWindow> rootWin = root->GetWindow(); // chrome shells can always open popups, but other types of shells can only // open popups when they are focused and visible - if (type != nsIDocShellTreeItem::typeChrome) { + if (dsti->ItemType() != nsIDocShellTreeItem::typeChrome) { // only allow popups in active windows - nsCOMPtr<nsIDocShellTreeItem> root; - dsti->GetRootTreeItem(getter_AddRefs(root)); - nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(root); - nsIFocusManager* fm = nsFocusManager::GetFocusManager(); if (!fm || !rootWin) return false; @@ -1482,6 +1661,15 @@ nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) return false; } +#ifdef XP_MACOSX + if (rootWin) { + nsGlobalWindow *globalWin = static_cast<nsGlobalWindow *>(rootWin.get()); + if (globalWin->IsInModalState()) { + return false; + } + } +#endif + // cannot open a popup that is a submenu of a menupopup that isn't open. nsMenuFrame* menuFrame = do_QueryFrame(aPopup->GetParent()); if (menuFrame) { @@ -1540,7 +1728,7 @@ nsXULPopupManager::PopupDestroyed(nsMenuPopupFrame* aPopup) else { // HidePopup will take care of hiding any of its children, so // break out afterwards - HidePopup(child->Content(), false, false, true); + HidePopup(child->Content(), false, false, true, false); break; } @@ -1604,11 +1792,11 @@ nsXULPopupManager::UpdateKeyboardListeners() nsMenuChainItem* item = GetTopVisibleMenu(); if (item) { if (!item->IgnoreKeys()) - newTarget = item->Content()->GetDocument(); + newTarget = item->Content()->GetComposedDoc(); isForMenu = item->PopupType() == ePopupTypeMenu; } else if (mActiveMenuBar) { - newTarget = mActiveMenuBar->GetContent()->GetDocument(); + newTarget = mActiveMenuBar->GetContent()->GetComposedDoc(); isForMenu = true; } @@ -1645,7 +1833,13 @@ nsXULPopupManager::UpdateMenuItems(nsIContent* aPopup) for (nsCOMPtr<nsIContent> grandChild = aPopup->GetFirstChild(); grandChild; grandChild = grandChild->GetNextSibling()) { - if (grandChild->NodeInfo()->Equals(nsGkAtoms::menuitem, kNameSpaceID_XUL)) { + if (grandChild->IsXUL(nsGkAtoms::menugroup)) { + if (grandChild->GetChildCount() == 0) { + continue; + } + grandChild = grandChild->GetFirstChild(); + } + if (grandChild->IsXUL(nsGkAtoms::menuitem)) { // See if we have a command attribute. nsAutoString command; grandChild->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command); @@ -1678,6 +1872,10 @@ nsXULPopupManager::UpdateMenuItems(nsIContent* aPopup) } } } + if (!grandChild->GetNextSibling() && + grandChild->GetParent()->IsXUL(nsGkAtoms::menugroup)) { + grandChild = grandChild->GetParent(); + } } } @@ -1740,7 +1938,7 @@ nsXULPopupManager::KillMenuTimer() mCloseTimer = nullptr; if (mTimerMenu->IsOpen()) - HidePopup(mTimerMenu->GetContent(), false, false, true); + HidePopup(mTimerMenu->GetContent(), false, false, true, false); } mTimerMenu = nullptr; @@ -1756,13 +1954,6 @@ nsXULPopupManager::CancelMenuTimer(nsMenuParent* aMenuParent) } } -static nsGUIEvent* DOMKeyEventToGUIEvent(nsIDOMEvent* aEvent) -{ - nsEvent* evt = aEvent ? aEvent->GetInternalNSEvent() : nullptr; - return evt && evt->eventStructType == NS_KEY_EVENT ? - static_cast<nsGUIEvent *>(evt) : nullptr; -} - bool nsXULPopupManager::HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent, nsMenuPopupFrame* aFrame) @@ -1777,7 +1968,7 @@ nsXULPopupManager::HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent, if (result) { aFrame->ChangeMenuItem(result, false); if (action) { - nsGUIEvent* evt = DOMKeyEventToGUIEvent(aKeyEvent); + WidgetGUIEvent* evt = aKeyEvent->GetInternalNSEvent()->AsGUIEvent(); nsMenuFrame* menuToOpen = result->Enter(evt); if (menuToOpen) { nsCOMPtr<nsIContent> content = menuToOpen->GetContent(); @@ -1840,7 +2031,8 @@ nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) return false; nsNavigationDirection theDirection; - NS_ASSERTION(aKeyCode >= NS_VK_END && aKeyCode <= NS_VK_DOWN, "Illegal key code"); + NS_ASSERTION(aKeyCode >= nsIDOMKeyEvent::DOM_VK_END && + aKeyCode <= nsIDOMKeyEvent::DOM_VK_DOWN, "Illegal key code"); theDirection = NS_DIRECTION_FROM_KEY_CODE(itemFrame, aKeyCode); // if a popup is open, first check for navigation within the popup @@ -1942,7 +2134,7 @@ nsXULPopupManager::HandleKeyboardNavigationInPopup(nsMenuChainItem* item, // close a submenu when Left is pressed nsMenuPopupFrame* popupFrame = currentMenu->GetPopup(); if (popupFrame) - HidePopup(popupFrame->GetContent(), false, false, false); + HidePopup(popupFrame->GetContent(), false, false, false, false); return true; } } @@ -1962,7 +2154,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( if (aTopVisibleMenuItem && aTopVisibleMenuItem->PopupType() != ePopupTypeMenu) { if (keyCode == nsIDOMKeyEvent::DOM_VK_ESCAPE) { - HidePopup(aTopVisibleMenuItem->Content(), false, false, false); + HidePopup(aTopVisibleMenuItem->Content(), false, false, false, true); aKeyEvent->StopPropagation(); aKeyEvent->PreventDefault(); } @@ -1986,7 +2178,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( // though in this latter case, a menu didn't actually close, the effect // ends up being the same. Similar for the tab key below. if (aTopVisibleMenuItem) { - HidePopup(aTopVisibleMenuItem->Content(), false, false, false); + HidePopup(aTopVisibleMenuItem->Content(), false, false, false, true); } else if (mActiveMenuBar) { mActiveMenuBar->MenuClosed(); } @@ -1998,19 +2190,18 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( #endif // close popups or deactivate menubar when Tab or F10 are pressed if (aTopVisibleMenuItem) { - Rollup(0, nullptr); + Rollup(0, false, nullptr, nullptr); } else if (mActiveMenuBar) { mActiveMenuBar->MenuClosed(); } break; - case nsIDOMKeyEvent::DOM_VK_ENTER: case nsIDOMKeyEvent::DOM_VK_RETURN: { // If there is a popup open, check if the current item needs to be opened. // Otherwise, tell the active menubar, if any, to activate the menu. The // Enter method will return a menu if one needs to be opened as a result. nsMenuFrame* menuToOpen = nullptr; - nsGUIEvent* GUIEvent = DOMKeyEventToGUIEvent(aKeyEvent); + WidgetGUIEvent* GUIEvent = aKeyEvent->GetInternalNSEvent()->AsGUIEvent(); if (aTopVisibleMenuItem) { menuToOpen = aTopVisibleMenuItem->Frame()->Enter(GUIEvent); } else if (mActiveMenuBar) { @@ -2034,31 +2225,42 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( return true; } - nsMenuFrame* -nsXULPopupManager::GetNextMenuItem(nsIFrame* aParent, +nsXULPopupManager::GetNextMenuItem(nsContainerFrame* aParent, nsMenuFrame* aStart, bool aIsPopup) { - nsIFrame* immediateParent = nullptr; nsPresContext* presContext = aParent->PresContext(); - presContext->PresShell()-> - FrameConstructor()->GetInsertionPoint(aParent, nullptr, &immediateParent); + auto insertion = presContext->PresShell()-> + FrameConstructor()->GetInsertionPoint(aParent->GetContent(), nullptr); + nsContainerFrame* immediateParent = insertion.mParentFrame; if (!immediateParent) immediateParent = aParent; nsIFrame* currFrame = nullptr; - if (aStart) - currFrame = aStart->GetNextSibling(); - else + if (aStart) { + if (aStart->GetNextSibling()) + currFrame = aStart->GetNextSibling(); + else if (aStart->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = aStart->GetParent()->GetNextSibling(); + } + else currFrame = immediateParent->GetFirstPrincipalChild(); - + while (currFrame) { // See if it's a menu item. - if (IsValidMenuItem(presContext, currFrame->GetContent(), aIsPopup)) { + nsIContent* currFrameContent = currFrame->GetContent(); + if (IsValidMenuItem(presContext, currFrameContent, aIsPopup)) { return do_QueryFrame(currFrame); } - currFrame = currFrame->GetNextSibling(); + if (currFrameContent->IsXUL(nsGkAtoms::menugroup) && + currFrameContent->GetChildCount() > 0) + currFrame = currFrame->GetFirstPrincipalChild(); + else if (!currFrame->GetNextSibling() && + currFrame->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = currFrame->GetParent()->GetNextSibling(); + else + currFrame = currFrame->GetNextSibling(); } currFrame = immediateParent->GetFirstPrincipalChild(); @@ -2066,11 +2268,18 @@ nsXULPopupManager::GetNextMenuItem(nsIFrame* aParent, // Still don't have anything. Try cycling from the beginning. while (currFrame && currFrame != aStart) { // See if it's a menu item. - if (IsValidMenuItem(presContext, currFrame->GetContent(), aIsPopup)) { + nsIContent* currFrameContent = currFrame->GetContent(); + if (IsValidMenuItem(presContext, currFrameContent, aIsPopup)) { return do_QueryFrame(currFrame); } - - currFrame = currFrame->GetNextSibling(); + if (currFrameContent->IsXUL(nsGkAtoms::menugroup) && + currFrameContent->GetChildCount() > 0) + currFrame = currFrame->GetFirstPrincipalChild(); + else if (!currFrame->GetNextSibling() && + currFrame->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = currFrame->GetParent()->GetNextSibling(); + else + currFrame = currFrame->GetNextSibling(); } // No luck. Just return our start value. @@ -2078,31 +2287,45 @@ nsXULPopupManager::GetNextMenuItem(nsIFrame* aParent, } nsMenuFrame* -nsXULPopupManager::GetPreviousMenuItem(nsIFrame* aParent, +nsXULPopupManager::GetPreviousMenuItem(nsContainerFrame* aParent, nsMenuFrame* aStart, bool aIsPopup) { - nsIFrame* immediateParent = nullptr; nsPresContext* presContext = aParent->PresContext(); - presContext->PresShell()-> - FrameConstructor()->GetInsertionPoint(aParent, nullptr, &immediateParent); + auto insertion = presContext->PresShell()-> + FrameConstructor()->GetInsertionPoint(aParent->GetContent(), nullptr); + nsContainerFrame* immediateParent = insertion.mParentFrame; if (!immediateParent) immediateParent = aParent; const nsFrameList& frames(immediateParent->PrincipalChildList()); nsIFrame* currFrame = nullptr; - if (aStart) - currFrame = aStart->GetPrevSibling(); + if (aStart) { + if (aStart->GetPrevSibling()) + currFrame = aStart->GetPrevSibling(); + else if (aStart->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = aStart->GetParent()->GetPrevSibling(); + } else currFrame = frames.LastChild(); while (currFrame) { // See if it's a menu item. - if (IsValidMenuItem(presContext, currFrame->GetContent(), aIsPopup)) { + nsIContent* currFrameContent = currFrame->GetContent(); + if (IsValidMenuItem(presContext, currFrameContent, aIsPopup)) { return do_QueryFrame(currFrame); } - currFrame = currFrame->GetPrevSibling(); + if (currFrameContent->IsXUL(nsGkAtoms::menugroup) && + currFrameContent->GetChildCount() > 0) { + const nsFrameList& menugroupFrames(currFrame->PrincipalChildList()); + currFrame = menugroupFrames.LastChild(); + } + else if (!currFrame->GetPrevSibling() && + currFrame->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = currFrame->GetParent()->GetPrevSibling(); + else + currFrame = currFrame->GetPrevSibling(); } currFrame = frames.LastChild(); @@ -2110,11 +2333,20 @@ nsXULPopupManager::GetPreviousMenuItem(nsIFrame* aParent, // Still don't have anything. Try cycling from the end. while (currFrame && currFrame != aStart) { // See if it's a menu item. - if (IsValidMenuItem(presContext, currFrame->GetContent(), aIsPopup)) { + nsIContent* currFrameContent = currFrame->GetContent(); + if (IsValidMenuItem(presContext, currFrameContent, aIsPopup)) { return do_QueryFrame(currFrame); } - - currFrame = currFrame->GetPrevSibling(); + if (currFrameContent->IsXUL(nsGkAtoms::menugroup) && + currFrameContent->GetChildCount() > 0) { + const nsFrameList& menugroupFrames(currFrame->PrincipalChildList()); + currFrame = menugroupFrames.LastChild(); + } + else if (!currFrame->GetPrevSibling() && + currFrame->GetParent()->GetContent()->IsXUL(nsGkAtoms::menugroup)) + currFrame = currFrame->GetParent()->GetPrevSibling(); + else + currFrame = currFrame->GetPrevSibling(); } // No luck. Just return our start value. @@ -2240,7 +2472,7 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent) // The access key just went down and no other // modifiers are already down. if (mPopups) - Rollup(0, nullptr); + Rollup(0, false, nullptr, nullptr); else if (mActiveMenuBar) mActiveMenuBar->MenuClosed(); // Clear the item to avoid bugs as it may have been deleted during rollup. @@ -2266,12 +2498,9 @@ nsXULPopupManager::KeyPress(nsIDOMKeyEvent* aKeyEvent) nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent); NS_ENSURE_TRUE(keyEvent, NS_ERROR_UNEXPECTED); - // if a menu is open or a menubar is active, it consumes the key event bool consume = (mPopups || mActiveMenuBar); - HandleShortcutNavigation(keyEvent, nullptr); - if (consume) { aKeyEvent->StopPropagation(); aKeyEvent->PreventDefault(); @@ -2303,7 +2532,7 @@ nsXULPopupHidingEvent::Run() nsPresContext* context = presShell->GetPresContext(); if (context) { pm->FirePopupHidingEvent(mPopup, mNextPopup, mLastPopup, - context, mPopupType, mDeselectMenu); + context, mPopupType, mDeselectMenu, mIsRollup); } } } @@ -2357,14 +2586,14 @@ nsXULMenuCommandEvent::Run() if (mCloseMenuMode != CloseMenuMode_None) menuFrame->SelectMenu(false); - nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, - shell->GetDocument()); + AutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, + shell->GetDocument()); nsContentUtils::DispatchXULCommand(mMenu, mIsTrusted, nullptr, shell, mControl, mAlt, mShift, mMeta); } if (popup && mCloseMenuMode != CloseMenuMode_None) - pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false); + pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false, false); return NS_OK; } diff --git a/layout/xul/base/public/nsXULPopupManager.h b/layout/xul/nsXULPopupManager.h index eeb53ddab..900350ef4 100644 --- a/layout/xul/base/public/nsXULPopupManager.h +++ b/layout/xul/nsXULPopupManager.h @@ -11,17 +11,18 @@ #define nsXULPopupManager_h__ #include "prlog.h" -#include "nsGUIEvent.h" #include "nsIContent.h" #include "nsIRollupListener.h" #include "nsIDOMEventListener.h" #include "nsPoint.h" #include "nsCOMPtr.h" #include "nsTArray.h" +#include "nsIObserver.h" #include "nsITimer.h" #include "nsIReflowCallback.h" #include "nsThreadUtils.h" #include "nsStyleConsts.h" +#include "nsWidgetInitData.h" #include "mozilla/Attributes.h" // X.h defines KeyPress @@ -45,12 +46,14 @@ * calling Rollup. */ +class nsContainerFrame; class nsMenuFrame; class nsMenuPopupFrame; class nsMenuBarFrame; class nsMenuParent; class nsIDOMKeyEvent; class nsIDocShellTreeItem; +class nsPIDOMWindow; // when a menu command is executed, the closemenu attribute may be used // to define how the menu should be closed up @@ -103,11 +106,6 @@ enum nsNavigationDirection { dir == eNavigationDirection_Last) PR_STATIC_ASSERT(NS_STYLE_DIRECTION_LTR == 0 && NS_STYLE_DIRECTION_RTL == 1); -PR_STATIC_ASSERT((NS_VK_HOME == NS_VK_END + 1) && - (NS_VK_LEFT == NS_VK_END + 2) && - (NS_VK_UP == NS_VK_END + 3) && - (NS_VK_RIGHT == NS_VK_END + 4) && - (NS_VK_DOWN == NS_VK_END + 5)); /** * DirectionFromKeyCodeTable: two arrays, the first for left-to-right and the @@ -118,7 +116,7 @@ extern const nsNavigationDirection DirectionFromKeyCodeTable[2][6]; #define NS_DIRECTION_FROM_KEY_CODE(frame, keycode) \ (DirectionFromKeyCodeTable[frame->StyleVisibility()->mDirection] \ - [keycode - NS_VK_END]) + [keycode - nsIDOMKeyEvent::DOM_VK_END]) // nsMenuChainItem holds info about an open popup. Items are stored in a // doubly linked list. Note that the linked list is stored beginning from @@ -191,7 +189,7 @@ public: NS_ASSERTION(aPopup, "null popup supplied to nsXULPopupShowingEvent constructor"); } - NS_IMETHOD Run() MOZ_OVERRIDE; + NS_IMETHOD Run() override; private: nsCOMPtr<nsIContent> mPopup; @@ -207,18 +205,20 @@ public: nsIContent* aNextPopup, nsIContent* aLastPopup, nsPopupType aPopupType, - bool aDeselectMenu) + bool aDeselectMenu, + bool aIsCancel) : mPopup(aPopup), mNextPopup(aNextPopup), mLastPopup(aLastPopup), mPopupType(aPopupType), - mDeselectMenu(aDeselectMenu) + mDeselectMenu(aDeselectMenu), + mIsRollup(aIsCancel) { NS_ASSERTION(aPopup, "null popup supplied to nsXULPopupHidingEvent constructor"); // aNextPopup and aLastPopup may be null } - NS_IMETHOD Run() MOZ_OVERRIDE; + NS_IMETHOD Run() override; private: nsCOMPtr<nsIContent> mPopup; @@ -226,6 +226,7 @@ private: nsCOMPtr<nsIContent> mLastPopup; nsPopupType mPopupType; bool mDeselectMenu; + bool mIsRollup; }; // this class is used for dispatching menu command events asynchronously. @@ -253,7 +254,7 @@ public: NS_ASSERTION(aMenu, "null menu supplied to nsXULMenuCommandEvent constructor"); } - NS_IMETHOD Run() MOZ_OVERRIDE; + NS_IMETHOD Run() override; void SetCloseMenuMode(CloseMenuMode aCloseMenuMode) { mCloseMenuMode = aCloseMenuMode; } @@ -269,7 +270,7 @@ private: CloseMenuMode mCloseMenuMode; }; -class nsXULPopupManager MOZ_FINAL : public nsIDOMEventListener, +class nsXULPopupManager final : public nsIDOMEventListener, public nsIRollupListener, public nsITimerCallback, public nsIObserver @@ -279,6 +280,7 @@ public: friend class nsXULPopupShowingEvent; friend class nsXULPopupHidingEvent; friend class nsXULMenuCommandEvent; + friend class TransitionEnder; NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER @@ -286,13 +288,14 @@ public: NS_DECL_NSIDOMEVENTLISTENER // nsIRollupListener - virtual bool Rollup(uint32_t aCount, nsIContent** aLastRolledUp) MOZ_OVERRIDE; - virtual bool ShouldRollupOnMouseWheelEvent() MOZ_OVERRIDE; - virtual bool ShouldConsumeOnMouseWheelEvent() MOZ_OVERRIDE; - virtual bool ShouldRollupOnMouseActivate() MOZ_OVERRIDE; - virtual uint32_t GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) MOZ_OVERRIDE; - virtual void NotifyGeometryChange() MOZ_OVERRIDE {} - virtual nsIWidget* GetRollupWidget() MOZ_OVERRIDE; + virtual bool Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) override; + virtual bool ShouldRollupOnMouseWheelEvent() override; + virtual bool ShouldConsumeOnMouseWheelEvent() override; + virtual bool ShouldRollupOnMouseActivate() override; + virtual uint32_t GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) override; + virtual void NotifyGeometryChange() override {} + virtual nsIWidget* GetRollupWidget() override; static nsXULPopupManager* sInstance; @@ -304,7 +307,10 @@ public: // if a popup manager could not be allocated static nsXULPopupManager* GetInstance(); + // This should be called when a window is moved or resized to adjust the + // popups accordingly. void AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow); + void AdjustPopupsOnWindowChange(nsIPresShell* aPresShell); // given a menu frame, find the prevous or next menu frame. If aPopup is // true then navigate a menupopup, from one item on the menu to the previous @@ -325,10 +331,10 @@ public: // returns the item before it, while GetNextMenuItem returns the // item after it. // aIsPopup - true for menupopups, false for menubars - static nsMenuFrame* GetPreviousMenuItem(nsIFrame* aParent, + static nsMenuFrame* GetPreviousMenuItem(nsContainerFrame* aParent, nsMenuFrame* aStart, bool aIsPopup); - static nsMenuFrame* GetNextMenuItem(nsIFrame* aParent, + static nsMenuFrame* GetNextMenuItem(nsContainerFrame* aParent, nsMenuFrame* aStart, bool aIsPopup); @@ -433,6 +439,7 @@ public: * aAsynchronous - true if the first popuphiding event should be sent * asynchrously. This should be true if HidePopup is called * from a frame. + * aIsCancel - true if this popup is hiding due to being cancelled. * aLastPopup - optional popup to close last when hiding a chain of menus. * If null, then all popups will be closed. */ @@ -440,6 +447,7 @@ public: bool aHideChain, bool aDeselectMenu, bool aAsynchronous, + bool aIsCancel, nsIContent* aLastPopup = nullptr); /** @@ -664,13 +672,15 @@ protected: * aPresContext - nsPresContext for the popup's frame * aPopupType - the PopupType of the frame. * aDeselectMenu - true to unhighlight the menu when hiding it + * aIsCancel - true if this popup is hiding due to being cancelled. */ void FirePopupHidingEvent(nsIContent* aPopup, nsIContent* aNextPopup, nsIContent* aLastPopup, nsPresContext *aPresContext, nsPopupType aPopupType, - bool aDeselectMenu); + bool aDeselectMenu, + bool aIsCancel); /** * Handle keyboard navigation within a menu popup specified by aItem. @@ -733,10 +743,10 @@ protected: int32_t mRangeOffset; // Device pixels relative to the showing popup's presshell's // root prescontext's root frame. - nsIntPoint mCachedMousePoint; + mozilla::LayoutDeviceIntPoint mCachedMousePoint; // cached modifiers - mozilla::widget::Modifiers mCachedModifiers; + mozilla::Modifiers mCachedModifiers; // set to the currently active menu bar, if any nsMenuBarFrame* mActiveMenuBar; diff --git a/layout/xul/base/src/nsXULTooltipListener.cpp b/layout/xul/nsXULTooltipListener.cpp index f9e45d939..4624df716 100644 --- a/layout/xul/base/src/nsXULTooltipListener.cpp +++ b/layout/xul/nsXULTooltipListener.cpp @@ -5,13 +5,11 @@ #include "nsXULTooltipListener.h" -#include "nsDOMEvent.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMXULDocument.h" #include "nsIDOMXULElement.h" #include "nsIDocument.h" #include "nsGkAtoms.h" -#include "nsIPopupBoxObject.h" #include "nsMenuPopupFrame.h" #include "nsIServiceManager.h" #include "nsIDragService.h" @@ -19,17 +17,18 @@ #ifdef MOZ_XUL #include "nsITreeView.h" #endif -#include "nsGUIEvent.h" #include "nsIScriptContext.h" #include "nsPIDOMWindow.h" #ifdef MOZ_XUL #include "nsXULPopupManager.h" #endif #include "nsIRootBox.h" -#include "nsEventDispatcher.h" +#include "nsIBoxObject.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent() +#include "mozilla/dom/BoxObject.h" using namespace mozilla; using namespace mozilla::dom; @@ -73,7 +72,7 @@ nsXULTooltipListener::~nsXULTooltipListener() } } -NS_IMPL_ISUPPORTS1(nsXULTooltipListener, nsIDOMEventListener) +NS_IMPL_ISUPPORTS(nsXULTooltipListener, nsIDOMEventListener) void nsXULTooltipListener::MouseOut(nsIDOMEvent* aEvent) @@ -273,14 +272,12 @@ nsXULTooltipListener::HandleEvent(nsIDOMEvent* aEvent) //// nsXULTooltipListener // static -int +void nsXULTooltipListener::ToolbarTipsPrefChanged(const char *aPref, void *aClosure) { sShowTooltips = Preferences::GetBool("browser.chrome.toolbar_tips", sShowTooltips); - - return 0; } ////////////////////////////////////////////////////////////////////////// @@ -334,7 +331,7 @@ nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent) // get the boxObject of the documentElement of the document the tree is in nsCOMPtr<nsIBoxObject> bx; - nsIDocument* doc = sourceNode->GetDocument(); + nsIDocument* doc = sourceNode->GetComposedDoc(); if (doc) { ErrorResult ignored; bx = doc->GetBoxObjectFor(doc->GetRootElement(), ignored); @@ -349,7 +346,7 @@ nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent) int32_t row; nsCOMPtr<nsITreeColumn> col; - nsAutoCString obj; + nsAutoString obj; // subtract off the documentElement's boxObject int32_t boxX, boxY; @@ -390,11 +387,12 @@ nsXULTooltipListener::ShowTooltip() return NS_ERROR_FAILURE; // the target node doesn't need a tooltip // set the node in the document that triggered the tooltip and show it - nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(tooltipNode->GetDocument())); + nsCOMPtr<nsIDOMXULDocument> xulDoc = + do_QueryInterface(tooltipNode->GetComposedDoc()); if (xulDoc) { // Make sure the target node is still attached to some document. // It might have been deleted. - if (sourceNode->GetDocument()) { + if (sourceNode->IsInComposedDoc()) { #ifdef MOZ_XUL if (!mIsSourceTree) { mLastTreeRow = -1; @@ -416,7 +414,7 @@ nsXULTooltipListener::ShowTooltip() this, false, false); // listen for mousedown, mouseup, keydown, and DOMMouseScroll events at document level - nsIDocument* doc = sourceNode->GetDocument(); + nsIDocument* doc = sourceNode->GetComposedDoc(); if (doc) { // Probably, we should listen to untrusted events for hiding tooltips // on content since tooltips might disturb something of web @@ -525,7 +523,7 @@ nsXULTooltipListener::HideTooltip() if (currentTooltip) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) - pm->HidePopup(currentTooltip, false, false, false); + pm->HidePopup(currentTooltip, false, false, false, false); } #endif @@ -558,7 +556,7 @@ nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip) return NS_ERROR_NULL_POINTER; // before we go on, make sure that target node still has a window - nsIDocument *document = aTarget->GetDocument(); + nsIDocument *document = aTarget->GetComposedDoc(); if (!document) { NS_WARNING("Unable to retrieve the tooltip node document."); return NS_ERROR_FAILURE; @@ -598,8 +596,10 @@ nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip) return NS_OK; } - if (!tooltipId.IsEmpty()) { + if (!tooltipId.IsEmpty() && aTarget->IsInUncomposedDoc()) { // tooltip must be an id, use getElementById to find it + //XXXsmaug If aTarget is in shadow dom, should we use + // ShadowRoot::GetElementById()? nsCOMPtr<nsIContent> tooltipEl = document->GetElementById(tooltipId); if (tooltipEl) { @@ -661,7 +661,7 @@ nsXULTooltipListener::DestroyTooltip() mCurrentTooltip = nullptr; // clear out the tooltip node on the document - nsCOMPtr<nsIDocument> doc = currentTooltip->GetDocument(); + nsCOMPtr<nsIDocument> doc = currentTooltip->GetComposedDoc(); if (doc) { // remove the mousedown and keydown listener from document doc->RemoveSystemEventListener(NS_LITERAL_STRING("DOMMouseScroll"), this, diff --git a/layout/xul/base/src/nsXULTooltipListener.h b/layout/xul/nsXULTooltipListener.h index 7cf0c44c4..51e0a2c3f 100644 --- a/layout/xul/base/src/nsXULTooltipListener.h +++ b/layout/xul/nsXULTooltipListener.h @@ -21,7 +21,7 @@ class nsIContent; -class nsXULTooltipListener MOZ_FINAL : public nsIDOMEventListener +class nsXULTooltipListener final : public nsIDOMEventListener { public: NS_DECL_ISUPPORTS @@ -66,7 +66,7 @@ protected: nsresult GetTooltipFor(nsIContent* aTarget, nsIContent** aTooltip); static nsXULTooltipListener* mInstance; - static int ToolbarTipsPrefChanged(const char *aPref, void *aClosure); + static void ToolbarTipsPrefChanged(const char *aPref, void *aClosure); nsWeakPtr mSourceNode; nsWeakPtr mTargetNode; diff --git a/layout/xul/base/reftest/image-scaling-min-height-1-ref.xul b/layout/xul/reftest/image-scaling-min-height-1-ref.xul index 595450fe4..595450fe4 100644 --- a/layout/xul/base/reftest/image-scaling-min-height-1-ref.xul +++ b/layout/xul/reftest/image-scaling-min-height-1-ref.xul diff --git a/layout/xul/base/reftest/image-scaling-min-height-1.xul b/layout/xul/reftest/image-scaling-min-height-1.xul index 5c45d6b0c..5c45d6b0c 100644 --- a/layout/xul/base/reftest/image-scaling-min-height-1.xul +++ b/layout/xul/reftest/image-scaling-min-height-1.xul diff --git a/layout/xul/base/reftest/image-size-ref.xul b/layout/xul/reftest/image-size-ref.xul index c67364686..c67364686 100644 --- a/layout/xul/base/reftest/image-size-ref.xul +++ b/layout/xul/reftest/image-size-ref.xul diff --git a/layout/xul/base/reftest/image-size.xul b/layout/xul/reftest/image-size.xul index 732dc51f3..732dc51f3 100644 --- a/layout/xul/base/reftest/image-size.xul +++ b/layout/xul/reftest/image-size.xul diff --git a/layout/xul/base/reftest/image4x3.png b/layout/xul/reftest/image4x3.png Binary files differindex 6719bf5ce..6719bf5ce 100644 --- a/layout/xul/base/reftest/image4x3.png +++ b/layout/xul/reftest/image4x3.png diff --git a/layout/xul/base/reftest/popup-explicit-size-ref.xul b/layout/xul/reftest/popup-explicit-size-ref.xul index 4c864f103..4c864f103 100644 --- a/layout/xul/base/reftest/popup-explicit-size-ref.xul +++ b/layout/xul/reftest/popup-explicit-size-ref.xul diff --git a/layout/xul/base/reftest/popup-explicit-size.xul b/layout/xul/reftest/popup-explicit-size.xul index 6f1bf8582..6f1bf8582 100644 --- a/layout/xul/base/reftest/popup-explicit-size.xul +++ b/layout/xul/reftest/popup-explicit-size.xul diff --git a/layout/xul/reftest/reftest.list b/layout/xul/reftest/reftest.list new file mode 100644 index 000000000..f5c157ef3 --- /dev/null +++ b/layout/xul/reftest/reftest.list @@ -0,0 +1,6 @@ +fails-if(Android||B2G) skip-if(B2G&&browserIsRemote) == textbox-multiline-noresize.xul textbox-multiline-ref.xul # reference is blank on Android (due to no native theme support?) +skip-if(B2G&&browserIsRemote) != textbox-multiline-resize.xul textbox-multiline-ref.xul +skip-if(B2G&&browserIsRemote) == popup-explicit-size.xul popup-explicit-size-ref.xul +random-if(Android) skip-if(B2G&&browserIsRemote) == image-size.xul image-size-ref.xul +skip-if(B2G&&browserIsRemote) == image-scaling-min-height-1.xul image-scaling-min-height-1-ref.xul +skip-if(B2G&&browserIsRemote) == textbox-text-transform.xul textbox-text-transform-ref.xul diff --git a/layout/xul/base/reftest/textbox-multiline-noresize.xul b/layout/xul/reftest/textbox-multiline-noresize.xul index 27945ae9a..27945ae9a 100644 --- a/layout/xul/base/reftest/textbox-multiline-noresize.xul +++ b/layout/xul/reftest/textbox-multiline-noresize.xul diff --git a/layout/xul/base/reftest/textbox-multiline-ref.xul b/layout/xul/reftest/textbox-multiline-ref.xul index 23d279a75..23d279a75 100644 --- a/layout/xul/base/reftest/textbox-multiline-ref.xul +++ b/layout/xul/reftest/textbox-multiline-ref.xul diff --git a/layout/xul/base/reftest/textbox-multiline-resize.xul b/layout/xul/reftest/textbox-multiline-resize.xul index d7a25a669..d7a25a669 100644 --- a/layout/xul/base/reftest/textbox-multiline-resize.xul +++ b/layout/xul/reftest/textbox-multiline-resize.xul diff --git a/layout/xul/reftest/textbox-text-transform-ref.xul b/layout/xul/reftest/textbox-text-transform-ref.xul new file mode 100644 index 000000000..cbe95e079 --- /dev/null +++ b/layout/xul/reftest/textbox-text-transform-ref.xul @@ -0,0 +1,6 @@ +<?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"> +<label value="UPPERCASE"/> +<label value="lowercase"/> +</window> diff --git a/layout/xul/reftest/textbox-text-transform.xul b/layout/xul/reftest/textbox-text-transform.xul new file mode 100644 index 000000000..5de1c6af2 --- /dev/null +++ b/layout/xul/reftest/textbox-text-transform.xul @@ -0,0 +1,6 @@ +<?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"> +<label style="text-transform: uppercase" value="uppercase"/> +<label style="text-transform: lowercase" value="LOWERCASE"/> +</window> diff --git a/layout/xul/test/Makefile.in b/layout/xul/test/Makefile.in deleted file mode 100644 index df82e07ee..000000000 --- a/layout/xul/test/Makefile.in +++ /dev/null @@ -1,34 +0,0 @@ -# -# 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/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ -relativesrcdir = @relativesrcdir@ - -include $(DEPTH)/config/autoconf.mk - -MOCHITEST_FILES =\ - test_bug386386.html \ - test_bug394800.xhtml \ - test_bug563416.html \ - $(NULL) - -MOCHITEST_CHROME_FILES = \ - test_bug159346.xul \ - test_bug372685.xul \ - test_bug398982-1.xul \ - test_bug398982-2.xul \ - test_bug703150.xul \ - $(NULL) - -MOCHITEST_BROWSER_FILES = \ - browser_bug685470.js \ - browser_bug703210.js \ - browser_bug706743.js \ - $(NULL) - -include $(topsrcdir)/config/rules.mk diff --git a/layout/xul/test/browser.ini b/layout/xul/test/browser.ini new file mode 100644 index 000000000..f6a2feb5f --- /dev/null +++ b/layout/xul/test/browser.ini @@ -0,0 +1,8 @@ +[DEFAULT] + +[browser_bug685470.js] +skip-if = e10s # Bug ?????? - test touches content (TypeError: doc.documentElement is null) +[browser_bug703210.js] +skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly +[browser_bug706743.js] +skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly diff --git a/layout/xul/test/chrome.ini b/layout/xul/test/chrome.ini new file mode 100644 index 000000000..dfe026610 --- /dev/null +++ b/layout/xul/test/chrome.ini @@ -0,0 +1,24 @@ +[DEFAULT] +support-files = + window_resizer.xul + window_resizer_element.xul + +[test_bug159346.xul] +skip-if = buildapp == 'mulet' +[test_bug372685.xul] +[test_bug381167.xhtml] +[test_bug393970.xul] +[test_bug398982-1.xul] +[test_bug398982-2.xul] +[test_bug467442.xul] +[test_bug477754.xul] +[test_bug703150.xul] +skip-if = buildapp == 'mulet' +[test_bug987230.xul] +skip-if = os == 'linux' # No native mousedown event +[test_popupSizeTo.xul] +[test_popupZoom.xul] +[test_resizer.xul] +[test_stack.xul] +[test_windowminmaxsize.xul] +skip-if = buildapp == 'mulet' diff --git a/layout/xul/test/mochitest.ini b/layout/xul/test/mochitest.ini new file mode 100644 index 000000000..f52c2ad5c --- /dev/null +++ b/layout/xul/test/mochitest.ini @@ -0,0 +1,10 @@ +[DEFAULT] +skip-if = buildapp == 'mulet' || buildapp == 'b2g' + +[test_bug386386.html] +[test_bug394800.xhtml] +[test_bug511075.html] +skip-if = toolkit == 'android' #bug 798806 +[test_bug563416.html] +[test_resizer_incontent.xul] +[test_splitter.xul] diff --git a/layout/xul/test/moz.build b/layout/xul/test/moz.build deleted file mode 100644 index 895d11993..000000000 --- a/layout/xul/test/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; 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/. - diff --git a/layout/xul/base/test/test_bug381167.xhtml b/layout/xul/test/test_bug381167.xhtml index 1b056dcfb..1b056dcfb 100644 --- a/layout/xul/base/test/test_bug381167.xhtml +++ b/layout/xul/test/test_bug381167.xhtml diff --git a/layout/xul/test/test_bug386386.html b/layout/xul/test/test_bug386386.html index 836ce730e..b39ccede2 100644 --- a/layout/xul/test/test_bug386386.html +++ b/layout/xul/test/test_bug386386.html @@ -26,6 +26,7 @@ function do_test() { setTimeout(boom, 200); } SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); addLoadEvent(do_test); </script> diff --git a/layout/xul/base/test/test_bug393970.xul b/layout/xul/test/test_bug393970.xul index fcb0f9e43..fcb0f9e43 100644 --- a/layout/xul/base/test/test_bug393970.xul +++ b/layout/xul/test/test_bug393970.xul diff --git a/layout/xul/test/test_bug467442.xul b/layout/xul/test/test_bug467442.xul new file mode 100644 index 000000000..809e90cb8 --- /dev/null +++ b/layout/xul/test/test_bug467442.xul @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=467442 +--> +<window title="Mozilla Bug 467442" + onload="onload()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test code goes here --> + <popupset> + <panel id="panel"> + Hello. + </panel> + </popupset> + <hbox> + <button id="anchor" label="Anchor hello on here" style="transform: translate(100px, 0)"/> + </hbox> + <script type="application/javascript"> + <![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + function onload() { + /** Test for Bug 467442 **/ + let panel = document.getElementById("panel"); + let anchor = document.getElementById("anchor"); + + panel.addEventListener("popupshown", function onpopupshown() { + panel.removeEventListener("popupshown", onpopupshown); + let panelRect = panel.getBoundingClientRect(); + let anchorRect = anchor.getBoundingClientRect(); + is(panelRect.left, anchorRect.left, "Panel should be anchored to the button"); + panel.addEventListener("popuphidden", function onpopuphidden() { + panel.removeEventListener("popuphidden", onpopuphidden); + SimpleTest.finish(); + }); + panel.hidePopup(); + }); + + panel.openPopup(anchor, "after_start", 0, 0, false, false); + } + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467442" + target="_blank">Mozilla Bug 467442</a> + </body> +</window> diff --git a/layout/xul/base/test/test_bug477754.xul b/layout/xul/test/test_bug477754.xul index 111c5b805..111c5b805 100644 --- a/layout/xul/base/test/test_bug477754.xul +++ b/layout/xul/test/test_bug477754.xul diff --git a/layout/xul/base/test/test_bug511075.html b/layout/xul/test/test_bug511075.html index 313d140a3..ecb228884 100644 --- a/layout/xul/base/test/test_bug511075.html +++ b/layout/xul/test/test_bug511075.html @@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=511075 /** Test for Bug 511075 **/ SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); var tests = [ function() { diff --git a/layout/xul/test/test_bug563416.html b/layout/xul/test/test_bug563416.html index 66ce536fb..dd245de0b 100644 --- a/layout/xul/test/test_bug563416.html +++ b/layout/xul/test/test_bug563416.html @@ -10,7 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=563416 </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=563416">Mozilla Bug 563416</a> -<p id="display"><iframe id="test" src='data:text/html,<textarea style="box-sizing:content-box; -moz-appearance:none; height: 0px;" cols="20" rows="10">hsldkjvmshlkkajskdlfksdjflskdjflskdjflskdjflskdjfddddddddd</textarea>'></iframe></p> +<p id="display"><iframe id="test" src='data:text/html,<textarea style="box-sizing:content-box; -moz-appearance:none; height: 0px; padding: 0px;" cols="20" rows="10">hsldkjvmshlkkajskdlfksdjflskdjflskdjflskdjflskdjfddddddddd</textarea>'></iframe></p> <div id="content" style="display: none"> </div> diff --git a/layout/xul/test/test_bug987230.xul b/layout/xul/test/test_bug987230.xul new file mode 100644 index 000000000..2a61221d7 --- /dev/null +++ b/layout/xul/test/test_bug987230.xul @@ -0,0 +1,115 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=987230 +--> +<window title="Mozilla Bug 987230" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="SimpleTest.waitForFocus(nextTest, window)"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/> + + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=987230" + target="_blank">Mozilla Bug 987230</a> + </body> + + <vbox> + <toolbar> + <toolbarbutton id="toolbarbutton-anchor" + label="Anchor" + consumeanchor="toolbarbutton-anchor" + onclick="onAnchorClick(event)" + style="padding: 50px !important; list-style-image: url(chrome://branding/content/icon32.png)"/> + </toolbar> + <spacer flex="1"/> + <hbox id="hbox-anchor" + style="padding: 20px" + onclick="onAnchorClick(event)"> + <hbox id="inner-anchor" + consumeanchor="hbox-anchor" + > + Another anchor + </hbox> + </hbox> + <spacer flex="1"/> + </vbox> + + <panel id="mypopup" + type="arrow" + onpopupshown="onMyPopupShown(event)" + onpopuphidden="onMyPopupHidden(event)">This is a test popup</panel> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 987230 **/ + SimpleTest.waitForExplicitFinish(); + + const Ci = Components.interfaces; + const Cc = Components.classes; + + let platform = navigator.platform.toLowerCase(); + let isWindows = platform.startsWith("win"); + let mouseDown = isWindows ? 2 : 1; + let mouseUp = isWindows ? 4 : 2; + let mouseMove = isWindows ? 1 : 5; + let utils = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + let scale = utils.screenPixelsPerCSSPixel; + + + function synthesizeNativeMouseClick(aElement, aOffsetX, aOffsetY) { + let rect = aElement.getBoundingClientRect(); + let win = aElement.ownerDocument.defaultView; + let x = aOffsetX + win.mozInnerScreenX + rect.left; + let y = aOffsetY + win.mozInnerScreenY + rect.top; + + utils.sendNativeMouseEvent(x * scale, y * scale, mouseDown, 0, null); + utils.sendNativeMouseEvent(x * scale, y * scale, mouseUp, 0, null); + } + + function onMyPopupHidden(e) { + ok(true, "Popup hidden"); + if (outerAnchor.id == "toolbarbutton-anchor") { + popupHasShown = false; + outerAnchor = document.getElementById("hbox-anchor"); + anchor = document.getElementById("inner-anchor"); + nextTest(); + } else { + //XXXgijs set mouse position back outside the iframe: + let frameRect = window.frameElement.getBoundingClientRect(); + let outsideOfFrameX = (window.mozInnerScreenX + frameRect.width + 100) * scale; + let outsideOfFrameY = Math.max(0, window.mozInnerScreenY - 100) * scale; + + utils.sendNativeMouseEvent(outsideOfFrameX, outsideOfFrameY, mouseMove, 0, null); + SimpleTest.finish(); + } + } + + let popupHasShown = false; + function onMyPopupShown(e) { + popupHasShown = true; + synthesizeNativeMouseClick(outerAnchor, 5, 5); + } + + function onAnchorClick(e) { + info("click: " + e.target.id); + ok(!popupHasShown, "Popup should only be shown once"); + popup.openPopup(anchor, "bottomcenter topright"); + } + + let popup = document.getElementById("mypopup"); + let outerAnchor = document.getElementById("toolbarbutton-anchor"); + let anchor = document.getAnonymousElementByAttribute(outerAnchor, "class", "toolbarbutton-icon"); + + function nextTest(e) { + synthesizeMouse(outerAnchor, 5, 5, {}); + } + + ]]> + </script> +</window> diff --git a/layout/xul/base/test/test_popupSizeTo.xul b/layout/xul/test/test_popupSizeTo.xul index a135e1980..a135e1980 100644 --- a/layout/xul/base/test/test_popupSizeTo.xul +++ b/layout/xul/test/test_popupSizeTo.xul diff --git a/layout/xul/test/test_popupZoom.xul b/layout/xul/test/test_popupZoom.xul new file mode 100644 index 000000000..b8e15ba1d --- /dev/null +++ b/layout/xul/test/test_popupZoom.xul @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<window title="XUL Panel zoom test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + var docviewer; + var savedzoom; + + function openPopup() + { + docviewer = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIWebNavigation) + .QueryInterface(Components.interfaces.nsIDocShell) + .contentViewer; + savedzoom = docviewer.fullZoom; + docviewer.fullZoom = 2; + + document.getElementById("panel"). + openPopup(document.getElementById("anchor"), "after_start", 0, 0, false, false, null); + } + + function popupShown(event) + { + var panel = document.getElementById("panel"); + var panelbcr = panel.getBoundingClientRect(); + var anchorbcr = document.getElementById("anchor").getBoundingClientRect(); + + ok(Math.abs(panelbcr.x - anchorbcr.x) < 3, "x pos is correct"); + ok(Math.abs(panelbcr.y - anchorbcr.bottom) < 3, "y pos is correct"); + + docviewer.fullZoom = savedzoom; + + event.target.hidePopup(); + } + + SimpleTest.waitForFocus(openPopup); + ]]></script> + +<description id="anchor" value="Sometext to this some texts"/> +<panel id="panel" onpopupshown="popupShown(event)" onpopuphidden="SimpleTest.finish()"> + <resizer id="resizer" dir="bottomend" width="16" height="16"/> + <hbox width="50" height="50" flex="1"/> +</panel> + + +</window> diff --git a/layout/xul/base/test/test_resizer.xul b/layout/xul/test/test_resizer.xul index 2ba971d05..2ba971d05 100644 --- a/layout/xul/base/test/test_resizer.xul +++ b/layout/xul/test/test_resizer.xul diff --git a/layout/xul/base/test/test_resizer_incontent.xul b/layout/xul/test/test_resizer_incontent.xul index 068bd5bb1..068bd5bb1 100644 --- a/layout/xul/base/test/test_resizer_incontent.xul +++ b/layout/xul/test/test_resizer_incontent.xul diff --git a/layout/xul/base/test/test_splitter.xul b/layout/xul/test/test_splitter.xul index 697ad4be8..697ad4be8 100644 --- a/layout/xul/base/test/test_splitter.xul +++ b/layout/xul/test/test_splitter.xul diff --git a/layout/xul/base/test/test_stack.xul b/layout/xul/test/test_stack.xul index fdfb6977f..fdfb6977f 100644 --- a/layout/xul/base/test/test_stack.xul +++ b/layout/xul/test/test_stack.xul diff --git a/layout/xul/base/test/test_windowminmaxsize.xul b/layout/xul/test/test_windowminmaxsize.xul index d41f6a5f5..d41f6a5f5 100644 --- a/layout/xul/base/test/test_windowminmaxsize.xul +++ b/layout/xul/test/test_windowminmaxsize.xul diff --git a/layout/xul/base/test/window_resizer.xul b/layout/xul/test/window_resizer.xul index 4e349d125..4e349d125 100644 --- a/layout/xul/base/test/window_resizer.xul +++ b/layout/xul/test/window_resizer.xul diff --git a/layout/xul/base/test/window_resizer_element.xul b/layout/xul/test/window_resizer_element.xul index b0c58d1a1..b0c58d1a1 100644 --- a/layout/xul/base/test/window_resizer_element.xul +++ b/layout/xul/test/window_resizer_element.xul diff --git a/layout/xul/tree/Makefile.in b/layout/xul/tree/Makefile.in deleted file mode 100644 index 5033f0cd0..000000000 --- a/layout/xul/tree/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# -# 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/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -LIBXUL_LIBRARY = 1 -FAIL_ON_WARNINGS = 1 - -LOCAL_INCLUDES = \ - -I$(srcdir) \ - -I$(topsrcdir)/content/events/src \ - -I$(srcdir)/../base/src \ - -I$(srcdir)/../../base \ - -I$(srcdir)/../../generic \ - -I$(srcdir)/../../style \ - -I$(srcdir)/../../forms \ - $(NULL) - -# we don't want the shared lib, but we want to force the creation of a static lib. -FORCE_STATIC_LIB = 1 - -include $(topsrcdir)/config/rules.mk - -DEFINES += -D_IMPL_NS_LAYOUT diff --git a/layout/xul/tree/TreeBoxObject.cpp b/layout/xul/tree/TreeBoxObject.cpp new file mode 100644 index 000000000..25a1f3cfc --- /dev/null +++ b/layout/xul/tree/TreeBoxObject.cpp @@ -0,0 +1,695 @@ +/* -*- 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/. */ + +#include "mozilla/dom/TreeBoxObject.h" +#include "nsCOMPtr.h" +#include "nsIDOMXULElement.h" +#include "nsIScriptableRegion.h" +#include "nsIXULTemplateBuilder.h" +#include "nsTreeContentView.h" +#include "nsITreeSelection.h" +#include "ChildIterator.h" +#include "nsContentUtils.h" +#include "nsError.h" +#include "nsTreeBodyFrame.h" +#include "mozilla/dom/TreeBoxObjectBinding.h" +#include "nsITreeColumns.h" +#include "mozilla/dom/DOMRect.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/ToJSValue.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_INHERITED(TreeBoxObject, BoxObject, + mView) + +NS_IMPL_ADDREF_INHERITED(TreeBoxObject, BoxObject) +NS_IMPL_RELEASE_INHERITED(TreeBoxObject, BoxObject) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TreeBoxObject) + NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject) +NS_INTERFACE_MAP_END_INHERITING(BoxObject) + +void +TreeBoxObject::Clear() +{ + ClearCachedValues(); + + // Drop the view's ref to us. + if (mView) { + nsCOMPtr<nsITreeSelection> sel; + mView->GetSelection(getter_AddRefs(sel)); + if (sel) + sel->SetTree(nullptr); + mView->SetTree(nullptr); // Break the circular ref between the view and us. + } + mView = nullptr; + + BoxObject::Clear(); +} + + +TreeBoxObject::TreeBoxObject() + : mTreeBody(nullptr) +{ +} + +TreeBoxObject::~TreeBoxObject() +{ +} + +static nsIContent* FindBodyElement(nsIContent* aParent) +{ + mozilla::dom::FlattenedChildIterator iter(aParent); + for (nsIContent* content = iter.GetNextChild(); content; content = iter.GetNextChild()) { + mozilla::dom::NodeInfo *ni = content->NodeInfo(); + if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) { + return content; + } else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) { + // There are nesting tree elements. Only the innermost should + // find the treechilren. + return nullptr; + } else if (content->IsElement() && + !ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) { + nsIContent* result = FindBodyElement(content); + if (result) + return result; + } + } + + return nullptr; +} + +nsTreeBodyFrame* +TreeBoxObject::GetTreeBodyFrame(bool aFlushLayout) +{ + // Make sure our frames are up to date, and layout as needed. We + // have to do this before checking for our cached mTreeBody, since + // it might go away on style flush, and in any case if aFlushLayout + // is true we need to make sure to flush no matter what. + // XXXbz except that flushing style when we were not asked to flush + // layout here breaks things. See bug 585123. + nsIFrame* frame; + if (aFlushLayout) { + frame = GetFrame(aFlushLayout); + if (!frame) + return nullptr; + } + + if (mTreeBody) { + // Have one cached already. + return mTreeBody; + } + + if (!aFlushLayout) { + frame = GetFrame(aFlushLayout); + if (!frame) + return nullptr; + } + + // Iterate over our content model children looking for the body. + nsCOMPtr<nsIContent> content = FindBodyElement(frame->GetContent()); + if (!content) + return nullptr; + + frame = content->GetPrimaryFrame(); + if (!frame) + return nullptr; + + // Make sure that the treebodyframe has a pointer to |this|. + nsTreeBodyFrame *treeBody = do_QueryFrame(frame); + NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr); + + mTreeBody = treeBody; + return mTreeBody; +} + +NS_IMETHODIMP +TreeBoxObject::GetView(nsITreeView * *aView) +{ + if (!mTreeBody) { + if (!GetTreeBodyFrame()) { + // Don't return an uninitialised view + *aView = nullptr; + return NS_OK; + } + + if (mView) + // Our new frame needs to initialise itself + return mTreeBody->GetView(aView); + } + if (!mView) { + nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(mContent); + if (xulele) { + // See if there is a XUL tree builder associated with the element + nsCOMPtr<nsIXULTemplateBuilder> builder; + xulele->GetBuilder(getter_AddRefs(builder)); + mView = do_QueryInterface(builder); + + if (!mView) { + // No tree builder, create a tree content view. + nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView)); + NS_ENSURE_SUCCESS(rv, rv); + } + + // Initialise the frame and view + mTreeBody->SetView(mView); + } + } + NS_IF_ADDREF(*aView = mView); + return NS_OK; +} + +already_AddRefed<nsITreeView> +TreeBoxObject::GetView() { + nsCOMPtr<nsITreeView> view; + GetView(getter_AddRefs(view)); + return view.forget(); +} + +static bool +CanTrustView(nsISupports* aValue) +{ + // Untrusted content is only allowed to specify known-good views + if (nsContentUtils::IsCallerChrome()) + return true; + nsCOMPtr<nsINativeTreeView> nativeTreeView = do_QueryInterface(aValue); + if (!nativeTreeView || NS_FAILED(nativeTreeView->EnsureNative())) { + // XXX ERRMSG need a good error here for developers + return false; + } + return true; +} + +NS_IMETHODIMP TreeBoxObject::SetView(nsITreeView * aView) +{ + if (!CanTrustView(aView)) + return NS_ERROR_DOM_SECURITY_ERR; + + mView = aView; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + body->SetView(aView); + + return NS_OK; +} + +void TreeBoxObject::SetView(nsITreeView* aView, ErrorResult& aRv) +{ + aRv = SetView(aView); +} + +bool TreeBoxObject::Focused() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->GetFocused(); + return false; +} + +NS_IMETHODIMP TreeBoxObject::GetFocused(bool* aFocused) +{ + *aFocused = Focused(); + return NS_OK; +} + +NS_IMETHODIMP TreeBoxObject::SetFocused(bool aFocused) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->SetFocused(aFocused); + return NS_OK; +} + +NS_IMETHODIMP TreeBoxObject::GetTreeBody(nsIDOMElement** aElement) +{ + *aElement = nullptr; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->GetTreeBody(aElement); + return NS_OK; +} + +already_AddRefed<Element> +TreeBoxObject::GetTreeBody() +{ + nsCOMPtr<nsIDOMElement> el; + GetTreeBody(getter_AddRefs(el)); + nsCOMPtr<Element> ret(do_QueryInterface(el)); + return ret.forget(); +} + +already_AddRefed<nsTreeColumns> +TreeBoxObject::GetColumns() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->Columns(); + return nullptr; +} + +NS_IMETHODIMP TreeBoxObject::GetColumns(nsITreeColumns** aColumns) +{ + *aColumns = GetColumns().take(); + return NS_OK; +} + +int32_t TreeBoxObject::RowHeight() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->RowHeight(); + return 0; +} + +int32_t TreeBoxObject::RowWidth() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->RowWidth(); + return 0; +} + +NS_IMETHODIMP TreeBoxObject::GetRowHeight(int32_t* aRowHeight) +{ + *aRowHeight = RowHeight(); + return NS_OK; +} + +NS_IMETHODIMP TreeBoxObject::GetRowWidth(int32_t *aRowWidth) +{ + *aRowWidth = RowWidth(); + return NS_OK; +} + +int32_t TreeBoxObject::GetFirstVisibleRow() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->FirstVisibleRow(); + return 0; +} + +NS_IMETHODIMP TreeBoxObject::GetFirstVisibleRow(int32_t *aFirstVisibleRow) +{ + *aFirstVisibleRow = GetFirstVisibleRow(); + return NS_OK; +} + +int32_t TreeBoxObject::GetLastVisibleRow() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->LastVisibleRow(); + return 0; +} + +NS_IMETHODIMP TreeBoxObject::GetLastVisibleRow(int32_t *aLastVisibleRow) +{ + *aLastVisibleRow = GetLastVisibleRow(); + return NS_OK; +} + +int32_t TreeBoxObject::HorizontalPosition() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->GetHorizontalPosition(); + return 0; +} + +NS_IMETHODIMP TreeBoxObject::GetHorizontalPosition(int32_t *aHorizontalPosition) +{ + *aHorizontalPosition = HorizontalPosition(); + return NS_OK; +} + +int32_t TreeBoxObject::GetPageLength() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->PageLength(); + return 0; +} + +NS_IMETHODIMP TreeBoxObject::GetPageLength(int32_t *aPageLength) +{ + *aPageLength = GetPageLength(); + return NS_OK; +} + +NS_IMETHODIMP TreeBoxObject::GetSelectionRegion(nsIScriptableRegion **aRegion) +{ + *aRegion = nullptr; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->GetSelectionRegion(aRegion); + return NS_OK; +} + +already_AddRefed<nsIScriptableRegion> +TreeBoxObject::SelectionRegion() +{ + nsCOMPtr<nsIScriptableRegion> region; + GetSelectionRegion(getter_AddRefs(region)); + return region.forget(); +} + +NS_IMETHODIMP +TreeBoxObject::EnsureRowIsVisible(int32_t aRow) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->EnsureRowIsVisible(aRow); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->EnsureCellIsVisible(aRow, aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollToRow(int32_t aRow) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(true); + if (body) + return body->ScrollToRow(aRow); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollByLines(int32_t aNumLines) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ScrollByLines(aNumLines); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollByPages(int32_t aNumPages) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ScrollByPages(aNumPages); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollToCell(int32_t aRow, nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ScrollToCell(aRow, aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollToColumn(nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ScrollToColumn(aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ScrollToHorizontalPosition(int32_t aHorizontalPosition) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ScrollToHorizontalPosition(aHorizontalPosition); + return NS_OK; +} + +NS_IMETHODIMP TreeBoxObject::Invalidate() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->Invalidate(); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::InvalidateColumn(nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->InvalidateColumn(aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::InvalidateRow(int32_t aIndex) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->InvalidateRow(aIndex); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::InvalidateCell(int32_t aRow, nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->InvalidateCell(aRow, aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->InvalidateRange(aStart, aEnd); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::InvalidateColumnRange(int32_t aStart, int32_t aEnd, nsITreeColumn* aCol) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->InvalidateColumnRange(aStart, aEnd, aCol); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::GetRowAt(int32_t x, int32_t y, int32_t *aRow) +{ + *aRow = 0; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->GetRowAt(x, y, aRow); + return NS_OK; +} + +int32_t +TreeBoxObject::GetRowAt(int32_t x, int32_t y) +{ + int32_t row; + GetRowAt(x, y, &row); + return row; +} + +NS_IMETHODIMP +TreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t *aRow, + nsITreeColumn** aCol, nsAString& aChildElt) +{ + *aRow = 0; + *aCol = nullptr; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) { + nsAutoCString element; + nsresult retval = body->GetCellAt(aX, aY, aRow, aCol, element); + CopyUTF8toUTF16(element, aChildElt); + return retval; + } + return NS_OK; +} + +void +TreeBoxObject::GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv) +{ + nsCOMPtr<nsITreeColumn> col; + GetCellAt(x, y, &aRetVal.mRow, getter_AddRefs(col), aRetVal.mChildElt); + aRetVal.mCol = col.forget().downcast<nsTreeColumn>(); +} + +void +TreeBoxObject::GetCellAt(JSContext* cx, + int32_t x, int32_t y, + JS::Handle<JSObject*> rowOut, + JS::Handle<JSObject*> colOut, + JS::Handle<JSObject*> childEltOut, + ErrorResult& aRv) +{ + int32_t row; + nsITreeColumn* col; + nsAutoString childElt; + GetCellAt(x, y, &row, &col, childElt); + + JS::Rooted<JS::Value> v(cx); + + if (!ToJSValue(cx, row, &v) || + !JS_SetProperty(cx, rowOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + if (!dom::WrapObject(cx, col, &v) || + !JS_SetProperty(cx, colOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + if (!ToJSValue(cx, childElt, &v) || + !JS_SetProperty(cx, childEltOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } +} + +NS_IMETHODIMP +TreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const nsAString& aElement, + int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight) +{ + *aX = *aY = *aWidth = *aHeight = 0; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + NS_ConvertUTF16toUTF8 element(aElement); + if (body) + return body->GetCoordsForCellItem(aRow, aCol, element, aX, aY, aWidth, aHeight); + return NS_OK; +} + +already_AddRefed<DOMRect> +TreeBoxObject::GetCoordsForCellItem(int32_t row, nsTreeColumn& col, const nsAString& element, ErrorResult& aRv) +{ + int32_t x, y, w, h; + GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h); + nsRefPtr<DOMRect> rect = new DOMRect(mContent, x, y, w, h); + return rect.forget(); +} + +void +TreeBoxObject::GetCoordsForCellItem(JSContext* cx, + int32_t row, + nsTreeColumn& col, + const nsAString& element, + JS::Handle<JSObject*> xOut, + JS::Handle<JSObject*> yOut, + JS::Handle<JSObject*> widthOut, + JS::Handle<JSObject*> heightOut, + ErrorResult& aRv) +{ + int32_t x, y, w, h; + GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h); + JS::Rooted<JS::Value> v(cx, INT_TO_JSVAL(x)); + if (!JS_SetProperty(cx, xOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + v = INT_TO_JSVAL(y); + if (!JS_SetProperty(cx, yOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + v = INT_TO_JSVAL(w); + if (!JS_SetProperty(cx, widthOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } + v = INT_TO_JSVAL(h); + if (!JS_SetProperty(cx, heightOut, "value", v)) { + aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL); + return; + } +} + +NS_IMETHODIMP +TreeBoxObject::IsCellCropped(int32_t aRow, nsITreeColumn* aCol, bool *aIsCropped) +{ + *aIsCropped = false; + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->IsCellCropped(aRow, aCol, aIsCropped); + return NS_OK; +} + +bool +TreeBoxObject::IsCellCropped(int32_t row, nsITreeColumn* col, ErrorResult& aRv) +{ + bool ret; + aRv = IsCellCropped(row, col, &ret); + return ret; +} + +NS_IMETHODIMP +TreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta) +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->RowCountChanged(aIndex, aDelta); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::BeginUpdateBatch() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->BeginUpdateBatch(); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::EndUpdateBatch() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->EndUpdateBatch(); + return NS_OK; +} + +NS_IMETHODIMP +TreeBoxObject::ClearStyleAndImageCaches() +{ + nsTreeBodyFrame* body = GetTreeBodyFrame(); + if (body) + return body->ClearStyleAndImageCaches(); + return NS_OK; +} + +void +TreeBoxObject::ClearCachedValues() +{ + mTreeBody = nullptr; +} + +JSObject* +TreeBoxObject::WrapObject(JSContext* aCx) +{ + return TreeBoxObjectBinding::Wrap(aCx, this); +} + +} // namespace dom +} // namespace mozilla + +// Creation Routine /////////////////////////////////////////////////////////////////////// + +using namespace mozilla::dom; + +nsresult +NS_NewTreeBoxObject(nsIBoxObject** aResult) +{ + NS_ADDREF(*aResult = new TreeBoxObject()); + return NS_OK; +} diff --git a/layout/xul/tree/TreeBoxObject.h b/layout/xul/tree/TreeBoxObject.h new file mode 100644 index 000000000..c6e523061 --- /dev/null +++ b/layout/xul/tree/TreeBoxObject.h @@ -0,0 +1,128 @@ +/* -*- 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 mozilla_dom_TreeBoxObject_h +#define mozilla_dom_TreeBoxObject_h + +#include "mozilla/dom/BoxObject.h" +#include "nsITreeView.h" +#include "nsITreeBoxObject.h" + +class nsTreeBodyFrame; +class nsTreeColumn; +class nsTreeColumns; + +namespace mozilla { +namespace dom { + +struct TreeCellInfo; +class DOMRect; + +class TreeBoxObject final : public BoxObject, + public nsITreeBoxObject +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TreeBoxObject, BoxObject) + NS_DECL_NSITREEBOXOBJECT + + TreeBoxObject(); + + nsTreeBodyFrame* GetTreeBodyFrame(bool aFlushLayout = false); + nsTreeBodyFrame* GetCachedTreeBodyFrame() { return mTreeBody; } + + //NS_PIBOXOBJECT interfaces + virtual void Clear() override; + virtual void ClearCachedValues() override; + + // WebIDL + virtual JSObject* WrapObject(JSContext* aCx) override; + + already_AddRefed<nsTreeColumns> GetColumns(); + + already_AddRefed<nsITreeView> GetView(); + + void SetView(nsITreeView* arg, ErrorResult& aRv); + + bool Focused(); + + already_AddRefed<Element> GetTreeBody(); + + int32_t RowHeight(); + + int32_t RowWidth(); + + int32_t HorizontalPosition(); + + already_AddRefed<nsIScriptableRegion> SelectionRegion(); + + int32_t GetFirstVisibleRow(); + + int32_t GetLastVisibleRow(); + + int32_t GetPageLength(); + + int32_t GetRowAt(int32_t x, int32_t y); + + void GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv); + + already_AddRefed<DOMRect> GetCoordsForCellItem(int32_t row, + nsTreeColumn& col, + const nsAString& element, + ErrorResult& aRv); + + bool IsCellCropped(int32_t row, nsITreeColumn* col, ErrorResult& aRv); + + // Deprecated APIs from old IDL + void GetCellAt(JSContext* cx, + int32_t x, int32_t y, + JS::Handle<JSObject*> rowOut, + JS::Handle<JSObject*> colOut, + JS::Handle<JSObject*> childEltOut, + ErrorResult& aRv); + + void GetCoordsForCellItem(JSContext* cx, + int32_t row, + nsTreeColumn& col, + const nsAString& element, + JS::Handle<JSObject*> xOut, + JS::Handle<JSObject*> yOut, + JS::Handle<JSObject*> widthOut, + JS::Handle<JSObject*> heightOut, + ErrorResult& aRv); + + // Same signature (except for nsresult return type) as the XPIDL impls + // void Invalidate(); + // void BeginUpdateBatch(); + // void EndUpdateBatch(); + // void ClearStyleAndImageCaches(); + // void SetFocused(bool arg); + // void EnsureRowIsVisible(int32_t index); + // void EnsureCellIsVisible(int32_t row, nsITreeColumn* col); + // void ScrollToRow(int32_t index); + // void ScrollByLines(int32_t numLines); + // void ScrollByPages(int32_t numPages); + // void ScrollToCell(int32_t row, nsITreeColumn* col); + // void ScrollToColumn(nsITreeColumn* col); + // void ScrollToHorizontalPosition(int32_t horizontalPosition); + // void InvalidateColumn(nsITreeColumn* col); + // void InvalidateRow(int32_t index); + // void InvalidateCell(int32_t row, nsITreeColumn* col); + // void InvalidateRange(int32_t startIndex, int32_t endIndex); + // void InvalidateColumnRange(int32_t startIndex, int32_t endIndex, nsITreeColumn* col); + // void RowCountChanged(int32_t index, int32_t count); + +protected: + nsTreeBodyFrame* mTreeBody; + nsCOMPtr<nsITreeView> mView; + +private: + ~TreeBoxObject(); +}; + +} // namespace dom +} // namespace mozilla + +#endif diff --git a/layout/xul/tree/crashtests/585815-iframe.xul b/layout/xul/tree/crashtests/585815-iframe.xul index ec0e5417e..ce9d29448 100644 --- a/layout/xul/tree/crashtests/585815-iframe.xul +++ b/layout/xul/tree/crashtests/585815-iframe.xul @@ -62,7 +62,7 @@ <script type="text/javascript"><![CDATA[ function run() { var tree = document.getElementsByTagName("tree")[0]; - var sel = tree.treeBoxObject.view.selection; + var sel = tree.view.selection; sel.rangedSelect(0, 0, true); sel.rangedSelect(1000, 1001, true); sel.adjustSelection(1, 0x7fffffff); @@ -70,4 +70,3 @@ function run() { ]]></script> </window> - diff --git a/layout/xul/tree/crashtests/730441-1.xul b/layout/xul/tree/crashtests/730441-1.xul index 293919b0f..a31c3b63f 100644 --- a/layout/xul/tree/crashtests/730441-1.xul +++ b/layout/xul/tree/crashtests/730441-1.xul @@ -8,7 +8,7 @@ $6 = (nsIContent * const) 0x0 (gdb) bt 3 #0 0xb6457185 in nsIContent::SetAttr (this=0x0, aNameSpaceID=0, aName=0xb0cb064c, aValue=..., aNotify=1) at ../../dist/include/nsIContent.h:285 #1 0xb6b72072 in nsTreeColumns::RestoreNaturalOrder (this=0xaaf83cc0) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:605 -#2 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 +#2 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 (More stack frames follow...) (gdb) frame 1 #1 0xb6b72072 in nsTreeColumns::RestoreNaturalOrder (this=0xaaf83cc0) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:605 diff --git a/layout/xul/tree/crashtests/730441-2.xul b/layout/xul/tree/crashtests/730441-2.xul index 0428c89d8..02b3a307e 100644 --- a/layout/xul/tree/crashtests/730441-2.xul +++ b/layout/xul/tree/crashtests/730441-2.xul @@ -5,7 +5,7 @@ Program received signal SIGSEGV, Segmentation fault. 610 mTree->Invalidate(); (gdb) bt 3 #0 0xb6b720a6 in nsTreeColumns::RestoreNaturalOrder (this=0xa947a580) at layout/xul/base/src/tree/src/nsTreeColumns.cpp:610 -#1 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 +#1 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 #2 0xb6171901 in XPCWrappedNative::CallMethod (ccx=..., mode=XPCWrappedNative::CALL_METHOD) at js/src/xpconnect/src/xpcwrappednative.cpp:2722 (More stack frames follow...) diff --git a/layout/xul/tree/crashtests/730441-3.xul b/layout/xul/tree/crashtests/730441-3.xul index eb42657f5..2cf74d1b9 100644 --- a/layout/xul/tree/crashtests/730441-3.xul +++ b/layout/xul/tree/crashtests/730441-3.xul @@ -7,7 +7,7 @@ Program received signal SIGSEGV, Segmentation fault. 571 boxObject->GetElement(getter_AddRefs(element)); (gdb) bt 3 #0 0xb6b7463a in nsTreeContentView::SetTree (this=0xb0ba2510, aTree=0xaaecece0) at layout/xul/base/src/tree/src/nsTreeContentView.cpp:571 -#1 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 +#1 0xb736c76f in NS_InvokeByIndex_P () at xpcom/reflect/xptcall/md/unix/xptcinvoke_gcc_x86_unix.cpp:69 #2 0xb6171901 in XPCWrappedNative::CallMethod (ccx=..., mode=XPCWrappedNative::CALL_METHOD) at js/src/xpconnect/src/xpcwrappednative.cpp:2722 (More stack frames follow...) diff --git a/layout/xul/tree/crashtests/crashtests.list b/layout/xul/tree/crashtests/crashtests.list index 9064c612f..7e305f692 100644 --- a/layout/xul/tree/crashtests/crashtests.list +++ b/layout/xul/tree/crashtests/crashtests.list @@ -1,7 +1,7 @@ load 307298-1.xul load 309732-1.xul load 309732-2.xul -asserts-if(Android,3) load 366583-1.xul +load 366583-1.xul asserts-if(winWidget,0-4) load 380217-1.xul # bug 616710 load 382444-1.html load 391178-1.xhtml diff --git a/layout/xul/tree/moz.build b/layout/xul/tree/moz.build index 8add51baf..b7eae70c8 100644 --- a/layout/xul/tree/moz.build +++ b/layout/xul/tree/moz.build @@ -14,16 +14,18 @@ XPIDL_SOURCES += [ XPIDL_MODULE = 'layout_xul_tree' -MODULE = 'layout' - EXPORTS += [ 'nsTreeColFrame.h', + 'nsTreeColumns.h', 'nsTreeUtils.h', ] -CPP_SOURCES += [ +EXPORTS.mozilla.dom += [ + 'TreeBoxObject.h' +] + +UNIFIED_SOURCES += [ 'nsTreeBodyFrame.cpp', - 'nsTreeBoxObject.cpp', 'nsTreeColFrame.cpp', 'nsTreeColumns.cpp', 'nsTreeContentView.cpp', @@ -31,7 +33,17 @@ CPP_SOURCES += [ 'nsTreeSelection.cpp', 'nsTreeStyleCache.cpp', 'nsTreeUtils.cpp', + 'TreeBoxObject.cpp', ] -LIBRARY_NAME = 'gkxultree_s' +FAIL_ON_WARNINGS = True +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '..', + '../../base', + '../../forms', + '../../generic', + '../../style', + '/dom/base', +] diff --git a/layout/xul/tree/nsITreeBoxObject.idl b/layout/xul/tree/nsITreeBoxObject.idl index 05f2e4ac5..638c8a41c 100644 --- a/layout/xul/tree/nsITreeBoxObject.idl +++ b/layout/xul/tree/nsITreeBoxObject.idl @@ -4,15 +4,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" -#include "domstubs.idl" +interface nsIDOMElement; interface nsITreeView; interface nsITreeSelection; interface nsITreeColumn; interface nsITreeColumns; interface nsIScriptableRegion; -[scriptable, uuid(64BA5199-C4F4-4498-BBDC-F8E4C369086C)] +[scriptable, uuid(f3da0c5e-51f5-45f0-b2cd-6be3ab6847ae)] interface nsITreeBoxObject : nsISupports { /** @@ -148,12 +148,12 @@ interface nsITreeBoxObject : nsISupports * The coordinate system is the client coordinate system for the * document this boxObject lives in, and the units are CSS pixels. */ - void getCellAt(in long x, in long y, out long row, out nsITreeColumn col, out ACString childElt); + void getCellAt(in long x, in long y, out long row, out nsITreeColumn col, out AString childElt); /** * Find the coordinates of an element within a specific cell. */ - void getCoordsForCellItem(in long row, in nsITreeColumn col, in ACString element, + void getCoordsForCellItem(in long row, in nsITreeColumn col, in AString element, out long x, out long y, out long width, out long height); /** diff --git a/layout/xul/tree/nsITreeContentView.idl b/layout/xul/tree/nsITreeContentView.idl index 0856ce381..0b5d178aa 100644 --- a/layout/xul/tree/nsITreeContentView.idl +++ b/layout/xul/tree/nsITreeContentView.idl @@ -4,7 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" -#include "nsIDOMElement.idl" + +interface nsIDOMElement; [scriptable, uuid(5ef62896-0c0a-41f1-bb3c-44a60f5dfdab)] interface nsITreeContentView : nsISupports diff --git a/layout/xul/tree/nsITreeView.idl b/layout/xul/tree/nsITreeView.idl index 22d045fd6..66920f81b 100644 --- a/layout/xul/tree/nsITreeView.idl +++ b/layout/xul/tree/nsITreeView.idl @@ -3,9 +3,9 @@ * 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/. */ -#include "nsITreeBoxObject.idl" -#include "domstubs.idl" +#include "nsISupports.idl" +interface nsITreeBoxObject; interface nsITreeSelection; interface nsITreeColumn; interface nsIDOMDataTransfer; diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 55a31ed23..fad899fea 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -3,13 +3,22 @@ * 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/. */ +#include "mozilla/AsyncEventDispatcher.h" +#include "mozilla/ContentEvents.h" #include "mozilla/DebugOnly.h" +#include "mozilla/EventDispatcher.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/PathHelpers.h" #include "mozilla/MathAlgorithms.h" +#include "mozilla/MouseEvents.h" #include "mozilla/Likely.h" +#include "gfxUtils.h" +#include "nsAlgorithm.h" #include "nsCOMPtr.h" +#include "nsFontMetrics.h" #include "nsPresContext.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsTreeBodyFrame.h" #include "nsTreeSelection.h" @@ -21,9 +30,7 @@ #include "nsIContent.h" #include "nsStyleContext.h" #include "nsIBoxObject.h" -#include "nsGUIEvent.h" -#include "nsAsyncDOMEvent.h" -#include "nsIDOMDataContainerEvent.h" +#include "nsIDOMCustomEvent.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMElement.h" #include "nsIDOMNodeList.h" @@ -39,24 +46,21 @@ #include "nsViewManager.h" #include "nsWidgetsCID.h" #include "nsBoxFrame.h" -#include "nsBoxObject.h" #include "nsIURL.h" #include "nsNetUtil.h" #include "nsBoxLayoutState.h" #include "nsTreeContentView.h" #include "nsTreeUtils.h" -#include "nsChildIterator.h" #include "nsITheme.h" #include "imgIRequest.h" #include "imgIContainer.h" #include "imgILoader.h" -#include "nsINodeInfo.h" +#include "mozilla/dom/NodeInfo.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "nsIScrollableFrame.h" -#include "nsEventDispatcher.h" #include "nsDisplayList.h" -#include "nsTreeBoxObject.h" +#include "mozilla/dom/TreeBoxObject.h" #include "nsRenderingContext.h" #include "nsIScriptableRegion.h" #include <algorithm> @@ -64,12 +68,12 @@ #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" +#include "nsIWritablePropertyBag2.h" #endif -#ifdef IBMBIDI #include "nsBidiUtils.h" -#endif using namespace mozilla; +using namespace mozilla::gfx; using namespace mozilla::layout; // Enumeration function that cancels all the image requests in our cache @@ -97,21 +101,21 @@ CancelImageRequest(const nsAString& aKey, nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsTreeBodyFrame(aPresShell, aContext); + return new (aPresShell) nsTreeBodyFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsTreeBodyFrame) NS_QUERYFRAME_HEAD(nsTreeBodyFrame) NS_QUERYFRAME_ENTRY(nsIScrollbarMediator) - NS_QUERYFRAME_ENTRY(nsIScrollbarOwner) NS_QUERYFRAME_ENTRY(nsTreeBodyFrame) NS_QUERYFRAME_TAIL_INHERITING(nsLeafBoxFrame) // Constructor -nsTreeBodyFrame::nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) -:nsLeafBoxFrame(aPresShell, aContext), +nsTreeBodyFrame::nsTreeBodyFrame(nsStyleContext* aContext) +:nsLeafBoxFrame(aContext), mSlots(nullptr), + mImageCache(), mTopRowIndex(0), mPageLength(0), mHorzPosition(0), @@ -128,7 +132,8 @@ nsTreeBodyFrame::nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aCont mHasFixedRowCount(false), mVerticalOverflow(false), mHorizontalOverflow(false), - mReflowCallbackPosted(false) + mReflowCallbackPosted(false), + mCheckingOverflow(false) { mColumns = new nsTreeColumns(this); } @@ -160,23 +165,20 @@ AdjustForBorderPadding(nsStyleContext* aContext, nsRect& aRect) } void -nsTreeBodyFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsTreeBodyFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsLeafBoxFrame::Init(aContent, aParent, aPrevInFlow); mIndentation = GetIndentation(); mRowHeight = GetRowHeight(); - mCreatedListeners.Init(); - - mImageCache.Init(16); EnsureBoxObject(); if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { mScrollbarActivity = new ScrollbarActivity( - static_cast<nsIScrollbarOwner*>(this)); + static_cast<nsIScrollbarMediator*>(this)); } } @@ -246,17 +248,15 @@ nsTreeBodyFrame::CalcMaxRowWidth() nscoord rowWidth; nsTreeColumn* col; - nsRefPtr<nsRenderingContext> rc = - PresContext()->PresShell()->GetReferenceRenderingContext(); - if (!rc) - return 0; + nsRenderingContext rc( + PresContext()->PresShell()->CreateReferenceRenderingContext()); for (int32_t row = 0; row < mRowCount; ++row) { rowWidth = 0; for (col = mColumns->GetFirstColumn(); col; col = col->GetNext()) { nscoord desiredWidth, currentWidth; - nsresult rv = GetCellWidth(row, col, rc, desiredWidth, currentWidth); + nsresult rv = GetCellWidth(row, col, &rc, desiredWidth, currentWidth); if (NS_FAILED(rv)) { NS_NOTREACHED("invalid column"); continue; @@ -324,7 +324,7 @@ nsTreeBodyFrame::EnsureBoxObject() if (!mTreeBoxObject) { nsIContent* parent = GetBaseElement(); if (parent) { - nsIDocument* nsDoc = parent->GetDocument(); + nsIDocument* nsDoc = parent->GetComposedDoc(); if (!nsDoc) // there may be no document, if we're called from Destroy() return; ErrorResult ignored; @@ -336,8 +336,8 @@ nsTreeBodyFrame::EnsureBoxObject() nsCOMPtr<nsITreeBoxObject> realTreeBoxObject = do_QueryInterface(pBox); if (realTreeBoxObject) { nsTreeBodyFrame* innerTreeBoxObject = - static_cast<nsTreeBoxObject*>(realTreeBoxObject.get()) - ->GetCachedTreeBody(); + static_cast<dom::TreeBoxObject*>(realTreeBoxObject.get()) + ->GetCachedTreeBodyFrame(); ENSURE_TRUE(!innerTreeBoxObject || innerTreeBoxObject == this); mTreeBoxObject = realTreeBoxObject; } @@ -364,7 +364,7 @@ nsTreeBodyFrame::EnsureView() mTreeBoxObject->GetView(getter_AddRefs(treeView)); if (treeView && weakFrame.IsAlive()) { nsXPIDLString rowStr; - box->GetProperty(NS_LITERAL_STRING("topRow").get(), + box->GetProperty(MOZ_UTF16("topRow"), getter_Copies(rowStr)); nsAutoString rowStr2(rowStr); nsresult error; @@ -381,7 +381,7 @@ nsTreeBodyFrame::EnsureView() // Clear out the property info for the top row, but we always keep the // view current. - box->RemoveProperty(NS_LITERAL_STRING("topRow").get()); + box->RemoveProperty(MOZ_UTF16("topRow")); } } } @@ -543,13 +543,6 @@ nsTreeBodyFrame::SetView(nsITreeView * aView) } nsresult -nsTreeBodyFrame::GetFocused(bool* aFocused) -{ - *aFocused = mFocused; - return NS_OK; -} - -nsresult nsTreeBodyFrame::SetFocused(bool aFocused) { if (mFocused != aFocused) { @@ -574,25 +567,22 @@ nsTreeBodyFrame::GetTreeBody(nsIDOMElement** aElement) return mContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)aElement); } -nsresult -nsTreeBodyFrame::GetRowHeight(int32_t* _retval) +int32_t +nsTreeBodyFrame::RowHeight() const { - *_retval = nsPresContext::AppUnitsToIntCSSPixels(mRowHeight); - return NS_OK; + return nsPresContext::AppUnitsToIntCSSPixels(mRowHeight); } -nsresult -nsTreeBodyFrame::GetRowWidth(int32_t *aRowWidth) +int32_t +nsTreeBodyFrame::RowWidth() { - *aRowWidth = nsPresContext::AppUnitsToIntCSSPixels(CalcHorzWidth(GetScrollParts())); - return NS_OK; + return nsPresContext::AppUnitsToIntCSSPixels(CalcHorzWidth(GetScrollParts())); } -nsresult -nsTreeBodyFrame::GetHorizontalPosition(int32_t *aHorizontalPosition) +int32_t +nsTreeBodyFrame::GetHorizontalPosition() const { - *aHorizontalPosition = nsPresContext::AppUnitsToIntCSSPixels(mHorzPosition); - return NS_OK; + return nsPresContext::AppUnitsToIntCSSPixels(mHorzPosition); } nsresult @@ -919,24 +909,44 @@ nsTreeBodyFrame::CheckOverflow(const ScrollParts& aParts) } } } - + + nsWeakFrame weakFrame(this); + nsRefPtr<nsPresContext> presContext = PresContext(); + nsCOMPtr<nsIPresShell> presShell = presContext->GetPresShell(); nsCOMPtr<nsIContent> content = mContent; if (verticalOverflowChanged) { - nsScrollPortEvent event(true, mVerticalOverflow ? NS_SCROLLPORT_OVERFLOW - : NS_SCROLLPORT_UNDERFLOW, nullptr); - event.orient = nsScrollPortEvent::vertical; - nsEventDispatcher::Dispatch(content, presContext, &event); + InternalScrollPortEvent event(true, + mVerticalOverflow ? NS_SCROLLPORT_OVERFLOW : NS_SCROLLPORT_UNDERFLOW, + nullptr); + event.orient = InternalScrollPortEvent::vertical; + EventDispatcher::Dispatch(content, presContext, &event); } if (horizontalOverflowChanged) { - nsScrollPortEvent event(true, - mHorizontalOverflow ? NS_SCROLLPORT_OVERFLOW - : NS_SCROLLPORT_UNDERFLOW, nullptr); - event.orient = nsScrollPortEvent::horizontal; - nsEventDispatcher::Dispatch(content, presContext, &event); + InternalScrollPortEvent event(true, + mHorizontalOverflow ? NS_SCROLLPORT_OVERFLOW : NS_SCROLLPORT_UNDERFLOW, + nullptr); + event.orient = InternalScrollPortEvent::horizontal; + EventDispatcher::Dispatch(content, presContext, &event); } + + // The synchronous event dispatch above can trigger reflow notifications. + // Flush those explicitly now, so that we can guard against potential infinite + // recursion. See bug 905909. + if (!weakFrame.IsAlive()) { + return; + } + NS_ASSERTION(!mCheckingOverflow, "mCheckingOverflow should not already be set"); + // Don't use AutoRestore since we want to not touch mCheckingOverflow if we fail + // the weakFrame.IsAlive() check below + mCheckingOverflow = true; + presShell->FlushPendingNotifications(Flush_Layout); + if (!weakFrame.IsAlive()) { + return; + } + mCheckingOverflow = false; } void @@ -1156,10 +1166,8 @@ nsTreeBodyFrame::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const n // interfere with our computations. AdjustForBorderPadding(cellContext, cellRect); - nsRefPtr<nsRenderingContext> rc = - presContext->PresShell()->GetReferenceRenderingContext(); - if (!rc) - return NS_ERROR_OUT_OF_MEMORY; + nsRenderingContext rc( + presContext->PresShell()->CreateReferenceRenderingContext()); // Now we'll start making our way across the cell, starting at the edge of // the cell and proceeding until we hit the right edge. |cellX| is the @@ -1183,7 +1191,7 @@ nsTreeBodyFrame::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const n nsRect twistyRect(cellRect); nsStyleContext* twistyContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreetwisty); GetTwistyRect(aRow, currCol, imageRect, twistyRect, presContext, - *rc, twistyContext); + rc, twistyContext); if (NS_LITERAL_CSTRING("twisty").Equals(aElement)) { // If we're looking for the twisty Rect, just return the size @@ -1261,8 +1269,7 @@ nsTreeBodyFrame::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const n GetBorderPadding(textContext, bp); textRect.height += bp.top + bp.bottom; - rc->SetFont(fm); - AdjustForCellText(cellText, aRow, currCol, *rc, textRect); + AdjustForCellText(cellText, aRow, currCol, rc, *fm, textRect); theRect = textRect; } @@ -1307,18 +1314,21 @@ void nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, int32_t aRowIndex, nsTreeColumn* aColumn, nsRenderingContext& aRenderingContext, + nsFontMetrics& aFontMetrics, nsRect& aTextRect) { NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed"); - nscoord width = - nsLayoutUtils::GetStringWidth(this, &aRenderingContext, aText.get(), aText.Length()); nscoord maxWidth = aTextRect.width; + bool widthIsGreater = nsLayoutUtils::StringWidthIsGreaterThan(aText, + aFontMetrics, + aRenderingContext, + maxWidth); if (aColumn->Overflow()) { DebugOnly<nsresult> rv; nsTreeColumn* nextColumn = aColumn->GetNext(); - while (nextColumn && width > maxWidth) { + while (nextColumn && widthIsGreater) { while (nextColumn) { nscoord width; rv = nextColumn->GetWidthInTwips(this, &width); @@ -1342,6 +1352,10 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, NS_ASSERTION(NS_SUCCEEDED(rv), "nextColumn is invalid"); maxWidth += width; + widthIsGreater = nsLayoutUtils::StringWidthIsGreaterThan(aText, + aFontMetrics, + aRenderingContext, + maxWidth); nextColumn = nextColumn->GetNext(); } @@ -1352,12 +1366,15 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, } } - if (width > maxWidth) { + nscoord width; + if (widthIsGreater) { // See if the width is even smaller than the ellipsis // If so, clear the text completely. const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis(); - aRenderingContext.SetTextRunRTL(false); - nscoord ellipsisWidth = aRenderingContext.GetWidth(kEllipsis); + aFontMetrics.SetTextRunRTL(false); + nscoord ellipsisWidth = + nsLayoutUtils::AppUnitWidthOfString(kEllipsis, aFontMetrics, + aRenderingContext); width = maxWidth; if (ellipsisWidth > width) @@ -1380,9 +1397,10 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, uint32_t length = aText.Length(); uint32_t i; for (i = 0; i < length; ++i) { - PRUnichar ch = aText[i]; + char16_t ch = aText[i]; // XXX this is horrible and doesn't handle clusters - cwidth = aRenderingContext.GetWidth(ch); + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aFontMetrics, + aRenderingContext); if (twidth + cwidth > width) break; twidth += cwidth; @@ -1399,8 +1417,9 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, int32_t length = aText.Length(); int32_t i; for (i=length-1; i >= 0; --i) { - PRUnichar ch = aText[i]; - cwidth = aRenderingContext.GetWidth(ch); + char16_t ch = aText[i]; + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aFontMetrics, + aRenderingContext); if (twidth + cwidth > width) break; twidth += cwidth; @@ -1421,15 +1440,17 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, int32_t length = aText.Length(); int32_t rightPos = length - 1; for (int32_t leftPos = 0; leftPos < rightPos; ++leftPos) { - PRUnichar ch = aText[leftPos]; - cwidth = aRenderingContext.GetWidth(ch); + char16_t ch = aText[leftPos]; + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aFontMetrics, + aRenderingContext); twidth += cwidth; if (twidth > width) break; leftStr.Append(ch); ch = aText[rightPos]; - cwidth = aRenderingContext.GetWidth(ch); + cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aFontMetrics, + aRenderingContext); twidth += cwidth; if (twidth > width) break; @@ -1443,10 +1464,11 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, break; } } - - width = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, aText.get(), aText.Length()); } + width = nsLayoutUtils::AppUnitWidthOfStringBidi(aText, this, aFontMetrics, + aRenderingContext); + switch (aColumn->GetTextAlignment()) { case NS_STYLE_TEXT_ALIGN_RIGHT: { aTextRect.x += aTextRect.width - width; @@ -1499,10 +1521,8 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, bool isRTL = StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; nsPresContext* presContext = PresContext(); - nsRefPtr<nsRenderingContext> rc = - presContext->PresShell()->GetReferenceRenderingContext(); - if (!rc) - return nsCSSAnonBoxes::moztreecell; + nsRenderingContext rc( + presContext->PresShell()->CreateReferenceRenderingContext()); if (aColumn->IsPrimary()) { // If we're the primary column, we have indentation and a twisty. @@ -1536,7 +1556,7 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, nsRect imageSize; GetTwistyRect(aRowIndex, aColumn, imageSize, twistyRect, presContext, - *rc, twistyContext); + rc, twistyContext); // We will treat a click as hitting the twisty if it happens on the margins, borders, padding, // or content of the twisty object. By allowing a "slop" into the margin, we make it a little @@ -1604,9 +1624,7 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, nsRefPtr<nsFontMetrics> fm; nsLayoutUtils::GetFontMetricsForStyleContext(textContext, getter_AddRefs(fm)); - rc->SetFont(fm); - - AdjustForCellText(cellText, aRowIndex, aColumn, *rc, textRect); + AdjustForCellText(cellText, aRowIndex, aColumn, rc, *fm, textRect); if (aX >= textRect.x && aX < textRect.x + textRect.width) return nsCSSAnonBoxes::moztreecelltext; @@ -1734,11 +1752,9 @@ nsTreeBodyFrame::GetCellWidth(int32_t aRow, nsTreeColumn* aCol, nsRefPtr<nsFontMetrics> fm; nsLayoutUtils::GetFontMetricsForStyleContext(textContext, getter_AddRefs(fm)); - aRenderingContext->SetFont(fm); - // Get the width of the text itself - nscoord width = - nsLayoutUtils::GetStringWidth(this, aRenderingContext, cellText.get(), cellText.Length()); + nscoord width = nsLayoutUtils::AppUnitWidthOfStringBidi(cellText, this, *fm, + *aRenderingContext); nscoord totalTextWidth = width + bp.left + bp.right; aDesiredSize += totalTextWidth; return NS_OK; @@ -1754,11 +1770,10 @@ nsTreeBodyFrame::IsCellCropped(int32_t aRow, nsITreeColumn* aCol, bool *_retval) if (!col) return NS_ERROR_INVALID_ARG; - nsRefPtr<nsRenderingContext> rc = - PresContext()->PresShell()->GetReferenceRenderingContext(); - NS_ENSURE_TRUE(rc, NS_ERROR_FAILURE); + nsRenderingContext rc( + PresContext()->PresShell()->CreateReferenceRenderingContext()); - rv = GetCellWidth(aRow, col, rc, desiredSize, currentSize); + rv = GetCellWidth(aRow, col, &rc, desiredSize, currentSize); NS_ENSURE_SUCCESS(rv, rv); *_retval = desiredSize > currentSize; @@ -2076,7 +2091,7 @@ nsTreeBodyFrame::GetTwistyRect(int32_t aRowIndex, if (useTheme) { nsIntSize minTwistySizePx(0,0); bool canOverride = true; - theme->GetMinimumWidgetSize(&aRenderingContext, this, twistyDisplayData->mAppearance, + theme->GetMinimumWidgetSize(aPresContext, this, twistyDisplayData->mAppearance, &minTwistySizePx, &canOverride); // GMWS() returns size in pixels, we need to convert it back to app units @@ -2161,7 +2176,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex if (styleRequest) { styleRequest->Clone(imgNotificationObserver, getter_AddRefs(imageRequest)); } else { - nsIDocument* doc = mContent->GetDocument(); + nsIDocument* doc = mContent->GetComposedDoc(); if (!doc) // The page is currently being torn down. Why bother. return NS_ERROR_FAILURE; @@ -2184,8 +2199,10 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex doc, mContent->NodePrincipal(), doc->GetDocumentURI(), + doc->GetReferrerPolicy(), imgNotificationObserver, nsIRequest::LOAD_NORMAL, + EmptyString(), getter_AddRefs(imageRequest)); NS_ENSURE_SUCCESS(rv, rv); @@ -2503,14 +2520,14 @@ nsTreeBodyFrame::CalcHorzWidth(const ScrollParts& aParts) return width; } -NS_IMETHODIMP +nsresult nsTreeBodyFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) { // Check the GetScriptHandlingObject so we don't end up running code when // the document is a zombie. bool dummy; - if (mView && GetContent()->GetCurrentDoc()->GetScriptHandlingObject(dummy)) { + if (mView && GetContent()->GetComposedDoc()->GetScriptHandlingObject(dummy)) { int32_t row; nsTreeColumn* col; nsIAtom* child; @@ -2532,10 +2549,10 @@ nsTreeBodyFrame::GetCursor(const nsPoint& aPoint, return nsLeafBoxFrame::GetCursor(aPoint, aCursor); } -static uint32_t GetDropEffect(nsGUIEvent* aEvent) +static uint32_t GetDropEffect(WidgetGUIEvent* aEvent) { - NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "wrong event type"); - nsDragEvent* dragEvent = static_cast<nsDragEvent *>(aEvent); + NS_ASSERTION(aEvent->mClass == eDragEventClass, "wrong event type"); + WidgetDragEvent* dragEvent = aEvent->AsDragEvent(); nsContentUtils::SetDataTransferInEvent(dragEvent); uint32_t action = 0; @@ -2544,9 +2561,9 @@ static uint32_t GetDropEffect(nsGUIEvent* aEvent) return action; } -NS_IMETHODIMP +nsresult nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, + WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { if (aEvent->message == NS_MOUSE_ENTER_SYNTH || aEvent->message == NS_MOUSE_MOVE) { @@ -2681,9 +2698,9 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext, // The dataTransfer was initialized by the call to GetDropEffect above. bool canDropAtNewLocation = false; - nsDragEvent* dragEvent = static_cast<nsDragEvent *>(aEvent); mView->CanDrop(mSlots->mDropRow, mSlots->mDropOrient, - dragEvent->dataTransfer, &canDropAtNewLocation); + aEvent->AsDragEvent()->dataTransfer, + &canDropAtNewLocation); if (canDropAtNewLocation) { // Invalidate row at the new location. @@ -2712,8 +2729,8 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext, rv = mView->GetParentIndex(parentIndex, &parentIndex); } - NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "wrong event type"); - nsDragEvent* dragEvent = static_cast<nsDragEvent*>(aEvent); + NS_ASSERTION(aEvent->mClass == eDragEventClass, "wrong event type"); + WidgetDragEvent* dragEvent = aEvent->AsDragEvent(); nsContentUtils::SetDataTransferInEvent(dragEvent); mView->Drop(mSlots->mDropRow, mSlots->mDropOrient, dragEvent->dataTransfer); @@ -2756,25 +2773,40 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext, return NS_OK; } -static nsLineStyle -ConvertBorderStyleToLineStyle(uint8_t aBorderStyle) -{ - switch (aBorderStyle) { - case NS_STYLE_BORDER_STYLE_DOTTED: - return nsLineStyle_kDotted; - case NS_STYLE_BORDER_STYLE_DASHED: - return nsLineStyle_kDashed; - default: - return nsLineStyle_kSolid; +class nsDisplayTreeBody final : public nsDisplayItem { +public: + nsDisplayTreeBody(nsDisplayListBuilder* aBuilder, nsFrame* aFrame) : + nsDisplayItem(aBuilder, aFrame), + mDisableSubpixelAA(false) { + MOZ_COUNT_CTOR(nsDisplayTreeBody); } -} +#ifdef NS_BUILD_REFCNT_LOGGING + virtual ~nsDisplayTreeBody() { + MOZ_COUNT_DTOR(nsDisplayTreeBody); + } +#endif -static void -PaintTreeBody(nsIFrame* aFrame, nsRenderingContext* aCtx, - const nsRect& aDirtyRect, nsPoint aPt) -{ - static_cast<nsTreeBodyFrame*>(aFrame)->PaintTreeBody(*aCtx, aDirtyRect, aPt); -} + virtual void Paint(nsDisplayListBuilder* aBuilder, + nsRenderingContext* aCtx) override + { + gfxContext* ctx = aCtx->ThebesContext(); + gfxContextAutoDisableSubpixelAntialiasing disable(ctx, mDisableSubpixelAA); + static_cast<nsTreeBodyFrame*>(mFrame)-> + PaintTreeBody(*aCtx, mVisibleRect, ToReferenceFrame()); + } + NS_DISPLAY_DECL_NAME("XULTreeBody", TYPE_XUL_TREE_BODY) + + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override + { + bool snap; + return GetBounds(aBuilder, &snap); + } + virtual void DisableComponentAlpha() override { + mDisableSubpixelAA = true; + } + + bool mDisableSubpixelAA; +}; // Painting routines void @@ -2791,12 +2823,11 @@ nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Bail out now if there's no view or we can't run script because the // document is a zombie - if (!mView || !GetContent()->GetCurrentDoc()->GetWindow()) + if (!mView || !GetContent ()->GetComposedDoc()->GetWindow()) return; aLists.Content()->AppendNewToTop(new (aBuilder) - nsDisplayGeneric(aBuilder, this, ::PaintTreeBody, "XULTreeBody", - nsDisplayItem::TYPE_XUL_TREE_BODY)); + nsDisplayTreeBody(aBuilder, this)); } void @@ -2805,8 +2836,14 @@ nsTreeBodyFrame::PaintTreeBody(nsRenderingContext& aRenderingContext, { // Update our available height and our page count. CalcInnerBox(); - aRenderingContext.PushState(); - aRenderingContext.IntersectClip(mInnerBox + aPt); + + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + + gfx->Save(); + gfx->Clip(NSRectToSnappedRect(mInnerBox + aPt, + PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); int32_t oldPageCount = mPageLength; if (!mHasFixedRowCount) mPageLength = mInnerBox.height/mRowHeight; @@ -2864,7 +2901,7 @@ nsTreeBodyFrame::PaintTreeBody(nsRenderingContext& aRenderingContext, PaintDropFeedback(feedbackRect, PresContext(), aRenderingContext, aDirtyRect, aPt); } } - aRenderingContext.PopState(); + gfx->Restore(); } @@ -3184,24 +3221,29 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, twistyContext->StyleMargin()->GetMargin(twistyMargin); twistyRect.Inflate(twistyMargin); - aRenderingContext.PushState(); + aRenderingContext.ThebesContext()->Save(); const nsStyleBorder* borderStyle = lineContext->StyleBorder(); nscolor color; - bool foreground; - borderStyle->GetBorderColor(NS_SIDE_LEFT, color, foreground); - if (foreground) { + bool useForegroundColor; + borderStyle->GetBorderColor(NS_SIDE_LEFT, color, useForegroundColor); + if (useForegroundColor) { // GetBorderColor didn't touch color, thus grab it from the treeline context color = lineContext->StyleColor()->mColor; } - aRenderingContext.SetColor(color); + ColorPattern colorPatt(ToDeviceColor(color)); + uint8_t style; style = borderStyle->GetBorderStyle(NS_SIDE_LEFT); - aRenderingContext.SetLineStyle(ConvertBorderStyleToLineStyle(style)); + StrokeOptions strokeOptions; + nsLayoutUtils::InitDashPattern(strokeOptions, style); nscoord srcX = currX + twistyRect.width - mIndentation / 2; nscoord lineY = (aRowIndex - mTopRowIndex) * mRowHeight + aPt.y; + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + nsPresContext* pc = PresContext(); + // Don't paint off our cell. if (srcX <= cellRect.x + cellRect.width) { nscoord destX = currX + twistyRect.width; @@ -3211,7 +3253,12 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, srcX = currX + remainingWidth - (srcX - cellRect.x); destX = currX + remainingWidth - (destX - cellRect.x); } - aRenderingContext.DrawLine(srcX, lineY + mRowHeight / 2, destX, lineY + mRowHeight / 2); + Point p1(pc->AppUnitsToGfxUnits(srcX), + pc->AppUnitsToGfxUnits(lineY + mRowHeight / 2)); + Point p2(pc->AppUnitsToGfxUnits(destX), + pc->AppUnitsToGfxUnits(lineY + mRowHeight / 2)); + SnapLineToDevicePixelsForStroking(p1, p2, *drawTarget); + drawTarget->StrokeLine(p1, p2, colorPatt, strokeOptions); } int32_t currentParent = aRowIndex; @@ -3220,10 +3267,20 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, // Paint full vertical line only if we have next sibling. bool hasNextSibling; mView->HasNextSibling(currentParent, aRowIndex, &hasNextSibling); - if (hasNextSibling) - aRenderingContext.DrawLine(srcX, lineY, srcX, lineY + mRowHeight); - else if (i == level) - aRenderingContext.DrawLine(srcX, lineY, srcX, lineY + mRowHeight / 2); + if (hasNextSibling || i == level) { + Point p1(pc->AppUnitsToGfxUnits(srcX), + pc->AppUnitsToGfxUnits(lineY)); + Point p2; + p2.x = pc->AppUnitsToGfxUnits(srcX); + + if (hasNextSibling) + p2.y = pc->AppUnitsToGfxUnits(lineY + mRowHeight); + else if (i == level) + p2.y = pc->AppUnitsToGfxUnits(lineY + mRowHeight / 2); + + SnapLineToDevicePixelsForStroking(p1, p2, *drawTarget); + drawTarget->StrokeLine(p1, p2, colorPatt, strokeOptions); + } } int32_t parent; @@ -3233,7 +3290,7 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, srcX -= mIndentation; } - aRenderingContext.PopState(); + aRenderingContext.ThebesContext()->Restore(); } // Always leave space for the twisty. @@ -3256,11 +3313,9 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, nsRect elementRect(currX, cellRect.y, remainingWidth, cellRect.height); nsRect dirtyRect; if (dirtyRect.IntersectRect(aDirtyRect, elementRect)) { - bool textRTL = cellContext->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; switch (aColumn->GetType()) { case nsITreeColumn::TYPE_TEXT: - PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX, - textRTL); + PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX); break; case nsITreeColumn::TYPE_CHECKBOX: PaintCheckbox(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect); @@ -3275,8 +3330,7 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex, break; case nsITreeView::PROGRESS_NONE: default: - PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX, - textRTL); + PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX); break; } break; @@ -3372,8 +3426,9 @@ nsTreeBodyFrame::PaintTwisty(int32_t aRowIndex, } // Paint the image. - nsLayoutUtils::DrawSingleUnscaledImage(&aRenderingContext, image, - gfxPattern::FILTER_NEAREST, pt, &aDirtyRect, + nsLayoutUtils::DrawSingleUnscaledImage(*aRenderingContext.ThebesContext(), + aPresContext, image, + GraphicsFilter::FILTER_NEAREST, pt, &aDirtyRect, imgIContainer::FLAG_NONE, &imageSize); } } @@ -3508,10 +3563,10 @@ nsTreeBodyFrame::PaintImage(int32_t aRowIndex, gfxContext* ctx = aRenderingContext.ThebesContext(); if (opacity != 1.0f) { - ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); + ctx->PushGroup(gfxContentType::COLOR_ALPHA); } - nsLayoutUtils::DrawImage(&aRenderingContext, image, + nsLayoutUtils::DrawImage(*ctx, aPresContext, image, nsLayoutUtils::GetGraphicsFilterForFrame(this), wholeImageDest, destRect, destRect.TopLeft(), aDirtyRect, imgIContainer::FLAG_NONE); @@ -3536,8 +3591,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex, nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, - nscoord& aCurrX, - bool aTextRTL) + nscoord& aCurrX) { NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed"); @@ -3553,6 +3607,9 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex, if (text.Length() == 0) return; // Don't paint an empty string. XXX What about background/borders? Still paint? + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + // Resolve style for the text. It contains all the info we need to lay ourselves // out and to paint. nsStyleContext* textContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecelltext); @@ -3587,9 +3644,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex, } // Set our font. - aRenderingContext.SetFont(fontMet); - - AdjustForCellText(text, aRowIndex, aColumn, aRenderingContext, textRect); + AdjustForCellText(text, aRowIndex, aColumn, aRenderingContext, *fontMet, textRect); textRect.Inflate(bp); // Subtract out the remaining width. @@ -3602,7 +3657,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex, textRect.Deflate(bp); // Set our color. - aRenderingContext.SetColor(textContext->StyleColor()->mColor); + ColorPattern color(ToDeviceColor(textContext->StyleColor()->mColor)); // Draw decorations. uint8_t decorations = textContext->StyleTextReset()->mTextDecorationLine; @@ -3611,25 +3666,39 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex, nscoord size; if (decorations & (NS_FONT_DECORATION_OVERLINE | NS_FONT_DECORATION_UNDERLINE)) { fontMet->GetUnderline(offset, size); - if (decorations & NS_FONT_DECORATION_OVERLINE) - aRenderingContext.FillRect(textRect.x, textRect.y, textRect.width, size); - if (decorations & NS_FONT_DECORATION_UNDERLINE) - aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size); + if (decorations & NS_FONT_DECORATION_OVERLINE) { + nsRect r(textRect.x, textRect.y, textRect.width, size); + Rect devPxRect = + NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget); + drawTarget->FillRect(devPxRect, color); + } + if (decorations & NS_FONT_DECORATION_UNDERLINE) { + nsRect r(textRect.x, textRect.y + baseline - offset, + textRect.width, size); + Rect devPxRect = + NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget); + drawTarget->FillRect(devPxRect, color); + } } if (decorations & NS_FONT_DECORATION_LINE_THROUGH) { fontMet->GetStrikeout(offset, size); - aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size); + nsRect r(textRect.x, textRect.y + baseline - offset, textRect.width, size); + Rect devPxRect = + NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget); + drawTarget->FillRect(devPxRect, color); } - uint8_t direction = aTextRTL ? NS_STYLE_DIRECTION_RTL : - NS_STYLE_DIRECTION_LTR; + nsStyleContext* cellContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecell); gfxContext* ctx = aRenderingContext.ThebesContext(); if (opacity != 1.0f) { - ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); + ctx->PushGroup(gfxContentType::COLOR_ALPHA); } - nsLayoutUtils::DrawString(this, &aRenderingContext, text.get(), text.Length(), - textRect.TopLeft() + nsPoint(0, baseline), direction); + ctx->SetColor(textContext->StyleColor()->mColor); + nsLayoutUtils::DrawString(this, *fontMet, &aRenderingContext, text.get(), + text.Length(), + textRect.TopLeft() + nsPoint(0, baseline), + cellContext); if (opacity != 1.0f) { ctx->PopGroupToSource(); @@ -3695,8 +3764,9 @@ nsTreeBodyFrame::PaintCheckbox(int32_t aRowIndex, } // Paint the image. - nsLayoutUtils::DrawSingleUnscaledImage(&aRenderingContext, image, - gfxPattern::FILTER_NEAREST, pt, &aDirtyRect, + nsLayoutUtils::DrawSingleUnscaledImage(*aRenderingContext.ThebesContext(), + aPresContext, + image, GraphicsFilter::FILTER_NEAREST, pt, &aDirtyRect, imgIContainer::FLAG_NONE, &imageSize); } } @@ -3733,9 +3803,6 @@ nsTreeBodyFrame::PaintProgressMeter(int32_t aRowIndex, // Adjust the rect for its border and padding. AdjustForBorderPadding(meterContext, meterRect); - // Set our color. - aRenderingContext.SetColor(meterContext->StyleColor()->mColor); - // Now obtain the value for our cell. nsAutoString value; mView->GetCellValue(aRowIndex, aColumn, value); @@ -3760,12 +3827,18 @@ nsTreeBodyFrame::PaintProgressMeter(int32_t aRowIndex, image->GetHeight(&height); nsSize size(width*nsDeviceContext::AppUnitsPerCSSPixel(), height*nsDeviceContext::AppUnitsPerCSSPixel()); - nsLayoutUtils::DrawImage(&aRenderingContext, image, + nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(), + aPresContext, image, nsLayoutUtils::GetGraphicsFilterForFrame(this), nsRect(meterRect.TopLeft(), size), meterRect, meterRect.TopLeft(), aDirtyRect, imgIContainer::FLAG_NONE); } else { - aRenderingContext.FillRect(meterRect); + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); + Rect rect = + NSRectToSnappedRect(meterRect, appUnitsPerDevPixel, *drawTarget); + ColorPattern color(ToDeviceColor(meterContext->StyleColor()->mColor)); + drawTarget->FillRect(rect, color); } } else if (state == nsITreeView::PROGRESS_UNDETERMINED) { @@ -3781,7 +3854,8 @@ nsTreeBodyFrame::PaintProgressMeter(int32_t aRowIndex, image->GetHeight(&height); nsSize size(width*nsDeviceContext::AppUnitsPerCSSPixel(), height*nsDeviceContext::AppUnitsPerCSSPixel()); - nsLayoutUtils::DrawImage(&aRenderingContext, image, + nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(), + aPresContext, image, nsLayoutUtils::GetGraphicsFilterForFrame(this), nsRect(meterRect.TopLeft(), size), meterRect, meterRect.TopLeft(), aDirtyRect, imgIContainer::FLAG_NONE); @@ -4039,10 +4113,9 @@ nsresult nsTreeBodyFrame::ScrollToRow(int32_t aRow) { ScrollParts parts = GetScrollParts(); - nsresult rv = ScrollToRowInternal(parts, aRow); - NS_ENSURE_SUCCESS(rv, rv); + ScrollToRowInternal(parts, aRow); UpdateScrollbars(parts); - return rv; + return NS_OK; } nsresult nsTreeBodyFrame::ScrollToRowInternal(const ScrollParts& aParts, int32_t aRow) @@ -4055,62 +4128,43 @@ nsresult nsTreeBodyFrame::ScrollToRowInternal(const ScrollParts& aParts, int32_t nsresult nsTreeBodyFrame::ScrollByLines(int32_t aNumLines) { - if (!mView) + if (!mView) { return NS_OK; - - int32_t newIndex = mTopRowIndex + aNumLines; - if (newIndex < 0) - newIndex = 0; - else { - int32_t lastPageTopRow = mRowCount - mPageLength; - if (newIndex > lastPageTopRow) - newIndex = lastPageTopRow; } + int32_t newIndex = mTopRowIndex + aNumLines; ScrollToRow(newIndex); - return NS_OK; } nsresult nsTreeBodyFrame::ScrollByPages(int32_t aNumPages) { - if (!mView) + if (!mView) { return NS_OK; - - int32_t newIndex = mTopRowIndex + aNumPages * mPageLength; - if (newIndex < 0) - newIndex = 0; - else { - int32_t lastPageTopRow = mRowCount - mPageLength; - if (newIndex > lastPageTopRow) - newIndex = lastPageTopRow; } + int32_t newIndex = mTopRowIndex + aNumPages * mPageLength; ScrollToRow(newIndex); - return NS_OK; } nsresult nsTreeBodyFrame::ScrollInternal(const ScrollParts& aParts, int32_t aRow) { - if (!mView) + if (!mView) { return NS_OK; - - int32_t delta = aRow - mTopRowIndex; - - if (delta > 0) { - if (mTopRowIndex == (mRowCount - mPageLength + 1)) - return NS_OK; - } - else { - if (mTopRowIndex == 0) - return NS_OK; } - mTopRowIndex += delta; + // Note that we may be "over scrolled" at this point; that is the + // current mTopRowIndex may be larger than mRowCount - mPageLength. + // This can happen when items are removed for example. (bug 1085050) + int32_t maxTopRowIndex = std::max(0, mRowCount - mPageLength); + aRow = mozilla::clamped(aRow, 0, maxTopRowIndex); + if (aRow == mTopRowIndex) { + return NS_OK; + } + mTopRowIndex = aRow; Invalidate(); - PostScrollEvent(); return NS_OK; } @@ -4147,48 +4201,85 @@ nsTreeBodyFrame::ScrollHorzInternal(const ScrollParts& aParts, int32_t aPosition return NS_OK; } -NS_IMETHODIMP -nsTreeBodyFrame::ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) +void +nsTreeBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + ScrollByPages(aDirection); +} + +void +nsTreeBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + int32_t newIndex = aDirection < 0 ? 0 : mTopRowIndex; + ScrollToRow(newIndex); +} + +void +nsTreeBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) +{ + MOZ_ASSERT(aScrollbar != nullptr); + ScrollByLines(aDirection); +} + +void +nsTreeBodyFrame::RepeatButtonScroll(nsScrollbarFrame* aScrollbar) { ScrollParts parts = GetScrollParts(); + int32_t increment = aScrollbar->GetIncrement(); + int32_t direction = 0; + if (increment < 0) { + direction = -1; + } else if (increment > 0) { + direction = 1; + } + bool isHorizontal = aScrollbar->IsHorizontal(); - if (aScrollbar == parts.mVScrollbar) { - if (aNewIndex > aOldIndex) - ScrollToRowInternal(parts, mTopRowIndex+1); - else if (aNewIndex < aOldIndex) - ScrollToRowInternal(parts, mTopRowIndex-1); + nsWeakFrame weakFrame(this); + if (isHorizontal) { + int32_t curpos = aScrollbar->MoveToNewPosition(); + if (weakFrame.IsAlive()) { + ScrollHorzInternal(parts, curpos); + } } else { - nsresult rv = ScrollHorzInternal(parts, aNewIndex); - if (NS_FAILED(rv)) return rv; + ScrollToRowInternal(parts, mTopRowIndex+direction); } - UpdateScrollbars(parts); - - return NS_OK; + if (weakFrame.IsAlive() && mScrollbarActivity) { + mScrollbarActivity->ActivityOccurred(); + } + if (weakFrame.IsAlive()) { + UpdateScrollbars(parts); + } } - -NS_IMETHODIMP -nsTreeBodyFrame::PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) + +void +nsTreeBodyFrame::ThumbMoved(nsScrollbarFrame* aScrollbar, + nscoord aOldPos, + nscoord aNewPos) { ScrollParts parts = GetScrollParts(); - if (aOldIndex == aNewIndex) - return NS_OK; + if (aOldPos == aNewPos) + return; + + nsWeakFrame weakFrame(this); // Vertical Scrollbar if (parts.mVScrollbar == aScrollbar) { nscoord rh = nsPresContext::AppUnitsToIntCSSPixels(mRowHeight); - - nscoord newrow = aNewIndex/rh; + nscoord newIndex = nsPresContext::AppUnitsToIntCSSPixels(aNewPos); + nscoord newrow = newIndex/rh; ScrollInternal(parts, newrow); // Horizontal Scrollbar } else if (parts.mHScrollbar == aScrollbar) { - nsresult rv = ScrollHorzInternal(parts, aNewIndex); - if (NS_FAILED(rv)) return rv; + int32_t newIndex = nsPresContext::AppUnitsToIntCSSPixels(aNewPos); + ScrollHorzInternal(parts, newIndex); + } + if (weakFrame.IsAlive()) { + UpdateScrollbars(parts); } - - UpdateScrollbars(parts); - return NS_OK; } // The style cache. @@ -4224,7 +4315,7 @@ nsTreeBodyFrame::GetBaseElement() while (parent) { nsIContent* content = parent->GetContent(); if (content) { - nsINodeInfo* ni = content->NodeInfo(); + dom::NodeInfo* ni = content->NodeInfo(); if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL) || (ni->Equals(nsGkAtoms::select) && @@ -4315,7 +4406,9 @@ nsTreeBodyFrame::CanAutoScroll(int32_t aRowIndex) // For non-containers, if the mouse is in the top 50% of the row, the drop is // _before_ and the bottom 50% _after_ void -nsTreeBodyFrame::ComputeDropPosition(nsGUIEvent* aEvent, int32_t* aRow, int16_t* aOrient, +nsTreeBodyFrame::ComputeDropPosition(WidgetGUIEvent* aEvent, + int32_t* aRow, + int16_t* aOrient, int16_t* aScrollLines) { *aOrient = -1; @@ -4454,10 +4547,10 @@ void nsTreeBodyFrame::FireScrollEvent() { mScrollEvent.Forget(); - nsScrollbarEvent event(true, NS_SCROLL_EVENT, nullptr); + WidgetGUIEvent event(true, NS_SCROLL_EVENT, nullptr); // scroll events fired at elements don't bubble event.mFlags.mBubbles = false; - nsEventDispatcher::Dispatch(GetContent(), PresContext(), &event); + EventDispatcher::Dispatch(GetContent(), PresContext(), &event); } void @@ -4475,6 +4568,22 @@ nsTreeBodyFrame::PostScrollEvent() } void +nsTreeBodyFrame::ScrollbarActivityStarted() const +{ + if (mScrollbarActivity) { + mScrollbarActivity->ActivityStarted(); + } +} + +void +nsTreeBodyFrame::ScrollbarActivityStopped() const +{ + if (mScrollbarActivity) { + mScrollbarActivity->ActivityStopped(); + } +} + +void nsTreeBodyFrame::DetachImageListeners() { mCreatedListeners.Clear(); @@ -4501,40 +4610,38 @@ nsTreeBodyFrame::FireRowCountChangedEvent(int32_t aIndex, int32_t aCount) return; nsCOMPtr<nsIDOMEvent> event; - domDoc->CreateEvent(NS_LITERAL_STRING("datacontainerevents"), + domDoc->CreateEvent(NS_LITERAL_STRING("customevent"), getter_AddRefs(event)); - nsCOMPtr<nsIDOMDataContainerEvent> treeEvent(do_QueryInterface(event)); + nsCOMPtr<nsIDOMCustomEvent> treeEvent(do_QueryInterface(event)); if (!treeEvent) return; - event->InitEvent(NS_LITERAL_STRING("TreeRowCountChanged"), true, false); - - // Set 'index' data - the row index rows are changed from. - nsCOMPtr<nsIWritableVariant> indexVariant( - do_CreateInstance("@mozilla.org/variant;1")); - if (!indexVariant) + nsCOMPtr<nsIWritablePropertyBag2> propBag( + do_CreateInstance("@mozilla.org/hash-property-bag;1")); + if (!propBag) return; - indexVariant->SetAsInt32(aIndex); - treeEvent->SetData(NS_LITERAL_STRING("index"), indexVariant); + // Set 'index' data - the row index rows are changed from. + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("index"), aIndex); // Set 'count' data - the number of changed rows. - nsCOMPtr<nsIWritableVariant> countVariant( + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("count"), aCount); + + nsCOMPtr<nsIWritableVariant> detailVariant( do_CreateInstance("@mozilla.org/variant;1")); - if (!countVariant) + if (!detailVariant) return; - countVariant->SetAsInt32(aCount); - treeEvent->SetData(NS_LITERAL_STRING("count"), countVariant); + detailVariant->SetAsISupports(propBag); + treeEvent->InitCustomEvent(NS_LITERAL_STRING("TreeRowCountChanged"), + true, false, detailVariant); event->SetTrusted(true); - nsRefPtr<nsAsyncDOMEvent> plevent = new nsAsyncDOMEvent(content, event); - if (!plevent) - return; - - plevent->PostDOMEvent(); + nsRefPtr<AsyncEventDispatcher> asyncDispatcher = + new AsyncEventDispatcher(content, event); + asyncDispatcher->PostDOMEvent(); } void @@ -4551,78 +4658,70 @@ nsTreeBodyFrame::FireInvalidateEvent(int32_t aStartRowIdx, int32_t aEndRowIdx, return; nsCOMPtr<nsIDOMEvent> event; - domDoc->CreateEvent(NS_LITERAL_STRING("datacontainerevents"), + domDoc->CreateEvent(NS_LITERAL_STRING("customevent"), getter_AddRefs(event)); - nsCOMPtr<nsIDOMDataContainerEvent> treeEvent(do_QueryInterface(event)); + nsCOMPtr<nsIDOMCustomEvent> treeEvent(do_QueryInterface(event)); if (!treeEvent) return; - event->InitEvent(NS_LITERAL_STRING("TreeInvalidated"), true, false); + nsCOMPtr<nsIWritablePropertyBag2> propBag( + do_CreateInstance("@mozilla.org/hash-property-bag;1")); + if (!propBag) + return; if (aStartRowIdx != -1 && aEndRowIdx != -1) { // Set 'startrow' data - the start index of invalidated rows. - nsCOMPtr<nsIWritableVariant> startRowVariant( - do_CreateInstance("@mozilla.org/variant;1")); - if (!startRowVariant) - return; - - startRowVariant->SetAsInt32(aStartRowIdx); - treeEvent->SetData(NS_LITERAL_STRING("startrow"), startRowVariant); + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("startrow"), + aStartRowIdx); // Set 'endrow' data - the end index of invalidated rows. - nsCOMPtr<nsIWritableVariant> endRowVariant( - do_CreateInstance("@mozilla.org/variant;1")); - if (!endRowVariant) - return; - - endRowVariant->SetAsInt32(aEndRowIdx); - treeEvent->SetData(NS_LITERAL_STRING("endrow"), endRowVariant); + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("endrow"), + aEndRowIdx); } if (aStartCol && aEndCol) { // Set 'startcolumn' data - the start index of invalidated rows. - nsCOMPtr<nsIWritableVariant> startColVariant( - do_CreateInstance("@mozilla.org/variant;1")); - if (!startColVariant) - return; - int32_t startColIdx = 0; nsresult rv = aStartCol->GetIndex(&startColIdx); if (NS_FAILED(rv)) return; - startColVariant->SetAsInt32(startColIdx); - treeEvent->SetData(NS_LITERAL_STRING("startcolumn"), startColVariant); + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("startcolumn"), + startColIdx); // Set 'endcolumn' data - the start index of invalidated rows. - nsCOMPtr<nsIWritableVariant> endColVariant( - do_CreateInstance("@mozilla.org/variant;1")); - if (!endColVariant) - return; - int32_t endColIdx = 0; rv = aEndCol->GetIndex(&endColIdx); if (NS_FAILED(rv)) return; - endColVariant->SetAsInt32(endColIdx); - treeEvent->SetData(NS_LITERAL_STRING("endcolumn"), endColVariant); + propBag->SetPropertyAsInt32(NS_LITERAL_STRING("endcolumn"), + endColIdx); } + nsCOMPtr<nsIWritableVariant> detailVariant( + do_CreateInstance("@mozilla.org/variant;1")); + if (!detailVariant) + return; + + detailVariant->SetAsISupports(propBag); + treeEvent->InitCustomEvent(NS_LITERAL_STRING("TreeInvalidated"), + true, false, detailVariant); + event->SetTrusted(true); - nsRefPtr<nsAsyncDOMEvent> plevent = new nsAsyncDOMEvent(content, event); - if (plevent) - plevent->PostDOMEvent(); + nsRefPtr<AsyncEventDispatcher> asyncDispatcher = + new AsyncEventDispatcher(content, event); + asyncDispatcher->PostDOMEvent(); } #endif class nsOverflowChecker : public nsRunnable { public: - nsOverflowChecker(nsTreeBodyFrame* aFrame) : mFrame(aFrame) {} - NS_IMETHOD Run() + explicit nsOverflowChecker(nsTreeBodyFrame* aFrame) : mFrame(aFrame) {} + NS_IMETHOD Run() override { if (mFrame.IsAlive()) { nsTreeBodyFrame* tree = static_cast<nsTreeBodyFrame*>(mFrame.GetFrame()); @@ -4648,7 +4747,17 @@ nsTreeBodyFrame::FullScrollbarsUpdate(bool aNeedsFullInvalidation) } InvalidateScrollbars(parts, weakColumnsFrame); NS_ENSURE_TRUE(weakFrame.IsAlive(), false); - nsContentUtils::AddScriptRunner(new nsOverflowChecker(this)); + + // Overflow checking dispatches synchronous events, which can cause infinite + // recursion during reflow. Do the first overflow check synchronously, but + // force any nested checks to round-trip through the event loop. See bug + // 905909. + nsRefPtr<nsOverflowChecker> checker = new nsOverflowChecker(this); + if (!mCheckingOverflow) { + nsContentUtils::AddScriptRunner(checker); + } else { + NS_DispatchToCurrentThread(checker); + } return weakFrame.IsAlive(); } diff --git a/layout/xul/tree/nsTreeBodyFrame.h b/layout/xul/tree/nsTreeBodyFrame.h index 0d1557e52..577f3336e 100644 --- a/layout/xul/tree/nsTreeBodyFrame.h +++ b/layout/xul/tree/nsTreeBodyFrame.h @@ -24,8 +24,8 @@ #include "nsScrollbarFrame.h" #include "nsThreadUtils.h" #include "mozilla/LookAndFeel.h" -#include "nsIScrollbarOwner.h" +class nsFontMetrics; class nsOverflowChecker; class nsTreeImageListener; @@ -47,17 +47,16 @@ struct nsTreeImageCacheEntry }; // The actual frame that paints the cells and rows. -class nsTreeBodyFrame MOZ_FINAL +class nsTreeBodyFrame final : public nsLeafBoxFrame , public nsICSSPseudoComparator , public nsIScrollbarMediator , public nsIReflowCallback - , public nsIScrollbarOwner { public: typedef mozilla::layout::ScrollbarActivity ScrollbarActivity; - nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + explicit nsTreeBodyFrame(nsStyleContext* aContext); ~nsTreeBodyFrame(); NS_DECL_QUERYFRAME_TARGET(nsTreeBodyFrame) @@ -82,12 +81,12 @@ public: } nsresult GetView(nsITreeView **aView); nsresult SetView(nsITreeView *aView); - nsresult GetFocused(bool *aFocused); + bool GetFocused() const { return mFocused; } nsresult SetFocused(bool aFocused); nsresult GetTreeBody(nsIDOMElement **aElement); - nsresult GetRowHeight(int32_t *aValue); - nsresult GetRowWidth(int32_t *aValue); - nsresult GetHorizontalPosition(int32_t *aValue); + int32_t RowHeight() const; + int32_t RowWidth(); + int32_t GetHorizontalPosition() const; nsresult GetSelectionRegion(nsIScriptableRegion **aRegion); int32_t FirstVisibleRow() const { return mTopRowIndex; } int32_t LastVisibleRow() const { return mTopRowIndex + mPageLength; } @@ -122,46 +121,51 @@ public: void ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth); - virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, - bool aRemoveOverflowArea = false) MOZ_OVERRIDE; + bool aRemoveOverflowArea = false) override; // nsIReflowCallback - virtual bool ReflowFinished() MOZ_OVERRIDE; - virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; + virtual bool ReflowFinished() override; + virtual void ReflowCallbackCanceled() override; // nsICSSPseudoComparator - virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE; + virtual bool PseudoMatches(nsCSSSelector* aSelector) override; // nsIScrollbarMediator - NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t& aNewIndex) MOZ_OVERRIDE; - NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE; - NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); return NS_OK; } - - // nsIScrollbarOwner - virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) override; + virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override; + virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, + nscoord aOldPos, + nscoord aNewPos) override; + virtual void VisibilityChanged(bool aVisible) override { Invalidate(); } + virtual nsIFrame* GetScrollbarBox(bool aVertical) override { ScrollParts parts = GetScrollParts(); return aVertical ? parts.mVScrollbar : parts.mHScrollbar; } + virtual void ScrollbarActivityStarted() const override; + virtual void ScrollbarActivityStopped() const override; // Overridden from nsIFrame to cache our pres context. - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; - NS_IMETHOD GetCursor(const nsPoint& aPoint, - nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; + virtual nsresult GetCursor(const nsPoint& aPoint, + nsIFrame::Cursor& aCursor) override; - NS_IMETHOD HandleEvent(nsPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) MOZ_OVERRIDE; + virtual nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell); friend class nsTreeColumn; @@ -248,8 +252,7 @@ protected: nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, - nscoord& aCurrX, - bool aTextRTL); + nscoord& aCurrX); // This method paints the checkbox inside a particular cell of the tree. void PaintCheckbox(int32_t aRowIndex, @@ -294,6 +297,7 @@ protected: void AdjustForCellText(nsAutoString& aText, int32_t aRowIndex, nsTreeColumn* aColumn, nsRenderingContext& aRenderingContext, + nsFontMetrics& aFontMetrics, nsRect& aTextRect); // A helper used when hit testing. @@ -402,7 +406,9 @@ protected: // Also calc if we're in the region in which we want to auto-scroll the tree. // A positive value of |aScrollLines| means scroll down, a negative value // means scroll up, a zero value means that we aren't in drag scroll region. - void ComputeDropPosition(nsGUIEvent* aEvent, int32_t* aRow, int16_t* aOrient, + void ComputeDropPosition(mozilla::WidgetGUIEvent* aEvent, + int32_t* aRow, + int16_t* aOrient, int16_t* aScrollLines); // Mark ourselves dirty if we're a select widget @@ -454,7 +460,7 @@ protected: class ScrollEvent : public nsRunnable { public: NS_DECL_NSIRUNNABLE - ScrollEvent(nsTreeBodyFrame *aInner) : mInner(aInner) {} + explicit ScrollEvent(nsTreeBodyFrame *aInner) : mInner(aInner) {} void Revoke() { mInner = nullptr; } private: nsTreeBodyFrame* mInner; @@ -472,7 +478,7 @@ protected: #ifdef ACCESSIBILITY /** * Fires 'treeRowCountChanged' event asynchronously. The event supports - * nsIDOMDataContainerEvent interface that is used to expose the following + * nsIDOMCustomEvent interface that is used to expose the following * information structures. * * @param aIndex the row index rows are added/removed from @@ -483,7 +489,7 @@ protected: /** * Fires 'treeInvalidated' event asynchronously. The event supports - * nsIDOMDataContainerEvent interface that is used to expose the information + * nsIDOMCustomEvent interface that is used to expose the information * structures described by method arguments. * * @param aStartRow the start index of invalidated rows, -1 means that @@ -543,7 +549,7 @@ protected: // Data Members nsRevocableEventPtr<ScrollEvent> mScrollEvent; - nsCOMPtr<ScrollbarActivity> mScrollbarActivity; + nsRefPtr<ScrollbarActivity> mScrollbarActivity; // The cached box object parent. nsCOMPtr<nsITreeBoxObject> mTreeBoxObject; @@ -617,6 +623,10 @@ protected: // Data Members bool mReflowCallbackPosted; + // Set while we flush layout to take account of effects of + // overflow/underflow event handlers + bool mCheckingOverflow; + // Hash table to keep track of which listeners we created and thus // have pointers to us. nsTHashtable<nsPtrHashKey<nsTreeImageListener> > mCreatedListeners; diff --git a/layout/xul/tree/nsTreeBoxObject.cpp b/layout/xul/tree/nsTreeBoxObject.cpp deleted file mode 100644 index e00c8a3e2..000000000 --- a/layout/xul/tree/nsTreeBoxObject.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* -*- 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/. */ - -#include "nsTreeBoxObject.h" -#include "nsCOMPtr.h" -#include "nsIDOMXULElement.h" -#include "nsIXULTemplateBuilder.h" -#include "nsTreeContentView.h" -#include "nsITreeSelection.h" -#include "nsChildIterator.h" -#include "nsContentUtils.h" -#include "nsError.h" -#include "nsTreeBodyFrame.h" - -NS_IMPL_CYCLE_COLLECTION_1(nsTreeBoxObject, mView) - -NS_IMPL_ADDREF_INHERITED(nsTreeBoxObject, nsBoxObject) -NS_IMPL_RELEASE_INHERITED(nsTreeBoxObject, nsBoxObject) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsTreeBoxObject) - NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject) -NS_INTERFACE_MAP_END_INHERITING(nsBoxObject) - -void -nsTreeBoxObject::Clear() -{ - ClearCachedValues(); - - // Drop the view's ref to us. - if (mView) { - nsCOMPtr<nsITreeSelection> sel; - mView->GetSelection(getter_AddRefs(sel)); - if (sel) - sel->SetTree(nullptr); - mView->SetTree(nullptr); // Break the circular ref between the view and us. - } - mView = nullptr; - - nsBoxObject::Clear(); -} - - -nsTreeBoxObject::nsTreeBoxObject() - : mTreeBody(nullptr) -{ -} - -nsTreeBoxObject::~nsTreeBoxObject() -{ - /* destructor code */ -} - - -static void FindBodyElement(nsIContent* aParent, nsIContent** aResult) -{ - *aResult = nullptr; - ChildIterator iter, last; - for (ChildIterator::Init(aParent, &iter, &last); iter != last; ++iter) { - nsCOMPtr<nsIContent> content = *iter; - - nsINodeInfo *ni = content->NodeInfo(); - if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) { - *aResult = content; - NS_ADDREF(*aResult); - break; - } else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) { - // There are nesting tree elements. Only the innermost should - // find the treechilren. - break; - } else if (content->IsElement() && - !ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) { - FindBodyElement(content, aResult); - if (*aResult) - break; - } - } -} - -nsTreeBodyFrame* -nsTreeBoxObject::GetTreeBody(bool aFlushLayout) -{ - // Make sure our frames are up to date, and layout as needed. We - // have to do this before checking for our cached mTreeBody, since - // it might go away on style flush, and in any case if aFlushLayout - // is true we need to make sure to flush no matter what. - // XXXbz except that flushing style when we were not asked to flush - // layout here breaks things. See bug 585123. - nsIFrame* frame; - if (aFlushLayout) { - frame = GetFrame(aFlushLayout); - if (!frame) - return nullptr; - } - - if (mTreeBody) { - // Have one cached already. - return mTreeBody; - } - - if (!aFlushLayout) { - frame = GetFrame(aFlushLayout); - if (!frame) - return nullptr; - } - - // Iterate over our content model children looking for the body. - nsCOMPtr<nsIContent> content; - FindBodyElement(frame->GetContent(), getter_AddRefs(content)); - if (!content) - return nullptr; - - frame = content->GetPrimaryFrame(); - if (!frame) - return nullptr; - - // Make sure that the treebodyframe has a pointer to |this|. - nsTreeBodyFrame *treeBody = do_QueryFrame(frame); - NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr); - - mTreeBody = treeBody; - return mTreeBody; -} - -NS_IMETHODIMP nsTreeBoxObject::GetView(nsITreeView * *aView) -{ - if (!mTreeBody) { - if (!GetTreeBody()) { - // Don't return an uninitialised view - *aView = nullptr; - return NS_OK; - } - - if (mView) - // Our new frame needs to initialise itself - return mTreeBody->GetView(aView); - } - if (!mView) { - nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(mContent); - if (xulele) { - // See if there is a XUL tree builder associated with the element - nsCOMPtr<nsIXULTemplateBuilder> builder; - xulele->GetBuilder(getter_AddRefs(builder)); - mView = do_QueryInterface(builder); - - if (!mView) { - // No tree builder, create a tree content view. - nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView)); - NS_ENSURE_SUCCESS(rv, rv); - } - - // Initialise the frame and view - mTreeBody->SetView(mView); - } - } - NS_IF_ADDREF(*aView = mView); - return NS_OK; -} - -static bool -CanTrustView(nsISupports* aValue) -{ - // Untrusted content is only allowed to specify known-good views - if (nsContentUtils::IsCallerChrome()) - return true; - nsCOMPtr<nsINativeTreeView> nativeTreeView = do_QueryInterface(aValue); - if (!nativeTreeView || NS_FAILED(nativeTreeView->EnsureNative())) { - // XXX ERRMSG need a good error here for developers - return false; - } - return true; -} - -NS_IMETHODIMP nsTreeBoxObject::SetView(nsITreeView * aView) -{ - if (!CanTrustView(aView)) - return NS_ERROR_DOM_SECURITY_ERR; - - mView = aView; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - body->SetView(aView); - - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetFocused(bool* aFocused) -{ - *aFocused = false; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetFocused(aFocused); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::SetFocused(bool aFocused) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->SetFocused(aFocused); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetTreeBody(nsIDOMElement** aElement) -{ - *aElement = nullptr; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetTreeBody(aElement); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetColumns(nsITreeColumns** aColumns) -{ - *aColumns = nullptr; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - *aColumns = body->Columns().get(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetRowHeight(int32_t* aRowHeight) -{ - *aRowHeight = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetRowHeight(aRowHeight); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetRowWidth(int32_t *aRowWidth) -{ - *aRowWidth = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetRowWidth(aRowWidth); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetFirstVisibleRow(int32_t *aFirstVisibleRow) -{ - *aFirstVisibleRow = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - *aFirstVisibleRow = body->FirstVisibleRow(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetLastVisibleRow(int32_t *aLastVisibleRow) -{ - *aLastVisibleRow = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - *aLastVisibleRow = body->LastVisibleRow(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetHorizontalPosition(int32_t *aHorizontalPosition) -{ - *aHorizontalPosition = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetHorizontalPosition(aHorizontalPosition); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetPageLength(int32_t *aPageLength) -{ - *aPageLength = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - *aPageLength = body->PageLength(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetSelectionRegion(nsIScriptableRegion **aRegion) -{ - *aRegion = nullptr; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetSelectionRegion(aRegion); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::EnsureRowIsVisible(int32_t aRow) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->EnsureRowIsVisible(aRow); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->EnsureCellIsVisible(aRow, aCol); - return NS_OK; - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollToRow(int32_t aRow) -{ - nsTreeBodyFrame* body = GetTreeBody(true); - if (body) - return body->ScrollToRow(aRow); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollByLines(int32_t aNumLines) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ScrollByLines(aNumLines); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollByPages(int32_t aNumPages) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ScrollByPages(aNumPages); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollToCell(int32_t aRow, nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ScrollToCell(aRow, aCol); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollToColumn(nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ScrollToColumn(aCol); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::ScrollToHorizontalPosition(int32_t aHorizontalPosition) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ScrollToHorizontalPosition(aHorizontalPosition); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::Invalidate() -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->Invalidate(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::InvalidateColumn(nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->InvalidateColumn(aCol); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::InvalidateRow(int32_t aIndex) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->InvalidateRow(aIndex); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::InvalidateCell(int32_t aRow, nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->InvalidateCell(aRow, aCol); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->InvalidateRange(aStart, aEnd); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::InvalidateColumnRange(int32_t aStart, int32_t aEnd, nsITreeColumn* aCol) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->InvalidateColumnRange(aStart, aEnd, aCol); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetRowAt(int32_t x, int32_t y, int32_t *aRow) -{ - *aRow = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetRowAt(x, y, aRow); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t *aRow, nsITreeColumn** aCol, - nsACString& aChildElt) -{ - *aRow = 0; - *aCol = nullptr; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetCellAt(aX, aY, aRow, aCol, aChildElt); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const nsACString& aElement, - int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight) -{ - *aX = *aY = *aWidth = *aHeight = 0; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->GetCoordsForCellItem(aRow, aCol, aElement, aX, aY, aWidth, aHeight); - return NS_OK; -} - -NS_IMETHODIMP -nsTreeBoxObject::IsCellCropped(int32_t aRow, nsITreeColumn* aCol, bool *aIsCropped) -{ - *aIsCropped = false; - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->IsCellCropped(aRow, aCol, aIsCropped); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta) -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->RowCountChanged(aIndex, aDelta); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::BeginUpdateBatch() -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->BeginUpdateBatch(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::EndUpdateBatch() -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->EndUpdateBatch(); - return NS_OK; -} - -NS_IMETHODIMP nsTreeBoxObject::ClearStyleAndImageCaches() -{ - nsTreeBodyFrame* body = GetTreeBody(); - if (body) - return body->ClearStyleAndImageCaches(); - return NS_OK; -} - -void -nsTreeBoxObject::ClearCachedValues() -{ - mTreeBody = nullptr; -} - -// Creation Routine /////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewTreeBoxObject(nsIBoxObject** aResult) -{ - *aResult = new nsTreeBoxObject; - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; -} - diff --git a/layout/xul/tree/nsTreeBoxObject.h b/layout/xul/tree/nsTreeBoxObject.h deleted file mode 100644 index 897b22684..000000000 --- a/layout/xul/tree/nsTreeBoxObject.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- 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 nsTreeBoxObject_h___ -#define nsTreeBoxObject_h___ - -#include "mozilla/Attributes.h" -#include "nsBoxObject.h" -#include "nsITreeView.h" -#include "nsITreeBoxObject.h" - -class nsTreeBodyFrame; - -class nsTreeBoxObject : public nsITreeBoxObject, public nsBoxObject -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsTreeBoxObject, nsBoxObject) - NS_DECL_NSITREEBOXOBJECT - - nsTreeBoxObject(); - ~nsTreeBoxObject(); - - nsTreeBodyFrame* GetTreeBody(bool aFlushLayout = false); - nsTreeBodyFrame* GetCachedTreeBody() { return mTreeBody; } - - //NS_PIBOXOBJECT interfaces - virtual void Clear() MOZ_OVERRIDE; - virtual void ClearCachedValues() MOZ_OVERRIDE; - -protected: - nsTreeBodyFrame* mTreeBody; - nsCOMPtr<nsITreeView> mView; -}; - -#endif diff --git a/layout/xul/tree/nsTreeColFrame.cpp b/layout/xul/tree/nsTreeColFrame.cpp index 2a958a0b1..86a660b79 100644 --- a/layout/xul/tree/nsTreeColFrame.cpp +++ b/layout/xul/tree/nsTreeColFrame.cpp @@ -8,11 +8,10 @@ #include "nsGkAtoms.h" #include "nsIContent.h" #include "nsStyleContext.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsIBoxObject.h" -#include "nsTreeBoxObject.h" +#include "mozilla/dom/TreeBoxObject.h" #include "nsIDOMElement.h" -#include "nsITreeBoxObject.h" #include "nsITreeColumns.h" #include "nsIDOMXULTreeElement.h" #include "nsDisplayList.h" @@ -26,7 +25,7 @@ nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsTreeColFrame(aPresShell, aContext); + return new (aPresShell) nsTreeColFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsTreeColFrame) @@ -37,9 +36,9 @@ nsTreeColFrame::~nsTreeColFrame() } void -nsTreeColFrame::Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) +nsTreeColFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) { nsBoxFrame::Init(aContent, aParent, aPrevInFlow); InvalidateColumns(); @@ -66,7 +65,8 @@ public: #endif virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); + HitTestState* aState, + nsTArray<nsIFrame*> *aOutFrames) override; NS_DISPLAY_DECL_NAME("XULTreeColSplitterTarget", TYPE_XUL_TREE_COL_SPLITTER_TARGET) }; @@ -127,7 +127,7 @@ nsTreeColFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsDisplayXULTreeColSplitterTarget(aBuilder, this)); } -NS_IMETHODIMP +nsresult nsTreeColFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) @@ -187,7 +187,8 @@ nsTreeColFrame::InvalidateColumns(bool aCanWalkFrameTree) if (aCanWalkFrameTree) { treeBoxObject->GetColumns(getter_AddRefs(columns)); } else { - nsTreeBodyFrame* body = static_cast<nsTreeBoxObject*>(treeBoxObject)->GetCachedTreeBody(); + nsTreeBodyFrame* body = static_cast<mozilla::dom::TreeBoxObject*> + (treeBoxObject)->GetCachedTreeBodyFrame(); if (body) { columns = body->Columns(); } diff --git a/layout/xul/tree/nsTreeColFrame.h b/layout/xul/tree/nsTreeColFrame.h index bad44a539..a1c7c2016 100644 --- a/layout/xul/tree/nsTreeColFrame.h +++ b/layout/xul/tree/nsTreeColFrame.h @@ -16,26 +16,25 @@ class nsTreeColFrame : public nsBoxFrame public: NS_DECL_FRAMEARENA_HELPERS - nsTreeColFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext): - nsBoxFrame(aPresShell, aContext) {} + explicit nsTreeColFrame(nsStyleContext* aContext): + nsBoxFrame(aContext) {} - virtual void Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; - virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; + const nsDisplayListSet& aLists) override; - NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) MOZ_OVERRIDE; + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) override; virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, - bool aRemoveOverflowArea = false) MOZ_OVERRIDE; + bool aRemoveOverflowArea = false) override; friend nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); diff --git a/layout/xul/tree/nsTreeColumns.cpp b/layout/xul/tree/nsTreeColumns.cpp index 56f8cd5f7..03a1d5959 100644 --- a/layout/xul/tree/nsTreeColumns.cpp +++ b/layout/xul/tree/nsTreeColumns.cpp @@ -3,7 +3,7 @@ * 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/. */ -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsIDOMElement.h" #include "nsIBoxObject.h" @@ -11,10 +11,11 @@ #include "nsTreeUtils.h" #include "nsStyleContext.h" #include "nsDOMClassInfoID.h" -#include "nsINodeInfo.h" #include "nsContentUtils.h" #include "nsTreeBodyFrame.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/TreeBoxObject.h" +#include "mozilla/dom/TreeColumnBinding.h" #include "mozilla/dom/TreeColumnsBinding.h" using namespace mozilla; @@ -40,7 +41,10 @@ nsTreeColumn::~nsTreeColumn() } } +NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeColumn) + NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeColumn) + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent) if (tmp->mNext) { tmp->mNext->SetPrevious(nullptr); @@ -50,18 +54,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeColumn) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNext) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsTreeColumn) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn) -DOMCI_DATA(TreeColumn, nsTreeColumn) - // QueryInterface implementation for nsTreeColumn NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsITreeColumn) NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeColumn) if (aIID.Equals(NS_GET_IID(nsTreeColumn))) { AddRef(); *aInstancePtr = this; @@ -192,7 +196,7 @@ nsTreeColumn::GetId(nsAString& aId) } NS_IMETHODIMP -nsTreeColumn::GetIdConst(const PRUnichar** aIdConst) +nsTreeColumn::GetIdConst(const char16_t** aIdConst) { *aIdConst = mId.get(); return NS_OK; @@ -342,12 +346,56 @@ nsTreeColumn::Invalidate() return NS_OK; } +nsIContent* +nsTreeColumn::GetParentObject() const +{ + return mContent; +} + +/* virtual */ JSObject* +nsTreeColumn::WrapObject(JSContext* aCx) +{ + return dom::TreeColumnBinding::Wrap(aCx, this); +} + +mozilla::dom::Element* +nsTreeColumn::GetElement(mozilla::ErrorResult& aRv) +{ + nsCOMPtr<nsIDOMElement> element; + aRv = GetElement(getter_AddRefs(element)); + if (aRv.Failed()) { + return nullptr; + } + nsCOMPtr<nsINode> node = do_QueryInterface(element); + return node->AsElement(); +} + +int32_t +nsTreeColumn::GetX(mozilla::ErrorResult& aRv) +{ + int32_t x; + aRv = GetX(&x); + return x; +} + +int32_t +nsTreeColumn::GetWidth(mozilla::ErrorResult& aRv) +{ + int32_t width; + aRv = GetWidth(&width); + return width; +} + +void +nsTreeColumn::Invalidate(mozilla::ErrorResult& aRv) +{ + aRv = Invalidate(); +} nsTreeColumns::nsTreeColumns(nsTreeBodyFrame* aTree) : mTree(aTree), mFirstColumn(nullptr) { - SetIsDOMBinding(); } nsTreeColumns::~nsTreeColumns() @@ -374,15 +422,15 @@ nsTreeColumns::GetParentObject() const } /* virtual */ JSObject* -nsTreeColumns::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) +nsTreeColumns::WrapObject(JSContext* aCx) { - return dom::TreeColumnsBinding::Wrap(aCx, aScope, this); + return dom::TreeColumnsBinding::Wrap(aCx, this); } -nsITreeBoxObject* +dom::TreeBoxObject* nsTreeColumns::GetTree() const { - return mTree ? mTree->GetTreeBoxObject() : nullptr; + return mTree ? static_cast<mozilla::dom::TreeBoxObject*>(mTree->GetTreeBoxObject()) : nullptr; } NS_IMETHODIMP @@ -557,6 +605,12 @@ nsTreeColumns::NamedGetter(const nsAString& aId, bool& aFound) return nullptr; } +bool +nsTreeColumns::NameIsEnumerable(const nsAString& aName) +{ + return true; +} + nsTreeColumn* nsTreeColumns::GetNamedColumn(const nsAString& aId) { @@ -572,7 +626,7 @@ nsTreeColumns::GetNamedColumn(const nsAString& aId, nsITreeColumn** _retval) } void -nsTreeColumns::GetSupportedNames(nsTArray<nsString>& aNames) +nsTreeColumns::GetSupportedNames(unsigned, nsTArray<nsString>& aNames) { for (nsTreeColumn* currCol = mFirstColumn; currCol; currCol = currCol->GetNext()) { aNames.AppendElement(currCol->GetId()); diff --git a/layout/xul/tree/nsTreeColumns.h b/layout/xul/tree/nsTreeColumns.h index 88f5a6cc9..3a59e4a82 100644 --- a/layout/xul/tree/nsTreeColumns.h +++ b/layout/xul/tree/nsTreeColumns.h @@ -13,6 +13,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsAutoPtr.h" #include "nsWrapperCache.h" +#include "nsString.h" class nsTreeBodyFrame; class nsTreeColumns; @@ -21,8 +22,10 @@ class nsIContent; struct nsRect; namespace mozilla { +class ErrorResult; namespace dom { class Element; +class TreeBoxObject; } // namespace dom } // namespace mozilla @@ -36,21 +39,48 @@ class Element; // This class is our column info. We use it to iterate our columns and to obtain // information about each column. -class nsTreeColumn MOZ_FINAL : public nsITreeColumn { +class nsTreeColumn final : public nsITreeColumn + , public nsWrapperCache +{ public: nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent); - ~nsTreeColumn(); NS_DECLARE_STATIC_IID_ACCESSOR(NS_TREECOLUMN_IMPL_CID) NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeColumn) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsTreeColumn) NS_DECL_NSITREECOLUMN + // WebIDL + nsIContent* GetParentObject() const; + virtual JSObject* WrapObject(JSContext* aCx) override; + + mozilla::dom::Element* GetElement(mozilla::ErrorResult& aRv); + + nsTreeColumns* GetColumns() const { return mColumns; } + + int32_t GetX(mozilla::ErrorResult& aRv); + int32_t GetWidth(mozilla::ErrorResult& aRv); + + // GetId is fine + int32_t Index() const { return mIndex; } + + bool Primary() const { return mIsPrimary; } + bool Cycler() const { return mIsCycler; } + bool Editable() const { return mIsEditable; } + bool Selectable() const { return mIsSelectable; } + int16_t Type() const { return mType; } + + nsTreeColumn* GetNext() const { return mNext; } + nsTreeColumn* GetPrevious() const { return mPrevious; } + + void Invalidate(mozilla::ErrorResult& aRv); + friend class nsTreeBodyFrame; friend class nsTreeColumns; protected: + ~nsTreeColumn(); nsIFrame* GetFrame(); nsIFrame* GetFrame(nsTreeBodyFrame* aBodyFrame); // Don't call this if GetWidthInTwips or GetRect fails @@ -84,8 +114,6 @@ protected: int8_t GetCropStyle() { return mCropStyle; } int32_t GetTextAlignment() { return mTextAlignment; } - nsTreeColumn* GetNext() { return mNext; } - nsTreeColumn* GetPrevious() { return mPrevious; } void SetNext(nsTreeColumn* aNext) { NS_ASSERTION(!mNext, "already have a next sibling"); mNext = aNext; @@ -122,23 +150,24 @@ private: NS_DEFINE_STATIC_IID_ACCESSOR(nsTreeColumn, NS_TREECOLUMN_IMPL_CID) -class nsTreeColumns MOZ_FINAL : public nsITreeColumns +class nsTreeColumns final : public nsITreeColumns , public nsWrapperCache { -public: - nsTreeColumns(nsTreeBodyFrame* aTree); +private: ~nsTreeColumns(); +public: + explicit nsTreeColumns(nsTreeBodyFrame* aTree); + NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsTreeColumns) NS_DECL_NSITREECOLUMNS nsIContent* GetParentObject() const; - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; + virtual JSObject* WrapObject(JSContext* aCx) override; // WebIDL - nsITreeBoxObject* GetTree() const; + mozilla::dom::TreeBoxObject* GetTree() const; uint32_t Count(); uint32_t Length() { @@ -157,8 +186,9 @@ public: nsTreeColumn* IndexedGetter(uint32_t aIndex, bool& aFound); nsTreeColumn* GetColumnAt(uint32_t aIndex); nsTreeColumn* NamedGetter(const nsAString& aId, bool& aFound); + bool NameIsEnumerable(const nsAString& aName); nsTreeColumn* GetNamedColumn(const nsAString& aId); - void GetSupportedNames(nsTArray<nsString>& aNames); + void GetSupportedNames(unsigned, nsTArray<nsString>& aNames); // Uses XPCOM InvalidateColumns(). // Uses XPCOM RestoreNaturalOrder(). diff --git a/layout/xul/tree/nsTreeContentView.cpp b/layout/xul/tree/nsTreeContentView.cpp index 6071bb2e7..09c92b142 100644 --- a/layout/xul/tree/nsTreeContentView.cpp +++ b/layout/xul/tree/nsTreeContentView.cpp @@ -3,23 +3,22 @@ * 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/. */ -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsIBoxObject.h" #include "nsTreeUtils.h" #include "nsTreeContentView.h" -#include "nsChildIterator.h" +#include "ChildIterator.h" #include "nsDOMClassInfoID.h" #include "nsError.h" -#include "nsEventStates.h" -#include "nsINodeInfo.h" #include "nsIXULSortService.h" #include "nsContentUtils.h" #include "nsTreeBodyFrame.h" #include "mozilla/dom/Element.h" #include "nsServiceManagerUtils.h" +#include "nsIDocument.h" -namespace dom = mozilla::dom; +using namespace mozilla; #define NS_ENSURE_NATIVE_COLUMN(_col) \ nsRefPtr<nsTreeColumn> col = nsTreeBodyFrame::GetColumnImpl(_col); \ @@ -111,17 +110,15 @@ NS_NewTreeContentView(nsITreeView** aResult) return NS_OK; } -NS_IMPL_CYCLE_COLLECTION_4(nsTreeContentView, - mBoxObject, - mSelection, - mRoot, - mBody) +NS_IMPL_CYCLE_COLLECTION(nsTreeContentView, + mBoxObject, + mSelection, + mRoot, + mBody) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeContentView) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeContentView) -DOMCI_DATA(TreeContentView, nsTreeContentView) - NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeContentView) NS_INTERFACE_MAP_ENTRY(nsITreeView) NS_INTERFACE_MAP_ENTRY(nsITreeContentView) @@ -489,7 +486,7 @@ nsTreeContentView::SetTree(nsITreeBoxObject* aTree) NS_ENSURE_STATE(mRoot); // Add ourselves to document's observers. - nsIDocument* document = mRoot->GetDocument(); + nsIDocument* document = mRoot->GetComposedDoc(); if (document) { document->AddObserver(this); mDocument = document; @@ -556,7 +553,7 @@ nsTreeContentView::CycleHeader(nsITreeColumn* aCol) nsAutoString hints; column->GetAttr(kNameSpaceID_None, nsGkAtoms::sorthints, hints); - sortdirection.AppendLiteral(" "); + sortdirection.Append(' '); sortdirection += hints; nsCOMPtr<nsIDOMNode> rootnode = do_QueryInterface(mRoot); @@ -674,19 +671,19 @@ nsTreeContentView::SetCellText(int32_t aRow, nsITreeColumn* aCol, const nsAStrin } NS_IMETHODIMP -nsTreeContentView::PerformAction(const PRUnichar* aAction) +nsTreeContentView::PerformAction(const char16_t* aAction) { return NS_OK; } NS_IMETHODIMP -nsTreeContentView::PerformActionOnRow(const PRUnichar* aAction, int32_t aRow) +nsTreeContentView::PerformActionOnRow(const char16_t* aAction, int32_t aRow) { return NS_OK; } NS_IMETHODIMP -nsTreeContentView::PerformActionOnCell(const PRUnichar* aAction, int32_t aRow, nsITreeColumn* aCol) +nsTreeContentView::PerformActionOnCell(const char16_t* aAction, int32_t aRow, nsITreeColumn* aCol) { return NS_OK; } @@ -1046,9 +1043,8 @@ nsTreeContentView::Serialize(nsIContent* aContent, int32_t aParentIndex, if (!aContent->IsXUL()) return; - ChildIterator iter, last; - for (ChildIterator::Init(aContent, &iter, &last); iter != last; ++iter) { - nsIContent* content = *iter; + dom::FlattenedChildIterator iter(aContent); + for (nsIContent* content = iter.GetNextChild(); content; content = iter.GetNextChild()) { nsIAtom *tag = content->Tag(); int32_t count = aRows.Length(); @@ -1367,10 +1363,8 @@ nsTreeContentView::GetCell(nsIContent* aContainer, nsITreeColumn* aCol) // index in a row. "ref" attribute has higher priority. nsIContent* result = nullptr; int32_t j = 0; - ChildIterator iter, last; - for (ChildIterator::Init(aContainer, &iter, &last); iter != last; ++iter) { - nsIContent* cell = *iter; - + dom::FlattenedChildIterator iter(aContainer); + for (nsIContent* cell = iter.GetNextChild(); cell; cell = iter.GetNextChild()) { if (cell->Tag() == nsGkAtoms::treecell) { if (colAtom && cell->AttrValueIs(kNameSpaceID_None, nsGkAtoms::ref, colAtom, eCaseMatters)) { diff --git a/layout/xul/tree/nsTreeContentView.h b/layout/xul/tree/nsTreeContentView.h index 2430a3b5e..c6bbbdf46 100644 --- a/layout/xul/tree/nsTreeContentView.h +++ b/layout/xul/tree/nsTreeContentView.h @@ -22,22 +22,20 @@ class Row; nsresult NS_NewTreeContentView(nsITreeView** aResult); -class nsTreeContentView MOZ_FINAL : public nsINativeTreeView, +class nsTreeContentView final : public nsINativeTreeView, public nsITreeContentView, public nsStubDocumentObserver { public: nsTreeContentView(void); - ~nsTreeContentView(void); - NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTreeContentView, nsINativeTreeView) NS_DECL_NSITREEVIEW // nsINativeTreeView: Untrusted code can use us - NS_IMETHOD EnsureNative() MOZ_OVERRIDE { return NS_OK; } + NS_IMETHOD EnsureNative() override { return NS_OK; } NS_DECL_NSITREECONTENTVIEW @@ -51,6 +49,8 @@ class nsTreeContentView MOZ_FINAL : public nsINativeTreeView, static bool CanTrustTreeSelection(nsISupports* aValue); protected: + ~nsTreeContentView(void); + // Recursive methods which deal with serializing of nested content. void Serialize(nsIContent* aContent, int32_t aParentIndex, int32_t* aIndex, nsTArray<nsAutoPtr<Row> >& aRows); diff --git a/layout/xul/tree/nsTreeImageListener.cpp b/layout/xul/tree/nsTreeImageListener.cpp index 1680a4b5b..f559be042 100644 --- a/layout/xul/tree/nsTreeImageListener.cpp +++ b/layout/xul/tree/nsTreeImageListener.cpp @@ -7,8 +7,9 @@ #include "nsITreeBoxObject.h" #include "imgIRequest.h" #include "imgIContainer.h" +#include "nsIContent.h" -NS_IMPL_ISUPPORTS1(nsTreeImageListener, imgINotificationObserver) +NS_IMPL_ISUPPORTS(nsTreeImageListener, imgINotificationObserver) nsTreeImageListener::nsTreeImageListener(nsTreeBodyFrame* aTreeFrame) : mTreeFrame(aTreeFrame), diff --git a/layout/xul/tree/nsTreeImageListener.h b/layout/xul/tree/nsTreeImageListener.h index 940083869..573b246e5 100644 --- a/layout/xul/tree/nsTreeImageListener.h +++ b/layout/xul/tree/nsTreeImageListener.h @@ -13,11 +13,10 @@ #include "mozilla/Attributes.h" // This class handles image load observation. -class nsTreeImageListener MOZ_FINAL : public imgINotificationObserver +class nsTreeImageListener final : public imgINotificationObserver { public: - nsTreeImageListener(nsTreeBodyFrame *aTreeFrame); - ~nsTreeImageListener(); + explicit nsTreeImageListener(nsTreeBodyFrame *aTreeFrame); NS_DECL_ISUPPORTS NS_DECL_IMGINOTIFICATIONOBSERVER @@ -27,6 +26,8 @@ public: friend class nsTreeBodyFrame; protected: + ~nsTreeImageListener(); + void UnsuppressInvalidation() { mInvalidationSuppressed = false; } void Invalidate(); void AddCell(int32_t aIndex, nsITreeColumn* aCol); @@ -39,7 +40,7 @@ private: class InvalidationArea { public: - InvalidationArea(nsITreeColumn* aCol); + explicit InvalidationArea(nsITreeColumn* aCol); ~InvalidationArea() { delete mNext; } friend class nsTreeImageListener; diff --git a/layout/xul/tree/nsTreeSelection.cpp b/layout/xul/tree/nsTreeSelection.cpp index e6c6cc89c..10ffa06e6 100644 --- a/layout/xul/tree/nsTreeSelection.cpp +++ b/layout/xul/tree/nsTreeSelection.cpp @@ -3,6 +3,7 @@ * 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/. */ +#include "mozilla/AsyncEventDispatcher.h" #include "nsCOMPtr.h" #include "nsTreeSelection.h" #include "nsIBoxObject.h" @@ -12,12 +13,12 @@ #include "nsIDOMElement.h" #include "nsDOMClassInfoID.h" #include "nsIContent.h" -#include "nsGUIEvent.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" -#include "nsAsyncDOMEvent.h" -#include "nsEventDispatcher.h" #include "nsAutoPtr.h" +#include "nsComponentManagerUtils.h" + +using namespace mozilla; // A helper class for managing our ranges of selection. struct nsTreeRange @@ -257,14 +258,11 @@ nsTreeSelection::~nsTreeSelection() mSelectTimer->Cancel(); } -NS_IMPL_CYCLE_COLLECTION_2(nsTreeSelection, mTree, mCurrentColumn) +NS_IMPL_CYCLE_COLLECTION(nsTreeSelection, mTree, mCurrentColumn) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeSelection) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeSelection) -DOMCI_DATA(TreeSelection, nsTreeSelection) - -// QueryInterface implementation for nsBoxObject NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection) NS_INTERFACE_MAP_ENTRY(nsITreeSelection) NS_INTERFACE_MAP_ENTRY(nsINativeTreeSelection) @@ -650,11 +648,12 @@ NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(int32_t aIndex) NS_NAMED_LITERAL_STRING(DOMMenuItemActive, "DOMMenuItemActive"); NS_NAMED_LITERAL_STRING(DOMMenuItemInactive, "DOMMenuItemInactive"); - nsRefPtr<nsAsyncDOMEvent> event = - new nsAsyncDOMEvent(treeDOMNode, - (aIndex != -1 ? DOMMenuItemActive : DOMMenuItemInactive), - true, false); - return event->PostDOMEvent(); + nsRefPtr<AsyncEventDispatcher> asyncDispatcher = + new AsyncEventDispatcher(treeDOMNode, + (aIndex != -1 ? DOMMenuItemActive : + DOMMenuItemInactive), + true, false); + return asyncDispatcher->PostDOMEvent(); } NS_IMETHODIMP nsTreeSelection::GetCurrentColumn(nsITreeColumn** aCurrentColumn) @@ -838,9 +837,9 @@ nsTreeSelection::FireOnSelectHandler() nsCOMPtr<nsINode> node(do_QueryInterface(elt)); NS_ENSURE_STATE(node); - nsRefPtr<nsAsyncDOMEvent> event = - new nsAsyncDOMEvent(node, NS_LITERAL_STRING("select"), true, false); - event->RunDOMEventWhenSafe(); + nsRefPtr<AsyncEventDispatcher> asyncDispatcher = + new AsyncEventDispatcher(node, NS_LITERAL_STRING("select"), true, false); + asyncDispatcher->RunDOMEventWhenSafe(); return NS_OK; } diff --git a/layout/xul/tree/nsTreeSelection.h b/layout/xul/tree/nsTreeSelection.h index 83425c77b..41ffe31fb 100644 --- a/layout/xul/tree/nsTreeSelection.h +++ b/layout/xul/tree/nsTreeSelection.h @@ -16,22 +16,23 @@ class nsITreeBoxObject; struct nsTreeRange; -class nsTreeSelection MOZ_FINAL : public nsINativeTreeSelection +class nsTreeSelection final : public nsINativeTreeSelection { public: - nsTreeSelection(nsITreeBoxObject* aTree); - ~nsTreeSelection(); + explicit nsTreeSelection(nsITreeBoxObject* aTree); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeSelection) NS_DECL_NSITREESELECTION // nsINativeTreeSelection: Untrusted code can use us - NS_IMETHOD EnsureNative() MOZ_OVERRIDE { return NS_OK; } + NS_IMETHOD EnsureNative() override { return NS_OK; } friend struct nsTreeRange; protected: + ~nsTreeSelection(); + nsresult FireOnSelectHandler(); static void SelectCallback(nsITimer *aTimer, void *aClosure); diff --git a/layout/xul/tree/nsTreeStyleCache.cpp b/layout/xul/tree/nsTreeStyleCache.cpp index 140a0f602..b8b2ec8db 100644 --- a/layout/xul/tree/nsTreeStyleCache.cpp +++ b/layout/xul/tree/nsTreeStyleCache.cpp @@ -7,86 +7,87 @@ #include "nsStyleSet.h" #include "mozilla/dom/Element.h" +nsTreeStyleCache::Transition::Transition(DFAState aState, nsIAtom* aSymbol) + : mState(aState), mInputSymbol(aSymbol) +{ +} + +bool +nsTreeStyleCache::Transition::operator==(const Transition& aOther) const +{ + return aOther.mState == mState && aOther.mInputSymbol == mInputSymbol; +} + +uint32_t +nsTreeStyleCache::Transition::Hash() const +{ + // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol. + uint32_t hb = mState << 16; + uint32_t lb = (NS_PTR_TO_UINT32(mInputSymbol.get()) << 16) >> 16; + return hb+lb; +} + + // The style context cache impl nsStyleContext* nsTreeStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator, nsPresContext* aPresContext, - nsIContent* aContent, + nsIContent* aContent, nsStyleContext* aContext, nsIAtom* aPseudoElement, const AtomArray & aInputWord) { uint32_t count = aInputWord.Length(); - nsDFAState startState(0); - nsDFAState* currState = &startState; // Go ahead and init the transition table. if (!mTransitionTable) { // Automatic miss. Build the table - mTransitionTable = - new nsObjectHashtable(nullptr, nullptr, DeleteDFAState, nullptr); + mTransitionTable = new TransitionTable(); } // The first transition is always made off the supplied pseudo-element. - nsTransitionKey key(currState->GetStateID(), aPseudoElement); - currState = static_cast<nsDFAState*>(mTransitionTable->Get(&key)); + Transition transition(0, aPseudoElement); + DFAState currState = mTransitionTable->Get(transition); if (!currState) { // We had a miss. Make a new state and add it to our hash. - currState = new nsDFAState(mNextState); + currState = mNextState; mNextState++; - mTransitionTable->Put(&key, currState); + mTransitionTable->Put(transition, currState); } for (uint32_t i = 0; i < count; i++) { - nsTransitionKey key(currState->GetStateID(), aInputWord[i]); - currState = static_cast<nsDFAState*>(mTransitionTable->Get(&key)); + Transition transition(currState, aInputWord[i]); + currState = mTransitionTable->Get(transition); if (!currState) { // We had a miss. Make a new state and add it to our hash. - currState = new nsDFAState(mNextState); + currState = mNextState; mNextState++; - mTransitionTable->Put(&key, currState); + mTransitionTable->Put(transition, currState); } } // We're in a final state. // Look up our style context for this state. nsStyleContext* result = nullptr; - if (mCache) - result = static_cast<nsStyleContext*>(mCache->Get(currState)); + if (mCache) { + result = mCache->GetWeak(currState); + } if (!result) { // We missed the cache. Resolve this pseudo-style. - result = aPresContext->StyleSet()-> + nsRefPtr<nsStyleContext> newResult = aPresContext->StyleSet()-> ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement, - aContext, aComparator).get(); + aContext, aComparator); // Put the style context in our table, transferring the owning reference to the table. if (!mCache) { - mCache = new nsObjectHashtable(nullptr, nullptr, ReleaseStyleContext, nullptr); + mCache = new StyleContextCache(); } - mCache->Put(currState, result); + result = newResult.get(); + mCache->Put(currState, newResult.forget()); } return result; } -bool -nsTreeStyleCache::DeleteDFAState(nsHashKey *aKey, - void *aData, - void *closure) -{ - nsDFAState* entry = static_cast<nsDFAState*>(aData); - delete entry; - return true; -} - -bool -nsTreeStyleCache::ReleaseStyleContext(nsHashKey *aKey, - void *aData, - void *closure) -{ - nsStyleContext* context = static_cast<nsStyleContext*>(aData); - context->Release(); - return true; -} diff --git a/layout/xul/tree/nsTreeStyleCache.h b/layout/xul/tree/nsTreeStyleCache.h index 68923c1bd..074f99fa6 100644 --- a/layout/xul/tree/nsTreeStyleCache.h +++ b/layout/xul/tree/nsTreeStyleCache.h @@ -7,87 +7,63 @@ #define nsTreeStyleCache_h__ #include "mozilla/Attributes.h" -#include "nsHashtable.h" #include "nsIAtom.h" #include "nsCOMArray.h" #include "nsICSSPseudoComparator.h" +#include "nsRefPtrHashtable.h" #include "nsStyleContext.h" typedef nsCOMArray<nsIAtom> AtomArray; -class nsDFAState : public nsHashKey +class nsTreeStyleCache { public: - uint32_t mStateID; - - nsDFAState(uint32_t aID) :mStateID(aID) {} - - uint32_t GetStateID() { return mStateID; } - - uint32_t HashCode(void) const MOZ_OVERRIDE { - return mStateID; - } - - bool Equals(const nsHashKey *aKey) const MOZ_OVERRIDE { - nsDFAState* key = (nsDFAState*)aKey; - return key->mStateID == mStateID; - } - - nsHashKey *Clone(void) const MOZ_OVERRIDE { - return new nsDFAState(mStateID); - } -}; - -class nsTransitionKey : public nsHashKey -{ -public: - uint32_t mState; - nsCOMPtr<nsIAtom> mInputSymbol; - - nsTransitionKey(uint32_t aState, nsIAtom* aSymbol) :mState(aState), mInputSymbol(aSymbol) {} - - uint32_t HashCode(void) const MOZ_OVERRIDE { - // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol. - int32_t hb = mState << 16; - int32_t lb = (NS_PTR_TO_INT32(mInputSymbol.get()) << 16) >> 16; - return hb+lb; + nsTreeStyleCache() + : mNextState(0) + { } - bool Equals(const nsHashKey *aKey) const MOZ_OVERRIDE { - nsTransitionKey* key = (nsTransitionKey*)aKey; - return key->mState == mState && key->mInputSymbol == mInputSymbol; + ~nsTreeStyleCache() + { + Clear(); } - nsHashKey *Clone(void) const MOZ_OVERRIDE { - return new nsTransitionKey(mState, mInputSymbol); + void Clear() + { + mTransitionTable = nullptr; + mCache = nullptr; + mNextState = 0; } -}; - -class nsTreeStyleCache -{ -public: - nsTreeStyleCache() :mTransitionTable(nullptr), mCache(nullptr), mNextState(0) {} - ~nsTreeStyleCache() { Clear(); } - - void Clear() { delete mTransitionTable; mTransitionTable = nullptr; delete mCache; mCache = nullptr; mNextState = 0; } nsStyleContext* GetStyleContext(nsICSSPseudoComparator* aComparator, - nsPresContext* aPresContext, - nsIContent* aContent, + nsPresContext* aPresContext, + nsIContent* aContent, nsStyleContext* aContext, nsIAtom* aPseudoElement, const AtomArray & aInputWord); - static bool DeleteDFAState(nsHashKey *aKey, void *aData, void *closure); +protected: + typedef uint32_t DFAState; - static bool ReleaseStyleContext(nsHashKey *aKey, void *aData, void *closure); + class Transition final + { + public: + Transition(DFAState aState, nsIAtom* aSymbol); + bool operator==(const Transition& aOther) const; + uint32_t Hash() const; + + private: + DFAState mState; + nsCOMPtr<nsIAtom> mInputSymbol; + }; + + typedef nsDataHashtable<nsGenericHashKey<Transition>, DFAState> TransitionTable; -protected: // A transition table for a deterministic finite automaton. The DFA - // takes as its input a single pseudoelement and an ordered set of properties. + // takes as its input a single pseudoelement and an ordered set of properties. // It transitions on an input word that is the concatenation of the pseudoelement supplied // with the properties in the array. - // + // // It transitions from state to state by looking up entries in the transition table (which is // a mapping from (S,i)->S', where S is the current state, i is the next // property in the input word, and S' is the state to transition to. @@ -97,15 +73,16 @@ protected: // // Once the entire word has been consumed, the final state is used // to reference the cache table to locate the style context. - nsObjectHashtable* mTransitionTable; + nsAutoPtr<TransitionTable> mTransitionTable; - // The cache of all active style contexts. This is a hash from + // The cache of all active style contexts. This is a hash from // a final state in the DFA, Sf, to the resultant style context. - nsObjectHashtable* mCache; + typedef nsRefPtrHashtable<nsUint32HashKey, nsStyleContext> StyleContextCache; + nsAutoPtr<StyleContextCache> mCache; // An integer counter that is used when we need to make new states in the // DFA. - uint32_t mNextState; + DFAState mNextState; }; #endif // nsTreeStyleCache_h__ diff --git a/layout/xul/tree/nsTreeUtils.cpp b/layout/xul/tree/nsTreeUtils.cpp index f14b3c973..b65ebcf22 100644 --- a/layout/xul/tree/nsTreeUtils.cpp +++ b/layout/xul/tree/nsTreeUtils.cpp @@ -5,12 +5,14 @@ #include "nsReadableUtils.h" #include "nsTreeUtils.h" -#include "nsChildIterator.h" +#include "ChildIterator.h" #include "nsCRT.h" #include "nsIAtom.h" -#include "nsINameSpaceManager.h" +#include "nsNameSpaceManager.h" #include "nsGkAtoms.h" -#include "nsINodeInfo.h" +#include "nsIContent.h" + +using namespace mozilla; nsresult nsTreeUtils::TokenizeProperties(const nsAString& aProperties, AtomArray & aPropertiesArray) @@ -52,10 +54,8 @@ nsTreeUtils::TokenizeProperties(const nsAString& aProperties, AtomArray & aPrope nsIContent* nsTreeUtils::GetImmediateChild(nsIContent* aContainer, nsIAtom* aTag) { - ChildIterator iter, last; - for (ChildIterator::Init(aContainer, &iter, &last); iter != last; ++iter) { - nsIContent* child = *iter; - + dom::FlattenedChildIterator iter(aContainer); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { if (child->Tag() == aTag) { return child; } @@ -67,9 +67,8 @@ nsTreeUtils::GetImmediateChild(nsIContent* aContainer, nsIAtom* aTag) nsIContent* nsTreeUtils::GetDescendantChild(nsIContent* aContainer, nsIAtom* aTag) { - ChildIterator iter, last; - for (ChildIterator::Init(aContainer, &iter, &last); iter != last; ++iter) { - nsIContent* child = *iter; + dom::FlattenedChildIterator iter(aContainer); + for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { if (child->Tag() == aTag) { return child; } |