Compare commits
109 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e788c832c6 | |||
| a33f4e0834 | |||
| 9e4007dcba | |||
| 50b67cfa94 | |||
| 47d244289e | |||
| 6b81d6e465 | |||
| 13b8fe7808 | |||
| 94fed8afa1 | |||
| 30dc6cf343 | |||
| badf070907 | |||
| 3443321459 | |||
| 60dc6bfc43 | |||
| 60a5821a2c | |||
| 621dbe36d6 | |||
| 50ae2c5283 | |||
| 0cb374681c | |||
| c09adc2f96 | |||
| 09991a149f | |||
| f735fcdfd6 | |||
| 5a3c1063e7 | |||
| 8cb088367d | |||
| 7ec90d6470 | |||
| 002564f9ae | |||
| 4c80c520d4 | |||
| 85abf35099 | |||
| 578806ec2f | |||
| 7923efb02b | |||
| f4d42e0753 | |||
| 56f99f9168 | |||
| c8dd1d7791 | |||
| c57d3453fc | |||
| a413156514 | |||
| 203d153487 | |||
| 4ceb913b9f | |||
| 7896f1687e | |||
| 55bb8effb2 | |||
| 2e10c23f52 | |||
| 4f47a750e0 | |||
| 46beae1b2d | |||
| 2e441727bc | |||
| cc101b9f4e | |||
| 0635744a2d | |||
| b5bb0a48b6 | |||
| 95ffccf67b | |||
| 6af01a1214 | |||
| 667693939f | |||
| f05adfb56b | |||
| bed2edf22a | |||
| 2574736359 | |||
| ab7de014cf | |||
| 15e768267a | |||
| ee82cacc48 | |||
| 61d7c683fb | |||
| bd84884bf7 | |||
| f248b39d26 | |||
| 118ea137f4 | |||
| 0366f39d1a | |||
| d107c05a44 | |||
| 5ca3bf1192 | |||
| 02393ddedd | |||
| 33df9e7fb2 | |||
| 6020b2bdd9 | |||
| c44c77d63d | |||
| 9905f45e27 | |||
| c868bd1a56 | |||
| 8f38aed6c6 | |||
| 1917fb1f1c | |||
| dc93bb07f6 | |||
| a74be4dfa9 | |||
| 7cd47486ac | |||
| ad902e3138 | |||
| 6cfe3b6f83 | |||
| a2096b0e54 | |||
| 79fda9fdbe | |||
| 1a05c41f86 | |||
| bf751d94b1 | |||
| 43705dac69 | |||
| 3c7e6e1913 | |||
| af4444e9a8 | |||
| 23d0d62295 | |||
| b0668e121e | |||
| aa95bbd9f2 | |||
| 1544f71c50 | |||
| b1ddbc5f75 | |||
| 576dc4dfb2 | |||
| c4aacfae2b | |||
| a54cae8829 | |||
| 852dfad19c | |||
| a5d53b3eef | |||
| 5e5b903c52 | |||
| 40b6e41e12 | |||
| 05e224283a | |||
| 8490d4d2ca | |||
| 52b850317e | |||
| f5d970ba87 | |||
| 0c8fd754c3 | |||
| 4f03e00003 | |||
| 62b385d9b4 | |||
| a7a30a7cbf | |||
| 221b085fe5 | |||
| a2d9e65f0e | |||
| 745d0f72a7 | |||
| c401c3ca2c | |||
| 3cb5ed9a42 | |||
| acec99ffea | |||
| 7c58268dfd | |||
| c87076b470 | |||
| 81a20f0333 | |||
| 4fcaf4c810 |
+25
-6
@@ -1,8 +1,12 @@
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
@@ -12,13 +16,28 @@ build/
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
|
||||
## Other
|
||||
*.xccheckout
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.xcuserstate
|
||||
*.xcscmblueprint
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
*.ipa
|
||||
|
||||
# CocoaPods
|
||||
Pods
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
Pods/
|
||||
|
||||
# Carthage
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||
Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
@@ -7,49 +7,51 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; };
|
||||
620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; };
|
||||
620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */; };
|
||||
620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; };
|
||||
620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */; };
|
||||
620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; };
|
||||
620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */; };
|
||||
62132E591C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; };
|
||||
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; };
|
||||
62132E5C1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; };
|
||||
62132E5D1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; };
|
||||
621FBE5A1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */; };
|
||||
621FBE5B1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */; };
|
||||
621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; };
|
||||
621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */; };
|
||||
622BF5821BBF2FD700363583 /* CSSSelectorParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */; };
|
||||
622BF5831BBF2FD700363583 /* CSSSelectorParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 622BF5801BBF2FD700363583 /* CSSSelectorParser.m */; };
|
||||
623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; };
|
||||
623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E01ADB04F9004677A3 /* HTMLTemplate.m */; };
|
||||
623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */; };
|
||||
623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E51ADB05AD004677A3 /* HTMLDocumentFragment.m */; };
|
||||
623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */ = {isa = PBXBuildFile; fileRef = 623406E51ADB05AD004677A3 /* HTMLDocumentFragment.m */; };
|
||||
623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 623424861AB467B200726190 /* HTMLOrderedDictionary.h */; };
|
||||
623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 623424871AB467B200726190 /* HTMLOrderedDictionary.m */; };
|
||||
6234248A1AB467B200726190 /* HTMLOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 623424871AB467B200726190 /* HTMLOrderedDictionary.m */; };
|
||||
6234584E1A9D2FA4009BD491 /* HTMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234584C1A9D2FA4009BD491 /* HTMLNode.h */; };
|
||||
6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234584D1A9D2FA4009BD491 /* HTMLNode.m */; };
|
||||
623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234584D1A9D2FA4009BD491 /* HTMLNode.m */; };
|
||||
6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234BEEC1AABBF1400DEB15F /* HTMLStackOfOpenElements.h */; };
|
||||
6234BEEF1AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234BEED1AABBF1400DEB15F /* HTMLStackOfOpenElements.m */; };
|
||||
6234BEF01AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 6234BEED1AABBF1400DEB15F /* HTMLStackOfOpenElements.m */; };
|
||||
6234CF571ABF892400B6077D /* libHTMLKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DE19C7834000AD0C32 /* libHTMLKit.a */; };
|
||||
6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE991AA509430026937B /* NSString+HTMLKit.h */; };
|
||||
6235CE9C1AA509430026937B /* NSString+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9A1AA509430026937B /* NSString+HTMLKit.m */; };
|
||||
6235CE9D1AA509430026937B /* NSString+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9A1AA509430026937B /* NSString+HTMLKit.m */; };
|
||||
6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE9E1AA5170A0026937B /* HTMLMarker.h */; };
|
||||
6235CEA11AA5170A0026937B /* HTMLMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9F1AA5170A0026937B /* HTMLMarker.m */; };
|
||||
6235CEA21AA5170A0026937B /* HTMLMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6235CE9F1AA5170A0026937B /* HTMLMarker.m */; };
|
||||
62362A3C1A9FA70400301989 /* HTMLText.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3A1A9FA70400301989 /* HTMLText.h */; };
|
||||
62362A3D1A9FA70400301989 /* HTMLText.m in Sources */ = {isa = PBXBuildFile; fileRef = 62362A3B1A9FA70400301989 /* HTMLText.m */; };
|
||||
62362A3E1A9FA70400301989 /* HTMLText.m in Sources */ = {isa = PBXBuildFile; fileRef = 62362A3B1A9FA70400301989 /* HTMLText.m */; };
|
||||
62363C3D1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 62363C3B1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h */; };
|
||||
62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 62363C3C1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m */; };
|
||||
62363C3F1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */ = {isa = PBXBuildFile; fileRef = 62363C3C1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m */; };
|
||||
6236738E1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 6236738D1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m */; };
|
||||
6236738F1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 6236738D1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m */; };
|
||||
6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238039D1AB63A8C008A53D0 /* HTMLEOFToken.h */; };
|
||||
623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238039E1AB63A8C008A53D0 /* HTMLEOFToken.m */; };
|
||||
623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238039E1AB63A8C008A53D0 /* HTMLEOFToken.m */; };
|
||||
623857911A9E772B003A45D9 /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238578F1A9E772B003A45D9 /* HTMLDocument.h */; };
|
||||
623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857901A9E772B003A45D9 /* HTMLDocument.m */; };
|
||||
623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857901A9E772B003A45D9 /* HTMLDocument.m */; };
|
||||
623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857941A9E8606003A45D9 /* HTMLDocumentType.h */; };
|
||||
623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857951A9E8606003A45D9 /* HTMLDocumentType.m */; };
|
||||
623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 623857951A9E8606003A45D9 /* HTMLDocumentType.m */; };
|
||||
6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857991A9E8934003A45D9 /* HTMLComment.h */; };
|
||||
6238579C1A9E8934003A45D9 /* HTMLComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238579A1A9E8934003A45D9 /* HTMLComment.m */; };
|
||||
6238579D1A9E8934003A45D9 /* HTMLComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238579A1A9E8934003A45D9 /* HTMLComment.m */; };
|
||||
6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238C9831AB8D6330006512E /* HTMLKitDOMExceptions.h */; };
|
||||
6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238C9841AB8D6330006512E /* HTMLKitDOMExceptions.m */; };
|
||||
6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6238C9841AB8D6330006512E /* HTMLKitDOMExceptions.m */; };
|
||||
623916C71AC7209E0066B4FE /* HTMLKitNodeIteratorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 623916C61AC7209E0066B4FE /* HTMLKitNodeIteratorTests.m */; };
|
||||
@@ -60,33 +62,38 @@
|
||||
6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6239755D1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m */; };
|
||||
623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 623CAF9C1AD88BEA00E34C32 /* HTMLKitParserPerformance.m */; };
|
||||
623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 623CAF9C1AD88BEA00E34C32 /* HTMLKitParserPerformance.m */; };
|
||||
624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */; };
|
||||
624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */; };
|
||||
624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */; };
|
||||
624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; };
|
||||
624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; };
|
||||
624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; };
|
||||
624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; };
|
||||
624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; };
|
||||
6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717171B22333200C11912 /* HTMLNodeTraversal.m */; };
|
||||
6247171C1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247171B1B2240B800C11912 /* HTMLTreeWalkerTests.m */; };
|
||||
6247171D1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247171B1B2240B800C11912 /* HTMLTreeWalkerTests.m */; };
|
||||
624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; };
|
||||
624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717B71B21FE5400B38302 /* HTMLNodeFilter.m */; };
|
||||
624717BC1B22009200B38302 /* HTMLTreeWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717BA1B22009200B38302 /* HTMLTreeWalker.h */; };
|
||||
624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717BB1B22009200B38302 /* HTMLTreeWalker.m */; };
|
||||
624717BE1B22009200B38302 /* HTMLTreeWalker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624717BB1B22009200B38302 /* HTMLTreeWalker.m */; };
|
||||
6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */; };
|
||||
6247A9441B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; };
|
||||
6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */; };
|
||||
6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */; };
|
||||
624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; };
|
||||
624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; };
|
||||
624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */; };
|
||||
624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; };
|
||||
624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */; };
|
||||
624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; };
|
||||
624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */; };
|
||||
624AC90519FBFE9A00BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; };
|
||||
624AC90619FBFEA000BD3C4A /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; };
|
||||
624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; };
|
||||
624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; };
|
||||
624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; };
|
||||
624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28B71B03DA820048D328 /* CSSTypeSelector.m */; };
|
||||
624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; };
|
||||
624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28BE1B0413200048D328 /* CSSAttributeSelector.m */; };
|
||||
624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; };
|
||||
624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */; };
|
||||
624B371F1B24E9BA0010BDDF /* CSSInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */; };
|
||||
624B37201B24E9BA0010BDDF /* CSSInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B371D1B24E9BA0010BDDF /* CSSInputStream.m */; };
|
||||
624B9FB21AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */; };
|
||||
624B9FB31AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */; };
|
||||
624B9FB51AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624B9FB41AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m */; };
|
||||
@@ -95,7 +102,6 @@
|
||||
624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624FC3791AE591D80015DDF9 /* HTMLKitNodesTests.m */; };
|
||||
625A14B019C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; };
|
||||
625A14BA19C7829400AD0C32 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 625A14B819C7829400AD0C32 /* InfoPlist.strings */; };
|
||||
625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A14BD19C7829400AD0C32 /* HTMLKit.m */; };
|
||||
625A14C519C7829400AD0C32 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14C419C7829400AD0C32 /* XCTest.framework */; };
|
||||
625A14C619C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; };
|
||||
625A14C919C7829400AD0C32 /* HTMLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AC19C7829400AD0C32 /* HTMLKit.framework */; };
|
||||
@@ -103,48 +109,102 @@
|
||||
625A14E019C7834100AD0C32 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DF19C7834100AD0C32 /* Foundation.framework */; };
|
||||
625A14ED19C7834100AD0C32 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14C419C7829400AD0C32 /* XCTest.framework */; };
|
||||
625A14EE19C7834100AD0C32 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14DF19C7834100AD0C32 /* Foundation.framework */; };
|
||||
625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A14BD19C7829400AD0C32 /* HTMLKit.m */; };
|
||||
625A150319C783E200AD0C32 /* HTMLKit.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; };
|
||||
625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */; };
|
||||
625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; };
|
||||
625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; };
|
||||
6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; };
|
||||
626652F91C03D7AC00C3F121 /* HTMLKitErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; };
|
||||
6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; };
|
||||
62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; };
|
||||
628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; };
|
||||
628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; };
|
||||
628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; };
|
||||
628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */; };
|
||||
628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; };
|
||||
628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */; };
|
||||
629AA0EA1BDD9C2900D5CC98 /* HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A14BC19C7829400AD0C32 /* HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0EB1BDD9C2900D5CC98 /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0EC1BDD9C2900D5CC98 /* HTMLDOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3F1A9FDE8A00301989 /* HTMLDOM.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0ED1BDD9C2900D5CC98 /* HTMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234584C1A9D2FA4009BD491 /* HTMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0EE1BDD9C2900D5CC98 /* HTMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238578F1A9E772B003A45D9 /* HTMLDocument.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0EF1BDD9C2900D5CC98 /* HTMLDocumentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857941A9E8606003A45D9 /* HTMLDocumentType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F01BDD9C2900D5CC98 /* HTMLDocumentFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F11BDD9C2900D5CC98 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F21BDD9C2900D5CC98 /* HTMLComment.h in Headers */ = {isa = PBXBuildFile; fileRef = 623857991A9E8934003A45D9 /* HTMLComment.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F31BDD9C2900D5CC98 /* HTMLText.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3A1A9FA70400301989 /* HTMLText.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F41BDD9C2A00D5CC98 /* HTMLTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 623406DF1ADB04F9004677A3 /* HTMLTemplate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F51BDD9C2A00D5CC98 /* HTMLNodeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F61BDD9C2A00D5CC98 /* HTMLTreeWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717BA1B22009200B38302 /* HTMLTreeWalker.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F71BDD9C2A00D5CC98 /* HTMLNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 624717161B22333200C11912 /* HTMLNodeTraversal.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F81BDD9C2A00D5CC98 /* HTMLNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0F91BDD9C2A00D5CC98 /* HTMLKitDOMExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238C9831AB8D6330006512E /* HTMLKitDOMExceptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FA1BDD9C2A00D5CC98 /* HTMLNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FB1BDD9C2A00D5CC98 /* HTMLQuirksMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FC1BDD9C2A00D5CC98 /* NSString+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE991AA509430026937B /* NSString+HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FD1BDD9C2A00D5CC98 /* NSCharacterSet+HTMLKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FE1BDD9C2A00D5CC98 /* HTMLOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 623424861AB467B200726190 /* HTMLOrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA0FF1BDD9C2A00D5CC98 /* CSSSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AB3151B04EA4200F3830D /* CSSSelectors.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1001BDD9C2A00D5CC98 /* CSSSelectorParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1011BDD9C2A00D5CC98 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62079BE71AF56F1E00D3B402 /* CSSSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1021BDD9C2B00D5CC98 /* CSSSelectorBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1031BDD9C2B00D5CC98 /* CSSTypeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28B61B03DA820048D328 /* CSSTypeSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1041BDD9C2B00D5CC98 /* CSSAttributeSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B28BD1B0413200048D328 /* CSSAttributeSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1051BDD9C2B00D5CC98 /* CSSPseudoClassSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1061BDD9C2B00D5CC98 /* CSSStructuralPseudoSelectors.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1071BDD9C2B00D5CC98 /* CSSNthExpressionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1081BDD9C2B00D5CC98 /* CSSPseudoFunctionSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA1091BDD9C2B00D5CC98 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA10A1BDD9C2B00D5CC98 /* CSSCompoundSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
629AA10B1BDD9C5200D5CC98 /* HTMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */; };
|
||||
629AA10C1BDD9C5200D5CC98 /* HTMLTokenizerStates.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */; };
|
||||
629AA10D1BDD9C5300D5CC98 /* HTMLTokenizerCharacters.h in Headers */ = {isa = PBXBuildFile; fileRef = 62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */; };
|
||||
629AA10E1BDD9C5300D5CC98 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; };
|
||||
629AA10F1BDD9C5300D5CC98 /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; };
|
||||
629AA1101BDD9C5300D5CC98 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; };
|
||||
629AA1111BDD9C5300D5CC98 /* HTMLCharacterToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594719F9948A0043F069 /* HTMLCharacterToken.h */; };
|
||||
629AA1121BDD9C5300D5CC98 /* HTMLCommentToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594219F992F30043F069 /* HTMLCommentToken.h */; };
|
||||
629AA1131BDD9C5300D5CC98 /* HTMLDOCTYPEToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */; };
|
||||
629AA1141BDD9C5400D5CC98 /* HTMLParseErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593319F97D880043F069 /* HTMLParseErrorToken.h */; };
|
||||
629AA1151BDD9C5400D5CC98 /* HTMLTagToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593D19F9907C0043F069 /* HTMLTagToken.h */; };
|
||||
629AA1161BDD9C5400D5CC98 /* HTMLEOFToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 6238039D1AB63A8C008A53D0 /* HTMLEOFToken.h */; };
|
||||
629AA1171BDD9C5400D5CC98 /* HTMLStackOfOpenElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234BEEC1AABBF1400DEB15F /* HTMLStackOfOpenElements.h */; };
|
||||
629AA1181BDD9C5400D5CC98 /* HTMLListOfActiveFormattingElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 62363C3B1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h */; };
|
||||
629AA1191BDD9C5400D5CC98 /* HTMLElementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */; };
|
||||
629AA11A1BDD9C5400D5CC98 /* HTMLElementAdjustment.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234C3361AB3BF710046F527 /* HTMLElementAdjustment.h */; };
|
||||
629AA11B1BDD9C5500D5CC98 /* HTMLParserInsertionModes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */; };
|
||||
629AA11C1BDD9C5500D5CC98 /* HTMLMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6235CE9E1AA5170A0026937B /* HTMLMarker.h */; };
|
||||
629AA11D1BDD9C5500D5CC98 /* CSSCodePoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B37211B250BB50010BDDF /* CSSCodePoints.h */; };
|
||||
629AA11E1BDD9C5500D5CC98 /* CSSInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 624B371C1B24E9BA0010BDDF /* CSSInputStream.h */; };
|
||||
629AA11F1BDD9C5E00D5CC98 /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; };
|
||||
62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593419F97D880043F069 /* HTMLParseErrorToken.m */; };
|
||||
62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */; };
|
||||
62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593919F97E1C0043F069 /* HTMLDOCTYPEToken.m */; };
|
||||
62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593919F97E1C0043F069 /* HTMLDOCTYPEToken.m */; };
|
||||
62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE593D19F9907C0043F069 /* HTMLTagToken.h */; };
|
||||
62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593E19F9907C0043F069 /* HTMLTagToken.m */; };
|
||||
62AE594119F9907C0043F069 /* HTMLTagToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE593E19F9907C0043F069 /* HTMLTagToken.m */; };
|
||||
62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594219F992F30043F069 /* HTMLCommentToken.h */; };
|
||||
62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594319F992F30043F069 /* HTMLCommentToken.m */; };
|
||||
62AE594619F992F30043F069 /* HTMLCommentToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594319F992F30043F069 /* HTMLCommentToken.m */; };
|
||||
62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594719F9948A0043F069 /* HTMLCharacterToken.h */; };
|
||||
62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594819F9948A0043F069 /* HTMLCharacterToken.m */; };
|
||||
62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594819F9948A0043F069 /* HTMLCharacterToken.m */; };
|
||||
62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; };
|
||||
62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; };
|
||||
62D89DB01AE7080300B6243D /* HTMLDOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 62362A3F1A9FDE8A00301989 /* HTMLDOM.h */; };
|
||||
62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */; };
|
||||
62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */ = {isa = PBXBuildFile; fileRef = 62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */; };
|
||||
62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 628B7CE61A080E1000602C87 /* HTMLNamespaces.h */; };
|
||||
62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6223211D1A969B9300BACED5 /* HTMLElementTypes.h */; };
|
||||
62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234C3361AB3BF710046F527 /* HTMLElementAdjustment.h */; };
|
||||
62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */; };
|
||||
62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */; };
|
||||
62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; };
|
||||
62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; };
|
||||
62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; };
|
||||
62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; };
|
||||
62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; };
|
||||
62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; };
|
||||
62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; };
|
||||
62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; };
|
||||
62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; };
|
||||
62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; };
|
||||
62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; };
|
||||
62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; };
|
||||
62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; };
|
||||
62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */; };
|
||||
62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; };
|
||||
62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */; };
|
||||
62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; };
|
||||
62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */; };
|
||||
62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; };
|
||||
62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FC60451BD0519B0042BBE7 /* CSSSelector.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -178,7 +238,19 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelector.h; sourceTree = "<group>"; };
|
||||
620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 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; path = CSSPseudoClassSelector.h; sourceTree = "<group>"; };
|
||||
620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoClassSelector.m; sourceTree = "<group>"; };
|
||||
62132E571C01F83200084175 /* CSSSelectorTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorTest.h; sourceTree = "<group>"; };
|
||||
62132E581C01F83200084175 /* CSSSelectorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorTest.m; sourceTree = "<group>"; };
|
||||
62132E5B1C021FF200084175 /* css-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "css-tests"; sourceTree = "<group>"; };
|
||||
621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorParserTests.m; sourceTree = "<group>"; };
|
||||
621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelectorTests.m; sourceTree = "<group>"; };
|
||||
6223211D1A969B9300BACED5 /* HTMLElementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLElementTypes.h; sourceTree = "<group>"; };
|
||||
622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorParser.h; sourceTree = "<group>"; };
|
||||
622BF5801BBF2FD700363583 /* CSSSelectorParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorParser.m; sourceTree = "<group>"; };
|
||||
623406DF1ADB04F9004677A3 /* HTMLTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTemplate.h; sourceTree = "<group>"; };
|
||||
623406E01ADB04F9004677A3 /* HTMLTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTemplate.m; sourceTree = "<group>"; };
|
||||
623406E41ADB05AD004677A3 /* HTMLDocumentFragment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDocumentFragment.h; sourceTree = "<group>"; };
|
||||
@@ -230,10 +302,22 @@
|
||||
6247A9411B152F4F00CCF25C /* HTMLNodeIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeIterator.h; sourceTree = "<group>"; };
|
||||
6247A9421B152F4F00CCF25C /* HTMLNodeIterator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLNodeIterator.m; sourceTree = "<group>"; };
|
||||
6247A9461B152F8C00CCF25C /* HTMLNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLNodeFilter.h; sourceTree = "<group>"; };
|
||||
624AB3151B04EA4200F3830D /* CSSSelectors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSSelectors.h; sourceTree = "<group>"; };
|
||||
624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelectorTests.m; sourceTree = "<group>"; };
|
||||
624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelectorTests.m; sourceTree = "<group>"; };
|
||||
624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = "<group>"; };
|
||||
624AC90019FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitTokenizerTests.m; sourceTree = "<group>"; };
|
||||
624AC90419FBFE8A00BD3C4A /* html5lib-tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "html5lib-tests"; sourceTree = "<group>"; };
|
||||
624AC90D19FC702E00BD3C4A /* HTML Standard.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "HTML Standard.html"; sourceTree = "<group>"; };
|
||||
624B28B61B03DA820048D328 /* CSSTypeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSTypeSelector.h; sourceTree = "<group>"; };
|
||||
624B28B71B03DA820048D328 /* CSSTypeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSTypeSelector.m; sourceTree = "<group>"; };
|
||||
624B28BD1B0413200048D328 /* CSSAttributeSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSAttributeSelector.h; sourceTree = "<group>"; };
|
||||
624B28BE1B0413200048D328 /* CSSAttributeSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSAttributeSelector.m; sourceTree = "<group>"; };
|
||||
624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCharacterSet+HTMLKit.h"; sourceTree = "<group>"; };
|
||||
624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSCharacterSet+HTMLKit.m"; sourceTree = "<group>"; };
|
||||
624B371C1B24E9BA0010BDDF /* CSSInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSInputStream.h; sourceTree = "<group>"; };
|
||||
624B371D1B24E9BA0010BDDF /* CSSInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSInputStream.m; sourceTree = "<group>"; };
|
||||
624B37211B250BB50010BDDF /* CSSCodePoints.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSSCodePoints.h; sourceTree = "<group>"; };
|
||||
624B9FB11AE0313300646C4C /* HTMLKitStringCategoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitStringCategoryTests.m; sourceTree = "<group>"; };
|
||||
624B9FB41AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitOrderedDictionaryTests.m; sourceTree = "<group>"; };
|
||||
624FC3791AE591D80015DDF9 /* HTMLKitNodesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitNodesTests.m; sourceTree = "<group>"; };
|
||||
@@ -246,7 +330,6 @@
|
||||
625A14B919C7829400AD0C32 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
625A14BB19C7829400AD0C32 /* HTMLKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HTMLKit-Prefix.pch"; sourceTree = "<group>"; };
|
||||
625A14BC19C7829400AD0C32 /* HTMLKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLKit.h; sourceTree = "<group>"; };
|
||||
625A14BD19C7829400AD0C32 /* HTMLKit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HTMLKit.m; sourceTree = "<group>"; };
|
||||
625A14C319C7829400AD0C32 /* HTMLKitFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTMLKitFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
625A14C419C7829400AD0C32 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
625A14CC19C7829400AD0C32 /* HTMLKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HTMLKitTests-Info.plist"; sourceTree = "<group>"; };
|
||||
@@ -256,10 +339,18 @@
|
||||
625A14EC19C7834100AD0C32 /* HTMLKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTMLKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLInputStreamReader.h; sourceTree = "<group>"; };
|
||||
625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLInputStreamReader.m; sourceTree = "<group>"; };
|
||||
626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLKitErrorDomain.h; sourceTree = "<group>"; };
|
||||
6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLParserInsertionModes.h; sourceTree = "<group>"; };
|
||||
6279F87219E1808D00F12EE5 /* HTMLElement.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = HTMLElement.h; sourceTree = "<group>"; };
|
||||
6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = "<group>"; };
|
||||
628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionsParserTests.m; sourceTree = "<group>"; };
|
||||
628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionSelector.h; sourceTree = "<group>"; };
|
||||
628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionSelector.m; sourceTree = "<group>"; };
|
||||
628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSStructuralPseudoSelectors.h; sourceTree = "<group>"; };
|
||||
628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSStructuralPseudoSelectors.m; sourceTree = "<group>"; };
|
||||
628B7CE61A080E1000602C87 /* HTMLNamespaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLNamespaces.h; sourceTree = "<group>"; };
|
||||
62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPseudoFunctionSelector.h; sourceTree = "<group>"; };
|
||||
62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSPseudoFunctionSelector.m; sourceTree = "<group>"; };
|
||||
62AE593319F97D880043F069 /* HTMLParseErrorToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParseErrorToken.h; sourceTree = "<group>"; };
|
||||
62AE593419F97D880043F069 /* HTMLParseErrorToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParseErrorToken.m; sourceTree = "<group>"; };
|
||||
62AE593819F97E1C0043F069 /* HTMLDOCTYPEToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDOCTYPEToken.h; sourceTree = "<group>"; };
|
||||
@@ -276,8 +367,17 @@
|
||||
62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitMutationAlgorithmsTests.m; sourceTree = "<group>"; };
|
||||
62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerEntities.h; sourceTree = "<group>"; };
|
||||
62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = "<group>"; };
|
||||
62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionParser.h; sourceTree = "<group>"; };
|
||||
62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = "<group>"; };
|
||||
62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNThExpressionSelectorTests.m; sourceTree = "<group>"; };
|
||||
62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = "<group>"; };
|
||||
62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = "<group>"; };
|
||||
62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSCombinatorSelector.h; sourceTree = "<group>"; };
|
||||
62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCombinatorSelector.m; sourceTree = "<group>"; };
|
||||
62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = "<group>"; };
|
||||
62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorBlock.h; sourceTree = "<group>"; };
|
||||
62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectorBlock.m; sourceTree = "<group>"; };
|
||||
62FC60451BD0519B0042BBE7 /* CSSSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelector.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -320,6 +420,42 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
62079BE61AF5656600D3B402 /* Selectors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
624AB3151B04EA4200F3830D /* CSSSelectors.h */,
|
||||
62FA98031BD57B6200A2AF86 /* CSSSelectors.m */,
|
||||
624B37211B250BB50010BDDF /* CSSCodePoints.h */,
|
||||
624B371C1B24E9BA0010BDDF /* CSSInputStream.h */,
|
||||
624B371D1B24E9BA0010BDDF /* CSSInputStream.m */,
|
||||
622BF57F1BBF2FD700363583 /* CSSSelectorParser.h */,
|
||||
622BF5801BBF2FD700363583 /* CSSSelectorParser.m */,
|
||||
62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */,
|
||||
62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */,
|
||||
62079BE71AF56F1E00D3B402 /* CSSSelector.h */,
|
||||
62FC60451BD0519B0042BBE7 /* CSSSelector.m */,
|
||||
62FA98061BD5A7E200A2AF86 /* CSSSelectorBlock.h */,
|
||||
62FA98071BD5A7E200A2AF86 /* CSSSelectorBlock.m */,
|
||||
624B28B61B03DA820048D328 /* CSSTypeSelector.h */,
|
||||
624B28B71B03DA820048D328 /* CSSTypeSelector.m */,
|
||||
624B28BD1B0413200048D328 /* CSSAttributeSelector.h */,
|
||||
624B28BE1B0413200048D328 /* CSSAttributeSelector.m */,
|
||||
620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */,
|
||||
620EE9481BC46F2A0028ED34 /* CSSPseudoClassSelector.m */,
|
||||
628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */,
|
||||
628AF63D1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m */,
|
||||
628AF6311BC9A63D00496128 /* CSSNthExpressionSelector.h */,
|
||||
628AF6321BC9A63D00496128 /* CSSNthExpressionSelector.m */,
|
||||
62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */,
|
||||
62ACB8DC1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.m */,
|
||||
62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */,
|
||||
62FA04E21BCC360D009ABF98 /* CSSCombinatorSelector.m */,
|
||||
620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */,
|
||||
620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */,
|
||||
);
|
||||
name = Selectors;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6236738C1AC0CD2400FF89B3 /* Tokenizer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -451,12 +587,13 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
625A14BC19C7829400AD0C32 /* HTMLKit.h */,
|
||||
625A14BD19C7829400AD0C32 /* HTMLKit.m */,
|
||||
626652F81C03D30F00C3F121 /* HTMLKitErrorDomain.h */,
|
||||
62AE593219F97CCA0043F069 /* Tokenizing */,
|
||||
628E16EC1ADAE71700B15A06 /* Parsing */,
|
||||
623719441AA1472B002E03C8 /* DOM */,
|
||||
628E16ED1ADAE73700B15A06 /* Categories */,
|
||||
628E16EE1ADAE75300B15A06 /* Structures */,
|
||||
62079BE61AF5656600D3B402 /* Selectors */,
|
||||
625A14B619C7829400AD0C32 /* Supporting Files */,
|
||||
);
|
||||
name = "Source Code";
|
||||
@@ -481,6 +618,7 @@
|
||||
624B9FB71AE072CB00646C4C /* DOM */,
|
||||
624B9FB81AE072D500646C4C /* Categories */,
|
||||
624E1A2D1B1D1C8A00E66AAC /* Structures */,
|
||||
62FF516C1C0A430A009BFDFE /* Selectors */,
|
||||
625A14CB19C7829400AD0C32 /* Supporting Files */,
|
||||
);
|
||||
name = Tests;
|
||||
@@ -490,6 +628,7 @@
|
||||
625A14CB19C7829400AD0C32 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
62132E5B1C021FF200084175 /* css-tests */,
|
||||
624AC90D19FC702E00BD3C4A /* HTML Standard.html */,
|
||||
624AC90419FBFE8A00BD3C4A /* html5lib-tests */,
|
||||
625A14CC19C7829400AD0C32 /* HTMLKitTests-Info.plist */,
|
||||
@@ -521,6 +660,8 @@
|
||||
children = (
|
||||
6235CE991AA509430026937B /* NSString+HTMLKit.h */,
|
||||
6235CE9A1AA509430026937B /* NSString+HTMLKit.m */,
|
||||
624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */,
|
||||
624B28C31B04190D0048D328 /* NSCharacterSet+HTMLKit.m */,
|
||||
);
|
||||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
@@ -564,6 +705,21 @@
|
||||
name = Tokenizing;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
62FF516C1C0A430A009BFDFE /* Selectors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
62132E571C01F83200084175 /* CSSSelectorTest.h */,
|
||||
62132E581C01F83200084175 /* CSSSelectorTest.m */,
|
||||
621FBE591BDAD68700BC9555 /* CSSSelectorParserTests.m */,
|
||||
628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */,
|
||||
624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */,
|
||||
624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */,
|
||||
62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */,
|
||||
621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */,
|
||||
);
|
||||
name = Selectors;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
@@ -571,45 +727,61 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
624717181B22333200C11912 /* HTMLNodeTraversal.h in Headers */,
|
||||
6235CE9B1AA509430026937B /* NSString+HTMLKit.h in Headers */,
|
||||
62D89DB11AE7081600B6243D /* HTMLTokenizerStates.h in Headers */,
|
||||
62D89DB21AE7081600B6243D /* HTMLTokenizerCharacters.h in Headers */,
|
||||
62D89DB31AE7081600B6243D /* HTMLNamespaces.h in Headers */,
|
||||
62D89DB41AE7081600B6243D /* HTMLElementTypes.h in Headers */,
|
||||
62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */,
|
||||
62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */,
|
||||
62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */,
|
||||
62D89DB01AE7080300B6243D /* HTMLDOM.h in Headers */,
|
||||
62F873EB19E088C90062683C /* HTMLParser.h in Headers */,
|
||||
624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */,
|
||||
62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */,
|
||||
624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */,
|
||||
6235CEA01AA5170A0026937B /* HTMLMarker.h in Headers */,
|
||||
62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */,
|
||||
623406E11ADB04F9004677A3 /* HTMLTemplate.h in Headers */,
|
||||
6234BEEE1AABBF1400DEB15F /* HTMLStackOfOpenElements.h in Headers */,
|
||||
6238C9851AB8D6330006512E /* HTMLKitDOMExceptions.h in Headers */,
|
||||
6238039F1AB63A8C008A53D0 /* HTMLEOFToken.h in Headers */,
|
||||
6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */,
|
||||
62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */,
|
||||
623857911A9E772B003A45D9 /* HTMLDocument.h in Headers */,
|
||||
624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */,
|
||||
62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */,
|
||||
6247A9471B152F8C00CCF25C /* HTMLNodeFilter.h in Headers */,
|
||||
623424881AB467B200726190 /* HTMLOrderedDictionary.h in Headers */,
|
||||
6247A9431B152F4F00CCF25C /* HTMLNodeIterator.h in Headers */,
|
||||
625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */,
|
||||
625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */,
|
||||
6238579B1A9E8934003A45D9 /* HTMLComment.h in Headers */,
|
||||
62AE593519F97D880043F069 /* HTMLParseErrorToken.h in Headers */,
|
||||
62AE594919F9948A0043F069 /* HTMLCharacterToken.h in Headers */,
|
||||
623857961A9E8606003A45D9 /* HTMLDocumentType.h in Headers */,
|
||||
623406E61ADB05AD004677A3 /* HTMLDocumentFragment.h in Headers */,
|
||||
62363C3D1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.h in Headers */,
|
||||
624717BC1B22009200B38302 /* HTMLTreeWalker.h in Headers */,
|
||||
62362A3C1A9FA70400301989 /* HTMLText.h in Headers */,
|
||||
6234584E1A9D2FA4009BD491 /* HTMLNode.h in Headers */,
|
||||
629AA0EA1BDD9C2900D5CC98 /* HTMLKit.h in Headers */,
|
||||
626652F91C03D7AC00C3F121 /* HTMLKitErrorDomain.h in Headers */,
|
||||
629AA0EB1BDD9C2900D5CC98 /* HTMLParser.h in Headers */,
|
||||
629AA0EC1BDD9C2900D5CC98 /* HTMLDOM.h in Headers */,
|
||||
629AA0ED1BDD9C2900D5CC98 /* HTMLNode.h in Headers */,
|
||||
629AA0EE1BDD9C2900D5CC98 /* HTMLDocument.h in Headers */,
|
||||
629AA0EF1BDD9C2900D5CC98 /* HTMLDocumentType.h in Headers */,
|
||||
629AA0F01BDD9C2900D5CC98 /* HTMLDocumentFragment.h in Headers */,
|
||||
629AA0F11BDD9C2900D5CC98 /* HTMLElement.h in Headers */,
|
||||
629AA0F21BDD9C2900D5CC98 /* HTMLComment.h in Headers */,
|
||||
629AA0F31BDD9C2900D5CC98 /* HTMLText.h in Headers */,
|
||||
629AA0F41BDD9C2A00D5CC98 /* HTMLTemplate.h in Headers */,
|
||||
629AA0F51BDD9C2A00D5CC98 /* HTMLNodeIterator.h in Headers */,
|
||||
629AA0F61BDD9C2A00D5CC98 /* HTMLTreeWalker.h in Headers */,
|
||||
629AA0F71BDD9C2A00D5CC98 /* HTMLNodeTraversal.h in Headers */,
|
||||
629AA0F81BDD9C2A00D5CC98 /* HTMLNodeFilter.h in Headers */,
|
||||
629AA0F91BDD9C2A00D5CC98 /* HTMLKitDOMExceptions.h in Headers */,
|
||||
629AA0FA1BDD9C2A00D5CC98 /* HTMLNamespaces.h in Headers */,
|
||||
629AA0FB1BDD9C2A00D5CC98 /* HTMLQuirksMode.h in Headers */,
|
||||
629AA0FC1BDD9C2A00D5CC98 /* NSString+HTMLKit.h in Headers */,
|
||||
629AA0FD1BDD9C2A00D5CC98 /* NSCharacterSet+HTMLKit.h in Headers */,
|
||||
629AA0FE1BDD9C2A00D5CC98 /* HTMLOrderedDictionary.h in Headers */,
|
||||
629AA0FF1BDD9C2A00D5CC98 /* CSSSelectors.h in Headers */,
|
||||
629AA1001BDD9C2A00D5CC98 /* CSSSelectorParser.h in Headers */,
|
||||
629AA11F1BDD9C5E00D5CC98 /* CSSNthExpressionParser.h in Headers */,
|
||||
629AA1011BDD9C2A00D5CC98 /* CSSSelector.h in Headers */,
|
||||
629AA1021BDD9C2B00D5CC98 /* CSSSelectorBlock.h in Headers */,
|
||||
629AA1031BDD9C2B00D5CC98 /* CSSTypeSelector.h in Headers */,
|
||||
629AA1041BDD9C2B00D5CC98 /* CSSAttributeSelector.h in Headers */,
|
||||
629AA1051BDD9C2B00D5CC98 /* CSSPseudoClassSelector.h in Headers */,
|
||||
629AA1061BDD9C2B00D5CC98 /* CSSStructuralPseudoSelectors.h in Headers */,
|
||||
629AA1071BDD9C2B00D5CC98 /* CSSNthExpressionSelector.h in Headers */,
|
||||
629AA1081BDD9C2B00D5CC98 /* CSSPseudoFunctionSelector.h in Headers */,
|
||||
629AA1091BDD9C2B00D5CC98 /* CSSCombinatorSelector.h in Headers */,
|
||||
629AA10A1BDD9C2B00D5CC98 /* CSSCompoundSelector.h in Headers */,
|
||||
629AA10B1BDD9C5200D5CC98 /* HTMLTokenizer.h in Headers */,
|
||||
629AA10C1BDD9C5200D5CC98 /* HTMLTokenizerStates.h in Headers */,
|
||||
629AA10D1BDD9C5300D5CC98 /* HTMLTokenizerCharacters.h in Headers */,
|
||||
629AA10E1BDD9C5300D5CC98 /* HTMLTokenizerEntities.h in Headers */,
|
||||
629AA10F1BDD9C5300D5CC98 /* HTMLTokens.h in Headers */,
|
||||
629AA1101BDD9C5300D5CC98 /* HTMLToken.h in Headers */,
|
||||
629AA1111BDD9C5300D5CC98 /* HTMLCharacterToken.h in Headers */,
|
||||
629AA1121BDD9C5300D5CC98 /* HTMLCommentToken.h in Headers */,
|
||||
629AA1131BDD9C5300D5CC98 /* HTMLDOCTYPEToken.h in Headers */,
|
||||
629AA1141BDD9C5400D5CC98 /* HTMLParseErrorToken.h in Headers */,
|
||||
629AA1151BDD9C5400D5CC98 /* HTMLTagToken.h in Headers */,
|
||||
629AA1161BDD9C5400D5CC98 /* HTMLEOFToken.h in Headers */,
|
||||
629AA1171BDD9C5400D5CC98 /* HTMLStackOfOpenElements.h in Headers */,
|
||||
629AA1181BDD9C5400D5CC98 /* HTMLListOfActiveFormattingElements.h in Headers */,
|
||||
629AA1191BDD9C5400D5CC98 /* HTMLElementTypes.h in Headers */,
|
||||
629AA11A1BDD9C5400D5CC98 /* HTMLElementAdjustment.h in Headers */,
|
||||
629AA11B1BDD9C5500D5CC98 /* HTMLParserInsertionModes.h in Headers */,
|
||||
629AA11C1BDD9C5500D5CC98 /* HTMLMarker.h in Headers */,
|
||||
629AA11D1BDD9C5500D5CC98 /* CSSCodePoints.h in Headers */,
|
||||
629AA11E1BDD9C5500D5CC98 /* CSSInputStream.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -693,7 +865,7 @@
|
||||
625A14A319C7829400AD0C32 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = BrainCookie;
|
||||
TargetAttributes = {
|
||||
625A14C219C7829400AD0C32 = {
|
||||
@@ -739,6 +911,7 @@
|
||||
files = (
|
||||
624AC90F19FC702E00BD3C4A /* HTML Standard.html in Resources */,
|
||||
624AC90519FBFE9A00BD3C4A /* html5lib-tests in Resources */,
|
||||
62132E5D1C021FF200084175 /* css-tests in Resources */,
|
||||
625A14CF19C7829400AD0C32 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -747,6 +920,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62132E5C1C021FF200084175 /* css-tests in Resources */,
|
||||
624AC90619FBFEA000BD3C4A /* html5lib-tests in Resources */,
|
||||
624AC90E19FC702E00BD3C4A /* HTML Standard.html in Resources */,
|
||||
);
|
||||
@@ -759,34 +933,48 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */,
|
||||
62362A3E1A9FA70400301989 /* HTMLText.m in Sources */,
|
||||
622BF5831BBF2FD700363583 /* CSSSelectorParser.m in Sources */,
|
||||
6235CE9D1AA509430026937B /* NSString+HTMLKit.m in Sources */,
|
||||
6247A9451B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */,
|
||||
6238579D1A9E8934003A45D9 /* HTMLComment.m in Sources */,
|
||||
6234BEF01AABBF1400DEB15F /* HTMLStackOfOpenElements.m in Sources */,
|
||||
624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */,
|
||||
6235CEA21AA5170A0026937B /* HTMLMarker.m in Sources */,
|
||||
62FA98051BD57B6200A2AF86 /* CSSSelectors.m in Sources */,
|
||||
6234248A1AB467B200726190 /* HTMLOrderedDictionary.m in Sources */,
|
||||
624717BE1B22009200B38302 /* HTMLTreeWalker.m in Sources */,
|
||||
62AE594119F9907C0043F069 /* HTMLTagToken.m in Sources */,
|
||||
624B37201B24E9BA0010BDDF /* CSSInputStream.m in Sources */,
|
||||
62AE594619F992F30043F069 /* HTMLCommentToken.m in Sources */,
|
||||
62363C3F1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */,
|
||||
62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */,
|
||||
623406E31ADB04F9004677A3 /* HTMLTemplate.m in Sources */,
|
||||
62FA04E51BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */,
|
||||
6238C9871AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */,
|
||||
62FA980A1BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */,
|
||||
628AF6401BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */,
|
||||
6247171A1B22333200C11912 /* HTMLNodeTraversal.m in Sources */,
|
||||
62F873ED19E088C90062683C /* HTMLParser.m in Sources */,
|
||||
623803A11AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */,
|
||||
624B28C61B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */,
|
||||
6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */,
|
||||
620C877D1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */,
|
||||
625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */,
|
||||
628AF6351BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */,
|
||||
623857931A9E772B003A45D9 /* HTMLDocument.m in Sources */,
|
||||
623406E81ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */,
|
||||
624717B91B21FE5400B38302 /* HTMLNodeFilter.m in Sources */,
|
||||
620EE94B1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */,
|
||||
624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */,
|
||||
625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */,
|
||||
624B28BA1B03DA820048D328 /* CSSTypeSelector.m in Sources */,
|
||||
62FC60471BD0519B0042BBE7 /* CSSSelector.m in Sources */,
|
||||
623857981A9E8606003A45D9 /* HTMLDocumentType.m in Sources */,
|
||||
620C877F1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */,
|
||||
62AE594B19F9948A0043F069 /* HTMLCharacterToken.m in Sources */,
|
||||
623458501A9D2FA4009BD491 /* HTMLNode.m in Sources */,
|
||||
624B28C11B0413200048D328 /* CSSAttributeSelector.m in Sources */,
|
||||
62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */,
|
||||
62AE593719F97D880043F069 /* HTMLParseErrorToken.m in Sources */,
|
||||
);
|
||||
@@ -796,11 +984,15 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */,
|
||||
6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
|
||||
62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */,
|
||||
623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */,
|
||||
6247171D1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */,
|
||||
62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */,
|
||||
624AB31B1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */,
|
||||
624B9FB61AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */,
|
||||
624AB3181B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */,
|
||||
6236738F1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */,
|
||||
624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */,
|
||||
624B9FB31AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */,
|
||||
@@ -808,6 +1000,9 @@
|
||||
62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */,
|
||||
6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */,
|
||||
624FC37B1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */,
|
||||
621FBE5B1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */,
|
||||
621FBE5E1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */,
|
||||
628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -816,6 +1011,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62362A3D1A9FA70400301989 /* HTMLText.m in Sources */,
|
||||
622BF5821BBF2FD700363583 /* CSSSelectorParser.m in Sources */,
|
||||
6235CE9C1AA509430026937B /* NSString+HTMLKit.m in Sources */,
|
||||
6247A9441B152F4F00CCF25C /* HTMLNodeIterator.m in Sources */,
|
||||
6238579C1A9E8934003A45D9 /* HTMLComment.m in Sources */,
|
||||
@@ -823,26 +1019,39 @@
|
||||
624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */,
|
||||
6235CEA11AA5170A0026937B /* HTMLMarker.m in Sources */,
|
||||
623424891AB467B200726190 /* HTMLOrderedDictionary.m in Sources */,
|
||||
62FA98041BD57B6200A2AF86 /* CSSSelectors.m in Sources */,
|
||||
624717BD1B22009200B38302 /* HTMLTreeWalker.m in Sources */,
|
||||
62AE594019F9907C0043F069 /* HTMLTagToken.m in Sources */,
|
||||
62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */,
|
||||
624B371F1B24E9BA0010BDDF /* CSSInputStream.m in Sources */,
|
||||
62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */,
|
||||
62363C3E1ABE428200DAB4C6 /* HTMLListOfActiveFormattingElements.m in Sources */,
|
||||
62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */,
|
||||
623406E21ADB04F9004677A3 /* HTMLTemplate.m in Sources */,
|
||||
62FA04E41BCC360D009ABF98 /* CSSCombinatorSelector.m in Sources */,
|
||||
628AF63F1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.m in Sources */,
|
||||
62FA98091BD5A7E200A2AF86 /* CSSSelectorBlock.m in Sources */,
|
||||
6238C9861AB8D6330006512E /* HTMLKitDOMExceptions.m in Sources */,
|
||||
624717191B22333200C11912 /* HTMLNodeTraversal.m in Sources */,
|
||||
62F873EC19E088C90062683C /* HTMLParser.m in Sources */,
|
||||
623803A01AB63A8C008A53D0 /* HTMLEOFToken.m in Sources */,
|
||||
624B28C51B04190D0048D328 /* NSCharacterSet+HTMLKit.m in Sources */,
|
||||
6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */,
|
||||
620C877C1BD44CBE00FB3EEE /* CSSCompoundSelector.m in Sources */,
|
||||
625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */,
|
||||
623857921A9E772B003A45D9 /* HTMLDocument.m in Sources */,
|
||||
623406E71ADB05AD004677A3 /* HTMLDocumentFragment.m in Sources */,
|
||||
624717B81B21FE5400B38302 /* HTMLNodeFilter.m in Sources */,
|
||||
620EE94A1BC46F2A0028ED34 /* CSSPseudoClassSelector.m in Sources */,
|
||||
624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */,
|
||||
625A150219C783DE00AD0C32 /* HTMLKit.m in Sources */,
|
||||
624B28B91B03DA820048D328 /* CSSTypeSelector.m in Sources */,
|
||||
623857971A9E8606003A45D9 /* HTMLDocumentType.m in Sources */,
|
||||
62FC60461BD0519B0042BBE7 /* CSSSelector.m in Sources */,
|
||||
62AE594A19F9948A0043F069 /* HTMLCharacterToken.m in Sources */,
|
||||
620C877E1BD4519A00FB3EEE /* CSSPseudoFunctionSelector.m in Sources */,
|
||||
6234584F1A9D2FA4009BD491 /* HTMLNode.m in Sources */,
|
||||
624B28C01B0413200048D328 /* CSSAttributeSelector.m in Sources */,
|
||||
628AF6341BC9A63D00496128 /* CSSNthExpressionSelector.m in Sources */,
|
||||
62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */,
|
||||
62AE593619F97D880043F069 /* HTMLParseErrorToken.m in Sources */,
|
||||
);
|
||||
@@ -852,11 +1061,15 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62132E591C01F83200084175 /* CSSSelectorTest.m in Sources */,
|
||||
6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
|
||||
62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */,
|
||||
623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */,
|
||||
6247171C1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */,
|
||||
62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */,
|
||||
624AB31A1B050A4D00F3830D /* CSSAttributeSelectorTests.m in Sources */,
|
||||
624B9FB51AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */,
|
||||
624AB3171B0508AE00F3830D /* CSSTypeSelectorTests.m in Sources */,
|
||||
6236738E1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */,
|
||||
624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */,
|
||||
624B9FB21AE0313300646C4C /* HTMLKitStringCategoryTests.m in Sources */,
|
||||
@@ -864,6 +1077,9 @@
|
||||
62D8345919FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */,
|
||||
6239755E1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */,
|
||||
624FC37A1AE591D80015DDF9 /* HTMLKitNodesTests.m in Sources */,
|
||||
621FBE5A1BDAD68700BC9555 /* CSSSelectorParserTests.m in Sources */,
|
||||
621FBE5D1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m in Sources */,
|
||||
628AF62F1BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -919,6 +1135,7 @@
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
@@ -976,12 +1193,14 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
INFOPLIST_FILE = "HTMLKit/HTMLKit-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = HTMLKit;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
@@ -991,12 +1210,14 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
INFOPLIST_FILE = "HTMLKit/HTMLKit-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = HTMLKit;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
@@ -1018,6 +1239,7 @@
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
@@ -1036,6 +1258,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
@@ -1045,6 +1268,7 @@
|
||||
625A14FD19C7834100AD0C32 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DSTROOT = /tmp/HTMLKit.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
@@ -1063,6 +1287,7 @@
|
||||
625A14FE19C7834100AD0C32 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DSTROOT = /tmp/HTMLKit.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
@@ -1091,6 +1316,8 @@
|
||||
);
|
||||
INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
|
||||
OTHER_LDFLAGS = " -ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
@@ -1110,6 +1337,8 @@
|
||||
GCC_PREFIX_HEADER = "HTMLKit/HTMLKit-Prefix.pch";
|
||||
INFOPLIST_FILE = "HTMLKitTests/HTMLKitTests-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
|
||||
OTHER_LDFLAGS = " -ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.braincookie.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:HTMLKit.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// CSSAttributeSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSAttributeSelector : CSSSelector
|
||||
|
||||
@property (nonatomic, assign) CSSAttributeSelectorType type;
|
||||
@property (nonatomic, strong, readonly) NSString *name;
|
||||
@property (nonatomic, strong, readonly) NSString *value;
|
||||
|
||||
+ (instancetype)classSelector:(NSString *)className;
|
||||
+ (instancetype)idSelector:(NSString *)elementId;
|
||||
+ (instancetype)hasAttributeSelector:(NSString *)attributeName;
|
||||
|
||||
- (instancetype)initWithType:(CSSAttributeSelectorType)type
|
||||
attributeName:(NSString *)name
|
||||
attrbiuteValue:(NSString *)value;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// CSSAttributeSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSAttributeSelector.h"
|
||||
#import "HTMLElement.h"
|
||||
#import "NSCharacterSet+HTMLKit.h"
|
||||
|
||||
@interface CSSAttributeSelector ()
|
||||
{
|
||||
CSSAttributeSelectorType _type;
|
||||
NSString *_name;
|
||||
NSString *_value;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSAttributeSelector
|
||||
|
||||
+ (instancetype)classSelector:(NSString *)className
|
||||
{
|
||||
return [[self alloc] initWithType:CSSAttributeSelectorIncludes attributeName:@"class" attrbiuteValue:className];
|
||||
}
|
||||
|
||||
+ (instancetype)idSelector:(NSString *)elementId
|
||||
{
|
||||
return [[self alloc] initWithType:CSSAttributeSelectorExactMatch attributeName:@"id" attrbiuteValue:elementId];
|
||||
}
|
||||
|
||||
+ (instancetype)hasAttributeSelector:(NSString *)attributeName
|
||||
{
|
||||
return [[self alloc] initWithType:CSSAttributeSelectorExists attributeName:attributeName attrbiuteValue:@""];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType:(CSSAttributeSelectorType)type
|
||||
attributeName:(NSString *)name
|
||||
attrbiuteValue:(NSString *)value
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.type = type;
|
||||
_name = [name copy];
|
||||
_value = value ? [value copy]: @"";
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
switch (_type) {
|
||||
case CSSAttributeSelectorExists:
|
||||
{
|
||||
return !!element[_name];
|
||||
}
|
||||
case CSSAttributeSelectorExactMatch:
|
||||
{
|
||||
return [element[_name] isEqualToString:_value];
|
||||
}
|
||||
case CSSAttributeSelectorIncludes:
|
||||
{
|
||||
NSArray *components = [element[_name] componentsSeparatedByCharactersInSet:[NSCharacterSet HTMLWhitespaceCharacterSet]];
|
||||
return [components containsObject:_value];
|
||||
}
|
||||
case CSSAttributeSelectorBegins:
|
||||
{
|
||||
return [element[_name] hasPrefix:_value];
|
||||
}
|
||||
case CSSAttributeSelectorEnds:
|
||||
{
|
||||
return [element[_name] hasSuffix:_value];
|
||||
}
|
||||
case CSSAttributeSelectorContains:
|
||||
{
|
||||
return [element[_name] containsString:_value];
|
||||
}
|
||||
case CSSAttributeSelectorHyphen:
|
||||
{
|
||||
return [element[_name] isEqualToString:_value] || [element[_name] hasPrefix:[_value stringByAppendingString:@"-"]];
|
||||
}
|
||||
case CSSAttributeSelectorNot:
|
||||
{
|
||||
return ![element[_name] isEqualToString:_value];
|
||||
}
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Description
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
if (self.type == CSSAttributeSelectorExists) {
|
||||
return [NSString stringWithFormat:@"[%@]", self.name];
|
||||
}
|
||||
|
||||
NSString *matcher = @{@(CSSAttributeSelectorExactMatch): @"=",
|
||||
@(CSSAttributeSelectorIncludes): @"~=",
|
||||
@(CSSAttributeSelectorBegins): @"^=",
|
||||
@(CSSAttributeSelectorEnds): @"$=",
|
||||
@(CSSAttributeSelectorContains): @"*=",
|
||||
@(CSSAttributeSelectorHyphen): @"|=",
|
||||
@(CSSAttributeSelectorNot): @"!="}[@(self.type)];
|
||||
|
||||
return [NSString stringWithFormat:@"[%@%@'%@']", self.name, matcher, self.value];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// CSSTokenizer CODEPOINTs.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 08/06/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#define CODEPOINTS \
|
||||
CODEPOINT( CONTROL, 0x0080 ) \
|
||||
CODEPOINT( CHARACTER_TABULATION, 0x0009 ) \
|
||||
CODEPOINT( LINE_FEED, 0x000A ) \
|
||||
CODEPOINT( SPACE, 0x0020 ) \
|
||||
CODEPOINT( QUOTATION_MARK, 0x0022 ) \
|
||||
CODEPOINT( NUMBER_SIGN, 0x0023 ) \
|
||||
CODEPOINT( DOLLAR_SIGN, 0x0024 ) \
|
||||
CODEPOINT( APOSTROPHE, 0x0027 ) \
|
||||
CODEPOINT( LEFT_PARENTHESIS, 0x0028 ) \
|
||||
CODEPOINT( RIGHT_PARENTHESIS, 0x0029 ) \
|
||||
CODEPOINT( ASTERIX, 0x002A ) \
|
||||
CODEPOINT( PLUS_SIGN, 0x002B ) \
|
||||
CODEPOINT( COMMA, 0x002C ) \
|
||||
CODEPOINT( HYPHEN_MINUS, 0x002D ) \
|
||||
CODEPOINT( FULL_STOP, 0x002E ) \
|
||||
CODEPOINT( DIGIT_ZERO, 0x0030 ) \
|
||||
CODEPOINT( DIGIT_NINE, 0x0039 ) \
|
||||
CODEPOINT( COLON, 0x003A ) \
|
||||
CODEPOINT( EQUALS_SIGN, 0x003D ) \
|
||||
CODEPOINT( GREATER_THAN_SIGN, 0x003E ) \
|
||||
CODEPOINT( LATIN_CAPITAL_LETTER_A, 0x0041 ) \
|
||||
CODEPOINT( LATIN_CAPITAL_LETTER_F, 0x0046 ) \
|
||||
CODEPOINT( LATIN_CAPITAL_LETTER_Z, 0x005A ) \
|
||||
CODEPOINT( LEFT_SQUARE_BRACKET, 0x005B ) \
|
||||
CODEPOINT( REVERSE_SOLIDUS, 0x005C ) \
|
||||
CODEPOINT( RIGHT_SQUARE_BRACKET, 0x005D ) \
|
||||
CODEPOINT( CIRCUMFLEX_ACCENT, 0x005E ) \
|
||||
CODEPOINT( LOW_LINE, 0x005F ) \
|
||||
CODEPOINT( LATIN_SMALL_LETTER_A, 0x0061 ) \
|
||||
CODEPOINT( LATIN_SMALL_LETTER_F, 0x0066 ) \
|
||||
CODEPOINT( LATIN_SMALL_LETTER_Z, 0x007A ) \
|
||||
CODEPOINT( VERTICAL_LINE, 0x007C ) \
|
||||
CODEPOINT( TILDE, 0x007E ) \
|
||||
CODEPOINT( REPLACEMENT_CHARACTER, 0xFFFD )
|
||||
|
||||
#define CODEPOINT( name, value ) static UniChar const name = value;
|
||||
CODEPOINTS
|
||||
#undef CODEPOINT
|
||||
|
||||
NS_INLINE BOOL isWhitespace(UTF32Char codePoint)
|
||||
{
|
||||
return (codePoint == CHARACTER_TABULATION ||
|
||||
codePoint == LINE_FEED ||
|
||||
codePoint == SPACE);
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isCombinator(UTF32Char codePoint)
|
||||
{
|
||||
return (codePoint == SPACE ||
|
||||
codePoint == PLUS_SIGN ||
|
||||
codePoint == COMMA ||
|
||||
codePoint == GREATER_THAN_SIGN ||
|
||||
codePoint == TILDE);
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isDigit(UTF32Char codePoint)
|
||||
{
|
||||
return codePoint >= DIGIT_ZERO && codePoint <= DIGIT_NINE;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isHexDigit(UTF32Char codePoint)
|
||||
{
|
||||
return ((codePoint >= DIGIT_ZERO && codePoint <= DIGIT_NINE) ||
|
||||
(codePoint >= LATIN_CAPITAL_LETTER_A && codePoint <= LATIN_CAPITAL_LETTER_F) ||
|
||||
(codePoint >= LATIN_SMALL_LETTER_A && codePoint <= LATIN_SMALL_LETTER_F));
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isQuote(UTF32Char codePoint)
|
||||
{
|
||||
return codePoint == QUOTATION_MARK || codePoint == APOSTROPHE;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isNewLine(UTF32Char codePoint)
|
||||
{
|
||||
return codePoint == LINE_FEED;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isNameStart(UTF32Char codePoint)
|
||||
{
|
||||
return ((codePoint >= LATIN_CAPITAL_LETTER_A && codePoint <= LATIN_CAPITAL_LETTER_Z) ||
|
||||
(codePoint >= LATIN_SMALL_LETTER_A && codePoint <= LATIN_SMALL_LETTER_Z) ||
|
||||
codePoint >= CONTROL ||
|
||||
codePoint == LOW_LINE);
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isName(UTF32Char codePoint)
|
||||
{
|
||||
return isNameStart(codePoint) || isDigit(codePoint) || codePoint == HYPHEN_MINUS;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isValidEscape(UTF32Char first, UTF32Char second)
|
||||
{
|
||||
if (first != REVERSE_SOLIDUS || isNewLine(second)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isValidEscapedCodePoint(UTF32Char codePoint)
|
||||
{
|
||||
return (codePoint != 0 &&
|
||||
!(codePoint >= 0xD800 && codePoint <= 0x0DFFF) &&
|
||||
codePoint <= 0x10FFFF);
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isValidIdentifierStart(UTF32Char first, UTF32Char second, UTF32Char third)
|
||||
{
|
||||
if (first == HYPHEN_MINUS) {
|
||||
if (isNameStart(second) ||
|
||||
second == HYPHEN_MINUS ||
|
||||
isValidEscape(second, third)) {
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
} else if (isNameStart(first)) {
|
||||
return YES;
|
||||
} else if (first == REVERSE_SOLIDUS) {
|
||||
return isValidEscape(first, second);
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
NS_INLINE void AppendCodePoint(CFMutableStringRef string, UTF32Char codePoint)
|
||||
{
|
||||
UniChar pair[2];
|
||||
Boolean isPair = CFStringGetSurrogatePairForLongCharacter(codePoint, pair);
|
||||
CFStringAppendCharacters(string, pair, isPair ? 2 : 1);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// CSSCombinatorSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 12/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSCombinatorSelector : CSSSelector
|
||||
|
||||
+ (instancetype)childOfElementCombinator:(CSSSelector *)selector;
|
||||
+ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector;
|
||||
+ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector;
|
||||
+ (instancetype)generalSiblingCombinator:(CSSSelector *)selector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,154 @@
|
||||
//
|
||||
// CSSCombinatorSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 12/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSCombinatorSelector.h"
|
||||
#import "HTMLElement.h"
|
||||
|
||||
#pragma mark - Declarations
|
||||
|
||||
@interface CSSChildOfElementCombinatorSelector : CSSCombinatorSelector
|
||||
@end
|
||||
|
||||
@interface CSSDecendantOfElementCombinatorSelector : CSSCombinatorSelector
|
||||
@end
|
||||
|
||||
@interface CSSAdjacentSiblingCombinatorSelector : CSSCombinatorSelector
|
||||
@end
|
||||
|
||||
@interface CSSGeneralSiblingCombinatorSelector : CSSCombinatorSelector
|
||||
@end
|
||||
|
||||
#pragma mark - Base Combinator
|
||||
|
||||
@interface CSSCombinatorSelector ()
|
||||
{
|
||||
CSSSelector *_selector;
|
||||
}
|
||||
@property (nonatomic, strong, readonly) CSSSelector *selector;
|
||||
@end
|
||||
|
||||
@implementation CSSCombinatorSelector
|
||||
@synthesize selector = _selector;
|
||||
|
||||
+ (instancetype)childOfElementCombinator:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSChildOfElementCombinatorSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
+ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSDecendantOfElementCombinatorSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
+ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSAdjacentSiblingCombinatorSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
+ (instancetype)generalSiblingCombinator:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSGeneralSiblingCombinatorSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSelector:(CSSSelector *)selector
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_selector = selector;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Child OfElement Combinator
|
||||
|
||||
@implementation CSSChildOfElementCombinatorSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
HTMLElement *parent = element.parentElement;
|
||||
return parent != nil && [self.selector acceptElement:parent];
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ > ", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Decendant Of Element Combinator
|
||||
|
||||
@implementation CSSDecendantOfElementCombinatorSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
HTMLElement *parent = element.parentElement;
|
||||
|
||||
while (parent != nil) {
|
||||
if ([self.selector acceptElement:parent]) {
|
||||
return YES;
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ ", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Adjacent Sibling Combinator
|
||||
|
||||
@implementation CSSAdjacentSiblingCombinatorSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
HTMLNode *previous = element.previousSiblingElement;
|
||||
if (previous == nil || previous.nodeType != HTMLNodeElement) {
|
||||
return NO;
|
||||
}
|
||||
return [self.selector acceptElement:previous.asElement];
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ + ", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - General Sibling Combinator
|
||||
|
||||
@implementation CSSGeneralSiblingCombinatorSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
HTMLNode *previous = element.previousSiblingElement;
|
||||
|
||||
while (previous != nil && previous.nodeType == HTMLNodeElement) {
|
||||
if ([self.selector acceptElement:previous.asElement]) {
|
||||
return YES;
|
||||
}
|
||||
previous = previous.previousSiblingElement;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ ~ ", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// CSSCompoundSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 18/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSCompoundSelector : CSSSelector
|
||||
|
||||
+ (instancetype)andSelector:(NSArray<CSSSelector *> *)selectors;
|
||||
+ (instancetype)orSelector:(NSArray<CSSSelector *> *)selectors;
|
||||
|
||||
- (void)addSelector:(CSSSelector *)selector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// CSSCompoundSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 18/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSCompoundSelector.h"
|
||||
|
||||
#pragma mark - Declarations
|
||||
|
||||
@interface CSSAndCompoundSelector : CSSCompoundSelector
|
||||
@end
|
||||
|
||||
@interface CSSOrCompoundSelector : CSSCompoundSelector
|
||||
@end
|
||||
|
||||
#pragma mark - Base Combinator
|
||||
|
||||
@interface CSSCompoundSelector ()
|
||||
{
|
||||
NSMutableArray *_selectors;
|
||||
}
|
||||
@property (nonatomic, strong, readonly) NSArray *selectors;
|
||||
@end
|
||||
|
||||
@implementation CSSCompoundSelector
|
||||
@synthesize selectors = _selectors;
|
||||
|
||||
+ (instancetype)andSelector:(NSArray *)selectors
|
||||
{
|
||||
return [[CSSAndCompoundSelector alloc] initWithSelectors:selectors];
|
||||
}
|
||||
|
||||
+ (instancetype)orSelector:(NSArray *)selectors
|
||||
{
|
||||
return [[CSSOrCompoundSelector alloc] initWithSelectors:selectors];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSelectors:(NSArray *)selectors
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_selectors = [[NSMutableArray alloc] initWithArray:selectors];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addSelector:(CSSSelector *)selector
|
||||
{
|
||||
[_selectors addObject:selector];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - And Compound Selector
|
||||
|
||||
@implementation CSSAndCompoundSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
for (CSSSelector *selector in self.selectors) {
|
||||
if (![selector acceptElement:element]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"];
|
||||
return [descriptions componentsJoinedByString:@""];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Or Compound Selector
|
||||
|
||||
@implementation CSSOrCompoundSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
for (CSSSelector *selector in self.selectors) {
|
||||
if ([selector acceptElement:element]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
NSArray *descriptions = [self.selectors valueForKey:@"debugDescription"];
|
||||
return [descriptions componentsJoinedByString:@","];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// CSSInputStream.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 07/06/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "HTMLInputStreamReader.h"
|
||||
|
||||
@interface CSSInputStream : HTMLInputStreamReader
|
||||
|
||||
- (void)consumeWhitespace;
|
||||
- (NSString *)consumeIdentifier;
|
||||
- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint;
|
||||
- (UTF32Char)consumeEscapedCodePoint;
|
||||
- (NSString *)consumeCombinator;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// CSSInputStream.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 07/06/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSInputStream.h"
|
||||
#import "CSSCodePoints.h"
|
||||
|
||||
@interface HTMLInputStreamReader ()
|
||||
- (void)emitParseError:(NSString *)reason;
|
||||
@end
|
||||
|
||||
@implementation CSSInputStream
|
||||
|
||||
- (void)consumeWhitespace
|
||||
{
|
||||
while (isWhitespace(self.nextInputCharacter)) {
|
||||
[self consumeNextInputCharacter];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)consumeIdentifier
|
||||
{
|
||||
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
|
||||
|
||||
if (!isValidIdentifierStart([self inputCharacterPointAtOffset:0],
|
||||
[self inputCharacterPointAtOffset:1],
|
||||
[self inputCharacterPointAtOffset:2])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
while (YES) {
|
||||
UTF32Char codePoint = [self consumeNextInputCharacter];
|
||||
if (codePoint == EOF) {
|
||||
break;
|
||||
} else if (isName(codePoint)) {
|
||||
AppendCodePoint(value, codePoint);
|
||||
} else if (isValidEscape(codePoint, [self inputCharacterPointAtOffset:1])) {
|
||||
UTF32Char escapedCodePoint = [self consumeEscapedCodePoint];
|
||||
AppendCodePoint(value, escapedCodePoint);
|
||||
} else {
|
||||
[self reconsumeCurrentInputCharacter];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
|
||||
}
|
||||
|
||||
- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint
|
||||
{
|
||||
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
|
||||
|
||||
while (YES) {
|
||||
UTF32Char codePoint = [self consumeNextInputCharacter];
|
||||
if (codePoint == endingCodePoint) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (codePoint) {
|
||||
case EOF:
|
||||
break;
|
||||
case LINE_FEED:
|
||||
[self emitParseError:@"New-line character (0x000A) in CSS attribute value"];
|
||||
[self reconsumeCurrentInputCharacter];
|
||||
break;
|
||||
case REVERSE_SOLIDUS:
|
||||
{
|
||||
UTF32Char next = self.nextInputCharacter;
|
||||
if (next == EOF) {
|
||||
continue;
|
||||
} else if (next == LINE_FEED) {
|
||||
[self consumeNextInputCharacter];
|
||||
} else {
|
||||
UTF32Char escapedCodePoint = [self consumeNextInputCharacter];
|
||||
AppendCodePoint(value, escapedCodePoint);
|
||||
}
|
||||
}
|
||||
default:
|
||||
AppendCodePoint(value, codePoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
|
||||
}
|
||||
|
||||
- (UTF32Char)consumeEscapedCodePoint
|
||||
{
|
||||
UTF32Char codePoint = [self consumeNextInputCharacter];
|
||||
|
||||
if (isHexDigit(codePoint)) {
|
||||
CFMutableStringRef hexString = CFStringCreateMutable(kCFAllocatorDefault, 6);
|
||||
AppendCodePoint(hexString, codePoint);
|
||||
|
||||
while (isHexDigit(self.nextInputCharacter) && CFStringGetLength(hexString) <= 6) {
|
||||
UniChar codePoint = [self consumeNextInputCharacter];
|
||||
CFStringAppendCharacters(hexString, &codePoint, 1);
|
||||
}
|
||||
|
||||
if (isWhitespace(self.nextInputCharacter)) {
|
||||
[self consumeNextInputCharacter];
|
||||
}
|
||||
|
||||
NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexString)];
|
||||
UTF32Char number;
|
||||
[scanner scanHexInt:&number];
|
||||
|
||||
return isValidEscapedCodePoint(number) ? number : REPLACEMENT_CHARACTER;
|
||||
} else if (codePoint == EOF) {
|
||||
return REPLACEMENT_CHARACTER;
|
||||
}
|
||||
|
||||
return codePoint;
|
||||
}
|
||||
|
||||
- (NSString *)consumeCombinator
|
||||
{
|
||||
NSString *combinator = [self consumeCharactersInString:@" >+~"];
|
||||
combinator = [combinator stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
|
||||
return combinator;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// CSSNthExpression.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 10/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CSSSelectors.h"
|
||||
|
||||
@interface CSSNthExpressionParser : NSObject
|
||||
|
||||
+ (CSSNthExpression)parseExpression:(NSString *)expression;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// CSSNthExpression.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 10/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSNthExpressionParser.h"
|
||||
#import "CSSCodePoints.h"
|
||||
#import "NSString+HTMLKit.h"
|
||||
#import "NSCharacterSet+HTMLKit.h"
|
||||
|
||||
@implementation CSSNthExpressionParser
|
||||
|
||||
+ (CSSNthExpression)parseExpression:(NSString *)expression
|
||||
{
|
||||
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
|
||||
NSString *string = [expression.lowercaseString copy];
|
||||
string = [[string stringByTrimmingCharactersInSet:whitespace] copy];
|
||||
|
||||
if ([string isEqualToStringIgnoringCase:@"odd"]) {
|
||||
return CSSNthExpressionOdd;
|
||||
} else if ([string isEqualToStringIgnoringCase:@"even"]) {
|
||||
return CSSNthExpressionEven;
|
||||
}
|
||||
|
||||
NSCharacterSet *set = [[NSCharacterSet CSSNthExpressionCharacterSet] invertedSet];
|
||||
if ([string rangeOfCharacterFromSet:set].location != NSNotFound) {
|
||||
return CSSNthExpressionMake(0, 0);
|
||||
}
|
||||
NSArray *parts = [string componentsSeparatedByString:@"n"];
|
||||
|
||||
if (parts.count == 1) {
|
||||
NSInteger b = [parts[0] integerValue];
|
||||
return CSSNthExpressionMake(0, b);
|
||||
} else if (parts.count == 2) {
|
||||
NSInteger a = [parts[0] integerValue];
|
||||
if (a == 0) {
|
||||
a = [parts[0] isEqualToString:@"-"] ? -1 : 1;
|
||||
}
|
||||
NSInteger b = [parts[1] integerValue];
|
||||
return CSSNthExpressionMake(a, b);
|
||||
} else {
|
||||
return CSSNthExpressionMake(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// CSSNthExpressionSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 10/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSNthExpressionSelector : CSSSelector
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *className;
|
||||
@property (nonatomic, assign, readonly) CSSNthExpression expression;
|
||||
|
||||
+ (instancetype)nthChildSelector:(CSSNthExpression)expression;
|
||||
+ (instancetype)nthLastChildSelector:(CSSNthExpression)expression;
|
||||
+ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression;
|
||||
+ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// CSSNthExpressionSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 10/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSNthExpressionSelector.h"
|
||||
#import "HTMLElement.h"
|
||||
|
||||
#pragma mark - Nth-Expression
|
||||
|
||||
const CSSNthExpression CSSNthExpressionOdd = (CSSNthExpression) {
|
||||
.an = 2, .b = 1
|
||||
};
|
||||
|
||||
const CSSNthExpression CSSNthExpressionEven = (CSSNthExpression) {
|
||||
.an = 2, .b = 0
|
||||
};
|
||||
|
||||
NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression)
|
||||
{
|
||||
if (expression.an == 0 && expression.b == 0) {
|
||||
return @"invalid";
|
||||
}
|
||||
|
||||
if (expression.an == 0) {
|
||||
return [NSString stringWithFormat:@"%ld", expression.b];
|
||||
}
|
||||
if (expression.b == 0) {
|
||||
return [NSString stringWithFormat:@"%ldn", expression.an];
|
||||
}
|
||||
|
||||
return [NSString stringWithFormat:@"%ldn%+ld", expression.an, expression.b];
|
||||
}
|
||||
|
||||
#pragma mark - Implementation
|
||||
|
||||
NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element)
|
||||
{
|
||||
NSInteger index = 0;
|
||||
for (HTMLNode *node in enumerator) {
|
||||
if (node.nodeType != HTMLNodeElement) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([node.asElement.tagName isEqualToString:element.tagName]) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (node == element) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
@interface CSSNthExpressionSelector ()
|
||||
{
|
||||
NSString *_className;
|
||||
CSSNthExpression _expression;
|
||||
NSInteger (^ _computeIndex)(HTMLElement *);
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSNthExpressionSelector
|
||||
@synthesize expression = _expression;
|
||||
@synthesize className = _className;
|
||||
|
||||
+ (instancetype)nthChildSelector:(CSSNthExpression)expression
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"nth-child" expression:expression block:^NSInteger(HTMLElement *element) {
|
||||
return [element.parentElement indexOfChildElement:element] + 1;
|
||||
}];
|
||||
}
|
||||
|
||||
+ (instancetype)nthLastChildSelector:(CSSNthExpression)expression
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"nth-last-child" expression:expression block:^NSInteger(HTMLElement *element) {
|
||||
return element.parentElement.childElementsCount - [element.parentElement indexOfChildElement:element];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"nth-of-type" expression:expression block:^NSInteger(HTMLElement *element) {
|
||||
return computeIndex(element.parentElement.childNodes.array.objectEnumerator, element);
|
||||
}];
|
||||
}
|
||||
|
||||
+ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"nth-last-of-type" expression:expression block:^NSInteger(HTMLElement *element) {
|
||||
return computeIndex(element.parentElement.childNodes.array.reverseObjectEnumerator, element);
|
||||
}];
|
||||
}
|
||||
|
||||
- (instancetype)initWithClassName:(NSString *)className
|
||||
expression:(CSSNthExpression)expression
|
||||
block:(NSInteger (^)(HTMLElement *element))block
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_className = [className copy];
|
||||
_expression = expression;
|
||||
_computeIndex = [block copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
NSInteger index = _computeIndex(element);
|
||||
|
||||
if (_expression.an == 0) {
|
||||
return index == _expression.b;
|
||||
} else {
|
||||
NSInteger diff = (index - _expression.b);
|
||||
return (diff * _expression.an >= 0) && (diff % _expression.an == 0);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@":%@(%@)", self.className, NSStringFromNthExpression(self.expression)];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// CSSPseudoClassSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 06/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSPseudoClassSelector : CSSSelector
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *className;
|
||||
|
||||
- (instancetype)initWithClassName:(NSString *)className selector:(CSSSelector *)selector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// CSSPseudoClassSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 06/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSPseudoClassSelector.h"
|
||||
|
||||
@interface CSSPseudoClassSelector ()
|
||||
{
|
||||
NSString *_className;
|
||||
CSSSelector *_selector;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSPseudoClassSelector
|
||||
@synthesize className = _className;
|
||||
|
||||
- (instancetype)initWithClassName:(NSString *)className selector:(CSSSelector *)selector
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_className = [className copy];
|
||||
_selector = selector;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
return [_selector acceptElement:element];
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@":%@", self.className];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// CSSPseudoFunctionSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 07/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSPseudoFunctionSelector : CSSSelector
|
||||
|
||||
+ (instancetype)notSelector:(CSSSelector *)selector;
|
||||
+ (instancetype)hasSelector:(CSSSelector *)selector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// CSSPseudoFunctionSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 07/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSPseudoFunctionSelector.h"
|
||||
#import "HTMLElement.h"
|
||||
|
||||
#pragma mark - Declarations
|
||||
|
||||
@interface CSSNotSelector : CSSPseudoFunctionSelector
|
||||
@end
|
||||
|
||||
@interface CSSHasSelector : CSSPseudoFunctionSelector
|
||||
@end
|
||||
|
||||
#pragma mark - Base Function Selector
|
||||
|
||||
@interface CSSPseudoFunctionSelector ()
|
||||
{
|
||||
CSSSelector *_selector;
|
||||
}
|
||||
@property (nonatomic, strong, readonly) CSSSelector *selector;
|
||||
@end
|
||||
|
||||
@implementation CSSPseudoFunctionSelector
|
||||
@synthesize selector = _selector;
|
||||
|
||||
+ (instancetype)notSelector:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSNotSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
+ (instancetype)hasSelector:(CSSSelector *)selector
|
||||
{
|
||||
return [[CSSHasSelector alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSelector:(CSSSelector *)selector
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_selector = selector;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Not Selector
|
||||
|
||||
@implementation CSSNotSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
return ![self.selector acceptElement:element];
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@":not(%@)", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Has Selector
|
||||
|
||||
@implementation CSSHasSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
for (HTMLNode *child in element.childNodes) {
|
||||
if (child.nodeType == HTMLNodeElement && [self.selector acceptElement:child.asElement]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return [NSString stringWithFormat:@":has(%@)", self.selector.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// HTMLSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 02/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#pragma mark - Attribute Selector Type
|
||||
|
||||
typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType)
|
||||
{
|
||||
CSSAttributeSelectorExists,
|
||||
CSSAttributeSelectorExactMatch,
|
||||
CSSAttributeSelectorIncludes,
|
||||
CSSAttributeSelectorBegins,
|
||||
CSSAttributeSelectorEnds,
|
||||
CSSAttributeSelectorContains,
|
||||
CSSAttributeSelectorHyphen,
|
||||
CSSAttributeSelectorNot
|
||||
};
|
||||
|
||||
#pragma mark - CSS Nth-Expression
|
||||
|
||||
typedef struct CSSNthExpression
|
||||
{
|
||||
NSInteger an;
|
||||
NSInteger b;
|
||||
} CSSNthExpression;
|
||||
|
||||
NS_INLINE CSSNthExpression CSSNthExpressionMake(NSInteger an, NSInteger b) {
|
||||
return (CSSNthExpression){ .an = an, .b = b };
|
||||
}
|
||||
|
||||
extern const CSSNthExpression CSSNthExpressionOdd;
|
||||
extern const CSSNthExpression CSSNthExpressionEven;
|
||||
extern NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression);
|
||||
|
||||
#pragma mark - Base Selector Class
|
||||
|
||||
@class HTMLElement;
|
||||
|
||||
@interface CSSSelector : NSObject
|
||||
|
||||
- (BOOL)acceptElement:(nonnull HTMLElement *)element;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// CSSSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 15/10/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CSSSelector.h"
|
||||
|
||||
@implementation CSSSelector
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Description
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
[self doesNotRecognizeSelector:_cmd];
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.debugDescription];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// CSSSelectorBlock.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 20/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class HTMLElement;
|
||||
|
||||
@interface CSSSelectorBlock : CSSSelector
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name block:(BOOL (^)(HTMLElement *))block;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// CSSSelectorBlock.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 20/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelectorBlock.h"
|
||||
|
||||
@interface CSSSelectorBlock ()
|
||||
{
|
||||
NSString *_name;
|
||||
BOOL (^ _acceptBlock)(HTMLElement *);
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSSelectorBlock
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name block:(BOOL (^)(HTMLElement *))block
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_name = [name copy];
|
||||
_acceptBlock = [block copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
return _acceptBlock ? _acceptBlock(element) : NO;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// CSSSelectorParser.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 02/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class CSSSelector;
|
||||
|
||||
@interface CSSSelectorParser : NSObject
|
||||
|
||||
+ (CSSSelector *)parseSelector:(NSString *)string error:(NSError **)error;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,367 @@
|
||||
//
|
||||
// CSSSelectorParser.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 02/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelectorParser.h"
|
||||
#import "CSSInputStream.h"
|
||||
#import "CSSCodePoints.h"
|
||||
#import "CSSSelectors.h"
|
||||
#import "NSString+HTMLKit.h"
|
||||
#import "NSCharacterSet+HTMLKit.h"
|
||||
#import "CSSNthExpressionParser.h"
|
||||
#import "CSSCompoundSelector.h"
|
||||
#import "HTMLKitErrorDomain.h"
|
||||
|
||||
@interface CSSSelectorParser ()
|
||||
{
|
||||
NSString *_string;
|
||||
CSSInputStream *_inputStream;
|
||||
NSUInteger _location;
|
||||
|
||||
NSMutableArray *_selectors;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSSelectorParser
|
||||
|
||||
+ (CSSSelector *)parseSelector:(NSString *)string error:(NSError * __autoreleasing *)error
|
||||
{
|
||||
CSSSelectorParser *parser = [[CSSSelectorParser alloc] initWithString:string];
|
||||
CSSSelector *selector = [parser parse:error];
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
#pragma mark - Init
|
||||
|
||||
- (instancetype)initWithString:(NSString *)string
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_string = [self preprocessInput:string];
|
||||
_location = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)preprocessInput:(NSString *)string
|
||||
{
|
||||
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
string = [string stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"];
|
||||
string = [string stringByReplacingOccurrencesOfString:@"\r" withString:@"\n"];
|
||||
string = [string stringByReplacingOccurrencesOfString:@"\f" withString:@"\n"];
|
||||
string = [string stringByReplacingOccurrencesOfString:@"\0" withString:@"\uFFFD"];
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
#pragma mark - Errors
|
||||
|
||||
- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason location:(NSUInteger)location
|
||||
{
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: @"Error parsing selector",
|
||||
NSLocalizedFailureReasonErrorKey: reason,
|
||||
CSSSelectorStringKey: _string,
|
||||
CSSSelectorErrorLocationKey: @(location)
|
||||
};
|
||||
|
||||
if(error) {
|
||||
*error = [NSError errorWithDomain:HTMLKitSelectorErrorDomain code:HTMLKitSelectorParseError userInfo:userInfo];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Parsing
|
||||
|
||||
- (CSSSelector *)parse:(NSError * __autoreleasing *)error
|
||||
{
|
||||
if (_string.length == 0) {
|
||||
[self emitError:error reason:@"Empty selector" location:0];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSArray *allSubSelectors = [_string componentsSeparatedByString:@","];
|
||||
NSMutableArray *parsed = [NSMutableArray array];
|
||||
|
||||
for (NSString *subSelector in allSubSelectors) {
|
||||
if ([subSelector isEqualToString:@""]) {
|
||||
[self emitError:error reason:@"Empty selector" location:_location];
|
||||
break;
|
||||
}
|
||||
|
||||
CSSSelector *selector = [self parseSelector:subSelector error:error];
|
||||
if (selector == nil) {
|
||||
break;
|
||||
}
|
||||
[parsed addObject:selector];
|
||||
|
||||
_location += subSelector.length;
|
||||
}
|
||||
|
||||
if (*error != nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (parsed.count > 1) {
|
||||
return anyOf(parsed);
|
||||
}
|
||||
|
||||
return parsed.firstObject;
|
||||
}
|
||||
|
||||
- (CSSSelector *)parseSelector:(NSString *)selectorString error:(NSError * __autoreleasing *)error
|
||||
{
|
||||
_inputStream = [[CSSInputStream alloc] initWithString:selectorString];
|
||||
[_inputStream consumeWhitespace];
|
||||
|
||||
CSSSelector *result = nil;
|
||||
|
||||
while (YES) {
|
||||
CSSSelector *selector = [self parseSequenceOfSimpleSelectors:error];
|
||||
if (selector == nil) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = result ? allOf(@[result, selector]) : selector;
|
||||
|
||||
UTF32Char next = _inputStream.nextInputCharacter;
|
||||
|
||||
if (isCombinator(next)) {
|
||||
NSString *combinator = [_inputStream consumeCombinator];
|
||||
|
||||
if ([combinator isEqualToString:@""]) {
|
||||
result = descendantOfElementSelector(result);
|
||||
} else if ([combinator isEqualToString:@">"]) {
|
||||
result = childOfElementSelector(result);
|
||||
} else if ([combinator isEqualToString:@"+"]) {
|
||||
result = adjacentSiblingSelector(result);
|
||||
} else if ([combinator isEqualToString:@"~"]) {
|
||||
result = generalSiblingSelector(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (CSSSelector *)parseSequenceOfSimpleSelectors:(NSError * __autoreleasing *)error
|
||||
{
|
||||
NSMutableArray *selectors = [NSMutableArray array];
|
||||
|
||||
CSSSelector *typeSelector = [self parseTypeSelector:error];
|
||||
if (typeSelector != nil) {
|
||||
[selectors addObject:typeSelector];
|
||||
}
|
||||
|
||||
while (YES) {
|
||||
UTF32Char next = _inputStream.nextInputCharacter;
|
||||
if (next == EOF || isCombinator(next)) {
|
||||
break;
|
||||
}
|
||||
|
||||
CSSSelector *simpleSelector = [self parseSimpleSelector:error];
|
||||
if (simpleSelector == nil) {
|
||||
return nil;
|
||||
}
|
||||
[selectors addObject:simpleSelector];
|
||||
}
|
||||
|
||||
if (selectors.count > 1) {
|
||||
return allOf(selectors);
|
||||
}
|
||||
|
||||
return selectors.firstObject;
|
||||
}
|
||||
|
||||
- (CSSSelector *)parseTypeSelector:(NSError * __autoreleasing *)error
|
||||
{
|
||||
NSString *identifier = [_inputStream consumeIdentifier];
|
||||
if (identifier != nil) {
|
||||
return typeSelector(identifier);
|
||||
}
|
||||
|
||||
if ([_inputStream consumeCharacter:ASTERIX]) {
|
||||
return universalSelector();
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CSSSelector *)parseSimpleSelector:(NSError * __autoreleasing *)error
|
||||
{
|
||||
CSSSelector *typeSelector = [self parseTypeSelector:error];
|
||||
if (typeSelector != nil) {
|
||||
return typeSelector;
|
||||
}
|
||||
|
||||
UTF32Char codePoint = [_inputStream consumeNextInputCharacter];
|
||||
switch (codePoint) {
|
||||
case NUMBER_SIGN:
|
||||
{
|
||||
NSString *elementId = [_inputStream consumeIdentifier];
|
||||
if (elementId == nil) {
|
||||
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
|
||||
return nil;
|
||||
}
|
||||
return idSelector(elementId);
|
||||
}
|
||||
case FULL_STOP:
|
||||
{
|
||||
NSString *className = [_inputStream consumeIdentifier];
|
||||
if (className == nil) {
|
||||
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
|
||||
return nil;
|
||||
}
|
||||
return classSelector(className);
|
||||
}
|
||||
case LEFT_SQUARE_BRACKET:
|
||||
{
|
||||
return [self parseAttributeSelector:error];
|
||||
}
|
||||
case COLON:
|
||||
{
|
||||
return [self parsePseudoSelector:error];
|
||||
}
|
||||
default:
|
||||
{
|
||||
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (CSSSelector *)parseAttributeSelector:(NSError * __autoreleasing *)error
|
||||
{
|
||||
NSString *attribute = [_inputStream consumeIdentifier];
|
||||
if (attribute == nil) {
|
||||
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation + 1];
|
||||
return nil;
|
||||
}
|
||||
[_inputStream consumeWhitespace];
|
||||
|
||||
CSSAttributeSelectorType type = CSSAttributeSelectorExists;
|
||||
|
||||
NSString *operator = [_inputStream consumeCharactersInString:@"=~|^$*!"];
|
||||
|
||||
if ([operator isEqualToString:@"="]) {
|
||||
type = CSSAttributeSelectorExactMatch;
|
||||
} else if ([operator isEqualToString:@"~="]) {
|
||||
type = CSSAttributeSelectorIncludes;
|
||||
} else if ([operator isEqualToString:@"|="]) {
|
||||
type = CSSAttributeSelectorHyphen;
|
||||
} else if ([operator isEqualToString:@"^="]) {
|
||||
type = CSSAttributeSelectorBegins;
|
||||
} else if ([operator isEqualToString:@"$="]) {
|
||||
type = CSSAttributeSelectorEnds;
|
||||
} else if ([operator isEqualToString:@"*="]) {
|
||||
type = CSSAttributeSelectorContains;
|
||||
} else if ([operator isEqualToString:@"!="]) {
|
||||
type = CSSAttributeSelectorNot;
|
||||
}
|
||||
|
||||
NSString *value = nil;
|
||||
[_inputStream consumeWhitespace];
|
||||
|
||||
UTF32Char next = _inputStream.nextInputCharacter;
|
||||
if (isQuote(next)) {
|
||||
UTF32Char quote = [_inputStream consumeNextInputCharacter];
|
||||
value = [_inputStream consumeStringWithEndingCodePoint:quote];
|
||||
} else {
|
||||
value = [_inputStream consumeIdentifier];
|
||||
}
|
||||
|
||||
[_inputStream consumeWhitespace];
|
||||
|
||||
// Consume RIGHT_SQUARE_BRACKET
|
||||
if (![_inputStream consumeCharacter:RIGHT_SQUARE_BRACKET]) {
|
||||
[self emitError:error reason:@"Expected closing right square bracket ']'" location:_location + _inputStream.currentLocation];
|
||||
}
|
||||
|
||||
if (type == CSSAttributeSelectorExists) {
|
||||
return hasAttributeSelector(attribute);
|
||||
}
|
||||
|
||||
return attributeSelector(type, attribute, value);
|
||||
}
|
||||
|
||||
- (CSSSelector *)parsePseudoSelector:(NSError * __autoreleasing *)error
|
||||
{
|
||||
NSString *pseudoClass = [_inputStream consumeIdentifier];
|
||||
|
||||
if ([pseudoClass hasPrefix:@"nth"]) {
|
||||
[_inputStream consumeWhitespace];
|
||||
if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) {
|
||||
[self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation];
|
||||
}
|
||||
|
||||
NSString *functionExpression = [_inputStream consumeCharactersUpToString:@")"];
|
||||
CSSNthExpression expression = [CSSNthExpressionParser parseExpression:functionExpression];
|
||||
|
||||
[_inputStream consumeWhitespace];
|
||||
if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) {
|
||||
[self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation];
|
||||
}
|
||||
|
||||
if ([pseudoClass isEqualToString:@"nth-child"]) {
|
||||
return nthChildSelector(expression);
|
||||
} else if ([pseudoClass isEqualToString:@"nth-last-child"]) {
|
||||
return nthLastChildSelector(expression);
|
||||
} else if ([pseudoClass isEqualToString:@"nth-of-type"]) {
|
||||
return nthOfTypeSelector(expression);
|
||||
} else if ([pseudoClass isEqualToString:@"nth-last-of-type"]) {
|
||||
return nthLastOfTypeSelector(expression);
|
||||
}
|
||||
} else if ([pseudoClass isEqualToString:@"not"]) {
|
||||
[_inputStream consumeWhitespace];
|
||||
if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) {
|
||||
[self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation];
|
||||
}
|
||||
|
||||
CSSSelector *subSelector = [self parseSimpleSelector:error];
|
||||
[_inputStream consumeWhitespace];
|
||||
if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) {
|
||||
[self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation];
|
||||
}
|
||||
|
||||
return nay(subSelector);
|
||||
} else {
|
||||
if ([pseudoClass isEqualToString:@"even"]) {
|
||||
return evenSlector();
|
||||
} else if ([pseudoClass isEqualToString:@"odd"]) {
|
||||
return oddSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"first-child"]) {
|
||||
return firstChildSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"last-child"]) {
|
||||
return lastChildSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"first-of-type"]) {
|
||||
return firstOfTypeSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"last-of-type"]) {
|
||||
return lastOfTypeSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"only-child"]) {
|
||||
return onlyChildSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"only-of-type"]) {
|
||||
return onlyOfTypeSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"root"]) {
|
||||
return rootSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"empty"]) {
|
||||
return emptySelector();
|
||||
} else if ([pseudoClass isEqualToString:@"link"]) {
|
||||
return linkSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"enabled"]) {
|
||||
return enabledSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"disabled"]) {
|
||||
return disabledSelector();
|
||||
} else if ([pseudoClass isEqualToString:@"checked"]) {
|
||||
return checkedSelector();
|
||||
}
|
||||
}
|
||||
NSString *reason = [NSString stringWithFormat:@"Unknown pseudo class: %@", pseudoClass];
|
||||
[self emitError:error reason:reason location:_location + _inputStream.currentLocation];
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// CSSSelectors.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelector.h"
|
||||
#import "CSSStructuralPseudoSelectors.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#pragma mark - Type Selectors
|
||||
|
||||
extern CSSSelector * universalSelector();
|
||||
extern CSSSelector * typeSelector(NSString *type);
|
||||
|
||||
#pragma mark - Atribute Selectors
|
||||
|
||||
extern CSSSelector * idSelector(NSString *elementId);
|
||||
extern CSSSelector * classSelector(NSString *className);
|
||||
extern CSSSelector * hasAttributeSelector(NSString *attribute);
|
||||
extern CSSSelector * attributeSelector(CSSAttributeSelectorType type,
|
||||
NSString *attribute,
|
||||
NSString *value);
|
||||
|
||||
#pragma mark - Nth-Expression Selectors
|
||||
|
||||
extern CSSSelector * nthChildSelector(CSSNthExpression expression);
|
||||
extern CSSSelector * nthLastChildSelector(CSSNthExpression expression);
|
||||
extern CSSSelector * nthOfTypeSelector(CSSNthExpression expression);
|
||||
extern CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression);
|
||||
|
||||
extern CSSSelector * oddSelector();
|
||||
extern CSSSelector * evenSlector();
|
||||
|
||||
extern CSSSelector * firstChildSelector();
|
||||
extern CSSSelector * lastChildSelector();
|
||||
extern CSSSelector * firstOfTypeSelector();
|
||||
extern CSSSelector * lastOfTypeSelector();
|
||||
|
||||
extern CSSSelector * onlyChildSelector();
|
||||
extern CSSSelector * onlyOfTypeSelector();
|
||||
|
||||
#pragma mark - Combinators
|
||||
|
||||
extern CSSSelector * childOfElementSelector(CSSSelector *selector);
|
||||
extern CSSSelector * descendantOfElementSelector(CSSSelector *selector);
|
||||
extern CSSSelector * adjacentSiblingSelector(CSSSelector *selector);
|
||||
extern CSSSelector * generalSiblingSelector(CSSSelector *selector);
|
||||
|
||||
#pragma mark - Pseudo Functions
|
||||
|
||||
extern CSSSelector * nay(CSSSelector *selector);
|
||||
extern CSSSelector * has(CSSSelector *selector);
|
||||
|
||||
#pragma mark - Compound Selectors
|
||||
|
||||
extern CSSSelector * allOf(NSArray<CSSSelector *> *selectors);
|
||||
extern CSSSelector * anyOf(NSArray<CSSSelector *> *selectors);
|
||||
|
||||
#pragma mark - Pseudo
|
||||
|
||||
extern CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector);
|
||||
|
||||
#pragma mark - Block
|
||||
|
||||
extern CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element));
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// CSSSelectors.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 19/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelectors.h"
|
||||
#import "CSSTypeSelector.h"
|
||||
#import "CSSAttributeSelector.h"
|
||||
#import "CSSPseudoClassSelector.h"
|
||||
#import "CSSPseudoFunctionSelector.h"
|
||||
#import "CSSNthExpressionSelector.h"
|
||||
#import "CSSCombinatorSelector.h"
|
||||
#import "CSSCompoundSelector.h"
|
||||
#import "CSSSelectorBlock.h"
|
||||
|
||||
#pragma mark - Type Selectors
|
||||
|
||||
CSSSelector * universalSelector()
|
||||
{
|
||||
return [CSSTypeSelector universalSelector];
|
||||
}
|
||||
|
||||
CSSSelector * typeSelector(NSString *type)
|
||||
{
|
||||
return [[CSSTypeSelector alloc] initWithType:type];
|
||||
}
|
||||
|
||||
#pragma mark - Atribute Selectors
|
||||
|
||||
CSSSelector * idSelector(NSString *elementId)
|
||||
{
|
||||
return [CSSAttributeSelector idSelector:elementId];
|
||||
}
|
||||
|
||||
CSSSelector * classSelector(NSString *className)
|
||||
{
|
||||
return [CSSAttributeSelector classSelector:className];
|
||||
}
|
||||
|
||||
CSSSelector * hasAttributeSelector(NSString *attribute)
|
||||
{
|
||||
return [CSSAttributeSelector hasAttributeSelector:attribute];
|
||||
}
|
||||
|
||||
CSSSelector * attributeSelector(CSSAttributeSelectorType type,
|
||||
NSString *attribute,
|
||||
NSString *value)
|
||||
{
|
||||
return [[CSSAttributeSelector alloc] initWithType:type attributeName:attribute attrbiuteValue:value];
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Expression Selectors
|
||||
|
||||
CSSSelector * nthChildSelector(CSSNthExpression expression)
|
||||
{
|
||||
return [CSSNthExpressionSelector nthChildSelector:expression];
|
||||
}
|
||||
|
||||
CSSSelector * nthLastChildSelector(CSSNthExpression expression)
|
||||
{
|
||||
return [CSSNthExpressionSelector nthLastChildSelector:expression];
|
||||
}
|
||||
|
||||
CSSSelector * nthOfTypeSelector(CSSNthExpression expression)
|
||||
{
|
||||
return [CSSNthExpressionSelector nthOfTypeSelector:expression];
|
||||
}
|
||||
|
||||
CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression)
|
||||
{
|
||||
return [CSSNthExpressionSelector nthLastOfTypeSelector:expression];
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Expression Shorthand
|
||||
|
||||
CSSSelector * oddSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"odd", nthChildSelector(CSSNthExpressionOdd));
|
||||
}
|
||||
|
||||
CSSSelector * evenSlector()
|
||||
{
|
||||
return namedPseudoSelector(@"even", nthChildSelector(CSSNthExpressionEven));
|
||||
}
|
||||
|
||||
CSSSelector * firstChildSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"first-child", nthChildSelector(CSSNthExpressionMake(0, 1)));
|
||||
}
|
||||
|
||||
CSSSelector * lastChildSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"last-child", nthLastChildSelector(CSSNthExpressionMake(0, 1)));
|
||||
}
|
||||
|
||||
CSSSelector * firstOfTypeSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"first-of-type", nthOfTypeSelector(CSSNthExpressionMake(0, 1)));
|
||||
}
|
||||
|
||||
CSSSelector * lastOfTypeSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"last-of-type", nthLastOfTypeSelector(CSSNthExpressionMake(0, 1)));
|
||||
}
|
||||
|
||||
CSSSelector * onlyChildSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"only-child", allOf(@[firstChildSelector(), lastChildSelector()]));
|
||||
}
|
||||
|
||||
CSSSelector * onlyOfTypeSelector()
|
||||
{
|
||||
return namedPseudoSelector(@"only-of-type", allOf(@[firstOfTypeSelector(), lastOfTypeSelector()]));
|
||||
}
|
||||
|
||||
#pragma mark - Combinators
|
||||
|
||||
CSSSelector * childOfElementSelector(CSSSelector *selector)
|
||||
{
|
||||
return [CSSCombinatorSelector childOfElementCombinator:selector];
|
||||
}
|
||||
|
||||
CSSSelector * descendantOfElementSelector(CSSSelector *selector)
|
||||
{
|
||||
return [CSSCombinatorSelector descendantOfElementCombinator:selector];
|
||||
}
|
||||
|
||||
CSSSelector * adjacentSiblingSelector(CSSSelector *selector)
|
||||
{
|
||||
return [CSSCombinatorSelector adjacentSiblingCombinator:selector];
|
||||
}
|
||||
|
||||
CSSSelector * generalSiblingSelector(CSSSelector *selector)
|
||||
{
|
||||
return [CSSCombinatorSelector generalSiblingCombinator:selector];
|
||||
}
|
||||
|
||||
#pragma mark - Pseudo Functions
|
||||
|
||||
CSSSelector * nay(CSSSelector *selector)
|
||||
{
|
||||
return [CSSPseudoFunctionSelector notSelector:selector];
|
||||
}
|
||||
|
||||
CSSSelector * has(CSSSelector *selector)
|
||||
{
|
||||
return [CSSPseudoFunctionSelector hasSelector:selector];
|
||||
}
|
||||
|
||||
#pragma mark - Compound Selectors
|
||||
|
||||
CSSSelector * allOf( NSArray<CSSSelector *> * selectors)
|
||||
{
|
||||
return [CSSCompoundSelector andSelector:selectors];
|
||||
}
|
||||
|
||||
CSSSelector * anyOf( NSArray<CSSSelector *> * selectors)
|
||||
{
|
||||
return [CSSCompoundSelector orSelector:selectors];
|
||||
}
|
||||
|
||||
#pragma mark - Pseudo
|
||||
|
||||
CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector)
|
||||
{
|
||||
return [[CSSPseudoClassSelector alloc] initWithClassName:name selector:selector];
|
||||
}
|
||||
|
||||
#pragma mark - Block
|
||||
|
||||
CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element))
|
||||
{
|
||||
return [[CSSSelectorBlock alloc] initWithName:name block:acceptBlock];
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// CSSStructuralPseudoSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 11/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
@class CSSSelector;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern CSSSelector * rootSelector();
|
||||
extern CSSSelector * emptySelector();
|
||||
extern CSSSelector * parentSelector();
|
||||
|
||||
extern CSSSelector * buttonSelector();
|
||||
extern CSSSelector * checkboxSelector();
|
||||
extern CSSSelector * fileSelector();
|
||||
extern CSSSelector * headerSelector();
|
||||
extern CSSSelector * imageSelector();
|
||||
extern CSSSelector * inputSelector();
|
||||
extern CSSSelector * linkSelector();
|
||||
extern CSSSelector * passwordSelector();
|
||||
extern CSSSelector * radioSelector();
|
||||
extern CSSSelector * resetSelector();
|
||||
extern CSSSelector * submitSelector();
|
||||
extern CSSSelector * textSelector();
|
||||
|
||||
extern CSSSelector * enabledSelector();
|
||||
extern CSSSelector * disabledSelector();
|
||||
extern CSSSelector * checkedSelector();
|
||||
extern CSSSelector * optionalSelector();
|
||||
extern CSSSelector * requiredSelector();
|
||||
|
||||
extern CSSSelector * ltSelector();
|
||||
extern CSSSelector * gtSelector();
|
||||
extern CSSSelector * eqSelector();
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// CSSStructuralPseudoSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 11/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSStructuralPseudoSelectors.h"
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLElement.h"
|
||||
#import "NSString+HTMLKit.h"
|
||||
|
||||
#pragma mark - Elements
|
||||
|
||||
CSSSelector * rootSelector()
|
||||
{
|
||||
return namedBlockSelector(@":root", ^BOOL(HTMLElement * element) {
|
||||
return element.parentElement == nil;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * emptySelector()
|
||||
{
|
||||
return namedBlockSelector(@":empty", ^BOOL(HTMLElement * element) {
|
||||
for (HTMLNode *child in element.childNodes) {
|
||||
if (child.nodeType == HTMLNodeElement) {
|
||||
return NO;
|
||||
} else if (child.nodeType == HTMLNodeText && child.textContent.length > 0) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * parentSelector()
|
||||
{
|
||||
return namedBlockSelector(@":parent", ^BOOL(HTMLElement * element) {
|
||||
return element.childNodesCount > 0;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * buttonSelector()
|
||||
{
|
||||
return namedBlockSelector(@":button", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element.tagName isEqualToString:@"button"]) {
|
||||
return YES;
|
||||
}
|
||||
if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"button"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * checkboxSelector()
|
||||
{
|
||||
return namedBlockSelector(@":checkbox", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"checkbox"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * fileSelector()
|
||||
{
|
||||
return namedBlockSelector(@":file", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"file"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * headerSelector()
|
||||
{
|
||||
return namedBlockSelector(@":header", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * imageSelector()
|
||||
{
|
||||
return namedBlockSelector(@":image", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"image"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * inputSelector()
|
||||
{
|
||||
return namedBlockSelector(@":input", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element.tagName isEqualToAny:@"button", @"input", @"select", @"textarea", nil]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * linkSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-link
|
||||
return namedBlockSelector(@":link", ^BOOL(HTMLElement * element) {
|
||||
if ([element hasAttribute:@"href"]) {
|
||||
return [element.tagName isEqualToAny:@"a", @"area", @"link", nil];
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * passwordSelector()
|
||||
{
|
||||
return namedBlockSelector(@":password", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"password"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * radioSelector()
|
||||
{
|
||||
return namedBlockSelector(@":radio", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"radio"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * resetSelector()
|
||||
{
|
||||
return namedBlockSelector(@":reset", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"reset"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * submitSelector()
|
||||
{
|
||||
return namedBlockSelector(@":submit", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element.tagName isEqualToString:@"input"] && [element[@"type"] isEqualToString:@"submit"]) {
|
||||
return YES;
|
||||
}
|
||||
if ([element.tagName isEqualToString:@"button"] && [element[@"type"] isEqualToString:@"submit"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * textSelector()
|
||||
{
|
||||
return namedBlockSelector(@":text", ^BOOL(HTMLElement * _Nonnull element) {
|
||||
if ([element[@"type"] isEqualToString:@"text"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - State
|
||||
|
||||
CSSSelector * enabledSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
|
||||
CSSSelector *candiate = anyOf(@[
|
||||
typeSelector(@"button"),
|
||||
typeSelector(@"input"),
|
||||
typeSelector(@"select"),
|
||||
typeSelector(@"textarea"),
|
||||
typeSelector(@"optgroup"),
|
||||
typeSelector(@"option"),
|
||||
typeSelector(@"menuitem"),
|
||||
typeSelector(@"fieldset"),
|
||||
]);
|
||||
return namedPseudoSelector(@"enabled", allOf(@[candiate, nay(disabledSelector())]));
|
||||
}
|
||||
|
||||
CSSSelector * disabledSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
|
||||
CSSSelector *disabledAttribute = hasAttributeSelector(@"disabled");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-fieldset-disabled
|
||||
CSSSelector *disabledFieldset = allOf(@[typeSelector(@"fieldset"), disabledAttribute]);
|
||||
CSSSelector *firstLegend = allOf(@[typeSelector(@"legend"), firstOfTypeSelector()]);
|
||||
CSSSelector *firstLegendDecendantDisabledFieldSet = allOf(@[firstLegend, descendantOfElementSelector(disabledFieldset)]);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
|
||||
CSSSelector *disabledForm = anyOf(@[
|
||||
anyOf(@[
|
||||
allOf(@[typeSelector(@"button"), disabledAttribute]),
|
||||
allOf(@[typeSelector(@"input"), disabledAttribute]),
|
||||
allOf(@[typeSelector(@"select"), disabledAttribute]),
|
||||
allOf(@[typeSelector(@"textarea"), disabledAttribute])
|
||||
]),
|
||||
allOf(@[
|
||||
descendantOfElementSelector(disabledFieldset),
|
||||
nay(firstLegendDecendantDisabledFieldSet)
|
||||
])
|
||||
]);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
|
||||
CSSSelector *disabledMenuItem = allOf(@[typeSelector(@"menuitem"), disabledAttribute]);
|
||||
CSSSelector *disabledOptgroup = allOf(@[typeSelector(@"optgroup"), disabledAttribute]);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
|
||||
CSSSelector *disabledOption = allOf(@[
|
||||
typeSelector(@"option"),
|
||||
anyOf(@[
|
||||
disabledAttribute,
|
||||
descendantOfElementSelector(disabledOptgroup)])
|
||||
]);
|
||||
return namedPseudoSelector(@"disabled",
|
||||
anyOf(@[disabledOption, disabledOptgroup, disabledMenuItem, disabledForm, disabledFieldset]));
|
||||
}
|
||||
|
||||
CSSSelector * checkedSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-checked
|
||||
CSSSelector *candidate = anyOf(@[
|
||||
typeSelector(@"input"),
|
||||
typeSelector(@"option"),
|
||||
typeSelector(@"menutitem")
|
||||
]);
|
||||
CSSSelector *hasAttribute = anyOf(@[
|
||||
hasAttributeSelector(@"checked"),
|
||||
hasAttributeSelector(@"selected")
|
||||
]);
|
||||
|
||||
return namedPseudoSelector(@"checked", allOf(@[candidate, hasAttribute]));
|
||||
}
|
||||
|
||||
CSSSelector * optionalSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-optional
|
||||
CSSSelector *candidate = anyOf(@[
|
||||
typeSelector(@"input"),
|
||||
typeSelector(@"select"),
|
||||
typeSelector(@"textarea")
|
||||
]);
|
||||
CSSSelector *noAttribute = nay(hasAttributeSelector(@"required"));
|
||||
|
||||
return namedPseudoSelector(@"optional", allOf(@[candidate, noAttribute]));
|
||||
}
|
||||
|
||||
CSSSelector * requiredSelector()
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-required
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-input-required
|
||||
CSSSelector *candidate = anyOf(@[
|
||||
typeSelector(@"input"),
|
||||
typeSelector(@"select"),
|
||||
typeSelector(@"textarea")
|
||||
]);
|
||||
CSSSelector *hasAttribute = hasAttributeSelector(@"required");
|
||||
|
||||
return namedPseudoSelector(@"required", allOf(@[candidate, hasAttribute]));
|
||||
}
|
||||
|
||||
#pragma mark - Positional
|
||||
|
||||
CSSSelector * ltSelector(NSUInteger index)
|
||||
{
|
||||
NSString *name = [NSString stringWithFormat:@":lt(%lu)", (unsigned long)index];
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
return [element.parentElement indexOfChildNode:element] < index;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * gtSelector(NSUInteger index)
|
||||
{
|
||||
NSString *name = [NSString stringWithFormat:@":gt(%lu)", (unsigned long)index];
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
return [element.parentElement indexOfChildNode:element] > index;
|
||||
});
|
||||
}
|
||||
|
||||
CSSSelector * eqSelector(NSInteger index)
|
||||
{
|
||||
NSString *name = [NSString stringWithFormat:@":eq(%lu)", (unsigned long)index];
|
||||
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
|
||||
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
|
||||
|
||||
if (index > 0) {
|
||||
return elementIndex == index;
|
||||
} else {
|
||||
return elementIndex == element.parentElement.childNodesCount - index - 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// CSSTypeSelector.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 13/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CSSSelector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CSSTypeSelector : CSSSelector
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *type;
|
||||
|
||||
+ (instancetype)universalSelector;
|
||||
|
||||
- (instancetype)initWithType:(NSString *)type;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// CSSTypeSelector.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 13/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSTypeSelector.h"
|
||||
#import "HTMLElement.h"
|
||||
#import "NSString+HTMLKit.h"
|
||||
|
||||
@interface CSSTypeSelector ()
|
||||
{
|
||||
NSString *_type;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSTypeSelector
|
||||
|
||||
+ (instancetype)universalSelector
|
||||
{
|
||||
return [[self alloc] initWithType:@"*"];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType:(NSString *)type
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_type = [type copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)acceptElement:(HTMLElement *)element
|
||||
{
|
||||
if ([_type isEqualToString:@"*"] || [_type isEqualToStringIgnoringCase:element.tagName]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Description
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return self.type;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -32,7 +32,7 @@
|
||||
- (NSString *)textContent
|
||||
{
|
||||
NSMutableString *content = [NSMutableString string];
|
||||
for (HTMLNode *node in self.treeEnumerator) {
|
||||
for (HTMLNode *node in self.nodeIterator) {
|
||||
if (node.nodeType == HTMLNodeText) {
|
||||
[content appendString:[(HTMLText *)node data]];
|
||||
}
|
||||
|
||||
@@ -180,4 +180,9 @@
|
||||
return description;
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return self.description;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason);
|
||||
|
||||
- (UTF32Char)currentInputCharacter;
|
||||
- (UTF32Char)nextInputCharacter;
|
||||
- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset;
|
||||
|
||||
- (UTF32Char)consumeNextInputCharacter;
|
||||
- (void)reconsumeCurrentInputCharacter;
|
||||
@@ -35,6 +36,7 @@ typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason);
|
||||
- (BOOL)consumeString:(NSString *)string caseSensitive:(BOOL)caseSensitive;
|
||||
- (NSString *)consumeCharactersUpToCharactersInString:(NSString *)characters;
|
||||
- (NSString *)consumeCharactersUpToString:(NSString *)string;
|
||||
- (NSString *)consumeCharactersInString:(NSString *)characters;
|
||||
- (NSString *)consumeAlphanumericCharacters;
|
||||
|
||||
- (void)markCurrentLocation;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "HTMLInputStreamReader.h"
|
||||
#import "HTMLTokenizerCharacters.h"
|
||||
#import "NSCharacterSet+HTMLKit.h"
|
||||
|
||||
#pragma mark - HTMLInputStreamReader
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
if (self) {
|
||||
_string = [string copy];
|
||||
_scanner = [[NSScanner alloc] initWithString:string];
|
||||
_scanner.charactersToBeSkipped = nil;
|
||||
CFStringInitInlineBuffer((CFStringRef)_string, &_buffer, CFRangeMake(0, _string.length));
|
||||
}
|
||||
return self;
|
||||
@@ -63,7 +65,6 @@
|
||||
- (UTF32Char)nextInputCharacter
|
||||
{
|
||||
if (_reconsume) {
|
||||
_reconsume = NO;
|
||||
return _currentInputCharacter;
|
||||
}
|
||||
|
||||
@@ -106,6 +107,11 @@
|
||||
return nextInputCharacter;
|
||||
}
|
||||
|
||||
- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset
|
||||
{
|
||||
return CFStringGetCharacterFromInlineBuffer(&_buffer, _location + offset);
|
||||
}
|
||||
|
||||
- (UTF32Char)consumeNextInputCharacter
|
||||
{
|
||||
if (_reconsume) {
|
||||
@@ -124,9 +130,12 @@
|
||||
{
|
||||
UTF32Char nextInputCharacter = [self nextInputCharacter];
|
||||
if (nextInputCharacter == character) {
|
||||
_location += _consume;
|
||||
_scanner.scanLocation = _location;
|
||||
_currentInputCharacter = nextInputCharacter;
|
||||
if (!_reconsume) {
|
||||
_location += _consume;
|
||||
_scanner.scanLocation = _location;
|
||||
_currentInputCharacter = nextInputCharacter;
|
||||
}
|
||||
_reconsume = NO;
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
@@ -145,7 +154,7 @@
|
||||
|
||||
- (BOOL)consumeHexNumber:(unsigned long long *)result
|
||||
{
|
||||
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"];
|
||||
NSCharacterSet *set = [NSCharacterSet HTMLHexNumberCharacterSet];
|
||||
|
||||
NSString *string = nil;
|
||||
BOOL success = [_scanner scanCharactersFromSet:set intoString:&string];
|
||||
@@ -193,6 +202,26 @@
|
||||
return consumed;
|
||||
}
|
||||
|
||||
- (NSString *)consumeCharactersInString:(NSString *)characters
|
||||
{
|
||||
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:characters];
|
||||
|
||||
if (_reconsume) {
|
||||
_scanner.scanLocation--;
|
||||
}
|
||||
|
||||
NSString *string = nil;
|
||||
BOOL success = [_scanner scanCharactersFromSet:set intoString:&string];
|
||||
if (success == NO) {
|
||||
_scanner.scanLocation++;
|
||||
return nil;
|
||||
}
|
||||
|
||||
_reconsume = NO;
|
||||
_location = _scanner.scanLocation;
|
||||
return string;
|
||||
}
|
||||
|
||||
- (NSString *)consumeAlphanumericCharacters
|
||||
{
|
||||
NSCharacterSet *set = [NSCharacterSet alphanumericCharacterSet];
|
||||
|
||||
+4
-5
@@ -6,8 +6,7 @@
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HTMLKit : NSObject
|
||||
|
||||
@end
|
||||
#import "HTMLParser.h"
|
||||
#import "HTMLDOM.h"
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLKitErrorDomain.h"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// HTMLKit.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 15/09/14.
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HTMLKit.h"
|
||||
|
||||
@implementation HTMLKit
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// HTMLKitErrorDomain.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 24/11/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef HTMLKitErrorDomain_h
|
||||
#define HTMLKitErrorDomain_h
|
||||
|
||||
static NSString *const HTMLKitErrorDomain = @"HTMLKit";
|
||||
static NSString *const HTMLKitSelectorErrorDomain = @"HTMLKitSelector";
|
||||
|
||||
static NSString *const CSSSelectorStringKey = @"CSSSelectorString";
|
||||
static NSString *const CSSSelectorErrorLocationKey = @"CSSSelectorErrorLocation";
|
||||
|
||||
NS_ENUM(NSInteger)
|
||||
{
|
||||
HTMLKitSelectorParseError = 4200
|
||||
};
|
||||
|
||||
#endif /* HTMLKitErrorDomain_h */
|
||||
@@ -38,6 +38,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
|
||||
|
||||
@class HTMLDocument;
|
||||
@class HTMLElement;
|
||||
@class CSSSelector;
|
||||
|
||||
@interface HTMLNode : NSObject <NSCopying>
|
||||
|
||||
@@ -61,6 +62,10 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
|
||||
|
||||
@property (nonatomic, strong, readonly) HTMLNode *nextSibling;
|
||||
|
||||
@property (nonatomic, strong, readonly) HTMLElement *previousSiblingElement;
|
||||
|
||||
@property (nonatomic, strong, readonly) HTMLElement *nextSiblingElement;
|
||||
|
||||
@property (nonatomic, copy) NSString *textContent;
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *outerHTML;
|
||||
@@ -83,6 +88,12 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
|
||||
|
||||
- (NSUInteger)indexOfChildNode:(HTMLNode *)node;
|
||||
|
||||
- (NSUInteger)childElementsCount;
|
||||
|
||||
- (HTMLElement *)childElementAtIndex:(NSUInteger)index;
|
||||
|
||||
- (NSUInteger)indexOfChildElement:(HTMLElement *)element;
|
||||
|
||||
- (HTMLNode *)prependNode:(HTMLNode *)node;
|
||||
|
||||
- (void)prependNodes:(NSArray *)nodes;
|
||||
@@ -121,6 +132,9 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
|
||||
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
|
||||
filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))filter;
|
||||
|
||||
- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector;
|
||||
- (NSArray<HTMLElement *> *)elementsMatchingSelector:(CSSSelector *)selector;
|
||||
|
||||
- (NSString *)treeDescription;
|
||||
|
||||
@end
|
||||
|
||||
+78
-6
@@ -13,6 +13,7 @@
|
||||
#import "HTMLText.h"
|
||||
#import "HTMLComment.h"
|
||||
#import "HTMLKitDOMExceptions.h"
|
||||
#import "CSSSelector.h"
|
||||
|
||||
@interface HTMLDocument (Private)
|
||||
- (void)runRemovingStepsForNode:(HTMLNode *)oldNode
|
||||
@@ -98,6 +99,24 @@
|
||||
return [_parentNode childNodeAtIndex:index + 1];
|
||||
}
|
||||
|
||||
- (HTMLElement *)previousSiblingElement
|
||||
{
|
||||
HTMLNode *node = self.previousSibling;
|
||||
while (node && node.nodeType != HTMLNodeElement) {
|
||||
node = node.previousSibling;
|
||||
}
|
||||
return node.asElement;
|
||||
}
|
||||
|
||||
- (HTMLElement *)nextSiblingElement
|
||||
{
|
||||
HTMLNode *node = self.previousSibling;
|
||||
while (node && node.nodeType != HTMLNodeElement) {
|
||||
node = node.nextSibling;
|
||||
}
|
||||
return node.asElement;
|
||||
}
|
||||
|
||||
- (NSString *)textContent
|
||||
{
|
||||
return nil;
|
||||
@@ -140,11 +159,46 @@
|
||||
return [self.childNodes objectAtIndex:index];
|
||||
}
|
||||
|
||||
- (NSUInteger)childElementsCount
|
||||
{
|
||||
return [self.childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
return node.nodeType == HTMLNodeElement;
|
||||
}].count;
|
||||
}
|
||||
|
||||
- (NSUInteger)indexOfChildNode:(HTMLNode *)node
|
||||
{
|
||||
return [self.childNodes indexOfObject:node];
|
||||
}
|
||||
|
||||
- (HTMLElement *)childElementAtIndex:(NSUInteger)index
|
||||
{
|
||||
NSUInteger counter = 0;
|
||||
for (HTMLNode *node in self.childNodes) {
|
||||
if (node.nodeType == HTMLNodeElement) {
|
||||
if (counter == index) {
|
||||
return node.asElement;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSUInteger)indexOfChildElement:(HTMLElement *)element
|
||||
{
|
||||
NSUInteger counter = 0;
|
||||
for (HTMLNode *node in self.childNodes) {
|
||||
if (node.nodeType == HTMLNodeElement) {
|
||||
if (node == element) {
|
||||
return counter;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (HTMLNode *)prependNode:(HTMLNode *)node
|
||||
{
|
||||
return [self insertNode:node beforeChildNode:self.firstChild];
|
||||
@@ -386,6 +440,29 @@
|
||||
return [HTMLNodeIterator iteratorWithNode:self showOptions:showOptions filter:filter];
|
||||
}
|
||||
|
||||
#pragma mark - Selectors
|
||||
|
||||
- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector
|
||||
{
|
||||
for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) {
|
||||
if ([selector acceptElement:element]) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray<HTMLElement *> *)elementsMatchingSelector:(CSSSelector *)selector
|
||||
{
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
for (HTMLElement *element in [self nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) {
|
||||
if ([selector acceptElement:element]) {
|
||||
[result addObject:element];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef HTMLKIT_NO_DOM_CHECKS
|
||||
|
||||
#pragma mark - Validity Checks
|
||||
@@ -610,12 +687,7 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p %@>", self.class, self, self.name];
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
return self.treeDescription;
|
||||
return [NSString stringWithFormat:@"<%@: %p '%@'>", self.class, self, self.name];
|
||||
}
|
||||
|
||||
- (id)debugQuickLookObject
|
||||
|
||||
@@ -26,6 +26,9 @@ typedef NS_OPTIONS(unsigned long, HTMLNodeFilterShowOptions)
|
||||
HTMLNodeFilterShowDocumentFragment = 0x400
|
||||
};
|
||||
|
||||
|
||||
#pragma mark - Node Filter
|
||||
|
||||
@class HTMLNode;
|
||||
|
||||
@protocol HTMLNodeFilter <NSObject>
|
||||
@@ -34,8 +37,20 @@ typedef NS_OPTIONS(unsigned long, HTMLNodeFilterShowOptions)
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Block Filter
|
||||
|
||||
@interface HTMLNodeFilterBlock : NSObject <HTMLNodeFilter>
|
||||
|
||||
+ (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))block;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - CSS Selector Filter
|
||||
|
||||
@class CSSSelector;
|
||||
|
||||
@interface HTMLSelectorNodeFilter : NSObject <HTMLNodeFilter>
|
||||
|
||||
+ (instancetype)filterWithSelector:(CSSSelector *)selector;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
//
|
||||
|
||||
#import "HTMLNodeFilter.h"
|
||||
#import "HTMLNode.h"
|
||||
#import "CSSSelector.h"
|
||||
|
||||
#pragma mark - Block Filter
|
||||
|
||||
@interface HTMLNodeFilterBlock ()
|
||||
{
|
||||
@@ -40,3 +44,42 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - CSS Selector Filter
|
||||
|
||||
@interface HTMLSelectorNodeFilter ()
|
||||
{
|
||||
CSSSelector *_selector;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation HTMLSelectorNodeFilter
|
||||
|
||||
+ (instancetype)filterWithSelector:(CSSSelector *)selector
|
||||
{
|
||||
return [[self alloc] initWithSelector:selector];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSelector:(CSSSelector *)selector
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_selector = selector;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node
|
||||
{
|
||||
if (node.nodeType != HTMLNodeElement) {
|
||||
return HTMLNodeFilterSkip;
|
||||
}
|
||||
|
||||
if ([_selector acceptElement:node.asElement]) {
|
||||
return HTMLNodeFilterAccept;
|
||||
}
|
||||
|
||||
return HTMLNodeFilterSkip;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,18 +8,22 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HTMLOrderedDictionary : NSMutableDictionary
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (id)objectAtIndex:(NSUInteger)index;
|
||||
- (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey atIndex:(NSUInteger)index;
|
||||
@interface HTMLOrderedDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType>
|
||||
|
||||
- (ObjectType)objectAtIndex:(NSUInteger)index;
|
||||
- (void)setObject:(ObjectType)anObject forKey:(KeyType<NSCopying>)aKey atIndex:(NSUInteger)index;
|
||||
- (void)removeObjectAtIndex:(NSUInteger)index;
|
||||
- (void)replaceKeyValueAtIndex:(NSUInteger)index withObject:(id)anObject andKey:(id<NSCopying>)aKey;
|
||||
- (void)replaceKey:(id<NSCopying>)aKey withKey:(id<NSCopying>)newKey;
|
||||
- (NSUInteger)indexOfKey:(id<NSCopying>)aKey;
|
||||
- (void)replaceKeyValueAtIndex:(NSUInteger)index withObject:(ObjectType)anObject andKey:(KeyType<NSCopying>)aKey;
|
||||
- (void)replaceKey:(KeyType<NSCopying>)aKey withKey:(KeyType<NSCopying>)newKey;
|
||||
- (NSUInteger)indexOfKey:(KeyType<NSCopying>)aKey;
|
||||
|
||||
- (id)objectAtIndexedSubscript:(NSUInteger)index;
|
||||
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index;
|
||||
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)index;
|
||||
- (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)index;
|
||||
|
||||
- (NSEnumerator *)reverseKeyEnumerator;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// NSCharacterSet+HTMLKit.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSCharacterSet (HTMLKit)
|
||||
|
||||
+ (instancetype)HTMLWhitespaceCharacterSet;
|
||||
+ (instancetype)HTMLHexNumberCharacterSet;
|
||||
+ (instancetype)CSSNthExpressionCharacterSet;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// NSCharacterSet+HTMLKit.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSCharacterSet+HTMLKit.h"
|
||||
|
||||
@implementation NSCharacterSet (HTMLKit)
|
||||
|
||||
+ (instancetype)HTMLWhitespaceCharacterSet
|
||||
{
|
||||
static NSCharacterSet *set = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
set = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r\f"];
|
||||
});
|
||||
return set;
|
||||
}
|
||||
|
||||
+ (instancetype)HTMLHexNumberCharacterSet
|
||||
{
|
||||
static NSCharacterSet *set = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"];
|
||||
});
|
||||
return set;
|
||||
}
|
||||
|
||||
+ (instancetype)CSSNthExpressionCharacterSet
|
||||
{
|
||||
static NSCharacterSet *set = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
set = [NSCharacterSet characterSetWithCharactersInString:@" 0123456789nN-+"];
|
||||
});
|
||||
return set;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,238 @@
|
||||
//
|
||||
// CSSAttributeSelectorTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLDOM.h"
|
||||
|
||||
@interface CSSAttributeSelectorTests : XCTestCase
|
||||
{
|
||||
HTMLElement *_element;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSAttributeSelectorTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
_element = [[HTMLElement alloc] initWithTagName:@"div"];
|
||||
}
|
||||
|
||||
- (void)testAttributeExists
|
||||
{
|
||||
CSSSelector *selector = hasAttributeSelector(@"attr");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"value 2";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"value 3";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeExactMatch
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorExactMatch, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value 1";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value 2";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value 3";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeIncludes
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorIncludes, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"a b value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"a value b";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeBegins
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorBegins, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"val";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"a value";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"values";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeEnds
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorEnds, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"val";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"a value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"some-value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeContains
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorContains, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"val";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"a value b";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"some-values";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeHyphen
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorHyphen, @"attr", @"top");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"top_text";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"toptext";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
|
||||
_element[@"attr"] = @"top";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"top-text";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testAttributeNot
|
||||
{
|
||||
CSSSelector *selector = attributeSelector(CSSAttributeSelectorNot, @"attr", @"value");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"top_text";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"toptext";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"top";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"top-text";
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
[_element.attributes removeObjectForKey:@"attr"];
|
||||
XCTAssertEqual([selector acceptElement:_element], YES);
|
||||
|
||||
_element[@"attr"] = @"value";
|
||||
XCTAssertEqual([selector acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testIdSelector
|
||||
{
|
||||
_element[@"id"] = @"id";
|
||||
XCTAssertEqual([idSelector(@"id") acceptElement:_element], YES);
|
||||
XCTAssertEqual([idSelector(@"other id") acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
- (void)testClassSelector
|
||||
{
|
||||
_element[@"class"] = @"class";
|
||||
XCTAssertEqual([classSelector(@"class") acceptElement:_element], YES);
|
||||
XCTAssertEqual([classSelector(@"other class") acceptElement:_element], NO);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// CSSCombinatorSelectorTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 23/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLParser.h"
|
||||
#import "HTMLDOM.h"
|
||||
|
||||
@interface CSSCombinatorSelectorTests : XCTestCase
|
||||
{
|
||||
HTMLDocument *_document;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSCombinatorSelectorTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
/*
|
||||
| <body>
|
||||
| <p id='p1'>
|
||||
| A paragraph<span id='span1'>A span</span>
|
||||
| <table id='table'>
|
||||
| <tbody id='tbody'>
|
||||
| <tr id='tr1'>
|
||||
| <td id='td'>
|
||||
| <span id='span2'>Span in table</span>
|
||||
| </td>
|
||||
| </tr>
|
||||
| <tr id='tr2'></tr>
|
||||
| <tr id='tr3'></tr>
|
||||
| </tbody>
|
||||
| </table>
|
||||
| </p>
|
||||
| <div id='inner-div1'>
|
||||
| <p id='p2'></p>
|
||||
| </div>
|
||||
| <div id='inner-div2'>
|
||||
| <p id='p3'></p>
|
||||
| </div>
|
||||
| </body>
|
||||
*/
|
||||
_document = [[[HTMLParser alloc] initWithString:@"<body>"
|
||||
"<p id='p1'>"
|
||||
"A paragraph<span id='span1'>A span</span>"
|
||||
"<table id='table'>"
|
||||
"<tbody id='tbody'>"
|
||||
"<tr id='tr1'><td id='td'>"
|
||||
"<span id='span2'>Span in table</span>"
|
||||
"</td></tr>"
|
||||
"<tr id='tr2'></tr>"
|
||||
"<tr id='tr3'></tr>"
|
||||
"</tbody>"
|
||||
"</table>"
|
||||
"</p>"
|
||||
"<div id='inner-div1'>"
|
||||
"<p id='p2'></p>"
|
||||
"</div>"
|
||||
"<div id='inner-div2'>"
|
||||
"<p id='p3'></p>"
|
||||
"</div>"
|
||||
"</body>"] document];
|
||||
}
|
||||
|
||||
-(void)testChildOfElementCombinator
|
||||
{
|
||||
NSArray *elements = [_document elementsMatchingSelector:childOfElementSelector(typeSelector(@"body"))];
|
||||
NSArray *expected = @[@"p1", @"inner-div1", @"inner-div2"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_document elementsMatchingSelector:childOfElementSelector(typeSelector(@"p"))];
|
||||
expected = @[@"span1", @"table"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
-(void)testDescendantOfElementCombinator
|
||||
{
|
||||
NSArray *elements = [_document elementsMatchingSelector:descendantOfElementSelector(typeSelector(@"p"))];
|
||||
NSArray *expected = @[@"span1", @"table", @"tbody", @"tr1", @"td", @"span2", @"tr2", @"tr3"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_document elementsMatchingSelector:descendantOfElementSelector(typeSelector(@"table"))];
|
||||
expected = @[@"tbody", @"tr1", @"td", @"span2", @"tr2", @"tr3"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
-(void)testAdjacentSiblingCombinator
|
||||
{
|
||||
NSArray *elements = [_document elementsMatchingSelector:adjacentSiblingSelector(typeSelector(@"tr"))];
|
||||
NSArray *expected = @[@"tr2", @"tr3"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_document elementsMatchingSelector:adjacentSiblingSelector(typeSelector(@"p"))];
|
||||
expected = @[@"inner-div1"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
-(void)testGeneralSiblingCombinator
|
||||
{
|
||||
NSArray *elements = [_document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"tr"))];
|
||||
NSArray *expected = @[@"tr2", @"tr3"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"p"))];
|
||||
expected = @[@"inner-div1", @"inner-div2"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,352 @@
|
||||
//
|
||||
// CSSNThExpressionSelectorTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 21/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLParser.h"
|
||||
#import "HTMLDOM.h"
|
||||
|
||||
@interface CSSNThExpressionSelectorTests : XCTestCase
|
||||
{
|
||||
HTMLDocument *_childTree;
|
||||
HTMLDocument *_typeTree;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CSSNThExpressionSelectorTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
/*
|
||||
| <div>
|
||||
| <table>
|
||||
| <tr id='11'><td>11</td></tr>
|
||||
| <tr id='12'><td>12</td></tr>
|
||||
| <tr id='13'><td>13</td></tr>
|
||||
| <tr id='14'><td>14</td></tr>
|
||||
| </table>
|
||||
| </div>
|
||||
| <div>
|
||||
| <table>
|
||||
| <tr id='21'><td>21</td></tr>
|
||||
| </table>
|
||||
| </div>
|
||||
| <div>
|
||||
| <table>
|
||||
| <tr id='31'><td>31</td></tr>
|
||||
| <tr id='32'><td>32</td></tr>
|
||||
| <tr id='33'><td>33</td></tr>
|
||||
| <tr id='34'><td>34</td></tr>
|
||||
| <tr id='35'><td>35</td></tr>
|
||||
| <tr id='36'><td>36</td></tr>
|
||||
| </table>
|
||||
| </div>
|
||||
*/
|
||||
_childTree = [[[HTMLParser alloc] initWithString:@"<div><table>"
|
||||
"<tr id='11'><td>11</td></tr>"
|
||||
"<tr id='12'><td>12</td></tr>"
|
||||
"<tr id='13'><td>13</td></tr>"
|
||||
"<tr id='14'><td>14</td></tr>"
|
||||
"</table></div>"
|
||||
"<div><table>"
|
||||
"<tr id='21'><td>21</td></tr>"
|
||||
"</table></div>"
|
||||
"<div><table>"
|
||||
"<tr id='31'><td>31</td></tr>"
|
||||
"<tr id='32'><td>32</td></tr>"
|
||||
"<tr id='33'><td>33</td></tr>"
|
||||
"<tr id='34'><td>34</td></tr>"
|
||||
"<tr id='35'><td>35</td></tr>"
|
||||
"<tr id='36'><td>36</td></tr>"
|
||||
"</table></div>"] document];
|
||||
|
||||
/*
|
||||
| <div>
|
||||
| <span id='s11'>s11</span>
|
||||
| <span id='s12'>s12</span>
|
||||
| <span id='s13'>s13</span>
|
||||
| <b id='b1'>b1</b>
|
||||
| </div>
|
||||
| <div>
|
||||
| <b id='b2'>b2</b>
|
||||
| <span id='s21'>s21</span>
|
||||
| <span id='s22'>s22</span>
|
||||
| <span id='s23'>s23</span>
|
||||
| </div>
|
||||
| <div>
|
||||
| <span id='s31'>s31</span>
|
||||
| <b id='b3'>b3</b>
|
||||
| <span id='s32'>s32</span>
|
||||
| <b id='b4'>b4</b>
|
||||
| <span id='s33'>s33</span>
|
||||
| <b id='b5'>b5</b>
|
||||
| <span id='s34'>s34</span>
|
||||
| </div>
|
||||
*/
|
||||
_typeTree = [[[HTMLParser alloc] initWithString:@"<div>"
|
||||
"<span id='s11'>s11</span>"
|
||||
"<span id='s12'>s12</span>"
|
||||
"<span id='s13'>s13</span>"
|
||||
"<b id='b1'>b1</b>"
|
||||
"</div>"
|
||||
"<div>"
|
||||
"<b id='b2'>b2</b>"
|
||||
"<span id='s21'>s21</span>"
|
||||
"<span id='s22'>s22</span>"
|
||||
"<span id='s23'>s23</span>"
|
||||
"</div>"
|
||||
"<div>"
|
||||
"<span id='s31'>s31</span>"
|
||||
"<b id='b3'>b3</b>"
|
||||
"<span id='s32'>s32</span>"
|
||||
"<b id='b4'>b4</b>"
|
||||
"<span id='s33'>s33</span>"
|
||||
"<b id='b5'>b5</b>"
|
||||
"<span id='s34'>s34</span>"
|
||||
"</div>"] document];
|
||||
}
|
||||
|
||||
- (void)testOddSelector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), oddSelector()])];
|
||||
NSArray *expected = @[@"11", @"13", @"21", @"31", @"33", @"35"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testEvenSelector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), evenSlector()])];
|
||||
NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testFirstChildSelector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), firstChildSelector()])];
|
||||
NSArray *expected = @[@"11", @"21", @"31"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testLastChildSelector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), lastChildSelector()])];
|
||||
NSArray *expected = @[@"14", @"21", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testFirstOfTypeSelector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), firstOfTypeSelector()])];
|
||||
NSArray *expected = @[@"s11", @"s21", @"s31"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testLastOfTypeSelector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), lastOfTypeSelector()])];
|
||||
NSArray *expected = @[@"s13", @"s23", @"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testOnlyChildSelector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyChildSelector()])];
|
||||
NSArray *expected = @[@"21"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)testOnlyOfTypeSelector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyOfTypeSelector()])];
|
||||
NSArray *expected = @[];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), onlyOfTypeSelector()])];
|
||||
expected = @[];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"b"), onlyOfTypeSelector()])];
|
||||
expected = @[@"b1", @"b2"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Child Selector
|
||||
|
||||
- (void)test_NthChild_B_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 1))])];
|
||||
NSArray *expected = @[@"11", @"21", @"31"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 2))])];
|
||||
expected = @[@"12", @"32"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 3))])];
|
||||
expected = @[@"13", @"33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthChild_An_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(2, 0))])];
|
||||
NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 0))])];
|
||||
expected = @[@"13", @"33", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(4, 0))])];
|
||||
expected = @[@"14", @"34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthChild_An_B_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 1))])];
|
||||
NSArray *expected = @[@"11", @"14", @"21", @"31", @"34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 2))])];
|
||||
expected = @[@"12", @"32", @"35"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Last-Child Selector
|
||||
|
||||
- (void)test_NthLastChild_B_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 1))])];
|
||||
NSArray *expected = @[@"14", @"21", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 2))])];
|
||||
expected = @[@"13", @"35"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 3))])];
|
||||
expected = @[@"12", @"34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthLastChild_An_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(2, 0))])];
|
||||
NSArray *expected = @[@"11", @"13", @"31", @"33", @"35"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 0))])];
|
||||
expected = @[@"12", @"31", @"34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(4, 0))])];
|
||||
expected = @[@"11", @"33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthLastChild_An_B_Selector
|
||||
{
|
||||
NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 1))])];
|
||||
NSArray *expected = @[@"11", @"14", @"21", @"33", @"36"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 2))])];
|
||||
expected = @[@"13", @"32", @"35"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Of-Type Selector
|
||||
|
||||
- (void)test_NthOfType_B_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 1))])];
|
||||
NSArray *expected = @[@"s11", @"s21", @"s31"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 2))])];
|
||||
expected = @[@"s12", @"s22", @"s32"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 3))])];
|
||||
expected = @[@"s13", @"s23", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthOfType_An_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 0))])];
|
||||
NSArray *expected = @[@"s12", @"s22", @"s32", @"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(3, 0))])];
|
||||
expected = @[@"s13", @"s23", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(4, 0))])];
|
||||
expected = @[@"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthOfType_An_B_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 1))])];
|
||||
NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s31", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 2))])];
|
||||
expected = @[@"s12", @"s22", @"s32", @"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
#pragma mark - Nth-Last-Of-Type Selector
|
||||
|
||||
- (void)test_NthLastOfType_B_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 1))])];
|
||||
NSArray *expected = @[@"s13", @"s23", @"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 2))])];
|
||||
expected = @[@"s12", @"s22", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 3))])];
|
||||
expected = @[@"s11", @"s21", @"s32"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthLastOfType_An_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 0))])];
|
||||
NSArray *expected = @[@"s12", @"s22", @"s31", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(3, 0))])];
|
||||
expected = @[@"s11", @"s21", @"s32"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(4, 0))])];
|
||||
expected = @[@"s31"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
- (void)test_NthLastOfType_An_B_Selector
|
||||
{
|
||||
NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 1))])];
|
||||
NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s32", @"s34"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
|
||||
elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 2))])];
|
||||
expected = @[@"s12", @"s22", @"s31", @"s33"];
|
||||
XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// CSSNthExpressionsParserTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 10/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSNthExpressionParser.h"
|
||||
|
||||
@interface CSSNthExpressionsParserTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation CSSNthExpressionsParserTests
|
||||
|
||||
- (void)testOddEvenExpression
|
||||
{
|
||||
CSSNthExpression odd = [CSSNthExpressionParser parseExpression:@"odd"];
|
||||
XCTAssertEqual(odd.an, 2);
|
||||
XCTAssertEqual(odd.b, 1);
|
||||
|
||||
odd = [CSSNthExpressionParser parseExpression:@" odd"];
|
||||
XCTAssertEqual(odd.an, 2);
|
||||
XCTAssertEqual(odd.b, 1);
|
||||
|
||||
odd = [CSSNthExpressionParser parseExpression:@"odd "];
|
||||
XCTAssertEqual(odd.an, 2);
|
||||
XCTAssertEqual(odd.b, 1);
|
||||
|
||||
odd = [CSSNthExpressionParser parseExpression:@" odd "];
|
||||
XCTAssertEqual(odd.an, 2);
|
||||
XCTAssertEqual(odd.b, 1);
|
||||
|
||||
CSSNthExpression even = [CSSNthExpressionParser parseExpression:@"even"];
|
||||
XCTAssertEqual(even.an, 2);
|
||||
XCTAssertEqual(even.b, 0);
|
||||
|
||||
even = [CSSNthExpressionParser parseExpression:@" even"];
|
||||
XCTAssertEqual(even.an, 2);
|
||||
XCTAssertEqual(even.b, 0);
|
||||
|
||||
even = [CSSNthExpressionParser parseExpression:@"even "];
|
||||
XCTAssertEqual(even.an, 2);
|
||||
XCTAssertEqual(even.b, 0);
|
||||
|
||||
even = [CSSNthExpressionParser parseExpression:@" even "];
|
||||
XCTAssertEqual(even.an, 2);
|
||||
XCTAssertEqual(even.b, 0);
|
||||
}
|
||||
|
||||
- (void)test_B_Expression
|
||||
{
|
||||
CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"1"];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+1"];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-1"];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@" -1"];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+1 "];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@" +1 "];
|
||||
XCTAssertEqual(expression.an, 0);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
}
|
||||
|
||||
- (void)test_AN_Expression
|
||||
{
|
||||
CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"n"];
|
||||
XCTAssertEqual(expression.an, 1);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+n"];
|
||||
XCTAssertEqual(expression.an, 1);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"2n"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+2n"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-n"];
|
||||
XCTAssertEqual(expression.an, -1);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-2n"];
|
||||
XCTAssertEqual(expression.an, -2);
|
||||
XCTAssertEqual(expression.b, 0);
|
||||
}
|
||||
|
||||
- (void)test_AN_B_Expression
|
||||
{
|
||||
CSSNthExpression expression = [CSSNthExpressionParser parseExpression:@"2n+1"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+2n+1"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-2n+1"];
|
||||
XCTAssertEqual(expression.an, -2);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"2n-1"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-2n-1"];
|
||||
XCTAssertEqual(expression.an, -2);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"n-1"];
|
||||
XCTAssertEqual(expression.an, 1);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-n-1"];
|
||||
XCTAssertEqual(expression.an, -1);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+n-1"];
|
||||
XCTAssertEqual(expression.an, 1);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"+2n + 1"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@"-2n + 1"];
|
||||
XCTAssertEqual(expression.an, -2);
|
||||
XCTAssertEqual(expression.b, 1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@" 2n - 1"];
|
||||
XCTAssertEqual(expression.an, 2);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
|
||||
expression = [CSSNthExpressionParser parseExpression:@" -2n -1 "];
|
||||
XCTAssertEqual(expression.an, -2);
|
||||
XCTAssertEqual(expression.b, -1);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// CSSSelectorParserTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 23/10/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import <HTMLKit/HTMLKit.h>
|
||||
#import "CSSSelectorTest.h"
|
||||
#import "CSSSelectorParser.h"
|
||||
|
||||
@interface CSSSelectorParserTests : XCTestCase
|
||||
@property (nonatomic, strong) CSSSelectorTest *testCase;
|
||||
@end
|
||||
|
||||
@implementation CSSSelectorParserTests
|
||||
|
||||
+ (XCTestSuite *)defaultTestSuite
|
||||
{
|
||||
XCTestSuite *suite = [[XCTestSuite alloc] initWithName:NSStringFromClass(self)];
|
||||
|
||||
NSArray *tests = [CSSSelectorTest loadCSSSelectorTests];
|
||||
for (CSSSelectorTest *test in tests) {
|
||||
[self addSelectorTest:test toTestSuite:suite];
|
||||
}
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
+ (void)addSelectorTest:(CSSSelectorTest *)selectorTest toTestSuite:(XCTestSuite *)suite
|
||||
{
|
||||
NSArray *allInvocations = [self testInvocations];
|
||||
for (NSInvocation *invocation in allInvocations) {
|
||||
XCTestCase *testCase = [[self alloc] initWithInvocation:invocation
|
||||
testCase:selectorTest];
|
||||
[suite addTest:testCase];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Instance
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation *)invocation
|
||||
testCase:(CSSSelectorTest *)testCase
|
||||
{
|
||||
self = [super initWithInvocation:invocation];
|
||||
if (self) {
|
||||
_testCase = testCase;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
NSInvocation *invocation = [self invocation];
|
||||
NSString *title = self.testCase.testName.stringByDeletingPathExtension;
|
||||
return [NSString stringWithFormat:@"-[%@ %@_%@]", self.class, NSStringFromSelector(invocation.selector), title];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return self.name;
|
||||
}
|
||||
|
||||
#pragma mark - Tests
|
||||
|
||||
- (void)testParser
|
||||
{
|
||||
for (NSDictionary *testDescription in self.testCase.selectors) {
|
||||
NSString *selectorString = testDescription[@"selector"];
|
||||
NSArray *expectedMatches = testDescription[@"match"];
|
||||
NSNumber *expectedError = testDescription[@"error"];
|
||||
HTMLElement *testDOM = self.testCase.testDOM;
|
||||
|
||||
NSError *error = nil;
|
||||
CSSSelector *parsedSelector = [CSSSelectorParser parseSelector:selectorString error:&error];
|
||||
|
||||
if (expectedError) {
|
||||
XCTAssertNotNil(error);
|
||||
XCTAssertNil(parsedSelector);
|
||||
|
||||
NSUInteger errorLocation = [error.userInfo[CSSSelectorErrorLocationKey] unsignedIntegerValue];
|
||||
XCTAssertEqual(errorLocation, expectedError.unsignedIntegerValue);
|
||||
} else {
|
||||
XCTAssertNil(error);
|
||||
XCTAssertNotNil(parsedSelector);
|
||||
|
||||
NSArray *matchedElements = [testDOM elementsMatchingSelector:parsedSelector];
|
||||
NSArray *matchedIds = [matchedElements valueForKeyPath:@"attributes.id"];
|
||||
|
||||
NSString *message = [NSString stringWithFormat:@"CSS test: \'%@\'\nInput:\n%@\nDOM:\n%@\nExpected:\n%@\nActual:\n%@\n",
|
||||
self.name,
|
||||
selectorString,
|
||||
testDOM.outerHTML,
|
||||
expectedMatches,
|
||||
matchedIds];
|
||||
|
||||
XCTAssertEqualObjects(matchedIds, expectedMatches, @"IDs mismatch:\n%@", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// CSSSelectorTest.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 22/11/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class HTMLElement;
|
||||
|
||||
@interface CSSSelectorTest : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString *testName;
|
||||
@property (nonatomic, strong) NSArray *selectors;
|
||||
@property (nonatomic, strong) HTMLElement *testDOM;
|
||||
|
||||
+ (NSArray *)loadCSSSelectorTests;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// CSSSelectorTest.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 22/11/15.
|
||||
// Copyright © 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSSSelectorTest.h"
|
||||
#import "HTMLParser.h"
|
||||
#import "HTMLDocument.h"
|
||||
#import "HTMLElement.h"
|
||||
#import "CSSSelectors.h"
|
||||
|
||||
static NSString * const CSSTests = @"css-tests";
|
||||
|
||||
@implementation CSSSelectorTest
|
||||
|
||||
+ (NSArray *)loadCSSSelectorTests
|
||||
{
|
||||
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
|
||||
path = [path stringByAppendingPathComponent:CSSTests];
|
||||
|
||||
NSMutableArray *tests = [NSMutableArray array];
|
||||
NSArray *testFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
|
||||
|
||||
for (NSString *testFile in testFiles) {
|
||||
if (![testFile.pathExtension isEqualToString:@"html"]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString *testFilePath = [path stringByAppendingPathComponent:testFile];
|
||||
CSSSelectorTest *test = [CSSSelectorTest testWithFileAtPath:testFilePath];
|
||||
[tests addObject:test];
|
||||
}
|
||||
|
||||
return tests;
|
||||
}
|
||||
|
||||
+ (instancetype)testWithFileAtPath:(NSString *)filePath
|
||||
{
|
||||
NSString *testName = filePath.lastPathComponent.stringByDeletingPathExtension;
|
||||
|
||||
NSString *html = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
|
||||
|
||||
HTMLDocument *document = [HTMLDocument documentWithString:html];
|
||||
|
||||
HTMLElement *domElement = [document firstElementMatchingSelector:idSelector(@"testDOM")];
|
||||
HTMLElement *scriptElement = [document firstElementMatchingSelector:idSelector(@"selectors")];
|
||||
NSData *data = [scriptElement.textContent dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSArray *selectors = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
|
||||
|
||||
CSSSelectorTest *instance = [CSSSelectorTest new];
|
||||
instance.testName = testName;
|
||||
instance.selectors = selectors;
|
||||
instance.testDOM = domElement;
|
||||
return instance;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// CSSTypeSelectorTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 14/05/15.
|
||||
// Copyright (c) 2015 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "CSSSelectors.h"
|
||||
#import "HTMLDOM.h"
|
||||
#import "CSSSelectorParser.h"
|
||||
|
||||
@interface CSSTypeSelectorTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation CSSTypeSelectorTests
|
||||
|
||||
- (void)testUniversalSelector
|
||||
{
|
||||
CSSSelector *selector = universalSelector();
|
||||
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:nil]], YES);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@""]], YES);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"div"]], YES);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"p"]], YES);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"any other name"]], YES);
|
||||
}
|
||||
|
||||
- (void)testTypeSelector
|
||||
{
|
||||
CSSSelector *selector = typeSelector(@"div");
|
||||
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:nil]], NO);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@""]], NO);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"p"]], NO);
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"any other name"]], NO);
|
||||
|
||||
XCTAssertEqual([selector acceptElement:[[HTMLElement alloc] initWithTagName:@"div"]], YES);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -38,9 +38,6 @@
|
||||
[_dictionary setObject:@"3" forKey:@"C"];
|
||||
expected = @[@"A", @"B", @"C"];
|
||||
XCTAssertEqualObjects(_dictionary.keyEnumerator.allObjects, expected);
|
||||
|
||||
XCTAssertThrows([_dictionary setObject:nil forKey:@"Key"]);
|
||||
XCTAssertThrows([_dictionary setObject:@"Object" forKey:nil]);
|
||||
}
|
||||
|
||||
- (void)testIndexOfKey
|
||||
@@ -51,7 +48,6 @@
|
||||
XCTAssertEqual([_dictionary indexOfKey:@"A"], 0);
|
||||
XCTAssertEqual([_dictionary indexOfKey:@"B"], 1);
|
||||
XCTAssertEqual([_dictionary indexOfKey:@"C"], 2);
|
||||
XCTAssertEqual([_dictionary indexOfKey:nil], NSNotFound);
|
||||
}
|
||||
|
||||
- (void)testObjectAtIndex
|
||||
@@ -64,8 +60,6 @@
|
||||
[_dictionary setObject:@"3" forKey:@"C" atIndex:1];
|
||||
XCTAssertEqualObjects([_dictionary objectAtIndex:1], @"3");
|
||||
|
||||
XCTAssertThrows([_dictionary setObject:nil forKey:@"Key" atIndex:0]);
|
||||
XCTAssertThrows([_dictionary setObject:@"Object" forKey:nil atIndex:0]);
|
||||
XCTAssertThrows([_dictionary setObject:@"Object" forKey:@"Key" atIndex:100]);
|
||||
}
|
||||
|
||||
@@ -120,8 +114,6 @@
|
||||
XCTAssertEqualObjects(_dictionary[2], @"5");
|
||||
XCTAssertEqualObjects(_dictionary[@"A"], @"5");
|
||||
|
||||
XCTAssertThrows([_dictionary setObject:nil forKey:@"Key" atIndex:0]);
|
||||
XCTAssertThrows([_dictionary setObject:@"Object" forKey:nil atIndex:0]);
|
||||
XCTAssertThrows([_dictionary setObject:@"Object" forKey:@"Key" atIndex:100]);
|
||||
}
|
||||
|
||||
@@ -158,8 +150,6 @@
|
||||
XCTAssertEqualObjects(_dictionary[0], @"5");
|
||||
XCTAssertEqualObjects(_dictionary[@"E"], @"5");
|
||||
|
||||
XCTAssertThrows([_dictionary replaceKeyValueAtIndex:1 withObject:nil andKey:@"Key"]);
|
||||
XCTAssertThrows([_dictionary replaceKeyValueAtIndex:1 withObject:@"Object" andKey:nil]);
|
||||
XCTAssertThrows([_dictionary replaceKeyValueAtIndex:100 withObject:@"Object" andKey:@"Key"]);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
actual = [parser parseFragmentWithContextElement:contextElement];
|
||||
}
|
||||
|
||||
NSString *expectedNodes = [[test.nodes valueForKey:@"debugDescription"] componentsJoinedByString:@"\n"];
|
||||
NSString *actualNodes = [[parser.document.childNodes.array valueForKey:@"debugDescription"] componentsJoinedByString:@"\n"];
|
||||
NSString *expectedNodes = [[test.nodes valueForKey:@"treeDescription"] componentsJoinedByString:@"\n"];
|
||||
NSString *actualNodes = [[actual valueForKey:@"treeDescription"] componentsJoinedByString:@"\n"];
|
||||
|
||||
NSString *message = [NSString stringWithFormat:@"HTML5Lib test in file: \'%@\'\nInput:\n%@\nExpected:\n%@\nActual:\n%@\n",
|
||||
test.testFile,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "li,p",
|
||||
"match": ["1", "2", "3"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<ul>
|
||||
<li id="1">The background of this list item should be green</li>
|
||||
<li id="2">The background of this second list item should be also green</li>
|
||||
</ul>
|
||||
<p id="3">The background of this paragraph should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p[title$=\"bar\"]",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" title="foobar">This paragraph should have a green background because its title attribute ends with "bar"</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p[title*=\"bar\"]",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" title="foobarufoo">This paragraph should have a green background because its title attribute contains "bar"</p>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".t1",
|
||||
"match": ["1"]
|
||||
},
|
||||
{
|
||||
"selector": "li.t2",
|
||||
"match": ["2", "3"]
|
||||
},
|
||||
{
|
||||
"selector": ".t3",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<ul>
|
||||
<li id="1" class="t1">This list item should have green background because its class is "t1"</li>
|
||||
<li id="2" class="t2">This list item should have green background because its class is "t2"</li>
|
||||
<li id="3" class="t2">
|
||||
<span id="4" class="t33">This list item should have green background because the inner SPAN does not match SPAN.t3</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p.t1",
|
||||
"match": ["1"]
|
||||
},
|
||||
{
|
||||
"selector": "p.t2",
|
||||
"match": ["1"]
|
||||
},
|
||||
{
|
||||
"selector": "div.teST",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div.te",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div.st",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div.te.st",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="t1 t2">This paragraph should have a green background and a green thick solid border because it carries both classes t1 and t2.</p>
|
||||
<div id="2" class="test">This line should be green.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "div :not(:enabled):not(:disabled)",
|
||||
"match": ["1", "2"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<div id="1">
|
||||
<p id="2">This paragraph should have a green background.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p:empty",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "address:empty",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<address id="1"></address>
|
||||
<div id="2" class="text">This line should have a green background.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".t1.fail",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ".fail.t2",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ".t2.fail",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ".fail.t2",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="t1">This line should be green.</p>
|
||||
<p id="2" class="t1 t2">This line should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p.t1.t2",
|
||||
"match": ["1"]
|
||||
},
|
||||
{
|
||||
"selector": "div.t1",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "address.t5.t5",
|
||||
"match": ["3"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="t1 t2">This line should be green.</p>
|
||||
<div id="2" class="t3">This line should be green.</div>
|
||||
<address id="3" class="t4 t5 t6">This line should be green.</address>
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".t1:not(.t2)",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ":not(.t2).t1",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ".t2:not(.t1)",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ":not(.t1).t2",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="t1 t2">This line should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p:not(.t1):not(.t2)",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div:not(.t1)",
|
||||
"match": ["testDOM", "2"]
|
||||
},
|
||||
{
|
||||
"selector": "address:not(.t5):not(.t5)",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="t1 t2">This line should be green.</p>
|
||||
<div id="2" class="t3">This line should be green.</div>
|
||||
<address id="3" class="t4 t5 t6">This line should be green.</address>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "#t1",
|
||||
"match": ["t1"]
|
||||
},
|
||||
{
|
||||
"selector": "li#t2",
|
||||
"match": ["t2"]
|
||||
},
|
||||
{
|
||||
"selector": "li#t3",
|
||||
"match": ["t3"]
|
||||
},
|
||||
{
|
||||
"selector": "#t4",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<ul id="1">
|
||||
<li id="t1">This list item should have a green background. because its ID is "t1"</li>
|
||||
<li id="t2">This list item should have a green background. because its ID is "t2"</li>
|
||||
<li id="t3">
|
||||
<span id="t44">This list item should have a green background. because the inner SPAN does not match "#t4"</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "address:empty",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<address id="1"><!-- --><?test random PI></address>
|
||||
<div id="2" class="text">This line should have a green background.</div>
|
||||
<p id="3">(Note: This test is based on unpublished errata.)</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "address:empty",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<address id="1"> </address>
|
||||
<div id="2" class="text">This line should have a green background.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "address:empty",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<address id="1"><span id="2"></span></address>
|
||||
<div id="3" class="text">This line should have a green background.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p,",
|
||||
"match": [],
|
||||
"error": 1
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".5cm",
|
||||
"match": [],
|
||||
"error": 1
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="5cm">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".\\5cm",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="5cm">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".two\\ words",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="two words">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".one.word",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="one.word">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".one\\.word",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="one.word">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "foo & address, p",
|
||||
"match": [],
|
||||
"error": 5
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p>This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "[*=test]",
|
||||
"match": [],
|
||||
"error": 2
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="test">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "[*|*=test]",
|
||||
"match": [],
|
||||
"error": 2
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="test">This line should have a green background.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "#test#fail",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "#fail#test",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "#fail",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "#pass#pass",
|
||||
"match": ["pass"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="test">This line should be green.</p>
|
||||
<div id="pass">This line should be green.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p.test a",
|
||||
"match": ["2"]
|
||||
},
|
||||
{
|
||||
"selector": "p.test *:link",
|
||||
"match": ["2"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="test">
|
||||
<a id="2" href="http://unvisited.example.org/css3-modsel-16/">This link should have green background.</a> (Don't follow this link.)
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p:subject",
|
||||
"match": [],
|
||||
"error": 9
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="test">This line should have a green background.</p>
|
||||
</div>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".13",
|
||||
"match": [],
|
||||
"error": 1
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="13">This line should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".\13",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="13">This line should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".\31 \33",
|
||||
"match": ["1"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="13">This line should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p:not(#other).class:not(.fail).test#id#id",
|
||||
"match": ["id"]
|
||||
},
|
||||
{
|
||||
"selector": "div:not(#theid).class:not(.fail).test#theid#theid",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div:not(#other).notclass:not(.fail).test#theid#theid",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div:not(#other).class:not(.test).test#theid#theid",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div:not(#other).class:not(.fail).nottest#theid#theid",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": "div:not(#other).class:not(.fail).nottest#theid#other",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="id" class="class test">This line should be green.</p>
|
||||
<div id="theid" class="class test">This line should be green.</div>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p::first-child",
|
||||
"match": [],
|
||||
"error": 2
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<div>
|
||||
<p>This line should be green.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": ".ci P",
|
||||
"match": ["2", "3", "4"]
|
||||
},
|
||||
{
|
||||
"selector": ".ci .a",
|
||||
"match": []
|
||||
},
|
||||
{
|
||||
"selector": ".ci SPAN",
|
||||
"match": ["5"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<div>
|
||||
|
||||
|
||||
<div id="1" class="ci">
|
||||
<p id="2">This line should be green.</p>
|
||||
<p id="3" class="A">This line should be green.</p>
|
||||
<p id="4"><SPAN id="5">This line should be green.</SPAN></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "..test",
|
||||
"match": [],
|
||||
"error": 1
|
||||
},
|
||||
{
|
||||
"selector": ".foo..quux ",
|
||||
"match": [],
|
||||
"error": 5
|
||||
},
|
||||
{
|
||||
"selector": ".bar.",
|
||||
"match": [],
|
||||
"error": 5
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p class="test">This text should be green.</p>
|
||||
<p class=".test">This text should be green.</p>
|
||||
<p class="foo">This text should be green.</p>
|
||||
<p class="foo quux">This text should be green.</p>
|
||||
<p class="foo quux">This text should be green.</p>
|
||||
<p class=" bar ">This text should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p[class$=\"\"]",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="">This text should be green.</p>
|
||||
<p id="2">This text should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p[class^=\"\"]",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="">This text should be green.</p>
|
||||
<p id="2">This text should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p[class*=\"\"]",
|
||||
"match": []
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="">This text should be green.</p>
|
||||
<p id="2">This text should be green.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script type="application/json" id="selectors">
|
||||
[{
|
||||
"selector": "p:not([class$=\"\"])",
|
||||
"match": ["1", "2"]
|
||||
}]
|
||||
</script>
|
||||
<div id="testDOM">
|
||||
<p id="1" class="">This text should be green.</p>
|
||||
<p id="2">This text should be green.</p>
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user