Skip to content

Commit ba364af

Browse files
committed
remove RowContainer and fix class tree
1 parent 58747fe commit ba364af

File tree

5 files changed

+252
-213
lines changed

5 files changed

+252
-213
lines changed

src/main/java/org/htmlunit/javascript/configuration/JavaScriptConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@
319319
import org.htmlunit.javascript.host.html.HTMLUListElement;
320320
import org.htmlunit.javascript.host.html.HTMLUnknownElement;
321321
import org.htmlunit.javascript.host.html.HTMLVideoElement;
322-
import org.htmlunit.javascript.host.html.RowContainer;
323322
import org.htmlunit.javascript.host.html.ValidityState;
324323
import org.htmlunit.javascript.host.idb.IDBCursor;
325324
import org.htmlunit.javascript.host.idb.IDBCursorWithValue;
@@ -655,7 +654,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
655654
HTMLSelectElement.class, HTMLSlotElement.class, HTMLSourceElement.class, HTMLSpanElement.class,
656655
HTMLStyleElement.class, HTMLTableCaptionElement.class, HTMLTableComponent.class,
657656
HTMLTemplateElement.class, HTMLTextAreaElement.class, HTMLTimeElement.class, HTMLTitleElement.class,
658-
HTMLTrackElement.class, HTMLUnknownElement.class, RowContainer.class, SVGAnimationElement.class,
657+
HTMLTrackElement.class, HTMLUnknownElement.class, SVGAnimationElement.class,
659658
SVGClipPathElement.class, SVGComponentTransferFunctionElement.class, SVGDescElement.class,
660659
SVGFEBlendElement.class, SVGFEColorMatrixElement.class, SVGFEComponentTransferElement.class,
661660
SVGFECompositeElement.class, SVGFEConvolveMatrixElement.class, SVGFEDiffuseLightingElement.class,

src/main/java/org/htmlunit/javascript/host/html/HTMLTableElement.java

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
import java.io.Serializable;
1818
import java.util.ArrayList;
1919
import java.util.List;
20+
import java.util.function.Predicate;
2021
import java.util.function.Supplier;
2122

23+
import org.htmlunit.html.DomElement;
2224
import org.htmlunit.html.DomNode;
2325
import org.htmlunit.html.HtmlElement;
26+
import org.htmlunit.html.HtmlPage;
2427
import org.htmlunit.html.HtmlTable;
2528
import org.htmlunit.html.HtmlTableBody;
2629
import org.htmlunit.html.HtmlTableFooter;
@@ -48,7 +51,7 @@
4851
* @author Frank Danek
4952
*/
5053
@JsxClass(domClass = HtmlTable.class)
51-
public class HTMLTableElement extends RowContainer {
54+
public class HTMLTableElement extends HTMLElement {
5255

5356
/**
5457
* JavaScript constructor.
@@ -248,36 +251,54 @@ public void deleteTHead() {
248251
}
249252

250253
/**
251-
* Indicates if the row belongs to this container.
252-
* @param row the row to test
253-
* @return {@code true} if it belongs to this container
254+
* Inserts a new row at the given position.
255+
* @param index the index where the row should be inserted (0 <= index <= nbRows)
256+
* @return the inserted row
254257
*/
255-
@Override
256-
protected boolean isContainedRow(final HtmlTableRow row) {
257-
final DomNode parent = row.getParentNode(); // the tbody, thead or tfoo
258-
return parent != null
259-
&& parent.getParentNode() == getDomNodeOrDie();
258+
public HtmlUnitScriptable insertRow(final int index) {
259+
final HTMLCollection rows = getRows();
260+
final int rowCount = rows.getLength();
261+
final DomElement newRow = ((HtmlPage) getDomNodeOrDie().getPage()).createElement("tr");
262+
if (rowCount == 0) {
263+
getDomNodeOrDie().appendChild(newRow);
264+
}
265+
else if (index == rowCount) {
266+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index - 1));
267+
row.getDomNodeOrDie().getParentNode().appendChild(newRow);
268+
}
269+
else {
270+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index));
271+
// if at the end, then in the same "sub-container" as the last existing row
272+
if (index > rowCount - 1) {
273+
row.getDomNodeOrDie().getParentNode().appendChild(newRow);
274+
}
275+
else {
276+
row.getDomNodeOrDie().insertBefore(newRow);
277+
}
278+
}
279+
return getScriptableFor(newRow);
260280
}
261281

262282
/**
263283
* Handle special case where table is empty.
264-
* {@inheritDoc}
284+
* @param index the index where the row should be inserted (0 <= index <= nbRows)
285+
* @return the inserted row
265286
*/
266-
@Override
267-
public HtmlUnitScriptable insertRow(final int index) {
287+
@JsxFunction(functionName = "insertRow")
288+
public HtmlUnitScriptable js_insertRow(final int index) {
268289
// check if a tbody should be created
269290
if (index != 0) {
270291
for (final HtmlElement htmlElement : getDomNodeOrDie().getHtmlElementDescendants()) {
271292
if (htmlElement instanceof HtmlTableBody
272293
|| htmlElement instanceof HtmlTableHeader
273294
|| htmlElement instanceof HtmlTableFooter) {
274-
return super.insertRow(index);
295+
return insertRow(index);
275296
}
276297
}
277298
}
278299

279300
final HtmlElement tBody = getDomNodeOrDie().appendChildIfNoneExists("tbody");
280-
return ((RowContainer) getScriptableFor(tBody)).insertRow(0);
301+
return ((HTMLTableSectionElement) getScriptableFor(tBody)).insertRow(0);
281302
}
282303

283304
/**
@@ -428,4 +449,64 @@ public void setRules(final String rules) {
428449
setAttribute("rules", rules);
429450
}
430451

452+
/**
453+
* Returns the value of the {@code align} property.
454+
* @return the value of the {@code align} property
455+
*/
456+
@JsxGetter
457+
public String getAlign() {
458+
return getAlign(true);
459+
}
460+
461+
/**
462+
* Sets the value of the {@code align} property.
463+
* @param align the value of the {@code align} property
464+
*/
465+
@JsxSetter
466+
public void setAlign(final String align) {
467+
setAlign(align, false);
468+
}
469+
470+
/**
471+
* Deletes the row at the specified index.
472+
* @see <a href="http://msdn.microsoft.com/en-us/library/ms536408.aspx">MSDN Documentation</a>
473+
* @param rowIndex the zero-based index of the row to delete
474+
*/
475+
@JsxFunction
476+
public void deleteRow(int rowIndex) {
477+
final HTMLCollection rows = getRows();
478+
final int rowCount = rows.getLength();
479+
if (rowIndex == -1) {
480+
rowIndex = rowCount - 1;
481+
}
482+
final boolean rowIndexValid = rowIndex >= 0 && rowIndex < rowCount;
483+
if (rowIndexValid) {
484+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(rowIndex));
485+
row.getDomNodeOrDie().remove();
486+
}
487+
}
488+
489+
/**
490+
* Returns the rows in the element.
491+
* @return the rows in the element
492+
*/
493+
@JsxGetter
494+
public HTMLCollection getRows() {
495+
final HTMLCollection rows = new HTMLCollection(getDomNodeOrDie(), false);
496+
rows.setIsMatchingPredicate(
497+
(Predicate<DomNode> & Serializable)
498+
node -> node instanceof HtmlTableRow && isContainedRow((HtmlTableRow) node));
499+
return rows;
500+
}
501+
502+
/**
503+
* Indicates if the row belongs to this container.
504+
* @param row the row to test
505+
* @return {@code true} if it belongs to this container
506+
*/
507+
private boolean isContainedRow(final HtmlTableRow row) {
508+
final DomNode parent = row.getParentNode(); // the tbody, thead or tfoo
509+
return parent != null
510+
&& parent.getParentNode() == getDomNodeOrDie();
511+
}
431512
}

src/main/java/org/htmlunit/javascript/host/html/HTMLTableSectionElement.java

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,24 @@
1414
*/
1515
package org.htmlunit.javascript.host.html;
1616

17+
import java.io.Serializable;
18+
import java.util.function.Predicate;
19+
20+
import org.htmlunit.html.DomElement;
21+
import org.htmlunit.html.DomNode;
22+
import org.htmlunit.html.HtmlPage;
1723
import org.htmlunit.html.HtmlTableBody;
1824
import org.htmlunit.html.HtmlTableFooter;
1925
import org.htmlunit.html.HtmlTableHeader;
26+
import org.htmlunit.html.HtmlTableRow;
27+
import org.htmlunit.javascript.HtmlUnitScriptable;
28+
import org.htmlunit.javascript.JavaScriptEngine;
2029
import org.htmlunit.javascript.configuration.JsxClass;
2130
import org.htmlunit.javascript.configuration.JsxConstructor;
31+
import org.htmlunit.javascript.configuration.JsxFunction;
2232
import org.htmlunit.javascript.configuration.JsxGetter;
2333
import org.htmlunit.javascript.configuration.JsxSetter;
34+
import org.htmlunit.javascript.host.dom.DOMException;
2435

2536
/**
2637
* A JavaScript object representing "HTMLTableSectionElement", it is used by
@@ -33,7 +44,7 @@
3344
@JsxClass(domClass = HtmlTableBody.class)
3445
@JsxClass(domClass = HtmlTableHeader.class)
3546
@JsxClass(domClass = HtmlTableFooter.class)
36-
public class HTMLTableSectionElement extends RowContainer {
47+
public class HTMLTableSectionElement extends HTMLElement {
3748

3849
/** The default value of the "vAlign" property. */
3950
private static final String VALIGN_DEFAULT_VALUE = "top";
@@ -112,4 +123,128 @@ public String getChOff() {
112123
public void setChOff(final String chOff) {
113124
super.setChOff(chOff);
114125
}
126+
127+
/**
128+
* Returns the rows in the element.
129+
* @return the rows in the element
130+
*/
131+
@JsxGetter
132+
public HTMLCollection getRows() {
133+
final HTMLCollection rows = new HTMLCollection(getDomNodeOrDie(), false);
134+
rows.setIsMatchingPredicate(
135+
(Predicate<DomNode> & Serializable)
136+
node -> node instanceof HtmlTableRow && isContainedRow((HtmlTableRow) node));
137+
return rows;
138+
}
139+
140+
/**
141+
* Indicates if the row belongs to this container.
142+
* @param row the row to test
143+
* @return {@code true} if it belongs to this container
144+
*/
145+
protected boolean isContainedRow(final HtmlTableRow row) {
146+
return row.getParentNode() == getDomNodeOrDie();
147+
}
148+
149+
/**
150+
* Deletes the row at the specified index.
151+
* @see <a href="http://msdn.microsoft.com/en-us/library/ms536408.aspx">MSDN Documentation</a>
152+
* @param rowIndex the zero-based index of the row to delete
153+
*/
154+
@JsxFunction
155+
public void deleteRow(int rowIndex) {
156+
final HTMLCollection rows = getRows();
157+
final int rowCount = rows.getLength();
158+
if (rowIndex == -1) {
159+
rowIndex = rowCount - 1;
160+
}
161+
final boolean rowIndexValid = rowIndex >= 0 && rowIndex < rowCount;
162+
if (rowIndexValid) {
163+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(rowIndex));
164+
row.getDomNodeOrDie().remove();
165+
}
166+
}
167+
168+
/**
169+
* Inserts a new row at the specified index in the element's row collection. If the index
170+
* is -1 or there is no index specified, then the row is appended at the end of the
171+
* element's row collection.
172+
* @see <a href="http://msdn.microsoft.com/en-us/library/ms536457.aspx">MSDN Documentation</a>
173+
* @param index specifies where to insert the row in the rows collection.
174+
* The default value is -1, which appends the new row to the end of the rows collection
175+
* @return the newly-created row
176+
*/
177+
@JsxFunction
178+
public HtmlUnitScriptable insertRow(final Object index) {
179+
int rowIndex = -1;
180+
if (!JavaScriptEngine.isUndefined(index)) {
181+
rowIndex = (int) JavaScriptEngine.toNumber(index);
182+
}
183+
final HTMLCollection rows = getRows();
184+
final int rowCount = rows.getLength();
185+
final int r;
186+
if (rowIndex == -1 || rowIndex == rowCount) {
187+
r = Math.max(0, rowCount);
188+
}
189+
else {
190+
r = rowIndex;
191+
}
192+
193+
if (r < 0 || r > rowCount) {
194+
throw JavaScriptEngine.asJavaScriptException(
195+
getWindow(),
196+
"Index or size is negative or greater than the allowed amount "
197+
+ "(index: " + rowIndex + ", " + rowCount + " rows)",
198+
DOMException.INDEX_SIZE_ERR);
199+
}
200+
201+
return insertRow(r);
202+
}
203+
204+
/**
205+
* Inserts a new row at the given position.
206+
* @param index the index where the row should be inserted (0 &lt;= index &lt;= nbRows)
207+
* @return the inserted row
208+
*/
209+
public HtmlUnitScriptable insertRow(final int index) {
210+
final HTMLCollection rows = getRows();
211+
final int rowCount = rows.getLength();
212+
final DomElement newRow = ((HtmlPage) getDomNodeOrDie().getPage()).createElement("tr");
213+
if (rowCount == 0) {
214+
getDomNodeOrDie().appendChild(newRow);
215+
}
216+
else if (index == rowCount) {
217+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index - 1));
218+
row.getDomNodeOrDie().getParentNode().appendChild(newRow);
219+
}
220+
else {
221+
final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index));
222+
// if at the end, then in the same "sub-container" as the last existing row
223+
if (index > rowCount - 1) {
224+
row.getDomNodeOrDie().getParentNode().appendChild(newRow);
225+
}
226+
else {
227+
row.getDomNodeOrDie().insertBefore(newRow);
228+
}
229+
}
230+
return getScriptableFor(newRow);
231+
}
232+
233+
/**
234+
* Returns the value of the {@code align} property.
235+
* @return the value of the {@code align} property
236+
*/
237+
@JsxGetter
238+
public String getAlign() {
239+
return getAlign(true);
240+
}
241+
242+
/**
243+
* Sets the value of the {@code align} property.
244+
* @param align the value of the {@code align} property
245+
*/
246+
@JsxSetter
247+
public void setAlign(final String align) {
248+
setAlign(align, false);
249+
}
115250
}

0 commit comments

Comments
 (0)