|
36 | 36 | import org.htmlunit.javascript.configuration.JsxFunction; |
37 | 37 | import org.htmlunit.javascript.configuration.JsxGetter; |
38 | 38 | import org.htmlunit.javascript.configuration.JsxSetter; |
| 39 | +import org.htmlunit.javascript.host.dom.DOMException; |
39 | 40 | import org.htmlunit.javascript.host.dom.Node; |
40 | 41 |
|
41 | 42 | /** |
@@ -251,48 +252,75 @@ public void deleteTHead() { |
251 | 252 | } |
252 | 253 |
|
253 | 254 | /** |
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 |
| 255 | + * Inserts a new row at the specified index in the element's row collection. If the index |
| 256 | + * is -1 or there is no index specified, then the row is appended at the end of the |
| 257 | + * element's row collection. |
| 258 | + * @see <a href="http://msdn.microsoft.com/en-us/library/ms536457.aspx">MSDN Documentation</a> |
| 259 | + * @param index specifies where to insert the row in the rows collection. |
| 260 | + * The default value is -1, which appends the new row to the end of the rows collection |
| 261 | + * @return the newly-created row |
257 | 262 | */ |
258 | | - public HtmlUnitScriptable insertRow(final int index) { |
| 263 | + @JsxFunction |
| 264 | + public HtmlUnitScriptable insertRow(final Object index) { |
| 265 | + int rowIndex = -1; |
| 266 | + if (!JavaScriptEngine.isUndefined(index)) { |
| 267 | + rowIndex = (int) JavaScriptEngine.toNumber(index); |
| 268 | + } |
259 | 269 | final HTMLCollection rows = getRows(); |
260 | 270 | 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); |
| 271 | + final int r; |
| 272 | + if (rowIndex == -1 || rowIndex == rowCount) { |
| 273 | + r = Math.max(0, rowCount); |
268 | 274 | } |
269 | 275 | 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 | | - } |
| 276 | + r = rowIndex; |
| 277 | + } |
| 278 | + |
| 279 | + if (r < 0 || r > rowCount) { |
| 280 | + throw JavaScriptEngine.asJavaScriptException( |
| 281 | + getWindow(), |
| 282 | + "Index or size is negative or greater than the allowed amount " |
| 283 | + + "(index: " + rowIndex + ", " + rowCount + " rows)", |
| 284 | + DOMException.INDEX_SIZE_ERR); |
278 | 285 | } |
279 | | - return getScriptableFor(newRow); |
| 286 | + |
| 287 | + return insertRow(r); |
280 | 288 | } |
281 | 289 |
|
282 | 290 | /** |
283 | | - * Handle special case where table is empty. |
| 291 | + * Inserts a new row at the given position. |
284 | 292 | * @param index the index where the row should be inserted (0 <= index <= nbRows) |
285 | 293 | * @return the inserted row |
286 | 294 | */ |
287 | | - @JsxFunction(functionName = "insertRow") |
288 | | - public HtmlUnitScriptable js_insertRow(final int index) { |
| 295 | + public HtmlUnitScriptable insertRow(final int index) { |
289 | 296 | // check if a tbody should be created |
290 | 297 | if (index != 0) { |
291 | 298 | for (final HtmlElement htmlElement : getDomNodeOrDie().getHtmlElementDescendants()) { |
292 | 299 | if (htmlElement instanceof HtmlTableBody |
293 | 300 | || htmlElement instanceof HtmlTableHeader |
294 | 301 | || htmlElement instanceof HtmlTableFooter) { |
295 | | - return insertRow(index); |
| 302 | + |
| 303 | + final HTMLCollection rows = getRows(); |
| 304 | + final int rowCount = rows.getLength(); |
| 305 | + final DomElement newRow = ((HtmlPage) getDomNodeOrDie().getPage()).createElement("tr"); |
| 306 | + if (rowCount == 0) { |
| 307 | + getDomNodeOrDie().appendChild(newRow); |
| 308 | + } |
| 309 | + else if (index == rowCount) { |
| 310 | + final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index - 1)); |
| 311 | + row.getDomNodeOrDie().getParentNode().appendChild(newRow); |
| 312 | + } |
| 313 | + else { |
| 314 | + final HtmlUnitScriptable row = (HtmlUnitScriptable) rows.item(Integer.valueOf(index)); |
| 315 | + // if at the end, then in the same "sub-container" as the last existing row |
| 316 | + if (index > rowCount - 1) { |
| 317 | + row.getDomNodeOrDie().getParentNode().appendChild(newRow); |
| 318 | + } |
| 319 | + else { |
| 320 | + row.getDomNodeOrDie().insertBefore(newRow); |
| 321 | + } |
| 322 | + } |
| 323 | + return getScriptableFor(newRow); |
296 | 324 | } |
297 | 325 | } |
298 | 326 | } |
|
0 commit comments