Merge pull request #372 from htacg/attrdict_phase2
Attrdict phase2 - enforce strict tags and attributes
This commit is contained in:
commit
468cc02cf3
47
src/attrs.c
47
src/attrs.c
|
@ -479,11 +479,12 @@ uint TY_(NodeAttributeVersions)( Node* node, TidyAttrId id )
|
||||||
return VERS_UNKNOWN;
|
return VERS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns true if the element is a W3C defined element */
|
/* returns true if the element is a W3C defined element
|
||||||
/* but the element/attribute combination is not. We're */
|
* but the element/attribute combination is not. We're
|
||||||
/* only defining as "proprietary" items that are not in */
|
* only defining as "proprietary" items that are not in
|
||||||
/* the element's AttrVersion structure. */
|
* the element's AttrVersion structure.
|
||||||
static Bool AttributeIsProprietary(Node* node, AttVal* attval)
|
*/
|
||||||
|
Bool TY_(AttributeIsProprietary)(Node* node, AttVal* attval)
|
||||||
{
|
{
|
||||||
if (!node || !attval)
|
if (!node || !attval)
|
||||||
return no;
|
return no;
|
||||||
|
@ -500,6 +501,34 @@ static Bool AttributeIsProprietary(Node* node, AttVal* attval)
|
||||||
return yes;
|
return yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns true if the element is a W3C defined element
|
||||||
|
* but the element/attribute combination is not. We're
|
||||||
|
* considering it a mismatch if the document version
|
||||||
|
* does not allow the attribute as called out in its
|
||||||
|
* AttrVersion structure.
|
||||||
|
*/
|
||||||
|
Bool TY_(AttributeIsMismatched)(Node* node, AttVal* attval, TidyDocImpl* doc)
|
||||||
|
{
|
||||||
|
uint doctype;
|
||||||
|
|
||||||
|
if (!node || !attval)
|
||||||
|
return no;
|
||||||
|
|
||||||
|
if (!node->tag)
|
||||||
|
return no;
|
||||||
|
|
||||||
|
if (!(node->tag->versions & VERS_ALL))
|
||||||
|
return no;
|
||||||
|
|
||||||
|
doctype = doc->lexer->versionEmitted == 0 ? doc->lexer->doctype : doc->lexer->versionEmitted;
|
||||||
|
|
||||||
|
if (AttributeVersions(node, attval) & doctype)
|
||||||
|
return no;
|
||||||
|
|
||||||
|
return yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* used by CheckColor() */
|
/* used by CheckColor() */
|
||||||
struct _colors
|
struct _colors
|
||||||
{
|
{
|
||||||
|
@ -1358,14 +1387,6 @@ const Attribute* TY_(CheckAttribute)( TidyDocImpl* doc, Node *node, AttVal *attv
|
||||||
attribute->attrchk( doc, node, attval );
|
attribute->attrchk( doc, node, attval );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AttributeIsProprietary(node, attval))
|
|
||||||
{
|
|
||||||
TY_(ReportAttrError)(doc, node, attval, PROPRIETARY_ATTRIBUTE);
|
|
||||||
|
|
||||||
if (cfgBool(doc, TidyDropPropAttrs))
|
|
||||||
TY_(RemoveAttribute)( doc, node, attval );
|
|
||||||
}
|
|
||||||
|
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,10 @@ AttVal* TY_(AttrGetById)( Node* node, TidyAttrId id );
|
||||||
|
|
||||||
uint TY_(NodeAttributeVersions)( Node* node, TidyAttrId id );
|
uint TY_(NodeAttributeVersions)( Node* node, TidyAttrId id );
|
||||||
|
|
||||||
|
Bool TY_(AttributeIsProprietary)(Node* node, AttVal* attval);
|
||||||
|
Bool TY_(AttributeIsMismatched)(Node* node, AttVal* attval, TidyDocImpl* doc);
|
||||||
|
|
||||||
|
|
||||||
/* 0 == TidyAttr_UNKNOWN */
|
/* 0 == TidyAttr_UNKNOWN */
|
||||||
#define AttrId(av) ((av) && (av)->dict ? (av)->dict->id : TidyAttr_UNKNOWN)
|
#define AttrId(av) ((av) && (av)->dict ? (av)->dict->id : TidyAttr_UNKNOWN)
|
||||||
#define AttrIsId(av, atid) ((av) && (av)->dict && ((av)->dict->id == atid))
|
#define AttrIsId(av, atid) ((av) && (av)->dict && ((av)->dict->id == atid))
|
||||||
|
|
20
src/clean.c
20
src/clean.c
|
@ -1917,6 +1917,7 @@ void TY_(CleanWord2000)( TidyDocImpl* doc, Node *node)
|
||||||
/* used to a list from a sequence of bulletted p's */
|
/* used to a list from a sequence of bulletted p's */
|
||||||
Lexer* lexer = doc->lexer;
|
Lexer* lexer = doc->lexer;
|
||||||
Node* list = NULL;
|
Node* list = NULL;
|
||||||
|
AttVal *next_attr, *attval;
|
||||||
|
|
||||||
while ( node )
|
while ( node )
|
||||||
{
|
{
|
||||||
|
@ -1928,6 +1929,19 @@ void TY_(CleanWord2000)( TidyDocImpl* doc, Node *node)
|
||||||
!cfgBool(doc, TidyMakeBare) )
|
!cfgBool(doc, TidyMakeBare) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Output proprietary attributes to maintain errout compatability
|
||||||
|
* with traditional Tidy. This is a result of moving all of the
|
||||||
|
* proprietary checks to near the end of the cleanup process,
|
||||||
|
* meaning this result would not ordinarily be displayed.
|
||||||
|
*/
|
||||||
|
attval = node->attributes;
|
||||||
|
while ( attval ) {
|
||||||
|
next_attr = attval->next;
|
||||||
|
if ( strcmp(attval->attribute, "xmlns") != 0 )
|
||||||
|
TY_(ReportAttrError)(doc, node, attval, PROPRIETARY_ATTRIBUTE);
|
||||||
|
attval = next_attr;
|
||||||
|
}
|
||||||
|
|
||||||
TY_(FreeAttrs)( doc, node );
|
TY_(FreeAttrs)( doc, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2001,6 +2015,12 @@ void TY_(CleanWord2000)( TidyDocImpl* doc, Node *node)
|
||||||
/* discards <o:p> which encodes the paragraph mark */
|
/* discards <o:p> which encodes the paragraph mark */
|
||||||
if ( node->tag && TY_(tmbstrcmp)(node->tag->name,"o:p")==0)
|
if ( node->tag && TY_(tmbstrcmp)(node->tag->name,"o:p")==0)
|
||||||
{
|
{
|
||||||
|
/* Output proprietary elements to maintain errout compatability
|
||||||
|
* with traditional Tidy. This is a result of moving all of the
|
||||||
|
* proprietary checks to near the end of the cleanup process,
|
||||||
|
* meaning this result would not ordinarily be displayed.
|
||||||
|
*/
|
||||||
|
TY_(ReportError)(doc, NULL, node, PROPRIETARY_ELEMENT);
|
||||||
Node* next;
|
Node* next;
|
||||||
DiscardContainer( doc, node, &next );
|
DiscardContainer( doc, node, &next );
|
||||||
node = next;
|
node = next;
|
||||||
|
|
|
@ -322,7 +322,7 @@ static const TidyOptionImpl option_defs[] =
|
||||||
{ TidyAnchorAsName, MU, "anchor-as-name", BL, yes, ParseBool, boolPicks },
|
{ TidyAnchorAsName, MU, "anchor-as-name", BL, yes, ParseBool, boolPicks },
|
||||||
{ TidyPPrintTabs, PP, "indent-with-tabs", BL, no, ParseTabs, boolPicks }, /* 20150515 - Issue #108 */
|
{ TidyPPrintTabs, PP, "indent-with-tabs", BL, no, ParseTabs, boolPicks }, /* 20150515 - Issue #108 */
|
||||||
{ TidySkipNested, MU, "skip-nested", BL, yes, ParseBool, boolPicks }, /* 1642186 - Issue #65 */
|
{ TidySkipNested, MU, "skip-nested", BL, yes, ParseBool, boolPicks }, /* 1642186 - Issue #65 */
|
||||||
{ TidyStrictTagsAttr, MU, "strict-tags-attributes", BL, yes, ParseBool, boolPicks }, /* 20160209 - Issue #350 */
|
{ TidyStrictTagsAttr, MU, "strict-tags-attributes", BL, no, ParseBool, boolPicks }, /* 20160209 - Issue #350 */
|
||||||
{ N_TIDY_OPTIONS, XX, NULL, XY, 0, NULL, NULL }
|
{ N_TIDY_OPTIONS, XX, NULL, XY, 0, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,8 @@ static const tidyErrorFilterKeyItem tidyErrorFilterKeysStruct[] = {
|
||||||
{ "CANT_BE_NESTED", CANT_BE_NESTED },
|
{ "CANT_BE_NESTED", CANT_BE_NESTED },
|
||||||
{ "OBSOLETE_ELEMENT", OBSOLETE_ELEMENT },
|
{ "OBSOLETE_ELEMENT", OBSOLETE_ELEMENT },
|
||||||
{ "PROPRIETARY_ELEMENT", PROPRIETARY_ELEMENT },
|
{ "PROPRIETARY_ELEMENT", PROPRIETARY_ELEMENT },
|
||||||
|
{ "ELEMENT_VERS_MISMATCH_ERROR", ELEMENT_VERS_MISMATCH_ERROR },
|
||||||
|
{ "ELEMENT_VERS_MISMATCH_WARN", ELEMENT_VERS_MISMATCH_WARN },
|
||||||
{ "UNKNOWN_ELEMENT", UNKNOWN_ELEMENT },
|
{ "UNKNOWN_ELEMENT", UNKNOWN_ELEMENT },
|
||||||
{ "TRIM_EMPTY_ELEMENT", TRIM_EMPTY_ELEMENT },
|
{ "TRIM_EMPTY_ELEMENT", TRIM_EMPTY_ELEMENT },
|
||||||
{ "COERCE_TO_ENDTAG", COERCE_TO_ENDTAG },
|
{ "COERCE_TO_ENDTAG", COERCE_TO_ENDTAG },
|
||||||
|
@ -298,6 +300,8 @@ static const tidyErrorFilterKeyItem tidyErrorFilterKeysStruct[] = {
|
||||||
{ "BAD_ATTRIBUTE_VALUE", BAD_ATTRIBUTE_VALUE },
|
{ "BAD_ATTRIBUTE_VALUE", BAD_ATTRIBUTE_VALUE },
|
||||||
{ "UNEXPECTED_GT", UNEXPECTED_GT },
|
{ "UNEXPECTED_GT", UNEXPECTED_GT },
|
||||||
{ "PROPRIETARY_ATTRIBUTE", PROPRIETARY_ATTRIBUTE },
|
{ "PROPRIETARY_ATTRIBUTE", PROPRIETARY_ATTRIBUTE },
|
||||||
|
{ "MISMATCHED_ATTRIBUTE_ERROR", MISMATCHED_ATTRIBUTE_ERROR },
|
||||||
|
{ "MISMATCHED_ATTRIBUTE_WARN", MISMATCHED_ATTRIBUTE_WARN },
|
||||||
{ "PROPRIETARY_ATTR_VALUE", PROPRIETARY_ATTR_VALUE },
|
{ "PROPRIETARY_ATTR_VALUE", PROPRIETARY_ATTR_VALUE },
|
||||||
{ "REPEATED_ATTRIBUTE", REPEATED_ATTRIBUTE },
|
{ "REPEATED_ATTRIBUTE", REPEATED_ATTRIBUTE },
|
||||||
{ "MISSING_IMAGEMAP", MISSING_IMAGEMAP },
|
{ "MISSING_IMAGEMAP", MISSING_IMAGEMAP },
|
||||||
|
@ -322,8 +326,6 @@ static const tidyErrorFilterKeyItem tidyErrorFilterKeysStruct[] = {
|
||||||
{ "MISSING_ATTRIBUTE", MISSING_ATTRIBUTE },
|
{ "MISSING_ATTRIBUTE", MISSING_ATTRIBUTE },
|
||||||
{ "WHITE_IN_URI", WHITE_IN_URI },
|
{ "WHITE_IN_URI", WHITE_IN_URI },
|
||||||
{ "REMOVED_HTML5", REMOVED_HTML5 },
|
{ "REMOVED_HTML5", REMOVED_HTML5 },
|
||||||
{ "BAD_BODY_HTML5", BAD_BODY_HTML5 },
|
|
||||||
{ "BAD_ALIGN_HTML5", BAD_ALIGN_HTML5 },
|
|
||||||
{ "BAD_SUMMARY_HTML5", BAD_SUMMARY_HTML5 },
|
{ "BAD_SUMMARY_HTML5", BAD_SUMMARY_HTML5 },
|
||||||
{ "PREVIOUS_LOCATION", PREVIOUS_LOCATION },
|
{ "PREVIOUS_LOCATION", PREVIOUS_LOCATION },
|
||||||
{ "VENDOR_SPECIFIC_CHARS", VENDOR_SPECIFIC_CHARS },
|
{ "VENDOR_SPECIFIC_CHARS", VENDOR_SPECIFIC_CHARS },
|
||||||
|
|
|
@ -350,6 +350,8 @@ static languageDefinition language_en = { whichPluralForm_en, {
|
||||||
{ MISSING_ATTR_VALUE, 0, "%s attribute \"%s\" lacks value" }, /* Warning in CheckUrl, Error otherwise */
|
{ MISSING_ATTR_VALUE, 0, "%s attribute \"%s\" lacks value" }, /* Warning in CheckUrl, Error otherwise */
|
||||||
{ UNKNOWN_ATTRIBUTE, 0, "%s unknown attribute \"%s\"" }, /* Error */
|
{ UNKNOWN_ATTRIBUTE, 0, "%s unknown attribute \"%s\"" }, /* Error */
|
||||||
{ PROPRIETARY_ATTRIBUTE, 0, "%s proprietary attribute \"%s\"" }, /* Error */
|
{ PROPRIETARY_ATTRIBUTE, 0, "%s proprietary attribute \"%s\"" }, /* Error */
|
||||||
|
{ MISMATCHED_ATTRIBUTE_ERROR, 0, "%s attribute \"%s\" not allowed for %s" }, /* Error */
|
||||||
|
{ MISMATCHED_ATTRIBUTE_WARN, 0, "%s attribute \"%s\" not allowed for %s" }, /* Warning */
|
||||||
{ JOINING_ATTRIBUTE, 0, "%s joining values of repeated attribute \"%s\"" }, /* Error */
|
{ JOINING_ATTRIBUTE, 0, "%s joining values of repeated attribute \"%s\"" }, /* Error */
|
||||||
{ XML_ATTRIBUTE_VALUE, 0, "%s has XML attribute \"%s\"" }, /* Error (but deprecated) */
|
{ XML_ATTRIBUTE_VALUE, 0, "%s has XML attribute \"%s\"" }, /* Error (but deprecated) */
|
||||||
|
|
||||||
|
@ -392,8 +394,6 @@ static languageDefinition language_en = { whichPluralForm_en, {
|
||||||
{ OBSOLETE_ELEMENT, 0, "replacing obsolete element %s with %s" }, /* Warning */
|
{ OBSOLETE_ELEMENT, 0, "replacing obsolete element %s with %s" }, /* Warning */
|
||||||
{ COERCE_TO_ENDTAG_WARN, 0, "<%s> is probably intended as </%s>" }, /* Warning */
|
{ COERCE_TO_ENDTAG_WARN, 0, "<%s> is probably intended as </%s>" }, /* Warning */
|
||||||
{ REMOVED_HTML5, 0, "%s element removed from HTML5" }, /* Warning */
|
{ REMOVED_HTML5, 0, "%s element removed from HTML5" }, /* Warning */
|
||||||
{ BAD_BODY_HTML5, 0, "Found attribute on body that is obsolete in HTML5. Use CSS" }, /* Warning */
|
|
||||||
{ BAD_ALIGN_HTML5, 0, "The align attribute on the %s element is obsolete. Use CSS" }, /* Warning */
|
|
||||||
{ BAD_SUMMARY_HTML5, 0, "The summary attribute on the %s element is obsolete in HTML5" }, /* Warning */
|
{ BAD_SUMMARY_HTML5, 0, "The summary attribute on the %s element is obsolete in HTML5" }, /* Warning */
|
||||||
|
|
||||||
/* ReportNotice */
|
/* ReportNotice */
|
||||||
|
@ -415,6 +415,8 @@ static languageDefinition language_en = { whichPluralForm_en, {
|
||||||
{ INSERTING_TAG, 0, "inserting implicit <%s>" }, /* Error */
|
{ INSERTING_TAG, 0, "inserting implicit <%s>" }, /* Error */
|
||||||
{ CANT_BE_NESTED, 0, "%s can't be nested" }, /* Error */
|
{ CANT_BE_NESTED, 0, "%s can't be nested" }, /* Error */
|
||||||
{ PROPRIETARY_ELEMENT, 0, "%s is not approved by W3C" }, /* Error */
|
{ PROPRIETARY_ELEMENT, 0, "%s is not approved by W3C" }, /* Error */
|
||||||
|
{ ELEMENT_VERS_MISMATCH_ERROR, 0, "%s element not available in %s" }, /* Error */
|
||||||
|
{ ELEMENT_VERS_MISMATCH_WARN, 0, "%s element not available in %s" }, /* Warning */
|
||||||
{ ILLEGAL_NESTING, 0, "%s shouldn't be nested" }, /* Error */
|
{ ILLEGAL_NESTING, 0, "%s shouldn't be nested" }, /* Error */
|
||||||
{ NOFRAMES_CONTENT, 0, "%s not inside 'noframes' element" }, /* Error */
|
{ NOFRAMES_CONTENT, 0, "%s not inside 'noframes' element" }, /* Error */
|
||||||
{ UNEXPECTED_END_OF_FILE, 0, "unexpected end of file %s" }, /* Error */
|
{ UNEXPECTED_END_OF_FILE, 0, "unexpected end of file %s" }, /* Error */
|
||||||
|
@ -745,7 +747,9 @@ static languageDefinition language_en = { whichPluralForm_en, {
|
||||||
- The strings "Tidy" and "HTML Tidy" are the program name and must not be translated. */
|
- The strings "Tidy" and "HTML Tidy" are the program name and must not be translated. */
|
||||||
TidyDropPropAttrs, 0,
|
TidyDropPropAttrs, 0,
|
||||||
"This option specifies if Tidy should strip out proprietary attributes, "
|
"This option specifies if Tidy should strip out proprietary attributes, "
|
||||||
"such as Microsoft data binding attributes. "
|
"such as Microsoft data binding attributes. Additionally attributes "
|
||||||
|
"that aren't permitted in the output version of HTML will be dropped "
|
||||||
|
"if used with <code>strict-tags-attributes</code>. "
|
||||||
},
|
},
|
||||||
{/* Please use _only_ <code></code>, <em></em>, <strong></strong>, and <br/>.
|
{/* Please use _only_ <code></code>, <em></em>, <strong></strong>, and <br/>.
|
||||||
It's very important that <br/> be self-closing in this manner!
|
It's very important that <br/> be self-closing in this manner!
|
||||||
|
@ -1574,6 +1578,21 @@ static languageDefinition language_en = { whichPluralForm_en, {
|
||||||
"This option specifies that Tidy should skip nested tags when parsing "
|
"This option specifies that Tidy should skip nested tags when parsing "
|
||||||
"script and style data. "
|
"script and style data. "
|
||||||
},
|
},
|
||||||
|
{/* Please use _only_ <code></code>, <em></em>, <strong></strong>, and <br/>.
|
||||||
|
It's very important that <br/> be self-closing in this manner!
|
||||||
|
- The strings "Tidy" and "HTML Tidy" are the program name and must not be translated. */
|
||||||
|
TidyStrictTagsAttr, 0,
|
||||||
|
"This options ensures that tags and attributes are applicable for the "
|
||||||
|
"version of HTML that Tidy outputs. When set to <code>yes</code> (the "
|
||||||
|
"default) and the output document type is a strict doctype, then Tidy "
|
||||||
|
"will report errors. If the output document type is a loose or "
|
||||||
|
"transitional doctype, then Tidy will report warnings. "
|
||||||
|
"<br/>"
|
||||||
|
"Additionally if <code>drop-proprietary-attributes</code> is enabled, "
|
||||||
|
"then not applicable attributes will be dropped, too. "
|
||||||
|
"<br/>"
|
||||||
|
"When set to <code>no</code>, these checks are not performed. "
|
||||||
|
},
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
** Console Application
|
** Console Application
|
||||||
|
|
22
src/lexer.c
22
src/lexer.c
|
@ -2753,26 +2753,8 @@ static Node* GetTokenFromStream( TidyDocImpl* doc, GetTokenMode mode )
|
||||||
}
|
}
|
||||||
else if ( !cfgBool(doc, TidyXmlTags) )
|
else if ( !cfgBool(doc, TidyXmlTags) )
|
||||||
{
|
{
|
||||||
Node* curr = lexer->token;
|
TY_(ConstrainVersion)( doc, lexer->token->tag->versions );
|
||||||
TY_(ConstrainVersion)( doc, curr->tag->versions );
|
TY_(RepairDuplicateAttributes)( doc, lexer->token, no );
|
||||||
|
|
||||||
if ( curr->tag->versions & VERS_PROPRIETARY )
|
|
||||||
{
|
|
||||||
if ( !cfgBool(doc, TidyMakeClean) ||
|
|
||||||
( !nodeIsNOBR(curr) && !nodeIsWBR(curr) ) )
|
|
||||||
{
|
|
||||||
TY_(ReportError)(doc, NULL, curr, PROPRIETARY_ELEMENT );
|
|
||||||
|
|
||||||
if ( nodeIsLAYER(curr) )
|
|
||||||
doc->badLayout |= USING_LAYER;
|
|
||||||
else if ( nodeIsSPACER(curr) )
|
|
||||||
doc->badLayout |= USING_SPACER;
|
|
||||||
else if ( nodeIsNOBR(curr) )
|
|
||||||
doc->badLayout |= USING_NOBR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TY_(RepairDuplicateAttributes)( doc, curr, no );
|
|
||||||
} else
|
} else
|
||||||
TY_(RepairDuplicateAttributes)( doc, lexer->token, yes );
|
TY_(RepairDuplicateAttributes)( doc, lexer->token, yes );
|
||||||
#ifdef TIDY_STORE_ORIGINAL_TEXT
|
#ifdef TIDY_STORE_ORIGINAL_TEXT
|
||||||
|
|
|
@ -525,6 +525,8 @@ void TY_(ReportAttrError)(TidyDocImpl* doc, Node *node, AttVal *av, uint code)
|
||||||
char const *name = "NULL", *value = "NULL";
|
char const *name = "NULL", *value = "NULL";
|
||||||
char tagdesc[64];
|
char tagdesc[64];
|
||||||
ctmbstr fmt = tidyLocalizedString(code);
|
ctmbstr fmt = tidyLocalizedString(code);
|
||||||
|
uint version;
|
||||||
|
ctmbstr extra_string;
|
||||||
|
|
||||||
assert( fmt != NULL );
|
assert( fmt != NULL );
|
||||||
|
|
||||||
|
@ -549,6 +551,22 @@ void TY_(ReportAttrError)(TidyDocImpl* doc, Node *node, AttVal *av, uint code)
|
||||||
messageNode(doc, TidyWarning, code, node, fmt, tagdesc, name);
|
messageNode(doc, TidyWarning, code, node, fmt, tagdesc, name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MISMATCHED_ATTRIBUTE_WARN:
|
||||||
|
version = doc->lexer->versionEmitted == 0 ? doc->lexer->doctype : doc->lexer->versionEmitted;
|
||||||
|
extra_string = TY_(HTMLVersionNameFromCode)(version, 0);
|
||||||
|
if (!extra_string)
|
||||||
|
extra_string = tidyLocalizedString(STRING_HTML_PROPRIETARY);
|
||||||
|
messageNode(doc, TidyWarning, code, node, fmt, tagdesc, name, extra_string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MISMATCHED_ATTRIBUTE_ERROR:
|
||||||
|
version = doc->lexer->versionEmitted == 0 ? doc->lexer->doctype : doc->lexer->versionEmitted;
|
||||||
|
extra_string = TY_(HTMLVersionNameFromCode)(version, 0);
|
||||||
|
if (!extra_string)
|
||||||
|
extra_string = tidyLocalizedString(STRING_HTML_PROPRIETARY);
|
||||||
|
messageNode(doc, TidyError, code, node, fmt, tagdesc, name, extra_string);
|
||||||
|
break;
|
||||||
|
|
||||||
case BAD_ATTRIBUTE_VALUE:
|
case BAD_ATTRIBUTE_VALUE:
|
||||||
case BAD_ATTRIBUTE_VALUE_REPLACED:
|
case BAD_ATTRIBUTE_VALUE_REPLACED:
|
||||||
case INVALID_ATTRIBUTE:
|
case INVALID_ATTRIBUTE:
|
||||||
|
@ -665,8 +683,6 @@ void TY_(ReportWarning)(TidyDocImpl* doc, Node *element, Node *node, uint code)
|
||||||
|
|
||||||
case NESTED_EMPHASIS:
|
case NESTED_EMPHASIS:
|
||||||
case REMOVED_HTML5:
|
case REMOVED_HTML5:
|
||||||
case BAD_BODY_HTML5:
|
|
||||||
case BAD_ALIGN_HTML5:
|
|
||||||
case BAD_SUMMARY_HTML5:
|
case BAD_SUMMARY_HTML5:
|
||||||
messageNode(doc, TidyWarning, code, rpt, fmt, nodedesc);
|
messageNode(doc, TidyWarning, code, rpt, fmt, nodedesc);
|
||||||
break;
|
break;
|
||||||
|
@ -707,6 +723,8 @@ void TY_(ReportError)(TidyDocImpl* doc, Node *element, Node *node, uint code)
|
||||||
char elemdesc[ 256 ] = {0};
|
char elemdesc[ 256 ] = {0};
|
||||||
Node* rpt = ( element ? element : node );
|
Node* rpt = ( element ? element : node );
|
||||||
ctmbstr fmt = tidyLocalizedString(code);
|
ctmbstr fmt = tidyLocalizedString(code);
|
||||||
|
uint versionEmitted, declared, version;
|
||||||
|
ctmbstr extra_string = NULL;
|
||||||
|
|
||||||
assert( fmt != NULL );
|
assert( fmt != NULL );
|
||||||
|
|
||||||
|
@ -729,6 +747,26 @@ void TY_(ReportError)(TidyDocImpl* doc, Node *element, Node *node, uint code)
|
||||||
messageNode(doc, TidyWarning, code, node, fmt, nodedesc);
|
messageNode(doc, TidyWarning, code, node, fmt, nodedesc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_VERS_MISMATCH_WARN:
|
||||||
|
versionEmitted = doc->lexer->versionEmitted;
|
||||||
|
declared = doc->lexer->doctype;
|
||||||
|
version = versionEmitted == 0 ? declared : versionEmitted;
|
||||||
|
extra_string = TY_(HTMLVersionNameFromCode)(version, 0);
|
||||||
|
if (!extra_string)
|
||||||
|
extra_string = tidyLocalizedString(STRING_HTML_PROPRIETARY);
|
||||||
|
messageNode(doc, TidyWarning, code, node, fmt, nodedesc, extra_string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_VERS_MISMATCH_ERROR:
|
||||||
|
versionEmitted = doc->lexer->versionEmitted;
|
||||||
|
declared = doc->lexer->doctype;
|
||||||
|
version = versionEmitted == 0 ? declared : versionEmitted;
|
||||||
|
extra_string = TY_(HTMLVersionNameFromCode)(version, 0);
|
||||||
|
if (!extra_string)
|
||||||
|
extra_string = tidyLocalizedString(STRING_HTML_PROPRIETARY);
|
||||||
|
messageNode(doc, TidyError, code, node, fmt, nodedesc, extra_string);
|
||||||
|
break;
|
||||||
|
|
||||||
case MISSING_TITLE_ELEMENT:
|
case MISSING_TITLE_ELEMENT:
|
||||||
case INCONSISTENT_VERSION:
|
case INCONSISTENT_VERSION:
|
||||||
case MALFORMED_DOCTYPE:
|
case MALFORMED_DOCTYPE:
|
||||||
|
|
|
@ -98,6 +98,8 @@ typedef enum {
|
||||||
CANT_BE_NESTED,
|
CANT_BE_NESTED,
|
||||||
OBSOLETE_ELEMENT,
|
OBSOLETE_ELEMENT,
|
||||||
PROPRIETARY_ELEMENT,
|
PROPRIETARY_ELEMENT,
|
||||||
|
ELEMENT_VERS_MISMATCH_ERROR,
|
||||||
|
ELEMENT_VERS_MISMATCH_WARN,
|
||||||
UNKNOWN_ELEMENT,
|
UNKNOWN_ELEMENT,
|
||||||
TRIM_EMPTY_ELEMENT,
|
TRIM_EMPTY_ELEMENT,
|
||||||
COERCE_TO_ENDTAG,
|
COERCE_TO_ENDTAG,
|
||||||
|
@ -137,6 +139,8 @@ typedef enum {
|
||||||
BAD_ATTRIBUTE_VALUE,
|
BAD_ATTRIBUTE_VALUE,
|
||||||
UNEXPECTED_GT,
|
UNEXPECTED_GT,
|
||||||
PROPRIETARY_ATTRIBUTE,
|
PROPRIETARY_ATTRIBUTE,
|
||||||
|
MISMATCHED_ATTRIBUTE_ERROR,
|
||||||
|
MISMATCHED_ATTRIBUTE_WARN,
|
||||||
PROPRIETARY_ATTR_VALUE,
|
PROPRIETARY_ATTR_VALUE,
|
||||||
REPEATED_ATTRIBUTE,
|
REPEATED_ATTRIBUTE,
|
||||||
MISSING_IMAGEMAP,
|
MISSING_IMAGEMAP,
|
||||||
|
@ -168,8 +172,6 @@ typedef enum {
|
||||||
WHITE_IN_URI,
|
WHITE_IN_URI,
|
||||||
|
|
||||||
REMOVED_HTML5, /* this element removed from HTML5 */
|
REMOVED_HTML5, /* this element removed from HTML5 */
|
||||||
BAD_BODY_HTML5, /* attr on body removed from HTML5 */
|
|
||||||
BAD_ALIGN_HTML5, /* use of align attr removed from HTML5 */
|
|
||||||
BAD_SUMMARY_HTML5, /* use of summary attr removed from HTML5 */
|
BAD_SUMMARY_HTML5, /* use of summary attr removed from HTML5 */
|
||||||
|
|
||||||
PREVIOUS_LOCATION, /* last */
|
PREVIOUS_LOCATION, /* last */
|
||||||
|
|
276
src/tidylib.c
276
src/tidylib.c
|
@ -1300,9 +1300,9 @@ void tidyDocReportDoctype( TidyDocImpl* doc )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ######################################################################################
|
/*****************************************************************************
|
||||||
HTML5 STUFF
|
* HTML5 STUFF
|
||||||
*/
|
*****************************************************************************/
|
||||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||||
extern void show_not_html5(void);
|
extern void show_not_html5(void);
|
||||||
/* -----------------------------
|
/* -----------------------------
|
||||||
|
@ -1358,19 +1358,19 @@ Bool inRemovedInfo( uint tid )
|
||||||
return no;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool BadBody5( Node* node )
|
/* Things that should not be in an HTML5 body. This is special for CheckHTML5(),
|
||||||
{
|
and we might just want to remove CheckHTML5()'s output altogether and count
|
||||||
if (TY_(AttrGetById)(node, TidyAttr_BACKGROUND) ||
|
on the default --strict-tags-attributes.
|
||||||
TY_(AttrGetById)(node, TidyAttr_BGCOLOR) ||
|
*/
|
||||||
TY_(AttrGetById)(node, TidyAttr_TEXT) ||
|
static BadBody5Attribs[] = {
|
||||||
TY_(AttrGetById)(node, TidyAttr_LINK) ||
|
TidyAttr_BACKGROUND,
|
||||||
TY_(AttrGetById)(node, TidyAttr_VLINK) ||
|
TidyAttr_BGCOLOR,
|
||||||
TY_(AttrGetById)(node, TidyAttr_ALINK))
|
TidyAttr_TEXT,
|
||||||
{
|
TidyAttr_LINK,
|
||||||
return yes;
|
TidyAttr_VLINK,
|
||||||
}
|
TidyAttr_ALINK,
|
||||||
return no;
|
TidyAttr_UNKNOWN /* Must be last! */
|
||||||
}
|
};
|
||||||
|
|
||||||
static Bool nodeHasAlignAttr( Node *node )
|
static Bool nodeHasAlignAttr( Node *node )
|
||||||
{
|
{
|
||||||
|
@ -1383,46 +1383,65 @@ static Bool nodeHasAlignAttr( Node *node )
|
||||||
return no;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#obsolete */
|
/*
|
||||||
|
* Perform special checks for HTML, even when we're not using the default
|
||||||
|
* option `--strict-tags-attributes yes`. This will ensure that HTML5 warning
|
||||||
|
* and error output is given regardless of the new option, and ensure that
|
||||||
|
* cleanup takes place. This provides mostly consistent Tidy behavior even with
|
||||||
|
* the introduction of this new option. Note that strings have changed, though,
|
||||||
|
* in order to maintain consistency with the `--strict-tags-attributes`
|
||||||
|
* messages.
|
||||||
|
*
|
||||||
|
* See also: http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#obsolete
|
||||||
|
*/
|
||||||
void TY_(CheckHTML5)( TidyDocImpl* doc, Node* node )
|
void TY_(CheckHTML5)( TidyDocImpl* doc, Node* node )
|
||||||
{
|
{
|
||||||
/* Lexer* lexer = doc->lexer; */
|
|
||||||
Bool clean = cfgBool( doc, TidyMakeClean );
|
Bool clean = cfgBool( doc, TidyMakeClean );
|
||||||
|
Bool already_strict = cfgBool( doc, TidyStrictTagsAttr );
|
||||||
Node* body = TY_(FindBody)( doc );
|
Node* body = TY_(FindBody)( doc );
|
||||||
Bool warn = yes; /* should this be a warning, error, or report??? */
|
Bool warn = yes; /* should this be a warning, error, or report??? */
|
||||||
|
AttVal* attr = NULL;
|
||||||
|
int i = 0;
|
||||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||||
// list_not_html5();
|
// list_not_html5();
|
||||||
#endif
|
#endif
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
if ( nodeHasAlignAttr( node ) ) {
|
if ( nodeHasAlignAttr( node ) ) {
|
||||||
/*\
|
/* @todo: Is this for ALL elements that accept an 'align' attribute,
|
||||||
* Is this for ALL elements that accept an 'align' attribute, or should
|
* or should this be a sub-set test?
|
||||||
* this be a sub-set test
|
*/
|
||||||
\*/
|
|
||||||
TY_(ReportWarning)(doc, node, node, BAD_ALIGN_HTML5);
|
/* We will only emit this message if `--strict-tags-attributes==no`;
|
||||||
|
* otherwise if yes this message will be output during later
|
||||||
|
* checking.
|
||||||
|
*/
|
||||||
|
if ( !already_strict )
|
||||||
|
TY_(ReportAttrError)(doc, node, TY_(AttrGetById)(node, TidyAttr_ALIGN), MISMATCHED_ATTRIBUTE_WARN);
|
||||||
}
|
}
|
||||||
if ( node == body ) {
|
if ( node == body ) {
|
||||||
if ( BadBody5(body) ) {
|
i = 0;
|
||||||
/* perhaps need a new/different warning for this, like
|
/* We will only emit these messages if `--strict-tags-attributes==no`;
|
||||||
* The background 'attribute" on the body element is obsolete. Use CSS instead.
|
* otherwise if yes these messages will be output during later
|
||||||
* but how to pass an attribute name to be embedded in the message.
|
* checking.
|
||||||
\*/
|
*/
|
||||||
TY_(ReportWarning)(doc, node, body, BAD_BODY_HTML5);
|
if ( !already_strict ) {
|
||||||
|
while ( BadBody5Attribs[i] != TidyAttr_UNKNOWN ) {
|
||||||
|
attr = TY_(AttrGetById)(node, BadBody5Attribs[i]);
|
||||||
|
if ( attr )
|
||||||
|
TY_(ReportAttrError)(doc, node, attr , MISMATCHED_ATTRIBUTE_WARN);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if ( nodeIsACRONYM(node) ) {
|
if ( nodeIsACRONYM(node) ) {
|
||||||
if (clean) {
|
if (clean) {
|
||||||
/* replace with 'abbr' with warning to that effect
|
/* Replace with 'abbr' with warning to that effect.
|
||||||
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
* Maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
||||||
*/
|
*/
|
||||||
TY_(CoerceNode)(doc, node, TidyTag_ABBR, warn, no);
|
TY_(CoerceNode)(doc, node, TidyTag_ABBR, warn, no);
|
||||||
} else {
|
} else {
|
||||||
/* sadly, this stops writing of the tidied document, unless 'forced'
|
if ( !already_strict )
|
||||||
TY_(ReportError)(doc, node, node, REMOVED_HTML5);
|
|
||||||
so go back to a 'warning' for now...
|
|
||||||
*/
|
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -1433,22 +1452,24 @@ void TY_(CheckHTML5)( TidyDocImpl* doc, Node* node )
|
||||||
*/
|
*/
|
||||||
TY_(CoerceNode)(doc, node, TidyTag_OBJECT, warn, no);
|
TY_(CoerceNode)(doc, node, TidyTag_OBJECT, warn, no);
|
||||||
} else {
|
} else {
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if ( nodeIsBASEFONT(node) ) {
|
if ( nodeIsBASEFONT(node) ) {
|
||||||
/*\
|
/* basefont: CSS equivalent 'font-size', 'font-family' and 'color'
|
||||||
* basefont: CSS equivalen 'font-size', 'font-family' and 'color' on body or class on each subsequent element
|
* on body or class on each subsequent element.
|
||||||
* Difficult - If it is the first body element, then could consider adding that
|
* Difficult - If it is the first body element, then could consider
|
||||||
* to the <body> as a whole, else could perhaps apply it to all subsequent element.
|
* adding that to the <body> as a whole, else could perhaps apply it
|
||||||
* But also in consideration is the fact that it was NOT supported in many browsers
|
* to all subsequent elements. But also in consideration is the fact
|
||||||
* For now just report a warning
|
* that it was NOT supported in many browsers.
|
||||||
\*/
|
* - For now just report a warning
|
||||||
|
*/
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
} else
|
} else
|
||||||
if ( nodeIsBIG(node) ) {
|
if ( nodeIsBIG(node) ) {
|
||||||
/*\
|
/* big: CSS equivalent 'font-size:larger'
|
||||||
* big: CSS equivalent 'font-size:larger'
|
|
||||||
* so could replace the <big> ... </big> with
|
* so could replace the <big> ... </big> with
|
||||||
* <span style="font-size: larger"> ... </span>
|
* <span style="font-size: larger"> ... </span>
|
||||||
* then replace <big> with <span>
|
* then replace <big> with <span>
|
||||||
|
@ -1461,80 +1482,78 @@ void TY_(CheckHTML5)( TidyDocImpl* doc, Node* node )
|
||||||
* Also maybe need a specific message like
|
* Also maybe need a specific message like
|
||||||
* Element '%s' replaced with 'span' with a 'font-size: larger style attribute
|
* Element '%s' replaced with 'span' with a 'font-size: larger style attribute
|
||||||
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
||||||
*
|
*/
|
||||||
\*/
|
|
||||||
if (clean) {
|
if (clean) {
|
||||||
TY_(AddStyleProperty)( doc, node, "font-size: larger" );
|
TY_(AddStyleProperty)( doc, node, "font-size: larger" );
|
||||||
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
||||||
} else {
|
} else {
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if ( nodeIsCENTER(node) ) {
|
if ( nodeIsCENTER(node) ) {
|
||||||
/*\
|
/* center: CSS equivalent 'text-align:center'
|
||||||
* center: CSS equivalent 'text-align:center'
|
|
||||||
* and 'margin-left:auto; margin-right:auto' on descendant blocks
|
* and 'margin-left:auto; margin-right:auto' on descendant blocks
|
||||||
* Tidy already handles this if 'clean' by SILENTLY generating the <style>
|
* Tidy already handles this if 'clean' by SILENTLY generating the
|
||||||
* and adding a <div class="c1"> around the elements.
|
* <style> and adding a <div class="c1"> around the elements.
|
||||||
* see: static Bool Center2Div( TidyDocImpl* doc, Node *node, Node **pnode)
|
* see: static Bool Center2Div( TidyDocImpl* doc, Node *node, Node **pnode)
|
||||||
\*/
|
*/
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
} else
|
} else
|
||||||
if ( nodeIsDIR(node) ) {
|
if ( nodeIsDIR(node) ) {
|
||||||
/*\
|
/* dir: replace by <ul>
|
||||||
* dir: replace by <ul>
|
|
||||||
* Tidy already actions this and issues a warning
|
* Tidy already actions this and issues a warning
|
||||||
* Should this be CHANGED???
|
* Should this be CHANGED???
|
||||||
\*/
|
*/
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
} else
|
} else
|
||||||
if ( nodeIsFONT(node) ) {
|
if ( nodeIsFONT(node) ) {
|
||||||
/*\
|
/* Tidy already handles this -
|
||||||
* Tidy already handles this -
|
|
||||||
* If 'clean' replaced by CSS, else
|
* If 'clean' replaced by CSS, else
|
||||||
* if is NOT clean, and doctype html5 then warnings issued
|
* if is NOT clean, and doctype html5 then warnings issued
|
||||||
* done in Bool Font2Span( TidyDocImpl* doc, Node *node, Node **pnode ) (I think?)
|
* done in Bool Font2Span( TidyDocImpl* doc, Node *node, Node **pnode ) (I think?)
|
||||||
*
|
*/
|
||||||
\*/
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
} else
|
} else
|
||||||
if (( nodesIsFRAME(node) ) || ( nodeIsFRAMESET(node) ) || ( nodeIsNOFRAMES(node) )) {
|
if (( nodesIsFRAME(node) ) || ( nodeIsFRAMESET(node) ) || ( nodeIsNOFRAMES(node) )) {
|
||||||
/*\
|
/* YOW: What to do here?????? Maybe <iframe>????
|
||||||
* YOW: What to do here?????? Maybe <iframe>????
|
*/
|
||||||
\*/
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
} else
|
} else
|
||||||
if ( nodeIsSTRIKE(node) ) {
|
if ( nodeIsSTRIKE(node) ) {
|
||||||
/*\
|
/* strike: CSS equivalent 'text-decoration:line-through'
|
||||||
* strike: CSS equivalent 'text-decoration:line-through'
|
|
||||||
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
||||||
\*/
|
*/
|
||||||
if (clean) {
|
if (clean) {
|
||||||
TY_(AddStyleProperty)( doc, node, "text-decoration: line-through" );
|
TY_(AddStyleProperty)( doc, node, "text-decoration: line-through" );
|
||||||
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
||||||
} else {
|
} else {
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if ( nodeIsTT(node) ) {
|
if ( nodeIsTT(node) ) {
|
||||||
/*\
|
/* tt: CSS equivalent 'font-family:monospace'
|
||||||
* tt: CSS equivalent 'font-family:monospace'
|
|
||||||
* Tidy presently does nothing. Tidy5 issues a warning
|
* Tidy presently does nothing. Tidy5 issues a warning
|
||||||
* But like the 'clean' <font> replacement this could also be replaced with CSS
|
* But like the 'clean' <font> replacement this could also be replaced with CSS
|
||||||
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
* maybe should use static void RenameElem( TidyDocImpl* doc, Node* node, TidyTagId tid )
|
||||||
*
|
*/
|
||||||
\*/
|
|
||||||
if (clean) {
|
if (clean) {
|
||||||
TY_(AddStyleProperty)( doc, node, "font-family: monospace" );
|
TY_(AddStyleProperty)( doc, node, "font-family: monospace" );
|
||||||
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
TY_(CoerceNode)(doc, node, TidyTag_SPAN, warn, no);
|
||||||
} else {
|
} else {
|
||||||
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (TY_(nodeIsElement)(node)) {
|
if (TY_(nodeIsElement)(node)) {
|
||||||
if (node->tag) {
|
if (node->tag) {
|
||||||
if ((!(node->tag->versions & VERS_HTML5))||(inRemovedInfo(node->tag->id))) {
|
if ( (!(node->tag->versions & VERS_HTML5) && !(node->tag->versions & VERS_PROPRIETARY)) || (inRemovedInfo(node->tag->id)) ) {
|
||||||
/* issue warning for elements like 'markquee' */
|
if ( !already_strict )
|
||||||
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
TY_(ReportWarning)(doc, node, node, REMOVED_HTML5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1546,9 +1565,102 @@ void TY_(CheckHTML5)( TidyDocImpl* doc, Node* node )
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* END HTML5 STUFF
|
/*****************************************************************************
|
||||||
######################################################################################
|
* END HTML5 STUFF
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check and report HTML tags and attributes that are:
|
||||||
|
* - Proprietary, and/or
|
||||||
|
* - Not supported in the current version of HTML, defined as the version
|
||||||
|
* of HTML that we are emitting.
|
||||||
|
* Proprietary items are reported as WARNINGS, and version mismatches will
|
||||||
|
* be reported as WARNING or ERROR in the following conditions:
|
||||||
|
* - ERROR if the emitted doctype is a strict doctype.
|
||||||
|
* - WARNING if the emitted doctype is a non-strict doctype.
|
||||||
|
* The propriety checks are *always* run as they have always been an integral
|
||||||
|
* part of Tidy. The version checks are controlled by `strict-tags-attributes`.
|
||||||
*/
|
*/
|
||||||
|
void TY_(CheckHTMLTagsAttribsVersions)( TidyDocImpl* doc, Node* node )
|
||||||
|
{
|
||||||
|
uint versionEmitted = doc->lexer->versionEmitted;
|
||||||
|
uint declared = doc->lexer->doctype;
|
||||||
|
uint version = versionEmitted == 0 ? declared : versionEmitted;
|
||||||
|
int tagReportType = VERS_STRICT & version ? ELEMENT_VERS_MISMATCH_ERROR : ELEMENT_VERS_MISMATCH_WARN;
|
||||||
|
int attrReportType = VERS_STRICT & version ? MISMATCHED_ATTRIBUTE_ERROR : MISMATCHED_ATTRIBUTE_WARN;
|
||||||
|
Bool check_versions = cfgBool( doc, TidyStrictTagsAttr );
|
||||||
|
AttVal *next_attr, *attval;
|
||||||
|
Bool attrIsProprietary = no;
|
||||||
|
Bool attrIsMismatched = yes;
|
||||||
|
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
/* This bit here handles our HTML tags */
|
||||||
|
if ( TY_(nodeIsElement)(node) && node->tag ) {
|
||||||
|
|
||||||
|
/* Leave XML stuff alone. */
|
||||||
|
if ( !cfgBool(doc, TidyXmlTags) )
|
||||||
|
{
|
||||||
|
/* Version mismatches take priority. */
|
||||||
|
if ( check_versions && !(node->tag->versions & version) )
|
||||||
|
{
|
||||||
|
TY_(ReportError)(doc, NULL, node, tagReportType );
|
||||||
|
}
|
||||||
|
/* If it's not mismatched, it could still be proprietary. */
|
||||||
|
else if ( node->tag->versions & VERS_PROPRIETARY )
|
||||||
|
{
|
||||||
|
if ( !cfgBool(doc, TidyMakeClean) ||
|
||||||
|
( !nodeIsNOBR(node) && !nodeIsWBR(node) ) )
|
||||||
|
{
|
||||||
|
TY_(ReportError)(doc, NULL, node, PROPRIETARY_ELEMENT );
|
||||||
|
|
||||||
|
if ( nodeIsLAYER(node) )
|
||||||
|
doc->badLayout |= USING_LAYER;
|
||||||
|
else if ( nodeIsSPACER(node) )
|
||||||
|
doc->badLayout |= USING_SPACER;
|
||||||
|
else if ( nodeIsNOBR(node) )
|
||||||
|
doc->badLayout |= USING_NOBR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And this bit here handles our attributes */
|
||||||
|
if (TY_(nodeIsElement)(node))
|
||||||
|
{
|
||||||
|
attval = node->attributes;
|
||||||
|
|
||||||
|
while (attval)
|
||||||
|
{
|
||||||
|
next_attr = attval->next;
|
||||||
|
|
||||||
|
attrIsProprietary = TY_(AttributeIsProprietary)(node, attval);
|
||||||
|
attrIsMismatched = check_versions ? TY_(AttributeIsMismatched)(node, attval, doc) : no;
|
||||||
|
/* Let the PROPRIETARY_ATTRIBUTE warning have precedence. */
|
||||||
|
if ( attrIsProprietary )
|
||||||
|
TY_(ReportAttrError)(doc, node, attval, PROPRIETARY_ATTRIBUTE);
|
||||||
|
else if ( attrIsMismatched )
|
||||||
|
{
|
||||||
|
TY_(ReportAttrError)(doc, node, attval, attrReportType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @todo: do we need a new option to drop mismatches? Or should we
|
||||||
|
simply drop them? */
|
||||||
|
if ( ( attrIsProprietary || attrIsMismatched ) && cfgBool(doc, TidyDropPropAttrs) )
|
||||||
|
TY_(RemoveAttribute)( doc, node, attval );
|
||||||
|
|
||||||
|
attval = next_attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->content)
|
||||||
|
TY_(CheckHTMLTagsAttribsVersions)( doc, node->content );
|
||||||
|
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||||
/* *** FOR DEBUG ONLY *** */
|
/* *** FOR DEBUG ONLY *** */
|
||||||
|
@ -1686,7 +1798,6 @@ int tidyDocCleanAndRepair( TidyDocImpl* doc )
|
||||||
Bool tidyXmlTags = cfgBool( doc, TidyXmlTags );
|
Bool tidyXmlTags = cfgBool( doc, TidyXmlTags );
|
||||||
Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName );
|
Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName );
|
||||||
Bool mergeEmphasis = cfgBool( doc, TidyMergeEmphasis );
|
Bool mergeEmphasis = cfgBool( doc, TidyMergeEmphasis );
|
||||||
ctmbstr sdef = NULL;
|
|
||||||
Node* node;
|
Node* node;
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||||
|
@ -1747,12 +1858,7 @@ int tidyDocCleanAndRepair( TidyDocImpl* doc )
|
||||||
|
|
||||||
/* remember given doctype for reporting */
|
/* remember given doctype for reporting */
|
||||||
node = TY_(FindDocType)(doc);
|
node = TY_(FindDocType)(doc);
|
||||||
sdef = tidyOptGetValue((TidyDoc)doc, TidyDoctype );
|
|
||||||
if (!sdef)
|
|
||||||
sdef = tidyOptGetCurrPick((TidyDoc) doc, TidyDoctypeMode );
|
|
||||||
if (sdef && (strcmp(sdef,"html5") == 0)) {
|
|
||||||
TY_(CheckHTML5)( doc, &doc->root );
|
|
||||||
}
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
AttVal* fpi = TY_(GetAttrByName)(node, "PUBLIC");
|
AttVal* fpi = TY_(GetAttrByName)(node, "PUBLIC");
|
||||||
|
@ -1798,6 +1904,14 @@ int tidyDocCleanAndRepair( TidyDocImpl* doc )
|
||||||
if ( xmlOut && xmlDecl )
|
if ( xmlOut && xmlDecl )
|
||||||
TY_(FixXmlDecl)( doc );
|
TY_(FixXmlDecl)( doc );
|
||||||
|
|
||||||
|
/* At this point the apparent doctype is going to be as stable as
|
||||||
|
it can ever be, so we can start detecting things that shouldn't
|
||||||
|
be in this version of HTML
|
||||||
|
*/
|
||||||
|
if (doc->lexer->versionEmitted & VERS_HTML5)
|
||||||
|
TY_(CheckHTML5)( doc, &doc->root );
|
||||||
|
TY_(CheckHTMLTagsAttribsVersions)( doc, &doc->root );
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(_MSC_VER)
|
#if !defined(NDEBUG) && defined(_MSC_VER)
|
||||||
SPRTF("All nodes AFTER clean and repair\n");
|
SPRTF("All nodes AFTER clean and repair\n");
|
||||||
dbg_show_all_nodes( doc, &doc->root, 0 );
|
dbg_show_all_nodes( doc, &doc->root, 0 );
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
5.1.38
|
5.1.39
|
||||||
2016.02.16
|
2016.02.16
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue