diff options
Diffstat (limited to 'layout/xul/grid')
83 files changed, 6038 insertions, 0 deletions
diff --git a/layout/xul/grid/crashtests/306911-crash.xul b/layout/xul/grid/crashtests/306911-crash.xul new file mode 100644 index 000000000..cf55dfdf8 --- /dev/null +++ b/layout/xul/grid/crashtests/306911-crash.xul @@ -0,0 +1,4 @@ +<?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">
<listbox id="thelist" flex="1">
<listitem label="Item1" value="item1"> + <listitem label="Item2" value="item2"/> + </listitem>
</listbox>
+</window>
\ No newline at end of file diff --git a/layout/xul/grid/crashtests/306911-grid-testcases.xul b/layout/xul/grid/crashtests/306911-grid-testcases.xul new file mode 100644 index 000000000..bb69f5bcd --- /dev/null +++ b/layout/xul/grid/crashtests/306911-grid-testcases.xul @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <tabbox> + <tabs> + <tab label="full grid" /> + <tab label="grid alone" /> + <tab label="columns alone" /> + <tab label="rows alone" /> + <tab label="column alone" /> + <tab label="row alone" /> + <tab label="wacky" /> + </tabs> + <tabpanels> + <tabpanel> + <grid> + <rows style="color: blue"> + <row> + <label value="row 1,1" /> + <label value="row 1,2" /> + </row> + <row> + <label value="row 2,1" /> + <label value="row 2,2" /> + </row> + </rows> + <columns style="color: fuchsia; opacity: 0.7"> + <column> + <label value="column 1,1" /> + <label value="column 1,2" /> + </column> + <column> + <label value="column 2,1" /> + <label value="column 2,2" /> + </column> + </columns> + </grid> + </tabpanel> + <tabpanel> + <grid> + <label value="Text inside grid" /> + </grid> + </tabpanel> + <tabpanel> + <columns> + <label value="Text inside columns" /> + </columns> + </tabpanel> + <tabpanel> + <rows> + <label value="Text inside rows" /> + </rows> + </tabpanel> + <tabpanel> + <column> + <label value="Text inside column" /> + </column> + </tabpanel> + <tabpanel> + <row> + <label value="Text inside row" /> + </row> + </tabpanel> + <tabpanel> + <grid> + <label value="Text inside grid one" /> + <rows style="color: blue"> + <label value="Text inside rows #1" /> + <row> + <label value="row 1,1" /> + <label value="row 1,2" /> + </row> + <label value="Text inside rows #2" /> + <row> + <label value="row 2,1" /> + <label value="row 2,2" /> + </row> + <label value="Text inside rows #3" /> + </rows> + <label value="Text inside grid two" style="opacity: 0.7" /> + <columns style="color: fuchsia; opacity: 0.7"> + <label value="Text inside columns #1" /> + <column> + <label value="column 1,1" /> + <label value="column 1,2" /> + </column> + <label value="Text inside columns #2" /> + <column> + <label value="column 2,1" /> + <label value="column 2,2" /> + </column> + <label value="Text inside columns #3" /> + </columns> + <label value="Text inside grid three" style="opacity: 0.4" /> + </grid> + </tabpanel> + </tabpanels> + </tabbox> +</window> diff --git a/layout/xul/grid/crashtests/306911-grid-testcases2.xul b/layout/xul/grid/crashtests/306911-grid-testcases2.xul new file mode 100644 index 000000000..c6b4e3849 --- /dev/null +++ b/layout/xul/grid/crashtests/306911-grid-testcases2.xul @@ -0,0 +1,98 @@ +<?xml version="1.0"?> +<!-- vim:sw=4:ts=4:noet: + --> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <tabbox> + <tabs> + <tab label="no group" /> + <tab label="wacky orientations" /> + </tabs> + <tabpanels> + <tabpanel> + <grid> + <row> + <label value="row 1,1" /> + <label value="row 1,2" /> + </row> + <row> + <label value="row 2,1" /> + <label value="row 2,2" /> + </row> + <column> + <label value="column 1,1" /> + <label value="column 1,2" /> + </column> + <column> + <label value="column 2,1" /> + <label value="column 2,2" /> + </column> + </grid> + </tabpanel> + <tabpanel> + <grid> + <rows style="color: green"> + <row> + <label value="rows+row 1" /> + <label value="rows+row 2" /> + </row> + <column> + <label value="rows+column 1" /> + <label value="rows+column 2" /> + </column> + <rows style="color: purple"> + <row> + <label value="rows+rows+row 1" /> + <label value="rows+rows+row 2" /> + </row> + <column> + <label value="rows+rows+column 1" /> + <label value="rows+rows+column 2" /> + </column> + </rows> + <columns style="color: blue"> + <row> + <label value="rows+columns+row 1" /> + <label value="rows+columns+row 2" /> + </row> + <column> + <label value="rows+columns+column 1" /> + <label value="rows+columns+column 2" /> + </column> + </columns> + </rows> + <columns style="opacity: 0.7; color: lime"> + <row> + <label value="columns+row 1" /> + <label value="columns+row 2" /> + </row> + <column> + <label value="columns+column 1" /> + <label value="columns+column 2" /> + </column> + <rows style="color: fuchsia"> + <row> + <label value="columns+rows+row 1" /> + <label value="columns+rows+row 2" /> + </row> + <column> + <label value="columns+rows+column 1" /> + <label value="columns+rows+column 2" /> + </column> + </rows> + <columns style="color: aqua"> + <row> + <label value="columns+columns+row 1" /> + <label value="columns+columns+row 2" /> + </row> + <column> + <label value="columns+columns+column 1" /> + <label value="columns+columns+column 2" /> + </column> + </columns> + </columns> + </grid> + </tabpanel> + </tabpanels> + </tabbox> +</window> diff --git a/layout/xul/grid/crashtests/311710-1.xul b/layout/xul/grid/crashtests/311710-1.xul new file mode 100644 index 000000000..403b267e9 --- /dev/null +++ b/layout/xul/grid/crashtests/311710-1.xul @@ -0,0 +1,22 @@ +<window title="Testcase bug 311710 - Evil xul testcase, using display:-moz-grid-group causes crash [@ nsGridRow::IsCollapsed]" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml"> +<script type="application/x-javascript"> +function clickit() { + var button = document.getElementById('button'); + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + button.dispatchEvent(evt); +} +window.addEventListener('load', clickit, false); +</script> + + <grid> + <rows> + <row> + <separator/> + </row> + </rows> + </grid> +<button id="button" onclick="document.getElementsByTagName('row')[0].style.display='-moz-grid-group'" label="Mozilla should not crash, when clicking this button"/> +</window> diff --git a/layout/xul/grid/crashtests/312784-1.xul b/layout/xul/grid/crashtests/312784-1.xul new file mode 100644 index 000000000..ee4054d80 --- /dev/null +++ b/layout/xul/grid/crashtests/312784-1.xul @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<script type="application/x-JavaScript"> +function crash() { + document.getElementById("test").style.display = "none"; +} + +function clickit() { + var button = document.getElementById('button'); + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + button.dispatchEvent(evt); +} + +window.onload = clickit; + +</script> + + <grid> + <columns> + <column/> + </columns> + <rows id="test"> + <row><button label="placeholder"/></row> + </rows> + </grid> +<button id="button" label="Crash me" onclick="crash()"/> +</window> diff --git a/layout/xul/grid/crashtests/313173-1-inner.xul b/layout/xul/grid/crashtests/313173-1-inner.xul new file mode 100644 index 000000000..284d6c1f1 --- /dev/null +++ b/layout/xul/grid/crashtests/313173-1-inner.xul @@ -0,0 +1,41 @@ +<?xml version="1.0"?> + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<window title="Testcase bug - Crash with evil xul testcase, using -moz-grid/table-caption" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<grid flex="1"> + <columns> + <column flex="1"/> + </columns> + + <rows> + <row> + </row> + </rows> +</grid> + +<html:script> +function doe(){ +document.getElementsByTagName('columns')[0].style.display='table-caption'; +setTimeout(doe2,20); +} +function doe2(){ +document.getElementsByTagName('columns')[0].style.display='-moz-grid'; +} + +function clickit() { + var button = document.getElementById('button'); + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + button.dispatchEvent(evt); +setTimeout('clickit();', 20); +} +window.addEventListener('load', clickit, false); + +</html:script> + <html:button id="button" onclick="doe()" label="click">Clicking this should not crash Mozilla</html:button> +</window> + diff --git a/layout/xul/grid/crashtests/313173-1.html b/layout/xul/grid/crashtests/313173-1.html new file mode 100644 index 000000000..8b45339ab --- /dev/null +++ b/layout/xul/grid/crashtests/313173-1.html @@ -0,0 +1,9 @@ +<html class="reftest-wait"> +<head> +<script> +setTimeout('document.documentElement.className = ""', 500); +</script> +<body> +<iframe src="313173-1-inner.xul"></iframe> +</body> +</html> diff --git a/layout/xul/grid/crashtests/321066-1.xul b/layout/xul/grid/crashtests/321066-1.xul new file mode 100644 index 000000000..789c2582c --- /dev/null +++ b/layout/xul/grid/crashtests/321066-1.xul @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <grid> + <rows> + <column/> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/crashtests/321073-1.xul b/layout/xul/grid/crashtests/321073-1.xul new file mode 100644 index 000000000..b92098b62 --- /dev/null +++ b/layout/xul/grid/crashtests/321073-1.xul @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <listcols> + <grid/> + <listitem/> + </listcols> +</window>
\ No newline at end of file diff --git a/layout/xul/grid/crashtests/382750-1.xul b/layout/xul/grid/crashtests/382750-1.xul new file mode 100644 index 000000000..7a9da73ec --- /dev/null +++ b/layout/xul/grid/crashtests/382750-1.xul @@ -0,0 +1,5 @@ +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<grid><rows><listbox/></rows></grid> + +</window> diff --git a/layout/xul/grid/crashtests/400790-1.xul b/layout/xul/grid/crashtests/400790-1.xul new file mode 100644 index 000000000..4de709428 --- /dev/null +++ b/layout/xul/grid/crashtests/400790-1.xul @@ -0,0 +1,20 @@ +<xul xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="boom();"> + +<script> + +function boom() +{ + var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + + var newListbox = document.createElementNS(XUL_NS, "listbox"); + document.getElementById("listbox").appendChild(newListbox); + + var newHbox = document.createElementNS(XUL_NS, "hbox"); + document.getElementById("listitem").appendChild(newHbox); +} + +</script> + +<listbox id="listbox"><listitem id="listitem" /></listbox> + +</xul> diff --git a/layout/xul/grid/crashtests/423802-crash.xul b/layout/xul/grid/crashtests/423802-crash.xul new file mode 100644 index 000000000..0ae4eab8f --- /dev/null +++ b/layout/xul/grid/crashtests/423802-crash.xul @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<window xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<grid> + <columns> + <column id="col1" flex="1"/> + <column id="col2" flex="1"/> + <column id="col3" flex="P-2"/> + </columns> +</grid> + +</window> diff --git a/layout/xul/grid/crashtests/crashtests.list b/layout/xul/grid/crashtests/crashtests.list new file mode 100644 index 000000000..afe8e1002 --- /dev/null +++ b/layout/xul/grid/crashtests/crashtests.list @@ -0,0 +1,11 @@ +load 306911-crash.xul +load 306911-grid-testcases.xul +load 306911-grid-testcases2.xul +load 311710-1.xul +load 312784-1.xul +load 313173-1.html +load 321066-1.xul +load 321073-1.xul +load 382750-1.xul +load 400790-1.xul +load 423802-crash.xul diff --git a/layout/xul/grid/examples/borderedcolumns.xul b/layout/xul/grid/examples/borderedcolumns.xul new file mode 100644 index 000000000..15ee06911 --- /dev/null +++ b/layout/xul/grid/examples/borderedcolumns.xul @@ -0,0 +1,43 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" id="grid"> + <columns> + <column style="border: 10px inset red;"/> + <column/> + <column style="border: 10px inset red;"/> + </columns> + + <rows style="font-size: 20pt;"> + <row> + <text value="Cell 1 "/> + <text value="Cell 2 "/> + <text value="Cell 3 "/> + </row> + <row> + <text value="Cell 4 "/> + <text value="Cell 5 " style="border: 10px inset red;"/> + <text value="Cell 6 "/> + </row> + <row> + <text value="Cell 7 "/> + <text value="Cell 8 "/> + <text value="Cell 9 "/> + </row> + + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/borderedrowscolumns.xul b/layout/xul/grid/examples/borderedrowscolumns.xul new file mode 100644 index 000000000..94d3d8d99 --- /dev/null +++ b/layout/xul/grid/examples/borderedrowscolumns.xul @@ -0,0 +1,55 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" id="grid"> + <columns style="border: 0px solid blue"> + <column/> + <column/> + <column/> + </columns> + + <rows style="font-size: 40pt; border: 15px inset blue"> + <row> + <text value="Cell(1)"/> + <text value="Cell(2)"/> + <text value="Cell(3)"/> + </row> + <rows style="border: 10px inset green"> + <row> + <text value="Cell(1)"/> + <text value="Cell(2)"/> + <text value="Cell(3)"/> + </row> + <row> + <text value="Cell(4)"/> + <text value="Cell(5)"/> + <text value="Cell(6)"/> + </row> + <row> + <text value="Cell(7)"/> + <text value="Cell(8)"/> + <text value="Cell(9)"/> + </row> + + </rows> + <row> + <text value="Cell(7)"/> + <text value="Cell(8)"/> + <text value="Cell(9)"/> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/borderedrowscolumns2.xul b/layout/xul/grid/examples/borderedrowscolumns2.xul new file mode 100644 index 000000000..96b6ca9e5 --- /dev/null +++ b/layout/xul/grid/examples/borderedrowscolumns2.xul @@ -0,0 +1,44 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="gridsample.css" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" id="grid"> + <columns> + <column style="border: 10px solid red;"/> + <column/> + <column/> + </columns> + + <rows style="font-size: 40pt;"> + <row style="border: 10px solid red;"> + <text value="Cell 1 "/> + <text value="Cell 2 "/> + <text value="Cell 3 "/> + </row> + <row> + <text value="Cell 4 "/> + <text value="Cell 5 "/> + <text value="Cell 6 "/> + </row> + <row> + <text value="Cell 7 "/> + <text value="Cell 8 "/> + <text value="Cell 9 "/> + </row> + + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/borderedrowscolumns3.xul b/layout/xul/grid/examples/borderedrowscolumns3.xul new file mode 100644 index 000000000..30a6fcc1b --- /dev/null +++ b/layout/xul/grid/examples/borderedrowscolumns3.xul @@ -0,0 +1,57 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" id="grid"> + <columns> + <column/> + <columns style="border: 10px solid red"> + <column/> + </columns> + <column/> + </columns> + + <rows style="font-size: 24pt"> + <row> + <text value="Cell(1)"/> + <text value="Cell(2)"/> + <text value="Cell(3)"/> + </row> + <rows style="border: 10px solid green"> + <row> + <text value="Cell(1)"/> + <text value="Cell(2)"/> + <text value="Cell(3)"/> + </row> + <row> + <text value="Cell(4)"/> + <text value="Cell(5)"/> + <text value="Cell(6)"/> + </row> + <row> + <text value="Cell(7)"/> + <text value="Cell(8)"/> + <text value="Cell(9)"/> + </row> + + </rows> + <row> + <text value="Cell(7)"/> + <text value="Cell(8)"/> + <text value="Cell(9)"/> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/bordermargincolumns1.xul b/layout/xul/grid/examples/bordermargincolumns1.xul new file mode 100644 index 000000000..009f932a8 --- /dev/null +++ b/layout/xul/grid/examples/bordermargincolumns1.xul @@ -0,0 +1,44 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="gridsample.css" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" id="grid"> + <columns> + <column style="border: 10px inset red; margin: 10px; "/> + <column/> + <column/> + </columns> + + <rows style="font-size: 40pt;"> + <row style="border: 5px solid green"> + <text value="Cell 1"/> + <text value="Cell 2"/> + <text value="Cell 3"/> + </row> + <row> + <text value="Cell 4"/> + <text value="Cell 5"/> + <text value="Cell 6"/> + </row> + <row> + <text value="Cell 7"/> + <text value="Cell 8"/> + <text value="Cell 9"/> + </row> + + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/collapsetest.xul b/layout/xul/grid/examples/collapsetest.xul new file mode 100644 index 000000000..5e1a042f6 --- /dev/null +++ b/layout/xul/grid/examples/collapsetest.xul @@ -0,0 +1,67 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<script> + + function collapseTag(id) + { + var row = window.document.getElementById(id); + row.setAttribute("collapsed","true"); + } + + function uncollapseTag(id) + { + var row = window.document.getElementById(id); + row.setAttribute("collapsed","false"); + } + + +</script> + + <hbox> + <grid style="border: 2px solid red;" id="grid"> + <columns id="columns1"> + <column id="column1"/> + <column id="column2"/> + <column id="column3"/> + </columns> + + <rows id="rows1" style="font-size: 24pt"> + <row id="row1"> + <text value="cell1"/> + <text value="cell2"/> + <text value="cell3"/> + </row> + <row id="row2"> + <text value="cell4"/> + <text value="cell5"/> + <text value="cell6"/> + </row> + <row id="row3"> + <text value="cell7"/> + <text value="cell8"/> + <text value="cell9"/> + </row> + </rows> + </grid> + </hbox> + <hbox> + <button label="collapse row 2" oncommand="collapseTag('row2');"/> + <button label="uncollapse row 2" oncommand="uncollapseTag('row2');"/> + <button label="collapse column 2" oncommand="collapseTag('column2');"/> + <button label="uncollapse column 2" oncommand="uncollapseTag('column2');"/> + + </hbox> + +</window> diff --git a/layout/xul/grid/examples/divcolumngrid.xul b/layout/xul/grid/examples/divcolumngrid.xul new file mode 100644 index 000000000..2268c302c --- /dev/null +++ b/layout/xul/grid/examples/divcolumngrid.xul @@ -0,0 +1,33 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <hbox> + <grid style="border: 2px solid red;"> + <columns> + <column/> + <description style="border: 10px inset gray"> + hello + </description> + <column/> + </columns> + + <rows> + <row> + <text style="font-size: 40px" value="foo1"/> + <text style="font-size: 40px" value="foo2"/> + </row> + </rows> + </grid> + <spacer flex="1" style="background-color: white"/> + </hbox> +</window> diff --git a/layout/xul/grid/examples/divrowgrid.xul b/layout/xul/grid/examples/divrowgrid.xul new file mode 100644 index 000000000..657553aab --- /dev/null +++ b/layout/xul/grid/examples/divrowgrid.xul @@ -0,0 +1,36 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="width: 100px; border: 2px solid red;"> + <rows> + <row style="font-size: 40px"> + <text value="foo1"/> + <text value="foo2"/> + </row> + <description> + this is some html in the row this should wrap if it is big enough. + </description> + <row style="font-size: 40px"> + <text value="foo3"/> + <text value="foo4"/> + </row> + + </rows> + </grid> + <spacer flex="1" style="background-color: white"/> + </hbox> + + +</window> diff --git a/layout/xul/grid/examples/dynamicgrid.xul b/layout/xul/grid/examples/dynamicgrid.xul new file mode 100644 index 000000000..d718df5f9 --- /dev/null +++ b/layout/xul/grid/examples/dynamicgrid.xul @@ -0,0 +1,370 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="gridsample.css" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start()"> + +<script> + + var selected; + var count = 0; + + function isCell(box) + { + if (box.localName == "row" || + box.localName == "column" || + box.localName == "rows" || + box.localName == "columns" || + box.localName == "grid") + return false; + + return true; + } + + function start() + { + selectIt(window.document.getElementById("rows")); + } + + function selectIt(box) + { + if (!box) + return; + + var a = box.getAttribute("selected"); + if (a != "true") { + box.setAttribute("selected","true"); + if (selected) + selected.setAttribute("selected","false"); + + selected = box; + } + } + + function addCellSelectionHandle(box) + { + box.setAttribute("oncommand", "selectIt(this);"); + } + + function addRowColumnSelectionHandle(box) + { + box.setAttribute("onclick", "selectIt(this);"); + } + + function createButton(str) + { + var b = document.createElement("button"); + b.setAttribute("label", str+count); + count++; + addCellSelectionHandle(b); + return b; + } + + function createRow() + { + var b = document.createElement("row"); + b.setAttribute("dynamic","true"); + + addRowColumnSelectionHandle(b); + return b; + } + + function createColumn() + { + var b = document.createElement("column"); + b.setAttribute("dynamic","true"); + addRowColumnSelectionHandle(b); + return b; + } + + function createText(str) + { + var text = document.createElement("text"); + text.setAttribute("value", str+count); + count++; + text.setAttribute("style", "font-size: 40pt"); + addCellSelectionHandle(text); + return text; + } + + function appendElement(element, prepend) + { + if (!selected) + return; + + setUserAttribute(element); + + if (selected.localName == "rows") + appendRow(false); + else if (selected.localName == "columns") + appendColumn(false); + + if (selected.localName == "row" || selected.localName == "column" ) { // is row or column + selected.appendChild(element); + } else { + var parent = selected.parentNode; + if (prepend) + parent.insertBefore(element, selected); + else { + var next = selected.nextSibling; + if (next) + parent.insertBefore(element,next); + else + parent.appendChild(element); + } + } + + selectIt(element); + } + + function getRows(box) + { + return window.document.getElementById("rows"); + } + + function getColumns(box) + { + return window.document.getElementById("columns"); + } + + function setUserAttribute(element) + { + var attributeBox = document.getElementById("attributebox"); + var valueBox = document.getElementById("valuebox"); + var attribute = attributeBox.value; + var value = valueBox.value; + if (attribute != "") + element.setAttribute(attribute,value); + } + + function appendRowColumn(rowColumn, prepend) + { + if (!selected) + return; + + setUserAttribute(rowColumn); + + var row = rowColumn; + + // first see what we are adding. + + if (isCell(selected)) { // if cell then select row/column + selectIt(selected.parentNode); + } + + if (selected.localName == "row" || selected.localName == "rows") + if (row.localName == "column") { + selectIt(getColumns(selected)); + dump("Selecting the column") + dump("Selected="+selected.localName); + } + + if (selected.localName == "column" || selected.localName == "columns") + if (row.localName == "row") + selectIt(getRows(selected)); + + if (selected.localName == "rows" || selected.localName == "columns" ) + { // if rows its easy + selected.appendChild(row); + } else { + var parent = selected.parentNode; + if (prepend) + parent.insertBefore(row, selected); + else { + var next = selected.nextSibling; + if (next) + parent.insertBefore(row,next); + else + parent.appendChild(row); + } + } + + selectIt(row); + } + + function appendRow(prepend) + { + var row = createRow(); + appendRowColumn(row,prepend); + } + + + function appendColumn(prepend) + { + var column = createColumn(); + appendRowColumn(column,prepend); + } + + + function selectRows() + { + var rows = getRows(); + if (rows.firstChild) + selectIt(rows.firstChild); + else + selectIt(rows); + } + + + function selectColumns() + { + var columns = getColumns(); + if (columns.firstChild) + selectIt(columns.firstChild); + else + selectIt(columns); + } + + function nextElement() + { + if (!selected) + return; + + selectIt(selected.nextSibling); + } + + function previousElement() + { + if (!selected) + return; + + selectIt(selected.previousSibling); + } + + function selectRow() + { + if (!selected) + return; + + if (selected.localName == "row") + return; + + if (isCell(selected)) { + if (selected.parentNode.localName == "row") + selectIt(selected.parentNode); + } + } + + function selectColumn() + { + if (!selected) + return; + + if (selected.localName == "column") + return; + + if (isCell(selected)) { + if (selected.parentNode.localName == "column") + selectIt(selected.parentNode); + } + } + + function collapseGrid() + { + var grid = document.getElementById("grid"); + var collapsed = grid.getAttribute("collapsed"); + + if (collapsed == "") + grid.setAttribute("collapsed","true"); + else + grid.setAttribute("collapsed",""); + + } + + function collapseElement() + { + if (selected) { + var collapsed = selected.getAttribute("collapsed"); + + if (collapsed == "") + selected.setAttribute("collapsed","true"); + else + selected.setAttribute("collapsed",""); + } + } + +</script> + + <hbox flex="1" style="border: 2px inset gray; overflow: auto"> + <vbox flex="1"> + <hbox> + <grid id="grid" style="border: 2px solid red;"> + <columns id="columns"> + </columns> + + <rows start="true" id="rows"> + </rows> + </grid> + <spacer flex="1"/> + </hbox> + <spacer flex="1"/> + </vbox> + </hbox> + + <grid style="background-color: blue"> + <columns> + <column flex="1"/> + <column flex="1"/> + <column flex="1"/> + <column flex="1"/> + </columns> + <rows> + + <row> + <button label="append row" oncommand="appendRow(false);"/> + <button label="prepend row" oncommand="appendRow(true);"/> + + <button label="append column" oncommand="appendColumn(false);"/> + <button label="prepend column" oncommand="appendColumn(true);"/> + </row> + + <row> + + <button label="append button" oncommand="appendElement(createButton('button'),false);"/> + <button label="prepend button" oncommand="appendElement(createButton('button'),true);"/> + + <button label="append text" oncommand="appendElement(createText('text'),false);"/> + <button label="prepend text" oncommand="appendElement(createText('text'),true);"/> + + </row> + + <row> + + <button label="select rows" oncommand="selectRows()"/> + <button label="select columns" oncommand="selectColumns()"/> + + <button label="next" oncommand="nextElement()"/> + <button label="previous" oncommand="previousElement()"/> + + </row> + + <hbox align="center"> + <button label="collapse/uncollapse grid" flex="1" oncommand="collapseGrid()"/> + <button label="collapse/uncollapse element" flex="1" oncommand="collapseElement()"/> + </hbox> + + + + <hbox> + + <text value="attribute"/> + <textbox id="attributebox" value="" flex="1"/> + <text value="value"/> + <textbox id="valuebox" value="" flex="2"/> + </hbox> + + + </rows> + </grid> + +</window> diff --git a/layout/xul/grid/examples/flexgroupgrid.xul b/layout/xul/grid/examples/flexgroupgrid.xul new file mode 100644 index 000000000..f4cd6622c --- /dev/null +++ b/layout/xul/grid/examples/flexgroupgrid.xul @@ -0,0 +1,47 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="gridsample.css" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px inset gray;" flex="1"> + <columns> + <columns style="border: 10px solid red" flex="1"> + <column flex="2"/> + <column flex="1"/> + </columns> + <column flex="1"/> + </columns> + + <rows style="font-size: 20pt"> + <rows> + <row> + <text class="yellow" value="CellA"/> + <text class="yellow" value="CellAB"/> + <text class="yellow" value="CellABC"/> + </row> + <row> + <text class="yellow" value="CellA"/> + <text class="yellow" value="CellAB"/> + <text class="yellow" value="CellABC"/> + </row> + </rows> + <row> + <text class="yellow" value="CellA"/> + <text class="yellow" value="CellAB"/> + <text class="yellow" value="CellABC"/> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/javascriptappend.xul b/layout/xul/grid/examples/javascriptappend.xul new file mode 100644 index 000000000..f2a415cae --- /dev/null +++ b/layout/xul/grid/examples/javascriptappend.xul @@ -0,0 +1,42 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script> + function start() + { + var row = document.getElementById("row"); + var text = document.createElement("text"); + text.setAttribute("value", "foo"); + row.appendChild(text); + } + + </script> + + <hbox> + <grid style="border: 2px solid red;" id="grid"> + <columns> + </columns> + + <rows> + <row id="row"> + <button label="value"/> + </row> + </rows> + </grid> + <spacer flex="1" style="background-color: white"/> + </hbox> + + <button label="insert" oncommand="start()"/> + +</window> diff --git a/layout/xul/grid/examples/jumpygrid.xul b/layout/xul/grid/examples/jumpygrid.xul new file mode 100644 index 000000000..8bbeb5806 --- /dev/null +++ b/layout/xul/grid/examples/jumpygrid.xul @@ -0,0 +1,82 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="gridsample.css" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script> + function flip(child) + { + var jump = child.getAttribute("jumpy"); + if (jump != "true") + child.setAttribute("jumpy","true"); + else + child.setAttribute("jumpy","false"); + } + + </script> + <hbox> + <grid style="border: 2px solid yellow;"> + <columns> + </columns> + + <rows> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + <row> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + <button label="button" class="jumpy"/> + </row> + + </rows> + </grid> + <spacer style="border: 2px solid white;" flex="1"/> + </hbox> + <spacer style="border: 2px solid white;" flex="1"/> + +</window> diff --git a/layout/xul/grid/examples/nestedrows.xul b/layout/xul/grid/examples/nestedrows.xul new file mode 100644 index 000000000..700f785b3 --- /dev/null +++ b/layout/xul/grid/examples/nestedrows.xul @@ -0,0 +1,48 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox flex="1"> + <grid style="border: 2px solid red" flex="1"> + + <columns> + <column flex="1"/> + <column flex="1"/> + <column flex="1"/> + </columns> + + <rows> + <row> + <text value="out1"/> + <text value="out2"/> + <text value="out3"/> + </row> + + <rows flex="1" style="border: 10px inset yellow; font-size: 20pt"> + <row> + <text value="in1"/> + <text value="in2"/> + <text value="in3"/> + </row> + <row> + <text value="in4"/> + <text value="in5"/> + <text value="in5"/> + </row> + </rows> + + </rows> + + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/examples/rowspan.xul b/layout/xul/grid/examples/rowspan.xul new file mode 100644 index 000000000..266a32229 --- /dev/null +++ b/layout/xul/grid/examples/rowspan.xul @@ -0,0 +1,41 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px solid red;"> + <columns> + <column/> + <column/> + </columns> + + <rows> + <row style="font-size: 40px"> + <text value="foo1"/> + <text value="foo2"/> + </row> + <box width="50" style="border:5px inset grey"> + <text value="hello there. This spans"/> + </box> + <row style="font-size: 40px" > + <text value="foo1"/> + <text value="foo2"/> + </row> + + </rows> + </grid> + <spacer flex="1" style="background-color: white"/> + </hbox> + + +</window> diff --git a/layout/xul/grid/examples/scrollingcolumns.xul b/layout/xul/grid/examples/scrollingcolumns.xul new file mode 100644 index 000000000..f29909624 --- /dev/null +++ b/layout/xul/grid/examples/scrollingcolumns.xul @@ -0,0 +1,80 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox flex="1"> + <grid style="border: 2px solid red" flex="1"> + + <rows> + <row flex="1"/> + <row flex="1"/> + <row flex="1"/> + </rows> + <columns> + + <column> + <button label="left"/> + <button label="left"/> + <button label="left"/> + </column> + + <columns flex="1" style="min-width: 1px; overflow: auto; background-color: green"> + <column> + <button label="cell1"/> + <button label="cell1"/> + <button label="cell1"/> + </column> + <column> + <button label="cell2"/> + <button label="cell2"/> + <button label="cell2"/> + </column> + <column> + <button label="cell3"/> + <button label="cell3"/> + <button label="cell3"/> + </column> + <column> + <button label="cell4"/> + <button label="cell4"/> + <button label="cell4"/> + </column> + <column> + <button label="cell5"/> + <button label="cell5"/> + <button label="cell5"/> + </column> + <column> + <button label="cell6"/> + <button label="cell6"/> + <button label="cell6"/> + </column> + <column> + <button label="cell7"/> + <button label="cell7"/> + <button label="cell7"/> + </column> + </columns> + <column> + <button label="right"/> + <button label="right"/> + <button label="right"/> + </column> + + </columns> + + </grid> + <spacer width="100"/> + </hbox> + <spacer height="100"/> +</window> diff --git a/layout/xul/grid/examples/scrollingrows.xul b/layout/xul/grid/examples/scrollingrows.xul new file mode 100644 index 000000000..fd5077cde --- /dev/null +++ b/layout/xul/grid/examples/scrollingrows.xul @@ -0,0 +1,80 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox flex="1"> + <grid style="border: 2px solid red" flex="1"> + + <columns> + <column flex="1"/> + <column flex="1"/> + <column flex="1"/> + </columns> + + <rows> + <row> + <button label="left"/> + <button label="left"/> + <button label="left"/> + </row> + + <rows flex="1" style="border: 10px inset gray; overflow: auto; background-color: green"> + <row> + <button label="cell1"/> + <button label="cell1"/> + <button label="cell1"/> + </row> + <row> + <button label="cell2"/> + <button label="cell2"/> + <button label="cell2"/> + </row> + <row> + <button label="cell3"/> + <button label="cell3"/> + <button label="cell3"/> + </row> + <row> + <button label="cell4"/> + <button label="cell4"/> + <button label="cell4"/> + </row> + <row> + <button label="cell5"/> + <button label="cell5"/> + <button label="cell5"/> + </row> + <row> + <button label="cell6"/> + <button label="cell6"/> + <button label="cell6"/> + </row> + <row> + <button label="cell7"/> + <button label="cell7"/> + <button label="cell7"/> + </row> + </rows> + <row> + <button label="right"/> + <button label="right"/> + <button label="right"/> + </row> + + </rows> + + </grid> + <spacer width="100"/> + </hbox> + <spacer height="100"/> +</window> diff --git a/layout/xul/grid/examples/splitter.xul b/layout/xul/grid/examples/splitter.xul new file mode 100644 index 000000000..67946d487 --- /dev/null +++ b/layout/xul/grid/examples/splitter.xul @@ -0,0 +1,40 @@ +<?xml version="1.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/. --> + + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window> + + +<window orient="vertical" style="border: 2px solid green" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <grid style="border: 2px solid red;"> + <columns> + <column style="min-width: 1px"/> + <splitter/> + <column style="min-width: 1px"/> + </columns> + + <rows> + <row> + <text style="font-size: 40px" value="foo1"/> + <text style="font-size: 40px" value="foo2"/> + </row> + <label value="this is some text. This is longer"/> + <row> + <text style="font-size: 40px" value="foo1"/> + <text style="font-size: 40px" value="foo2"/> + </row> + + </rows> + </grid> + <spacer flex="1" style="background-color: white"/> + </hbox> + + +</window> diff --git a/layout/xul/grid/moz.build b/layout/xul/grid/moz.build new file mode 100644 index 000000000..074985aaf --- /dev/null +++ b/layout/xul/grid/moz.build @@ -0,0 +1,43 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +with Files('**'): + BUG_COMPONENT = ('Core', 'XP Toolkit/Widgets: XUL') + +EXPORTS += [ + 'nsGrid.h', + 'nsGridCell.h', + 'nsGridLayout2.h', + 'nsGridRow.h', + 'nsGridRowGroupLayout.h', + 'nsGridRowLayout.h', + 'nsGridRowLeafFrame.h', + 'nsGridRowLeafLayout.h', + 'nsIGridPart.h', +] + +UNIFIED_SOURCES += [ + 'nsGrid.cpp', + 'nsGridCell.cpp', + 'nsGridLayout2.cpp', + 'nsGridRow.cpp', + 'nsGridRowGroupFrame.cpp', + 'nsGridRowGroupLayout.cpp', + 'nsGridRowLayout.cpp', + 'nsGridRowLeafFrame.cpp', + 'nsGridRowLeafLayout.cpp', +] + +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '..', + '../../forms', + '../../generic', + '../../style', +] + +if CONFIG['GNU_CXX']: + CXXFLAGS += ['-Wno-error=shadow'] diff --git a/layout/xul/grid/nsGrid.cpp b/layout/xul/grid/nsGrid.cpp new file mode 100644 index 000000000..762bbfcd7 --- /dev/null +++ b/layout/xul/grid/nsGrid.cpp @@ -0,0 +1,1276 @@ +/* -*- 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 "nsGrid.h" +#include "nsGridRowGroupLayout.h" +#include "nsBox.h" +#include "nsIScrollableFrame.h" +#include "nsSprocketLayout.h" +#include "nsGridLayout2.h" +#include "nsGridRow.h" +#include "nsGridCell.h" +#include "mozilla/ReflowInput.h" + +/* +The grid control expands the idea of boxes from 1 dimension to 2 dimensions. +It works by allowing the XUL to define a collection of rows and columns and then +stacking them on top of each other. Here is and example. + +Example 1: + +<grid> + <columns> + <column/> + <column/> + </columns> + + <rows> + <row/> + <row/> + </rows> +</grid> + +example 2: + +<grid> + <columns> + <column flex="1"/> + <column flex="1"/> + </columns> + + <rows> + <row> + <text value="hello"/> + <text value="there"/> + </row> + </rows> +</grid> + +example 3: + +<grid> + +<rows> + <row> + <text value="hello"/> + <text value="there"/> + </row> + </rows> + + <columns> + <column> + <text value="Hey I'm in the column and I'm on top!"/> + </column> + <column/> + </columns> + +</grid> + +Usually the columns are first and the rows are second, so the rows will be drawn on top of the columns. +You can reverse this by defining the rows first. +Other tags are then placed in the <row> or <column> tags causing the grid to accommodate everyone. +It does this by creating 3 things: A cellmap, a row list, and a column list. The cellmap is a 2 +dimensional array of nsGridCells. Each cell contains 2 boxes. One cell from the column list +and one from the row list. When a cell is asked for its size it returns that smallest size it can +be to accommodate the 2 cells. Row lists and Column lists use the same data structure: nsGridRow. +Essentially a row and column are the same except a row goes alone the x axis and a column the y. +To make things easier and save code everything is written in terms of the x dimension. A flag is +passed in called "isHorizontal" that can flip the calculations to the y axis. + +Usually the number of cells in a row match the number of columns, but not always. +It is possible to define 5 columns for a grid but have 10 cells in one of the rows. +In this case 5 extra columns will be added to the column list to handle the situation. +These are called extraColumns/Rows. +*/ + +using namespace mozilla; + +nsGrid::nsGrid():mBox(nullptr), + mRowsBox(nullptr), + mColumnsBox(nullptr), + mNeedsRebuild(true), + mRowCount(0), + mColumnCount(0), + mExtraRowCount(0), + mExtraColumnCount(0), + mMarkingDirty(false) +{ + MOZ_COUNT_CTOR(nsGrid); +} + +nsGrid::~nsGrid() +{ + FreeMap(); + MOZ_COUNT_DTOR(nsGrid); +} + +/* + * This is called whenever something major happens in the grid. And example + * might be when many cells or row are added. It sets a flag signaling that + * all the grids caches information should be recalculated. + */ +void +nsGrid::NeedsRebuild(nsBoxLayoutState& aState) +{ + if (mNeedsRebuild) + return; + + // iterate through columns and rows and dirty them + mNeedsRebuild = true; + + // find the new row and column box. They could have + // been changed. + mRowsBox = nullptr; + mColumnsBox = nullptr; + FindRowsAndColumns(&mRowsBox, &mColumnsBox); + + // tell all the rows and columns they are dirty + DirtyRows(mRowsBox, aState); + DirtyRows(mColumnsBox, aState); +} + + + +/** + * If we are marked for rebuild. Then build everything + */ +void +nsGrid::RebuildIfNeeded() +{ + if (!mNeedsRebuild) + return; + + mNeedsRebuild = false; + + // find the row and columns frames + FindRowsAndColumns(&mRowsBox, &mColumnsBox); + + // count the rows and columns + int32_t computedRowCount = 0; + int32_t computedColumnCount = 0; + int32_t rowCount = 0; + int32_t columnCount = 0; + + CountRowsColumns(mRowsBox, rowCount, computedColumnCount); + CountRowsColumns(mColumnsBox, columnCount, computedRowCount); + + // computedRowCount are the actual number of rows as determined by the + // columns children. + // computedColumnCount are the number of columns as determined by the number + // of rows children. + // We can use this information to see how many extra columns or rows we need. + // This can happen if there are are more children in a row that number of columns + // defined. Example: + // + // <columns> + // <column/> + // </columns> + // + // <rows> + // <row> + // <button/><button/> + // </row> + // </rows> + // + // computedColumnCount = 2 // for the 2 buttons in the row tag + // computedRowCount = 0 // there is nothing in the column tag + // mColumnCount = 1 // one column defined + // mRowCount = 1 // one row defined + // + // So in this case we need to make 1 extra column. + // + + // Make sure to update mExtraColumnCount no matter what, since it might + // happen that we now have as many columns as are defined, and we wouldn't + // want to have a positive mExtraColumnCount hanging about in that case! + mExtraColumnCount = computedColumnCount - columnCount; + if (computedColumnCount > columnCount) { + columnCount = computedColumnCount; + } + + // Same for rows. + mExtraRowCount = computedRowCount - rowCount; + if (computedRowCount > rowCount) { + rowCount = computedRowCount; + } + + // build and poplulate row and columns arrays + mRows = BuildRows(mRowsBox, rowCount, true); + mColumns = BuildRows(mColumnsBox, columnCount, false); + + // build and populate the cell map + mCellMap = BuildCellMap(rowCount, columnCount); + + mRowCount = rowCount; + mColumnCount = columnCount; + + // populate the cell map from column and row children + PopulateCellMap(mRows.get(), mColumns.get(), mRowCount, mColumnCount, true); + PopulateCellMap(mColumns.get(), mRows.get(), mColumnCount, mRowCount, false); +} + +void +nsGrid::FreeMap() +{ + mRows = nullptr; + mColumns = nullptr; + mCellMap = nullptr; + mColumnCount = 0; + mRowCount = 0; + mExtraColumnCount = 0; + mExtraRowCount = 0; + mRowsBox = nullptr; + mColumnsBox = nullptr; +} + +/** + * finds the first <rows> and <columns> tags in the <grid> tag + */ +void +nsGrid::FindRowsAndColumns(nsIFrame** aRows, nsIFrame** aColumns) +{ + *aRows = nullptr; + *aColumns = nullptr; + + // find the boxes that contain our rows and columns + nsIFrame* child = nullptr; + // if we have <grid></grid> then mBox will be null (bug 125689) + if (mBox) + child = nsBox::GetChildXULBox(mBox); + + while(child) + { + nsIFrame* oldBox = child; + nsIScrollableFrame *scrollFrame = do_QueryFrame(child); + if (scrollFrame) { + nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame(); + NS_ASSERTION(scrolledFrame,"Error no scroll frame!!"); + child = do_QueryFrame(scrolledFrame); + } + + nsCOMPtr<nsIGridPart> monument = GetPartFromBox(child); + if (monument) + { + nsGridRowGroupLayout* rowGroup = monument->CastToRowGroupLayout(); + if (rowGroup) { + bool isHorizontal = !nsSprocketLayout::IsXULHorizontal(child); + if (isHorizontal) + *aRows = child; + else + *aColumns = child; + + if (*aRows && *aColumns) + return; + } + } + + if (scrollFrame) { + child = oldBox; + } + + child = nsBox::GetNextXULBox(child); + } +} + +/** + * Count the number of rows and columns in the given box. aRowCount well become the actual number + * rows defined in the xul. aComputedColumnCount will become the number of columns by counting the number + * of cells in each row. + */ +void +nsGrid::CountRowsColumns(nsIFrame* aRowBox, int32_t& aRowCount, int32_t& aComputedColumnCount) +{ + aRowCount = 0; + aComputedColumnCount = 0; + // get the rowboxes layout manager. Then ask it to do the work for us + if (aRowBox) { + nsCOMPtr<nsIGridPart> monument = GetPartFromBox(aRowBox); + if (monument) + monument->CountRowsColumns(aRowBox, aRowCount, aComputedColumnCount); + } +} + + +/** + * Given the number of rows create nsGridRow objects for them and full them out. + */ +UniquePtr<nsGridRow[]> +nsGrid::BuildRows(nsIFrame* aBox, int32_t aRowCount, bool aIsHorizontal) +{ + // if no rows then return null + if (aRowCount == 0) { + return nullptr; + } + + // create the array + UniquePtr<nsGridRow[]> row; + + // only create new rows if we have to. Reuse old rows. + if (aIsHorizontal) + { + if (aRowCount > mRowCount) { + row = MakeUnique<nsGridRow[]>(aRowCount); + } else { + for (int32_t i=0; i < mRowCount; i++) + mRows[i].Init(nullptr, false); + + row = Move(mRows); + } + } else { + if (aRowCount > mColumnCount) { + row = MakeUnique<nsGridRow[]>(aRowCount); + } else { + for (int32_t i=0; i < mColumnCount; i++) + mColumns[i].Init(nullptr, false); + + row = Move(mColumns); + } + } + + // populate it if we can. If not it will contain only dynamic columns + if (aBox) + { + nsCOMPtr<nsIGridPart> monument = GetPartFromBox(aBox); + if (monument) { + monument->BuildRows(aBox, row.get()); + } + } + + return row; +} + + +/** + * Given the number of rows and columns. Build a cellmap + */ +UniquePtr<nsGridCell[]> +nsGrid::BuildCellMap(int32_t aRows, int32_t aColumns) +{ + int32_t size = aRows*aColumns; + int32_t oldsize = mRowCount*mColumnCount; + if (size == 0) { + return nullptr; + } + + if (size > oldsize) { + return MakeUnique<nsGridCell[]>(size); + } + + // clear out cellmap + for (int32_t i=0; i < oldsize; i++) { + mCellMap[i].SetBoxInRow(nullptr); + mCellMap[i].SetBoxInColumn(nullptr); + } + return Move(mCellMap); +} + +/** + * Run through all the cells in the rows and columns and populate then with 2 cells. One from the row and one + * from the column + */ +void +nsGrid::PopulateCellMap(nsGridRow* aRows, nsGridRow* aColumns, int32_t aRowCount, int32_t aColumnCount, bool aIsHorizontal) +{ + if (!aRows) + return; + + // look through the columns + int32_t j = 0; + + for(int32_t i=0; i < aRowCount; i++) + { + nsIFrame* child = nullptr; + nsGridRow* row = &aRows[i]; + + // skip bogus rows. They have no cells + if (row->mIsBogus) + continue; + + child = row->mBox; + if (child) { + child = nsBox::GetChildXULBox(child); + + j = 0; + + while(child && j < aColumnCount) + { + // skip bogus column. They have no cells + nsGridRow* column = &aColumns[j]; + if (column->mIsBogus) + { + j++; + continue; + } + + if (aIsHorizontal) + GetCellAt(j,i)->SetBoxInRow(child); + else + GetCellAt(i,j)->SetBoxInColumn(child); + + child = nsBox::GetNextXULBox(child); + + j++; + } + } + } +} + +/** + * Run through the rows in the given box and mark them dirty so they + * will get recalculated and get a layout. + */ +void +nsGrid::DirtyRows(nsIFrame* aRowBox, nsBoxLayoutState& aState) +{ + // make sure we prevent others from dirtying things. + mMarkingDirty = true; + + // if the box is a grid part have it recursively hand it. + if (aRowBox) { + nsCOMPtr<nsIGridPart> part = GetPartFromBox(aRowBox); + if (part) + part->DirtyRows(aRowBox, aState); + } + + mMarkingDirty = false; +} + +nsGridRow* +nsGrid::GetColumnAt(int32_t aIndex, bool aIsHorizontal) +{ + return GetRowAt(aIndex, !aIsHorizontal); +} + +nsGridRow* +nsGrid::GetRowAt(int32_t aIndex, bool aIsHorizontal) +{ + RebuildIfNeeded(); + + if (aIsHorizontal) { + NS_ASSERTION(aIndex < mRowCount && aIndex >= 0, "Index out of range"); + return &mRows[aIndex]; + } else { + NS_ASSERTION(aIndex < mColumnCount && aIndex >= 0, "Index out of range"); + return &mColumns[aIndex]; + } +} + +nsGridCell* +nsGrid::GetCellAt(int32_t aX, int32_t aY) +{ + RebuildIfNeeded(); + + NS_ASSERTION(aY < mRowCount && aY >= 0, "Index out of range"); + NS_ASSERTION(aX < mColumnCount && aX >= 0, "Index out of range"); + return &mCellMap[aY*mColumnCount+aX]; +} + +int32_t +nsGrid::GetExtraColumnCount(bool aIsHorizontal) +{ + return GetExtraRowCount(!aIsHorizontal); +} + +int32_t +nsGrid::GetExtraRowCount(bool aIsHorizontal) +{ + RebuildIfNeeded(); + + if (aIsHorizontal) + return mExtraRowCount; + else + return mExtraColumnCount; +} + + +/** + * These methods return the preferred, min, max sizes for a given row index. + * aIsHorizontal if aIsHorizontal is true. If you pass false you will get the inverse. + * As if you called GetPrefColumnSize(aState, index, aPref) + */ +nsSize +nsGrid::GetPrefRowSize(nsBoxLayoutState& aState, int32_t aRowIndex, bool aIsHorizontal) +{ + nsSize size(0,0); + if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal))) + return size; + + nscoord height = GetPrefRowHeight(aState, aRowIndex, aIsHorizontal); + SetLargestSize(size, height, aIsHorizontal); + + return size; +} + +nsSize +nsGrid::GetMinRowSize(nsBoxLayoutState& aState, int32_t aRowIndex, bool aIsHorizontal) +{ + nsSize size(0,0); + if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal))) + return size; + + nscoord height = GetMinRowHeight(aState, aRowIndex, aIsHorizontal); + SetLargestSize(size, height, aIsHorizontal); + + return size; +} + +nsSize +nsGrid::GetMaxRowSize(nsBoxLayoutState& aState, int32_t aRowIndex, bool aIsHorizontal) +{ + nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE); + if (!(aRowIndex >=0 && aRowIndex < GetRowCount(aIsHorizontal))) + return size; + + nscoord height = GetMaxRowHeight(aState, aRowIndex, aIsHorizontal); + SetSmallestSize(size, height, aIsHorizontal); + + return size; +} + +// static +nsIGridPart* +nsGrid::GetPartFromBox(nsIFrame* aBox) +{ + if (!aBox) + return nullptr; + + nsBoxLayout* layout = aBox->GetXULLayoutManager(); + return layout ? layout->AsGridPart() : nullptr; +} + +nsMargin +nsGrid::GetBoxTotalMargin(nsIFrame* aBox, bool aIsHorizontal) +{ + nsMargin margin(0,0,0,0); + // walk the boxes parent chain getting the border/padding/margin of our parent rows + + // first get the layour manager + nsIGridPart* part = GetPartFromBox(aBox); + if (part) + margin = part->GetTotalMargin(aBox, aIsHorizontal); + + return margin; +} + +/** + * The first and last rows can be affected by <rows> tags with borders or margin + * gets first and last rows and their indexes. + * If it fails because there are no rows then: + * FirstRow is nullptr + * LastRow is nullptr + * aFirstIndex = -1 + * aLastIndex = -1 + */ +void +nsGrid::GetFirstAndLastRow(int32_t& aFirstIndex, + int32_t& aLastIndex, + nsGridRow*& aFirstRow, + nsGridRow*& aLastRow, + bool aIsHorizontal) +{ + aFirstRow = nullptr; + aLastRow = nullptr; + aFirstIndex = -1; + aLastIndex = -1; + + int32_t count = GetRowCount(aIsHorizontal); + + if (count == 0) + return; + + + // We could have collapsed columns either before or after our index. + // they should not count. So if we are the 5th row and the first 4 are + // collaped we become the first row. Or if we are the 9th row and + // 10 up to the last row are collapsed we then become the last. + + // see if we are first + int32_t i; + for (i=0; i < count; i++) + { + nsGridRow* row = GetRowAt(i,aIsHorizontal); + if (!row->IsXULCollapsed()) { + aFirstIndex = i; + aFirstRow = row; + break; + } + } + + // see if we are last + for (i=count-1; i >= 0; i--) + { + nsGridRow* row = GetRowAt(i,aIsHorizontal); + if (!row->IsXULCollapsed()) { + aLastIndex = i; + aLastRow = row; + break; + } + + } +} + +/** + * A row can have a top and bottom offset. Usually this is just the top and bottom border/padding. + * However if the row is the first or last it could be affected by the fact a column or columns could + * have a top or bottom margin. + */ +void +nsGrid::GetRowOffsets(int32_t aIndex, nscoord& aTop, nscoord& aBottom, bool aIsHorizontal) +{ + + RebuildIfNeeded(); + + nsGridRow* row = GetRowAt(aIndex, aIsHorizontal); + + if (row->IsOffsetSet()) + { + aTop = row->mTop; + aBottom = row->mBottom; + return; + } + + // first get the rows top and bottom border and padding + nsIFrame* box = row->GetBox(); + + // add up all the padding + nsMargin margin(0,0,0,0); + nsMargin border(0,0,0,0); + nsMargin padding(0,0,0,0); + nsMargin totalBorderPadding(0,0,0,0); + nsMargin totalMargin(0,0,0,0); + + // if there is a box and it's not bogus take its + // borders padding into account + if (box && !row->mIsBogus) + { + if (!box->IsXULCollapsed()) + { + // get real border and padding. GetXULBorderAndPadding + // is redefined on nsGridRowLeafFrame. If we called it here + // we would be in finite recurson. + box->GetXULBorder(border); + box->GetXULPadding(padding); + + totalBorderPadding += border; + totalBorderPadding += padding; + } + + // if we are the first or last row + // take into account <rows> tags around us + // that could have borders or margins. + // fortunately they only affect the first + // and last row inside the <rows> tag + + totalMargin = GetBoxTotalMargin(box, aIsHorizontal); + } + + if (aIsHorizontal) { + row->mTop = totalBorderPadding.top; + row->mBottom = totalBorderPadding.bottom; + row->mTopMargin = totalMargin.top; + row->mBottomMargin = totalMargin.bottom; + } else { + row->mTop = totalBorderPadding.left; + row->mBottom = totalBorderPadding.right; + row->mTopMargin = totalMargin.left; + row->mBottomMargin = totalMargin.right; + } + + // if we are the first or last row take into account the top and bottom borders + // of each columns. + + // If we are the first row then get the largest top border/padding in + // our columns. If that's larger than the rows top border/padding use it. + + // If we are the last row then get the largest bottom border/padding in + // our columns. If that's larger than the rows bottom border/padding use it. + int32_t firstIndex = 0; + int32_t lastIndex = 0; + nsGridRow* firstRow = nullptr; + nsGridRow* lastRow = nullptr; + GetFirstAndLastRow(firstIndex, lastIndex, firstRow, lastRow, aIsHorizontal); + + if (aIndex == firstIndex || aIndex == lastIndex) { + nscoord maxTop = 0; + nscoord maxBottom = 0; + + // run through the columns. Look at each column + // pick the largest top border or bottom border + int32_t count = GetColumnCount(aIsHorizontal); + + for (int32_t i=0; i < count; i++) + { + nsMargin totalChildBorderPadding(0,0,0,0); + + nsGridRow* column = GetColumnAt(i,aIsHorizontal); + nsIFrame* box = column->GetBox(); + + if (box) + { + // ignore collapsed children + if (!box->IsXULCollapsed()) + { + // include the margin of the columns. To the row + // at this point border/padding and margins all added + // up to more needed space. + margin = GetBoxTotalMargin(box, !aIsHorizontal); + // get real border and padding. GetXULBorderAndPadding + // is redefined on nsGridRowLeafFrame. If we called it here + // we would be in finite recurson. + box->GetXULBorder(border); + box->GetXULPadding(padding); + totalChildBorderPadding += border; + totalChildBorderPadding += padding; + totalChildBorderPadding += margin; + } + + nscoord top; + nscoord bottom; + + // pick the largest top margin + if (aIndex == firstIndex) { + if (aIsHorizontal) { + top = totalChildBorderPadding.top; + } else { + top = totalChildBorderPadding.left; + } + if (top > maxTop) + maxTop = top; + } + + // pick the largest bottom margin + if (aIndex == lastIndex) { + if (aIsHorizontal) { + bottom = totalChildBorderPadding.bottom; + } else { + bottom = totalChildBorderPadding.right; + } + if (bottom > maxBottom) + maxBottom = bottom; + } + + } + + // If the biggest top border/padding the columns is larger than this rows top border/padding + // the use it. + if (aIndex == firstIndex) { + if (maxTop > (row->mTop + row->mTopMargin)) + row->mTop = maxTop - row->mTopMargin; + } + + // If the biggest bottom border/padding the columns is larger than this rows bottom border/padding + // the use it. + if (aIndex == lastIndex) { + if (maxBottom > (row->mBottom + row->mBottomMargin)) + row->mBottom = maxBottom - row->mBottomMargin; + } + } + } + + aTop = row->mTop; + aBottom = row->mBottom; +} + +/** + * These methods return the preferred, min, max coord for a given row index if + * aIsHorizontal is true. If you pass false you will get the inverse. + * As if you called GetPrefColumnHeight(aState, index, aPref). + */ +nscoord +nsGrid::GetPrefRowHeight(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) +{ + RebuildIfNeeded(); + + nsGridRow* row = GetRowAt(aIndex, aIsHorizontal); + + if (row->IsXULCollapsed()) + return 0; + + if (row->IsPrefSet()) + return row->mPref; + + nsIFrame* box = row->mBox; + + // set in CSS? + if (box) + { + bool widthSet, heightSet; + nsSize cssSize(-1, -1); + nsIFrame::AddXULPrefSize(box, cssSize, widthSet, heightSet); + + row->mPref = GET_HEIGHT(cssSize, aIsHorizontal); + + // yep do nothing. + if (row->mPref != -1) + return row->mPref; + } + + // get the offsets so they are cached. + nscoord top; + nscoord bottom; + GetRowOffsets(aIndex, top, bottom, aIsHorizontal); + + // is the row bogus? If so then just ask it for its size + // it should not be affected by cells in the grid. + if (row->mIsBogus) + { + nsSize size(0,0); + if (box) + { + size = box->GetXULPrefSize(aState); + nsBox::AddMargin(box, size); + nsGridLayout2::AddOffset(box, size); + } + + row->mPref = GET_HEIGHT(size, aIsHorizontal); + return row->mPref; + } + + nsSize size(0,0); + + nsGridCell* child; + + int32_t count = GetColumnCount(aIsHorizontal); + + for (int32_t i=0; i < count; i++) + { + if (aIsHorizontal) + child = GetCellAt(i,aIndex); + else + child = GetCellAt(aIndex,i); + + // ignore collapsed children + if (!child->IsXULCollapsed()) + { + nsSize childSize = child->GetXULPrefSize(aState); + + nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal); + } + } + + row->mPref = GET_HEIGHT(size, aIsHorizontal) + top + bottom; + + return row->mPref; +} + +nscoord +nsGrid::GetMinRowHeight(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) +{ + RebuildIfNeeded(); + + nsGridRow* row = GetRowAt(aIndex, aIsHorizontal); + + if (row->IsXULCollapsed()) + return 0; + + if (row->IsMinSet()) + return row->mMin; + + nsIFrame* box = row->mBox; + + // set in CSS? + if (box) { + bool widthSet, heightSet; + nsSize cssSize(-1, -1); + nsIFrame::AddXULMinSize(aState, box, cssSize, widthSet, heightSet); + + row->mMin = GET_HEIGHT(cssSize, aIsHorizontal); + + // yep do nothing. + if (row->mMin != -1) + return row->mMin; + } + + // get the offsets so they are cached. + nscoord top; + nscoord bottom; + GetRowOffsets(aIndex, top, bottom, aIsHorizontal); + + // is the row bogus? If so then just ask it for its size + // it should not be affected by cells in the grid. + if (row->mIsBogus) + { + nsSize size(0,0); + if (box) { + size = box->GetXULPrefSize(aState); + nsBox::AddMargin(box, size); + nsGridLayout2::AddOffset(box, size); + } + + row->mMin = GET_HEIGHT(size, aIsHorizontal) + top + bottom; + return row->mMin; + } + + nsSize size(0,0); + + nsGridCell* child; + + int32_t count = GetColumnCount(aIsHorizontal); + + for (int32_t i=0; i < count; i++) + { + if (aIsHorizontal) + child = GetCellAt(i,aIndex); + else + child = GetCellAt(aIndex,i); + + // ignore collapsed children + if (!child->IsXULCollapsed()) + { + nsSize childSize = child->GetXULMinSize(aState); + + nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal); + } + } + + row->mMin = GET_HEIGHT(size, aIsHorizontal); + + return row->mMin; +} + +nscoord +nsGrid::GetMaxRowHeight(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) +{ + RebuildIfNeeded(); + + nsGridRow* row = GetRowAt(aIndex, aIsHorizontal); + + if (row->IsXULCollapsed()) + return 0; + + if (row->IsMaxSet()) + return row->mMax; + + nsIFrame* box = row->mBox; + + // set in CSS? + if (box) { + bool widthSet, heightSet; + nsSize cssSize(-1, -1); + nsIFrame::AddXULMaxSize(box, cssSize, widthSet, heightSet); + + row->mMax = GET_HEIGHT(cssSize, aIsHorizontal); + + // yep do nothing. + if (row->mMax != -1) + return row->mMax; + } + + // get the offsets so they are cached. + nscoord top; + nscoord bottom; + GetRowOffsets(aIndex, top, bottom, aIsHorizontal); + + // is the row bogus? If so then just ask it for its size + // it should not be affected by cells in the grid. + if (row->mIsBogus) + { + nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE); + if (box) { + size = box->GetXULPrefSize(aState); + nsBox::AddMargin(box, size); + nsGridLayout2::AddOffset(box, size); + } + + row->mMax = GET_HEIGHT(size, aIsHorizontal); + return row->mMax; + } + + nsSize size(NS_INTRINSICSIZE,NS_INTRINSICSIZE); + + nsGridCell* child; + + int32_t count = GetColumnCount(aIsHorizontal); + + for (int32_t i=0; i < count; i++) + { + if (aIsHorizontal) + child = GetCellAt(i,aIndex); + else + child = GetCellAt(aIndex,i); + + // ignore collapsed children + if (!child->IsXULCollapsed()) + { + nsSize min = child->GetXULMinSize(aState); + nsSize childSize = nsBox::BoundsCheckMinMax(min, child->GetXULMaxSize(aState)); + nsSprocketLayout::AddLargestSize(size, childSize, aIsHorizontal); + } + } + + row->mMax = GET_HEIGHT(size, aIsHorizontal) + top + bottom; + + return row->mMax; +} + +bool +nsGrid::IsGrid(nsIFrame* aBox) +{ + nsIGridPart* part = GetPartFromBox(aBox); + if (!part) + return false; + + nsGridLayout2* grid = part->CastToGridLayout(); + + if (grid) + return true; + + return false; +} + +/** + * This get the flexibilty of the row at aIndex. It's not trivial. There are a few + * things we need to look at. Specifically we need to see if any <rows> or <columns> + * tags are around us. Their flexibilty will affect ours. + */ +nscoord +nsGrid::GetRowFlex(int32_t aIndex, bool aIsHorizontal) +{ + RebuildIfNeeded(); + + nsGridRow* row = GetRowAt(aIndex, aIsHorizontal); + + if (row->IsFlexSet()) + return row->mFlex; + + nsIFrame* box = row->mBox; + row->mFlex = 0; + + if (box) { + + // We need our flex but a inflexible row could be around us. If so + // neither are we. However if its the row tag just inside the grid it won't + // affect us. We need to do this for this case: + // <grid> + // <rows> + // <rows> // this is not flexible. So our children should not be flexible + // <row flex="1"/> + // <row flex="1"/> + // </rows> + // <row/> + // </rows> + // </grid> + // + // or.. + // + // <grid> + // <rows> + // <rows> // this is not flexible. So our children should not be flexible + // <rows flex="1"> + // <row flex="1"/> + // <row flex="1"/> + // </rows> + // <row/> + // </rows> + // </row> + // </grid> + + + // So here is how it looks + // + // <grid> + // <rows> // parentsParent + // <rows> // parent + // <row flex="1"/> + // <row flex="1"/> + // </rows> + // <row/> + // </rows> + // </grid> + + // so the answer is simple: 1) Walk our parent chain. 2) If we find + // someone who is not flexible and they aren't the rows immediately in + // the grid. 3) Then we are not flexible + + box = GetScrollBox(box); + nsIFrame* parent = nsBox::GetParentXULBox(box); + nsIFrame* parentsParent=nullptr; + + while(parent) + { + parent = GetScrollBox(parent); + parentsParent = nsBox::GetParentXULBox(parent); + + // if our parents parent is not a grid + // the get its flex. If its 0 then we are + // not flexible. + if (parentsParent) { + if (!IsGrid(parentsParent)) { + nscoord flex = parent->GetXULFlex(); + nsIFrame::AddXULFlex(parent, flex); + if (flex == 0) { + row->mFlex = 0; + return row->mFlex; + } + } else + break; + } + + parent = parentsParent; + } + + // get the row flex. + row->mFlex = box->GetXULFlex(); + nsIFrame::AddXULFlex(box, row->mFlex); + } + + return row->mFlex; +} + +void +nsGrid::SetLargestSize(nsSize& aSize, nscoord aHeight, bool aIsHorizontal) +{ + if (aIsHorizontal) { + if (aSize.height < aHeight) + aSize.height = aHeight; + } else { + if (aSize.width < aHeight) + aSize.width = aHeight; + } +} + +void +nsGrid::SetSmallestSize(nsSize& aSize, nscoord aHeight, bool aIsHorizontal) +{ + if (aIsHorizontal) { + if (aSize.height > aHeight) + aSize.height = aHeight; + } else { + if (aSize.width < aHeight) + aSize.width = aHeight; + } +} + +int32_t +nsGrid::GetRowCount(int32_t aIsHorizontal) +{ + RebuildIfNeeded(); + + if (aIsHorizontal) + return mRowCount; + else + return mColumnCount; +} + +int32_t +nsGrid::GetColumnCount(int32_t aIsHorizontal) +{ + return GetRowCount(!aIsHorizontal); +} + +/* + * A cell in the given row or columns at the given index has had a child added or removed + */ +void +nsGrid::CellAddedOrRemoved(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) +{ + // TBD see if the cell will fit in our current row. If it will + // just add it in. + // but for now rebuild everything. + if (mMarkingDirty) + return; + + NeedsRebuild(aState); +} + +/** + * A row or columns at the given index had been added or removed + */ +void +nsGrid::RowAddedOrRemoved(nsBoxLayoutState& aState, int32_t aIndex, bool aIsHorizontal) +{ + // TBD see if we have extra room in the table and just add the new row in + // for now rebuild the world + if (mMarkingDirty) + return; + + NeedsRebuild(aState); +} + +/* + * Scrollframes are tranparent. If this is given a scrollframe is will return the + * frame inside. If there is no scrollframe it does nothing. + */ +nsIFrame* +nsGrid::GetScrolledBox(nsIFrame* aChild) +{ + // first see if it is a scrollframe. If so walk down into it and get the scrolled child + nsIScrollableFrame *scrollFrame = do_QueryFrame(aChild); + if (scrollFrame) { + nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame(); + NS_ASSERTION(scrolledFrame,"Error no scroll frame!!"); + return scrolledFrame; + } + + return aChild; +} + +/* + * Scrollframes are tranparent. If this is given a child in a scrollframe is will return the + * scrollframe ourside it. If there is no scrollframe it does nothing. + */ +nsIFrame* +nsGrid::GetScrollBox(nsIFrame* aChild) +{ + if (!aChild) + return nullptr; + + // get parent + nsIFrame* parent = nsBox::GetParentXULBox(aChild); + + // walk up until we find a scrollframe or a part + // if it's a scrollframe return it. + // if it's a parent then the child passed does not + // have a scroll frame immediately wrapped around it. + while (parent) { + nsIScrollableFrame *scrollFrame = do_QueryFrame(parent); + // scrollframe? Yep return it. + if (scrollFrame) + return parent; + + nsCOMPtr<nsIGridPart> parentGridRow = GetPartFromBox(parent); + // if a part then just return the child + if (parentGridRow) + break; + + parent = nsBox::GetParentXULBox(parent); + } + + return aChild; +} + + + +#ifdef DEBUG_grid +void +nsGrid::PrintCellMap() +{ + + printf("-----Columns------\n"); + for (int x=0; x < mColumnCount; x++) + { + + nsGridRow* column = GetColumnAt(x); + printf("%d(pf=%d, mn=%d, mx=%d) ", x, column->mPref, column->mMin, column->mMax); + } + + printf("\n-----Rows------\n"); + for (x=0; x < mRowCount; x++) + { + nsGridRow* column = GetRowAt(x); + printf("%d(pf=%d, mn=%d, mx=%d) ", x, column->mPref, column->mMin, column->mMax); + } + + printf("\n"); + +} +#endif diff --git a/layout/xul/grid/nsGrid.h b/layout/xul/grid/nsGrid.h new file mode 100644 index 000000000..d8726a946 --- /dev/null +++ b/layout/xul/grid/nsGrid.h @@ -0,0 +1,132 @@ +/* -*- 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 nsGrid_h___ +#define nsGrid_h___ + +#include "nsStackLayout.h" +#include "nsIGridPart.h" +#include "nsCOMPtr.h" +#include "mozilla/UniquePtr.h" + +class nsBoxLayoutState; +class nsGridCell; + +//#define DEBUG_grid 1 + +/** + * The grid data structure, i.e., the grid cellmap. + */ +class nsGrid +{ +public: + nsGrid(); + ~nsGrid(); + + nsGridRow* GetColumnAt(int32_t aIndex, bool aIsHorizontal = true); + nsGridRow* GetRowAt(int32_t aIndex, bool aIsHorizontal = true); + nsGridCell* GetCellAt(int32_t aX, int32_t aY); + + void NeedsRebuild(nsBoxLayoutState& aBoxLayoutState); + void RebuildIfNeeded(); + + // For all the methods taking an aIsHorizontal parameter: + // * When aIsHorizontal is true, the words "rows" and (for + // GetColumnCount) "columns" refer to their normal meanings. + // * When aIsHorizontal is false, the meanings are flipped. + // FIXME: Maybe eliminate GetColumnCount and change aIsHorizontal to + // aIsRows? (Calling it horizontal doesn't really make sense because + // row groups and columns have vertical orientation, whereas column + // groups and rows are horizontal.) + + nsSize GetPrefRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + nsSize GetMinRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + nsSize GetMaxRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + nscoord GetRowFlex(int32_t aRowIndex, bool aIsHorizontal = true); + + nscoord GetPrefRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + nscoord GetMinRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + nscoord GetMaxRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex, bool aIsHorizontal = true); + void GetRowOffsets(int32_t aIndex, nscoord& aTop, nscoord& aBottom, bool aIsHorizontal = true); + + void RowAddedOrRemoved(nsBoxLayoutState& aBoxLayoutState, int32_t aIndex, bool aIsHorizontal = true); + void CellAddedOrRemoved(nsBoxLayoutState& aBoxLayoutState, int32_t aIndex, bool aIsHorizontal = true); + void DirtyRows(nsIFrame* aRowBox, nsBoxLayoutState& aState); +#ifdef DEBUG_grid + void PrintCellMap(); +#endif + int32_t GetExtraColumnCount(bool aIsHorizontal = true); + int32_t GetExtraRowCount(bool aIsHorizontal = true); + +// accessors + void SetBox(nsIFrame* aBox) { mBox = aBox; } + nsIFrame* GetBox() { return mBox; } + nsIFrame* GetRowsBox() { return mRowsBox; } + nsIFrame* GetColumnsBox() { return mColumnsBox; } + int32_t GetRowCount(int32_t aIsHorizontal = true); + int32_t GetColumnCount(int32_t aIsHorizontal = true); + + static nsIFrame* GetScrolledBox(nsIFrame* aChild); + static nsIFrame* GetScrollBox(nsIFrame* aChild); + static nsIGridPart* GetPartFromBox(nsIFrame* aBox); + void GetFirstAndLastRow(int32_t& aFirstIndex, + int32_t& aLastIndex, + nsGridRow*& aFirstRow, + nsGridRow*& aLastRow, + bool aIsHorizontal); + +private: + + nsMargin GetBoxTotalMargin(nsIFrame* aBox, bool aIsHorizontal = true); + + void FreeMap(); + void FindRowsAndColumns(nsIFrame** aRows, nsIFrame** aColumns); + mozilla::UniquePtr<nsGridRow[]> BuildRows(nsIFrame* aBox, int32_t aSize, + bool aIsHorizontal = true); + mozilla::UniquePtr<nsGridCell[]> BuildCellMap(int32_t aRows, int32_t aColumns); + void PopulateCellMap(nsGridRow* aRows, nsGridRow* aColumns, int32_t aRowCount, int32_t aColumnCount, bool aIsHorizontal = true); + void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount); + void SetLargestSize(nsSize& aSize, nscoord aHeight, bool aIsHorizontal = true); + void SetSmallestSize(nsSize& aSize, nscoord aHeight, bool aIsHorizontal = true); + bool IsGrid(nsIFrame* aBox); + + // the box that implement the <grid> tag + nsIFrame* mBox; + + // an array of row object + mozilla::UniquePtr<nsGridRow[]> mRows; + + // an array of columns objects. + mozilla::UniquePtr<nsGridRow[]> mColumns; + + // the first in the <grid> that implements the <rows> tag. + nsIFrame* mRowsBox; + + // the first in the <grid> that implements the <columns> tag. + nsIFrame* mColumnsBox; + + // a flag that is false tells us to rebuild the who grid + bool mNeedsRebuild; + + // number of rows and columns as defined by the XUL + int32_t mRowCount; + int32_t mColumnCount; + + // number of rows and columns that are implied but not + // explicitly defined int he XUL + int32_t mExtraRowCount; + int32_t mExtraColumnCount; + + // x,y array of cells in the rows and columns + mozilla::UniquePtr<nsGridCell[]> mCellMap; + + // a flag that when true suppresses all other MarkDirties. This + // prevents lots of extra work being done. + bool mMarkingDirty; +}; + +#endif + diff --git a/layout/xul/grid/nsGridCell.cpp b/layout/xul/grid/nsGridCell.cpp new file mode 100644 index 000000000..c54256297 --- /dev/null +++ b/layout/xul/grid/nsGridCell.cpp @@ -0,0 +1,127 @@ +/* -*- 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 "nsGridCell.h" +#include "nsFrame.h" +#include "nsBox.h" +#include "nsGridLayout2.h" + + +nsGridCell::nsGridCell():mBoxInColumn(nullptr),mBoxInRow(nullptr) +{ + MOZ_COUNT_CTOR(nsGridCell); +} + +nsGridCell::~nsGridCell() +{ + MOZ_COUNT_DTOR(nsGridCell); +} + +nsSize +nsGridCell::GetXULPrefSize(nsBoxLayoutState& aState) +{ + nsSize sum(0,0); + + // take our 2 children and add them up. + // we are as wide as the widest child plus its left offset + // we are tall as the tallest child plus its top offset + + if (mBoxInColumn) { + nsSize pref = mBoxInColumn->GetXULPrefSize(aState); + + nsBox::AddMargin(mBoxInColumn, pref); + nsGridLayout2::AddOffset(mBoxInColumn, pref); + + nsBoxLayout::AddLargestSize(sum, pref); + } + + if (mBoxInRow) { + nsSize pref = mBoxInRow->GetXULPrefSize(aState); + + nsBox::AddMargin(mBoxInRow, pref); + nsGridLayout2::AddOffset(mBoxInRow, pref); + + nsBoxLayout::AddLargestSize(sum, pref); + } + + return sum; +} + +nsSize +nsGridCell::GetXULMinSize(nsBoxLayoutState& aState) +{ + nsSize sum(0, 0); + + // take our 2 children and add them up. + // we are as wide as the widest child plus its left offset + // we are tall as the tallest child plus its top offset + + if (mBoxInColumn) { + nsSize min = mBoxInColumn->GetXULMinSize(aState); + + nsBox::AddMargin(mBoxInColumn, min); + nsGridLayout2::AddOffset(mBoxInColumn, min); + + nsBoxLayout::AddLargestSize(sum, min); + } + + if (mBoxInRow) { + nsSize min = mBoxInRow->GetXULMinSize(aState); + + nsBox::AddMargin(mBoxInRow, min); + nsGridLayout2::AddOffset(mBoxInRow, min); + + nsBoxLayout::AddLargestSize(sum, min); + } + + return sum; +} + +nsSize +nsGridCell::GetXULMaxSize(nsBoxLayoutState& aState) +{ + nsSize sum(NS_INTRINSICSIZE, NS_INTRINSICSIZE); + + // take our 2 children and add them up. + // we are as wide as the smallest child plus its left offset + // we are tall as the shortest child plus its top offset + + if (mBoxInColumn) { + nsSize max = mBoxInColumn->GetXULMaxSize(aState); + + nsBox::AddMargin(mBoxInColumn, max); + nsGridLayout2::AddOffset(mBoxInColumn, max); + + nsBoxLayout::AddSmallestSize(sum, max); + } + + if (mBoxInRow) { + nsSize max = mBoxInRow->GetXULMaxSize(aState); + + nsBox::AddMargin(mBoxInRow, max); + nsGridLayout2::AddOffset(mBoxInRow, max); + + nsBoxLayout::AddSmallestSize(sum, max); + } + + return sum; +} + + +bool +nsGridCell::IsXULCollapsed() +{ + return ((mBoxInColumn && mBoxInColumn->IsXULCollapsed()) || + (mBoxInRow && mBoxInRow->IsXULCollapsed())); +} + + diff --git a/layout/xul/grid/nsGridCell.h b/layout/xul/grid/nsGridCell.h new file mode 100644 index 000000000..eca652776 --- /dev/null +++ b/layout/xul/grid/nsGridCell.h @@ -0,0 +1,53 @@ +/* -*- 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/. */ + +/** + + Author: + Eric D Vaughan + +**/ + +#ifndef nsGridCell_h___ +#define nsGridCell_h___ + +#include "mozilla/Attributes.h" + +class nsBoxLayoutState; +struct nsSize; +class nsIFrame; + +/* + * Grid cell is what makes up the cellmap in the grid. Each GridCell contains + * 2 pointers. One to the matching box in the columns and one to the matching box + * in the rows. Remember that you can put content in both rows and columns. + * When asked for preferred/min/max sizes it works like a stack and takes the + * biggest sizes. + */ + +class nsGridCell final +{ +public: + nsGridCell(); + ~nsGridCell(); + + nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState); + nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState); + nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState); + bool IsXULCollapsed(); + +// accessors + nsIFrame* GetBoxInColumn() { return mBoxInColumn; } + nsIFrame* GetBoxInRow() { return mBoxInRow; } + void SetBoxInRow(nsIFrame* aBox) { mBoxInRow = aBox; } + void SetBoxInColumn(nsIFrame* aBox) { mBoxInColumn = aBox; } + +private: + nsIFrame* mBoxInColumn; + nsIFrame* mBoxInRow; +}; + +#endif + diff --git a/layout/xul/grid/nsGridLayout2.cpp b/layout/xul/grid/nsGridLayout2.cpp new file mode 100644 index 000000000..75408dce3 --- /dev/null +++ b/layout/xul/grid/nsGridLayout2.cpp @@ -0,0 +1,266 @@ +/* -*- 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 "nsGridLayout2.h" +#include "nsGridRowGroupLayout.h" +#include "nsGridRow.h" +#include "nsBox.h" +#include "nsIScrollableFrame.h" +#include "nsSprocketLayout.h" +#include "mozilla/ReflowInput.h" + +nsresult +NS_NewGridLayout2( nsIPresShell* aPresShell, nsBoxLayout** aNewLayout) +{ + *aNewLayout = new nsGridLayout2(aPresShell); + NS_IF_ADDREF(*aNewLayout); + + return NS_OK; + +} + +nsGridLayout2::nsGridLayout2(nsIPresShell* aPresShell):nsStackLayout() +{ +} + +nsGridLayout2::~nsGridLayout2() +{ +} + +// static +void +nsGridLayout2::AddOffset(nsIFrame* aChild, nsSize& aSize) +{ + nsMargin offset; + GetOffset(aChild, offset); + aSize.width += offset.left; + aSize.height += offset.top; +} + +NS_IMETHODIMP +nsGridLayout2::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) +{ + // XXX This should be set a better way! + mGrid.SetBox(aBox); + NS_ASSERTION(aBox->GetXULLayoutManager() == this, "setting incorrect box"); + + nsresult rv = nsStackLayout::XULLayout(aBox, aBoxLayoutState); +#ifdef DEBUG_grid + mGrid.PrintCellMap(); +#endif + return rv; +} + +void +nsGridLayout2::IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& 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). + mGrid.NeedsRebuild(aBoxLayoutState); +} + +nsGrid* +nsGridLayout2::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor) +{ + // XXX This should be set a better way! + mGrid.SetBox(aBox); + NS_ASSERTION(aBox->GetXULLayoutManager() == this, "setting incorrect box"); + return &mGrid; +} + +void +nsGridLayout2::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal) +{ + nscoord& size = GET_WIDTH(aSize, aIsHorizontal); + + if (size != NS_INTRINSICSIZE) { + if (aSize2 == NS_INTRINSICSIZE) + size = NS_INTRINSICSIZE; + else + size += aSize2; + } +} + +nsSize +nsGridLayout2::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize minSize = nsStackLayout::GetXULMinSize(aBox, aState); + + // if there are no <rows> tags that will sum up our columns, + // sum up our columns here. + nsSize total(0,0); + nsIFrame* rowsBox = mGrid.GetRowsBox(); + nsIFrame* columnsBox = mGrid.GetColumnsBox(); + if (!rowsBox || !columnsBox) { + if (!rowsBox) { + // max height is the sum of our rows + int32_t rows = mGrid.GetRowCount(); + for (int32_t i=0; i < rows; i++) + { + nscoord height = mGrid.GetMinRowHeight(aState, i, true); + AddWidth(total, height, false); // AddHeight + } + } + + if (!columnsBox) { + // max height is the sum of our rows + int32_t columns = mGrid.GetColumnCount(); + for (int32_t i=0; i < columns; i++) + { + nscoord width = mGrid.GetMinRowHeight(aState, i, false); + AddWidth(total, width, true); // AddWidth + } + } + + AddMargin(aBox, total); + AddOffset(aBox, total); + AddLargestSize(minSize, total); + } + + return minSize; +} + +nsSize +nsGridLayout2::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize pref = nsStackLayout::GetXULPrefSize(aBox, aState); + + // if there are no <rows> tags that will sum up our columns, + // sum up our columns here. + nsSize total(0,0); + nsIFrame* rowsBox = mGrid.GetRowsBox(); + nsIFrame* columnsBox = mGrid.GetColumnsBox(); + if (!rowsBox || !columnsBox) { + if (!rowsBox) { + // max height is the sum of our rows + int32_t rows = mGrid.GetRowCount(); + for (int32_t i=0; i < rows; i++) + { + nscoord height = mGrid.GetPrefRowHeight(aState, i, true); + AddWidth(total, height, false); // AddHeight + } + } + + if (!columnsBox) { + // max height is the sum of our rows + int32_t columns = mGrid.GetColumnCount(); + for (int32_t i=0; i < columns; i++) + { + nscoord width = mGrid.GetPrefRowHeight(aState, i, false); + AddWidth(total, width, true); // AddWidth + } + } + + AddMargin(aBox, total); + AddOffset(aBox, total); + AddLargestSize(pref, total); + } + + return pref; +} + +nsSize +nsGridLayout2::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize maxSize = nsStackLayout::GetXULMaxSize(aBox, aState); + + // if there are no <rows> tags that will sum up our columns, + // sum up our columns here. + nsSize total(NS_INTRINSICSIZE, NS_INTRINSICSIZE); + nsIFrame* rowsBox = mGrid.GetRowsBox(); + nsIFrame* columnsBox = mGrid.GetColumnsBox(); + if (!rowsBox || !columnsBox) { + if (!rowsBox) { + total.height = 0; + // max height is the sum of our rows + int32_t rows = mGrid.GetRowCount(); + for (int32_t i=0; i < rows; i++) + { + nscoord height = mGrid.GetMaxRowHeight(aState, i, true); + AddWidth(total, height, false); // AddHeight + } + } + + if (!columnsBox) { + total.width = 0; + // max height is the sum of our rows + int32_t columns = mGrid.GetColumnCount(); + for (int32_t i=0; i < columns; i++) + { + nscoord width = mGrid.GetMaxRowHeight(aState, i, false); + AddWidth(total, width, true); // AddWidth + } + } + + AddMargin(aBox, total); + AddOffset(aBox, total); + AddSmallestSize(maxSize, total); + } + + return maxSize; +} + +int32_t +nsGridLayout2::BuildRows(nsIFrame* aBox, nsGridRow* aRows) +{ + if (aBox) { + aRows[0].Init(aBox, true); + return 1; + } + return 0; +} + +nsMargin +nsGridLayout2::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) +{ + nsMargin margin(0,0,0,0); + return margin; +} + +void +nsGridLayout2::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, + nsIFrame* aPrevBox, + const nsFrameList::Slice& aNewChildren) +{ + mGrid.NeedsRebuild(aState); +} + +void +nsGridLayout2::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, + const nsFrameList::Slice& aNewChildren) +{ + mGrid.NeedsRebuild(aState); +} + +void +nsGridLayout2::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, + nsIFrame* aChildList) +{ + mGrid.NeedsRebuild(aState); +} + +void +nsGridLayout2::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, + nsIFrame* aChildList) +{ + mGrid.NeedsRebuild(aState); +} + +NS_IMPL_ADDREF_INHERITED(nsGridLayout2, nsStackLayout) +NS_IMPL_RELEASE_INHERITED(nsGridLayout2, nsStackLayout) + +NS_INTERFACE_MAP_BEGIN(nsGridLayout2) + NS_INTERFACE_MAP_ENTRY(nsIGridPart) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart) +NS_INTERFACE_MAP_END_INHERITING(nsStackLayout) diff --git a/layout/xul/grid/nsGridLayout2.h b/layout/xul/grid/nsGridLayout2.h new file mode 100644 index 000000000..eb696faf8 --- /dev/null +++ b/layout/xul/grid/nsGridLayout2.h @@ -0,0 +1,78 @@ +/* -*- 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 nsGridLayout2_h___ +#define nsGridLayout2_h___ + +#include "mozilla/Attributes.h" +#include "nsStackLayout.h" +#include "nsIGridPart.h" +#include "nsCoord.h" +#include "nsGrid.h" + +class nsGridRowGroupLayout; +class nsGridRowLayout; +class nsGridRow; +class nsBoxLayoutState; + +/** + * The nsBoxLayout implementation for a grid. + */ +class nsGridLayout2 final : public nsStackLayout, + public nsIGridPart +{ +public: + + friend nsresult NS_NewGridLayout2(nsIPresShell* aPresShell, nsBoxLayout** aNewLayout); + + NS_DECL_ISUPPORTS_INHERITED + + NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) 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 GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULPrefSize(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) override; + virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, + 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 nsIGridPart* AsGridPart() override { return this; } + + static void AddOffset(nsIFrame* aChild, nsSize& aSize); + +protected: + + explicit nsGridLayout2(nsIPresShell* aShell); + virtual ~nsGridLayout2(); + nsGrid mGrid; + +private: + void AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal); + + +}; // class nsGridLayout2 + + +#endif + diff --git a/layout/xul/grid/nsGridRow.cpp b/layout/xul/grid/nsGridRow.cpp new file mode 100644 index 000000000..2a2a64016 --- /dev/null +++ b/layout/xul/grid/nsGridRow.cpp @@ -0,0 +1,57 @@ +/* -*- 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 "nsGridRow.h" +#include "nsBoxLayoutState.h" +#include "nsIFrame.h" + +nsGridRow::nsGridRow():mIsBogus(false), + mBox(nullptr), + mFlex(-1), + mPref(-1), + mMin(-1), + mMax(-1), + mTop(-1), + mBottom(-1), + mTopMargin(0), + mBottomMargin(0) + +{ + MOZ_COUNT_CTOR(nsGridRow); +} + +void +nsGridRow::Init(nsIFrame* aBox, bool aIsBogus) +{ + mBox = aBox; + mIsBogus = aIsBogus; + mFlex = -1; + mPref = -1; + mMin = -1; + mMax = -1; + mTop = -1; + mBottom = -1; + mTopMargin = 0; + mBottomMargin = 0; +} + +nsGridRow::~nsGridRow() +{ + MOZ_COUNT_DTOR(nsGridRow); +} + +bool +nsGridRow::IsXULCollapsed() +{ + return mBox && mBox->IsXULCollapsed(); +} + diff --git a/layout/xul/grid/nsGridRow.h b/layout/xul/grid/nsGridRow.h new file mode 100644 index 000000000..a5bc39158 --- /dev/null +++ b/layout/xul/grid/nsGridRow.h @@ -0,0 +1,57 @@ +/* -*- 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/. */ + +/** + + Author: + Eric D Vaughan + +**/ + +#ifndef nsGridRow_h___ +#define nsGridRow_h___ + +#include "nsCoord.h" + +class nsIFrame; + +/** + * The row (or column) data structure in the grid cellmap. + */ +class nsGridRow +{ +public: + nsGridRow(); + ~nsGridRow(); + + void Init(nsIFrame* aBox, bool aIsBogus); + +// accessors + nsIFrame* GetBox() { return mBox; } + bool IsPrefSet() { return (mPref != -1); } + bool IsMinSet() { return (mMin != -1); } + bool IsMaxSet() { return (mMax != -1); } + bool IsFlexSet() { return (mFlex != -1); } + bool IsOffsetSet() { return (mTop != -1 && mBottom != -1); } + bool IsXULCollapsed(); + +public: + + bool mIsBogus; + nsIFrame* mBox; + nscoord mFlex; + nscoord mPref; + nscoord mMin; + nscoord mMax; + nscoord mTop; + nscoord mBottom; + nscoord mTopMargin; + nscoord mBottomMargin; + +}; + + +#endif + diff --git a/layout/xul/grid/nsGridRowGroupFrame.cpp b/layout/xul/grid/nsGridRowGroupFrame.cpp new file mode 100644 index 000000000..5b72d3753 --- /dev/null +++ b/layout/xul/grid/nsGridRowGroupFrame.cpp @@ -0,0 +1,63 @@ +/* -*- 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 "nsGridRowGroupFrame.h" +#include "nsGridRowLeafLayout.h" +#include "nsGridRow.h" +#include "nsBoxLayoutState.h" +#include "nsGridLayout2.h" + +already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout(); + +nsIFrame* +NS_NewGridRowGroupFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext) +{ + nsCOMPtr<nsBoxLayout> layout = NS_NewGridRowGroupLayout(); + return new (aPresShell) nsGridRowGroupFrame(aContext, layout); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsGridRowGroupFrame) + + +/** + * This is redefined because row groups have a funny property. If they are flexible + * then their flex must be equal to the sum of their children's flexes. + */ +nscoord +nsGridRowGroupFrame::GetXULFlex() +{ + // if we are flexible out flexibility is determined by our columns. + // so first get the our flex. If not 0 then our flex is the sum of + // our columns flexes. + + if (!DoesNeedRecalc(mFlex)) + return mFlex; + + if (nsBoxFrame::GetXULFlex() == 0) + return 0; + + // ok we are flexible add up our children + nscoord totalFlex = 0; + nsIFrame* child = nsBox::GetChildXULBox(this); + while (child) + { + totalFlex += child->GetXULFlex(); + child = GetNextXULBox(child); + } + + mFlex = totalFlex; + + return totalFlex; +} + + diff --git a/layout/xul/grid/nsGridRowGroupFrame.h b/layout/xul/grid/nsGridRowGroupFrame.h new file mode 100644 index 000000000..f367e2121 --- /dev/null +++ b/layout/xul/grid/nsGridRowGroupFrame.h @@ -0,0 +1,49 @@ +/* -*- 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 D Vaughan + A frame that can have multiple children. Only one child may be displayed at one time. So the + can be flipped though like a deck of cards. + +**/ + +#ifndef nsGridRowGroupFrame_h___ +#define nsGridRowGroupFrame_h___ + +#include "mozilla/Attributes.h" +#include "nsBoxFrame.h" + +/** + * A frame representing a grid row (or column) group, which is usually + * an element that is a child of a grid and contains all the rows (or + * all the columns). However, multiple levels of groups are allowed, so + * the parent or child could instead be another group. + */ +class nsGridRowGroupFrame : public nsBoxFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override + { + return MakeFrameName(NS_LITERAL_STRING("nsGridRowGroup"), aResult); + } +#endif + + nsGridRowGroupFrame(nsStyleContext* aContext, + nsBoxLayout* aLayoutManager): + nsBoxFrame(aContext, false, aLayoutManager) {} + + virtual nscoord GetXULFlex() override; + +}; // class nsGridRowGroupFrame + + + +#endif + diff --git a/layout/xul/grid/nsGridRowGroupLayout.cpp b/layout/xul/grid/nsGridRowGroupLayout.cpp new file mode 100644 index 000000000..1c600cef5 --- /dev/null +++ b/layout/xul/grid/nsGridRowGroupLayout.cpp @@ -0,0 +1,265 @@ +/* -*- 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 +// + + +/* + * The nsGridRowGroupLayout implements the <rows> or <columns> tag in a grid. + */ + +#include "nsGridRowGroupLayout.h" +#include "nsCOMPtr.h" +#include "nsIScrollableFrame.h" +#include "nsBox.h" +#include "nsBoxLayoutState.h" +#include "nsGridLayout2.h" +#include "nsGridRow.h" +#include "mozilla/ReflowInput.h" + +already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout() +{ + RefPtr<nsBoxLayout> layout = new nsGridRowGroupLayout(); + return layout.forget(); +} + +nsGridRowGroupLayout::nsGridRowGroupLayout():nsGridRowLayout(), mRowCount(0) +{ +} + +nsGridRowGroupLayout::~nsGridRowGroupLayout() +{ +} + +void +nsGridRowGroupLayout::ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + if (grid) + grid->RowAddedOrRemoved(aState, index, isHorizontal); +} + +void +nsGridRowGroupLayout::AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal) +{ + nscoord& size = GET_WIDTH(aSize, aIsHorizontal); + + if (size == NS_INTRINSICSIZE || aSize2 == NS_INTRINSICSIZE) + size = NS_INTRINSICSIZE; + else + size += aSize2; +} + +nsSize +nsGridRowGroupLayout::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize vpref = nsGridRowLayout::GetXULPrefSize(aBox, aState); + + + /* It is possible that we could have some extra columns. This is when less columns in XUL were + * defined that needed. And example might be a grid with 3 defined columns but a row with 4 cells in + * it. We would need an extra column to make the grid work. But because that extra column does not + * have a box associated with it we must add its size in manually. Remember we could have extra rows + * as well. + */ + + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + + if (grid) + { + // make sure we add in extra columns sizes as well + bool isHorizontal = IsXULHorizontal(aBox); + int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal); + int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal); + for (int32_t i=0; i < extraColumns; i++) + { + nscoord pref = + grid->GetPrefRowHeight(aState, i+start, !isHorizontal); // GetPrefColumnWidth + + AddWidth(vpref, pref, isHorizontal); + } + } + + return vpref; +} + +nsSize +nsGridRowGroupLayout::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize maxSize = nsGridRowLayout::GetXULMaxSize(aBox, aState); + + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + + if (grid) + { + // make sure we add in extra columns sizes as well + bool isHorizontal = IsXULHorizontal(aBox); + int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal); + int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal); + for (int32_t i=0; i < extraColumns; i++) + { + nscoord max = + grid->GetMaxRowHeight(aState, i+start, !isHorizontal); // GetMaxColumnWidth + + AddWidth(maxSize, max, isHorizontal); + } + } + + return maxSize; +} + +nsSize +nsGridRowGroupLayout::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + nsSize minSize = nsGridRowLayout::GetXULMinSize(aBox, aState); + + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + + if (grid) + { + // make sure we add in extra columns sizes as well + bool isHorizontal = IsXULHorizontal(aBox); + int32_t extraColumns = grid->GetExtraColumnCount(isHorizontal); + int32_t start = grid->GetColumnCount(isHorizontal) - grid->GetExtraColumnCount(isHorizontal); + for (int32_t i=0; i < extraColumns; i++) + { + nscoord min = + grid->GetMinRowHeight(aState, i+start, !isHorizontal); // GetMinColumnWidth + AddWidth(minSize, min, isHorizontal); + } + } + + return minSize; +} + +/* + * Run down through our children dirtying them recursively. + */ +void +nsGridRowGroupLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + if (aBox) { + // mark us dirty + // XXXldb We probably don't want to walk up the ancestor chain + // calling MarkIntrinsicISizesDirty for every row group. + aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange, + NS_FRAME_IS_DIRTY); + nsIFrame* child = nsBox::GetChildXULBox(aBox); + + while(child) { + + // walk into scrollframes + nsIFrame* deepChild = nsGrid::GetScrolledBox(child); + + // walk into other monuments + nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild); + if (monument) + monument->DirtyRows(deepChild, aState); + + child = nsBox::GetNextXULBox(child); + } + } +} + + +void +nsGridRowGroupLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) +{ + if (aBox) { + int32_t startCount = aRowCount; + + nsIFrame* child = nsBox::GetChildXULBox(aBox); + + while(child) { + + // first see if it is a scrollframe. If so walk down into it and get the scrolled child + nsIFrame* deepChild = nsGrid::GetScrolledBox(child); + + nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild); + if (monument) { + monument->CountRowsColumns(deepChild, aRowCount, aComputedColumnCount); + child = nsBox::GetNextXULBox(child); + deepChild = child; + continue; + } + + child = nsBox::GetNextXULBox(child); + + // if not a monument. Then count it. It will be a bogus row + aRowCount++; + } + + mRowCount = aRowCount - startCount; + } +} + + +/** + * Fill out the given row structure recursively + */ +int32_t +nsGridRowGroupLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows) +{ + int32_t rowCount = 0; + + if (aBox) { + nsIFrame* child = nsBox::GetChildXULBox(aBox); + + while(child) { + + // first see if it is a scrollframe. If so walk down into it and get the scrolled child + nsIFrame* deepChild = nsGrid::GetScrolledBox(child); + + nsIGridPart* monument = nsGrid::GetPartFromBox(deepChild); + if (monument) { + rowCount += monument->BuildRows(deepChild, &aRows[rowCount]); + child = nsBox::GetNextXULBox(child); + deepChild = child; + continue; + } + + aRows[rowCount].Init(child, true); + + child = nsBox::GetNextXULBox(child); + + // if not a monument. Then count it. It will be a bogus row + rowCount++; + } + } + + return rowCount; +} + +nsMargin +nsGridRowGroupLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) +{ + // group have border and padding added to the total margin + + nsMargin margin = nsGridRowLayout::GetTotalMargin(aBox, aIsHorizontal); + + // make sure we have the scrollframe on the outside if it has one. + // that's where the border is. + aBox = nsGrid::GetScrollBox(aBox); + + // add our border/padding to it + nsMargin borderPadding(0,0,0,0); + aBox->GetXULBorderAndPadding(borderPadding); + margin += borderPadding; + + return margin; +} + + diff --git a/layout/xul/grid/nsGridRowGroupLayout.h b/layout/xul/grid/nsGridRowGroupLayout.h new file mode 100644 index 000000000..07f2aa1eb --- /dev/null +++ b/layout/xul/grid/nsGridRowGroupLayout.h @@ -0,0 +1,51 @@ +/* -*- 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/. */ + +/** + + Author: + Eric D Vaughan + +**/ + +#ifndef nsGridRowGroupLayout_h___ +#define nsGridRowGroupLayout_h___ + +#include "mozilla/Attributes.h" +#include "nsGridRowLayout.h" + +/** + * The nsBoxLayout implementation for nsGridRowGroupFrame. + */ +class nsGridRowGroupLayout : public nsGridRowLayout +{ +public: + + friend already_AddRefed<nsBoxLayout> NS_NewGridRowGroupLayout(); + + virtual nsGridRowGroupLayout* CastToRowGroupLayout() override { return this; } + virtual nsSize GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULMaxSize(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) override; + static void AddWidth(nsSize& aSize, nscoord aSize2, bool aIsHorizontal); + +private: + int32_t mRowCount; +}; + +#endif + diff --git a/layout/xul/grid/nsGridRowLayout.cpp b/layout/xul/grid/nsGridRowLayout.cpp new file mode 100644 index 000000000..a658e088e --- /dev/null +++ b/layout/xul/grid/nsGridRowLayout.cpp @@ -0,0 +1,197 @@ +/* -*- 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 "nsGridRowLayout.h" +#include "nsBoxLayoutState.h" +#include "nsIScrollableFrame.h" +#include "nsBox.h" +#include "nsStackLayout.h" +#include "nsGrid.h" + +nsGridRowLayout::nsGridRowLayout():nsSprocketLayout() +{ +} + +nsGridRowLayout::~nsGridRowLayout() +{ +} + +void +nsGridRowLayout::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, + nsIFrame* aPrevBox, + const nsFrameList::Slice& aNewChildren) +{ + ChildAddedOrRemoved(aBox, aState); +} + +void +nsGridRowLayout::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, + const nsFrameList::Slice& aNewChildren) +{ + ChildAddedOrRemoved(aBox, aState); +} + +void +nsGridRowLayout::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) +{ + ChildAddedOrRemoved(aBox, aState); +} + +void +nsGridRowLayout::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList) +{ + ChildAddedOrRemoved(aBox, aState); +} + +nsIGridPart* +nsGridRowLayout::GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) +{ + // go up and find our parent gridRow. Skip and non gridRow + // parents. + *aParentBox = nullptr; + + // walk up through any scrollboxes + aBox = nsGrid::GetScrollBox(aBox); + + // get the parent + if (aBox) + aBox = nsBox::GetParentXULBox(aBox); + + if (aBox) + { + nsIGridPart* parentGridRow = nsGrid::GetPartFromBox(aBox); + if (parentGridRow && parentGridRow->CanContain(this)) { + *aParentBox = aBox; + return parentGridRow; + } + } + + return nullptr; +} + + +nsGrid* +nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor) +{ + + if (aRequestor == nullptr) + { + nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted. + nsIGridPart* parent = GetParentGridPart(aBox, &parentBox); + if (parent) + return parent->GetGrid(parentBox, aIndex, this); + return nullptr; + } + + int32_t index = -1; + nsIFrame* child = nsBox::GetChildXULBox(aBox); + int32_t count = 0; + while(child) + { + // if there is a scrollframe walk inside it to its child + nsIFrame* childBox = nsGrid::GetScrolledBox(child); + + nsBoxLayout* layout = childBox->GetXULLayoutManager(); + nsIGridPart* gridRow = nsGrid::GetPartFromBox(childBox); + if (gridRow) + { + if (layout == aRequestor) { + index = count; + break; + } + count += gridRow->GetRowCount(); + } else + count++; + + child = nsBox::GetNextXULBox(child); + } + + // if we didn't find ourselves then the tree isn't properly formed yet + // this could happen during initial construction so lets just + // fail. + if (index == -1) { + *aIndex = -1; + return nullptr; + } + + (*aIndex) += index; + + nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted. + nsIGridPart* parent = GetParentGridPart(aBox, &parentBox); + if (parent) + return parent->GetGrid(parentBox, aIndex, this); + + return nullptr; +} + +nsMargin +nsGridRowLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal) +{ + // get our parents margin + nsMargin margin(0,0,0,0); + nsIFrame* parent = nullptr; + nsIGridPart* part = GetParentGridPart(aBox, &parent); + if (part && parent) { + // if we are the first or last child walk upward and add margins. + + // make sure we check for a scrollbox + aBox = nsGrid::GetScrollBox(aBox); + + // see if we have a next to see if we are last + nsIFrame* next = nsBox::GetNextXULBox(aBox); + + // get the parent first child to see if we are first + nsIFrame* child = nsBox::GetChildXULBox(parent); + + margin = part->GetTotalMargin(parent, aIsHorizontal); + + // if first or last + if (child == aBox || next == nullptr) { + + // if it's not the first child remove the top margin + // we don't need it. + if (child != aBox) + { + if (aIsHorizontal) + margin.top = 0; + else + margin.left = 0; + } + + // if it's not the last child remove the bottom margin + // we don't need it. + if (next != nullptr) + { + if (aIsHorizontal) + margin.bottom = 0; + else + margin.right = 0; + } + + } + } + + // add ours to it. + nsMargin ourMargin; + aBox->GetXULMargin(ourMargin); + margin += ourMargin; + + return margin; +} + +NS_IMPL_ADDREF_INHERITED(nsGridRowLayout, nsBoxLayout) +NS_IMPL_RELEASE_INHERITED(nsGridRowLayout, nsBoxLayout) + +NS_INTERFACE_MAP_BEGIN(nsGridRowLayout) + NS_INTERFACE_MAP_ENTRY(nsIGridPart) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart) +NS_INTERFACE_MAP_END_INHERITING(nsBoxLayout) diff --git a/layout/xul/grid/nsGridRowLayout.h b/layout/xul/grid/nsGridRowLayout.h new file mode 100644 index 000000000..22a6f12c9 --- /dev/null +++ b/layout/xul/grid/nsGridRowLayout.h @@ -0,0 +1,60 @@ +/* -*- 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/. */ + +/** + + Author: + Eric D Vaughan + +**/ + +#ifndef nsGridRowLayout_h___ +#define nsGridRowLayout_h___ + +#include "mozilla/Attributes.h" +#include "nsSprocketLayout.h" +#include "nsIGridPart.h" +class nsGridRowGroupLayout; +class nsGridLayout2; +class nsBoxLayoutState; +class nsGrid; + +/** + * A common base class for nsGridRowLeafLayout (the nsBoxLayout object + * for a grid row or column) and nsGridRowGroupLayout (the nsBoxLayout + * object for a grid row group or column group). + */ +// XXXldb This needs a name that indicates that it's a base class for +// both row and rows (row-group). +class nsGridRowLayout : public nsSprocketLayout, + public nsIGridPart +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + 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) override; + virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, + 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() 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 new file mode 100644 index 000000000..e973877a4 --- /dev/null +++ b/layout/xul/grid/nsGridRowLeafFrame.cpp @@ -0,0 +1,94 @@ +/* -*- 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 "nsGridRowLeafFrame.h" +#include "nsGridRowLeafLayout.h" +#include "nsGridRow.h" +#include "nsBoxLayoutState.h" +#include "nsGridLayout2.h" + +already_AddRefed<nsBoxLayout> NS_NewGridRowLeafLayout(); + +nsIFrame* +NS_NewGridRowLeafFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext) +{ + nsCOMPtr<nsBoxLayout> layout = NS_NewGridRowLeafLayout(); + return new (aPresShell) nsGridRowLeafFrame(aContext, false, layout); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsGridRowLeafFrame) + +/* + * Our border and padding could be affected by our columns or rows. + * Let's go check it out. + */ +nsresult +nsGridRowLeafFrame::GetXULBorderAndPadding(nsMargin& aBorderAndPadding) +{ + // if our columns have made our padding larger add it in. + nsresult rv = nsBoxFrame::GetXULBorderAndPadding(aBorderAndPadding); + + nsIGridPart* part = nsGrid::GetPartFromBox(this); + if (!part) + return rv; + + int32_t index = 0; + nsGrid* grid = part->GetGrid(this, &index); + + if (!grid) + return rv; + + bool isHorizontal = IsXULHorizontal(); + + int32_t firstIndex = 0; + int32_t lastIndex = 0; + nsGridRow* firstRow = nullptr; + nsGridRow* lastRow = nullptr; + grid->GetFirstAndLastRow(firstIndex, lastIndex, firstRow, lastRow, isHorizontal); + + // only the first and last rows can be affected. + if (firstRow && firstRow->GetBox() == this) { + + nscoord top = 0; + nscoord bottom = 0; + grid->GetRowOffsets(firstIndex, top, bottom, isHorizontal); + + if (isHorizontal) { + if (top > aBorderAndPadding.top) + aBorderAndPadding.top = top; + } else { + if (top > aBorderAndPadding.left) + aBorderAndPadding.left = top; + } + } + + if (lastRow && lastRow->GetBox() == this) { + + nscoord top = 0; + nscoord bottom = 0; + grid->GetRowOffsets(lastIndex, top, bottom, isHorizontal); + + if (isHorizontal) { + if (bottom > aBorderAndPadding.bottom) + aBorderAndPadding.bottom = bottom; + } else { + if (bottom > aBorderAndPadding.right) + aBorderAndPadding.right = bottom; + } + + } + + return rv; +} + + diff --git a/layout/xul/grid/nsGridRowLeafFrame.h b/layout/xul/grid/nsGridRowLeafFrame.h new file mode 100644 index 000000000..dd4ee6835 --- /dev/null +++ b/layout/xul/grid/nsGridRowLeafFrame.h @@ -0,0 +1,54 @@ +/* -*- 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 D Vaughan + A frame that can have multiple children. Only one child may be displayed at one time. So the + can be flipped though like a deck of cards. + +**/ + +#ifndef nsGridRowLeafFrame_h___ +#define nsGridRowLeafFrame_h___ + +#include "mozilla/Attributes.h" +#include "nsBoxFrame.h" + +/** + * A frame representing a grid row (or column). Grid row (and column) + * elements are the children of row group (or column group) elements, + * and their children are placed one to a cell. + */ +// XXXldb This needs a better name that indicates that it's for any grid +// row. +class nsGridRowLeafFrame : public nsBoxFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + friend nsIFrame* NS_NewGridRowLeafFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext); + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override + { + return MakeFrameName(NS_LITERAL_STRING("nsGridRowLeaf"), aResult); + } +#endif + + nsGridRowLeafFrame(nsStyleContext* aContext, + bool aIsRoot, + nsBoxLayout* aLayoutManager): + nsBoxFrame(aContext, aIsRoot, aLayoutManager) {} + + virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding) override; + +}; // class nsGridRowLeafFrame + + + +#endif + diff --git a/layout/xul/grid/nsGridRowLeafLayout.cpp b/layout/xul/grid/nsGridRowLeafLayout.cpp new file mode 100644 index 000000000..2a089af0c --- /dev/null +++ b/layout/xul/grid/nsGridRowLeafLayout.cpp @@ -0,0 +1,328 @@ +/* -*- 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 "nsGridRowLeafLayout.h" +#include "nsGridRowGroupLayout.h" +#include "nsGridRow.h" +#include "nsBoxLayoutState.h" +#include "nsBox.h" +#include "nsIScrollableFrame.h" +#include "nsBoxFrame.h" +#include "nsGridLayout2.h" +#include <algorithm> + +already_AddRefed<nsBoxLayout> NS_NewGridRowLeafLayout() +{ + RefPtr<nsBoxLayout> layout = new nsGridRowLeafLayout(); + return layout.forget(); +} + +nsGridRowLeafLayout::nsGridRowLeafLayout():nsGridRowLayout() +{ +} + +nsGridRowLeafLayout::~nsGridRowLeafLayout() +{ +} + +nsSize +nsGridRowLeafLayout::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + // If we are not in a grid. Then we just work like a box. But if we are in a grid + // ask the grid for our size. + if (!grid) { + return nsGridRowLayout::GetXULPrefSize(aBox, aState); + } + else { + return grid->GetPrefRowSize(aState, index, isHorizontal); + //AddBorderAndPadding(aBox, pref); + } +} + +nsSize +nsGridRowLeafLayout::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + if (!grid) + return nsGridRowLayout::GetXULMinSize(aBox, aState); + else { + nsSize minSize = grid->GetMinRowSize(aState, index, isHorizontal); + AddBorderAndPadding(aBox, minSize); + return minSize; + } +} + +nsSize +nsGridRowLeafLayout::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + if (!grid) + return nsGridRowLayout::GetXULMaxSize(aBox, aState); + else { + nsSize maxSize; + maxSize = grid->GetMaxRowSize(aState, index, isHorizontal); + AddBorderAndPadding(aBox, maxSize); + return maxSize; + } +} + +/** If a child is added or removed or changes size + */ +void +nsGridRowLeafLayout::ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + if (grid) + grid->CellAddedOrRemoved(aState, index, isHorizontal); +} + +void +nsGridRowLeafLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsBoxSize*& aBoxSizes, nscoord& aMinSize, nscoord& aMaxSize, int32_t& aFlexes) +{ + int32_t index = 0; + nsGrid* grid = GetGrid(aBox, &index); + bool isHorizontal = IsXULHorizontal(aBox); + + // Our base class SprocketLayout is giving us a chance to change the box sizes before layout + // If we are a row lets change the sizes to match our columns. If we are a column then do the opposite + // and make them match or rows. + if (grid) { + nsGridRow* column; + int32_t count = grid->GetColumnCount(isHorizontal); + nsBoxSize* start = nullptr; + nsBoxSize* last = nullptr; + nsBoxSize* current = nullptr; + nsIFrame* child = nsBox::GetChildXULBox(aBox); + for (int i=0; i < count; i++) + { + column = grid->GetColumnAt(i,isHorizontal); + + // make sure the value was computed before we use it. + // !isHorizontal is passed in to invert the behavior of these methods. + nscoord pref = + grid->GetPrefRowHeight(aState, i, !isHorizontal); // GetPrefColumnWidth + nscoord min = + grid->GetMinRowHeight(aState, i, !isHorizontal); // GetMinColumnWidth + nscoord max = + grid->GetMaxRowHeight(aState, i, !isHorizontal); // GetMaxColumnWidth + nscoord flex = grid->GetRowFlex(i, !isHorizontal); // GetColumnFlex + nscoord left = 0; + nscoord right = 0; + grid->GetRowOffsets(i, left, right, !isHorizontal); // GetColumnOffsets + nsIFrame* box = column->GetBox(); + bool collapsed = false; + nscoord topMargin = column->mTopMargin; + nscoord bottomMargin = column->mBottomMargin; + + if (box) + collapsed = box->IsXULCollapsed(); + + pref = pref - (left + right); + if (pref < 0) + pref = 0; + + // if this is the first or last column. Take into account that + // our row could have a border that could affect our left or right + // padding from our columns. If the row has padding subtract it. + // would should always be able to garentee that our margin is smaller + // or equal to our left or right + int32_t firstIndex = 0; + int32_t lastIndex = 0; + nsGridRow* firstRow = nullptr; + nsGridRow* lastRow = nullptr; + grid->GetFirstAndLastRow(firstIndex, lastIndex, firstRow, lastRow, !isHorizontal); + + if (i == firstIndex || i == lastIndex) { + nsMargin offset = GetTotalMargin(aBox, isHorizontal); + + nsMargin border(0,0,0,0); + // can't call GetBorderPadding we will get into recursion + aBox->GetXULBorder(border); + offset += border; + aBox->GetXULPadding(border); + offset += border; + + // subtract from out left and right + if (i == firstIndex) + { + if (isHorizontal) + left -= offset.left; + else + left -= offset.top; + } + + if (i == lastIndex) + { + if (isHorizontal) + right -= offset.right; + else + right -= offset.bottom; + } + } + + // initialize the box size here + max = std::max(min, max); + pref = nsBox::BoundsCheck(min, pref, max); + + current = new (aState) nsBoxSize(); + current->pref = pref; + current->min = min; + current->max = max; + current->flex = flex; + current->bogus = column->mIsBogus; + current->left = left + topMargin; + current->right = right + bottomMargin; + current->collapsed = collapsed; + + if (!start) { + start = current; + last = start; + } else { + last->next = current; + last = current; + } + + if (child && !column->mIsBogus) + child = nsBox::GetNextXULBox(child); + + } + aBoxSizes = start; + } + + nsSprocketLayout::PopulateBoxSizes(aBox, aState, aBoxSizes, aMinSize, aMaxSize, aFlexes); +} + +void +nsGridRowLeafLayout::ComputeChildSizes(nsIFrame* aBox, + nsBoxLayoutState& aState, + nscoord& aGivenSize, + nsBoxSize* aBoxSizes, + nsComputedBoxSize*& aComputedBoxSizes) +{ + // see if we are in a scrollable frame. If we are then there could be scrollbars present + // if so we need to subtract them out to make sure our columns line up. + if (aBox) { + bool isHorizontal = aBox->IsXULHorizontal(); + + // go up the parent chain looking for scrollframes + nscoord diff = 0; + nsIFrame* parentBox; + (void)GetParentGridPart(aBox, &parentBox); + while (parentBox) { + nsIFrame* scrollbox = nsGrid::GetScrollBox(parentBox); + nsIScrollableFrame *scrollable = do_QueryFrame(scrollbox); + if (scrollable) { + // Don't call GetActualScrollbarSizes here because it's not safe + // to call that while we're reflowing the contents of the scrollframe, + // which we are here. + nsMargin scrollbarSizes = scrollable->GetDesiredScrollbarSizes(&aState); + uint32_t visible = scrollable->GetScrollbarVisibility(); + + if (isHorizontal && (visible & nsIScrollableFrame::VERTICAL)) { + diff += scrollbarSizes.left + scrollbarSizes.right; + } else if (!isHorizontal && (visible & nsIScrollableFrame::HORIZONTAL)) { + diff += scrollbarSizes.top + scrollbarSizes.bottom; + } + } + + (void)GetParentGridPart(parentBox, &parentBox); + } + + if (diff > 0) { + aGivenSize += diff; + + nsSprocketLayout::ComputeChildSizes(aBox, aState, aGivenSize, aBoxSizes, aComputedBoxSizes); + + aGivenSize -= diff; + + nsComputedBoxSize* s = aComputedBoxSizes; + nsComputedBoxSize* last = aComputedBoxSizes; + while(s) + { + last = s; + s = s->next; + } + + if (last) + last->size -= diff; + + return; + } + } + + nsSprocketLayout::ComputeChildSizes(aBox, aState, aGivenSize, aBoxSizes, aComputedBoxSizes); + +} + +NS_IMETHODIMP +nsGridRowLeafLayout::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) +{ + return nsGridRowLayout::XULLayout(aBox, aBoxLayoutState); +} + +void +nsGridRowLeafLayout::DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState) +{ + if (aBox) { + // mark us dirty + // XXXldb We probably don't want to walk up the ancestor chain + // calling MarkIntrinsicISizesDirty for every row. + aState.PresShell()->FrameNeedsReflow(aBox, nsIPresShell::eTreeChange, + NS_FRAME_IS_DIRTY); + } +} + +void +nsGridRowLeafLayout::CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount) +{ + if (aBox) { + nsIFrame* child = nsBox::GetChildXULBox(aBox); + + // count the children + int32_t columnCount = 0; + while(child) { + child = nsBox::GetNextXULBox(child); + columnCount++; + } + + // if our count is greater than the current column count + if (columnCount > aComputedColumnCount) + aComputedColumnCount = columnCount; + + aRowCount++; + } +} + +int32_t +nsGridRowLeafLayout::BuildRows(nsIFrame* aBox, nsGridRow* aRows) +{ + if (aBox) { + aRows[0].Init(aBox, false); + return 1; + } + + return 0; +} + diff --git a/layout/xul/grid/nsGridRowLeafLayout.h b/layout/xul/grid/nsGridRowLeafLayout.h new file mode 100644 index 000000000..b103ab176 --- /dev/null +++ b/layout/xul/grid/nsGridRowLeafLayout.h @@ -0,0 +1,62 @@ +/* -*- 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/. */ + +/** + + Author: + Eric D Vaughan + +**/ + +#ifndef nsGridRowLeafLayout_h___ +#define nsGridRowLeafLayout_h___ + +#include "mozilla/Attributes.h" +#include "nsGridRowLayout.h" +#include "nsCOMPtr.h" + +/** + * The nsBoxLayout implementation for nsGridRowLeafFrame. + */ +// XXXldb This needs a better name that indicates that it's for any grid +// row. +class nsGridRowLeafLayout final : public nsGridRowLayout +{ +public: + + friend already_AddRefed<nsBoxLayout> NS_NewGridRowLeafLayout(); + + virtual nsSize GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) override; + virtual void ChildAddedOrRemoved(nsIFrame* aBox, nsBoxLayoutState& aState) override; + NS_IMETHOD XULLayout(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) override; + virtual void ComputeChildSizes(nsIFrame* aBox, + nsBoxLayoutState& aState, + nscoord& aGivenSize, + nsBoxSize* aBoxSizes, + nsComputedBoxSize*& aComputedBoxSizes) override; + + + nsGridRowLeafLayout(); + virtual ~nsGridRowLeafLayout(); + //virtual void AddBorderAndPadding(nsIFrame* aBox, nsSize& aSize); + +private: + +}; // class nsGridRowLeafLayout + +#endif + diff --git a/layout/xul/grid/nsIGridPart.h b/layout/xul/grid/nsIGridPart.h new file mode 100644 index 000000000..202429de6 --- /dev/null +++ b/layout/xul/grid/nsIGridPart.h @@ -0,0 +1,95 @@ +/* -*- 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 nsIGridPart_h___ +#define nsIGridPart_h___ + +#include "nsISupports.h" + +class nsGridRowGroupLayout; +class nsGrid; +class nsGridRowLayout; +class nsGridRow; +class nsGridLayout2; + +// 07373ed7-e947-4a5e-b36c-69f7c195677b +#define NS_IGRIDPART_IID \ +{ 0x07373ed7, 0xe947, 0x4a5e, \ + { 0xb3, 0x6c, 0x69, 0xf7, 0xc1, 0x95, 0x67, 0x7b } } + +/** + * An additional interface implemented by nsBoxLayout implementations + * for parts of a grid (excluding cells, which are not special). + */ +class nsIGridPart : public nsISupports { + +public: + + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IGRIDPART_IID) + + virtual nsGridRowGroupLayout* CastToRowGroupLayout()=0; + virtual nsGridLayout2* CastToGridLayout()=0; + + /** + * @param aBox [IN] The other half of the |this| parameter, i.e., the box + * whose layout manager is |this|. + * @param aIndex [INOUT] For callers not setting aRequestor, the value + * pointed to by aIndex is incremented by the index + * of the row (aBox) within its row group; if aBox + * is not a row/column, it is untouched. + * The implementation does this by doing the aIndex + * incrementing in the call to the parent row group + * when aRequestor is non-null. + * @param aRequestor [IN] Non-null if and only if this is a recursive + * call from the GetGrid method on a child grid part, + * in which case it is a pointer to that grid part. + * (This may only be non-null for row groups and + * grids.) + * @return The grid of which aBox (a row, row group, or grid) is a part. + */ + virtual nsGrid* GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor=nullptr)=0; + + /** + * @param aBox [IN] The other half of the |this| parameter, i.e., the box + * whose layout manager is |this|. + * @param aParentBox [OUT] The box representing the next level up in + * the grid (i.e., row group for a row, grid for a + * row group). + * @returns The layout manager for aParentBox. + */ + virtual nsIGridPart* GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox) = 0; + + /** + * @param aBox [IN] The other half of the |this| parameter, i.e., the box + * whose layout manager is |this|. + * @param aRowCount [INOUT] Row count + * @param aComputedColumnCount [INOUT] Column count + */ + virtual void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount, int32_t& aComputedColumnCount)=0; + virtual void DirtyRows(nsIFrame* aBox, nsBoxLayoutState& aState)=0; + virtual int32_t BuildRows(nsIFrame* aBox, nsGridRow* aRows)=0; + virtual nsMargin GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal)=0; + virtual int32_t GetRowCount() { return 1; } + + /** + * Return the level of the grid hierarchy this grid part represents. + */ + enum Type { eGrid, eRowGroup, eRowLeaf }; + virtual Type GetType()=0; + + /** + * Return whether this grid part is an appropriate parent for the argument. + */ + bool CanContain(nsIGridPart* aPossibleChild) { + Type thisType = GetType(), childType = aPossibleChild->GetType(); + return thisType + 1 == childType || (thisType == eRowGroup && childType == eRowGroup); + } + +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIGridPart, NS_IGRIDPART_IID) + +#endif + diff --git a/layout/xul/grid/reftests/column-sizing-1-ref.xul b/layout/xul/grid/reftests/column-sizing-1-ref.xul new file mode 100644 index 000000000..df0113083 --- /dev/null +++ b/layout/xul/grid/reftests/column-sizing-1-ref.xul @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <hbox> + <vbox style="background:aqua"> + <label value="Left" /> + </vbox> + <vbox style="background:yellow"> + <textbox value="Right" /> + </vbox> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/column-sizing-1.xul b/layout/xul/grid/reftests/column-sizing-1.xul new file mode 100644 index 000000000..2a94569ba --- /dev/null +++ b/layout/xul/grid/reftests/column-sizing-1.xul @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <grid> + <columns> + <column style="background:aqua"> + <label value="Left" /> + </column> + <column style="background:yellow"> + <textbox value="Right" /> + </column> + </columns> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-basic-ref.xhtml b/layout/xul/grid/reftests/not-full-basic-ref.xhtml new file mode 100644 index 000000000..cd233585a --- /dev/null +++ b/layout/xul/grid/reftests/not-full-basic-ref.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + top: 0px; height: 200px; left: 0px; width: 200px;" /> +<div style="background: rgb(0, 255, 0); + top: 200px; bottom: 0px; left: 0px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 200px; height: 100px; left: 100px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + top: 0px; height: 100px; left: 200px; right: 0px;" /> +<div style="background: rgb(0, 0, 153); + top: 100px; height: 100px; left: 200px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/not-full-basic.xul b/layout/xul/grid/reftests/not-full-basic.xul new file mode 100644 index 000000000..5c7fa9123 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-basic.xul @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-grid-pack-align.xul b/layout/xul/grid/reftests/not-full-grid-pack-align.xul new file mode 100644 index 000000000..3fe6a95cb --- /dev/null +++ b/layout/xul/grid/reftests/not-full-grid-pack-align.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <!-- align and pack should be no-ops on grid element (not on columns/rows) --> + <grid flex="1" align="start" pack="end"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-group-align-ref.xhtml b/layout/xul/grid/reftests/not-full-row-group-align-ref.xhtml new file mode 100644 index 000000000..abef67f87 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-align-ref.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + top: 100px; height: 100px; left: 100px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 0px; height: 100px; left: 100px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 200px; height: 100px; left: 100px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + top: 100px; height: 100px; left: 0px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + top: 100px; height: 100px; left: 200px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/not-full-row-group-align.xul b/layout/xul/grid/reftests/not-full-row-group-align.xul new file mode 100644 index 000000000..0037d9fb8 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-align.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <grid flex="1"> + <!-- does anybody actually *want* the way columns align="start" behaves here? --> + <columns align="start"> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows align="start"> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-group-direction-ref.xhtml b/layout/xul/grid/reftests/not-full-row-group-direction-ref.xhtml new file mode 100644 index 000000000..b2a92b07b --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-direction-ref.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + bottom: 0px; height: 100px; right: 0px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + bottom: 0px; height: 100px; left: 0px; right: 100px;" /> +<div style="background: rgb(0, 0, 153); + bottom: 100px; height: 100px; left: 0px; width: 300px;" /> +<div style="background: rgb(0, 255, 0); + top: 0px; bottom: 100px; right: 0px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 0px; height: 300px; right: 100px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/not-full-row-group-direction.xul b/layout/xul/grid/reftests/not-full-row-group-direction.xul new file mode 100644 index 000000000..c38db40a5 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-direction.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + rows, columns { -moz-box-direction: reverse; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-group-pack-ref.xhtml b/layout/xul/grid/reftests/not-full-row-group-pack-ref.xhtml new file mode 100644 index 000000000..9232f6ba4 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-pack-ref.xhtml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + bottom: 200px; height: 100px; right: 200px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + bottom: 200px; height: 100px; left: 0px; right: 300px;" /> +<div style="background: rgb(0, 0, 153); + bottom: 100px; height: 100px; left: 0px; width: 300px;" /> +<div style="background: rgb(0, 0, 153); + bottom: 200px; height: 100px; right: 0px; width: 200px;" /> +<div style="background: rgb(0, 255, 0); + top: 0px; bottom: 300px; right: 200px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 0px; height: 300px; right: 100px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + bottom: 0px; height: 200px; right: 200px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/not-full-row-group-pack.xul b/layout/xul/grid/reftests/not-full-row-group-pack.xul new file mode 100644 index 000000000..bb8f650ae --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-group-pack.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + rows, columns { -moz-box-pack: end; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-leaf-align.xul b/layout/xul/grid/reftests/not-full-row-leaf-align.xul new file mode 100644 index 000000000..806514ebd --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-leaf-align.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + row, column { -moz-box-align: start; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-leaf-direction.xul b/layout/xul/grid/reftests/not-full-row-leaf-direction.xul new file mode 100644 index 000000000..17c3a6585 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-leaf-direction.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + row, column { -moz-box-direction: reverse; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/not-full-row-leaf-pack-ref.xhtml b/layout/xul/grid/reftests/not-full-row-leaf-pack-ref.xhtml new file mode 100644 index 000000000..30635313a --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-leaf-pack-ref.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + top: 0px; height: 100px; left: 0px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + top: 100px; bottom: 0px; left: 0px; width: 100px;" /> +<div style="background: rgb(0, 255, 0); + bottom: 0px; height: 300px; left: 100px; width: 100px;" /> +<div style="background: rgb(0, 0, 153); + top: 0px; height: 100px; left: 100px; right: 0px;" /> +<div style="background: rgb(0, 0, 153); + top: 100px; height: 100px; right: 0px; width: 300px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/not-full-row-leaf-pack.xul b/layout/xul/grid/reftests/not-full-row-leaf-pack.xul new file mode 100644 index 000000000..8f353c764 --- /dev/null +++ b/layout/xul/grid/reftests/not-full-row-leaf-pack.xul @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + row, column { -moz-box-pack: end; } + ]]></style> + <grid flex="1"> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/reftest-stylo.list b/layout/xul/grid/reftests/reftest-stylo.list new file mode 100644 index 000000000..eb73955c9 --- /dev/null +++ b/layout/xul/grid/reftests/reftest-stylo.list @@ -0,0 +1,38 @@ +# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing +skip-if((B2G&&browserIsRemote)||Mulet) == row-sizing-1.xul row-sizing-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == column-sizing-1.xul column-sizing-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == z-order-1.xul z-order-1.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == z-order-2.xul z-order-2.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == not-full-basic.xul not-full-basic.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,110000) == not-full-grid-pack-align.xul not-full-grid-pack-align.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,30000) == not-full-row-group-align.xul not-full-row-group-align.xul +# does anyone want/need this behavior? +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,10000) == not-full-row-group-pack.xul not-full-row-group-pack.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,50000) == not-full-row-group-direction.xul not-full-row-group-direction.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == not-full-row-leaf-align.xul not-full-row-leaf-align.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,50000) == not-full-row-leaf-pack.xul not-full-row-leaf-pack.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,80000) == not-full-row-leaf-direction.xul not-full-row-leaf-direction.xul +skip-if(B2G||Mulet) random-if(transparentScrollbars) fuzzy-if(OSX==1010,1,565) == scrollable-columns.xul scrollable-columns.xul +# bug 650597 +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == scrollable-rows.xul scrollable-rows.xul +# Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) == sizing-2d.xul sizing-2d.xul +# Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/xul/grid/reftests/reftest.list b/layout/xul/grid/reftests/reftest.list new file mode 100644 index 000000000..eb414f906 --- /dev/null +++ b/layout/xul/grid/reftests/reftest.list @@ -0,0 +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 +fuzzy-if(skiaContent,1,60000) == z-order-1.xul z-order-1-ref.xul +fuzzy-if(skiaContent,1,60000) == z-order-2.xul z-order-2-ref.xul +fuzzy-if(skiaContent,1,60000) == not-full-basic.xul not-full-basic-ref.xhtml +fuzzy-if(skiaContent,1,110000) == not-full-grid-pack-align.xul not-full-basic-ref.xhtml +fuzzy-if(skiaContent,1,30000) == not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior? +fuzzy-if(skiaContent,1,10000) == not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml +fuzzy-if(skiaContent,1,50000) == not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml +fuzzy-if(skiaContent,1,60000) == not-full-row-leaf-align.xul not-full-basic-ref.xhtml +fuzzy-if(skiaContent,1,50000) == not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml +fuzzy-if(skiaContent,1,80000) == not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml +random-if(transparentScrollbars) fuzzy-if(OSX==1010,1,565) == scrollable-columns.xul scrollable-columns-ref.xhtml # bug 650597 +fails == scrollable-rows.xul scrollable-rows-ref.xhtml +== sizing-2d.xul sizing-2d-ref.xul diff --git a/layout/xul/grid/reftests/row-or-column-sizing-1.xul b/layout/xul/grid/reftests/row-or-column-sizing-1.xul new file mode 100644 index 000000000..6c64eef18 --- /dev/null +++ b/layout/xul/grid/reftests/row-or-column-sizing-1.xul @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <grid> + <columns> + <column /> + <column /> + </columns> + <rows> + <row> + <hbox /> + <label value="Upper right" /> + </row> + <row> + <textbox value="Lower left" /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/row-or-column-sizing-2.xul b/layout/xul/grid/reftests/row-or-column-sizing-2.xul new file mode 100644 index 000000000..008f82fd5 --- /dev/null +++ b/layout/xul/grid/reftests/row-or-column-sizing-2.xul @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <grid> + <columns> + <column> + <hbox /> + <textbox value="Lower left" /> + </column> + <column> + <label value="Upper right" /> + <hbox /> + </column> + </columns> + <rows> + <row /> + <row /> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/row-or-column-sizing-3.xul b/layout/xul/grid/reftests/row-or-column-sizing-3.xul new file mode 100644 index 000000000..1e8e55c29 --- /dev/null +++ b/layout/xul/grid/reftests/row-or-column-sizing-3.xul @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <grid> + <columns> + <column> + <hbox /> + <hbox /> + </column> + <column> + <label value="Upper right" /> + <hbox /> + </column> + </columns> + <rows> + <row> + <hbox /> + <hbox /> + </row> + <row> + <textbox value="Lower left" /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/row-or-column-sizing-4.xul b/layout/xul/grid/reftests/row-or-column-sizing-4.xul new file mode 100644 index 000000000..5a826fd84 --- /dev/null +++ b/layout/xul/grid/reftests/row-or-column-sizing-4.xul @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <grid> + <columns> + <column> + <hbox /> + <textbox value="Lower left" /> + </column> + <column> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row> + <hbox /> + <label value="Upper right" /> + </row> + <row> + <hbox /> + <hbox /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/row-sizing-1-ref.xul b/layout/xul/grid/reftests/row-sizing-1-ref.xul new file mode 100644 index 000000000..b35719052 --- /dev/null +++ b/layout/xul/grid/reftests/row-sizing-1-ref.xul @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + orient="horizontal" + title="XUL Grid Test"> + <vbox> + <hbox style="background:aqua"> + <label value="Top" /> + </hbox> + <hbox style="background:yellow"> + <textbox value="Bottom" /> + </hbox> + </vbox> +</window> diff --git a/layout/xul/grid/reftests/row-sizing-1.xul b/layout/xul/grid/reftests/row-sizing-1.xul new file mode 100644 index 000000000..0455b8da4 --- /dev/null +++ b/layout/xul/grid/reftests/row-sizing-1.xul @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + orient="horizontal" + title="XUL Grid Test"> + <grid> + <rows> + <row style="background:aqua"> + <label value="Top" /> + </row> + <row style="background:yellow"> + <textbox value="Bottom" /> + </row> + </rows> + </grid> +</window> diff --git a/layout/xul/grid/reftests/scrollable-columns-ref.xhtml b/layout/xul/grid/reftests/scrollable-columns-ref.xhtml new file mode 100644 index 000000000..698c5a036 --- /dev/null +++ b/layout/xul/grid/reftests/scrollable-columns-ref.xhtml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + top: 0px; height: 200px; left: 0px; width: 200px;" /> +<div style="background: rgb(0, 255, 0); overflow: auto; + top: 200px; height: 100px; left: 0px; width: 200px;"> + <div style="width: 300px; height: 50px" /> +</div> +<div style="background: rgb(0, 0, 153); + top: 100px; height: 100px; left: 200px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/scrollable-columns.xul b/layout/xul/grid/reftests/scrollable-columns.xul new file mode 100644 index 000000000..661c4412f --- /dev/null +++ b/layout/xul/grid/reftests/scrollable-columns.xul @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + grid { width: 200px; height: 200px; } + columns { overflow: auto; } + ]]></style> + <hbox> + <grid> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/scrollable-rows-ref.xhtml b/layout/xul/grid/reftests/scrollable-rows-ref.xhtml new file mode 100644 index 000000000..6b5b95f02 --- /dev/null +++ b/layout/xul/grid/reftests/scrollable-rows-ref.xhtml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XUL Grid Test</title> + <style type="text/css"> + html { background: black; } + html, body { margin: 0; padding: 0; height: 100%; } + div { position: absolute; } + </style> +</head> +<body> + +<div style="background: rgb(0, 102, 153); + top: 0px; height: 200px; left: 0px; width: 200px;" /> +<div style="background: rgb(0, 0, 153); overflow: auto; + top: 0px; height: 200px; left: 200px; width: 100px;"> + <div style="width: 50px; height: 300px" /> +</div> +<div style="background: rgb(0, 255, 0); + top: 200px; height: 100px; left: 100px; width: 100px;" /> + +</body> +</html> diff --git a/layout/xul/grid/reftests/scrollable-rows.xul b/layout/xul/grid/reftests/scrollable-rows.xul new file mode 100644 index 000000000..9fa1f82c5 --- /dev/null +++ b/layout/xul/grid/reftests/scrollable-rows.xul @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + grid { width: 200px; height: 200px; } + rows { overflow: auto; } + ]]></style> + <hbox> + <grid> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/sizing-2d-ref.xul b/layout/xul/grid/reftests/sizing-2d-ref.xul new file mode 100644 index 000000000..a3bc4ca73 --- /dev/null +++ b/layout/xul/grid/reftests/sizing-2d-ref.xul @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" align="start"> + <hbox> + <box style="background:aqua; width: 50px; height: 100px" /> + <box style="background:fuchsia; width: 100px; height: 100px" /> + </hbox> + <hbox> + <box style="background:yellow; width: 50px; height: 75px" /> + <box style="background:blue; width: 100px; height: 75px" /> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/sizing-2d.xul b/layout/xul/grid/reftests/sizing-2d.xul new file mode 100644 index 000000000..7868f9eca --- /dev/null +++ b/layout/xul/grid/reftests/sizing-2d.xul @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" align="start"> + <grid> + <rows> + <row> + <box style="width: 25px; height: 25px" /> + <box /> + </row> + <row> + <box /> + <box style="width: 75px; height: 75px" /> + </row> + </rows> + <columns> + <column> + <box style="background: aqua" /> + <box style="background: yellow; width: 50px; height: 50px" /> + </column> + <column> + <box style="background: fuchsia; width: 100px; height: 100px" /> + <box style="background: blue" /> + </column> + </columns> + </grid> +</window> diff --git a/layout/xul/grid/reftests/z-order-1-ref.xul b/layout/xul/grid/reftests/z-order-1-ref.xul new file mode 100644 index 000000000..198c4e6c6 --- /dev/null +++ b/layout/xul/grid/reftests/z-order-1-ref.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <hbox> + <grid> + <rows> + <row> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 0, 153)" /> + </row> + <row> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 0, 153)" /> + </row> + <row> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 0, 0)" /> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/z-order-1.xul b/layout/xul/grid/reftests/z-order-1.xul new file mode 100644 index 000000000..d38ef9f4a --- /dev/null +++ b/layout/xul/grid/reftests/z-order-1.xul @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <hbox> + <grid> + <columns> + <column style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + <rows> + <row style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/z-order-2-ref.xul b/layout/xul/grid/reftests/z-order-2-ref.xul new file mode 100644 index 000000000..5b0793d6d --- /dev/null +++ b/layout/xul/grid/reftests/z-order-2-ref.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <hbox> + <grid> + <rows> + <row> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </row> + <row> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 102, 153)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </row> + <row> + <hbox style="background: rgb(0, 0, 153)" /> + <hbox style="background: rgb(0, 0, 153)" /> + <hbox style="background: rgb(0, 0, 0)" /> + </row> + </rows> + </grid> + </hbox> +</window> diff --git a/layout/xul/grid/reftests/z-order-2.xul b/layout/xul/grid/reftests/z-order-2.xul new file mode 100644 index 000000000..b2c270d6b --- /dev/null +++ b/layout/xul/grid/reftests/z-order-2.xul @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!DOCTYPE window> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="XUL Grid Test"> + <style xmlns="http://www.w3.org/1999/xhtml"><![CDATA[ + window { background: black; } + hbox { height: 100px; width: 100px; } + ]]></style> + <hbox> + <grid> + <rows> + <row style="background: rgb(0, 255, 0)"> + <hbox /> + <hbox /> + <hbox /> + </row> + <row> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + <hbox style="background: rgb(0, 255, 0)" /> + </row> + <row> + <hbox /> + <hbox /> + <hbox /> + </row> + </rows> + <columns> + <column style="background: rgba(0, 0, 255, 0.6)"> + <hbox /> + <hbox /> + <hbox /> + </column> + <column> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + <hbox style="background: rgba(0, 0, 255, 0.6)" /> + </column> + <column> + <hbox /> + <hbox /> + <hbox /> + </column> + </columns> + </grid> + </hbox> +</window> |