Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d756fc4298 | |||
| 7c2335184e | |||
| 0c6084ba73 | |||
| 5201860073 | |||
| cf21b88eb1 | |||
| 7617fceff1 | |||
| 9dd3c70fc3 | |||
| fe2a441171 | |||
| 7c32b5f219 | |||
| bf0d8560b0 | |||
| ebc6f7a097 | |||
| d29a70dfec | |||
| b8f56ca97d | |||
| 0f954d5d56 | |||
| ac5089d69b | |||
| c9c36397e0 | |||
| 923e271429 | |||
| 8546168324 | |||
| da765169fa | |||
| ec6d03ee57 | |||
| 7944549bd7 | |||
| bb6a97984b | |||
| 0aff9cf787 | |||
| b7bf9d2b04 | |||
| 12af838fa2 | |||
| 14b8b5390f | |||
| a5599c4163 | |||
| c0ac25645d | |||
| fa431550d7 | |||
| 70c6aee814 | |||
| 7309b97b92 | |||
| 7ffb8e5ca0 |
+1
-1
@@ -1,5 +1,5 @@
|
||||
module: HTMLKit
|
||||
module_version: 2.1.2
|
||||
module_version: 2.1.5
|
||||
author: Iskandar Abudiab
|
||||
author_url: https://twitter.com/iabudiab
|
||||
github_url: https://github.com/iabudiab/HTMLKit
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# Change Log
|
||||
|
||||
## [2.1.5](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.5)
|
||||
|
||||
Released on 2018.07.16
|
||||
|
||||
### Fixes
|
||||
|
||||
- Parser would handle foreign attributes incorrectly (issue #30)
|
||||
|
||||
|
||||
## [2.1.4](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.4)
|
||||
|
||||
Released on 2018.05.01
|
||||
|
||||
### Fixes
|
||||
|
||||
- `gt(n)`, `lt(n)` and `eq(n)` selectors would select wrong elements for the zero-index (issue #25)
|
||||
|
||||
|
||||
## [2.1.3](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.3)
|
||||
|
||||
Released on 2018.03.21
|
||||
|
||||
### Fixes
|
||||
|
||||
- `HTMLElement` clone would return an immutable dictionary for attributes (issue #20)
|
||||
- Fixed by @CRivlaldo in PR #24
|
||||
- `HTMLNodeFilterBlock` would behave differently on simulator and device (issue #22)
|
||||
- Fixed by @CRivlaldo in PR #23
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.2)
|
||||
|
||||
Released on 2017.11.6
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "HTMLKit"
|
||||
s.version = "2.1.2"
|
||||
s.version = "2.1.5"
|
||||
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
|
||||
s.license = "MIT"
|
||||
s.homepage = "https://github.com/iabudiab/HTMLKit"
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
62056C501E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
62056C511E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
62056C521E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
620AB7B12087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
|
||||
620AB7B22087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
|
||||
620AB7B32087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
|
||||
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; };
|
||||
62132E5D1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; };
|
||||
6216ACFD1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6216ACFC1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m */; };
|
||||
@@ -309,6 +312,9 @@
|
||||
62A95A4D1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
|
||||
62A95A4E1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
|
||||
62A95A4F1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
|
||||
62C82E0D20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
|
||||
62C82E0E20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
|
||||
62C82E0F20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
|
||||
62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; };
|
||||
62D91C231DE218A500BEFADE /* HTMLRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D91C211DE218A500BEFADE /* HTMLRange.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
62D91C241DE218A500BEFADE /* HTMLRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D91C211DE218A500BEFADE /* HTMLRange.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -584,6 +590,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "HTMLNodeIterator+Private.h"; path = "include/HTMLNodeIterator+Private.h"; sourceTree = "<group>"; };
|
||||
62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSSelector.h; path = include/CSSSelector.h; sourceTree = "<group>"; };
|
||||
620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CSSStructuralPseudoSelectors.m; path = HTMLKitTests/CSSStructuralPseudoSelectors.m; sourceTree = "<group>"; };
|
||||
620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSCompoundSelector.h; path = include/CSSCompoundSelector.h; sourceTree = "<group>"; };
|
||||
620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = "<group>"; };
|
||||
620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSPseudoClassSelector.h; path = include/CSSPseudoClassSelector.h; sourceTree = "<group>"; };
|
||||
@@ -719,6 +726,7 @@
|
||||
62AE594319F992F30043F069 /* HTMLCommentToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLCommentToken.m; sourceTree = "<group>"; };
|
||||
62AE594719F9948A0043F069 /* HTMLCharacterToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLCharacterToken.h; path = include/HTMLCharacterToken.h; sourceTree = "<group>"; };
|
||||
62AE594819F9948A0043F069 /* HTMLCharacterToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLCharacterToken.m; sourceTree = "<group>"; };
|
||||
62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = HTMLKitParserIssuesTests.m; path = HTMLKitTests/HTMLKitParserIssuesTests.m; sourceTree = "<group>"; };
|
||||
62D8345719FB1AC4009205A9 /* HTML5LibTokenizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTML5LibTokenizerTest.h; path = HTMLKitTests/HTML5LibTokenizerTest.h; sourceTree = "<group>"; };
|
||||
62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTML5LibTokenizerTest.m; path = HTMLKitTests/HTML5LibTokenizerTest.m; sourceTree = "<group>"; };
|
||||
62D91C211DE218A500BEFADE /* HTMLRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLRange.h; path = include/HTMLRange.h; sourceTree = "<group>"; };
|
||||
@@ -989,6 +997,7 @@
|
||||
625EE45A1CBB171300F2CC8E /* HTMLKitTestUtil.m */,
|
||||
6236738C1AC0CD2400FF89B3 /* Tokenizer */,
|
||||
623975581AC362A5007E26F1 /* Tree Construction */,
|
||||
62C82E0B20FD2FCB008497A8 /* Parser */,
|
||||
624B9FB71AE072CB00646C4C /* DOM */,
|
||||
624B9FB81AE072D500646C4C /* Categories */,
|
||||
624E1A2D1B1D1C8A00E66AAC /* Structures */,
|
||||
@@ -1093,6 +1102,14 @@
|
||||
name = Tokenizing;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
62C82E0B20FD2FCB008497A8 /* Parser */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */,
|
||||
);
|
||||
name = Parser;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
62ECBEDF1C0B671000AF847B /* Parsing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1144,6 +1161,7 @@
|
||||
624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */,
|
||||
62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */,
|
||||
621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */,
|
||||
620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */,
|
||||
);
|
||||
name = Selectors;
|
||||
sourceTree = "<group>";
|
||||
@@ -1750,8 +1768,10 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62EC0A851E158BD80007786B /* HTMLRangeTests.m in Sources */,
|
||||
620AB7B12087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
|
||||
62E0BA971E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
|
||||
6216ACFD1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */,
|
||||
62C82E0D20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
|
||||
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */,
|
||||
6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
|
||||
62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */,
|
||||
@@ -1893,8 +1913,10 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62EC0A871E158BD80007786B /* HTMLRangeTests.m in Sources */,
|
||||
620AB7B32087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
|
||||
62E0BA991E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
|
||||
62857D3B1D39A345008DC254 /* CSSSelectorTest.m in Sources */,
|
||||
62C82E0F20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
|
||||
62857D421D39A345008DC254 /* CSSCombinatorSelectorTests.m in Sources */,
|
||||
62857D3C1D39A345008DC254 /* CSSSelectorParserTests.m in Sources */,
|
||||
62857D301D39A339008DC254 /* HTMLKitTokenizerPerformance.m in Sources */,
|
||||
@@ -1981,8 +2003,10 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62EC0A861E158BD80007786B /* HTMLRangeTests.m in Sources */,
|
||||
620AB7B22087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
|
||||
62E0BA981E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
|
||||
6216ACFE1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */,
|
||||
62C82E0E20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
|
||||
62ECBFCA1C0B6E2E00AF847B /* HTML5LibTokenizerTest.m in Sources */,
|
||||
62ECBFCB1C0B6E2E00AF847B /* HTMLKitTokenizerTests.m in Sources */,
|
||||
62ECBFCC1C0B6E2E00AF847B /* HTMLKitTokenizerPerformance.m in Sources */,
|
||||
|
||||
@@ -76,10 +76,8 @@ $ gem install cocoapods
|
||||
To add `HTMLKit` as a dependency into your project using CocoaPods just add the following in your `Podfile`:
|
||||
|
||||
```ruby
|
||||
use_frameworks!
|
||||
|
||||
target 'MyTarget' do
|
||||
pod 'HTMLKit', '~> 2.0'
|
||||
pod 'HTMLKit', '~> 2.1'
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ CSSSelector * ltSelector(NSInteger index)
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
|
||||
|
||||
if (index > 0) {
|
||||
if (index >= 0) {
|
||||
return elementIndex < index;
|
||||
} else {
|
||||
return elementIndex < element.parentElement.childNodesCount - index - 1;
|
||||
@@ -290,7 +290,7 @@ CSSSelector * gtSelector(NSInteger index)
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
|
||||
|
||||
if (index > 0) {
|
||||
if (index >= 0) {
|
||||
return elementIndex > index;
|
||||
} else {
|
||||
return elementIndex > element.parentElement.childNodesCount - index - 1;
|
||||
@@ -304,7 +304,7 @@ CSSSelector * eqSelector(NSInteger index)
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
|
||||
|
||||
if (index > 0) {
|
||||
if (index >= 0) {
|
||||
return elementIndex == index;
|
||||
} else {
|
||||
return elementIndex == element.parentElement.childNodesCount - index - 1;
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
{
|
||||
HTMLElement *copy = [super copyWithZone:zone];
|
||||
copy->_tagName = [_tagName copy];
|
||||
copy->_attributes = [_attributes copy];
|
||||
copy->_attributes = [_attributes mutableCopy];
|
||||
copy->_htmlNamespace = _htmlNamespace;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.1.2</string>
|
||||
<string>2.1.5</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ NSString * const RemoveChildNode = @"-removeChildNode:";
|
||||
|
||||
- (HTMLElement *)nextSiblingElement
|
||||
{
|
||||
HTMLNode *node = self.previousSibling;
|
||||
HTMLNode *node = self.nextSibling;
|
||||
while (node && node.nodeType != HTMLNodeElement) {
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
@interface HTMLNodeFilterBlock ()
|
||||
{
|
||||
BOOL (^ _block)(HTMLNode *);
|
||||
HTMLNodeFilterValue (^ _block)(HTMLNode *);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -154,4 +154,11 @@
|
||||
return [_keys countByEnumeratingWithState:state objects:buffer count:len];
|
||||
}
|
||||
|
||||
#pragma mark - Copying
|
||||
|
||||
- (id)mutableCopy
|
||||
{
|
||||
return [[HTMLOrderedDictionary alloc] initWithDictionary:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1443,7 +1443,6 @@
|
||||
} else if ([tagName isEqualToString:@"math"]) {
|
||||
[self reconstructActiveFormattingElements];
|
||||
AdjustMathMLAttributes(token);
|
||||
AdjustForeignAttributes(token);
|
||||
[self insertForeignElementForToken:token inNamespace:HTMLNamespaceMathML];
|
||||
if (token.isSelfClosing) {
|
||||
[_stackOfOpenElements popCurrentNode];
|
||||
@@ -1451,7 +1450,6 @@
|
||||
} else if ([tagName isEqualToString:@"svg"]) {
|
||||
[self reconstructActiveFormattingElements];
|
||||
AdjustSVGAttributes(token);
|
||||
AdjustForeignAttributes(token);
|
||||
[self insertForeignElementForToken:token inNamespace:HTMLNamespaceSVG];
|
||||
if (token.isSelfClosing) {
|
||||
[_stackOfOpenElements popCurrentNode];
|
||||
@@ -2541,7 +2539,6 @@
|
||||
AdjustSVGNameCase(token.asTagToken);
|
||||
AdjustSVGAttributes(token.asTagToken);
|
||||
}
|
||||
AdjustForeignAttributes(token.asTagToken);
|
||||
[self insertForeignElementForToken:token.asTagToken inNamespace:self.adjustedCurrentNode.htmlNamespace];
|
||||
if (token.asTagToken.selfClosing) {
|
||||
[_stackOfOpenElements popCurrentNode];
|
||||
|
||||
@@ -24,3 +24,5 @@
|
||||
#import "HTMLKitDOMExceptions.h"
|
||||
#import "HTMLNamespaces.h"
|
||||
#import "HTMLQuirksMode.h"
|
||||
|
||||
#import "HTMLOrderedDictionary.h"
|
||||
|
||||
@@ -140,31 +140,3 @@ NS_INLINE void AdjustSVGNameCase(HTMLTagToken *token)
|
||||
NSString *replacement = replacements[token.tagName] ?: token.tagName;
|
||||
token.tagName = replacement;
|
||||
}
|
||||
|
||||
NS_INLINE void AdjustForeignAttributes(HTMLTagToken *token)
|
||||
{
|
||||
if (token.attributes == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *replacements = @{ @"xlink:actuate": @"xlink actuate",
|
||||
@"xlink:arcrole": @"xlink arcrole",
|
||||
@"xlink:href": @"xlink href",
|
||||
@"xlink:role": @"xlink role",
|
||||
@"xlink:show": @"xlink show",
|
||||
@"xlink:title": @"xlink title",
|
||||
@"xlink:type": @"xlink type",
|
||||
@"xml:base": @"xml base",
|
||||
@"xml:lang": @"xml lang",
|
||||
@"xml:space": @"xml space",
|
||||
@"xmlns": @"xmlns",
|
||||
@"xmlns:xlink": @"xmlns xlink"};
|
||||
|
||||
HTMLOrderedDictionary *adjusted = [HTMLOrderedDictionary new];
|
||||
for (id key in token.attributes) {
|
||||
NSString *replacement = replacements[key] ?: key;
|
||||
adjusted[replacement] = token.attributes[key];
|
||||
}
|
||||
token.attributes = adjusted;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// CSSStructuralPseudoSelectors.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 18.04.18.
|
||||
// Copyright © 2018 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLParser.h"
|
||||
#import "HTMLDOM.h"
|
||||
|
||||
@interface CSSStructuralPseudoSelectors : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation CSSStructuralPseudoSelectors
|
||||
|
||||
#pragma mark - Bug Fixes
|
||||
|
||||
- (void)testBugFix_Issue_25
|
||||
{
|
||||
NSString *html = @"<table><tr><td>TD #0</td><td>TD #1</td><td>TD #2</td><td>TD #3</td></tr></table>";
|
||||
HTMLDocument *doc = [HTMLDocument documentWithString:html];
|
||||
NSArray<HTMLElement *> *elements = [doc querySelectorAll:@"td:gt(0)"];
|
||||
|
||||
XCTAssertEqual(elements.count, 3);
|
||||
XCTAssertEqualObjects(elements[0].textContent, @"TD #1");
|
||||
XCTAssertEqualObjects(elements[1].textContent, @"TD #2");
|
||||
XCTAssertEqualObjects(elements[2].textContent, @"TD #3");
|
||||
|
||||
elements = [doc querySelectorAll:@"td:lt(0)"];
|
||||
XCTAssertEqual(elements.count, 0);
|
||||
|
||||
elements = [doc querySelectorAll:@"td:eq(0)"];
|
||||
XCTAssertEqual(elements.count, 1);
|
||||
XCTAssertEqualObjects(elements[0].textContent, @"TD #0");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "HTML5LibTreeConstructionTest.h"
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "HTMLDOM.h"
|
||||
#import "HTMLDocumentType.h"
|
||||
#import "HTMLElement.h"
|
||||
#import "HTMLText.h"
|
||||
@@ -289,6 +290,8 @@ NS_INLINE NSArray * parseAttribute(NSString *str)
|
||||
NSRange range = [str rangeOfString:@"=" options:0];
|
||||
|
||||
NSString *key = [str substringToIndex:range.location];
|
||||
key = [key stringByReplacingOccurrencesOfString:@" " withString:@":"];
|
||||
|
||||
NSString *value = [str substringFromIndex:range.location + 2];
|
||||
value = [value substringToIndex:value.length - 1];
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// HTMLKitParserTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 16.07.18.
|
||||
// Copyright © 2018 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "HTMLDOM.h"
|
||||
|
||||
@interface HTMLKitParserIssuesTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation HTMLKitParserIssuesTests
|
||||
|
||||
#pragma mark - Bug Fixes
|
||||
|
||||
- (void)testBugFix_Issue_30 {
|
||||
NSString *html =
|
||||
@"<body>"
|
||||
" <svg id='draw_area' width='600' height='800' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1'>"
|
||||
" <image id='overlay_img' xlink:href='foo.png' width='600' height='800'/>"
|
||||
" </svg>"
|
||||
"</body>";
|
||||
|
||||
HTMLDocument* document = [HTMLDocument documentWithString:html];
|
||||
HTMLElement *svg = [document querySelector:@"#draw_area"];
|
||||
|
||||
XCTAssertNil(svg.attributes[@"xlink"]);
|
||||
XCTAssertEqualObjects(svg.attributes[@"xmlns"], @"http://www.w3.org/2000/svg");
|
||||
XCTAssertEqualObjects(svg.attributes[@"xmlns:xlink"], @"http://www.w3.org/1999/xlink");
|
||||
|
||||
HTMLElement *image = [document querySelector:@"#overlay_img"];
|
||||
|
||||
XCTAssertNil(image.attributes[@"xlink"]);
|
||||
XCTAssertNil(image.attributes[@"href"]);
|
||||
XCTAssertEqualObjects(image.attributes[@"xlink:href"], @"foo.png");
|
||||
XCTAssertEqualObjects(image.outerHTML, @"<image id=\"overlay_img\" xlink:href=\"foo.png\" width=\"600\" height=\"800\"></image>");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -592,4 +592,35 @@ static HTMLNode * (^ LastDescendant)(HTMLNode *) = ^ HTMLNode * (HTMLNode *node)
|
||||
XCTAssertEqual(0, nodeIterators.count);
|
||||
}
|
||||
|
||||
- (void)testBugFix_Issue_22 {
|
||||
// The issue is applicable only for devices. On simulator the test is passed.
|
||||
HTMLDocument *document = [HTMLDocument documentWithString:@"<div id=\"id\"></div>"];
|
||||
|
||||
NSString *divId = @"id";
|
||||
HTMLNodeFilterBlock *filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode * _Nonnull node) {
|
||||
HTMLElement *element = (HTMLElement *)node;
|
||||
return [element.elementId isEqualToString:divId] ? HTMLNodeFilterAccept : HTMLNodeFilterSkip;
|
||||
}];
|
||||
|
||||
HTMLNodeIterator *iterator = [document nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:filter];
|
||||
|
||||
HTMLElement *element = (HTMLElement*)iterator.nextObject;
|
||||
XCTAssertTrue([element.elementId isEqualToString:divId]);
|
||||
}
|
||||
|
||||
- (void)testBugFix_Issue_28 {
|
||||
HTMLDocument *document = self.document;
|
||||
HTMLNodeIterator *iterator = document.body.nodeIterator;
|
||||
|
||||
[iterator nextNode]; // Reference node: <body>
|
||||
|
||||
HTMLElement *span = (HTMLElement*)iterator.nextNode; // <span>
|
||||
NSString *spanTag = @"span";
|
||||
XCTAssertTrue([span.tagName isEqualToString:spanTag]);
|
||||
|
||||
HTMLElement *paragraph = span.nextSiblingElement; // <p>
|
||||
NSString *paragraphTag = @"p";
|
||||
XCTAssertTrue([paragraph.tagName isEqualToString:paragraphTag]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -512,4 +512,60 @@
|
||||
XCTAssertTrue([image compareDocumentPositionWithNode:outerDiv] == (HTMLDocumentPositionContainedBy | HTMLDocumentPositionFollowing));
|
||||
}
|
||||
|
||||
- (void)testDeepCloneElement {
|
||||
HTMLElement *outer = [[HTMLElement alloc] initWithTagName:@"div"
|
||||
attributes:@{@"id": @"outer",
|
||||
@"class": @"green"}];
|
||||
|
||||
HTMLElement *innerLevel1 = [[HTMLElement alloc] initWithTagName:@"div"
|
||||
attributes:@{@"id": @"inner1",
|
||||
@"class": @"red"}];
|
||||
|
||||
HTMLElement *innerLevel2 = [[HTMLElement alloc] initWithTagName:@"div"
|
||||
attributes:@{@"id": @"inner2",
|
||||
@"class": @"red"}];
|
||||
|
||||
[outer appendNode:innerLevel1];
|
||||
[innerLevel1 appendNode:innerLevel2];
|
||||
|
||||
HTMLElement *clone = [outer cloneNodeDeep:YES];
|
||||
|
||||
XCTAssertNotEqual(clone, outer);
|
||||
XCTAssertEqualObjects(clone.elementId, outer.elementId);
|
||||
XCTAssertEqualObjects(clone.attributes, outer.attributes);
|
||||
|
||||
XCTAssertNotEqual(clone.firstChild, innerLevel1);
|
||||
XCTAssertEqualObjects(clone.firstChild.asElement.elementId, innerLevel1.elementId);
|
||||
XCTAssertEqualObjects(clone.firstChild.asElement.attributes, innerLevel1.attributes);
|
||||
|
||||
XCTAssertNotEqual(clone.firstChild, innerLevel2);
|
||||
XCTAssertEqualObjects(clone.firstChild.firstChild.asElement.elementId, innerLevel2.elementId);
|
||||
XCTAssertEqualObjects(clone.firstChild.firstChild.asElement.attributes, innerLevel2.attributes);
|
||||
}
|
||||
|
||||
- (void)testDeepCloneElementAttributes {
|
||||
HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"
|
||||
attributes:@{@"id": @"outer",
|
||||
@"class": @"green",
|
||||
@"data": @"test"}];
|
||||
|
||||
HTMLElement *clone = [div cloneNodeDeep:YES];
|
||||
|
||||
XCTAssertEqualObjects(clone.attributes, div.attributes);
|
||||
XCTAssertTrue([clone.attributes isKindOfClass:[HTMLOrderedDictionary class]]);
|
||||
}
|
||||
|
||||
#pragma mark - Bug Fixes
|
||||
|
||||
- (void)testBugFix_Issue_20 {
|
||||
HTMLElement *element = [HTMLElement new];
|
||||
element.elementId = @"originalId";
|
||||
|
||||
HTMLElement *clone = [element cloneNodeDeep:YES];
|
||||
NSString *cloneId = @"cloneId";
|
||||
clone.elementId = cloneId;
|
||||
|
||||
XCTAssertTrue([clone.elementId isEqualToString:cloneId]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+1
-1
Submodule Tests/html5lib-tests updated: cbafeba945...515dc09aaa
Reference in New Issue
Block a user