// // HTMLDocumentType.m // HTMLKit // // Created by Iska on 25/02/15. // Copyright (c) 2015 BrainCookie. All rights reserved. // #import "HTMLDocumentType.h" #import "NSString+HTMLKit.h" #import "HTMLNode+Private.h" NS_INLINE BOOL nilOrEqual(id first, id second) { return (first == nil) || ([first isEqual:second]); } @interface HTMLDocumentType () { NSString *_publicIdentifier; NSString *_systemIdentifier; } @end @implementation HTMLDocumentType - (instancetype)init { return [self initWithName:@"html" publicIdentifier:nil systemIdentifier:nil]; } - (instancetype)initWithName:(NSString *)name publicIdentifier:(NSString *)publicIdentifier systemIdentifier:(NSString *)systemIdentifier { self = [super initWithName:name type:HTMLNodeDocumentType]; if (self) { _publicIdentifier = [publicIdentifier copy]; _systemIdentifier = [systemIdentifier copy]; } return self; } - (NSString *)publicIdentifier { return _publicIdentifier ?: @""; } - (NSString *)systemIdentifier { return _systemIdentifier ?: @""; } - (BOOL)isValid { if (![self.name isEqualToString:@"html"]) { return NO; } if ([_publicIdentifier isEqualToString:@"-//W3C//DTD HTML 4.0//EN"] && nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/REC-html40/strict.dtd")) { return YES; } if ([_publicIdentifier isEqualToString:@"-//W3C//DTD HTML 4.01//EN"] && nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/html4/strict.dtd")) { return YES; } if ([_publicIdentifier isEqualToString:@"-//W3C//DTD XHTML 1.0 Strict//EN"] && nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")) { return YES; } if ([_publicIdentifier isEqualToString:@"-//W3C//DTD XHTML 1.1//EN"] && nilOrEqual(_systemIdentifier, @"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd")) { return YES; } if (_publicIdentifier != nil) { return NO; } if (_systemIdentifier && ![_systemIdentifier isEqualToString:@"about:legacy-compat"]) { return NO; } return YES; } - (HTMLQuirksMode)quirksMode { if (![self.name isEqualToString:@"html"]) { return HTMLQuirksModeQuirks; } if ([_publicIdentifier isEqualToStringIgnoringCase:@"-//W3O//DTD W3 HTML Strict 3.0//EN//"] || [_publicIdentifier isEqualToStringIgnoringCase:@"-/W3C/DTD HTML 4.0 Transitional/EN"] || [_publicIdentifier isEqualToStringIgnoringCase:@"HTML"]) { return HTMLQuirksModeQuirks; } if ([_publicIdentifier isEqualToStringIgnoringCase:@"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"]) { return HTMLQuirksModeQuirks; } if (QuirksModePrefixMatch(_publicIdentifier)) { return HTMLQuirksModeQuirks; } if (_systemIdentifier == nil) { if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Frameset//"] || [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Transitional//"]) { return HTMLQuirksModeQuirks; } } if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD XHTML 1.0 Frameset//"] || [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD XHTML 1.0 Transitional//"]) { return HTMLQuirksModeLimitedQuirks; } if (_systemIdentifier != nil) { if ([_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Frameset//"] || [_publicIdentifier hasPrefixIgnoringCase:@"-//W3C//DTD HTML 4.01 Transitional//"]) { return HTMLQuirksModeLimitedQuirks; } } return HTMLQuirksModeNoQuirks; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { HTMLDocumentType *copy = [super copyWithZone:zone]; copy->_publicIdentifier = self.publicIdentifier; copy->_systemIdentifier = self.systemIdentifier; return copy; } #pragma mark - Serialization - (NSString *)outerHTML { return [NSString stringWithFormat:@"", self.name]; } #pragma mark - Description - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p >", self.class, self, self.name, self.publicIdentifier, self.systemIdentifier]; } @end