diff --git a/HTMLKit.playground/Pages/Sanitizing HTML.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Sanitizing HTML.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..c335388 --- /dev/null +++ b/HTMLKit.playground/Pages/Sanitizing HTML.xcplaygroundpage/Contents.swift @@ -0,0 +1,29 @@ + +import HTMLKit + +HTMLSanitizingPolicy { (builder) in + builder + .allowCommonBlockElements() + .allowCommonInlineFormattingElements() + .allowElements(["p", "div"]) + .allow(HTMLElementPolicy.identity(), onElements: ["b", "p"]) + .allow(HTMLAttributePolicy.init(), onElements: []) + .disallowText(inElements: ["a"]) +} + +HTMLElementPolicy { (str) -> String in + return str +} + + +HTMLSanitizer { (builder) in + builder + .allowCommonBlockElements() + .allowCommonInlineFormattingElements() + .allowElements(["p", "div"]) + .allow(HTMLElementPolicy.identity() , onElements: ["b", "p"]) + .allow(HTMLAttributePolicy.init(), onElements: []) + .disallowText(inElements: ["a"]) +} + + diff --git a/HTMLKit.playground/contents.xcplayground b/HTMLKit.playground/contents.xcplayground index 0491d26..d54d9ab 100644 --- a/HTMLKit.playground/contents.xcplayground +++ b/HTMLKit.playground/contents.xcplayground @@ -1,10 +1,11 @@ - + + \ No newline at end of file diff --git a/Sources/HTMLSanitizer.h b/Sources/HTMLSanitizer.h index 412d65e..53d5eb8 100644 --- a/Sources/HTMLSanitizer.h +++ b/Sources/HTMLSanitizer.h @@ -7,7 +7,15 @@ // #import +#import "HTMLSanitizingPolicyBuilder.h" +#import "HTMLSanitizingPolicy.h" + +NS_ASSUME_NONNULL_BEGIN @interface HTMLSanitizer : NSObject ++ (instancetype)sanitizerWithPolicy:(void (^)(HTMLSanitizingPolicyBuilder *))block; + @end + +NS_ASSUME_NONNULL_END diff --git a/Sources/HTMLSanitizer.m b/Sources/HTMLSanitizer.m index ae761eb..a793e72 100644 --- a/Sources/HTMLSanitizer.m +++ b/Sources/HTMLSanitizer.m @@ -7,7 +7,39 @@ // #import "HTMLSanitizer.h" +#import "HTMLTokenizer.h" +#import "HTMLTokens.h" + +@interface HTMLSanitizer() +{ + HTMLTokenizer *_tokenizer; +} + +@end @implementation HTMLSanitizer ++ (instancetype)sanitizerWithPolicy:(void (^)(HTMLSanitizingPolicyBuilder *))block +{ + HTMLSanitizingPolicyBuilder *builder = [HTMLSanitizingPolicyBuilder new]; + block(builder); + return nil; //[[HTMLSanitizingPolicy alloc] initWithBuilder:builder]; +} + +- (instancetype)initWithString:(NSString *)string +{ + self = [super init]; + if (self) { + _tokenizer = [[HTMLTokenizer alloc] initWithString:string ?: @""]; + } + return self; +} + +- (void)sanitize +{ +// for (HTMLToken *token in _tokenizer) { +// +// } +} + @end diff --git a/Sources/HTMLSanitizingPolicy.h b/Sources/HTMLSanitizingPolicy.h index 9e563d7..23bad2e 100644 --- a/Sources/HTMLSanitizingPolicy.h +++ b/Sources/HTMLSanitizingPolicy.h @@ -8,6 +8,13 @@ #import +NS_ASSUME_NONNULL_BEGIN + @interface HTMLSanitizingPolicy : NSObject +- (HTMLSanitizingPolicy *)combineWith:(nullable HTMLSanitizingPolicy *)other; + @end + +NS_ASSUME_NONNULL_END + diff --git a/Sources/HTMLSanitizingPolicy.m b/Sources/HTMLSanitizingPolicy.m index b411d8c..033306f 100644 --- a/Sources/HTMLSanitizingPolicy.m +++ b/Sources/HTMLSanitizingPolicy.m @@ -8,6 +8,29 @@ #import "HTMLSanitizingPolicy.h" +@interface HTMLSanitizingPolicy() +{ + NSMutableArray *_policies; +} +@end + @implementation HTMLSanitizingPolicy +- (instancetype)init +{ + self = [super init]; + if (self) { + _policies = [NSMutableArray new]; + } + return self; +} + +- (HTMLSanitizingPolicy *)combineWith:(HTMLSanitizingPolicy *)other +{ + if (other) { + [_policies addObject:other]; + } + return self; +} + @end diff --git a/Sources/HTMLSanitizingPolicyBuilder.h b/Sources/HTMLSanitizingPolicyBuilder.h index 665903a..a812243 100644 --- a/Sources/HTMLSanitizingPolicyBuilder.h +++ b/Sources/HTMLSanitizingPolicyBuilder.h @@ -8,6 +8,32 @@ #import +#import "HTMLElementPolicy.h" +#import "HTMLTokenPolicy.h" +#import "HTMLAttributePolicy.h" + +NS_ASSUME_NONNULL_BEGIN + @interface HTMLSanitizingPolicyBuilder : NSObject +- (HTMLSanitizingPolicyBuilder *)allowElements:(NSArray *)elementNames; +- (HTMLSanitizingPolicyBuilder *)disallowElements:(NSArray *)elementNames; +- (HTMLSanitizingPolicyBuilder *)allowPolicy:(HTMLElementPolicy *)policy onElements:(NSArray *)elementNames; +- (HTMLSanitizingPolicyBuilder *)allowCommonInlineFormattingElements; +- (HTMLSanitizingPolicyBuilder *)allowCommonBlockElements; +- (HTMLSanitizingPolicyBuilder *)allowTextInElements:(NSArray *)elementNames; +- (HTMLSanitizingPolicyBuilder *)disallowTextInElements:(NSArray *)elementNames; + +//- (HTMLSanitizingPolicyBuilder *)allowAttributes:(NSArray *)attributeName +// onElements:(NSArray *)elementNames; +//- (HTMLSanitizingPolicyBuilder *)disallowAttributes:(NSArray *)attributeName +// onElements:(NSArray *)elementNames; +// +//- (HTMLSanitizingPolicyBuilder *)allowAttributePolicy:(HTMLAttributePolicy *)policy +// onElements:(NSArray *)elementNames; +//- (HTMLSanitizingPolicyBuilder *)disallowAttributePolicy:(HTMLAttributePolicy *)policy +// onElements:(NSArray *)elementNames; + @end + +NS_ASSUME_NONNULL_END diff --git a/Sources/HTMLSanitizingPolicyBuilder.m b/Sources/HTMLSanitizingPolicyBuilder.m index 32d8877..7422767 100644 --- a/Sources/HTMLSanitizingPolicyBuilder.m +++ b/Sources/HTMLSanitizingPolicyBuilder.m @@ -8,6 +8,87 @@ #import "HTMLSanitizingPolicyBuilder.h" +@interface HTMLSanitizingPolicyBuilder() +{ + NSMutableDictionary *> * elementPolicies; + NSMutableDictionary * attributePolicies; + NSMutableDictionary * textContainers; +} +@end + @implementation HTMLSanitizingPolicyBuilder +- (HTMLSanitizingPolicyBuilder *)allowElements:(NSArray *)elementNames +{ + return [self allowPolicy:HTMLElementPolicy.identity onElements:elementNames]; +} + +- (HTMLSanitizingPolicyBuilder *)disallowElements:(NSArray *)elementNames +{ + return [self allowPolicy:HTMLElementPolicy.rejectAll onElements:elementNames]; +} + +- (HTMLSanitizingPolicyBuilder *)allowPolicy:(HTMLElementPolicy *)policy onElements:(NSArray *)elementNames +{ + for (NSString *name in elementNames) { + NSMutableArray *list = elementPolicies[name]; + if (list == nil) { + list = [NSMutableArray new]; + } + [list addObject:policy]; + elementPolicies[name] = list; + } + return self; +} + +- (HTMLSanitizingPolicyBuilder *)allowCommonInlineFormattingElements +{ + return [self allowElements:@[@"b", @"i", @"font", @"s", @"u", @"o", @"sup", @"sub", @"ins", @"del", + @"strong", @"strike", @"tt", @"code", @"big", @"small", @"br", @"span", @"em"]]; +} + +- (HTMLSanitizingPolicyBuilder *)allowCommonBlockElements +{ + return [self allowElements:@[@"p", @"div", @"h1", @"h2", @"h3", @"h4", @"h5", @"h6", @"ul", @"ol", @"li", + @"blockquote"]]; +} + +- (HTMLSanitizingPolicyBuilder *)allowTextInElements:(NSArray *)elementNames; +{ + for (NSString *name in elementNames) { + textContainers[name] = @YES; + } + return self; +} + +- (HTMLSanitizingPolicyBuilder *)disallowTextInElements:(NSArray *)elementNames +{ + for (NSString *name in elementNames) { + textContainers[name] = @NO; + } + return self; +} + +//- (HTMLSanitizingPolicyBuilder *)allowAttributes:(NSArray *)attributeNames +// onElements:(NSArray *)elementNames +//{ +// for (NSString *attribute in attributeNames) { +// [self allowAttributePolicy:HTMLAttributePolicy.identity onElements:elementNames]; +// } +// return self; +//} +// +//- (HTMLSanitizingPolicyBuilder *)disallowAttributes:(NSArray *)attributeName +// onElements:(NSArray *)elementNames; +// +//- (HTMLSanitizingPolicyBuilder *)allowAttributePolicy:(HTMLAttributePolicy *)policy onElements:(NSArray *)elementNames +//{ +// return self; +//} +// +//- (HTMLSanitizingPolicyBuilder *)disallowAttributePolicy:(HTMLAttributePolicy *)policy onElements:(NSArray *)elementNames +//{ +// return self; +//} + @end diff --git a/Sources/HTMLTokenPolicy.h b/Sources/HTMLTokenPolicy.h index 519ea1a..0240ab5 100644 --- a/Sources/HTMLTokenPolicy.h +++ b/Sources/HTMLTokenPolicy.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN @interface HTMLTokenPolicy : NSObject -+ (instancetype)policy:(nullable HTMLToken * (^)(HTMLToken *))block; ++ (instancetype)policy:(HTMLToken * _Nullable (^)(HTMLToken *))block; - (nullable HTMLToken *)apply:(HTMLToken *)token; diff --git a/Sources/include/HTMLCharacterToken.h b/Sources/include/HTMLCharacterToken.h index 20ebd19..afc0308 100644 --- a/Sources/include/HTMLCharacterToken.h +++ b/Sources/include/HTMLCharacterToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import #import "HTMLToken.h" diff --git a/Sources/include/HTMLCommentToken.h b/Sources/include/HTMLCommentToken.h index 5c43f1e..0283f29 100644 --- a/Sources/include/HTMLCommentToken.h +++ b/Sources/include/HTMLCommentToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import #import "HTMLToken.h" diff --git a/Sources/include/HTMLDOCTYPEToken.h b/Sources/include/HTMLDOCTYPEToken.h index d54d991..dfab322 100644 --- a/Sources/include/HTMLDOCTYPEToken.h +++ b/Sources/include/HTMLDOCTYPEToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import #import "HTMLToken.h" diff --git a/Sources/include/HTMLEOFToken.h b/Sources/include/HTMLEOFToken.h index 369f315..f01f5e1 100644 --- a/Sources/include/HTMLEOFToken.h +++ b/Sources/include/HTMLEOFToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2015 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import "HTMLToken.h" /** diff --git a/Sources/include/HTMLKit.h b/Sources/include/HTMLKit.h index 1e94b55..5eb595b 100644 --- a/Sources/include/HTMLKit.h +++ b/Sources/include/HTMLKit.h @@ -16,6 +16,8 @@ extern const unsigned char HTMLKitVersionString[]; #import "HTMLDOM.h" #import "HTMLParser.h" +#import "HTMLSanitizer.h" + #import "HTMLKitErrorDomain.h" #import "HTMLOrderedDictionary.h" diff --git a/Sources/include/HTMLParseErrorToken.h b/Sources/include/HTMLParseErrorToken.h index 8b46e24..6ec50e0 100644 --- a/Sources/include/HTMLParseErrorToken.h +++ b/Sources/include/HTMLParseErrorToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import #import "HTMLToken.h" diff --git a/Sources/include/HTMLTagToken.h b/Sources/include/HTMLTagToken.h index 287f1ec..481f9a7 100644 --- a/Sources/include/HTMLTagToken.h +++ b/Sources/include/HTMLTagToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import #import "HTMLToken.h" #import "HTMLOrderedDictionary.h" diff --git a/Sources/include/HTMLToken.h b/Sources/include/HTMLToken.h index 32d5b87..b1da7a5 100644 --- a/Sources/include/HTMLToken.h +++ b/Sources/include/HTMLToken.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import @class HTMLDOCTYPEToken; diff --git a/Sources/include/HTMLTokens.h b/Sources/include/HTMLTokens.h index 6450e9f..4b1ac69 100644 --- a/Sources/include/HTMLTokens.h +++ b/Sources/include/HTMLTokens.h @@ -6,10 +6,6 @@ // Copyright (c) 2014 BrainCookie. All rights reserved. // -///------------------------------------------------------ -/// HTMLKit private header -///------------------------------------------------------ - #import "HTMLToken.h" #import "HTMLCharacterToken.h" #import "HTMLCommentToken.h"