001: /*
002: * @(#)CheckAttribsImpl.java 1.11 2000/08/16
003: *
004: */
005:
006: package org.w3c.tidy;
007:
008: /**
009: *
010: * Check HTML attributes implementation
011: *
012: * (c) 1998-2000 (W3C) MIT, INRIA, Keio University
013: * See Tidy.java for the copyright notice.
014: * Derived from <a href="http://www.w3.org/People/Raggett/tidy">
015: * HTML Tidy Release 4 Aug 2000</a>
016: *
017: * @author Dave Raggett <dsr@w3.org>
018: * @author Andy Quick <ac.quick@sympatico.ca> (translation to Java)
019: * @version 1.0, 1999/05/22
020: * @version 1.0.1, 1999/05/29
021: * @version 1.1, 1999/06/18 Java Bean
022: * @version 1.2, 1999/07/10 Tidy Release 7 Jul 1999
023: * @version 1.3, 1999/07/30 Tidy Release 26 Jul 1999
024: * @version 1.4, 1999/09/04 DOM support
025: * @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
026: * @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
027: * @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
028: * @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
029: * @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
030: * @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
031: * @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
032: */
033:
034: public class CheckAttribsImpl {
035:
036: public static class CheckHTML implements CheckAttribs {
037:
038: public void check(Lexer lexer, Node node) {
039: AttVal attval;
040: Attribute attribute;
041:
042: node.checkUniqueAttributes(lexer);
043:
044: for (attval = node.attributes; attval != null; attval = attval.next) {
045: attribute = attval.checkAttribute(lexer, node);
046:
047: if (attribute == AttributeTable.attrXmlns)
048: lexer.isvoyager = true;
049: }
050: }
051:
052: };
053:
054: public static class CheckSCRIPT implements CheckAttribs {
055:
056: public void check(Lexer lexer, Node node) {
057: Attribute attribute;
058: AttVal lang, type;
059:
060: node.checkUniqueAttributes(lexer);
061:
062: lang = node.getAttrByName("language");
063: type = node.getAttrByName("type");
064:
065: if (type == null) {
066: Report.attrError(lexer, node, "type",
067: Report.MISSING_ATTRIBUTE);
068:
069: /* check for javascript */
070:
071: if (lang != null) {
072: String str = lang.value;
073: if (str.length() > 10)
074: str = str.substring(0, 10);
075: if ((Lexer.wstrcasecmp(str, "javascript") == 0)
076: || (Lexer.wstrcasecmp(str, "jscript") == 0)) {
077: node.addAttribute("type", "text/javascript");
078: }
079: } else
080: node.addAttribute("type", "text/javascript");
081: }
082: }
083:
084: };
085:
086: public static class CheckTABLE implements CheckAttribs {
087:
088: public void check(Lexer lexer, Node node) {
089: AttVal attval;
090: Attribute attribute;
091: boolean hasSummary = false;
092:
093: node.checkUniqueAttributes(lexer);
094:
095: for (attval = node.attributes; attval != null; attval = attval.next) {
096: attribute = attval.checkAttribute(lexer, node);
097:
098: if (attribute == AttributeTable.attrSummary)
099: hasSummary = true;
100: }
101:
102: /* suppress warning for missing summary for HTML 2.0 and HTML 3.2 */
103: if (!hasSummary && lexer.doctype != Dict.VERS_HTML20
104: && lexer.doctype != Dict.VERS_HTML32) {
105: lexer.badAccess |= Report.MISSING_SUMMARY;
106: Report.attrError(lexer, node, "summary",
107: Report.MISSING_ATTRIBUTE);
108: }
109:
110: /* convert <table border> to <table border="1"> */
111: if (lexer.configuration.XmlOut) {
112: attval = node.getAttrByName("border");
113: if (attval != null) {
114: if (attval.value == null)
115: attval.value = "1";
116: }
117: }
118: }
119:
120: };
121:
122: public static class CheckCaption implements CheckAttribs {
123:
124: public void check(Lexer lexer, Node node) {
125: AttVal attval;
126: String value = null;
127:
128: node.checkUniqueAttributes(lexer);
129:
130: for (attval = node.attributes; attval != null; attval = attval.next) {
131: if (Lexer.wstrcasecmp(attval.attribute, "align") == 0) {
132: value = attval.value;
133: break;
134: }
135: }
136:
137: if (value != null) {
138: if (Lexer.wstrcasecmp(value, "left") == 0
139: || Lexer.wstrcasecmp(value, "right") == 0)
140: lexer.versions &= (short) (Dict.VERS_HTML40_LOOSE | Dict.VERS_FRAMES);
141: else if (Lexer.wstrcasecmp(value, "top") == 0
142: || Lexer.wstrcasecmp(value, "bottom") == 0)
143: lexer.versions &= Dict.VERS_FROM32;
144: else
145: Report.attrError(lexer, node, value,
146: Report.BAD_ATTRIBUTE_VALUE);
147: }
148: }
149:
150: };
151:
152: public static class CheckHR implements CheckAttribs {
153:
154: public void check(Lexer lexer, Node node) {
155: if (node.getAttrByName("src") != null)
156: Report.attrError(lexer, node, "src",
157: Report.PROPRIETARY_ATTR_VALUE);
158: }
159: };
160:
161: public static class CheckIMG implements CheckAttribs {
162:
163: public void check(Lexer lexer, Node node) {
164: AttVal attval;
165: Attribute attribute;
166: boolean hasAlt = false;
167: boolean hasSrc = false;
168: boolean hasUseMap = false;
169: boolean hasIsMap = false;
170: boolean hasDataFld = false;
171:
172: node.checkUniqueAttributes(lexer);
173:
174: for (attval = node.attributes; attval != null; attval = attval.next) {
175: attribute = attval.checkAttribute(lexer, node);
176:
177: if (attribute == AttributeTable.attrAlt)
178: hasAlt = true;
179: else if (attribute == AttributeTable.attrSrc)
180: hasSrc = true;
181: else if (attribute == AttributeTable.attrUsemap)
182: hasUseMap = true;
183: else if (attribute == AttributeTable.attrIsmap)
184: hasIsMap = true;
185: else if (attribute == AttributeTable.attrDatafld)
186: hasDataFld = true;
187: else if (attribute == AttributeTable.attrWidth
188: || attribute == AttributeTable.attrHeight)
189: lexer.versions &= ~Dict.VERS_HTML20;
190: }
191:
192: if (!hasAlt) {
193: lexer.badAccess |= Report.MISSING_IMAGE_ALT;
194: Report.attrError(lexer, node, "alt",
195: Report.MISSING_ATTRIBUTE);
196: if (lexer.configuration.altText != null)
197: node.addAttribute("alt",
198: lexer.configuration.altText);
199: }
200:
201: if (!hasSrc && !hasDataFld)
202: Report.attrError(lexer, node, "src",
203: Report.MISSING_ATTRIBUTE);
204:
205: if (hasIsMap && !hasUseMap)
206: Report.attrError(lexer, node, "ismap",
207: Report.MISSING_IMAGEMAP);
208: }
209:
210: };
211:
212: public static class CheckAREA implements CheckAttribs {
213:
214: public void check(Lexer lexer, Node node) {
215: AttVal attval;
216: Attribute attribute;
217: boolean hasAlt = false;
218: boolean hasHref = false;
219:
220: node.checkUniqueAttributes(lexer);
221:
222: for (attval = node.attributes; attval != null; attval = attval.next) {
223: attribute = attval.checkAttribute(lexer, node);
224:
225: if (attribute == AttributeTable.attrAlt)
226: hasAlt = true;
227: else if (attribute == AttributeTable.attrHref)
228: hasHref = true;
229: }
230:
231: if (!hasAlt) {
232: lexer.badAccess |= Report.MISSING_LINK_ALT;
233: Report.attrError(lexer, node, "alt",
234: Report.MISSING_ATTRIBUTE);
235: }
236: if (!hasHref)
237: Report.attrError(lexer, node, "href",
238: Report.MISSING_ATTRIBUTE);
239: }
240:
241: };
242:
243: public static class CheckAnchor implements CheckAttribs {
244:
245: public void check(Lexer lexer, Node node) {
246: node.checkUniqueAttributes(lexer);
247:
248: lexer.fixId(node);
249: }
250: };
251:
252: public static class CheckMap implements CheckAttribs {
253:
254: public void check(Lexer lexer, Node node) {
255: node.checkUniqueAttributes(lexer);
256:
257: lexer.fixId(node);
258: }
259: }
260:
261: public static class CheckSTYLE implements CheckAttribs {
262:
263: public void check(Lexer lexer, Node node) {
264: AttVal type = node.getAttrByName("type");
265:
266: node.checkUniqueAttributes(lexer);
267:
268: if (type == null) {
269: Report.attrError(lexer, node, "type",
270: Report.MISSING_ATTRIBUTE);
271:
272: node.addAttribute("type", "text/css");
273: }
274: }
275: }
276:
277: public static class CheckTableCell implements CheckAttribs {
278:
279: public void check(Lexer lexer, Node node) {
280: node.checkUniqueAttributes(lexer);
281:
282: /*
283: HTML4 strict doesn't allow mixed content for
284: elements with %block; as their content model
285: */
286: if (node.getAttrByName("width") != null
287: || node.getAttrByName("height") != null)
288: lexer.versions &= ~Dict.VERS_HTML40_STRICT;
289: }
290: }
291:
292: /* add missing type attribute when appropriate */
293: public static class CheckLINK implements CheckAttribs {
294:
295: public void check(Lexer lexer, Node node) {
296: AttVal rel = node.getAttrByName("rel");
297:
298: node.checkUniqueAttributes(lexer);
299:
300: if (rel != null && rel.value != null
301: && rel.value.equals("stylesheet")) {
302: AttVal type = node.getAttrByName("type");
303:
304: if (type == null) {
305: Report.attrError(lexer, node, "type",
306: Report.MISSING_ATTRIBUTE);
307:
308: node.addAttribute("type", "text/css");
309: }
310: }
311: }
312: }
313:
314: public static CheckAttribs getCheckHTML() {
315: return _checkHTML;
316: }
317:
318: public static CheckAttribs getCheckSCRIPT() {
319: return _checkSCRIPT;
320: }
321:
322: public static CheckAttribs getCheckTABLE() {
323: return _checkTABLE;
324: }
325:
326: public static CheckAttribs getCheckCaption() {
327: return _checkCaption;
328: }
329:
330: public static CheckAttribs getCheckIMG() {
331: return _checkIMG;
332: }
333:
334: public static CheckAttribs getCheckAREA() {
335: return _checkAREA;
336: }
337:
338: public static CheckAttribs getCheckAnchor() {
339: return _checkAnchor;
340: }
341:
342: public static CheckAttribs getCheckMap() {
343: return _checkMap;
344: }
345:
346: public static CheckAttribs getCheckSTYLE() {
347: return _checkStyle;
348: }
349:
350: public static CheckAttribs getCheckTableCell() {
351: return _checkTableCell;
352: }
353:
354: public static CheckAttribs getCheckLINK() {
355: return _checkLINK;
356: }
357:
358: public static CheckAttribs getCheckHR() {
359: return _checkHR;
360: }
361:
362: private static CheckAttribs _checkHTML = new CheckHTML();
363: private static CheckAttribs _checkSCRIPT = new CheckSCRIPT();
364: private static CheckAttribs _checkTABLE = new CheckTABLE();
365: private static CheckAttribs _checkCaption = new CheckCaption();
366: private static CheckAttribs _checkIMG = new CheckIMG();
367: private static CheckAttribs _checkAREA = new CheckAREA();
368: private static CheckAttribs _checkAnchor = new CheckAnchor();
369: private static CheckAttribs _checkMap = new CheckMap();
370: private static CheckAttribs _checkStyle = new CheckSTYLE();
371: private static CheckAttribs _checkTableCell = new CheckTableCell();
372: private static CheckAttribs _checkLINK = new CheckLINK();
373: private static CheckAttribs _checkHR = new CheckHR();
374:
375: }
|