| /******************************************************************************* |
| * Copyright (c) 2004, 2011 IBM Corporation and Others |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.actf.examples.adesigner.eval.html.internal; |
| |
| import java.lang.reflect.Method; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Stack; |
| import java.util.StringTokenizer; |
| import java.util.TreeSet; |
| import java.util.Vector; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.actf.model.dom.dombycom.IDocumentEx; |
| import org.eclipse.actf.model.dom.dombycom.IStyleSheet; |
| import org.eclipse.actf.model.dom.dombycom.IStyleSheets; |
| import org.eclipse.actf.model.dom.html.DocumentTypeUtil; |
| import org.eclipse.actf.visualization.engines.blind.TextCheckResult; |
| import org.eclipse.actf.visualization.engines.blind.TextChecker; |
| import org.eclipse.actf.visualization.eval.html.HtmlEvalUtil; |
| import org.eclipse.actf.visualization.eval.html.HtmlTagUtil; |
| import org.eclipse.actf.visualization.eval.problem.HighlightTargetId; |
| import org.eclipse.actf.visualization.eval.problem.HighlightTargetNodeInfo; |
| import org.eclipse.actf.visualization.eval.problem.IProblemItem; |
| import org.eclipse.actf.visualization.eval.problem.ProblemItemImpl; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentType; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.html.HTMLImageElement; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| @SuppressWarnings("unused") |
| public class CheckEngine extends HtmlTagUtil { |
| |
| // use org.w3c.dom.traversal, XPath |
| |
| private static final String SPACE_STR = " "; //$NON-NLS-1$ |
| |
| private static final String WINDOW_OPEN = "window.open"; //$NON-NLS-1$ |
| |
| public static final int ITEM_COUNT = 1000; |
| |
| private static final int QUOTATION_SHORT_NUM = 10; |
| |
| private static final int TABLE_CELL_ABBR_CHARS = 30; |
| |
| private static final int TABLE_CELL_ABBR_WORDS = 10; |
| |
| private static final Pattern COMMENT = Pattern.compile("/\\*.*?\\*/", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern FIXSIZE_PATTERN = Pattern |
| .compile( |
| ".*\\{[^\\}]*font-size(\\p{Space})*:[^;]*(mm|cm|in|pt|pc|px).*\\}.*", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern FIXSIZE_PATTERN_ATTR = Pattern.compile( |
| "font-size(\\p{Space})*:[^;]*(mm|cm|in|pt|pc|px)", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern BLINK_PATTERN = Pattern.compile( |
| ".*\\{[^\\}]*text-decoration(\\p{Space})*:[^;]*blink.*\\}.*", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern BLINK_PATTERN_ATTR = Pattern.compile( |
| "text-decoration(\\p{Space})*:[^;]*blink.*", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern BEFORE_PATTERN = Pattern.compile( |
| ".*:before(\\p{Space})*\\{[^\\}]*content(\\p{Space})*:.*\\}.*", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern AFTER_PATTERN = Pattern.compile( |
| ".*:after(\\p{Space})*\\{[^\\}]*content(\\p{Space})*:.*\\}.*", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| // not strict check |
| private static final String CSS_COLORS = "(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText|inherit|currentColor|rgb[a]?\\(.*\\)|hsl[a]?\\(.*\\)|#[a-f0-9]{3}|#[a-f0-9]{6})"; |
| |
| // TODO media / import / comment <!-- --> |
| private static final Pattern STYLEITEM = Pattern.compile(".*?\\{.*?\\}", |
| Pattern.DOTALL); |
| private static final Pattern COLOR = Pattern.compile( |
| "\\{(.*[^-]+)?color(\\p{Space})*:.*\\}", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| private static final Pattern BGCOLOR = Pattern.compile( |
| "\\{.*background-color(\\p{Space})*:.*\\}", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| private static final Pattern BGCOLOR2 = Pattern.compile( |
| "\\{.*background(\\p{Space})*:.*" + CSS_COLORS + ".*\\}", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| |
| private static final Pattern COLOR_ATTR = Pattern.compile( |
| "(((.*[^\\-]+)color)|(\\p{Space})*color)(\\p{Space})*:.*", |
| Pattern.DOTALL | Pattern.CASE_INSENSITIVE); |
| private static final Pattern BGCOLOR_ATTR = Pattern.compile( |
| ".*background-color(\\p{Space})*:.*", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| private static final Pattern BGCOLOR2_ATTR = Pattern.compile( |
| ".*background(\\p{Space})*:.*" + CSS_COLORS + ".*", Pattern.DOTALL |
| | Pattern.CASE_INSENSITIVE); |
| |
| @SuppressWarnings("nls") |
| private static final String[] ASCII_ART_CHAR = { "\u2227", "\uff3f", |
| "\uffe3", "\uff20", "\uff0f", "\uff3c", "\u03b3", "\u03a6", |
| "\u2229", "\u222a", "\u03b9", "\uff2f", "\u2282", "\uff9f", |
| "\u0414", "\u03c3", "\uff65", "\u2200", "\u2211", "i", "o", "0", |
| "_", "\uff3f", "\uffe3", "\u00b4", "\uff40", "\u30fe" }; |
| |
| private static Set<String> artCharSet; |
| |
| static { |
| artCharSet = new HashSet<String>(); |
| for (int i = 0; i < ASCII_ART_CHAR.length; i++) { |
| artCharSet.add(ASCII_ART_CHAR[i]); |
| } |
| } |
| |
| private static Method[] checkMethods; |
| private static Method[] mobileCheckMethods; |
| |
| static { |
| Method[] tmpM = CheckEngine.class.getDeclaredMethods(); |
| checkMethods = new Method[1000];// TODO |
| mobileCheckMethods = new Method[1000];// TODO |
| for (Method m : tmpM) { |
| String name = m.getName(); |
| if (name.startsWith("item_")) { //$NON-NLS-1$ |
| try { |
| int itemNum = Integer.parseInt(name.substring(5)); |
| checkMethods[itemNum] = m; |
| } catch (Exception e) { |
| } |
| } else if (name.startsWith("mobile_")) { //$NON-NLS-1$ |
| try { |
| int itemNum = Integer.parseInt(name.substring(7)); |
| mobileCheckMethods[itemNum] = m; |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| |
| private static final String[] AUDIO_FILE_EXTENSION = { |
| "mp3", "mid", "mrm", "mrl", "vqf", "wav" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ |
| |
| private static final String[] MULTIMEDIA_FILE_EXTENSION = { |
| "avi", "ram", "rm", "asf", "wm", "wmx", "wmv", "asx", "mpeg", "mpg" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ |
| |
| /** |
| * debug flag for developers! |
| */ |
| private static final boolean DEBUG = false; |
| |
| private Set<String> blockEleSet = HtmlTagUtil.getBlockElementSet(); |
| |
| private Document target; |
| |
| private Document resultDoc; |
| |
| private URL baseUrl; |
| |
| private Map<Node, Integer> document2IdMap; |
| |
| // private Vector html2ViewMapData; |
| |
| private boolean isDBCS; |
| |
| private Vector<IProblemItem> result; |
| |
| private boolean[] items; |
| |
| private int validate_str_len; |
| |
| private int valid_total_text_len; |
| |
| private boolean hasAwithHref = false; |
| |
| private Element[] aWithHref_elements; |
| |
| private String[] aWithHref_hrefs; |
| |
| private String[] aWithHref_strings; |
| |
| private HTMLImageElement[] img_elements; |
| |
| private Element[] table_elements; |
| |
| private Element[] body_elements; |
| |
| private Element[] frame_elements; |
| |
| private Element[] iframe_elements; |
| |
| private Element[] object_elements; |
| |
| private Element[] embed_elements; |
| |
| private Element[] parent_table_elements; |
| |
| private Element[] bottom_data_tables; |
| |
| private Element[] bottom_1row1col_tables; |
| |
| private Element[] bottom_notdata_tables; |
| |
| private Element[] headings; |
| |
| private double invalidLinkRatio; |
| |
| private boolean isXHTML = false; |
| |
| private List<Element> labelList; |
| private List<Element> formList; |
| private Vector<Node> formVwithText; |
| private List<Element> layoutTableList; |
| private List<Element> dataTableList; |
| private TextChecker checker; |
| |
| private List<Element> elementsWithStyleList; |
| private Map<Element, String> styleElementMap = new HashMap<Element, String>(); |
| |
| private int liveObject = 0; |
| private int liveEmbed = 0; |
| |
| // private int invisibleElementCount = 0; |
| // private String[] invisibleLinkStrings = new String[0]; |
| |
| private HtmlEvalUtil edu; |
| |
| private String docTypeS; |
| |
| private Map<IStyleSheet, String> styleSheetsMap = new HashMap<IStyleSheet, String>(); |
| |
| /** |
| * |
| */ |
| public CheckEngine(HtmlEvalUtil edu, boolean[] checkItems) { |
| this.edu = edu; |
| this.target = edu.getTarget(); |
| this.resultDoc = edu.getResult(); |
| Document tmpD = edu.getLiveDom(); |
| if (tmpD instanceof IDocumentEx) { |
| IStyleSheets styleSheets = ((IDocumentEx) tmpD).getStyleSheets(); |
| prepStyleSheets(styleSheets); |
| liveObject = tmpD.getElementsByTagName("object").getLength(); |
| liveEmbed = tmpD.getElementsByTagName("embed").getLength(); |
| } |
| |
| baseUrl = edu.getBaseUrl(); |
| |
| invalidLinkRatio = 0; |
| |
| this.items = checkItems; |
| |
| this.document2IdMap = edu.getDocument2IdMap(); |
| // this.html2ViewMapData = edu.getHtml2ViewMapData(); |
| |
| this.isDBCS = edu.isDBCS(); |
| if (isDBCS) { |
| validate_str_len = 20; |
| valid_total_text_len = 50; |
| } else { |
| validate_str_len = 50; |
| valid_total_text_len = 100; |
| } |
| result = new Vector<IProblemItem>(); |
| |
| hasAwithHref = edu.isHasAwithHref(); |
| |
| aWithHref_elements = edu.getAWithHref_elements(); |
| aWithHref_hrefs = edu.getAWithHref_hrefs(); |
| aWithHref_strings = edu.getAWithHref_strings(); |
| |
| img_elements = edu.getImg_elements(); |
| |
| table_elements = edu.getTable_elements(); |
| bottom_data_tables = edu.getBottom_data_tables(); |
| bottom_1row1col_tables = edu.getBottom_1row1col_tables(); |
| bottom_notdata_tables = edu.getBottom_notdata_tables(); |
| parent_table_elements = edu.getParent_table_elements(); |
| // for new JIS |
| layoutTableList = new ArrayList<Element>(); |
| layoutTableList.addAll(Arrays.asList(parent_table_elements)); |
| layoutTableList.addAll(Arrays.asList(bottom_1row1col_tables)); |
| layoutTableList.addAll(Arrays.asList(bottom_notdata_tables)); |
| dataTableList = new ArrayList<Element>(); |
| dataTableList.addAll(Arrays.asList(bottom_data_tables)); |
| assert table_elements.length == layoutTableList.size() |
| + dataTableList.size(); |
| |
| body_elements = edu.getBody_elements(); |
| frame_elements = edu.getFrame_elements(); |
| iframe_elements = edu.getIframe_elements(); |
| object_elements = edu.getObject_elements(); |
| embed_elements = edu.getEmbed_elements(); |
| |
| formList = edu.getElementsList(target, "form"); //$NON-NLS-1$ |
| |
| elementsWithStyleList = edu.getElementsWithStyle(); |
| List<Element> styleElementList = edu.getStyleElements(); |
| for (Element e : styleElementList) { |
| if (e.hasChildNodes()) { |
| Node n = e.getFirstChild(); |
| String style = n.getNodeValue(); |
| |
| String[] results = COMMENT.split(style); |
| String resultS = ""; |
| for (String tmpS : results) { |
| resultS = resultS + tmpS; |
| } |
| styleElementMap.put(e, resultS); |
| } |
| } |
| |
| headings = edu.getHeadings(); |
| |
| DocumentType docType = target.getDoctype(); |
| docTypeS = DocumentTypeUtil.getOriginalID(docType); |
| if (docTypeS.indexOf("XHTML") > 0) { |
| isXHTML = true; |
| } |
| checker = TextChecker.getInstance(); |
| |
| } |
| |
| private void prepStyleSheets(IStyleSheets styleSheets) { |
| if (styleSheets != null) { |
| for (int i = 0; i < styleSheets.getLength(); i++) { |
| IStyleSheet ss = styleSheets.item(i); |
| |
| // comments are already removed |
| // String[] results = COMMENT.split(ss.getCssText()); |
| // String resultS = ""; |
| // for (String tmpS : results) { |
| // resultS = resultS + tmpS; |
| // } |
| // styleSheetsMap.put(ss, resultS); |
| |
| styleSheetsMap.put(ss, ss.getCssText()); |
| prepStyleSheets(ss.getImports()); |
| } |
| } |
| } |
| |
| /** |
| * Checking main routine. This method invokes each item_*() methods by Java |
| * reflection, based on user's guidelines preference. |
| * |
| * @return |
| */ |
| public Vector<IProblemItem> check() { |
| // show list of techniques used in all problem items |
| /* |
| * if (DEBUG) { if (false) { for (ITechniquesItem tech : |
| * GuidelineHolder.getInstance() .getTechniquesItemSet()) { |
| * System.out.println(tech.getId()); } } |
| * |
| * Set<ITechniquesItem> techSet = GuidelineHolder.getInstance() |
| * .getTechniquesItemSet(); Map<String, Set<IProblemItem>> techProbMap = |
| * GuidelineHolder .getInstance().getTechProbMap(); |
| * |
| * for (ITechniquesItem tech : techSet) { for (IProblemItem pitem : |
| * techProbMap.get(tech.getId())) { System.out.println(tech.getId() + |
| * "\t" + pitem.getId() + "\t" + pitem.getSeverityStr() + "\t" + |
| * pitem.getDescription()); } } |
| * System.out.println(GuidelineHolder.getInstance()); } |
| */ |
| |
| // not required to use for WCAG 2.0 |
| // checkDomDifference(); |
| |
| validateHtml(); |
| |
| Object[] tmpO = null; |
| for (int i = 0; i < items.length; i++) { |
| if (items[i] && null != checkMethods[i]) { |
| try { |
| checkMethods[i].invoke(this, tmpO); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| // always |
| if (items.length < 90 || !items[89]) { |
| item_89(); |
| } |
| |
| formCheck(); |
| styleCheck(); |
| mediaCheck(); |
| always(); |
| |
| for (int i = 0; i < mobileCheckMethods.length; i++) { |
| if (null != mobileCheckMethods[i]) { |
| try { |
| mobileCheckMethods[i].invoke(this, tmpO); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| edu.getPageData().setInvalidLinkRatio(invalidLinkRatio); |
| |
| return (result); |
| } |
| |
| private IProblemItem addCheckerProblem(String strId) { |
| IProblemItem tmpCP = new ProblemItemImpl(strId); |
| result.add(tmpCP); |
| return (tmpCP); |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, String targetStr) { |
| IProblemItem tmpCP = new ProblemItemImpl(strId); |
| tmpCP.setTargetString(targetStr); |
| result.add(tmpCP); |
| return (tmpCP); |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, Element target) { |
| return addCheckerProblem(strId, "", target); //$NON-NLS-1$ |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, String targetStr, |
| Element target) { |
| IProblemItem tmpCP = new ProblemItemImpl(strId, target); |
| tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo(target)); |
| tmpCP.setTargetString(targetStr); |
| result.add(tmpCP); |
| |
| return (tmpCP); |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, Element startTarget, |
| Element endTarget) { |
| IProblemItem tmpCP = new ProblemItemImpl(strId, startTarget); |
| tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo( |
| startTarget, endTarget)); |
| result.add(tmpCP); |
| return (tmpCP); |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, String targetStr, |
| Vector<Node> targetV) { |
| IProblemItem tmpCP = new ProblemItemImpl(strId); |
| tmpCP.setTargetString(targetStr); |
| tmpCP.setHighlightTargetNodeInfo(new HighlightTargetNodeInfo(targetV)); |
| result.add(tmpCP); |
| return tmpCP; |
| } |
| |
| private IProblemItem addCheckerProblem(String strId, String targetStr, |
| NodeList targetNL) { |
| Vector<Node> targetV = new Vector<Node>(); |
| for (int i = 0; i < targetNL.getLength(); i++) { |
| targetV.add(targetNL.item(i)); |
| } |
| return addCheckerProblem(strId, targetStr, targetV); |
| } |
| |
| private void item_0() { |
| for (Element applet : edu.getAppletElements()) { |
| boolean bHasAlt = false; |
| boolean bHasText = false; |
| |
| // justify if has alt attribute |
| |
| String strAlt = applet.getAttribute(ATTR_ALT); |
| if (strAlt.length() > 0) { |
| bHasAlt = true; |
| } |
| |
| String desText = getTextAltDescendant(applet); |
| bHasText = (desText.length() > 0); |
| |
| if (!bHasAlt) |
| addCheckerProblem("C_0.0", applet); //$NON-NLS-1$ |
| if (!bHasText) { |
| addCheckerProblem("C_0.1", applet); //$NON-NLS-1$ |
| |
| // alternative link alert |
| // check descendant text or image |
| // addCheckerProblem("C_0.1", el); |
| } |
| } |
| } |
| |
| private void item_1() { |
| |
| for (int i = 0; i < object_elements.length; i++) { |
| Element el = object_elements[i]; |
| |
| /* |
| * boolean bReported = false; |
| * |
| * boolean bHasTextImg = hasTextDescendant(el); if (!bHasTextImg) { |
| * NodeList imgNl = el.getElementsByTagName("img"); //$NON-NLS-1$ if |
| * (imgNl.getLength() > 0) { // need alt description check |
| * bHasTextImg = true; } } if (!bHasTextImg) { // text or img check |
| * addCheckerProblem("C_1.1", el); //$NON-NLS-1$ bReported = true; } |
| * |
| * if (!bReported) { // alert // check links inside an OBJECT |
| * element, or a description link. // addCheckerProblem("C_1.2", |
| * el); } |
| */ |
| |
| if (getTextAltDescendant(el).trim().length() == 0) { |
| addCheckerProblem("C_1.1", el); //$NON-NLS-1$ |
| } |
| } |
| |
| } |
| |
| private void item_2() { |
| |
| NodeList nl = target.getElementsByTagName("input"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strType = el.getAttribute("type"); //$NON-NLS-1$ |
| if (strType != null && strType.equalsIgnoreCase("image")) { //$NON-NLS-1$ |
| String strUsemap; |
| boolean bIsMap; |
| try { |
| bIsMap = ((HTMLImageElement) el).getIsMap(); |
| strUsemap = ((HTMLImageElement) el).getUseMap(); |
| } catch (RuntimeException e) { |
| bIsMap = false; |
| strUsemap = ""; //$NON-NLS-1$ |
| } |
| if (bIsMap || !strUsemap.equals("")) { //$NON-NLS-1$ |
| // 1.1 server-side image map as submit button alert |
| addCheckerProblem("C_2.0", el); //$NON-NLS-1$ |
| |
| // // 9.1 alert: please use client-side image map |
| // addCheckerProblem("C_2.2",el); |
| } |
| } |
| } |
| |
| // nl = target.getElementsByTagName("img"); |
| // length = nl.getLength(); |
| for (int i = 0; i < img_elements.length; i++) { |
| Element el = img_elements[i]; |
| String strUsemap = ((HTMLImageElement) el).getUseMap(); |
| if (((HTMLImageElement) el).getIsMap() && strUsemap.equals("")) { //$NON-NLS-1$ |
| // 1.2 server side image map |
| addCheckerProblem("C_2.1", el); //$NON-NLS-1$ |
| |
| // 9.1 alert: please use client-side image map |
| addCheckerProblem("C_2.2", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_3() { |
| for (Element el : img_elements) { |
| if (el.hasAttribute("longdesc")) { //$NON-NLS-1$ |
| String strLongDesc = el.getAttribute("longdesc"); //$NON-NLS-1$ |
| // original aDesigner routine |
| if (strLongDesc.length() > 0) { |
| boolean isDlink = false; |
| // need to check distance |
| int length = aWithHref_hrefs.length; |
| for (int j = 0; j < length; j++) { |
| // must use URL as in 58? |
| if (strLongDesc.equalsIgnoreCase(aWithHref_hrefs[j])) { |
| String strValue = aWithHref_strings[j]; |
| if (strValue.trim().equalsIgnoreCase("d")) { //$NON-NLS-1$ |
| isDlink = true; |
| break; |
| } |
| } |
| } |
| if (!isDlink) { // d link check |
| addCheckerProblem("C_3.0", el); //$NON-NLS-1$ |
| } |
| } |
| // For new JIS |
| addCheckerProblem("C_3.1", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_4() { |
| // need to refine conditions |
| Vector<Node> nodeV = new Vector<Node>(); |
| for (int i = 0; i < img_elements.length; i++) { |
| Element el = img_elements[i]; |
| if (isNormalImage(el)) { |
| if (el.hasAttribute(ATTR_ALT)) { |
| String strAlt = el.getAttribute(ATTR_ALT); |
| if (getWordCount(strAlt) >= 3 |
| || strAlt.length() >= validate_str_len) { |
| if (!strAlt.matches("\\p{ASCII}*") //$NON-NLS-1$ |
| || strAlt.length() > 30) { |
| nodeV.add(el); |
| } |
| } |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_4.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private void item_5() { |
| int length = aWithHref_elements.length; |
| for (int i = 0; i < length; i++) { |
| Element el = aWithHref_elements[i]; |
| String strHref = aWithHref_hrefs[i]; |
| if (strHref != null && strHref.length() > 0) { |
| String strExt = getFileExtension(strHref); |
| if (isAudioFileExt(strExt)) { |
| // 1.1 audio alert |
| addCheckerProblem("C_5.0", el); //$NON-NLS-1$ |
| break; |
| } else if (isMultimediaFileExt(strExt)) { |
| // 1.1 |
| addCheckerProblem("C_5.1", el); //$NON-NLS-1$ |
| // 1.3 |
| addCheckerProblem("C_5.2", el); //$NON-NLS-1$ |
| // 1.4 |
| addCheckerProblem("C_5.3", el); //$NON-NLS-1$ |
| break; |
| } |
| } |
| } |
| } |
| |
| private void item_6() { |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = bodyEl; |
| |
| while (curNode != null) { |
| boolean isArtStr = false; |
| if (isLeafBlockEle(curNode) |
| && isAsciiArtString(getTextAltDescendant(curNode))) { |
| addCheckerProblem("C_6.0", (Element) curNode); //$NON-NLS-1$ |
| addCheckerProblem("C_6.1", (Element) curNode); //$NON-NLS-1$ |
| isArtStr = true; |
| } |
| |
| if (!isArtStr && curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| } |
| } |
| |
| private void item_7() { |
| int aLength = aWithHref_elements.length; |
| NodeList nl = target.getElementsByTagName("area"); //$NON-NLS-1$ |
| int areaLen = nl.getLength(); |
| for (int i = 0; i < areaLen; i++) { |
| boolean bHasLink = false; |
| Element el = (Element) nl.item(i); |
| String strHref = ""; //$NON-NLS-1$ |
| if (el.hasAttribute(HtmlTagUtil.ATTR_HREF)) { |
| strHref = el.getAttribute(HtmlTagUtil.ATTR_HREF); |
| if (strHref.length() > 0) { |
| for (int j = 0; j < aLength; j++) { |
| // TODO use URL |
| if (strHref.equalsIgnoreCase(aWithHref_hrefs[j])) { |
| bHasLink = true; |
| break; |
| } |
| } |
| } |
| } |
| if (!bHasLink) { // link check |
| addCheckerProblem("C_7.0", " (href=\"" + strHref + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| } |
| } |
| |
| private void item_8() { |
| // TODO add color info to Description |
| NodeList nl = target.getElementsByTagName("font"); //$NON-NLS-1$ |
| Vector<Node> nodeV = new Vector<Node>(); |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| if (el.hasAttribute("color") || el.hasAttribute("bgcolor")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| String strColor, strBgColor; |
| strColor = el.getAttribute("color"); //$NON-NLS-1$ |
| strBgColor = el.getAttribute("bgcolor"); //$NON-NLS-1$ |
| if (!strColor.equals("") || !strBgColor.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| nodeV.add(el); |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_8.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| // need to handle CSS |
| } |
| |
| private void item_9() { |
| // Use markup language alert |
| boolean bHasNormalImage = false; |
| for (int i = 0; i < img_elements.length; i++) { |
| Element el = img_elements[i]; |
| if (isNormalImage(el)) { |
| bHasNormalImage = true; |
| break; |
| } |
| } |
| if (bHasNormalImage) |
| addCheckerProblem("C_9.0"); //$NON-NLS-1$ |
| } |
| |
| private void item_10() { |
| // formal grammars alert |
| addCheckerProblem("C_10.0"); //$NON-NLS-1$ |
| } |
| |
| private void item_12() { |
| for (int i = 0; i < parent_table_elements.length; i++) { |
| Element el = parent_table_elements[i]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = el.getFirstChild(); |
| int tableCount = 0; |
| int maxCount = 0; |
| String strName = ""; //$NON-NLS-1$ |
| while (curNode != null) { |
| strName = curNode.getNodeName(); |
| if (curNode.getNodeType() == Node.ELEMENT_NODE |
| && strName.equalsIgnoreCase("table")) { //$NON-NLS-1$ |
| tableCount++; |
| if (maxCount < tableCount) |
| maxCount = tableCount; |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| if ((curNode.getNodeType() == Node.ELEMENT_NODE) |
| && curNode.getNodeName().equals("table")) { //$NON-NLS-1$ |
| tableCount--; |
| } |
| curNode = curNode.getNextSibling(); |
| } else { |
| if ((curNode.getNodeType() == Node.ELEMENT_NODE) |
| && curNode.getNodeName().equals("table")) { //$NON-NLS-1$ |
| tableCount--; |
| } |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| if ((curNode.getNodeType() == Node.ELEMENT_NODE) |
| && curNode.getNodeName().equals("table")) { //$NON-NLS-1$ |
| tableCount--; |
| } |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| if (maxCount > 0) { |
| String str = null; |
| if (maxCount == 1) { |
| str = Messages.CheckEngine_ChildTable; |
| } else { |
| str = MessageFormat.format( |
| Messages.CheckEngine_TieredChildTable, |
| new Object[] { String.valueOf(maxCount) }); |
| } |
| addCheckerProblem("C_12.0", str, el); //$NON-NLS-1$ |
| } else |
| ; // Unreachable code! |
| } // end of top-most for loop |
| for (int i = 0; i < bottom_1row1col_tables.length; i++) { |
| addCheckerProblem("C_12.1", //$NON-NLS-1$ |
| bottom_1row1col_tables[i]); |
| } |
| |
| for (int i = 0; i < bottom_notdata_tables.length; i++) { |
| addCheckerProblem("C_12.2", //$NON-NLS-1$ |
| bottom_notdata_tables[i]); |
| } |
| } |
| |
| private void item_13() { |
| // font |
| NodeList nl = target.getElementsByTagName("font"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| Vector<Node> nodeV = new Vector<Node>(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| if (el.hasAttribute("size")) { //$NON-NLS-1$ |
| String strSize = el.getAttribute("size"); //$NON-NLS-1$ |
| if (strSize != null && strSize.length() > 0) { |
| if (strSize.indexOf("+") == -1 //$NON-NLS-1$ |
| && strSize.indexOf("-") == -1) { // absolute size //$NON-NLS-1$ |
| nodeV.add(el); |
| } |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_13.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| // table |
| checkAbsoluteSize("table"); //$NON-NLS-1$ |
| // tr |
| checkAbsoluteSize("tr"); //$NON-NLS-1$ |
| // td |
| checkAbsoluteSize("td"); //$NON-NLS-1$ |
| // col |
| checkAbsoluteSize("col"); //$NON-NLS-1$ |
| // frames,style sheets? |
| } |
| |
| private void item_14() { |
| |
| int curLevel = 0; |
| int lastLevel = 0; |
| for (int i = 0; i < headings.length; i++) { |
| curLevel = edu.getHeadingLevel(headings[i].getNodeName()); |
| if (curLevel > 0) { |
| if (lastLevel > 0) { |
| if (curLevel - lastLevel > 1) { |
| // heading level check |
| |
| String targetStr = MessageFormat.format( |
| Messages.CheckEngine_Headings, new Object[] { |
| curLevel, lastLevel }); |
| Vector<Node> tmpV = new Vector<Node>(); |
| tmpV.add(headings[i - 1]); |
| tmpV.add(headings[i]); |
| addCheckerProblem("C_14.0", targetStr, tmpV); //$NON-NLS-1$ |
| } |
| } |
| lastLevel = curLevel; |
| } |
| } |
| |
| } |
| |
| private void item_15() { |
| Vector<Node> targetV = new Vector<Node>(); |
| |
| for (int i = 0; i < headings.length; i++) { |
| targetV.add(headings[i]); |
| } |
| |
| if (targetV.size() > 0) { |
| addCheckerProblem("C_15.0", "", targetV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private void item_16() { |
| // DL, DT, DD, UL, OL, LI |
| // checkListElement("dl"); |
| // checkListElement("dt"); |
| // checkListElement("dd"); |
| // checkListElement("ul"); |
| // checkListElement("ol"); |
| // checkListElement("li"); |
| NodeList nl = target.getElementsByTagName("ol"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| NodeList liNl = el.getElementsByTagName("li"); //$NON-NLS-1$ |
| if (liNl.getLength() == 0) { // list element alert |
| addCheckerProblem("C_16.1", el); //$NON-NLS-1$ |
| } |
| } |
| |
| nl = target.getElementsByTagName("ul"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| NodeList liNl = el.getElementsByTagName("li"); //$NON-NLS-1$ |
| if (liNl.getLength() == 0) { // list element alert |
| addCheckerProblem("C_16.1", el); //$NON-NLS-1$ |
| } |
| } |
| |
| nl = target.getElementsByTagName("li"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| Vector<Node> liVec = new Vector<Node>(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasUlOl = false; |
| Node curNode = nl.item(i); |
| if (liVec.contains(curNode)) |
| continue; |
| String strName = ""; //$NON-NLS-1$ |
| while (curNode != null) { |
| strName = curNode.getNodeName(); |
| if (strName.equalsIgnoreCase("ol") //$NON-NLS-1$ |
| || strName.equalsIgnoreCase("ul")) { //$NON-NLS-1$ |
| bHasUlOl = true; |
| break; |
| } else if (strName.equalsIgnoreCase("body")) { //$NON-NLS-1$ |
| break; |
| } |
| curNode = curNode.getParentNode(); |
| } |
| if (!bHasUlOl) { |
| Node startNode = nl.item(i); |
| Node endNode = nl.item(i); |
| liVec.add(nl.item(i)); |
| Node preNode = nl.item(i).getPreviousSibling(); |
| while (preNode != null) { |
| if (preNode.getNodeName().equalsIgnoreCase("li") //$NON-NLS-1$ |
| && !liVec.contains(preNode)) { |
| liVec.add(preNode); |
| startNode = preNode; |
| } else |
| break; |
| preNode = preNode.getPreviousSibling(); |
| } |
| Node nextNode = nl.item(i).getNextSibling(); |
| while (nextNode != null) { |
| if (nextNode.getNodeName().equalsIgnoreCase("li") //$NON-NLS-1$ |
| && !liVec.contains(nextNode)) { |
| liVec.add(nextNode); |
| endNode = nextNode; |
| } else |
| break; |
| nextNode = nextNode.getNextSibling(); |
| } |
| // list element alert |
| addCheckerProblem( |
| "C_16.2", (Element) startNode, (Element) endNode); //$NON-NLS-1$ |
| } |
| } |
| |
| // dl,dt,dd |
| // dir,menu > obsolete |
| } |
| |
| private void item_17() { |
| NodeList nl = target.getElementsByTagName("q"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasText = false; |
| Node qNode = nl.item(i); |
| bHasText = hasTextDescendant(qNode); |
| if (!bHasText) { // quotation check |
| Element el = (Element) qNode; |
| addCheckerProblem("C_17.0", el); //$NON-NLS-1$ |
| } |
| } // blockquote |
| nl = target.getElementsByTagName("blockquote"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasText = false; |
| Node qNode = nl.item(i); |
| bHasText = hasTextDescendant(qNode); |
| if (!bHasText) { // quotation check |
| Element el = (Element) qNode; |
| addCheckerProblem("C_17.0", el); //$NON-NLS-1$ |
| } |
| } |
| if (length > 0) { |
| addCheckerProblem("C_17.1", "", nl); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_18() { |
| NodeList nl = target.getElementsByTagName("q"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Node qNode = nl.item(i); |
| String str = getTextDescendant(qNode); |
| if (str.length() > QUOTATION_SHORT_NUM) { // longer quotation |
| // check |
| Element el = (Element) qNode; |
| addCheckerProblem("C_18.0", el); //$NON-NLS-1$ |
| |
| str = el.getAttribute("cite"); //$NON-NLS-1$ |
| if (str.equals("")) { //$NON-NLS-1$ |
| // cite attribute check |
| addCheckerProblem("C_18.2", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| // blockquote |
| nl = target.getElementsByTagName("blockquote"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Node qNode = nl.item(i); |
| Element el = (Element) qNode; |
| String str = getTextDescendant(qNode); |
| if (str.length() <= QUOTATION_SHORT_NUM) { |
| // short quotation check |
| addCheckerProblem("C_18.1", el); //$NON-NLS-1$ |
| } |
| |
| str = el.getAttribute("cite"); //$NON-NLS-1$ |
| if (str.equals("")) { //$NON-NLS-1$ |
| // cite attribute check |
| addCheckerProblem("C_18.2", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_21() { |
| Element el = target.getDocumentElement(); |
| String attName = isXHTML ? "xml:lang" : "lang"; |
| String strLang = el.getAttribute(attName); |
| // System.out.println("(xml:)lang = " + strLang); // debug |
| |
| if (isEmptyString(strLang)) { |
| // no lang attribute |
| addCheckerProblem("C_21.0", attName, el); //$NON-NLS-1$ |
| } else { |
| // check conformance to "BCP 47" |
| LanguageTag tag = new LanguageTag(strLang, false); |
| |
| if (!tag.isWellFormed()) { |
| addCheckerProblem("C_21.1", attName, el); //$NON-NLS-1$ |
| } else { |
| // valid language |
| addCheckerProblem("C_21.2", attName, el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_22() { |
| if (table_elements.length > 0) { |
| Vector<Node> tables = new Vector<Node>( |
| Arrays.asList(table_elements)); |
| addCheckerProblem("C_22.0", null, tables); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| private void item_23() { |
| for (int i = 0; i < parent_table_elements.length; i++) { |
| boolean bHasTh = false; |
| boolean bHasSummary = false; |
| boolean bHasCaption = false; |
| Element tNode = parent_table_elements[i]; |
| |
| bHasSummary = (tNode.getAttribute("summary") != null && tNode |
| .getAttribute("summary").length() > 0); |
| bHasCaption = tNode.getElementsByTagName("caption").getLength() > 0; |
| |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = tNode.getFirstChild(); |
| while (curNode != null) { |
| String strName = ""; //$NON-NLS-1$ |
| strName = curNode.getNodeName(); |
| if (strName.equalsIgnoreCase("th")) { //$NON-NLS-1$ |
| bHasTh = true; |
| break; |
| } |
| |
| if (curNode.hasChildNodes() |
| && !strName.equalsIgnoreCase("table")) { //$NON-NLS-1$ |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| |
| if (bHasTh || bHasCaption || bHasSummary) { // table aleret |
| addCheckerProblem("C_23.0", tNode); //$NON-NLS-1$ |
| } |
| |
| // bottom table check(layout / not) |
| } |
| |
| // C_23.1/2 check. For new JIS |
| List<Element> tables = new ArrayList<Element>(); |
| Vector<Node> table_25_1 = new Vector<Node>(); |
| Vector<Node> table_25_2 = new Vector<Node>(); |
| |
| for (Element table : dataTableList) { |
| boolean added = false; |
| if (getDirectDescendantElements(table, "th").size() > 0) { |
| tables.add(table); |
| added = true; |
| } |
| if (getDirectDescendantElements(table, "caption").size() > 0) { |
| if (!added) { |
| tables.add(table); |
| added = true; |
| } |
| addCheckerProblem("C_25.3", table); //$NON-NLS-1$ |
| } else { |
| table_25_1.add(table); |
| } |
| if (table.hasAttribute("summary") |
| && !isEmptyString(table.getAttribute("summary"))) { |
| if (!added) { |
| tables.add(table); |
| added = true; |
| } |
| addCheckerProblem("C_25.4", table); //$NON-NLS-1$ |
| } else { |
| table_25_2.add(table); |
| } |
| } |
| |
| if (tables.size() > 0) { |
| Vector<Node> tablesV = new Vector<Node>(tables); |
| addCheckerProblem("C_23.1", "", tablesV); //$NON-NLS-1$ |
| } |
| if (table_25_1.size() > 0) |
| addCheckerProblem("C_25.1", null, table_25_1); //$NON-NLS-1$ |
| if (table_25_2.size() > 0) |
| addCheckerProblem("C_25.2", null, table_25_2); //$NON-NLS-1$ |
| |
| tables.clear(); |
| for (Element table : layoutTableList) { |
| if (getDirectDescendantElements(table, "th").size() > 0) { |
| tables.add(table); |
| } else if (getDirectDescendantElements(table, "caption").size() > 0) { |
| tables.add(table); |
| } else if (table.hasAttribute("summary") |
| && !isEmptyString(table.getAttribute("summary"))) { |
| tables.add(table); |
| } |
| } |
| |
| if (tables.size() > 0) { |
| Vector<Node> tablesV = new Vector<Node>(tables); |
| addCheckerProblem("C_23.2", "", tablesV); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| // private void item_25() { |
| // // moved to item_23()! |
| // } |
| |
| private void item_26() { |
| NodeList nl = target.getElementsByTagName("th"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String str = getTextAltDescendant(el); |
| if (isDBCS) { |
| if (str.length() > TABLE_CELL_ABBR_CHARS) { |
| addCheckerProblem("C_26.0", el); //$NON-NLS-1$ |
| } |
| } else { |
| if (getWordCount(str) > TABLE_CELL_ABBR_WORDS) { |
| addCheckerProblem("C_26.0", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| |
| private void item_27() { |
| for (int i = 0; i < frame_elements.length; i++) { |
| Element el = frame_elements[i]; |
| String strSrc = el.getAttribute(ATTR_SRC); |
| |
| if (!isHtmlFile(strSrc)) { // no-html file check |
| addCheckerProblem("C_27.0", "(src=" + strSrc + ")", el); //$NON-NLS-1$ |
| } |
| } |
| |
| // nl = target.getElementsByTagName("iframe"); //$NON-NLS-1$ |
| // length = nl.getLength(); |
| // for (int i = 0; i < length; i++) { |
| // boolean bHasHtml = true; |
| // Element el = (Element)nl.item(i); |
| // String strSrc = el.getAttribute("src"); //$NON-NLS-1$ |
| // |
| // if (!isHtmlFile(strSrc)) { // no-html file check |
| // addCheckerProblem("C_27.1", el); //$NON-NLS-1$ |
| // } |
| // } |
| } |
| |
| private void item_28() { |
| // need to check script/noscript mapping |
| int scrSize = edu.getScript_elements().length; |
| if (scrSize > 0) { |
| NodeList nl = target.getElementsByTagName("noscript"); //$NON-NLS-1$ |
| if (scrSize > nl.getLength()) { // noscript check |
| addCheckerProblem("C_28.0"); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_29() { |
| if (edu.isHasJavascript() || edu.getScript_elements().length > 0) { |
| addCheckerProblem("C_29.0"); //$NON-NLS-1$ |
| } |
| |
| for (Element applet : edu.getAppletElements()) { |
| addCheckerProblem("C_29.2", //$NON-NLS-1$ |
| applet); |
| } |
| |
| for (int i = 0; i < aWithHref_hrefs.length; i++) { |
| String str = aWithHref_hrefs[i]; |
| if (str.toLowerCase().startsWith("javascript:")) { //$NON-NLS-1$ |
| addCheckerProblem("C_29.1", //$NON-NLS-1$ |
| " (href=\"" + str + "\")", //$NON-NLS-2$ //$NON-NLS-1$ |
| aWithHref_elements[i]); |
| } |
| } |
| } |
| |
| private void mediaCheck() { |
| boolean bHasObject = false; |
| Vector<Node> tmpV = new Vector<Node>(); |
| for (Element e : object_elements) { |
| tmpV.add(e); |
| } |
| for (Element e : embed_elements) { |
| tmpV.add(e); |
| } |
| tmpV.addAll(edu.getAppletElements()); |
| if (tmpV.size() > 0) { |
| addCheckerProblem("C_30.0", "", tmpV); //$NON-NLS-1$ |
| addCheckerProblem("C_30.1", "", tmpV); //$NON-NLS-1$ |
| |
| // TODO check if these two items should be shown |
| addCheckerProblem("C_500.0", "", tmpV); |
| addCheckerProblem("C_500.1", "", tmpV); |
| |
| addCheckerProblem("C_600.1", "", tmpV); |
| addCheckerProblem("C_600.2", "", tmpV); |
| addCheckerProblem("C_600.6", "", tmpV); |
| addCheckerProblem("C_600.7", "", tmpV); |
| |
| addCheckerProblem("C_600.16", "", tmpV); //$NON-NLS-1$ |
| } |
| if (edu.isHasJavascript()) { |
| addCheckerProblem("C_30.1", "(JavaScript)"); //$NON-NLS-1$ |
| } |
| |
| String tmpS = ""; |
| if (object_elements.length < liveObject) { |
| tmpS = tmpS + " object"; |
| } |
| if (object_elements.length < liveObject) { |
| tmpS = tmpS + " embed"; |
| } |
| if (tmpS.length() > 0) { |
| addCheckerProblem("C_30.0", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$ |
| addCheckerProblem("C_30.1", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$ |
| |
| // TODO check if these two items should be shown |
| addCheckerProblem("C_500.0", "(" + Messages.Dynamic + tmpS + ")"); |
| addCheckerProblem("C_500.1", "(" + Messages.Dynamic + tmpS + ")"); |
| |
| addCheckerProblem("C_600.1", "(" + Messages.Dynamic + tmpS + ")"); |
| addCheckerProblem("C_600.2", "(" + Messages.Dynamic + tmpS + ")"); |
| addCheckerProblem("C_600.6", "(" + Messages.Dynamic + tmpS + ")"); |
| addCheckerProblem("C_600.7", "(" + Messages.Dynamic + tmpS + ")"); |
| |
| |
| addCheckerProblem("C_600.16", "(" + Messages.Dynamic + tmpS + ")"); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| private void item_31() { |
| NodeList nl = target.getElementsByTagName("frameset"); //$NON-NLS-1$ |
| if (nl.getLength() > 0) { |
| NodeList noNl = target.getElementsByTagName("noframes"); //$NON-NLS-1$ |
| if (noNl.getLength() == 0) { // noframes check |
| Element el = (Element) nl.item(0); |
| addCheckerProblem("C_31.0", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_32() { |
| if (object_elements.length > 0) { // object alert |
| result.add(new ProblemItemImpl("C_32.0")); //$NON-NLS-1$ |
| } else { |
| if (edu.getAppletElements().size() > 0) { // object alert |
| result.add(new ProblemItemImpl("C_32.0")); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_33() { |
| NodeList nl = target.getElementsByTagName("blink"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasText = false; |
| Element el = (Element) nl.item(i); |
| bHasText = hasTextDescendant(el); |
| if (bHasText) { // blink text check |
| addCheckerProblem("C_33.0", el); //$NON-NLS-1$ |
| } |
| } |
| |
| // TODO move to styleCheck |
| for (Element e : elementsWithStyleList) { |
| String style = e.getAttribute("style"); |
| if (BLINK_PATTERN_ATTR.matcher(style).matches()) { |
| addCheckerProblem("C_33.1", "style=\"" + style + "\"", e); //$NON-NLS-1$ |
| } |
| } |
| |
| Set<Element> styleElementList = styleElementMap.keySet(); |
| for (Element e : styleElementList) { |
| String style = styleElementMap.get(e); |
| if (style != null) { |
| if (BLINK_PATTERN.matcher(style).matches()) { |
| addCheckerProblem("C_33.2", "", e); |
| } |
| } |
| } |
| |
| Set<IStyleSheet> keys = styleSheetsMap.keySet(); |
| for (IStyleSheet ss : keys) { |
| if (ss.getHref().length() > 0 // avoid duplication |
| && BLINK_PATTERN.matcher(styleSheetsMap.get(ss)).matches()) { |
| addCheckerProblem("C_33.2", "(" + ss.getHref() + ")"); |
| } |
| } |
| |
| } |
| |
| private void item_34() { |
| NodeList nl = target.getElementsByTagName("marquee"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| // marquee check |
| addCheckerProblem("C_34.0", el); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_35() { |
| Vector<Node> gifImages = new Vector<Node>(); |
| |
| for (int i = 0; i < img_elements.length; i++) { |
| Element el = img_elements[i]; |
| if (isNormalImage(el) && el.hasAttribute(ATTR_SRC)) { |
| String strSrc = el.getAttribute(ATTR_SRC); |
| if (strSrc != null && strSrc.length() > 0) { |
| String strExt = getFileExtension(strSrc); |
| if (strExt.equalsIgnoreCase("gif")) { //$NON-NLS-1$ |
| // TODO gif image check |
| gifImages.add(el); |
| } |
| } |
| } |
| } |
| if (gifImages.size() > 0) |
| addCheckerProblem("C_35.0", //$NON-NLS-1$ |
| // " (src=\"" + strSrc + "\")", //$NON-NLS-1$ //$NON-NLS-2$ |
| "", gifImages); |
| |
| } |
| |
| private void item_36() { |
| NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| |
| if (el.hasAttribute("http-equiv")) { //$NON-NLS-1$ |
| String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$ |
| if (strMeta != null && strMeta.equalsIgnoreCase("refresh")) { //$NON-NLS-1$ |
| String strCon = el.getAttribute("content"); //$NON-NLS-1$ |
| if (strCon == null |
| || strCon.toLowerCase().indexOf("url") < 0) { //$NON-NLS-1$ |
| // refresh |
| // refresh itself check |
| addCheckerProblem("C_36.0", el); //$NON-NLS-1$ |
| } else { |
| // redirect |
| Matcher m = Pattern.compile("(\\d+);.*") |
| .matcher(strCon); |
| if (m.matches() && Integer.parseInt(m.group(1)) > 0) |
| addCheckerProblem("C_36.1", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| } |
| |
| private void item_38() { |
| Element[] mouseButton = edu.getEventMouseButtonElements(); |
| Element[] mouseFocus = edu.getEventOnMouseElements(); |
| // Element[] onKey = edu.getEventOnKeyElements(); |
| |
| // TODO update message |
| |
| HashSet<Element> tmpSet = new HashSet<Element>(); |
| Vector<Node> nodeV = new Vector<Node>(); |
| for (int i = 0; i < mouseButton.length; i++) { |
| Element el = mouseButton[i]; |
| tmpSet.add(el); |
| if (el.hasAttribute(ATTR_ONKEYDOWN) |
| || el.hasAttribute(ATTR_ONKEYPRESS) |
| || el.hasAttribute(ATTR_ONKEYUP)) { |
| // info (confirm) |
| } else { |
| nodeV.add(el); |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_38.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| nodeV.clear(); |
| for (int i = 0; i < mouseFocus.length; i++) { |
| Element el = mouseFocus[i]; |
| if (tmpSet.add(el)) { |
| if (el.hasAttribute(ATTR_ONFOCUS) |
| || el.hasAttribute(ATTR_ONBLUR) |
| || el.hasAttribute(ATTR_ONSELECT)) { |
| // info (confirm) |
| } else { |
| nodeV.add(el); |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_38.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| } |
| |
| private void item_39() { |
| boolean bHasTabIndex = false; |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = bodyEl; |
| while (curNode != null) { |
| if (curNode.getNodeType() == Node.ELEMENT_NODE) { |
| Element el = (Element) curNode; |
| if (el.hasAttribute("tabindex")) { //$NON-NLS-1$ |
| String str = el.getAttribute("tabindex"); //$NON-NLS-1$ |
| if (!str.equals("")) { //$NON-NLS-1$ |
| bHasTabIndex = true; |
| break; |
| } |
| } |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| } |
| if (!bHasTabIndex) { |
| // tabindex check |
| addCheckerProblem("C_39.0"); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_40() { |
| boolean bHasAccess = false; |
| for (int i = 0; i < aWithHref_elements.length; i++) { |
| Element el = aWithHref_elements[i]; |
| if (el.hasAttribute("accesskey")) { //$NON-NLS-1$ |
| String str = el.getAttribute("accesskey"); //$NON-NLS-1$ |
| if (str.length() > 0) { |
| bHasAccess = true; |
| break; |
| } |
| } |
| } |
| if (!bHasAccess) { |
| // alert to add keyboard shortcut to frequently used links |
| addCheckerProblem("C_40.0"); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_41() { |
| boolean bHasAccess = false; |
| int length = formList.size(); |
| if (length == 0) |
| return; |
| for (Element formEl : formList) { |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = formEl.getFirstChild(); |
| while (curNode != null) { |
| if (curNode.getNodeType() == Node.ELEMENT_NODE) { |
| Element el = (Element) curNode; |
| if (el.hasAttribute("accesskey")) { //$NON-NLS-1$ |
| String str = el.getAttribute("accesskey"); //$NON-NLS-1$ |
| if (!str.equals("")) { //$NON-NLS-1$ |
| bHasAccess = true; |
| break; |
| } |
| } |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| |
| if (bHasAccess) |
| break; |
| } |
| if (!bHasAccess) { |
| // alert to furnish keyboard shortcut for form elements |
| addCheckerProblem("C_41.0"); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| private void item_42() { |
| Vector<Node> anchors = new Vector<Node>(); |
| |
| for (int i = 0; i < aWithHref_elements.length; i++) { |
| Element el = aWithHref_elements[i]; |
| if (el.hasAttribute("target")) { //$NON-NLS-1$ |
| String strTarget = el.getAttribute("target"); //$NON-NLS-1$ |
| if (!strTarget.equals("") //$NON-NLS-1$ |
| && !strTarget.equalsIgnoreCase("_top") //$NON-NLS-1$ |
| && !strTarget.equalsIgnoreCase("_self") //$NON-NLS-1$ |
| && !strTarget.equalsIgnoreCase("top") //$NON-NLS-1$ |
| && !strTarget.equalsIgnoreCase("self")) { //$NON-NLS-1$ |
| // && (strTarget.equalsIgnoreCase("_blank") |
| // || strTarget.equalsIgnoreCase("blank") |
| // || strTarget.equalsIgnoreCase("_new") |
| // || strTarget.equalsIgnoreCase("new") |
| // || strTarget.equalsIgnoreCase("_top") |
| // || strTarget.equalsIgnoreCase("top"))) { |
| // popup new window alert |
| anchors.add(el); |
| } |
| } |
| } |
| |
| if (anchors.size() > 0) |
| addCheckerProblem("C_42.0", null, anchors); //$NON-NLS-1$ |
| } |
| |
| private void item_43() { |
| |
| boolean bHasProblem = false; |
| Element[] tmpE = edu.getScript_elements(); |
| int length = tmpE.length; |
| for (int i = 0; i < length; i++) { |
| Element el = tmpE[i]; |
| Node curChild = el.getFirstChild(); |
| while (curChild != null) { |
| if (curChild.getNodeType() == Node.CDATA_SECTION_NODE) { |
| String strTxt = curChild.getNodeValue(); |
| if (strTxt != null |
| && strTxt.toLowerCase().indexOf(WINDOW_OPEN) >= 0) { |
| bHasProblem = true; |
| break; |
| } |
| } |
| curChild = curChild.getNextSibling(); |
| } |
| if (bHasProblem) { |
| result.add(new ProblemItemImpl("C_43.0")); //$NON-NLS-1$ |
| break; |
| } |
| } |
| |
| HashSet<Element> tmpSet = new HashSet<Element>(); |
| tmpE = edu.getEventFocusElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_FOCUS) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| tmpE = edu.getEventLoadElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_LOAD) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| tmpE = edu.getEventMouseButtonElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_MOUSE_BUTTON) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| tmpE = edu.getEventOnMouseElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_MOUSE_FOCUS) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| tmpE = edu.getEventOnKeyElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_ON_KEY) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| tmpE = edu.getEventWindowElements(); |
| for (int i = 0; i < tmpE.length; i++) { |
| if (hasOpenWndEvent(tmpE[i], HtmlEvalUtil.EVENT_WINDOW) |
| && tmpSet.add(tmpE[i])) { |
| result.add(new ProblemItemImpl("C_43.0", tmpE[i])); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_45() { |
| // input: text, text area, radio |
| NodeList nl = target.getElementsByTagName("input"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasDefault = false; |
| Element el = (Element) nl.item(i); |
| if (!el.hasAttribute("type")) //$NON-NLS-1$ |
| continue; |
| String strType = el.getAttribute("type"); //$NON-NLS-1$ |
| if (strType.equalsIgnoreCase("text") //$NON-NLS-1$ |
| || strType.equalsIgnoreCase("textbox") //$NON-NLS-1$ |
| || strType.equalsIgnoreCase("textarea") //$NON-NLS-1$ |
| || strType.equals("")) { //$NON-NLS-1$ |
| String strValue = el.getAttribute("value"); //$NON-NLS-1$ |
| if (strValue != null && strValue.length() > 0) |
| bHasDefault = true; |
| else { |
| bHasDefault = hasTextDescendant(el); |
| } |
| |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.0", el); //$NON-NLS-1$ |
| } |
| } else if (strType.equalsIgnoreCase("radio")) { //$NON-NLS-1$ |
| String strChecked = el.getAttribute("checked"); //$NON-NLS-1$ |
| if (strChecked != null && !strChecked.equals("")) //$NON-NLS-1$ |
| bHasDefault = true; |
| else { |
| if (!el.hasAttribute("name")) //$NON-NLS-1$ |
| continue; |
| String strName1 = el.getAttribute("name"); //$NON-NLS-1$ |
| |
| for (int j = 0; j < length; j++) { |
| if (i == j) |
| continue; |
| Element el2 = (Element) nl.item(j); |
| if (!el2.hasAttribute("type")) //$NON-NLS-1$ |
| continue; |
| String strType2 = el2.getAttribute("type"); //$NON-NLS-1$ |
| |
| if (strType2.equalsIgnoreCase("radio")) { //$NON-NLS-1$ |
| String strName2 = el2.getAttribute("name"); //$NON-NLS-1$ |
| if (strName2 != null |
| && strName1.equalsIgnoreCase(strName2)) { // this |
| // radio |
| // group |
| // has |
| // been |
| // checked |
| if (j < i) { |
| bHasDefault = true; |
| break; |
| } |
| String strChecked2 = el2 |
| .getAttribute("checked"); //$NON-NLS-1$ |
| if (strChecked2 != null |
| && !strChecked2.equals("")) { //$NON-NLS-1$ |
| bHasDefault = true; |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.1", el); //$NON-NLS-1$ |
| } |
| } else { |
| continue; |
| } |
| |
| } |
| |
| // select |
| nl = target.getElementsByTagName("select"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasDefault = false; |
| Element el = (Element) nl.item(i); |
| NodeList opNl = el.getElementsByTagName("option"); //$NON-NLS-1$ |
| int opLength = opNl.getLength(); |
| for (int j = 0; j < opLength; j++) { |
| String strSelected = ((Element) opNl.item(j)) |
| .getAttribute("selected"); //$NON-NLS-1$ |
| if (strSelected != null) { |
| bHasDefault = true; |
| break; |
| } |
| } |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.1", el); //$NON-NLS-1$ |
| } |
| } // html:text |
| nl = target.getElementsByTagName("html:text"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasDefault = false; |
| Element el = (Element) nl.item(i); |
| String strValue = el.getAttribute("value"); //$NON-NLS-1$ |
| if (strValue != null && strValue.length() > 0) { |
| bHasDefault = true; |
| } else { |
| bHasDefault = hasTextDescendant(el); |
| } |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.0", el); //$NON-NLS-1$ |
| } |
| } // textarea |
| nl = target.getElementsByTagName("textarea"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasDefault = false; |
| Element el = (Element) nl.item(i); |
| String strValue = el.getAttribute("value"); //$NON-NLS-1$ |
| if (strValue != null && strValue.length() > 0) { |
| bHasDefault = true; |
| } else { |
| bHasDefault = hasTextDescendant(el); |
| } |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.0", el); //$NON-NLS-1$ |
| } |
| } // html:radio |
| nl = target.getElementsByTagName("html:radio"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| boolean bHasDefault = false; |
| Element el = (Element) nl.item(i); |
| String strName1 = el.getAttribute("name"); //$NON-NLS-1$ |
| if (strName1 == null) |
| continue; |
| for (int j = i + 1; i < length; j++) { |
| Element el2 = (Element) nl.item(j); |
| String strName2 = el2.getAttribute("name"); //$NON-NLS-1$ |
| if (strName2 != null && strName1.equalsIgnoreCase(strName2)) { |
| String strChecked2 = el2.getAttribute("checked"); //$NON-NLS-1$ |
| if (strChecked2 != null) { |
| bHasDefault = true; |
| break; |
| } |
| } |
| } |
| if (!bHasDefault) { // default value check |
| addCheckerProblem("C_45.1", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_46() { |
| Vector<Element> eleVec = new Vector<Element>(); |
| for (int i = 0; i < aWithHref_elements.length; i++) { |
| boolean bAdjacentLink = false; |
| Element el = aWithHref_elements[i]; |
| if (eleVec.contains(el)) |
| continue; |
| Element endEl = null; |
| Node nextNode = el.getNextSibling(); |
| String url1 = aWithHref_hrefs[i]; |
| String url2; |
| try { |
| url1 = new URL(baseUrl, aWithHref_hrefs[i]).toString(); |
| } catch (MalformedURLException e) { |
| } |
| while (nextNode != null) { |
| if (nextNode.getNodeType() == Node.ELEMENT_NODE) { |
| String strName = nextNode.getNodeName(); |
| if (strName != null) { |
| if (strName.equalsIgnoreCase("br") //$NON-NLS-1$ |
| || strName.equalsIgnoreCase("p")) { //$NON-NLS-1$ |
| nextNode = nextNode.getNextSibling(); |
| continue; |
| } else if (strName.equalsIgnoreCase("a")) { //$NON-NLS-1$ |
| try { |
| url2 = new URL( |
| baseUrl, |
| ((Element) nextNode) |
| .getAttribute(HtmlTagUtil.ATTR_HREF)) |
| .toString(); |
| } catch (MalformedURLException e) { |
| url2 = ((Element) nextNode) |
| .getAttribute(HtmlTagUtil.ATTR_HREF); |
| } |
| if (!url1.equals(url2)) { |
| endEl = (Element) nextNode; |
| if (!eleVec.contains(el)) |
| eleVec.add(el); |
| if (!eleVec.contains(endEl)) |
| eleVec.add(endEl); |
| bAdjacentLink = true; |
| } else |
| break; |
| } else { |
| break; |
| } |
| } |
| // break; |
| } else if (nextNode.getNodeType() == Node.TEXT_NODE) { |
| String strText = nextNode.getNodeValue(); |
| if (strText != null && !strText.trim().equals("")) //$NON-NLS-1$ |
| break; |
| } |
| nextNode = nextNode.getNextSibling(); |
| } |
| if (bAdjacentLink) { // adjacent link check |
| addCheckerProblem("C_46.0", el, endEl); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| @SuppressWarnings("nls") |
| private void item_48() { |
| // Applet |
| checkObsoluteEle("C_48.1", "applet"); //$NON-NLS-1$ |
| // BASEFONT, CENTER, FONT, STRIKE, U |
| checkObsoluteEle("C_48.2", "basefont"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.2", "center"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.2", "font"); //$NON-NLS-1$ |
| // ? |
| checkObsoluteEle("C_48.2", "strike"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.2", "u"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.2", "s"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.2", "i"); //$NON-NLS-1$ |
| // DIR, MENU |
| checkObsoluteEle("C_48.3", "dir"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.3", "menu"); //$NON-NLS-1$ |
| // ISINDEX |
| checkObsoluteEle("C_48.4", "isindex"); //$NON-NLS-1$ |
| // LISTING, PLAINTEXT, XMP |
| checkObsoluteEle("C_48.5", "listing"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.5", "plaintext"); //$NON-NLS-1$ |
| checkObsoluteEle("C_48.5", "xmp"); //$NON-NLS-1$ |
| } |
| |
| private void item_49() { |
| // alert about customize experience |
| addCheckerProblem("C_49.0"); //$NON-NLS-1$ |
| } |
| |
| private void item_50() { |
| // alert about accessible version |
| addCheckerProblem("C_50.0"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Checks for title attributes of frame/iframe elements. |
| */ |
| private void item_51() { |
| for (int i = 0; i < frame_elements.length; i++) { |
| Element el = frame_elements[i]; |
| if (!hasTitle(el)) { |
| addCheckerProblem("C_51.0", el); //$NON-NLS-1$ |
| } else if (hasBlankTitle(el)) { |
| addCheckerProblem("C_51.4", el); //$NON-NLS-1$ |
| } else { |
| addCheckerProblem("C_51.2", el.getAttribute(ATTR_TITLE), el); //$NON-NLS-1$ |
| } |
| } |
| |
| for (int i = 0; i < iframe_elements.length; i++) { |
| Element el = iframe_elements[i]; |
| if (!hasTitle(el)) { |
| addCheckerProblem("C_51.1", //$NON-NLS-1$ |
| ": src=" + el.getAttribute(ATTR_SRC), //$NON-NLS-1$ |
| el); |
| } else if (hasBlankTitle(el)) { |
| addCheckerProblem("C_51.5", //$NON-NLS-1$ |
| ": src=" + el.getAttribute(ATTR_SRC), //$NON-NLS-1$ |
| el); |
| } else { |
| addCheckerProblem("C_51.3", el.getAttribute(ATTR_TITLE), el); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_52() { |
| // add longdesc/title into description |
| for (int i = 0; i < frame_elements.length; i++) { |
| Element el = frame_elements[i]; |
| String strTitle = el.getAttribute(ATTR_TITLE); |
| if (!strTitle.equals("")) { //$NON-NLS-1$ |
| String strLongdesc = el.getAttribute("longdesc"); //$NON-NLS-1$ |
| if (strLongdesc == null || strLongdesc.equals("")) { // alert //$NON-NLS-1$ |
| // about |
| // frame |
| // description |
| // //$NON-NLS-1$ |
| addCheckerProblem("C_52.0", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| // www.cnn.com --target has <iframe but source does not |
| for (int i = 0; i < iframe_elements.length; i++) { |
| Element el = iframe_elements[i]; |
| String strTitle = el.getAttribute(ATTR_TITLE); |
| if (!strTitle.equals("")) { //$NON-NLS-1$ |
| String strLongdesc = el.getAttribute("longdesc"); //$NON-NLS-1$ |
| if (strLongdesc == null || strLongdesc.equals("")) { // alert //$NON-NLS-1$ |
| // about |
| // frame |
| // description |
| // //$NON-NLS-1$ |
| addCheckerProblem("C_52.1", el); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| |
| private void item_53() { |
| NodeList nl = target.getElementsByTagName("select"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| // alert to group long lists of selections |
| Element select = (Element) nl.item(i); |
| |
| NodeList optGpNl = select.getElementsByTagName("optgroup"); //$NON-NLS-1$ |
| if (optGpNl.getLength() == 0) { |
| addCheckerProblem("C_53.2", select); //$NON-NLS-1$ |
| NodeList optList = select.getElementsByTagName("option"); //$NON-NLS-1$ |
| if (optList.getLength() > 10) { |
| addCheckerProblem("C_53.1", select); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| |
| /** |
| * Fieldset and legend checking |
| */ |
| private void item_54() { |
| |
| // move into initialization |
| // if (formList == null) |
| // formList = edu.getElementsList(target, "form"); //$NON-NLS-1$ |
| |
| Vector<Node> noFieldSetForms = new Vector<Node>(); |
| Vector<Node> fieldSetForms = new Vector<Node>(); |
| for (Element form : formList) { |
| if (getFormControlNum(form) <= 1) |
| continue; |
| List<Element> fieldsets = edu.getElementsList(form, "fieldset"); //$NON-NLS-1$ |
| if (fieldsets.size() == 0) { |
| noFieldSetForms.add(form); |
| } else { |
| for (Element fieldset : fieldsets) { |
| fieldSetForms.add(fieldset); |
| List<Element> legends = edu.getElementsList(fieldset, |
| "legend"); //$NON-NLS-1$ |
| if (legends.size() == 0) { |
| addCheckerProblem("C_54.1", fieldset); //$NON-NLS-1$ |
| } else { |
| for (Element e : legends) |
| addCheckerProblem("C_54.4", e); //$NON-NLS-1$ |
| } |
| } |
| } |
| // C_54.3 check |
| if (fieldsets.size() >= 2) { |
| FieldsetManager map = new FieldsetManager(); |
| int index = 0; |
| for (Element fieldset : fieldsets) { |
| for (Element ctrl : getRadioAndCheck(fieldset)) { |
| map.addEntry(ctrl.getAttribute("name"), ctrl, index); |
| } |
| index++; |
| } |
| for (Vector<Node> error : map.getErrorList()) { |
| addCheckerProblem("C_54.3", "", error); //$NON-NLS-1$ |
| } |
| } |
| } |
| if (noFieldSetForms.size() > 0) |
| addCheckerProblem("C_54.0", null, noFieldSetForms); //$NON-NLS-1$ |
| if (fieldSetForms.size() > 0) |
| addCheckerProblem("C_54.2", null, fieldSetForms); //$NON-NLS-1$ |
| } |
| |
| @SuppressWarnings("nls") |
| private void item_57() { |
| // need more detailed check |
| Element el = null; |
| int errorCount = 0; |
| int exceptCount = 0; |
| |
| int length = aWithHref_elements.length; |
| Vector<Node> item57V = new Vector<Node>(); |
| Vector<Node> linkTitle = new Vector<Node>(); |
| |
| for (int i = 0; i < length; i++) { |
| el = aWithHref_elements[i]; |
| |
| String strTxt = aWithHref_strings[i]; |
| |
| if (el.hasAttribute(ATTR_TITLE)) { |
| if (hasBlankTitle(el)) |
| addCheckerProblem("C_57.3", el); //$NON-NLS-1$ |
| else |
| linkTitle.add(el); |
| } |
| |
| if (getWordCount(strTxt) < 3 && strTxt.length() < validate_str_len) { |
| String strTitle = el.getAttribute(ATTR_TITLE); |
| if (strTitle.equals("")) { //$NON-NLS-1$ |
| if (strTxt.trim().length() > 0) { |
| item57V.add(el); |
| } else { |
| // can't use link |
| |
| if (!aWithHref_hrefs[i].startsWith("#")) { //$NON-NLS-1$ |
| |
| String noScriptText = getNoScriptText(el); |
| |
| if ((!el.hasChildNodes() || el |
| .getElementsByTagName("img").getLength() == 0)) { //$NON-NLS-1$ |
| exceptCount++; |
| // alert |
| } else if (noScriptText.length() > 0) { |
| // script + noscript(Text) |
| exceptCount++; |
| // alert |
| } else { |
| errorCount++; |
| String current = aWithHref_hrefs[i]; |
| boolean sequenceOk = false; |
| if (i - 1 > 0) { |
| if (current.equals(aWithHref_hrefs[i - 1]) |
| && aWithHref_strings[i - 1] |
| .length() > 0) { |
| sequenceOk = true; |
| } |
| } |
| if (!sequenceOk |
| && i + 1 < aWithHref_hrefs.length) { |
| if (current.equals(aWithHref_hrefs[i + 1]) |
| && aWithHref_strings[i + 1] |
| .length() > 0) { |
| sequenceOk = true; |
| } |
| } |
| |
| if (sequenceOk) { |
| // USER |
| IProblemItem tmpCP = addCheckerProblem( |
| "C_57.5", //$NON-NLS-1$ |
| " (href=\"" + aWithHref_hrefs[i] //$NON-NLS-1$ |
| + "\")", el); //$NON-NLS-1$ |
| edu.appendErrorIcon(tmpCP, el); |
| } else { |
| // WARN |
| IProblemItem tmpCP = addCheckerProblem( |
| "C_57.2", //$NON-NLS-1$ |
| " (href=\"" + aWithHref_hrefs[i] //$NON-NLS-1$ |
| + "\")", el); //$NON-NLS-1$ |
| edu.appendErrorIcon(tmpCP, el); |
| } |
| } |
| } else { |
| // need to count # (intra page link) |
| errorCount++; |
| } |
| } |
| } else { |
| if (getWordCount(strTitle) < 3 |
| && strTitle.length() < validate_str_len) { |
| // link title check |
| // show always? |
| addCheckerProblem("C_57.1", //$NON-NLS-1$ |
| " (linktext=\"" //$NON-NLS-1$ |
| + strTxt + "\", title=\"" //$NON-NLS-1$ |
| + strTitle + "\", href=\"" //$NON-NLS-1$ |
| + aWithHref_hrefs[i] + "\")", //$NON-NLS-1$ |
| el); |
| } |
| } |
| } |
| } |
| if (item57V.size() > 0) { |
| addCheckerProblem("C_57.0", "", item57V); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| /* |
| * if (linkTitle.size() > 0) addCheckerProblem("C_57.4", "", linkTitle); |
| * //$NON-NLS-1$ //$NON-NLS-2$ |
| */ |
| for (Node link : linkTitle) { |
| addCheckerProblem("C_57.4", |
| ((Element) link).getAttribute(ATTR_TITLE), (Element) link); |
| } |
| |
| // need URL check |
| |
| length = length - exceptCount; |
| |
| if (length > 0) { |
| invalidLinkRatio = (double) errorCount / (double) length; |
| // System.out.println(invalidLinkRatio); |
| } |
| |
| } |
| |
| private void item_58() { |
| |
| int[] countStrLen = { 0, 0, 0, 0, 0 }; |
| for (int i = 0; i < aWithHref_elements.length; i++) { |
| // strArray[i] = getTextAltDescendant(nl.item(i)); |
| int length = aWithHref_strings[i].length(); |
| |
| if (length == 0) { |
| continue; |
| } |
| |
| if (length > 9) { |
| if (length < 20) { |
| countStrLen[3]++; |
| } else { |
| countStrLen[4]++; |
| } |
| } else if (length < 7) { |
| if (length < 4) |
| countStrLen[0]++; |
| else |
| countStrLen[1]++; |
| } else { |
| countStrLen[2]++; |
| } |
| } |
| |
| // 0 (exclusion) |
| // length 1-3 |
| // length 4-6 |
| // length 7-9 |
| // length 10-20 |
| // length 20- |
| |
| int[][] strHash = new int[5][]; |
| Node[][] nodeArray = new Node[5][]; |
| String[][] strArray = new String[5][]; |
| String[][] urlArray = new String[5][]; |
| boolean[][] bDuplicate = new boolean[5][]; |
| for (int i = 0; i < 5; i++) { |
| strHash[i] = new int[countStrLen[i]]; |
| bDuplicate[i] = new boolean[countStrLen[i]]; |
| nodeArray[i] = new Node[countStrLen[i]]; |
| strArray[i] = new String[countStrLen[i]]; |
| urlArray[i] = new String[countStrLen[i]]; |
| // System.out.print(countStrLen[i] + " "); |
| countStrLen[i] = 0; |
| } |
| // System.out.println(); |
| |
| int nlLength = aWithHref_elements.length; |
| for (int i = 0; i < nlLength; i++) { |
| int length = aWithHref_strings[i].length(); |
| if (length == 0) |
| continue; |
| if (length > 9) { |
| if (length < 20) { |
| strHash[3][countStrLen[3]] = aWithHref_strings[i] |
| .hashCode(); |
| nodeArray[3][countStrLen[3]] = aWithHref_elements[i]; |
| strArray[3][countStrLen[3]] = aWithHref_strings[i]; |
| urlArray[3][countStrLen[3]] = aWithHref_hrefs[i]; |
| countStrLen[3]++; |
| } else { |
| strHash[4][countStrLen[4]] = aWithHref_strings[i] |
| .hashCode(); |
| nodeArray[4][countStrLen[4]] = aWithHref_elements[i]; |
| strArray[4][countStrLen[4]] = aWithHref_strings[i]; |
| urlArray[4][countStrLen[4]] = aWithHref_hrefs[i]; |
| countStrLen[4]++; |
| } |
| } else if (length < 7) { |
| if (length < 4) { |
| strHash[0][countStrLen[0]] = aWithHref_strings[i] |
| .hashCode(); |
| nodeArray[0][countStrLen[0]] = aWithHref_elements[i]; |
| strArray[0][countStrLen[0]] = aWithHref_strings[i]; |
| urlArray[0][countStrLen[0]] = aWithHref_hrefs[i]; |
| countStrLen[0]++; |
| } else { |
| strHash[1][countStrLen[1]] = aWithHref_strings[i] |
| .hashCode(); |
| nodeArray[1][countStrLen[1]] = aWithHref_elements[i]; |
| strArray[1][countStrLen[1]] = aWithHref_strings[i]; |
| urlArray[1][countStrLen[1]] = aWithHref_hrefs[i]; |
| countStrLen[1]++; |
| } |
| } else { |
| strHash[2][countStrLen[2]] = aWithHref_strings[i].hashCode(); |
| nodeArray[2][countStrLen[2]] = aWithHref_elements[i]; |
| strArray[2][countStrLen[2]] = aWithHref_strings[i]; |
| urlArray[2][countStrLen[2]] = aWithHref_hrefs[i]; |
| countStrLen[2]++; |
| } |
| } |
| |
| for (int i = 0; i < 5; i++) { |
| for (int j = 0; j < strHash[i].length - 1; j++) { |
| if (bDuplicate[i][j]) |
| continue; |
| Vector<Node> idVec = new Vector<Node>(); |
| |
| for (int k = j + 1; k < strHash[i].length; k++) { |
| if (bDuplicate[i][k]) |
| continue; |
| if (strHash[i][j] == strHash[i][k]) { |
| |
| String url1 = urlArray[i][j]; |
| try { |
| url1 = new URL(baseUrl, url1).toString(); |
| } catch (MalformedURLException e) { |
| // e.printStackTrace(); |
| } |
| |
| String url2 = urlArray[i][k]; |
| try { |
| url2 = new URL(baseUrl, url2).toString(); |
| } catch (MalformedURLException e1) { |
| // e1.printStackTrace(); |
| } |
| |
| // System.out.println(url1 + " " + url2); |
| if (!url1.equalsIgnoreCase(url2)) { |
| if (!bDuplicate[i][j]) { |
| idVec.add(nodeArray[i][j]); |
| bDuplicate[i][j] = true; |
| } |
| idVec.add(nodeArray[i][k]); |
| bDuplicate[i][k] = true; |
| } |
| } |
| |
| } |
| |
| if (idVec.size() > 0) { |
| addCheckerProblem("C_58.0", " (linktext=\"" //$NON-NLS-1$ //$NON-NLS-2$ |
| + strArray[i][j] + "\")", idVec); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| } |
| |
| private void item_59() { |
| |
| // 59.0 was identical with 68 |
| |
| boolean bHasKeyWdDesc = false; |
| NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strName = el.getAttribute("name"); //$NON-NLS-1$ |
| if (strName != null && strName.equalsIgnoreCase("keywords")) //$NON-NLS-1$ |
| bHasKeyWdDesc = true; |
| else if (strName != null && strName.equalsIgnoreCase("description")) //$NON-NLS-1$ |
| bHasKeyWdDesc = true; |
| } |
| if (!bHasKeyWdDesc) { |
| // Use the keywords |
| addCheckerProblem("C_59.1"); //$NON-NLS-1$ |
| } |
| |
| nl = target.getElementsByTagName("address"); //$NON-NLS-1$ |
| if (nl.getLength() == 0) { |
| // Use the ADDRESS element |
| addCheckerProblem("C_59.2"); //$NON-NLS-1$ |
| } |
| |
| // Use the Resource Description Framework (RDF) in the header of your |
| // document |
| addCheckerProblem("C_59.3"); //$NON-NLS-1$ |
| } |
| |
| private void item_60() { |
| boolean bHasTitle = false; |
| Element firstTitle = null; |
| NodeList nl = target.getElementsByTagName("head"); //$NON-NLS-1$ |
| if (nl.getLength() > 0) { |
| NodeList hdNl = ((Element) nl.item(0)) |
| .getElementsByTagName(ATTR_TITLE); |
| int length = hdNl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element titleEl = (Element) hdNl.item(i); |
| if (firstTitle == null) |
| firstTitle = titleEl; |
| bHasTitle = hasTextDescendant(titleEl); |
| } |
| } |
| if (!bHasTitle) { // document title check |
| result.add(new ProblemItemImpl("C_60.0")); //$NON-NLS-1$ |
| } else { |
| List<String> ngPatterns = new ArrayList<String>(); |
| ngPatterns.add("\u7121\u984c.*"); |
| ngPatterns.add(".*untitled.*"); |
| ngPatterns.add(".*no title.*"); |
| ngPatterns.add(".*\\.html?"); |
| ngPatterns.add("[\\p{Punct}\\d]+"); |
| String title = getTextDescendant(firstTitle).toLowerCase().trim(); |
| |
| for (String pattern : ngPatterns) { |
| if (title.matches(pattern)) { |
| addCheckerProblem("C_60.1", title, firstTitle); |
| break; |
| } |
| } |
| |
| } |
| } |
| |
| private void item_66() { |
| // need to check descendant text (or href txt) contains "search","go", |
| // etc. |
| // exist text box / text area |
| |
| for (Element formE : formList) { |
| // alert if there are different types of searches |
| addCheckerProblem("C_66.0", formE); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_68() { |
| boolean bHasRel = false; |
| NodeList nl = target.getElementsByTagName("link"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strRel = el.getAttribute("rel"); //$NON-NLS-1$ |
| if (strRel != null && !strRel.equals("") //$NON-NLS-1$ |
| && !strRel.equalsIgnoreCase("stylesheet")) { //$NON-NLS-1$ |
| bHasRel = true; |
| break; |
| } else { |
| strRel = el.getAttribute("rev"); //$NON-NLS-1$ |
| if (strRel != null && !strRel.equals("")) { //$NON-NLS-1$ |
| bHasRel = true; |
| break; |
| } |
| } |
| } |
| if (!bHasRel) { // alert about identifying document location |
| addCheckerProblem("C_68.0"); //$NON-NLS-1$ |
| } |
| |
| // //alert to use the Resource Description Framework (RDF) in the header |
| // result.add(new CheckerProblem("68.1")); |
| } |
| |
| private void item_69() { |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = bodyEl; |
| |
| while (curNode != null) { |
| // TODO have means to skip over? |
| boolean isArtStr = false; |
| if (isLeafBlockEle(curNode) |
| && isAsciiArtString(getTextAltDescendant(curNode))) { |
| addCheckerProblem("C_69.0", (Element) curNode); //$NON-NLS-1$ |
| isArtStr = true; |
| } |
| |
| if (!isArtStr && curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| |
| } |
| } |
| } |
| |
| private void item_73() { |
| Vector<Node> nodeV = new Vector<Node>(); |
| for (int i = 0; i < object_elements.length; i++) { |
| Element el = object_elements[i]; |
| String str = el.getAttribute("data"); //$NON-NLS-1$ |
| str = getFileExtension(str); |
| if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$ |
| || str.equalsIgnoreCase("ppt") //$NON-NLS-1$ |
| || isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| nodeV.add(el); |
| } |
| } |
| for (int i = 0; i < aWithHref_hrefs.length; i++) { |
| Element el = aWithHref_elements[i]; |
| String str = aWithHref_hrefs[i]; |
| str = getFileExtension(str); |
| if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$ |
| || str.equalsIgnoreCase("ppt") //$NON-NLS-1$ |
| || isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| nodeV.add(el); |
| } |
| } |
| |
| for (Element applet : edu.getAppletElements()) { |
| NodeList parNl = applet.getElementsByTagName("param"); //$NON-NLS-1$ |
| int parLength = parNl.getLength(); |
| for (int j = 0; j < parLength; j++) { |
| String str = ((Element) parNl.item(j)).getAttribute("value"); //$NON-NLS-1$ |
| str = getFileExtension(str); |
| if (str.equalsIgnoreCase("pdf") //$NON-NLS-1$ |
| || str.equalsIgnoreCase("ppt") //$NON-NLS-1$ |
| || isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| nodeV.add(applet); |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_73.0", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private void item_74() { |
| boolean hasHeader = false; |
| NodeList nl = target.getElementsByTagName("meta"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$ |
| if (strMeta.equalsIgnoreCase("refresh") //$NON-NLS-1$ |
| || strMeta.equalsIgnoreCase("location")) { //$NON-NLS-1$ |
| addCheckerProblem("C_74.1", el); //$NON-NLS-1$ |
| hasHeader = true; |
| } |
| } |
| // timeout process alert |
| if (!hasHeader) { |
| addCheckerProblem("C_74.0"); //$NON-NLS-1$ |
| } |
| |
| if (formList.size() > 0) { |
| addCheckerProblem("C_74.2"); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_75() { |
| for (int i = 0; i < bottom_data_tables.length; i++) { |
| Element tNode = bottom_data_tables[i]; |
| NodeList nl = tNode.getElementsByTagName("th"); //$NON-NLS-1$ |
| if (nl.getLength() == 0) { |
| // table header check |
| addCheckerProblem("C_75.0", tNode); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void item_76() { |
| Vector<Node> rowColTables = new Vector<Node>(); |
| |
| for (Element el : dataTableList) { |
| int thNum = 0; |
| boolean hasScopeAxis = false; |
| for (Element tr : edu.getElementsList(el, "tr")) { //$NON-NLS-1$ |
| List<Element> cells = edu.getElementsList(tr, "th"); //$NON-NLS-1$ |
| if (cells.size() > 0) |
| thNum++; |
| cells.addAll(edu.getElementsList(tr, "td")); |
| for (Element cell : cells) { |
| if (getAttribute(cell, "scope") != null |
| || getAttribute(cell, "axis") != null) { |
| hasScopeAxis = true; |
| break; |
| } |
| } |
| if (hasScopeAxis) |
| break; |
| } |
| if (!hasScopeAxis && thNum > 1) { |
| // TODO? alert: two or more rows or columns as table header |
| addCheckerProblem("C_76.0", el); //$NON-NLS-1$ |
| } |
| |
| // TODO? need to check structure (axis, scope) |
| |
| if (hasRowColSpan(el)) { |
| // the table has rowspan and/or colspan |
| rowColTables.add(el); |
| } |
| } |
| |
| if (rowColTables.size() > 0) |
| addCheckerProblem("C_76.1", "", rowColTables); |
| } |
| |
| /** |
| * Returns true if the specified table has any td or th elements which has |
| * rowspan and/or colspan attribute. for new JIS. |
| * |
| * @param table |
| * a leaf table element |
| * @return a boolean value that indicates if the specified table has any td |
| * or th elements which has rowspan and/or colspan attribute. |
| */ |
| private boolean hasRowColSpan(Element table) { |
| boolean bHasRowColSpan = false; |
| |
| for (Element cell : edu.getElementsList(table, "th", "td")) { |
| String rowspan = getAttribute(cell, "rowspan"); |
| String colspan = getAttribute(cell, "colspan"); |
| if ((rowspan != null && Integer.parseInt(rowspan) > 1) |
| || (colspan != null && Integer.parseInt(colspan) > 1)) { |
| bHasRowColSpan = true; |
| break; |
| } |
| } |
| |
| return bHasRowColSpan; |
| } |
| |
| private void item_77() { |
| Element el = null; |
| boolean bHasCSS = false; |
| NodeList nl = target.getElementsByTagName("link"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| el = (Element) nl.item(i); |
| String strRel = el.getAttribute("rel"); //$NON-NLS-1$ |
| if (strRel != null && strRel.equalsIgnoreCase("stylesheet")) { //$NON-NLS-1$ |
| bHasCSS = true; |
| break; |
| } |
| } |
| if (bHasCSS) { // alert about style sheet |
| addCheckerProblem("C_77.0", //$NON-NLS-1$ |
| // AdditionalDescription.getString("CheckEngine._(link_tag_for_include_stylesheet)_492"), |
| // //$NON-NLS-1$ |
| el); |
| // multi? |
| } |
| |
| nl = target.getElementsByTagName("style"); //$NON-NLS-1$ |
| if (nl.getLength() > 0) { |
| addCheckerProblem("C_77.1", "", nl); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| Vector<Node> nodeV = new Vector<Node>(); |
| |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = bodyEl; |
| while (curNode != null) { |
| if (curNode.getNodeType() == Node.ELEMENT_NODE) { |
| el = (Element) curNode; |
| String strAlt = el.getAttribute("style"); //$NON-NLS-1$ |
| if (!strAlt.equals("")) { //$NON-NLS-1$ |
| // alert about style |
| nodeV.add(el); |
| } |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_77.2", "", nodeV); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| @SuppressWarnings("nls") |
| private void item_78() { |
| Vector<Node> textInputs = new Vector<Node>(); |
| NodeList nl = target.getElementsByTagName("input"); |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| if (!el.hasAttribute("type")) |
| continue; |
| String strType = el.getAttribute("type"); |
| if (strType.equalsIgnoreCase("text") |
| || strType.equalsIgnoreCase("textbox") |
| || strType.equals("")) { |
| textInputs.add(el); |
| } |
| } |
| |
| nl = target.getElementsByTagName("html:text"); |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| textInputs.add((Element) nl.item(i)); |
| } |
| if (textInputs.size() > 0) |
| addCheckerProblem("C_78.2", null, textInputs); |
| } |
| |
| /** |
| * Checks labels and titles for form controls |
| */ |
| private void item_79() { |
| if (labelList == null) |
| labelList = edu.getElementsList(target, "label"); //$NON-NLS-1$ |
| Vector<Node> noTitleControls = new Vector<Node>(); |
| Vector<Node> noLabelControls = new Vector<Node>(); |
| Vector<Node> implicitLabelControls = new Vector<Node>(); |
| for (Element form : formList) { //$NON-NLS-1$ |
| // checks for each form element |
| for (Element el : getFormControl(form)) { |
| // checks for each input controls |
| TitleCheckResult res = item_79_title(el); |
| if (res == TitleCheckResult.NO_TITLE) |
| noTitleControls.add(el); |
| item_79_label(el, res, noLabelControls, implicitLabelControls); |
| } |
| } |
| if (noTitleControls.size() > 0) |
| addCheckerProblem("C_79.6", "", noTitleControls); |
| if (noLabelControls.size() > 0) |
| addCheckerProblem("C_79.0", "", noLabelControls); |
| if (implicitLabelControls.size() > 0) |
| addCheckerProblem("C_79.2", "", implicitLabelControls); |
| } |
| |
| private void item_79_label(Element ctrl, TitleCheckResult res, |
| Vector<Node> noLabelControls, Vector<Node> implicitLabelControls) { |
| String elType = getFormControlType(ctrl); |
| Element l; |
| if ((l = hasImplicitLabel(ctrl)) != null) { |
| implicitLabelControls.add(l); |
| // addCheckerProblem("C_79.2", l); |
| return; |
| } |
| if (!isLabelable(elType)) { |
| return; |
| } |
| |
| String strid = ctrl.getAttribute("id"); //$NON-NLS-1$ |
| boolean bHasLabel = this.hasLabel(ctrl); |
| boolean bHasTitle = this.hasTitle(ctrl); |
| |
| if (!bHasLabel && !(res == TitleCheckResult.G167)) { |
| noLabelControls.add(ctrl); |
| // addCheckerProblem("C_79.0", ctrl); //$NON-NLS-1$ |
| } else { |
| // TODO highlight the label as well |
| if (!hasProperLabel(ctrl)) { |
| // in case of TYPE was removed by IE |
| addCheckerProblem( |
| "C_79.1", //$NON-NLS-1$ |
| " (input type: " + (elType.equals("") ? "text" : elType) + ")", //$NON-NLS-1$ //$NON-NLS-2$ |
| ctrl); |
| } else { |
| // H44 OK |
| addCheckerProblem("C_79.5", ctrl); //$NON-NLS-1$ |
| |
| } |
| } |
| } |
| |
| /** |
| * If a control passes check, it returns true. |
| * |
| * @param ctrl |
| * @return |
| */ |
| private TitleCheckResult item_79_title(Element ctrl) { |
| if (hasTitle(ctrl)) { |
| addCheckerProblem("C_79.4", ctrl.getAttribute(ATTR_TITLE), ctrl); |
| return TitleCheckResult.OK; |
| } else { |
| if (isLabelable(getFormControlType(ctrl)) && hasLabel(ctrl)) |
| return TitleCheckResult.OK; |
| else { // no title? |
| if (check_G167(ctrl)) |
| return TitleCheckResult.G167; |
| else |
| return TitleCheckResult.NO_TITLE; |
| } |
| } |
| } |
| |
| /** |
| * Looks for an adjacent button to a text. If such text field is found, this |
| * method returns true, otherwise false. |
| * |
| * @param ctrl |
| * a form control element |
| */ |
| private boolean check_G167(Element ctrl) { |
| if (HtmlTagUtil.isTextControl(ctrl)) { |
| // looks for next control |
| Element next = findNextElementNode(ctrl); |
| if (next == null || !isButtonControl(next)) { |
| return false; |
| } else { |
| Vector<Node> ctrls = new Vector<Node>(); |
| ctrls.add(ctrl); |
| ctrls.add(next); |
| addCheckerProblem("C_79.7", null, ctrls); |
| return true; |
| } |
| } else if (HtmlTagUtil.isButtonControl(ctrl)) { |
| // does not occur |
| return false; |
| } else |
| return false; |
| } |
| |
| /** |
| * Finds most close element node that comes after the given element. |
| * |
| * @param el |
| * @return the next element node if any. returns null if no such element is |
| * found. |
| */ |
| private Element findNextElementNode(Element el) { |
| Node current = el; |
| while ((current = current.getNextSibling()) != null) { |
| short t = current.getNodeType(); |
| if (current.getNodeType() == Node.TEXT_NODE) { |
| if (!isBlankString(current.getNodeValue())) |
| return null; |
| } else if (current.getNodeType() == Node.ELEMENT_NODE) |
| break; |
| else { |
| // skips other node types (CDATA?) |
| // CDATA section treated as comment node |
| ; |
| } |
| } |
| return (Element) current; |
| } |
| |
| /** |
| * Checks whether any label attribute exists in controls temporally |
| * implemented as separated method. For new JIS |
| */ |
| /* |
| * private void item_79_label() { NodeList nl = |
| * target.getElementsByTagName("form"); //$NON-NLS-1$ int length = |
| * nl.getLength(); NodeList labelNl = target.getElementsByTagName("label"); |
| * //$NON-NLS-1$ // checks for each <form> element for (int i = 0; i < |
| * length; i++) { Element fEl = (Element) nl.item(i); Vector<Element> |
| * fcVector = getFormControl(fEl); int labelLen = labelNl.getLength(); // |
| * checks for each input controls for (int j = 0; j < fcVector.size(); j++) |
| * { Element el = fcVector.get(j); boolean bTitle = this.hasTitle(el); if |
| * (!bTitle) { // no title for a form control System.out.println("C_79.6"); |
| * addCheckerProblem("C_79.6", el); //$NON-NLS-1$ } } } } |
| */ |
| |
| private void item_80() { |
| // NodeList bodyNl = target.getElementsByTagName("body"); |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| Stack<Node> stack = new Stack<Node>(); |
| Node curNode = bodyEl; |
| while (curNode != null) { |
| if (curNode.getNodeType() == Node.ELEMENT_NODE) { |
| Element el = (Element) curNode; |
| String strAlt = el.getAttribute(ATTR_ALT); |
| if (strAlt != null && strAlt.length() > 150) { |
| // alt text length check |
| addCheckerProblem("C_80.0", el); //$NON-NLS-1$ |
| } |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| } |
| } |
| |
| private void item_85() { |
| boolean bHasBgsound = false; |
| NodeList nl = target.getElementsByTagName("head"); //$NON-NLS-1$ |
| Element targetE = null; |
| for (int i = 0; i < nl.getLength(); i++) { |
| NodeList bgNl = ((Element) nl.item(i)) |
| .getElementsByTagName("bgsound"); //$NON-NLS-1$ |
| if (bgNl.getLength() > 0) { |
| bHasBgsound = true; |
| targetE = (Element) bgNl.item(0); |
| break; |
| } |
| } |
| if (bHasBgsound) { |
| addCheckerProblem("C_85.0", targetE); //$NON-NLS-1$ |
| } |
| } |
| |
| private void item_86() { |
| boolean bHasMulti = false; |
| for (int i = 0; i < object_elements.length; i++) { |
| Element el = object_elements[i]; |
| String str = el.getAttribute("data"); //$NON-NLS-1$ |
| str = getFileExtension(str); |
| if (isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| bHasMulti = true; |
| break; |
| } |
| } |
| |
| if (!bHasMulti) { |
| for (Element applet : edu.getAppletElements()) { |
| NodeList parNl = applet.getElementsByTagName("param"); //$NON-NLS-1$ |
| int parLength = parNl.getLength(); |
| for (int j = 0; j < parLength; j++) { |
| String str = ((Element) parNl.item(j)) |
| .getAttribute("value"); //$NON-NLS-1$ |
| str = getFileExtension(str); |
| if (isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| bHasMulti = true; |
| break; |
| } |
| } |
| if (bHasMulti) { |
| break; |
| } |
| } |
| } |
| |
| if (!bHasMulti) { |
| for (int i = 0; i < aWithHref_hrefs.length; i++) { |
| // Element el = aWithHref_elements[i]; |
| String str = aWithHref_hrefs[i]; |
| str = getFileExtension(str); |
| if (isAudioFileExt(str) || isMultimediaFileExt(str)) { |
| bHasMulti = true; |
| break; |
| } |
| } |
| } |
| |
| if (bHasMulti) { |
| addCheckerProblem("C_86.0"); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| @SuppressWarnings("nls") |
| private void item_88() { |
| String charset = ""; |
| NodeList nl = target.getElementsByTagName("meta"); |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| if (el.hasAttribute("http-equiv") && el.hasAttribute("content")) { //$NON-NLS-1$ |
| String strMeta = el.getAttribute("http-equiv"); //$NON-NLS-1$ |
| String strCon = el.getAttribute("content"); |
| if (strMeta != null && strMeta.equalsIgnoreCase("Content-Type") |
| && strCon != null) { |
| int index = strCon.toLowerCase().indexOf("text/html"); |
| if (index >= 0) { |
| strCon = strCon.substring(index + 9); |
| index = strCon.indexOf(";"); |
| if (index >= 0) { |
| strCon = strCon.substring(index + 1); |
| index = strCon.toLowerCase().indexOf("charset"); |
| if (index >= 0) { |
| strCon = strCon.substring(index + 7); |
| index = strCon.indexOf("="); |
| if (index >= 0) { |
| charset = strCon.substring(index + 1); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // System.out.println("charset: " + charset); |
| if (charset.length() == 0) { |
| result.add(new ProblemItemImpl("C_88.0")); //$NON-NLS-1$ |
| } else { |
| // check coding (EUC-JP, Shift_JIS, UTF-8...) |
| // addCheckerProblem("C_88.1", charset); //$NON-NLS-1$ |
| } |
| } |
| |
| @SuppressWarnings("nls") |
| private void item_89() { |
| |
| if (body_elements.length == 1 |
| && target.getElementsByTagName("frameset").getLength() == 0) { |
| Node curNode = body_elements[0].getFirstChild(); |
| StringBuffer strBuf = new StringBuffer(512); |
| Stack<Node> stack = new Stack<Node>(); |
| while (curNode != null && strBuf.length() < valid_total_text_len) { |
| if (curNode.getNodeType() == Node.TEXT_NODE) { |
| // &#nbsp; (160) |
| strBuf.append(curNode.getNodeValue() |
| .replaceAll(String.valueOf((char) 160), "").trim()); |
| } else if (curNode.getNodeType() == Node.ELEMENT_NODE) { |
| Element tmpE = (Element) curNode; |
| |
| // need to check element name |
| |
| if (tmpE.hasAttribute(ATTR_ALT)) { |
| strBuf.append(tmpE |
| .getAttribute(ATTR_ALT) |
| .replaceAll(String.valueOf((char) 160), "").trim()); //$NON-NLS-1$ |
| } |
| if (tmpE.hasAttribute(ATTR_TITLE)) { |
| strBuf.append(tmpE.getAttribute(ATTR_TITLE) |
| .replaceAll(String.valueOf((char) 160), "") |
| .trim()); |
| } |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| } |
| if (strBuf.length() == 0) { |
| addCheckerProblem("C_89.0"); |
| } else if (strBuf.length() < valid_total_text_len) { |
| if (img_elements.length > 0) { |
| addCheckerProblem("C_89.1"); |
| } else { |
| addCheckerProblem("C_89.2"); |
| } |
| } |
| } |
| |
| } |
| |
| private void item_90() { |
| // TODO move to styleCheck |
| |
| Set<Element> styleElementList = styleElementMap.keySet(); |
| for (Element e : styleElementList) { |
| String style = styleElementMap.get(e); |
| if (style != null) { |
| if (BEFORE_PATTERN.matcher(style).matches()) { |
| addCheckerProblem("C_90.0", "", e); |
| } |
| if (AFTER_PATTERN.matcher(style).matches()) { |
| addCheckerProblem("C_90.1", "", e); |
| } |
| } |
| } |
| |
| Set<IStyleSheet> keys = styleSheetsMap.keySet(); |
| for (IStyleSheet ss : keys) { |
| if (ss.getHref().length() > 0) { // avoid duplication |
| String style = styleSheetsMap.get(ss); |
| if (BEFORE_PATTERN.matcher(style).matches()) |
| addCheckerProblem("C_90.0", "(" + ss.getHref() + ")"); |
| if (AFTER_PATTERN.matcher(style).matches()) |
| addCheckerProblem("C_90.1", "(" + ss.getHref() + ")"); |
| } |
| } |
| } |
| |
| /** |
| * ALT text check for image buttons, area elements. |
| */ |
| // For new JIS |
| private void item_300() { |
| for (Element button : edu.getImageButtons()) { |
| String alt = getAttribute(button, "alt"); |
| if (alt == null) |
| ; // B_1 error |
| else { |
| TextCheckResult result = checker.checkAlt(alt); |
| if (!TextCheckResult.OK.equals(result)) { |
| if (TextCheckResult.SPACE_SEPARATED.equals(result) |
| || TextCheckResult.SPACE_SEPARATED_JP |
| .equals(result)) |
| addCheckerProblem("C_300.3", alt, button); |
| else if (result.equals(TextCheckResult.NULL) |
| || result.equals(TextCheckResult.BLANK)) |
| addCheckerProblem("C_300.4", alt, button); |
| else |
| addCheckerProblem("C_300.0", alt, button); |
| } |
| } |
| } |
| for (Element button : edu.getTextButtons()) { |
| String value = getAttribute(button, "value"); |
| if (value == null) |
| ; // ??? error |
| else { |
| TextCheckResult result = checker.checkAlt(value); |
| if (!TextCheckResult.OK.equals(result)) { |
| // addCheckerProblem("C_300.0", alt, button); |
| } |
| } |
| } |
| for (Element area : edu.getAreaElements()) { |
| String alt = getAttribute(area, "alt"); |
| if (alt == null) { |
| ; // B_2 error |
| } else { |
| Set<String> ngWord = new TreeSet<String>(); |
| ngWord.add("area"); |
| TextCheckResult result = checker.checkAlt(alt, ngWord); |
| if (result.equals(TextCheckResult.OK)) { |
| ; |
| } else if (result.equals(TextCheckResult.SPACE_SEPARATED) |
| || result.equals(TextCheckResult.SPACE_SEPARATED_JP)) { |
| ; |
| } else if (!result.equals(TextCheckResult.BLANK) |
| || area.hasAttribute("href")) { |
| |
| Element map = (Element) area.getParentNode(); |
| for (Element image : HtmlTagUtil.getImgElementsFromMap( |
| target, map)) { |
| int id = document2IdMap.get(image); |
| |
| IProblemItem tmpP = addCheckerProblem("C_300.1", alt, |
| area); |
| tmpP.setHighlightTargetIds(new HighlightTargetId(id, id)); |
| edu.appendErrorIcon(tmpP, area); |
| } |
| } |
| } |
| } |
| for (Element applet : edu.getAppletElements()) { |
| String alt = getAttribute(applet, "alt"); |
| if (alt == null) |
| ; // B_2 error |
| else { |
| Set<String> ngWord = new TreeSet<String>(); |
| ngWord.add("applet"); |
| ngWord.add("\u30a2\u30d7\u30ec\u30c3\u30c8"); // "applet" in |
| // Japanese |
| ngWord.add("\u30d7\u30ed\u30b0\u30e9\u30e0"); // "program" in |
| // Japanese |
| TextCheckResult result = checker.checkAlt(alt, ngWord); |
| if (!TextCheckResult.OK.equals(result)) { |
| addCheckerProblem("C_300.2", alt, applet); |
| } |
| } |
| } |
| } |
| |
| // moved into 600.18 |
| // // For new JIS |
| // @SuppressWarnings("nls") |
| // private void item_320() { |
| // addCheckerProblem("C_320.0"); |
| // } |
| |
| // For new JIS |
| private void item_331() { |
| Vector<Node> withoutScope = new Vector<Node>(); |
| Vector<Node> invalidScope = new Vector<Node>(); |
| for (Element table : dataTableList) { |
| // all data tables are leaf tables, so getElements() suffice. |
| for (Element th : edu.getElementsList(table, "th")) { |
| if (!th.hasAttribute("scope")) |
| withoutScope.add(th); |
| else if (!th.getAttribute("scope").matches( |
| "row(group)?|col(group)?")) |
| invalidScope.add(th); |
| } |
| } |
| if (withoutScope.size() > 0) |
| addCheckerProblem("C_331.0", "", withoutScope); |
| if (invalidScope.size() > 0) |
| addCheckerProblem("C_331.1", "", invalidScope); |
| } |
| |
| // For new JIS |
| private void item_332() { |
| for (Element table : dataTableList) { |
| List<Element> cells = edu.getElementsList(target, "th", "td"); |
| for (Element cell : cells) { |
| if (cell.hasAttribute("headers")) { |
| for (String id : cell.getAttribute("headers").split( |
| "[ \t]+")) { |
| Element referred = target.getElementById(id); |
| if (referred == null) { |
| addCheckerProblem("C_332.1", "(id=" + id + ")", |
| cell); |
| } else if (!referred.getTagName().toLowerCase() |
| .matches("td|th")) { |
| addCheckerProblem("C_332.2", referred.getTagName() |
| .toLowerCase(), cell); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_380() { |
| Vector<Node> noSubmitForms = new Vector<Node>(); |
| for (Element form : formList) { |
| boolean hasSubmit = false; |
| NodeList inputs = form.getElementsByTagName("input"); |
| for (int j = 0; j < inputs.getLength(); j++) { |
| Element input = (Element) inputs.item(j); |
| String typeS = input.getAttribute("type"); |
| if ("submit".equals(typeS) || "image".equals(typeS)) { |
| hasSubmit = true; |
| break; |
| } |
| } |
| if (!hasSubmit) { |
| NodeList buttons = form.getElementsByTagName("button"); |
| for (int j = 0; j < buttons.getLength(); j++) { |
| Element button = (Element) buttons.item(j); |
| String typeS = button.getAttribute("type"); |
| if ("submit".equals(typeS)) { |
| hasSubmit = true; |
| break; |
| } |
| } |
| } |
| if (!hasSubmit) |
| noSubmitForms.add(form); |
| } |
| if (noSubmitForms.size() > 0) |
| addCheckerProblem("C_380.0", null, noSubmitForms); |
| } |
| |
| @SuppressWarnings("nls") |
| private void formCheck() { |
| for (Element form : formList) { |
| if (form.getElementsByTagName("select").getLength() > 0) |
| addCheckerProblem("C_381.0", form); |
| } |
| |
| NodeList nl = null; |
| if ((nl = target.getElementsByTagName("form")).getLength() > 0) { //$NON-NLS-1$ |
| addCheckerProblem("C_382.0", "", nl); |
| addCheckerProblem("C_383.0", "", nl); |
| addCheckerProblem("C_387.0", "", nl); |
| addCheckerProblem("C_388.0", "", nl); |
| } |
| |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_384() { |
| if (formVwithText == null) |
| formVwithText = getFormsWithTextinput(); |
| if (formVwithText.size() > 0) |
| addCheckerProblem("C_384.0", "", formVwithText); //$NON-NLS-1$ //$NON-NLS-1$ |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_385() { |
| if (formVwithText == null) |
| formVwithText = getFormsWithTextinput(); |
| if (formVwithText.size() > 0) |
| addCheckerProblem("C_385.0", "", formVwithText); |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_386() { |
| if (formVwithText == null) |
| formVwithText = getFormsWithTextinput(); |
| if (formVwithText.size() > 0) |
| addCheckerProblem("C_386.0", "", formVwithText); |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_389() { |
| if (formVwithText == null) |
| formVwithText = getFormsWithTextinput(); |
| if (formVwithText.size() > 0) |
| addCheckerProblem("C_389.0", "", formVwithText); |
| } |
| |
| // For new JIS |
| @SuppressWarnings("nls") |
| private void item_422() { |
| List<Element> accesskeys = edu.getAccessKeyElements(); |
| Map<String, List<Element>> map = new HashMap<String, List<Element>>(); |
| for (Element element : accesskeys) { |
| String key = element.getAttribute("accesskey"); |
| if (!map.containsKey(key)) |
| map.put(key, new ArrayList<Element>()); |
| map.get(key).add(element); |
| } |
| for (String key : map.keySet()) { |
| if (map.get(key).size() > 1) { |
| addCheckerProblem("C_422.0", key, |
| new Vector<Node>(map.get(key))); |
| } |
| } |
| } |
| |
| private void item_423() { |
| List<Element> idElementList = edu.getElementsWithId(); |
| Map<String, List<Element>> map = new HashMap<String, List<Element>>(); |
| for (Element element : idElementList) { |
| String key = element.getAttribute("id"); |
| if (!map.containsKey(key)) { |
| map.put(key, new ArrayList<Element>()); |
| } |
| map.get(key).add(element); |
| } |
| for (String key : map.keySet()) { |
| if (map.get(key).size() > 1) { |
| addCheckerProblem("C_423.0", key, |
| new Vector<Node>(map.get(key))); |
| } |
| } |
| } |
| |
| /** |
| * Displays AA items |
| */ |
| private void always() { |
| |
| // language check |
| addCheckerProblem("C_19.0"); //$NON-NLS-1$ |
| |
| // Use the ABBR and ACRONYM elements alert |
| // check sequence of capital |
| addCheckerProblem("C_20.0"); //$NON-NLS-1$ |
| |
| // alert to use latest technology |
| addCheckerProblem("C_47.0"); //$NON-NLS-1$ |
| |
| // alert to group related elements |
| addCheckerProblem("C_55.0"); //$NON-NLS-1$ |
| |
| if (hasAwithHref) { |
| // link phrase alert |
| addCheckerProblem("C_56.1"); //$NON-NLS-1$ |
| |
| // TBD estimation |
| // alert to identify logical groups of links |
| addCheckerProblem("C_64.0"); //$NON-NLS-1$ |
| |
| addCheckerProblem("C_65.0"); //$NON-NLS-1$ |
| |
| addCheckerProblem("C_81.0"); //$NON-NLS-1$ |
| } |
| |
| // alert if there is a site map or... |
| addCheckerProblem("C_61.0"); //$NON-NLS-1$ |
| |
| // alert if there is a clear navigation structure |
| addCheckerProblem("C_62.0"); //$NON-NLS-1$ |
| |
| // TBD estimation |
| // alert if there are navigation bars for navigation structure |
| addCheckerProblem("C_63.0"); //$NON-NLS-1$ |
| |
| // alert if there is distinguishing information |
| addCheckerProblem("C_67.0"); //$NON-NLS-1$ |
| |
| // alert about language |
| addCheckerProblem("C_70.0"); //$NON-NLS-1$ |
| |
| // alert |
| addCheckerProblem("C_71.0"); //$NON-NLS-1$ |
| |
| // alert about consistant style |
| addCheckerProblem("C_72.0"); //$NON-NLS-1$ |
| |
| addCheckerProblem("C_82.0"); //$NON-NLS-1$ |
| addCheckerProblem("C_83.0"); //$NON-NLS-1$ |
| addCheckerProblem("C_84.0"); //$NON-NLS-1$ |
| |
| addCheckerProblem("C_87.0"); //$NON-NLS-1$ |
| |
| // moved into mediaCheck |
| // if (SHOW_ALWAYS || object_elements.length > 0 |
| // || embed_elements.length > 0 |
| // || edu.getAppletElements().size() > 0) { |
| // addCheckerProblem("C_500.0"); |
| // addCheckerProblem("C_500.1"); |
| // } |
| |
| addCheckerProblem("C_321.0"); |
| addCheckerProblem("C_322.0"); |
| |
| addCheckerProblem("C_421.0"); |
| addCheckerProblem("C_421.1", isXHTML ? "XHTML" : "HTML"); |
| |
| addCheckerProblem("C_500.11"); |
| addCheckerProblem("C_500.12"); |
| addCheckerProblem("C_500.2"); |
| addCheckerProblem("C_500.3"); |
| |
| // moved into 15 & 388 |
| // // TODO same as above |
| // if (SHOW_ALWAYS || headings.length > 0 |
| // || target.getElementsByTagName("label").getLength() > 0) |
| // addCheckerProblem("C_500.4"); |
| |
| addCheckerProblem("C_500.5"); |
| addCheckerProblem("C_500.6"); |
| addCheckerProblem("C_500.7"); |
| addCheckerProblem("C_500.8"); |
| addCheckerProblem("C_500.9"); |
| addCheckerProblem("C_500.10"); |
| |
| // addCheckerProblem("C_500.13"); |
| // addCheckerProblem("C_500.14"); |
| // addCheckerProblem("C_500.15"); |
| // addCheckerProblem("C_500.16"); |
| |
| addCheckerProblem("C_600.0"); |
| |
| //moved into mediaCheck |
| // addCheckerProblem("C_600.1"); |
| // addCheckerProblem("C_600.2"); |
| // addCheckerProblem("C_600.6"); |
| // addCheckerProblem("C_600.7"); |
| |
| addCheckerProblem("C_600.3"); |
| addCheckerProblem("C_600.4"); |
| addCheckerProblem("C_600.5"); |
| |
| |
| addCheckerProblem("C_600.8"); |
| addCheckerProblem("C_600.9"); |
| addCheckerProblem("C_600.10"); |
| addCheckerProblem("C_600.11"); |
| addCheckerProblem("C_600.12"); |
| addCheckerProblem("C_600.13"); |
| addCheckerProblem("C_600.14"); |
| addCheckerProblem("C_600.15"); |
| |
| // move into mediaCheck |
| // addCheckerProblem("C_600.16"); |
| |
| addCheckerProblem("C_600.17"); |
| addCheckerProblem("C_600.18"); |
| addCheckerProblem("C_600.19"); |
| } |
| |
| private void styleCheck() { |
| Set<Element> styleElementList = styleElementMap.keySet(); |
| for (Element e : styleElementList) { |
| String style = styleElementMap.get(e); |
| if (style != null) { |
| Set<String> colorSelector = new HashSet<String>(); |
| Set<String> bgcolorSelector = new HashSet<String>(); |
| Set<String> allcolorSelector = new HashSet<String>(); |
| Set<String> fixSelector = new HashSet<String>(); |
| |
| Matcher matcher = STYLEITEM.matcher(style); |
| while (matcher.find()) { |
| String group = matcher.group(); |
| boolean color = COLOR.matcher(group).find(); |
| boolean bgColor = BGCOLOR.matcher(group).find() |
| || BGCOLOR2.matcher(group).find(); |
| |
| boolean fix = FIXSIZE_PATTERN.matcher(group).find(); |
| |
| // System.out.println(color + "/" + bgColor + "\t" + group); |
| if (color || bgColor) { |
| String selector = getSelector(group); |
| if (color && !bgColor) { |
| colorSelector.add(selector); |
| } else if (!color && bgColor) { |
| bgcolorSelector.add(selector); |
| } else { |
| allcolorSelector.add(selector); |
| } |
| } |
| if (fix) { |
| fixSelector.add(getSelector(group)); |
| } |
| } |
| if (colorSelector.size() > 0) { |
| addCheckerProblem("C_500.17", "(" + Messages.StyleElement |
| + ", " + Messages.Selector + "=" |
| + getSelectors(colorSelector) + ")", e); |
| } |
| if (bgcolorSelector.size() > 0) { |
| addCheckerProblem("C_500.18", "(" + Messages.StyleElement |
| + ", " + Messages.Selector + "=" |
| + getSelectors(bgcolorSelector) + ")", e); |
| } |
| if (allcolorSelector.size() > 0) { |
| addCheckerProblem("C_8.0", "(" + Messages.StyleElement |
| + ", " + Messages.Selector + "=" |
| + getSelectors(allcolorSelector) + ")", e); |
| } |
| if (fixSelector.size() > 0) { |
| addCheckerProblem("C_500.19", "(" + Messages.StyleElement |
| + ", " + Messages.Selector + "=" |
| + getSelectors(fixSelector) + ")", e); |
| } |
| |
| } |
| } |
| |
| Set<IStyleSheet> keys = styleSheetsMap.keySet(); |
| for (IStyleSheet ss : keys) { |
| if (ss.getHref().length() > 0) { // avoid duplication |
| String style = styleSheetsMap.get(ss); |
| Set<String> colorSelector = new HashSet<String>(); |
| Set<String> bgcolorSelector = new HashSet<String>(); |
| Set<String> allcolorSelector = new HashSet<String>(); |
| Set<String> fixSelector = new HashSet<String>(); |
| |
| Matcher matcher = STYLEITEM.matcher(style); |
| while (matcher.find()) { |
| String group = matcher.group(); |
| boolean color = COLOR.matcher(group).find(); |
| boolean bgColor = BGCOLOR.matcher(group).find() |
| || BGCOLOR2.matcher(group).find(); |
| boolean fix = FIXSIZE_PATTERN.matcher(group).find(); |
| |
| if (color || bgColor) { |
| String selector = getSelector(group); |
| if (color && !bgColor) { |
| colorSelector.add(selector); |
| } else if (!color && bgColor) { |
| bgcolorSelector.add(selector); |
| } else { |
| allcolorSelector.add(selector); |
| } |
| } |
| if (fix) { |
| fixSelector.add(getSelector(group)); |
| } |
| |
| // System.out.println(color + "/" + bgColor + "\t" + group); |
| |
| } |
| if (colorSelector.size() > 0) { |
| addCheckerProblem("C_500.17", "(" + ss.getHref() + ", " |
| + Messages.Selector + "=" |
| + getSelectors(colorSelector) + ")"); |
| } |
| if (bgcolorSelector.size() > 0) { |
| addCheckerProblem("C_500.18", "(" + ss.getHref() + ", " |
| + Messages.Selector + "=" |
| + getSelectors(bgcolorSelector) + ")"); |
| } |
| if (allcolorSelector.size() > 0) { |
| addCheckerProblem("C_8.0", "(" + ss.getHref() + ", " |
| + Messages.Selector + "=" |
| + getSelectors(allcolorSelector) + ")"); |
| } |
| if (fixSelector.size() > 0) { |
| addCheckerProblem("C_500.19", "(" + ss.getHref() + ", " |
| + Messages.Selector + "=" |
| + getSelectors(fixSelector) + ")"); |
| } |
| |
| } |
| } |
| |
| for (Element e : elementsWithStyleList) { |
| String style = e.getAttribute("style"); |
| |
| boolean color = COLOR_ATTR.matcher(style).matches(); // need to use |
| // matches() |
| boolean bgColor = BGCOLOR_ATTR.matcher(style).find() |
| || BGCOLOR2_ATTR.matcher(style).find(); |
| |
| boolean fix = FIXSIZE_PATTERN_ATTR.matcher(style).find(); |
| // System.out.println(color + "/" + bgColor + "\t" + style); |
| |
| if (color || bgColor) { |
| if (color && !bgColor) { |
| addCheckerProblem("C_500.17", "(" + style + ")", e); |
| } else if (!color && bgColor) { |
| addCheckerProblem("C_500.18", "(" + style + ")", e); |
| } else { |
| addCheckerProblem("C_8.0", "(" + style + ")", e); |
| } |
| } |
| |
| if (fix) { |
| addCheckerProblem("C_500.20", "(" + style + ")", e); // error |
| } |
| } |
| |
| //Special check for body element |
| //http://www.w3.org/TR/html4/sgml/loosedtd.html#bodycolors |
| |
| if (body_elements.length > 0) { |
| Element bodyEl = body_elements[0]; |
| boolean color = bodyEl.getAttribute("text").length() > 0; |
| boolean bgColor = bodyEl.getAttribute("bgcolor").length() > 0; |
| |
| boolean linkColor = (bodyEl.getAttribute("link").length() > 0 |
| || bodyEl.getAttribute("vlink").length() > 0 || bodyEl |
| .getAttribute("alink").length() > 0); |
| |
| if (color && !bgColor) { |
| addCheckerProblem("C_500.17", "", bodyEl); |
| } else if (!color && bgColor) { |
| addCheckerProblem("C_500.18", "", bodyEl); |
| } |
| |
| if(linkColor){ |
| addCheckerProblem("C_500.18", "(link)", bodyEl); |
| } |
| |
| } |
| } |
| |
| private String getSelector(String targetString) { |
| Pattern SELECTOR = Pattern.compile("^.*\\{", Pattern.MULTILINE); |
| Matcher matcher = SELECTOR.matcher(targetString); |
| if (matcher.find()) { |
| String tmpS = matcher.group(); |
| return (tmpS.substring(0, tmpS.lastIndexOf("{")).trim()); |
| } |
| return ""; |
| } |
| |
| private String getSelectors(Set<String> target) { |
| StringBuffer tmpSB = new StringBuffer(); |
| for (String tmpS : target) { |
| tmpSB.append("\"" + tmpS + "\", "); |
| } |
| if (tmpSB.length() > 2) { |
| tmpSB.setLength(tmpSB.length() - 2); |
| } |
| return (tmpSB.toString()); |
| } |
| |
| // Mobile Web Evaluation (from here) |
| private void mobile_1() { |
| // TODO implement evaluation |
| //addCheckerProblem("M_1"); //$NON-NLS-1$ |
| } |
| |
| // Mobile Web Evaluation (end here) |
| |
| private void validateHtml() { |
| if (body_elements.length > 1) { |
| addCheckerProblem("C_1000.0"); //$NON-NLS-1$ |
| } else if (body_elements.length == 0 |
| && !docTypeS.toLowerCase().contains("frameset")) { |
| addCheckerProblem("C_1000.4"); //$NON-NLS-1$ |
| } |
| } |
| |
| // @SuppressWarnings("nls") |
| // private void checkDomDifference() { |
| // |
| // if (edu.getInvisibleElementCount() > 0) { |
| // addCheckerProblem("C_201.0"); |
| // } |
| // String[] invisibleLinkStrings = edu.getInvisibleLinkStrings(); |
| // for (int i = 0; i < invisibleLinkStrings.length; i++) { |
| // if (invisibleLinkStrings[i].trim().length() > 0) { |
| // addCheckerProblem("C_201.1", " (href=" |
| // + invisibleLinkStrings[i] + ")"); |
| // } |
| // } |
| // |
| // Set<String> notExistSet = edu.getNotExistHrefSet(); |
| // for (String href : notExistSet) { |
| // addCheckerProblem("C_200.0", " (href=" + href + ")"); |
| // } |
| // if (notExistSet.size() > 10) { |
| // addCheckerProblem("C_200.1"); |
| // } |
| // |
| // } |
| |
| private void checkAbsoluteSize(String strName) { |
| NodeList nl = target.getElementsByTagName(strName); |
| int length = nl.getLength(); |
| Vector<Node> nodeV = new Vector<Node>(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strWidth = el.getAttribute("width"); //$NON-NLS-1$ |
| String strHeight = el.getAttribute("height"); //$NON-NLS-1$ |
| if ((strWidth != null && !strWidth.equals("") //$NON-NLS-1$ |
| && strWidth.indexOf("%") == -1) //$NON-NLS-1$ |
| || (strHeight != null && !strHeight.equals("") //$NON-NLS-1$ |
| && strHeight.indexOf("%") == -1)) { //$NON-NLS-1$ |
| // absolute width or height |
| nodeV.add(el); |
| } |
| } |
| if (nodeV.size() > 0) { |
| addCheckerProblem("C_13.0", "", nodeV);//$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private boolean hasOpenWndEvent(Element element, String[] targetAttrs) { |
| |
| // need to check open(...) (can use without 'window.') |
| |
| for (int i = 0; i < targetAttrs.length; i++) { |
| String str = element.getAttribute(targetAttrs[i]); |
| if (str.toLowerCase().indexOf(WINDOW_OPEN) >= 0) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private void checkObsoluteEle(String problemId, String strEle) { |
| NodeList nl = target.getElementsByTagName(strEle); |
| if (nl.getLength() > 0) { |
| addCheckerProblem(problemId, strEle, nl); |
| } |
| } |
| |
| private String getFormControlType(Element el) { |
| String strName = el.getNodeName().toLowerCase(); |
| if (strName.equals("input")) { //$NON-NLS-1$ |
| return el.getAttribute("type").toLowerCase(); //$NON-NLS-1$ |
| } else { |
| return strName; |
| } |
| } |
| |
| /** |
| * Returns radio buttons and check boxes contained in the specified fieldset |
| * element. |
| * |
| * @param fieldset |
| * @return A <code>List</code> of <code>Element</code>s. |
| */ |
| private List<Element> getRadioAndCheck(Element fieldset) { |
| List<Element> returns = new ArrayList<Element>(); |
| List<Element> inputs = edu.getElementsList(fieldset, "input"); |
| for (Element e : inputs) { |
| if (e.getAttribute("type").toLowerCase().matches("radio|checkbox")) |
| returns.add(e); |
| } |
| return returns; |
| } |
| |
| /** |
| * Obtains input controls in the given form element. |
| * |
| * @param formEl |
| * @return a Vector of controls |
| */ |
| private List<Element> getFormControl(Element formEl) { |
| List<Element> fcVector = new ArrayList<Element>(); |
| NodeList nl = formEl.getElementsByTagName("input"); //$NON-NLS-1$ |
| int length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| String strType = el.getAttribute("type").toLowerCase(); //$NON-NLS-1$ |
| if (strType.equals("") // default is text? //$NON-NLS-1$ |
| || strType.equals("text") //$NON-NLS-1$ |
| || strType.equals("textarea") //$NON-NLS-1$ |
| || strType.equals("radio") //$NON-NLS-1$ |
| || strType.equals("checkbox") //$NON-NLS-1$ |
| || strType.equals("file") //$NON-NLS-1$ // For new JIS |
| || strType.equals("password")) { //$NON-NLS-1$ |
| fcVector.add(el); |
| } |
| |
| } |
| |
| nl = formEl.getElementsByTagName("textarea"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| fcVector.add(el); |
| } |
| |
| nl = formEl.getElementsByTagName("select"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| fcVector.add(el); |
| } |
| |
| nl = formEl.getElementsByTagName("html:text"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| fcVector.add(el); |
| } |
| |
| nl = formEl.getElementsByTagName("html:radio"); //$NON-NLS-1$ |
| length = nl.getLength(); |
| for (int i = 0; i < length; i++) { |
| Element el = (Element) nl.item(i); |
| fcVector.add(el); |
| } |
| |
| return fcVector; |
| } |
| |
| private int getFormControlNum(Element formEl) { |
| int iNum = 0; |
| NodeList nl = formEl.getElementsByTagName("input"); //$NON-NLS-1$ |
| iNum += nl.getLength(); |
| nl = formEl.getElementsByTagName("select"); //$NON-NLS-1$ |
| iNum += nl.getLength(); |
| nl = formEl.getElementsByTagName("textarea"); //$NON-NLS-1$ |
| iNum += nl.getLength(); |
| nl = formEl.getElementsByTagName("html:text"); //$NON-NLS-1$ |
| iNum += nl.getLength(); |
| nl = formEl.getElementsByTagName("html:radio"); //$NON-NLS-1$ |
| iNum += nl.getLength(); |
| return iNum; |
| } |
| |
| /** |
| * Returns true if the specified form element has any text input controls. |
| * For new JIS. |
| * |
| * @param form |
| * @return |
| */ |
| private boolean hasTextFormControl(Element form) { |
| int iNum = 0; |
| for (Element e : edu.getElementsList(form, "input")) { //$NON-NLS-1$ |
| if (e.getAttribute("type").toLowerCase() |
| .matches("|text(area)?|password")) |
| iNum++; |
| } |
| iNum += form.getElementsByTagName("textarea").getLength(); //$NON-NLS-1$ |
| iNum += form.getElementsByTagName("html:text").getLength(); //$NON-NLS-1$ |
| return (iNum > 0); |
| } |
| |
| private Vector<Node> getFormsWithTextinput() { |
| Vector<Node> forms = new Vector<Node>(); |
| for (Element form : formList) { |
| if (hasTextFormControl(form)) |
| forms.add(form); |
| } |
| return forms; |
| } |
| |
| /** |
| * Returns true if the given control type is usually used with label |
| * elements. |
| * |
| * @return |
| */ |
| private boolean isLabelable(String type) { |
| return type.matches("|text(area)?|checkbox|radio|file|password|select"); |
| } |
| |
| /** |
| * For new JIS |
| * |
| * @param el |
| * @param labels |
| * @return |
| */ |
| private boolean hasLabel(Element el) { |
| String strid = el.getAttribute("id"); //$NON-NLS-1$ |
| |
| if (strid.equals("")) //$NON-NLS-1$ |
| return false; // no id |
| |
| for (Element e : labelList) { |
| String strFor = e.getAttribute("for"); //$NON-NLS-1$ |
| if (strFor != null && strFor.equalsIgnoreCase(strid)) { |
| return true; // label found |
| } |
| } |
| return false; // no label found |
| } |
| |
| /** |
| * Detects use of implicit labels. If an implicit label is used, the label |
| * element is returned. Otherwise, null is returned. For new JIS. |
| * |
| * @param el |
| * @return label element when an implicit label is used. |
| */ |
| private Element hasImplicitLabel(Element el) { |
| // TODO to be refined so that it looks up in ascendant, not in a parent |
| Node n = el.getParentNode(); |
| if (!(n instanceof Element)) |
| return null; |
| Element e = (Element) n; |
| if (e.getTagName().toLowerCase().equals("label")) |
| return e; |
| else |
| return null; |
| } |
| |
| /** |
| * Stub function, to be refined. For new JIS |
| * |
| * @param title |
| * @return |
| */ |
| private boolean isInappropriateTitle(String title) { |
| return title.matches("(?i).*untitled.*"); |
| } |
| |
| /** |
| * Checks if the specified form control has a properly located label. |
| * |
| * @param el |
| * @return |
| */ |
| private boolean hasProperLabel(Element el) { |
| |
| // need to consider position |
| boolean bRadioCheckbox = getFormControlType(el).matches( |
| "radio|checkbox"); //$NON-NLS-1$ |
| |
| Node node = el; |
| if (bRadioCheckbox) { |
| while (node.getNextSibling() == null) { |
| if (node.getNodeName().equalsIgnoreCase("body")) { //$NON-NLS-1$ |
| return false; |
| } |
| node = node.getParentNode(); |
| } |
| if (node.getNextSibling().getNodeType() != Node.ELEMENT_NODE) |
| return false; |
| Element nextEl = (Element) node.getNextSibling(); |
| Element labelEl; |
| if (nextEl.getNodeName().equalsIgnoreCase("label")) { //$NON-NLS-1$ |
| labelEl = nextEl; |
| } else { |
| NodeList nl = nextEl.getElementsByTagName("label"); //$NON-NLS-1$ |
| if (nl.getLength() == 0) { |
| return false; |
| } else { |
| labelEl = (Element) nl.item(0); |
| } |
| } |
| |
| String strId = el.getAttribute("id"); //$NON-NLS-1$ |
| String strFor = labelEl.getAttribute("for"); //$NON-NLS-1$ |
| if (!strId.equals(strFor)) { |
| return false; |
| } else { |
| if (getTextAltDescendant(nextEl).trim().indexOf( |
| getTextAltDescendant(labelEl).trim()) == 0) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| } else { |
| while (node.getPreviousSibling() == null) { |
| if (node.getNodeName().equalsIgnoreCase("body")) { //$NON-NLS-1$ |
| return false; |
| } |
| node = node.getParentNode(); |
| } |
| if (node.getPreviousSibling().getNodeType() != Node.ELEMENT_NODE) |
| return false; |
| Element preEl = (Element) node.getPreviousSibling(); |
| Element labelEl; |
| if (preEl.getNodeName().equalsIgnoreCase("label")) { //$NON-NLS-1$ |
| labelEl = preEl; |
| } else { |
| NodeList nl = preEl.getElementsByTagName("label"); //$NON-NLS-1$ |
| if (nl.getLength() == 0) { |
| return false; |
| } else { |
| labelEl = (Element) nl.item(nl.getLength() - 1); |
| } |
| } |
| String strId = el.getAttribute("id"); //$NON-NLS-1$ |
| String strFor = labelEl.getAttribute("for"); //$NON-NLS-1$ |
| if (!strId.equals(strFor)) { |
| return false; |
| } else { |
| String strWhole = getTextAltDescendant(preEl).trim(); |
| String strLabel = getTextAltDescendant(labelEl).trim(); |
| if (strWhole.indexOf(strLabel) == strWhole.length() |
| - strLabel.length()) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| } |
| } |
| |
| private boolean isAsciiArtString(String str) { |
| |
| if (str == null) { |
| return false; |
| } |
| |
| // int realTotal = str.length(); |
| String[] tmpS = str.split("\\p{Space}"); //$NON-NLS-1$ |
| int num = 0; |
| int total = 0; |
| |
| for (int j = 0; j < tmpS.length; j++) { |
| String target = tmpS[j]; |
| int strLength = target.length(); |
| total += strLength; |
| |
| target = target.replaceAll("\\p{Punct}", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| num += strLength - target.length(); |
| |
| strLength = target.length(); |
| for (int i = 0; i < strLength; i++) { |
| if (artCharSet.contains(target.substring(i, i + 1))) { |
| num++; |
| } |
| } |
| |
| } |
| if (total == 0) |
| total = 1; |
| if (num > 30 && (double) num / total > 0.8) |
| return true; |
| else if (num > 30 && checker.isAsciiArtString(str)) // another AA |
| // checking routine |
| return true; |
| else |
| return false; |
| } |
| |
| private boolean isNormalImage(Element imgEl) { |
| String strWidth = imgEl.getAttribute("width"); //$NON-NLS-1$ |
| String strHeight = imgEl.getAttribute("height"); //$NON-NLS-1$ |
| int iWidth = 0, iHeight = 0; |
| try { |
| if (strWidth != null) |
| iWidth = Integer.valueOf(strWidth).intValue(); |
| if (strHeight != null) |
| iHeight = Integer.valueOf(strHeight).intValue(); |
| |
| } catch (NumberFormatException e) { |
| iWidth = 100; |
| iHeight = 100; |
| } |
| // ignore small image according to bobby |
| if (iWidth < 50 || iHeight < 50) { |
| int iBig, iSmall; |
| if (iWidth > iHeight) { |
| iBig = iWidth; |
| iSmall = iHeight; |
| } else { |
| iBig = iHeight; |
| iSmall = iWidth; |
| } |
| if (iBig < 50) { |
| return false; |
| } else if ((double) iSmall / iBig < 0.2) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| // TODO check |
| private boolean isHtmlFile(String strFile) { |
| int iPos = strFile.lastIndexOf("."); //$NON-NLS-1$ |
| if (iPos > 0) { |
| String strExt = strFile.substring(iPos + 1).toLowerCase(); |
| if (strExt.equals("html") //$NON-NLS-1$ |
| || strExt.equals("htm") //$NON-NLS-1$ |
| || strExt.equals("jsp") //$NON-NLS-1$ |
| || strExt.equals("php") //$NON-NLS-1$ |
| || strExt.equals("shtml")) //$NON-NLS-1$ |
| return true; |
| else if (strFile.toLowerCase().indexOf(".cgi") > 0) //$NON-NLS-1$ |
| return true; |
| } |
| return false; |
| } |
| |
| private boolean isAudioFileExt(String strFileExt) { |
| for (int i = 0; i < AUDIO_FILE_EXTENSION.length; i++) { |
| if (strFileExt.equalsIgnoreCase(AUDIO_FILE_EXTENSION[i])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isMultimediaFileExt(String strFileExt) { |
| for (int i = 0; i < MULTIMEDIA_FILE_EXTENSION.length; i++) { |
| if (strFileExt.equalsIgnoreCase(MULTIMEDIA_FILE_EXTENSION[i])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isLeafBlockEle(Node node) { |
| String str = node.getNodeName().toLowerCase(); |
| if (!blockEleSet.contains(str)) { |
| return false; |
| } |
| if (!node.hasChildNodes()) { |
| return true; |
| } |
| Node curNode = node.getFirstChild(); |
| Stack<Node> stack = new Stack<Node>(); |
| while (curNode != null) { |
| str = curNode.getNodeName().toLowerCase(); |
| if (blockEleSet.contains(str)) { |
| return false; |
| } |
| |
| if (curNode.hasChildNodes()) { |
| stack.push(curNode); |
| curNode = curNode.getFirstChild(); |
| } else if (curNode.getNextSibling() != null) { |
| curNode = curNode.getNextSibling(); |
| } else { |
| curNode = null; |
| while ((curNode == null) && (stack.size() > 0)) { |
| curNode = stack.pop(); |
| curNode = curNode.getNextSibling(); |
| } |
| } |
| |
| } |
| return true; |
| } |
| |
| private int getWordCount(String str) { |
| StringTokenizer st = new StringTokenizer(str, |
| " \t\n\r\f,.[]()<>!?:/\"\u3001\u3002\u300c\u300d\u30fb\u3008\u3009\u3000"); //$NON-NLS-1$ |
| return st.countTokens(); |
| |
| } |
| |
| private String getFileExtension(String strName) { |
| int iPos = strName.lastIndexOf("."); //$NON-NLS-1$ |
| if (iPos > 0) { |
| return strName.substring(iPos + 1); |
| } |
| return ""; //$NON-NLS-1$ |
| } |
| |
| private boolean isElementVisible(Element el) { |
| // TODO function stub // For new JIS |
| return true; |
| } |
| |
| // For new JIS |
| private boolean isButton(Element el) { |
| return (el.getTagName().toLowerCase().equals("input") && (el |
| .getAttribute("type").toLowerCase().equals("submit") || el |
| .getAttribute("type").equals("image"))) |
| || (el.getTagName().toLowerCase().equals("button") && el |
| .getAttribute("type").toLowerCase().equals("submit")); |
| } |
| |
| private List<Element> getDirectDescendantElements(Element element, |
| String tagName) { |
| return getDirectDescendantElements(element, tagName, element |
| .getTagName().toLowerCase()); |
| } |
| |
| /** |
| * Utility function that returns a List array instead of a NodeList array. |
| * |
| * @param el |
| * @param tagName |
| * @return list of elements with given tag name that are direct descendants |
| * of the node. |
| */ |
| private List<Element> getDirectDescendantElements(Element element, |
| String tagName, String excluded) { |
| List<Element> nodes = new ArrayList<Element>(); |
| NodeList children = element.getChildNodes(); |
| for (int i = 0; i < children.getLength(); i++) { |
| Node n = children.item(i); |
| if (n.getNodeType() == Node.ELEMENT_NODE) { |
| Element e = (Element) n; |
| if (e.getTagName().toLowerCase().equals(tagName)) |
| nodes.add(e); |
| else if (!e.getTagName().toLowerCase().equals(excluded)) |
| nodes.addAll(getDirectDescendantElements(e, tagName, |
| excluded)); |
| } |
| } |
| return nodes; |
| } |
| |
| /** |
| * Returns string for the attribute value if it is specified in the HTML |
| * source, otherwise this method returns null. Note that hasAttribute() |
| * badly works when the default value of the attribute is specified in the |
| * HTML spec. Using this method and comparing the result to null works well. |
| * |
| * @param e |
| * @param attr |
| * @return attribute value string or null. |
| */ |
| // TODO consider <tag attr>, not <tag attr="value">. |
| private String getAttribute(Element e, String attr) { |
| Attr att = e.getAttributeNode(attr); |
| if (att == null) |
| return null; |
| return att.getValue(); |
| } |
| |
| /** |
| * For new JIS. used in item_23(). Returns the most nearest ascendant table |
| * element. If such table is not found (case of invalid use of caption |
| * elements), this method returns null. |
| */ |
| private Element nearestTable(Element el) { |
| Node e = el; |
| while ((e instanceof Element) |
| && !((Element) e).getTagName().toLowerCase().equals("table")) { |
| e = ((Element) e).getParentNode(); |
| } |
| return (e instanceof Element) ? (Element) e : null; |
| } |
| |
| /** |
| * For new JIS. Currently it is not used. It will be used from item_3(). |
| * |
| * @param alt |
| * @param longdescUri |
| * @return |
| */ |
| private boolean longdescLongerThanALT(String alt, String longdescUri) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| /** |
| * For new JIS. Currently it is not used. It will be used from item_3(). |
| * |
| * @param url |
| * @return |
| */ |
| private boolean isExistingUrl(String url) { |
| url = url.trim(); |
| if (url.length() == 0) |
| return false; |
| else |
| return true; // check routine comes here |
| } |
| |
| // For new JIS |
| /** |
| * @param table |
| */ |
| private boolean hasDuplicatedCaptionAndSummary(Element table) { |
| String strSum = table.getAttribute("summary").trim(); //$NON-NLS-1$ |
| NodeList capNl = table.getElementsByTagName("caption"); //$NON-NLS-1$ |
| for (int i = 0; i < capNl.getLength(); i++) { |
| if (strSum.equals(HtmlTagUtil.getTextDescendant(capNl.item(i)) |
| .trim())) |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * For new JIS |
| * |
| * @param table |
| */ |
| private boolean hasSummary(Element table) { |
| String strSum = table.getAttribute("summary"); //$NON-NLS-1$ |
| return strSum.length() > 0; |
| } |
| |
| private boolean hasCaption(Element table) { |
| return table.getElementsByTagName("caption").getLength() > 0; //$NON-NLS-1$ |
| } |
| |
| /** |
| * For new JIS |
| * |
| * @param el |
| * @param labels |
| * @return |
| */ |
| private boolean hasTitle(Element el) { |
| return el.hasAttribute("title"); //$NON-NLS-1$ |
| } |
| |
| private boolean hasBlankTitle(Element el) { |
| if (!el.hasAttribute("title")) |
| return true; |
| String title = el.getAttribute("title"); |
| return title.matches("^[\\s\u3000]*$"); |
| } |
| |
| // For new JIS |
| private boolean isEmptyString(String s) { |
| return (s == null || s.length() == 0); |
| } |
| } |