All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nu.validator.checker.table.Cell Maven / Gradle / Ivy

Go to download

An HTML-checking library (used by https://html5.validator.nu and the HTML5 facet of the W3C Validator)

There is a newer version: 20.7.2
Show newest version
/*
 * Copyright (c) 2006 Henri Sivonen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 */

package nu.validator.checker.table;

import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * A table cell for table integrity checking.
 * 
 * @version $Id$
 * @author hsivonen
 */
final class Cell implements Locator {

    // See
    // http://mxr-test.landfill.bugzilla.org/mxr-test/seamonkey/source/content/html/content/src/nsHTMLTableCellElement.cpp
    // for the source of these magic numbers.

    /**
     * Magic number from Gecko.
     */
    private static final int MAX_COLSPAN = 1000;

    /**
     * Magic number from Gecko.
     */
    private static final int MAX_ROWSPAN = 8190;

    /**
     * The column in which this cell starts. (Zero before positioning.)
     */
    private int left;

    /**
     * The first row in the row group onto which this cell does not span.
     * (rowspan before positioning)
     * 
     * 

However, Integen.MAX_VALUE is a magic value that means * rowspan=0. */ private int bottom; /** * The first column into which this cell does not span. * (colspan before positioning.) */ private int right; /** * The value of the headers attribute split on white space. */ private final String[] headers; /** * Whether this is a th cell. */ private final boolean header; /** * Source column. */ private final int columnNumber; /** * Source line. */ private final int lineNumber; /** * Source public id. */ private final String publicId; /** * Source system id. */ private final String systemId; /** * The error handler. */ private final ErrorHandler errorHandler; Cell(int colspan, int rowspan, String[] headers, boolean header, Locator locator, ErrorHandler errorHandler) throws SAXException { super(); this.errorHandler = errorHandler; if (locator == null) { this.columnNumber = -1; this.lineNumber = -1; this.publicId = null; this.systemId = null; } else { this.columnNumber = locator.getColumnNumber(); this.lineNumber = locator.getLineNumber(); this.publicId = locator.getPublicId(); this.systemId = locator.getSystemId(); } if (rowspan > MAX_ROWSPAN) { warn("A rowspan attribute has the value " + rowspan + ", which exceeds the magic Gecko limit of " + MAX_ROWSPAN + "."); } if (colspan > MAX_COLSPAN) { warn("A colspan attribute has the value " + colspan + ", which exceeds the magic browser limit of " + MAX_COLSPAN + "."); } if (rowspan == Integer.MAX_VALUE) { throw new SAXException( "Implementation limit reached. Table row counter overflowed."); } this.left = 0; this.right = colspan; this.bottom = (rowspan == 0 ? Integer.MAX_VALUE : rowspan); this.headers = headers; this.header = header; } /** * Returns the headers. * * @return the headers */ public String[] getHeadings() { return headers; } /** * Returns the header. * * @return the header */ public boolean isHeader() { return header; } public void warn(String message) throws SAXException { if (errorHandler != null) { errorHandler.warning(new SAXParseException(message, publicId, systemId, lineNumber, columnNumber)); } } public void err(String message) throws SAXException { if (errorHandler != null) { errorHandler.error(new SAXParseException(message, publicId, systemId, lineNumber, columnNumber)); } } /** * Emit errors if this cell and the argument overlap horizontally. * @param laterCell another cell * @throws SAXException if the ErrorHandler throws */ public void errOnHorizontalOverlap(Cell laterCell) throws SAXException { if (!((laterCell.right <= left) || (right <= laterCell.left))) { this.err("Table cell is overlapped by later table cell."); laterCell.err("Table cell overlaps an earlier table cell."); } } public void setPosition(int top, int left) throws SAXException { this.left = left; this.right += left; if (this.right < 1) { throw new SAXException( "Implementation limit reached. Table column counter overflowed."); } if (this.bottom != Integer.MAX_VALUE) { this.bottom += top; if (this.bottom < 1) { throw new SAXException( "Implementation limit reached. Table row counter overflowed."); } } } public boolean shouldBeCulled(int row) { return row >= bottom; } public int freeSlot(int potentialSlot) { if (potentialSlot < left || potentialSlot >= right) { return potentialSlot; } else { return right; } } /** * Returns the bottom. * * @return the bottom */ public int getBottom() { return bottom; } /** * Returns the left. * * @return the left */ int getLeft() { return left; } /** * Returns the right. * * @return the right */ int getRight() { return right; } public void errIfNotRowspanZero(String rowGroupType) throws SAXException { if (this.bottom != Integer.MAX_VALUE) { err("Table cell spans past the end of its " + (rowGroupType == null ? "implicit row group" : "row group established by a \u201C" + rowGroupType + "\u201D element") + "; clipped to the end of the row group."); } } /** * Returns the columnNumber. * * @return the columnNumber */ @Override public int getColumnNumber() { return columnNumber; } /** * Returns the lineNumber. * * @return the lineNumber */ @Override public int getLineNumber() { return lineNumber; } /** * Returns the publicId. * * @return the publicId */ @Override public String getPublicId() { return publicId; } /** * Returns the systemId. * * @return the systemId */ @Override public String getSystemId() { return systemId; } public String elementName() { return header ? "th" : "td"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy