122 Commits

Author SHA1 Message Date
iska 70eeecbf67 Merge branch 'release/3.0.0' 2019-03-28 22:20:12 +01:00
iska 918c59e5ff Bump HTMLKit version to 3.0.0 2019-03-28 22:19:58 +01:00
iska 2a641ddacd Update podspec for 3.0.0 2019-03-28 22:19:44 +01:00
iska 91d1f85c1b Update jazzy.yaml for 3.0.0 2019-03-28 22:19:32 +01:00
iska 85bd39963f Add Changelog entry for HTMLKit 3.0.0 2019-03-28 22:19:19 +01:00
iska 7cbfdb9c78 Introduce prefix for category methods to prevent collisions
See:
https://github.com/iabudiab/HTMLKit/issues/35
2019-03-26 23:23:08 +01:00
iska d756fc4298 Merge branch 'release/2.1.5' 2018-07-16 22:13:29 +02:00
iska 0fe6b7c42d Merge tag '2.1.5' into develop
no message
2018-07-16 22:13:29 +02:00
iska 7c2335184e Bump HTMLKit version to 2.1.5 2018-07-16 22:13:21 +02:00
iska 0c6084ba73 Update podspec for 2.1.4 2018-07-16 22:12:54 +02:00
iska 5201860073 Add Changelog entry for HTMLKit 2.1.5 2018-07-16 22:12:39 +02:00
iska cf21b88eb1 Add Changelog entry for HTMLKit 2.1.5 2018-07-16 22:12:30 +02:00
iska 7617fceff1 Add test for bug fix issue #30 2018-07-16 22:09:35 +02:00
iska 9dd3c70fc3 Remove foreign attributes adjustment
Fixes #30

Foreign attributes were handled incorrectly because attribute names
were implemented as pure strings without namespace prefix. This change
keeps the attributes as strings and eliminates any handling in regards
to namespaces.

Spec note about attributes:
"If designed today they would just have a name and value."

https://dom.spec.whatwg.org/#attr
2018-05-10 18:41:54 +02:00
Iskandar Abudiab fe2a441171 Merge pull request #29 from CRivlaldo/develop
Fix the issue 28
2018-05-03 20:11:33 +02:00
Vladimir Vlasov 7c32b5f219 Fix the issue 28 2018-05-03 19:00:29 +03:00
iska bf0d8560b0 Merge branch 'release/2.1.4' 2018-05-01 20:08:30 +02:00
iska ebc6f7a097 Merge branch 'release/2.1.4' into develop 2018-05-01 20:08:30 +02:00
iska d29a70dfec Bump HTMLKit version to 2.1.4 2018-05-01 20:08:00 +02:00
iska b8f56ca97d Update podspec for 2.1.4 2018-05-01 20:07:44 +02:00
iska 0f954d5d56 Update jazzy.yaml for 2.1.4 2018-05-01 20:07:35 +02:00
iska ac5089d69b Add Changelog entry for HTMLKit 2.1.4 2018-05-01 20:07:23 +02:00
iska c9c36397e0 Update CocoaPods block in Readme 2018-05-01 20:02:36 +02:00
iska 923e271429 Fix eq, lt & gt selectors for the zero-index case
Fixes #25
2018-04-18 23:51:39 +02:00
iska 8546168324 Merge branch 'release/2.1.3' 2018-03-21 22:52:09 +01:00
iska da765169fa Merge branch 'release/2.1.3' into develop 2018-03-21 22:51:46 +01:00
iska ec6d03ee57 Bump HTMLKit version to 2.1.3 2018-03-21 22:43:01 +01:00
iska 7944549bd7 Update podspec for 2.1.3 2018-03-21 22:42:41 +01:00
iska bb6a97984b Update jazzy.yaml for 2.1.3 2018-03-21 22:42:32 +01:00
iska 0aff9cf787 Add Changelog entry for HTMLKit 2.1.3 2018-03-21 22:42:00 +01:00
iska b7bf9d2b04 Use HTMLOrderedDictionary when cloning element's attributes 2018-03-21 22:19:24 +01:00
iska 12af838fa2 Update html5lib-tests to latest commit as of 2018.03.18 2018-03-18 21:45:44 +01:00
iska 14b8b5390f Add test case for node deep-clone 2018-03-18 21:45:04 +01:00
Iskandar Abudiab a5599c4163 Merge pull request #23 from CRivlaldo/iterator
Fix the issue #22
2018-03-18 21:26:27 +01:00
Iskandar Abudiab c0ac25645d Merge pull request #24 from CRivlaldo/deepclone
Fix the issue #20
2018-03-18 21:19:42 +01:00
Vladimir fa431550d7 Fix the issue 22 (fix a test name) 2018-03-17 11:34:22 +03:00
Vladimir 70c6aee814 Fix the issue 22 2018-03-17 11:33:30 +03:00
Vladimir 7309b97b92 Fix the HTMLElement attributes copying 2018-03-17 10:40:00 +03:00
iska 7ffb8e5ca0 Merge branch 'release/2.1.2' into develop 2017-11-06 22:05:08 +01:00
iska 682b19c242 Merge branch 'release/2.1.2' 2017-11-06 22:05:07 +01:00
iska 16ed846e65 Bump HTMLKit version to 2.1.2 2017-11-06 22:04:57 +01:00
iska 820b3ef091 Update podspec for 2.1.2 2017-11-06 22:04:38 +01:00
iska fb7ea25b1f Update jazzy.yaml for 2.1.2 2017-11-06 22:04:29 +01:00
iska 5302c16600 Add Changelog entry for HTMLKit 2.1.2 2017-11-06 22:04:18 +01:00
iska 2dfdeb22ca Fix HTMLElement attribute value serialization
Fixes #17
2017-11-06 21:58:08 +01:00
iska 135715b606 Fix HTMLText serialization
Fixes #16
2017-11-06 21:55:41 +01:00
iska f8e6a39171 Merge branch 'hotfix/2.1.1' into develop 2017-10-13 23:05:31 +02:00
iska 20cf2dc4d0 Merge branch 'hotfix/2.1.1' 2017-10-13 23:05:02 +02:00
iska 0921ebad8a Bump HTMLKit version to 2.1.1 2017-10-13 23:04:33 +02:00
iska c63e2cb8fd Update podspec for 2.1.1 2017-10-13 23:03:49 +02:00
iska 3deeb0138f Update jazzy.yaml for 2.1.1 2017-10-13 23:03:38 +02:00
iska b358a08f30 Add Changelog entry for HTMLKit 2.1.1 2017-10-13 23:03:19 +02:00
iska 84960e71ee Enable warnings for missing function prototypes and fix present error 2017-10-13 22:54:30 +02:00
iska 7b028a2819 Enable warnings for documentation comments and fix present errors 2017-10-13 22:48:16 +02:00
iska 5aa77eac9b Merge branch 'release/2.1.0' into develop 2017-10-12 22:44:50 +02:00
iska c1cd1c0831 Merge branch 'release/2.1.0' 2017-10-12 22:44:49 +02:00
iska 1101556cfe Bump HTMLKit version to 2.1.0 2017-10-12 22:44:39 +02:00
iska 839a724432 Update podspec for 2.1.0 2017-10-12 22:44:39 +02:00
iska 300705cb63 Update jazzy.yaml for 2.1.0 2017-10-12 22:44:39 +02:00
iska 1963c010f9 Add Changelog entry for HTMLKit 2.1.0 2017-10-12 22:44:39 +02:00
iska 89ef6bc101 Update README for master branch 2017-10-12 22:44:39 +02:00
iska 9069923e82 Update handling for ParseErrorTokens in the HTML Parser 2017-10-12 22:25:46 +02:00
iska c16c647394 Add codecove.yml and update badges in README 2017-09-28 00:00:23 +02:00
iska 27b8eaac67 Add codecov after-script to upload coverage reports 2017-09-27 18:58:22 +02:00
iska 956c46ec45 Fix travis destinations for iOS 9.3 and 10.3 2017-09-27 00:11:56 +02:00
iska cb7e5d519d Update travis.yml for Xcode 9 and iOS 11 2017-09-26 22:38:09 +02:00
iska 4e1959bd81 Fix strict-prototypes blocks declarations throughout codebase 2017-09-23 02:31:48 +02:00
iska f0d9817c68 Restore default modulemap file name
Closes #13
2017-09-23 02:27:35 +02:00
iska fee2d14ffc Update project for Xcode 9 2017-09-23 02:26:46 +02:00
iska 4291840a53 Update .travis.yml 2017-09-10 15:56:36 +02:00
iska 4b7c260738 Update HTML Spec fixture to source as of 2017.09.09 2017-09-10 02:26:39 +02:00
iska 4a41b89ecf Update tokenizer implementation as per spec as of 2017.09.09
- Use new initial states in tests according to:
https://github.com/html5lib/html5lib-tests/pull/101

- Implement tokenization errors introduced in:
https://github.com/whatwg/html/pull/2701
https://github.com/html5lib/html5lib-tests/pull/92
2017-09-10 02:23:31 +02:00
iska d4ff2e3869 Add error-code property for ParseError token
In addition to the detailed reason message parse errors have an
error-code property that is specified in the WHATWG HTML spec.
2017-09-07 22:08:28 +02:00
iska 6dee6c1e74 Update input stream reader error handling
Use newly specified parse errors:
https://html.spec.whatwg.org/multipage/parsing.html#parse-errors
2017-09-07 22:05:02 +02:00
iska 20ebd8c603 Update html5lib-tests to latest commit as of 2017.09.06 2017-09-06 22:14:34 +02:00
iska c002299247 Merge branch 'release/2.0.6' into develop 2017-05-02 15:49:16 +02:00
iska bb6d7ccc67 Merge branch 'release/2.0.6' 2017-05-02 15:49:15 +02:00
iska bf655c7ea2 Bump HTMLKit version to 2.0.6 2017-05-02 15:49:08 +02:00
iska 6cd03b4eed Update podspec for 2.0.6 2017-05-02 15:48:54 +02:00
iska cc0734e470 Update jazzy.yaml for 2.0.6 2017-05-02 15:48:45 +02:00
iska eca6098361 Add Changelog entry for HTMLKit 2.0.6 2017-05-02 15:48:36 +02:00
iska 2cd5098d8a Update destinations and simulators in travis.yml 2017-05-02 14:01:48 +02:00
iska 514d23f7a0 Update SDK versions in travis.yml 2017-05-02 13:52:16 +02:00
iska 2446da3a6d Update travis xcode image to 8.3 2017-05-02 13:50:35 +02:00
iska 644c180f81 Improve memory allocation/consumption in the Stack of Open Elements
Instead of allocating new dictionaries for the scope elements, the scope
checks are just unrolled in-place. Now we have 6 almost identical methods
that differ only in the inline-check-method. Not optimal but minimal
memory and performance penalty.

This should reduce memory consumption and increase the performance
while parsing, see issue #10
2017-04-26 21:31:55 +02:00
iska 47ec0867a8 Improve reverseObjectEnumerator usage while parsing HTML
Do not use the `allObjects` call on the reverse enumerators in the Parser
and the List of Active Formatting Elements to prevent allocating a new
array of the unenumerated objects.

This should reduce memory consumption while parsing, see issue #10
2017-04-25 00:12:39 +02:00
iska 1cd1a915d3 Replace NSStringFromSelector calls with constants in HTMLNode
This should reduce allocations during HTML parsing. See Issue #10
2017-04-24 22:58:49 +02:00
iska 8379cee44f Fix lazy allocation of childNodes Set in HTMLNode
The call self.childNodes always allocates the collection even if a nil
value is acceptable, i.e. hasChildNodes should return true even if the
childNodes Set is nil but should not allocate it yet.

Hence self.childNodes should only be used when appending child nodes.
2017-04-24 22:36:02 +02:00
iska 4094f51458 Merge branch 'release/2.0.5' 2017-04-19 00:02:10 +02:00
iska 57c931aece Merge branch 'release/2.0.5' into develop 2017-04-19 00:02:10 +02:00
iska 76b379448b Bump HTMLKit version to 2.0.5 2017-04-18 23:59:57 +02:00
iska 49bdfa018e Update podspec for 2.0.5 2017-04-18 23:59:37 +02:00
iska 746ef2ea3b Update jazzy.yaml for 2.0.5 2017-04-18 23:59:27 +02:00
iska 653f6cdf7e Add Changelog entry for HTMLKit 2.0.5 2017-04-18 23:58:46 +02:00
iska d9670cddf4 Add workaround for Xcode8.3 issue with modulemaps
This should be the fix for #12. However the issue will stay open until
tested with Xcode 8.3.1
2017-04-09 20:58:25 +02:00
iska 30389c5010 Add an autorelease pool in the Tokenizer’s iteration method 2017-04-09 20:54:01 +02:00
iska 14dfc0b854 Replace performSelector with for-loop in HTML Node methods 2017-04-09 20:53:11 +02:00
iska b693a60358 Use lazy allocation for underlying collections in HTML Nodes
Do not allocate empty collections for child nodes or attributes when
initializing new HTML Nodes or Elements. These are initialized the first
time they are accessed.

Analogously, the mutable data string of CharacterData is also allocated
with the empty string on first access.
2017-04-09 20:52:06 +02:00
iska d35e6c4d91 Fix memory leaks in CSS Input Stream
- Release allocated instances when returning nil
- Pass autoreleased instances on valid return value
2017-04-09 20:47:55 +02:00
iska c353512a65 Merge branch 'release/2.0.4' into develop 2017-04-03 22:21:43 +02:00
iska aaee85909b Merge branch 'release/2.0.4' 2017-04-03 22:21:42 +02:00
iska 8d3f24ef8b Bump HTMLKit version to 2.0.4 2017-04-03 22:21:15 +02:00
iska b652935739 Update podspec for 2.0.4 2017-04-03 22:20:51 +02:00
iska 601c83a51f Update jazzy.yaml for 2.0.4 2017-04-03 22:20:42 +02:00
iska 774ac35bbb Add Changelog entry for HTMLKit 2.0.4 2017-04-03 22:20:05 +02:00
iska 9651d12fd0 Deprecate for old HTMLRange’s initializers with typo 2017-03-31 17:23:30 +02:00
Iskandar Abudiab 0899a4013d Merge pull request #11 from tali/develop
Fix typo in HTMLRange's initializer

initWithDowcument: -> initWithDocument
2017-03-31 17:19:16 +02:00
Martin Waitz 22de41d912 Fix typo Dowcument -> Document 2017-03-31 08:53:11 +02:00
Iskandar Abudiab 2f47e733bd Merge pull request #8 from tali/develop
Fix tests for Swift 3.1
2017-03-14 00:13:36 +01:00
Martin Waitz 36f5df015a [Tests] fix includes 2017-03-13 23:11:16 +01:00
Martin Waitz bbc5467b33 [modulemap] use textual header for character definitions
Both CSSCodePoints.h and HTMLTokenizerCharacters.h define the same
symbols.
They are never included by the same compilation unit, but when they are
compiled into the same module, they create a conflict.
Fix this conflict by using `textual header`.
2017-03-13 23:11:16 +01:00
iska 7ef19f5e20 Ignore performance tests
For now these are ignored for faster testing/iterations.
The test fixture should also be replaced with several smaller
and more representative ones, since it is relatively big.
2017-03-13 23:04:58 +01:00
iska a102f5cd7d Fix loading of test resources
Building and testing the project via Xcode copies the resources into
the testing bundle, which is not the case for SwiftPM. Hence the helper
method, that tries loading the resource from the bundle first. If it is
nil then the resource is loaded from the test module path directly.
2017-03-13 23:01:53 +01:00
iska 7a40e8bafd Merge branch 'release/2.0.3' 2017-03-06 00:31:03 +01:00
iska 40b057b569 Merge branch 'release/2.0.3' into develop 2017-03-06 00:31:03 +01:00
iska a7ace9929f Bump HTMLKit version to 2.0.3 2017-03-06 00:30:41 +01:00
iska 32b674f786 Update podspec for 2.0.3 2017-03-06 00:30:37 +01:00
iska e9e3f04136 Update jazzy.yaml for 2.0.3 2017-03-06 00:30:32 +01:00
iska 44f1bc6946 Add Changelog entry for HTMLKit 2.0.3 2017-03-06 00:30:26 +01:00
Iskandar Abudiab ef36e674a4 Merge pull request #6 from tali/develop
Fix compilation for Swift 3.1
2017-03-03 10:32:58 +01:00
Martin Waitz b8f1123b86 Fix compilation for Swift 3.1
Move the `module.modulemap` into `Sources/include` and add an exclude
for `Tests/Fixtures`.
2017-03-03 08:25:14 +01:00
iska 17a2e375e0 Merge branch 'release/2.0.2' into develop 2017-02-26 21:46:00 +01:00
84 changed files with 4355 additions and 82508 deletions
+5
View File
@@ -0,0 +1,5 @@
codecov:
branch: develop
ignore:
- "Tests/"
+1 -1
View File
@@ -1,5 +1,5 @@
module: HTMLKit
module_version: 2.0.2
module_version: 3.0.0
author: Iskandar Abudiab
author_url: https://twitter.com/iabudiab
github_url: https://github.com/iabudiab/HTMLKit
+18 -18
View File
@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode8.2
osx_image: xcode9
branches:
except:
@@ -17,29 +17,29 @@ env:
- MACOS_FRAMEWORK_SCHEME=HTMLKit-macOS
- WATCHOS_FRAMEWORK_SCHEME="HTMLKit-watchOS"
- TVOS_FRAMEWORK_SCHEME="HTMLKit-tvOS"
- IOS_SDK=iphonesimulator10.2
- MACOS_SDK=macosx10.12
- WATCHOS_SDK=watchsimulator3.1
- TVOS_SDK=appletvsimulator10.1
- IOS_SDK=iphonesimulator11.0
- MACOS_SDK=macosx10.13
- WATCHOS_SDK=watchsimulator4.0
- TVOS_SDK=appletvsimulator11.0
matrix:
- DESTINATION="arch=x86_64" SIMULATOR="" SCHEME="$MACOS_FRAMEWORK_SCHEME" SDK="$MACOS_SDK"
- DESTINATION="OS=9.0,name=iPhone 6" SIMULATOR="iPhone 6 (9.0)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.1,name=iPhone 6 Plus" SIMULATOR="iPhone 6 Plus (9.1)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.2,name=iPhone 6S" SIMULATOR="iPhone 6S (9.2)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=9.3,name=iPhone 6S Plus" SIMULATOR="iPhone 6S Plus (9.3)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=10.1,name=iPhone 7 Plus" SIMULATOR="iPhone 7 Plus (10.1)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SIMULATOR="Apple Watch - 42mm (2.2)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=3.1,name=Apple Watch Series 2 - 42mm" SIMULATOR="Apple Watch Series 2 - 42mm (3.1)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=9.0,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (9.2)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="OS=10.0,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (10.0)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="arch=x86_64" SCHEME="$MACOS_FRAMEWORK_SCHEME" SDK="$MACOS_SDK"
- DESTINATION="OS=9.3,name=iPhone 6s Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=10.3.1,name=iPhone 7 Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=11.0,name=iPhone X" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK"
- DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=4.0,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
- DESTINATION="OS=11.0,name=Apple TV 4K" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK"
script:
- set -o pipefail
- xcodebuild -version
- xcodebuild -showsdks
- SIMULATOR_ID=$(xcrun instruments -s devices | grep -io "$SIMULATOR \[.*\]" | grep -o "\[.*\]" | sed "s/^\[\(.*\)\]$/\1/")
- open -b com.apple.iphonesimulator --args -CurrentDeviceUDID $SIMULATOR_ID
- travis_retry xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean build | xcpretty -c
- if [ "$SDK" != "$WATCHOS_SDK" ]; then
travis_retry xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO test | xcpretty -c;
travis_retry xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES test | xcpretty -c;
fi
after_success:
- bash <(curl -s https://codecov.io/bash)
+132
View File
@@ -1,10 +1,142 @@
# Change Log
## [3.0.0](https://github.com/iabudiab/HTMLKit/releases/tag/3.0.0)
Released on 2019.03.28
### Breaking Change
- Introduce prefix for `NSString` and `NSCharacterSet` categories to prevent collision with existing code (issue #35)
## [2.1.5](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.5)
Released on 2018.07.16
### Fixes
- Parser would handle foreign attributes incorrectly (issue #30)
## [2.1.4](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.4)
Released on 2018.05.01
### Fixes
- `gt(n)`, `lt(n)` and `eq(n)` selectors would select wrong elements for the zero-index (issue #25)
## [2.1.3](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.3)
Released on 2018.03.21
### Fixes
- `HTMLElement` clone would return an immutable dictionary for attributes (issue #20)
- Fixed by @CRivlaldo in PR #24
- `HTMLNodeFilterBlock` would behave differently on simulator and device (issue #22)
- Fixed by @CRivlaldo in PR #23
## [2.1.2](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.2)
Released on 2017.11.6
### Fixes
- `HTMLText` serialization (issue #16)
- `HTMLElement` attribute value serialization (issue #17)
## [2.1.1](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.1)
Released on 2017.10.13
### Hotfix
- Fixed documentation comments
- Should fix CocoaDocs generation and percentage
## [2.1.0](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.0)
Released on 2017.10.12
### Added
- Standarized tokenizer error codes:
- [whatwg/html#2701](https://github.com/whatwg/html/pull/2701)
- [html5lib/html5lib-tests#92](https://github.com/html5lib/html5lib-tests/pull/92)
### Updated
- Project for Xcode 9
- Travis config for iOS 11.0, macOS 10.13, tvOS 11.0 and watchOS 4.0
- Updated HTML5Lib-Tests submodule (cbafeba)
## [2.0.6](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.6)
Released on 2017.05.02
### Added
- Memory consumption improvements (issue #10)
- Allocate `childNodes` collection in `HTMLNode` only when inserting child nodes
- Replace `NSStringFromSelector` calls with constants in `HTMLNode` validations
- Improve `reverseObjectEnumerator` usage while parsing HTML
- Rewrite internal logic of the `HTMLStackOfOpenElements` to prevent excessive allocations
## [2.0.5](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.5)
Released on 2017.04.19
### Fixed
- Xcode 8.3 issue with modulemaps
- Temporary workaround (renamed modulemap file)
- Memory Leaks in `CSSInputStream`
### Added
- Minor memory consumption improvements
- Collections for child nodes or attributes of HTML Nodes or Elements are allocated lazily
- Underyling data string of `CharacterData` is allocated on first access
- Autorelease pool for the main `HTMLTokenizer` loop
## [2.0.4](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.4)
Released on 2017.04.2
### Fixed
- Testing with Swift 3.1
- Fixed by @tali in PR #8
### Deprecated
- `HTMLRange` initializers with typo
- `initWithDowcument:startContainer:startOffset:endContainer:endOffset:`
## [2.0.3](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.3)
Released on 2017.03.6
### Fixed
- Compilation for Swift 3.1
- Fixed by @tali in PR #6
## [2.0.2](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.2)
Released on 2017.02.26
### Fixed
- Retain cycles in `HTMLNodeIterator` (issue #4)
- Retain cycles in `HTMLRange` (issue #5)
- The layout of `HTMLKit` tests module for Swift Package Manager
@@ -89,7 +89,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = iabudiab;
TargetAttributes = {
629A63C81D9AFE0E0089679F = {
@@ -136,7 +136,9 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@@ -144,7 +146,12 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -184,7 +191,9 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
@@ -192,7 +201,12 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -212,6 +226,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
@@ -250,6 +265,7 @@
629A63D21D9AFE0E0089679F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -45,6 +46,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "HTMLKit"
s.version = "2.0.2"
s.version = "3.0.0"
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
s.license = "MIT"
s.homepage = "https://github.com/iabudiab/HTMLKit"
+99 -1
View File
@@ -11,6 +11,9 @@
62056C501E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
62056C511E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
62056C521E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
620AB7B12087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
620AB7B22087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
620AB7B32087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */; };
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62132E581C01F83200084175 /* CSSSelectorTest.m */; };
62132E5D1C021FF200084175 /* css-tests in Resources */ = {isa = PBXBuildFile; fileRef = 62132E5B1C021FF200084175 /* css-tests */; };
6216ACFD1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6216ACFC1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m */; };
@@ -55,6 +58,18 @@
625A14B019C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; };
625A14C519C7829400AD0C32 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14C419C7829400AD0C32 /* XCTest.framework */; };
625A14C919C7829400AD0C32 /* HTMLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AC19C7829400AD0C32 /* HTMLKit.framework */; };
625A67C9224AC62C00C6D57D /* NSString+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A67C7224AC62C00C6D57D /* NSString+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625A67CA224AC62C00C6D57D /* NSString+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A67C7224AC62C00C6D57D /* NSString+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625A67CB224AC62C00C6D57D /* NSString+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A67C7224AC62C00C6D57D /* NSString+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625A67CC224AC62C00C6D57D /* NSString+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A67C7224AC62C00C6D57D /* NSString+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625A67CD224AC62C00C6D57D /* NSString+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67C8224AC62C00C6D57D /* NSString+Private.m */; };
625A67CE224AC62C00C6D57D /* NSString+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67C8224AC62C00C6D57D /* NSString+Private.m */; };
625A67CF224AC62C00C6D57D /* NSString+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67C8224AC62C00C6D57D /* NSString+Private.m */; };
625A67D0224AC62C00C6D57D /* NSString+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67C8224AC62C00C6D57D /* NSString+Private.m */; };
625A67D2224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */; };
625A67D3224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */; };
625A67D4224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */; };
625A67D5224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */; };
625D0F031C2717DE00D7BEB0 /* HTMLNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625D0F011C2717DE00D7BEB0 /* HTMLNode+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625D0F041C2717DE00D7BEB0 /* HTMLNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 625D0F011C2717DE00D7BEB0 /* HTMLNode+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
625EE4571CBAA41D00F2CC8E /* HTMLKitTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 625EE4561CBAA41D00F2CC8E /* HTMLKitTestObserver.m */; };
@@ -306,6 +321,12 @@
62857D8F1D39A47F008DC254 /* CSSCombinatorSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
62857D901D39A47F008DC254 /* CSSCompoundSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
628AF6301BC99A6C00496128 /* CSSNthExpressionsParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */; };
62A95A4D1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
62A95A4E1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
62A95A4F1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */; };
62C82E0D20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
62C82E0E20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
62C82E0F20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */; };
62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */; };
62D91C231DE218A500BEFADE /* HTMLRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D91C211DE218A500BEFADE /* HTMLRange.h */; settings = {ATTRIBUTES = (Public, ); }; };
62D91C241DE218A500BEFADE /* HTMLRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D91C211DE218A500BEFADE /* HTMLRange.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -581,6 +602,7 @@
/* Begin PBXFileReference section */
62056C4E1E2AD9FB009A4EE0 /* HTMLNodeIterator+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "HTMLNodeIterator+Private.h"; path = "include/HTMLNodeIterator+Private.h"; sourceTree = "<group>"; };
62079BE71AF56F1E00D3B402 /* CSSSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSSelector.h; path = include/CSSSelector.h; sourceTree = "<group>"; };
620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CSSStructuralPseudoSelectors.m; path = HTMLKitTests/CSSStructuralPseudoSelectors.m; sourceTree = "<group>"; };
620C87791BD44CBE00FB3EEE /* CSSCompoundSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSCompoundSelector.h; path = include/CSSCompoundSelector.h; sourceTree = "<group>"; };
620C877A1BD44CBE00FB3EEE /* CSSCompoundSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSCompoundSelector.m; sourceTree = "<group>"; };
620EE9471BC46F2A0028ED34 /* CSSPseudoClassSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSPseudoClassSelector.h; path = include/CSSPseudoClassSelector.h; sourceTree = "<group>"; };
@@ -682,6 +704,9 @@
625A14DF19C7834100AD0C32 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLInputStreamReader.h; path = include/HTMLInputStreamReader.h; sourceTree = "<group>"; };
625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLInputStreamReader.m; sourceTree = "<group>"; };
625A67C7224AC62C00C6D57D /* NSString+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSString+Private.h"; path = "include/NSString+Private.h"; sourceTree = "<group>"; };
625A67C8224AC62C00C6D57D /* NSString+Private.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+Private.m"; sourceTree = "<group>"; };
625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HTMLQuircksMode.m; sourceTree = "<group>"; };
625D0F011C2717DE00D7BEB0 /* HTMLNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "HTMLNode+Private.h"; path = "include/HTMLNode+Private.h"; sourceTree = "<group>"; };
625EE4551CBAA41D00F2CC8E /* HTMLKitTestObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLKitTestObserver.h; path = HTMLKitTests/HTMLKitTestObserver.h; sourceTree = "<group>"; };
625EE4561CBAA41D00F2CC8E /* HTMLKitTestObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTMLKitTestObserver.m; path = HTMLKitTests/HTMLKitTestObserver.m; sourceTree = "<group>"; };
@@ -703,6 +728,7 @@
628AF63C1BC9D6FB00496128 /* CSSStructuralPseudoSelectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSStructuralPseudoSelectors.h; path = include/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; name = HTMLNamespaces.h; path = include/HTMLNamespaces.h; sourceTree = "<group>"; };
62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = HTMLSerializationTests.m; path = HTMLKitTests/HTMLSerializationTests.m; sourceTree = "<group>"; };
62ACB8DB1BC5C13E00E283C1 /* CSSPseudoFunctionSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSPseudoFunctionSelector.h; path = include/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; name = HTMLParseErrorToken.h; path = include/HTMLParseErrorToken.h; sourceTree = "<group>"; };
@@ -715,6 +741,7 @@
62AE594319F992F30043F069 /* HTMLCommentToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLCommentToken.m; sourceTree = "<group>"; };
62AE594719F9948A0043F069 /* HTMLCharacterToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLCharacterToken.h; path = include/HTMLCharacterToken.h; sourceTree = "<group>"; };
62AE594819F9948A0043F069 /* HTMLCharacterToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLCharacterToken.m; sourceTree = "<group>"; };
62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = HTMLKitParserIssuesTests.m; path = HTMLKitTests/HTMLKitParserIssuesTests.m; sourceTree = "<group>"; };
62D8345719FB1AC4009205A9 /* HTML5LibTokenizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTML5LibTokenizerTest.h; path = HTMLKitTests/HTML5LibTokenizerTest.h; sourceTree = "<group>"; };
62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTML5LibTokenizerTest.m; path = HTMLKitTests/HTML5LibTokenizerTest.m; sourceTree = "<group>"; };
62D91C211DE218A500BEFADE /* HTMLRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLRange.h; path = include/HTMLRange.h; sourceTree = "<group>"; };
@@ -860,6 +887,7 @@
6238C9841AB8D6330006512E /* HTMLKitDOMExceptions.m */,
628B7CE61A080E1000602C87 /* HTMLNamespaces.h */,
623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */,
625A67D1224ADC7700C6D57D /* HTMLQuircksMode.m */,
625D0F071C2717E400D7BEB0 /* Private */,
);
name = DOM;
@@ -885,6 +913,7 @@
62EC7AE51AEEAC6F0015D3BE /* HTMLMutationAlgorithmsTests.m */,
62EC0A841E158BD80007786B /* HTMLRangeTests.m */,
62E0BA961E25456700E4D193 /* HTMLCharacterDataTests.m */,
62A95A4C1FB0FBFC0009FF26 /* HTMLSerializationTests.m */,
);
name = DOM;
sourceTree = "<group>";
@@ -984,6 +1013,7 @@
625EE45A1CBB171300F2CC8E /* HTMLKitTestUtil.m */,
6236738C1AC0CD2400FF89B3 /* Tokenizer */,
623975581AC362A5007E26F1 /* Tree Construction */,
62C82E0B20FD2FCB008497A8 /* Parser */,
624B9FB71AE072CB00646C4C /* DOM */,
624B9FB81AE072D500646C4C /* Categories */,
624E1A2D1B1D1C8A00E66AAC /* Structures */,
@@ -1041,6 +1071,8 @@
628E16ED1ADAE73700B15A06 /* Categories */ = {
isa = PBXGroup;
children = (
625A67C7224AC62C00C6D57D /* NSString+Private.h */,
625A67C8224AC62C00C6D57D /* NSString+Private.m */,
6235CE991AA509430026937B /* NSString+HTMLKit.h */,
6235CE9A1AA509430026937B /* NSString+HTMLKit.m */,
624B28C21B04190D0048D328 /* NSCharacterSet+HTMLKit.h */,
@@ -1088,6 +1120,14 @@
name = Tokenizing;
sourceTree = "<group>";
};
62C82E0B20FD2FCB008497A8 /* Parser */ = {
isa = PBXGroup;
children = (
62C82E0C20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m */,
);
name = Parser;
sourceTree = "<group>";
};
62ECBEDF1C0B671000AF847B /* Parsing */ = {
isa = PBXGroup;
children = (
@@ -1139,6 +1179,7 @@
624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */,
62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */,
621FBE5C1BDAD90200BC9555 /* CSSCombinatorSelectorTests.m */,
620AB7B02087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m */,
);
name = Selectors;
sourceTree = "<group>";
@@ -1166,6 +1207,7 @@
62ECBEEA1C0B69FD00AF847B /* HTMLCommentToken.h in Headers */,
62ECBEEB1C0B69FD00AF847B /* HTMLDOCTYPEToken.h in Headers */,
626BE1E21DF3819500C49514 /* HTMLDOMUtils.h in Headers */,
625A67C9224AC62C00C6D57D /* NSString+Private.h in Headers */,
62ECBEEC1C0B69FD00AF847B /* HTMLParseErrorToken.h in Headers */,
62ECBEED1C0B69FD00AF847B /* HTMLTagToken.h in Headers */,
62ECBEEE1C0B69FD00AF847B /* HTMLEOFToken.h in Headers */,
@@ -1239,6 +1281,7 @@
62857C841D398917008DC254 /* HTMLParser.h in Headers */,
62857CDB1D3989CE008DC254 /* CSSAttributeSelector.h in Headers */,
62857C791D398907008DC254 /* HTMLEOFToken.h in Headers */,
625A67CC224AC62C00C6D57D /* NSString+Private.h in Headers */,
626BE1E51DF3819500C49514 /* HTMLDOMUtils.h in Headers */,
62857CC41D3989A9008DC254 /* CSSSelectors.h in Headers */,
62857C731D398907008DC254 /* HTMLToken.h in Headers */,
@@ -1312,6 +1355,7 @@
62857D4E1D39A40A008DC254 /* HTMLTokenizerCharacters.h in Headers */,
62857D4D1D39A40A008DC254 /* HTMLTokenizerStates.h in Headers */,
62857D501D39A411008DC254 /* HTMLTokens.h in Headers */,
625A67CB224AC62C00C6D57D /* NSString+Private.h in Headers */,
626BE1E41DF3819500C49514 /* HTMLDOMUtils.h in Headers */,
62857D7B1D39A452008DC254 /* HTMLNamespaces.h in Headers */,
62857D581D39A416008DC254 /* HTMLParser.h in Headers */,
@@ -1385,6 +1429,7 @@
62ECBFAF1C0B6D3B00AF847B /* HTMLNodeIterator.h in Headers */,
62ECBFB01C0B6D3C00AF847B /* HTMLTreeWalker.h in Headers */,
62ECBFB21C0B6D3C00AF847B /* HTMLNodeFilter.h in Headers */,
625A67CA224AC62C00C6D57D /* NSString+Private.h in Headers */,
62567F511C0CB5750025D458 /* HTMLDOMTokenList.h in Headers */,
62ECBFB31C0B6D3C00AF847B /* HTMLKitDOMExceptions.h in Headers */,
62ECBFB41C0B6D3D00AF847B /* HTMLNamespaces.h in Headers */,
@@ -1573,7 +1618,7 @@
625A14A319C7829400AD0C32 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = BrainCookie;
TargetAttributes = {
625A14C219C7829400AD0C32 = {
@@ -1707,6 +1752,7 @@
62ECBF2A1C0B6B7900AF847B /* HTMLNode.m in Sources */,
62ECBF2B1C0B6B7900AF847B /* HTMLDocument.m in Sources */,
62ECBF2C1C0B6B7900AF847B /* HTMLDocumentType.m in Sources */,
625A67D2224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */,
62ECBF2D1C0B6B7900AF847B /* HTMLDocumentFragment.m in Sources */,
62ECBF2E1C0B6B7900AF847B /* HTMLElement.m in Sources */,
62ECBF2F1C0B6B7900AF847B /* HTMLComment.m in Sources */,
@@ -1725,6 +1771,7 @@
62ECBF3C1C0B6B7900AF847B /* CSSInputStream.m in Sources */,
62ECBF3D1C0B6B7900AF847B /* CSSSelectorParser.m in Sources */,
62ECBF3E1C0B6B7900AF847B /* CSSNthExpressionParser.m in Sources */,
625A67CD224AC62C00C6D57D /* NSString+Private.m in Sources */,
62ECBF3F1C0B6B7900AF847B /* CSSSelector.m in Sources */,
62ECBF401C0B6B7900AF847B /* CSSSelectorBlock.m in Sources */,
62ECBF411C0B6B7900AF847B /* CSSTypeSelector.m in Sources */,
@@ -1745,8 +1792,10 @@
buildActionMask = 2147483647;
files = (
62EC0A851E158BD80007786B /* HTMLRangeTests.m in Sources */,
620AB7B12087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
62E0BA971E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
6216ACFD1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */,
62C82E0D20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
62132E5A1C01F83200084175 /* CSSSelectorTest.m in Sources */,
6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */,
@@ -1761,6 +1810,7 @@
62567F561C0CC3AE0025D458 /* HTMLDOMTokenListTests.m in Sources */,
624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */,
624B9FB31AE0313300646C4C /* HTMLStringCategoryTests.m in Sources */,
62A95A4D1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */,
623916C81AC7209E0066B4FE /* HTMLNodeIteratorTests.m in Sources */,
62D8345A19FB1AC4009205A9 /* HTML5LibTokenizerTest.m in Sources */,
6239755F1AC364BB007E26F1 /* HTML5LibTreeConstructionTest.m in Sources */,
@@ -1794,6 +1844,7 @@
62857C811D398912008DC254 /* HTMLParseErrorToken.m in Sources */,
62857CD21D3989B8008DC254 /* CSSCombinatorSelector.m in Sources */,
62857CB91D398992008DC254 /* HTMLNodeIterator.m in Sources */,
625A67D5224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */,
62857CCF1D3989B8008DC254 /* CSSPseudoClassSelector.m in Sources */,
62857C7A1D398912008DC254 /* HTMLInputStreamReader.m in Sources */,
62857CC11D39899C008DC254 /* NSCharacterSet+HTMLKit.m in Sources */,
@@ -1812,6 +1863,7 @@
62857CBC1D398992008DC254 /* HTMLNodeFilter.m in Sources */,
62857CC01D39899C008DC254 /* NSString+HTMLKit.m in Sources */,
62857CCA1D3989B8008DC254 /* CSSInputStream.m in Sources */,
625A67D0224AC62C00C6D57D /* NSString+Private.m in Sources */,
62857CCE1D3989B8008DC254 /* CSSAttributeSelector.m in Sources */,
62857CC31D3989A3008DC254 /* HTMLOrderedDictionary.m in Sources */,
62857CC91D3989B8008DC254 /* CSSNthExpressionParser.m in Sources */,
@@ -1849,6 +1901,7 @@
62857D0F1D39A32A008DC254 /* HTMLNode.m in Sources */,
62857D2C1D39A334008DC254 /* CSSCombinatorSelector.m in Sources */,
62857D181D39A32A008DC254 /* HTMLNodeIterator.m in Sources */,
625A67D4224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */,
62857D291D39A334008DC254 /* CSSPseudoClassSelector.m in Sources */,
62857D011D39A324008DC254 /* HTMLInputStreamReader.m in Sources */,
62857D1E1D39A334008DC254 /* NSCharacterSet+HTMLKit.m in Sources */,
@@ -1867,6 +1920,7 @@
62857D1B1D39A32A008DC254 /* HTMLNodeFilter.m in Sources */,
62857D1D1D39A334008DC254 /* NSString+HTMLKit.m in Sources */,
62857D241D39A334008DC254 /* CSSInputStream.m in Sources */,
625A67CF224AC62C00C6D57D /* NSString+Private.m in Sources */,
62857D281D39A334008DC254 /* CSSAttributeSelector.m in Sources */,
62857D1F1D39A334008DC254 /* HTMLOrderedDictionary.m in Sources */,
62857D231D39A334008DC254 /* CSSNthExpressionParser.m in Sources */,
@@ -1887,8 +1941,10 @@
buildActionMask = 2147483647;
files = (
62EC0A871E158BD80007786B /* HTMLRangeTests.m in Sources */,
620AB7B32087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
62E0BA991E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
62857D3B1D39A345008DC254 /* CSSSelectorTest.m in Sources */,
62C82E0F20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
62857D421D39A345008DC254 /* CSSCombinatorSelectorTests.m in Sources */,
62857D3C1D39A345008DC254 /* CSSSelectorParserTests.m in Sources */,
62857D301D39A339008DC254 /* HTMLKitTokenizerPerformance.m in Sources */,
@@ -1903,6 +1959,7 @@
62857D401D39A345008DC254 /* CSSAttributeSelectorTests.m in Sources */,
62857D311D39A33C008DC254 /* HTML5LibTreeConstructionTest.m in Sources */,
62857D391D39A342008DC254 /* HTMLOrderedDictionaryTests.m in Sources */,
62A95A4F1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */,
62857D411D39A345008DC254 /* CSSNThExpressionSelectorTests.m in Sources */,
62857D381D39A342008DC254 /* HTMLStringCategoryTests.m in Sources */,
62857D331D39A33C008DC254 /* HTMLKitParserPerformance.m in Sources */,
@@ -1936,6 +1993,7 @@
62ECBF721C0B6D2A00AF847B /* HTMLNode.m in Sources */,
62ECBF731C0B6D2A00AF847B /* HTMLDocument.m in Sources */,
62ECBF741C0B6D2A00AF847B /* HTMLDocumentType.m in Sources */,
625A67D3224ADC7700C6D57D /* HTMLQuircksMode.m in Sources */,
62ECBF751C0B6D2A00AF847B /* HTMLDocumentFragment.m in Sources */,
62ECBF761C0B6D2A00AF847B /* HTMLElement.m in Sources */,
62ECBF771C0B6D2A00AF847B /* HTMLComment.m in Sources */,
@@ -1954,6 +2012,7 @@
62ECBF841C0B6D2A00AF847B /* CSSInputStream.m in Sources */,
62ECBF851C0B6D2A00AF847B /* CSSSelectorParser.m in Sources */,
62ECBF861C0B6D2A00AF847B /* CSSNthExpressionParser.m in Sources */,
625A67CE224AC62C00C6D57D /* NSString+Private.m in Sources */,
62ECBF871C0B6D2A00AF847B /* CSSSelector.m in Sources */,
62ECBF881C0B6D2A00AF847B /* CSSSelectorBlock.m in Sources */,
62ECBF891C0B6D2A00AF847B /* CSSTypeSelector.m in Sources */,
@@ -1974,8 +2033,10 @@
buildActionMask = 2147483647;
files = (
62EC0A861E158BD80007786B /* HTMLRangeTests.m in Sources */,
620AB7B22087F18D00AFCCC7 /* CSSStructuralPseudoSelectors.m in Sources */,
62E0BA981E25456700E4D193 /* HTMLCharacterDataTests.m in Sources */,
6216ACFE1C28DCC80074CAB4 /* CSSExtensionSelectorsParsingTests.m in Sources */,
62C82E0E20FD2FFD008497A8 /* HTMLKitParserIssuesTests.m in Sources */,
62ECBFCA1C0B6E2E00AF847B /* HTML5LibTokenizerTest.m in Sources */,
62ECBFCB1C0B6E2E00AF847B /* HTMLKitTokenizerTests.m in Sources */,
62ECBFCC1C0B6E2E00AF847B /* HTMLKitTokenizerPerformance.m in Sources */,
@@ -1990,6 +2051,7 @@
62567F571C0CC3AE0025D458 /* HTMLDOMTokenListTests.m in Sources */,
62ECBFD41C0B6E2E00AF847B /* HTMLStringCategoryTests.m in Sources */,
62ECBFD51C0B6E2E00AF847B /* HTMLOrderedDictionaryTests.m in Sources */,
62A95A4E1FB0FBFC0009FF26 /* HTMLSerializationTests.m in Sources */,
62ECBFD61C0B6E2E00AF847B /* CSSSelectorTest.m in Sources */,
62ECBFD71C0B6E2E00AF847B /* CSSSelectorParserTests.m in Sources */,
62ECBFD81C0B6E2E00AF847B /* CSSNthExpressionsParserTests.m in Sources */,
@@ -2030,14 +2092,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -2074,14 +2142,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -2106,6 +2180,7 @@
625A14D519C7829400AD0C32 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2115,8 +2190,10 @@
FRAMEWORK_VERSION = A;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "@rpath";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2131,6 +2208,7 @@
625A14D619C7829400AD0C32 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2140,8 +2218,10 @@
FRAMEWORK_VERSION = A;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "@rpath";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2206,6 +2286,7 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
@@ -2217,7 +2298,9 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2241,6 +2324,7 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
COPY_PHASE_STRIP = NO;
@@ -2252,7 +2336,9 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2276,6 +2362,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
@@ -2289,7 +2376,9 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2311,6 +2400,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
@@ -2324,7 +2414,9 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2387,6 +2479,7 @@
62ECBF5F1C0B6C7600AF847B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -2399,8 +2492,10 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_INHIBIT_ALL_WARNINGS = NO;
GCC_WARN_PEDANTIC = NO;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
@@ -2423,6 +2518,7 @@
62ECBF601C0B6C7600AF847B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -2435,8 +2531,10 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_INHIBIT_ALL_WARNINGS = NO;
GCC_WARN_PEDANTIC = NO;
INFOPLIST_FILE = "Sources/HTMLKit-Info.plist";
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
@@ -70,6 +71,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
@@ -70,6 +71,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
@@ -64,6 +65,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
@@ -37,6 +38,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+1 -1
View File
@@ -2,5 +2,5 @@ import PackageDescription
let package = Package(
name: "HTMLKit",
exclude: ["Tests/Resources", "Tests/css-tests", "Tests/html5lib-tests"]
exclude: ["Tests/Fixtures", "Tests/css-tests", "Tests/html5lib-tests"]
)
+3 -4
View File
@@ -4,7 +4,8 @@
An Objective-C framework for your everyday HTML needs.
[![Build Status](https://img.shields.io/travis/iabudiab/HTMLKit/master.svg?style=flat)](https://travis-ci.org/iabudiab/HTMLKit)
[![Build Status](https://img.shields.io/travis/iabudiab/HTMLKit/develop.svg?style=flat)](https://travis-ci.org/iabudiab/HTMLKit)
[![codecov](https://codecov.io/gh/iabudiab/HTMLKit/branch/develop/graph/badge.svg)](https://codecov.io/gh/iabudiab/HTMLKit)
[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/HTMLKit.svg?style=flat)](https://cocoapods.org/pods/HTMLKit)
[![CocoaDocs](https://img.shields.io/cocoapods/metrics/doc-percent/HTMLKit.svg?style=flat)](http://cocoadocs.org/docsets/HTMLKit)
@@ -75,10 +76,8 @@ $ gem install cocoapods
To add `HTMLKit` as a dependency into your project using CocoaPods just add the following in your `Podfile`:
```ruby
use_frameworks!
target 'MyTarget' do
pod 'HTMLKit', '~> 2.0'
pod 'HTMLKit', '~> 2.1'
end
```
+1 -1
View File
@@ -61,7 +61,7 @@
}
case CSSAttributeSelectorIncludes:
{
NSArray *components = [element[_name] componentsSeparatedByCharactersInSet:[NSCharacterSet HTMLWhitespaceCharacterSet]];
NSArray *components = [element[_name] componentsSeparatedByCharactersInSet:[NSCharacterSet htmlkit_HTMLWhitespaceCharacterSet]];
return [components containsObject:_value];
}
case CSSAttributeSelectorBegins:
+15 -5
View File
@@ -24,14 +24,14 @@
- (NSString *)consumeIdentifier
{
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
if (!isValidIdentifierStart([self inputCharacterPointAtOffset:0],
[self inputCharacterPointAtOffset:1],
[self inputCharacterPointAtOffset:2])) {
return nil;
}
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
while (YES) {
UTF32Char codePoint = [self consumeNextInputCharacter];
if (codePoint == EOF) {
@@ -47,7 +47,12 @@
}
}
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
if (CFStringGetLength(value) > 0) {
return (__bridge_transfer NSString *)value;
}
CFRelease(value);
return nil;
}
- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint
@@ -85,7 +90,12 @@
}
}
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
if (CFStringGetLength(value) > 0) {
return (__bridge_transfer NSString *)value;
}
CFRelease(value);
return nil;
}
- (UTF32Char)consumeEscapedCodePoint
@@ -105,7 +115,7 @@
[self consumeNextInputCharacter];
}
NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexString)];
NSScanner *scanner = [NSScanner scannerWithString:(__bridge_transfer NSString *)(hexString)];
unsigned int number;
[scanner scanHexInt:&number];
+2 -2
View File
@@ -8,7 +8,7 @@
#import "CSSNthExpressionParser.h"
#import "CSSCodePoints.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#import "NSCharacterSet+HTMLKit.h"
@implementation CSSNthExpressionParser
@@ -26,7 +26,7 @@
return CSSNthExpressionEven;
}
NSCharacterSet *set = [[NSCharacterSet CSSNthExpressionCharacterSet] invertedSet];
NSCharacterSet *set = [[NSCharacterSet htmlkit_CSSNthExpressionCharacterSet] invertedSet];
if ([string rangeOfCharacterFromSet:set].location != NSNotFound) {
return CSSNthExpressionMake(0, 0);
}
+1 -1
View File
@@ -38,7 +38,7 @@ NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression)
#pragma mark - Implementation
NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element)
NS_INLINE NSInteger computeIndex(NSEnumerator *enumerator, HTMLElement *element)
{
NSInteger index = 0;
for (HTMLNode *node in enumerator) {
+1 -1
View File
@@ -10,7 +10,7 @@
#import "CSSInputStream.h"
#import "CSSCodePoints.h"
#import "CSSSelectors.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#import "NSCharacterSet+HTMLKit.h"
#import "CSSNthExpressionParser.h"
#import "CSSCompoundSelector.h"
+4 -4
View File
@@ -9,7 +9,7 @@
#import "CSSStructuralPseudoSelectors.h"
#import "CSSSelectors.h"
#import "HTMLElement.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#pragma mark - Elements
@@ -276,7 +276,7 @@ CSSSelector * ltSelector(NSInteger index)
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
if (index > 0) {
if (index >= 0) {
return elementIndex < index;
} else {
return elementIndex < element.parentElement.childNodesCount - index - 1;
@@ -290,7 +290,7 @@ CSSSelector * gtSelector(NSInteger index)
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
if (index > 0) {
if (index >= 0) {
return elementIndex > index;
} else {
return elementIndex > element.parentElement.childNodesCount - index - 1;
@@ -304,7 +304,7 @@ CSSSelector * eqSelector(NSInteger index)
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
if (index > 0) {
if (index >= 0) {
return elementIndex == index;
} else {
return elementIndex == element.parentElement.childNodesCount - index - 1;
+1 -1
View File
@@ -8,7 +8,7 @@
#import "CSSTypeSelector.h"
#import "HTMLElement.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
@interface CSSTypeSelector ()
{
+15 -4
View File
@@ -24,14 +24,25 @@
{
self = [super initWithName:name type:type];
if (self) {
_data = [[NSMutableString alloc] initWithString:data ?: @""];
if (data) {
_data = [[NSMutableString alloc] initWithString:data];
}
}
return self;
}
- (NSString *)data
{
if (_data == nil) {
_data = [[NSMutableString alloc] initWithString:@""];
}
return _data;
}
- (NSString *)textContent
{
return [_data copy];
return [self.data copy];
}
- (void)setTextContent:(NSString *)textContent
@@ -41,7 +52,7 @@
- (NSUInteger)length
{
return _data.length;
return self.data.length;
}
#pragma mark - Data
@@ -81,7 +92,7 @@ NS_INLINE void CheckValidOffset(HTMLCharacterData *node, NSUInteger offset, NSSt
range.length = MIN(range.length, self.length - range.location);
[_data replaceCharactersInRange:range withString:data];
[(NSMutableString *)self.data replaceCharactersInRange:range withString:data];
[self.ownerDocument didRemoveCharacterDataInNode:self atOffset:range.location withLength:range.length];
[self.ownerDocument didAddCharacterDataToNode:self atOffset:range.location withLength:data.length];
}
+4 -4
View File
@@ -36,7 +36,7 @@
- (BOOL)isWhitespaceToken
{
return [_characters isHTMLWhitespaceString];
return [_characters htmlkit_isHTMLWhitespaceString];
}
- (BOOL)isEmpty
@@ -46,7 +46,7 @@
- (void)retainLeadingWhitespace
{
NSUInteger index = _characters.leadingHTMLWhitespaceLength;
NSUInteger index = _characters.htmlkit_leadingHTMLWhitespaceLength;
if (index > 0) {
[_characters setString:[_characters substringToIndex:index]];
}
@@ -54,7 +54,7 @@
- (void)trimLeadingWhitespace
{
NSUInteger index = _characters.leadingHTMLWhitespaceLength;
NSUInteger index = _characters.htmlkit_leadingHTMLWhitespaceLength;
if (index > 0) {
[_characters setString:[_characters substringFromIndex:index]];
}
@@ -67,7 +67,7 @@
- (HTMLCharacterToken *)tokenBySplitingLeadingWhiteSpace
{
NSUInteger index = _characters.leadingHTMLWhitespaceLength;
NSUInteger index = _characters.htmlkit_leadingHTMLWhitespaceLength;
if (index > 0) {
NSString *leading = [_characters substringToIndex:index];
[_characters setString:[_characters substringFromIndex:index]];
+1 -1
View File
@@ -7,7 +7,7 @@
//
#import "HTMLDocumentType.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#import "HTMLNode+Private.h"
NS_INLINE BOOL nilOrEqual(id first, id second) {
+25 -16
View File
@@ -12,7 +12,7 @@
#import "HTMLText.h"
#import "HTMLDOMTokenList.h"
#import "HTMLOrderedDictionary.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#import "HTMLNode+Private.h"
@interface HTMLElement ()
@@ -32,7 +32,7 @@
- (instancetype)initWithTagName:(NSString *)tagName
{
return [self initWithTagName:tagName attributes:@{}];
return [self initWithTagName:tagName attributes:nil];
}
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes
@@ -45,8 +45,9 @@
self = [super initWithName:tagName type:HTMLNodeElement];
if (self) {
_tagName = [tagName copy];
_attributes = [HTMLOrderedDictionary new];
_attributes = nil;
if (attributes != nil) {
_attributes = [HTMLOrderedDictionary new];
[_attributes addEntriesFromDictionary:attributes];
}
_htmlNamespace = htmlNamespace;
@@ -56,24 +57,33 @@
#pragma mark - Special Attributes
- (NSMutableDictionary<NSString *,NSString *> *)attributes
{
if (_attributes == nil) {
_attributes = [HTMLOrderedDictionary new];
}
return _attributes;
}
- (NSString *)elementId
{
return _attributes[@"id"] ?: @"";
return self.attributes[@"id"] ?: @"";
}
- (void)setElementId:(NSString *)elementId
{
_attributes[@"id"] = elementId;
self.attributes[@"id"] = elementId;
}
- (NSString *)className
{
return _attributes[@"class"] ?: @"";
return self.attributes[@"class"] ?: @"";
}
- (void)setClassName:(NSString *)className
{
_attributes[@"class"] = className;
self.attributes[@"class"] = className;
}
- (HTMLDOMTokenList *)classList
@@ -85,22 +95,22 @@
- (BOOL)hasAttribute:(NSString *)name
{
return _attributes[name] != nil;
return self.attributes[name] != nil;
}
- (NSString *)objectForKeyedSubscript:(NSString *)name;
{
return _attributes[name];
return self.attributes[name];
}
- (void)setObject:(NSString *)value forKeyedSubscript:(NSString *)attribute
{
_attributes[attribute] = value;
self.attributes[attribute] = value;
}
- (void)removeAttribute:(NSString *)name
{
[_attributes removeObjectForKey:name];
[self.attributes removeObjectForKey:name];
}
- (NSString *)textContent
@@ -134,7 +144,7 @@
{
HTMLElement *copy = [super copyWithZone:zone];
copy->_tagName = [_tagName copy];
copy->_attributes = [_attributes copy];
copy->_attributes = [_attributes mutableCopy];
copy->_htmlNamespace = _htmlNamespace;
return copy;
}
@@ -147,11 +157,10 @@
[result appendFormat:@"<%@", self.tagName];
[self.attributes enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
NSRange range = NSMakeRange(0, value.length);
NSMutableString *escaped = [value mutableCopy];
[escaped replaceOccurrencesOfString:@"&" withString:@"&amp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"\00A0" withString:@"&nbsp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"\"" withString:@"&quot;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"&" withString:@"&amp;" options:0 range:NSMakeRange(0, escaped.length)];
[escaped replaceOccurrencesOfString:@"0x00A0" withString:@"&nbsp;" options:0 range:NSMakeRange(0, escaped.length)];
[escaped replaceOccurrencesOfString:@"\"" withString:@"&quot;" options:0 range:NSMakeRange(0, escaped.length)];
[result appendFormat:@" %@=\"%@\"", key, escaped];
}];
+15 -10
View File
@@ -48,10 +48,10 @@
#pragma mark - Errors
- (void)emitParseError:(NSString *)reason
- (void)emitParseError:(NSString *)code details:(NSString *)details
{
if (self.errorCallback) {
self.errorCallback(reason);
self.errorCallback(code, details);
}
}
@@ -82,16 +82,16 @@
return LINE_FEED;
}
if (CFStringIsSurrogateLowCharacter(nextInputCharacter)) {
NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated low surrogate: 0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:reason];
NSString *details = [NSString stringWithFormat:@"Non-Unicode character found (an isolated low surrogate: 0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:@"surrogate-in-input-stream" details:details];
return nextInputCharacter;
}
if (CFStringIsSurrogateHighCharacter(nextInputCharacter)) {
UniChar surrogateLow = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + 1);
if (CFStringIsSurrogateLowCharacter(surrogateLow) == NO) {
NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated high surrogate: 0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:reason];
NSString *details = [NSString stringWithFormat:@"Non-Unicode character found (an isolated high surrogate: 0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:@"surrogate-in-input-stream" details:details];
return nextInputCharacter;
}
@@ -99,9 +99,14 @@
nextInputCharacter = CFStringGetLongCharacterForSurrogatePair(nextInputCharacter, surrogateLow);
}
if (isControlOrUndefinedCharacter(nextInputCharacter)) {
NSString *reason = [NSString stringWithFormat:@"A control/undefined character found: (0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:reason];
if (isControlCharacter(nextInputCharacter)) {
NSString *details = [NSString stringWithFormat:@"A control character found: (0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:@"control-character-in-input-stream" details:details];
}
if (isNoncharacter(nextInputCharacter)) {
NSString *details = [NSString stringWithFormat:@"A noncharacter found: (0x%X)", (unsigned int)nextInputCharacter];
[self emitParseError:@"noncharacter-in-input-stream" details:details];
}
return nextInputCharacter;
@@ -165,7 +170,7 @@
- (BOOL)consumeHexNumber:(unsigned long long *)result
{
NSCharacterSet *set = [NSCharacterSet HTMLHexNumberCharacterSet];
NSCharacterSet *set = [NSCharacterSet htmlkit_HTMLHexNumberCharacterSet];
NSString *string = nil;
BOOL success = [_scanner scanCharactersFromSet:set intoString:&string];
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.2</string>
<string>3.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+1 -1
View File
@@ -46,7 +46,7 @@
- (void)addElement:(HTMLElement *)element
{
NSUInteger existing = 0;
for (HTMLElement *node in _list.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _list.reverseObjectEnumerator) {
if ([node isEqual:[HTMLMarker marker]]) {
break;
}
+60 -37
View File
@@ -19,6 +19,10 @@
#import "HTMLDocument+Private.h"
#import "HTMLDOMUtils.h"
NSString * const ValidationNodePreInsertion = @"-ensurePreInsertionValidityOfNode:beforeChildNode:";
NSString * const ValidationNodeReplacement = @"-ensureReplacementValidityOfChildNode:withNode:";
NSString * const RemoveChildNode = @"-removeChildNode:";
@interface HTMLNode ()
{
NSMutableOrderedSet *_childNodes;
@@ -36,13 +40,22 @@
if (self) {
_name = name;
_nodeType = type;
_childNodes = [NSMutableOrderedSet new];
_childNodes = nil;
}
return self;
}
#pragma mark - Properties
- (NSOrderedSet<HTMLNode *> *)childNodes
{
if (_childNodes == nil) {
_childNodes = [NSMutableOrderedSet new];
}
return _childNodes;
}
- (HTMLDocument *)ownerDocument
{
if (_nodeType == HTMLNodeDocument) {
@@ -55,7 +68,9 @@
- (void)setOwnerDocument:(HTMLDocument *)ownerDocument
{
_ownerDocument = ownerDocument;
[self.childNodes.array makeObjectsPerformSelector:@selector(setOwnerDocument:) withObject:ownerDocument];
for (HTMLNode *child in _childNodes) {
[child setOwnerDocument:ownerDocument];
}
}
- (HTMLNode *)rootNode
@@ -75,12 +90,12 @@
- (HTMLNode *)firstChild
{
return self.childNodes.firstObject;
return _childNodes.firstObject;
}
- (HTMLNode *)lastChild
{
return self.childNodes.lastObject;
return _childNodes.lastObject;
}
- (HTMLNode *)previousSibling
@@ -112,7 +127,7 @@
- (HTMLElement *)nextSiblingElement
{
HTMLNode *node = self.previousSibling;
HTMLNode *node = self.nextSibling;
while (node && node.nodeType != HTMLNodeElement) {
node = node.nextSibling;
}
@@ -121,7 +136,7 @@
- (NSUInteger)index
{
return [self.parentNode indexOfChildNode:self];
return [_parentNode indexOfChildNode:self];
}
- (NSString *)textContent
@@ -145,12 +160,16 @@
- (BOOL)hasChildNodes
{
return self.childNodes.count > 0;
return _childNodes.count > 0;
}
- (BOOL)hasChildNodeOfType:(HTMLNodeType)type
{
NSUInteger index = [self.childNodes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if (_childNodes == nil) {
return NO;
}
NSUInteger index = [_childNodes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if ([(HTMLNode *)obj nodeType] == type) {
*stop = YES;
return YES;
@@ -163,7 +182,7 @@
- (NSUInteger)childNodesCount
{
return self.childNodes.count;
return _childNodes.count;
}
- (BOOL)isEmpty
@@ -173,25 +192,25 @@
- (HTMLNode *)childNodeAtIndex:(NSUInteger)index
{
return [self.childNodes objectAtIndex:index];
return [_childNodes objectAtIndex:index];
}
- (NSUInteger)childElementsCount
{
return [self.childNodes indexesOfObjectsPassingTest:^BOOL(HTMLNode * _Nonnull node, NSUInteger idx, BOOL * _Nonnull stop) {
return [_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];
return [_childNodes indexOfObject:node];
}
- (HTMLElement *)childElementAtIndex:(NSUInteger)index
{
NSUInteger counter = 0;
for (HTMLNode *node in self.childNodes) {
for (HTMLNode *node in _childNodes) {
if (node.nodeType == HTMLNodeElement) {
if (counter == index) {
return node.asElement;
@@ -205,7 +224,7 @@
- (NSUInteger)indexOfChildElement:(HTMLElement *)element
{
NSUInteger counter = 0;
for (HTMLNode *node in self.childNodes) {
for (HTMLNode *node in _childNodes) {
if (node.nodeType == HTMLNodeElement) {
if (node == element) {
return counter;
@@ -262,7 +281,9 @@
[node removeAllChildNodes];
}
[nodes makeObjectsPerformSelector:@selector(setParentNode:) withObject:self];
for (HTMLNode *node in nodes) {
[node setParentNode:self];
}
return node;
}
@@ -290,7 +311,7 @@
- (void)removeFromParentNode
{
[self.parentNode removeChildNode:self];
[_parentNode removeChildNode:self];
}
- (HTMLNode *)removeChildNode:(HTMLNode *)child
@@ -298,7 +319,7 @@
if (child.parentNode != self) {
[NSException raise:HTMLKitNotFoundError
format:@"%@: Not Fount Error, removing non-child node %@. The object can not be found here.",
NSStringFromSelector(_cmd), child];
RemoveChildNode, child];
}
HTMLNode *oldNode = child;
@@ -322,16 +343,18 @@
- (void)reparentChildNodesIntoNode:(HTMLNode *)node
{
for (HTMLNode *child in self.childNodes.array) {
for (HTMLNode *child in _childNodes) {
[node appendNode:child];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (void)removeAllChildNodes
{
[self.childNodes.array makeObjectsPerformSelector:@selector(setParentNode:) withObject:nil];
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
for (HTMLNode *child in _childNodes) {
[child setParentNode:nil];
}
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (HTMLDocumentPosition)compareDocumentPositionWithNode:(HTMLNode *)otherNode
@@ -402,7 +425,7 @@
return self.nodeType != HTMLNodeDocument && self.ownerDocument == otherNode;
}
for (HTMLNode *parentNode = self.parentNode; parentNode; parentNode = parentNode.parentNode) {
for (HTMLNode *parentNode = _parentNode; parentNode; parentNode = parentNode.parentNode) {
if (parentNode == otherNode) {
return YES;
}
@@ -424,7 +447,7 @@
return;
}
[self.childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj, idx, stop);
}];
}
@@ -435,7 +458,7 @@
return;
}
[self.childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_childNodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[HTMLElement class]]) {
block([obj asElement], idx, stop);
}
@@ -558,18 +581,18 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
- (void)ensurePreInsertionValidityOfNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child
{
CheckParentValid(self, NSStringFromSelector(_cmd));
CheckParentValid(self, ValidationNodePreInsertion);
CheckChildsParent(self, child, NSStringFromSelector(_cmd));
CheckChildsParent(self, child, ValidationNodePreInsertion);
CheckInsertedNodeValid(node, NSStringFromSelector(_cmd));
CheckInsertedNodeValid(node, ValidationNodePreInsertion);
CheckInvalidCombination(self, node, NSStringFromSelector(_cmd));
CheckInvalidCombination(self, node, ValidationNodePreInsertion);
void (^ hierarchyError)() = ^{
void (^ hierarchyError)(void) = ^{
[NSException raise:HTMLKitHierarchyRequestError
format:@"%@: Hierarchy Request Error, inserting (%@) into (%@). The operation would yield an incorrect node tree.",
NSStringFromSelector(_cmd), self, node];
ValidationNodePreInsertion, self, node];
};
if (self.nodeType == HTMLNodeDocument) {
@@ -608,18 +631,18 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
- (void)ensureReplacementValidityOfChildNode:(HTMLNode *)child withNode:(HTMLNode *)node
{
CheckParentValid(self, NSStringFromSelector(_cmd));
CheckParentValid(self, ValidationNodeReplacement);
CheckChildsParent(self, child, NSStringFromSelector(_cmd));
CheckChildsParent(self, child, ValidationNodeReplacement);
CheckInsertedNodeValid(node, NSStringFromSelector(_cmd));
CheckInsertedNodeValid(node, ValidationNodeReplacement);
CheckInvalidCombination(self, node, NSStringFromSelector(_cmd));
CheckInvalidCombination(self, node, ValidationNodeReplacement);
void (^ hierarchyError)() = ^{
void (^ hierarchyError)(void) = ^{
[NSException raise:HTMLKitHierarchyRequestError
format:@"%@: Hierarchy Request Error. The operation would yield an incorrect node tree.",
NSStringFromSelector(_cmd)];
ValidationNodeReplacement];
};
void (^ checkParentHasAnotherChildOfType)(HTMLNodeType) = ^ void (HTMLNodeType type) {
@@ -675,7 +698,7 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin
HTMLNode *copy = [self copy];
if (deep) {
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[copy appendNode:[child cloneNodeDeep:YES]];
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
@interface HTMLNodeFilterBlock ()
{
BOOL (^ _block)(HTMLNode *);
HTMLNodeFilterValue (^ _block)(HTMLNode *);
}
@end
+7
View File
@@ -154,4 +154,11 @@
return [_keys countByEnumeratingWithState:state objects:buffer count:len];
}
#pragma mark - Copying
- (id)mutableCopy
{
return [[HTMLOrderedDictionary alloc] initWithDictionary:self];
}
@end
+22 -5
View File
@@ -10,29 +10,46 @@
@interface HTMLParseErrorToken ()
{
NSString *_reason;
NSString *_code;
NSString *_details;
NSUInteger _location;
}
@end
@implementation HTMLParseErrorToken
@synthesize reason = _reason;
@synthesize code = _code;
@synthesize details = _details;
@synthesize location = _location;
- (instancetype)initWithReasonMessage:(NSString *)reason andStreamLocation:(NSUInteger)location
- (instancetype)initWithCode:(NSString *)code details:(NSString *)details location:(NSUInteger)location
{
self = [super init];
if (self) {
self.type = HTMLTokenTypeParseError;
_reason = [reason copy];
_code = [code copy];
_details = [details copy];
_location = location;
}
return self;
}
- (BOOL)isEqual:(id)other
{
if ([other isKindOfClass:[self class]]) {
HTMLParseErrorToken *token = (HTMLParseErrorToken *)other;
return bothNilOrEqual(self.code, token.code);
}
return NO;
}
- (NSUInteger)hash
{
return self.code.hash + self.code.hash;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p Reason='%@' Location='%lu'>", self.class, self, _reason, (unsigned long)_location];
return [NSString stringWithFormat:@"<%@: %p Code='%@' Details='%@' Location='%lu'>", self.class, self, _code, _details, (unsigned long)_location];
}
@end
+19 -19
View File
@@ -73,6 +73,10 @@
_tokenizer = [[HTMLTokenizer alloc] initWithString:string ?: @""];
_tokenizer.parser = self;
__weak HTMLParser *weakSelf = self;
_tokenizer.parseErrorCallback = ^(HTMLParseErrorToken *token) {
[weakSelf emitParseError:@"Tokenization error: %@", token.asParseError];
};
_pendingTableCharacterTokens = [[HTMLCharacterToken alloc] initWithString:@""];
@@ -130,6 +134,10 @@
[self initializeDocument];
_tokenizer = [[HTMLTokenizer alloc] initWithString:_tokenizer.string];
_tokenizer.parser = self;
__weak HTMLParser *weakSelf = self;
_tokenizer.parseErrorCallback = ^(HTMLParseErrorToken *token) {
[weakSelf emitParseError:@"Tokenization error: %@", token.asParseError];
};
_contextElement = contextElement;
_fragmentParsingAlgorithm = YES;
@@ -226,11 +234,6 @@
return NO;
};
if (token.isParseError) {
[self emitParseError:@"Tokenizer Parser Error: %@", token.asParseError];
return;
}
if (_ignoreNextLineFeedCharacterToken) {
_ignoreNextLineFeedCharacterToken = NO;
if (token.isCharacterToken) {
@@ -1139,7 +1142,7 @@
if (charactes.length > 0) {
[self reconstructActiveFormattingElements];
[self insertCharacters:charactes];
if (!charactes.isHTMLWhitespaceString) {
if (!charactes.htmlkit_isHTMLWhitespaceString) {
_framesetOkFlag = NO;
}
}
@@ -1272,7 +1275,7 @@
@"dd": @[@"dd", @"dt"],
@"dt": @[@"dd", @"dt"]};
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator) {
if ([map[tagName] containsObject:node.tagName]) {
[self generateImpliedEndTagsExceptForElement:node.tagName];
if (![self.currentNode.tagName isEqualToString:node.tagName]) {
@@ -1440,7 +1443,6 @@
} else if ([tagName isEqualToString:@"math"]) {
[self reconstructActiveFormattingElements];
AdjustMathMLAttributes(token);
AdjustForeignAttributes(token);
[self insertForeignElementForToken:token inNamespace:HTMLNamespaceMathML];
if (token.isSelfClosing) {
[_stackOfOpenElements popCurrentNode];
@@ -1448,7 +1450,6 @@
} else if ([tagName isEqualToString:@"svg"]) {
[self reconstructActiveFormattingElements];
AdjustSVGAttributes(token);
AdjustForeignAttributes(token);
[self insertForeignElementForToken:token inNamespace:HTMLNamespaceSVG];
if (token.isSelfClosing) {
[_stackOfOpenElements popCurrentNode];
@@ -1529,7 +1530,7 @@
}
[self closePElement];
} else if ([tagName isEqualToString:@"li"]) {
if (![_stackOfOpenElements hasElementInListItemScopeWithTagName:@"li"]) {
if (![_stackOfOpenElements hasElementInListItemScopeWithTagName:tagName]) {
[self emitParseError:@"Unexpected <li> element in <body>"];
return;
}
@@ -1549,7 +1550,7 @@
}
[_stackOfOpenElements popElementsUntilElementPoppedWithTagName:tagName];
} else if ([tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil]) {
if (![_stackOfOpenElements hasAnyElementInScopeWithAnyOfTagNames:@[@"h1", @"h2", @"h3", @"h4", @"h5", @"h6"]]) {
if (![_stackOfOpenElements hasHeaderElementInScope]) {
[self emitParseError:@"Unexpected <%@> element in <body>", tagName];
return;
}
@@ -1569,7 +1570,7 @@
return;
}
} else if ([tagName isEqualToAny:@"applet", @"marquee", @"object", nil]) {
if (![_stackOfOpenElements hasAnyElementInScopeWithAnyOfTagNames:@[@"applet", @"marquee", @"object"]]) {
if (![_stackOfOpenElements hasElementInScopeWithTagName:tagName]) {
[self emitParseError:@"Unexpected <%@> element in <body>", tagName];
return;
}
@@ -1590,7 +1591,7 @@
- (void)processAnyOtherEndTagTokenInBody:(HTMLTagToken *)token
{
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator.allObjects) {
for (HTMLElement *node in _stackOfOpenElements.reverseObjectEnumerator) {
if ([node.tagName isEqualToString:token.tagName]) {
[self generateImpliedEndTagsExceptForElement:token.tagName];
if (![node.tagName isEqualToString:self.currentNode.tagName]) {
@@ -2312,7 +2313,7 @@
[characters enumerateSubstringsInRange:NSMakeRange(0, characters.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (substring.isHTMLWhitespaceString) {
if (substring.htmlkit_isHTMLWhitespaceString) {
[self insertCharacters:substring];
} else {
[self emitParseError:@"Unexpected Character (%@) in <frameset>", substring];
@@ -2380,7 +2381,7 @@
[characters enumerateSubstringsInRange:NSMakeRange(0, characters.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (substring.isHTMLWhitespaceString) {
if (substring.htmlkit_isHTMLWhitespaceString) {
[self insertCharacters:substring];
} else {
[self emitParseError:@"Unexpected Character (%@) after <frameset>", substring];
@@ -2514,7 +2515,7 @@
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if ([substring isEqualToString:@"\uFFFD"]) {
[self emitParseError:@"Unexpected Character (0x0000) in foreign content"];
} else if (!substring.isHTMLWhitespaceString) {
} else if (!substring.htmlkit_isHTMLWhitespaceString) {
_framesetOkFlag = NO;
}
[self insertCharacters:substring];
@@ -2530,7 +2531,7 @@
return;
case HTMLTokenTypeStartTag:
{
void (^ anythingElse)() = ^ {
void (^ anythingElse)(void) = ^ {
if (self.adjustedCurrentNode.htmlNamespace == HTMLNamespaceMathML) {
AdjustMathMLAttributes(token.asTagToken);
}
@@ -2538,14 +2539,13 @@
AdjustSVGNameCase(token.asTagToken);
AdjustSVGAttributes(token.asTagToken);
}
AdjustForeignAttributes(token.asTagToken);
[self insertForeignElementForToken:token.asTagToken inNamespace:self.adjustedCurrentNode.htmlNamespace];
if (token.asTagToken.selfClosing) {
[_stackOfOpenElements popCurrentNode];
}
};
void (^ matchedCase)() = ^ {
void (^ matchedCase)(void) = ^ {
[self emitParseError:@"Unexpected start tag <%@> in foreign content", token.asTagToken.tagName];
if (_fragmentParsingAlgorithm) {
anythingElse();
+21
View File
@@ -0,0 +1,21 @@
//
// HTMLQuircksMode.m
// HTMLKit
//
// Created by Iska on 26.03.19.
// Copyright © 2019 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLQuirksMode.h"
#import "NSString+Private.h"
BOOL QuirksModePrefixMatch(NSString *publicIdentifier)
{
for (int i = 0; i < sizeof(HTMLQuirksModePrefixes) / sizeof(HTMLQuirksModePrefixes[0]); i++) {
if ([publicIdentifier hasPrefixIgnoringCase:HTMLQuirksModePrefixes[i]]) {
return YES;
}
}
return NO;
}
+19 -5
View File
@@ -23,14 +23,28 @@
#pragma mark - Lifecycle
- (instancetype)initWithDocument:(HTMLDocument *)document
{
return [self initWithDocument:document startContainer:document startOffset:0 endContainer:document endOffset:0];
}
- (instancetype)initWithDowcument:(HTMLDocument *)document
{
return [self initWithDowcument:document startContainer:document startOffset:0 endContainer:document endOffset:0];
return [self initWithDocument:document startContainer:document startOffset:0 endContainer:document endOffset:0];
}
- (instancetype)initWithDowcument:(HTMLDocument *)document
startContainer:(HTMLNode *)startContainer startOffset:(NSUInteger)startOffset
endContainer:(HTMLNode *)endContainer endOffset:(NSUInteger)endOffset
{
return [self initWithDocument:document
startContainer:startContainer startOffset:startOffset
endContainer:endContainer endOffset:endOffset];
}
- (instancetype)initWithDocument:(HTMLDocument *)document
startContainer:(HTMLNode *)startContainer startOffset:(NSUInteger)startOffset
endContainer:(HTMLNode *)endContainer endOffset:(NSUInteger)endOffset
{
self = [super init];
if (self) {
@@ -517,7 +531,7 @@ NS_INLINE HTMLCharacterData * CloneCharachterData(HTMLNode *node, NSUInteger sta
HTMLNode *clone = [firstPartiallyContainedChild copy];
[fragment appendNode:clone];
HTMLRange *subRange = [[HTMLRange alloc] initWithDowcument:_ownerDocument
HTMLRange *subRange = [[HTMLRange alloc] initWithDocument:_ownerDocument
startContainer:_startContainer
startOffset:_startOffset
endContainer:firstPartiallyContainedChild
@@ -537,7 +551,7 @@ NS_INLINE HTMLCharacterData * CloneCharachterData(HTMLNode *node, NSUInteger sta
HTMLNode *clone = [lastPartiallyContainedChild copy];
[fragment appendNode:clone];
HTMLRange *subRange = [[HTMLRange alloc] initWithDowcument:_ownerDocument
HTMLRange *subRange = [[HTMLRange alloc] initWithDocument:_ownerDocument
startContainer:lastPartiallyContainedChild
startOffset:0
endContainer:_endContainer
@@ -580,7 +594,7 @@ NS_INLINE HTMLCharacterData * CloneCharachterData(HTMLNode *node, NSUInteger sta
HTMLNode *clone = [firstPartiallyContainedChild copy];
[fragment appendNode:clone];
HTMLRange *subRange = [[HTMLRange alloc] initWithDowcument:_ownerDocument
HTMLRange *subRange = [[HTMLRange alloc] initWithDocument:_ownerDocument
startContainer:_startContainer
startOffset:_startOffset
endContainer:firstPartiallyContainedChild
@@ -601,7 +615,7 @@ NS_INLINE HTMLCharacterData * CloneCharachterData(HTMLNode *node, NSUInteger sta
HTMLNode *clone = [lastPartiallyContainedChild copy];
[fragment appendNode:clone];
HTMLRange *subRange = [[HTMLRange alloc] initWithDowcument:_ownerDocument
HTMLRange *subRange = [[HTMLRange alloc] initWithDocument:_ownerDocument
startContainer:lastPartiallyContainedChild
startOffset:0
endContainer:_endContainer
+128 -83
View File
@@ -14,7 +14,6 @@
@interface HTMLStackOfOpenElements ()
{
NSMutableArray *_stack;
NSDictionary *_specificScopeElementTypes;
}
@end
@@ -27,26 +26,6 @@
self = [super init];
if (self) {
_stack = [NSMutableArray new];
_specificScopeElementTypes = @{
@"applet": @(HTMLNamespaceHTML),
@"caption": @(HTMLNamespaceHTML),
@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"td": @(HTMLNamespaceHTML),
@"th": @(HTMLNamespaceHTML),
@"marquee": @(HTMLNamespaceHTML),
@"object": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML),
@"mi": @(HTMLNamespaceMathML),
@"mo": @(HTMLNamespaceMathML),
@"mn": @(HTMLNamespaceMathML),
@"ms": @(HTMLNamespaceMathML),
@"mtext": @(HTMLNamespaceMathML),
@"annotation-xml": @(HTMLNamespaceMathML),
@"foreignObject": @(HTMLNamespaceSVG),
@"desc": @(HTMLNamespaceSVG),
@"title": @(HTMLNamespaceSVG)
};
}
return self;
}
@@ -195,82 +174,148 @@
#pragma mark - Element Scope
NS_INLINE BOOL IsSpecificScopeElement(HTMLElement *element)
{
switch (element.htmlNamespace) {
case HTMLNamespaceHTML:
return [element.tagName isEqualToAny:@"applet", @"caption", @"html", @"table", @"td", @"th", @"marquee", @"object", @"template", nil];
case HTMLNamespaceMathML:
return [element.tagName isEqualToAny:@"mi", @"mo", @"mn", @"ms", @"mtext", @"annotation-xml", nil];
case HTMLNamespaceSVG:
return [element.tagName isEqualToAny:@"foreignObject", @"desc", @"title", nil];
}
}
NS_INLINE BOOL IsHeaderElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"h1", @"h2", @"h3", @"h4", @"h5", @"h6", nil];
}
NS_INLINE BOOL IsTableScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"html", @"table", @"template", nil];
}
NS_INLINE BOOL IsListItemScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToAny:@"ol", @"ul", nil];
}
NS_INLINE BOOL IsSelectScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return ![element.tagName isEqualToString:@"optgroup"] && ![element.tagName isEqualToString:@"option"];
}
NS_INLINE BOOL IsButtonScopeElement(HTMLElement *element)
{
if (element.htmlNamespace != HTMLNamespaceHTML) {
return NO;
}
return [element.tagName isEqualToString:@"button"];
}
- (HTMLElement *)hasElementInScopeWithTagName:(NSString *)tagName;
{
return [self hasAnyElementInSpecificScopeWithTagNames:@[tagName] andElementTypes:_specificScopeElementTypes];
}
- (HTMLElement *)hasAnyElementInScopeWithAnyOfTagNames:(NSArray *)tagNames
{
return [self hasAnyElementInSpecificScopeWithTagNames:tagNames andElementTypes:_specificScopeElementTypes];
}
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName
{
NSMutableDictionary *elementTypes = [NSMutableDictionary dictionaryWithDictionary:_specificScopeElementTypes];
[elementTypes addEntriesFromDictionary:@{@"ol": @(HTMLNamespaceHTML),
@"ul": @(HTMLNamespaceHTML)}];
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:elementTypes];
}
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName
{
NSMutableDictionary *elementTypes = [NSMutableDictionary dictionaryWithDictionary:_specificScopeElementTypes];
[elementTypes addEntriesFromDictionary:@{@"button": @(HTMLNamespaceHTML)}];
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:elementTypes];
}
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName
{
return [self hasElementInSpecificScopeWithTagName:tagName
andElementTypes:@{@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML)}];
}
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames
{
return [self hasAnyElementInSpecificScopeWithTagNames:tagNames
andElementTypes:@{@"html": @(HTMLNamespaceHTML),
@"table": @(HTMLNamespaceHTML),
@"template": @(HTMLNamespaceHTML)}];
}
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if ([node.tagName isEqualToString:tagName]) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (!(node.htmlNamespace == HTMLNamespaceHTML &&
[node.tagName isEqualToAny:@"optgroup", @"option", nil])) {
if (IsSpecificScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInSpecificScopeWithTagName:(NSString *)tagName
andElementTypes:(NSDictionary *)elementTypes
{
return [self hasAnyElementInSpecificScopeWithTagNames:@[tagName] andElementTypes:elementTypes];
}
- (HTMLElement *)hasAnyElementInSpecificScopeWithTagNames:(NSArray *)tagNames
andElementTypes:(NSDictionary *)elementTypes
- (HTMLElement *)hasHeaderElementInScope
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if ([tagNames containsObject:node.tagName]) {
NSNumber *namespace = elementTypes[node.tagName] ?: @(HTMLNamespaceHTML);
if ([namespace isEqual:@(node.htmlNamespace)]) {
return node;
}
if (IsHeaderElement(node)) {
return node;
}
if ([elementTypes[node.tagName] isEqual:@(node.htmlNamespace)]) {
if (IsSpecificScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsTableScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagNames containsObject:node.tagName]) {
return node;
}
if (IsTableScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSpecificScopeElement(node) || IsListItemScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSpecificScopeElement(node) || IsButtonScopeElement(node)) {
return nil;
}
}
return nil;
}
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName
{
for (HTMLElement *node in _stack.reverseObjectEnumerator) {
if (node.htmlNamespace == HTMLNamespaceHTML && [tagName isEqualToString:node.tagName]) {
return node;
}
if (IsSelectScopeElement(node)) {
return nil;
}
}
+5 -6
View File
@@ -8,7 +8,7 @@
#import "HTMLText.h"
#import "HTMLElement.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
#import "HTMLCharacterData+Private.h"
#import "HTMLKitDOMExceptions.h"
#import "HTMLDocument+Private.h"
@@ -74,12 +74,11 @@ NS_INLINE void CheckValidOffset(HTMLNode *node, NSUInteger offset, NSString *cmd
@"plaintext", @"noscript", nil]) {
return self.data;
} else {
NSRange range = NSMakeRange(0, self.data.length);
NSMutableString *escaped = [self.data mutableCopy];
[escaped replaceOccurrencesOfString:@"&" withString:@"&amp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"\00A0" withString:@"&nbsp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"<" withString:@"&lt;" options:0 range:range];
[escaped replaceOccurrencesOfString:@">" withString:@"&gt;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"&" withString:@"&amp;" options:0 range:NSMakeRange(0, escaped.length)];
[escaped replaceOccurrencesOfString:@"\00A0" withString:@"&nbsp;" options:0 range:NSMakeRange(0, escaped.length)];
[escaped replaceOccurrencesOfString:@"<" withString:@"&lt;" options:0 range:NSMakeRange(0, escaped.length)];
[escaped replaceOccurrencesOfString:@">" withString:@"&gt;" options:0 range:NSMakeRange(0, escaped.length)];
return escaped;
}
}
+821 -650
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -10,7 +10,7 @@
@implementation NSCharacterSet (HTMLKit)
+ (instancetype)HTMLWhitespaceCharacterSet
+ (instancetype)htmlkit_HTMLWhitespaceCharacterSet
{
static NSCharacterSet *set = nil;
static dispatch_once_t onceToken;
@@ -20,7 +20,7 @@
return set;
}
+ (instancetype)HTMLHexNumberCharacterSet
+ (instancetype)htmlkit_HTMLHexNumberCharacterSet
{
static NSCharacterSet *set = nil;
static dispatch_once_t onceToken;
@@ -30,7 +30,7 @@
return set;
}
+ (instancetype)CSSNthExpressionCharacterSet
+ (instancetype)htmlkit_CSSNthExpressionCharacterSet
{
static NSCharacterSet *set = nil;
static dispatch_once_t onceToken;
+3 -28
View File
@@ -15,37 +15,12 @@ NS_INLINE BOOL isHtmlWhitespaceChar(unichar c)
@implementation NSString (HTMLKit)
- (BOOL)isEqualToStringIgnoringCase:(NSString *)aString
- (BOOL)htmlkit_isHTMLWhitespaceString
{
return [self caseInsensitiveCompare:aString] == NSOrderedSame;
return self.htmlkit_leadingHTMLWhitespaceLength == self.length;
}
- (BOOL)isEqualToAny:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION
{
va_list list;
va_start(list, first);
for (NSString *next = first; next != nil; next = va_arg(list, NSString *)) {
if ([self isEqualToString:next]) {
return YES;
}
}
va_end(list);
return NO;
}
- (BOOL)hasPrefixIgnoringCase:(NSString *)aString
{
NSRange reange = [self rangeOfString:aString
options:NSAnchoredSearch|NSCaseInsensitiveSearch];
return reange.location != NSNotFound;
}
- (BOOL)isHTMLWhitespaceString
{
return self.leadingHTMLWhitespaceLength == self.length;
}
- (NSUInteger)leadingHTMLWhitespaceLength
- (NSUInteger)htmlkit_leadingHTMLWhitespaceLength
{
size_t idx = 0;
NSUInteger length = self.length;
+38
View File
@@ -0,0 +1,38 @@
//
// NSString+Private.m
// HTMLKit
//
// Created by Iska on 26.03.19.
// Copyright © 2019 BrainCookie. All rights reserved.
//
#import "NSString+Private.h"
@implementation NSString (Private)
- (BOOL)isEqualToStringIgnoringCase:(NSString *)aString
{
return [self caseInsensitiveCompare:aString] == NSOrderedSame;
}
- (BOOL)isEqualToAny:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION
{
va_list list;
va_start(list, first);
for (NSString *next = first; next != nil; next = va_arg(list, NSString *)) {
if ([self isEqualToString:next]) {
return YES;
}
}
va_end(list);
return NO;
}
- (BOOL)hasPrefixIgnoringCase:(NSString *)aString
{
NSRange reange = [self rangeOfString:aString
options:NSAnchoredSearch|NSCaseInsensitiveSearch];
return reange.location != NSNotFound;
}
@end
+1 -1
View File
@@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Initializes and returns a CSS has-descendant selector, e.g. 'div:has(p)'
@discussion 'div:has(p)' matches all <div> elements which have a descendant <p> element.
@discussion 'div:has(p)' matches all &lt;div&gt; elements which have a descendant &lt;p&gt; element.
@param selector The selector matching a descendant element.
@return A new instance of the has-descendant selector.
+1 -1
View File
@@ -76,7 +76,7 @@ extern NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression
@param string The selector string which will be parsed.
@return A new instance of a parsed CSS Selector, `nil` if the string is not a valid selector string.
*/
+ (nullable instancetype)selectorWithString:(NSString *)stirng;
+ (nullable instancetype)selectorWithString:(NSString *)string;
/**
Implementations should override this method to provide the selector-sprecific logic for matching elements.
+10 -10
View File
@@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
@return The universal CSS selector.
*/
extern CSSSelector * universalSelector();
extern CSSSelector * universalSelector(void);
/**
CSS type selector, e.g. 'div', 'p', ...etc.
@@ -125,7 +125,7 @@ extern CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression);
@return Odd-Child selector.
*/
extern CSSSelector * oddSelector();
extern CSSSelector * oddSelector(void);
/**
CSS even-child selector: ':nth-child(even)'
@@ -134,49 +134,49 @@ extern CSSSelector * oddSelector();
@return Even-Child selector.
*/
extern CSSSelector * evenSlector();
extern CSSSelector * evenSlector(void);
/**
CSS first-child selector: ':nth-child(1)'
@return First-Child selector.
*/
extern CSSSelector * firstChildSelector();
extern CSSSelector * firstChildSelector(void);
/**
CSS first-child selector: ':nth-last-child(1)'
@return First-Child selector.
*/
extern CSSSelector * lastChildSelector();
extern CSSSelector * lastChildSelector(void);
/**
CSS first-of-type selector: ':nth-first-of-type(1)'
@return First-Of-Type selector.
*/
extern CSSSelector * firstOfTypeSelector();
extern CSSSelector * firstOfTypeSelector(void);
/**
CSS last-of-type selector: ':nth-last-of-type(1)'
@return Last-Of-Type selector.
*/
extern CSSSelector * lastOfTypeSelector();
extern CSSSelector * lastOfTypeSelector(void);
/**
CSS only-child selector: ':first-child:last-child'
@return Only-Child selector.
*/
extern CSSSelector * onlyChildSelector();
extern CSSSelector * onlyChildSelector(void);
/**
CSS only-of-type selector: ':first-of-type:last-of-type'
@return Only-Of-Type selector.
*/
extern CSSSelector * onlyOfTypeSelector();
extern CSSSelector * onlyOfTypeSelector(void);
#pragma mark - Combinators
@@ -225,7 +225,7 @@ extern CSSSelector * not(CSSSelector *selector);
/**
CSS has-descendant selector, e.g. 'div:has(p)'
@discussion 'div:has(p)' matches all <div> elements which have a descendant <p> element.
@discussion 'div:has(p)' matches all &lt;div&gt; elements which have a descendant &lt;p&gt; element.
@param selector The selector matching a descendant element.
@return A has-descendant selector.
+20 -20
View File
@@ -15,102 +15,102 @@ NS_ASSUME_NONNULL_BEGIN
/**
@return Root element selector: ':root'
*/
extern CSSSelector * rootSelector();
extern CSSSelector * rootSelector(void);
/**
@return Empy element selector: ':empty'
*/
extern CSSSelector * emptySelector();
extern CSSSelector * emptySelector(void);
/**
@return A parent element selector: ':parent'
*/
extern CSSSelector * parentSelector();
extern CSSSelector * parentSelector(void);
/**
@return A button element selector: ':button'
*/
extern CSSSelector * buttonSelector();
extern CSSSelector * buttonSelector(void);
/**
@return A checkbox element selector: ':checkbox'
*/
extern CSSSelector * checkboxSelector();
extern CSSSelector * checkboxSelector(void);
/**
@return A file element selector: ':file'
*/
extern CSSSelector * fileSelector();
extern CSSSelector * fileSelector(void);
/**
@return A header element selector: ':header'
*/
extern CSSSelector * headerSelector();
extern CSSSelector * headerSelector(void);
/**
@return An image element selector: ':image'
*/
extern CSSSelector * imageSelector();
extern CSSSelector * imageSelector(void);
/**
@return A parent element selector: ':parent'
*/
extern CSSSelector * inputSelector();
extern CSSSelector * inputSelector(void);
/**
@return A link element selector: ':link'
*/
extern CSSSelector * linkSelector();
extern CSSSelector * linkSelector(void);
/**
@return A password element selector: ':password'
*/
extern CSSSelector * passwordSelector();
extern CSSSelector * passwordSelector(void);
/**
@return A radio element selector: ':radio'
*/
extern CSSSelector * radioSelector();
extern CSSSelector * radioSelector(void);
/**
@return A reset element selector: ':reset'
*/
extern CSSSelector * resetSelector();
extern CSSSelector * resetSelector(void);
/**
@return A submit element selector: ':submit'
*/
extern CSSSelector * submitSelector();
extern CSSSelector * submitSelector(void);
/**
@return A text element selector: ':text'
*/
extern CSSSelector * textSelector();
extern CSSSelector * textSelector(void);
/**
@return An enabled element selector: ':enabled'
*/
extern CSSSelector * enabledSelector();
extern CSSSelector * enabledSelector(void);
/**
@return A disabled element selector: ':disabled'
*/
extern CSSSelector * disabledSelector();
extern CSSSelector * disabledSelector(void);
/**
@return A checked element selector: ':checked'
*/
extern CSSSelector * checkedSelector();
extern CSSSelector * checkedSelector(void);
/**
@return An optional element selector: ':optional'
*/
extern CSSSelector * optionalSelector();
extern CSSSelector * optionalSelector(void);
/**
@return A required element selector: ':required'
*/
extern CSSSelector * requiredSelector();
extern CSSSelector * requiredSelector(void);
/**
Less-than selector, e.g. 'lt(2)'
+1 -1
View File
@@ -24,7 +24,7 @@
/**
Initializes a new comment token.
@param string The string with which to initialize the token.
@param data The string with which to initialize the token.
@return A new instance of a comment token.
*/
- (instancetype)initWithData:(NSString *)data;
+2
View File
@@ -24,3 +24,5 @@
#import "HTMLKitDOMExceptions.h"
#import "HTMLNamespaces.h"
#import "HTMLQuirksMode.h"
#import "HTMLOrderedDictionary.h"
+7 -7
View File
@@ -63,7 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Initializes a new HTML element with the given tag name.
@param tagname The tag name.
@param tagName The tag name.
@return A new HTML element.
*/
- (instancetype)initWithTagName:(NSString *)tagName;
@@ -71,21 +71,21 @@ NS_ASSUME_NONNULL_BEGIN
/**
Initializes a new HTML element with the given tag name and attributes.
@param tagname The tag name.
@param tagName The tag name.
@param attributes The attributes.
@return A new HTML element.
*/
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary<NSString *, NSString *> *)attributes;
- (instancetype)initWithTagName:(NSString *)tagName attributes:(nullable NSDictionary<NSString *, NSString *> *)attributes;
/**
Initializes a new HTML element with the given tag name, namespace, and attributes.
@param tagname The tag name.
@param namespace The namespace.
@param tagName The tag name.
@param htmlNamespace The HTML namespace.
@param attributes The attributes.
@return A new HTML element.
*/
- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary<NSString *, NSString *> *)attributes;
- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(nullable NSDictionary<NSString *, NSString *> *)attributes;
/**
Checks whether this element has an attribute with the given name.
@@ -107,7 +107,7 @@ NS_ASSUME_NONNULL_BEGIN
Set the value of the attribute with the given name.
@param value The value to set.
@param name The attribute's name.
@param attribute The attribute's name.
*/
- (void)setObject:(NSString *)value forKeyedSubscript:(NSString *)attribute;
-28
View File
@@ -140,31 +140,3 @@ NS_INLINE void AdjustSVGNameCase(HTMLTagToken *token)
NSString *replacement = replacements[token.tagName] ?: token.tagName;
token.tagName = replacement;
}
NS_INLINE void AdjustForeignAttributes(HTMLTagToken *token)
{
if (token.attributes == nil) {
return;
}
NSDictionary *replacements = @{ @"xlink:actuate": @"xlink actuate",
@"xlink:arcrole": @"xlink arcrole",
@"xlink:href": @"xlink href",
@"xlink:role": @"xlink role",
@"xlink:show": @"xlink show",
@"xlink:title": @"xlink title",
@"xlink:type": @"xlink type",
@"xml:base": @"xml base",
@"xml:lang": @"xml lang",
@"xml:space": @"xml space",
@"xmlns": @"xmlns",
@"xmlns:xlink": @"xmlns xlink"};
HTMLOrderedDictionary *adjusted = [HTMLOrderedDictionary new];
for (id key in token.attributes) {
NSString *replacement = replacements[key] ?: key;
adjusted[replacement] = token.attributes[key];
}
token.attributes = adjusted;
}
+1 -1
View File
@@ -12,7 +12,7 @@
#import "HTMLElement.h"
#import "HTMLNamespaces.h"
#import "NSString+HTMLKit.h"
#import "NSString+Private.h"
NS_INLINE BOOL IsNodeMathMLTextIntegrationPoint(HTMLElement *node)
{
+3 -2
View File
@@ -15,9 +15,10 @@
/**
Typedef for the error callback block.
@param reason The string describing the reason of the reported error.
@param code The standarized error-code
@param details The string describing the reason of the reported error.
*/
typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason);
typedef void (^ HTMLStreamReaderErrorCallback)(NSString *code, NSString *details);
/**
* HTML Input Stream Reader processor conforming to the HTML standard
+2 -2
View File
@@ -232,7 +232,7 @@ typedef NS_OPTIONS(unsigned short, HTMLDocumentPosition)
/**
Returns the index of the given child element in the set of child nodes.
@param node The element.
@param element The element.
@return The index of the given element in the children set.
*/
- (NSUInteger)indexOfChildElement:(HTMLElement *)element;
@@ -248,7 +248,7 @@ typedef NS_OPTIONS(unsigned short, HTMLDocumentPosition)
/**
Prepends the given array of nodes to the set of child nodes.
@param node The nodes to prepend.
@param nodes The nodes to prepend.
*/
- (void)prependNodes:(NSArray<HTMLNode *> *)nodes;
+8 -5
View File
@@ -18,19 +18,22 @@
*/
@interface HTMLParseErrorToken : HTMLToken
/** @brief The error's reason message. */
@property (nonatomic, copy) NSString *reason;
/** @brief The parse error's code as specified at https://html.spec.whatwg.org/multipage/parsing.html#parse-errors. */
@property (nonatomic, strong, readonly) NSString *code;
/** @brief Additional detailed error information. */
@property (nonatomic, strong, readonly) NSString *details;
/** @brief The error's location in the stream. */
@property (nonatomic, assign) NSUInteger location;
@property (nonatomic, assign, readonly) NSUInteger location;
/**
Initializes a new Parse Error token.
@param reason The error's reason message.
@param code The parse error's as specified at https://html.spec.whatwg.org/multipage/parsing.html#parse-errors.
@param location The error's location in the stream.
@return A new instance of a parse error token.
*/
- (instancetype)initWithReasonMessage:(NSString *)reason andStreamLocation:(NSUInteger)location;
- (instancetype)initWithCode:(NSString *)code details:(NSString *)details location:(NSUInteger)location;
@end
+1 -11
View File
@@ -6,8 +6,6 @@
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "NSString+HTMLKit.h"
/**
HTML quirks modes
https://html.spec.whatwg.org/multipage/infrastructure.html#quirks-mode
@@ -82,12 +80,4 @@ static NSString * HTMLQuirksModePrefixes[] = {
#undef QUIRKS_ENTRY
};
NS_INLINE BOOL QuirksModePrefixMatch(NSString *publicIdentifier)
{
for (int i = 0; i < sizeof(HTMLQuirksModePrefixes) / sizeof(HTMLQuirksModePrefixes[0]); i++) {
if ([publicIdentifier hasPrefixIgnoringCase:HTMLQuirksModePrefixes[i]]) {
return YES;
}
}
return NO;
}
extern BOOL QuirksModePrefixMatch(NSString *publicIdentifier);
+19 -6
View File
@@ -81,7 +81,12 @@ typedef NS_ENUM(unsigned short, HTMLRangeComparisonMethod)
@param document The HTML doucment for which the range will be constructed.
@return A new HTML Range instance.
*/
- (instancetype)initWithDowcument:(HTMLDocument *)document;
- (instancetype)initWithDocument:(HTMLDocument *)document;
/**
Deprecated due to typo.
*/
- (instancetype)initWithDowcument:(HTMLDocument *)document __attribute__((deprecated("Replaced by -initWithDocument:")));
/**
Initializes a new range instance for the given document and boundaries.
@@ -93,23 +98,31 @@ typedef NS_ENUM(unsigned short, HTMLRangeComparisonMethod)
@param endOffset The offset of the end boundary
@return A new HTML Range instance.
*/
- (instancetype)initWithDocument:(HTMLDocument *)document
startContainer:(HTMLNode *)startContainer startOffset:(NSUInteger)startOffset
endContainer:(HTMLNode *)endContainer endOffset:(NSUInteger)endOffset;
/**
Deprecated due to typo.
*/
- (instancetype)initWithDowcument:(HTMLDocument *)document
startContainer:(HTMLNode *)startContainer startOffset:(NSUInteger)startOffset
endContainer:(HTMLNode *)endContainer endOffset:(NSUInteger)endOffset;
endContainer:(HTMLNode *)endContainer endOffset:(NSUInteger)endOffset
__attribute__((deprecated("Replaced by -initWithDocument:startContainer:startOffset:endContainer:endOffset:")));
/**
Sets the start boundary.
@param startNode The new node of the start boundary.
@param startOffset The new offset of the start boundary.
@param node The new node of the start boundary.
@param offset The new offset of the start boundary.
*/
- (void)setStartNode:(HTMLNode *)node startOffset:(NSUInteger)offset;
/**
Sets the end boundary.
@param startNode The new node of the end boundary.
@param startOffset The new offset of the end boundary.
@param node The new node of the end boundary.
@param offset The new offset of the end boundary.
*/
- (void)setEndNode:(HTMLNode *)node endOffset:(NSUInteger)offset;
+4 -4
View File
@@ -79,7 +79,7 @@
/**
Checks whether an element with the given tag name is in the stack.
@param tagname The element's tag name.
@param tagName The element's tag name.
@return `YES` if such an element is in the stack, `NO` otherwise.
*/
- (BOOL)containsElementWithTagName:(NSString *)tagName;
@@ -163,11 +163,11 @@
https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-the-specific-scope
*/
- (HTMLElement *)hasElementInScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasAnyElementInScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasHeaderElementInScope;
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName;
/**
+14
View File
@@ -16,6 +16,13 @@
@class HTMLParser;
/**
Typedef for the parse error callback block.
@param token The parse error token.
*/
typedef void (^ HTMLTokenizerParseErrorCallback)(HTMLParseErrorToken *token);
/**
* HTML Tokenizer
* https://html.spec.whatwg.org/multipage/syntax.html#tokenization
@@ -39,6 +46,13 @@
*/
@property (nonatomic, weak) HTMLParser *parser;
/**
An error callback block, which gets called when encountering parse errors while tokenizing the stream
Parse error tokens are dropped if the callback is `nil`.
*/
@property (nonatomic, copy) HTMLTokenizerParseErrorCallback parseErrorCallback;
/**
Initializes a new Tokenizer with the given string.
+28 -10
View File
@@ -23,11 +23,16 @@
CHAR( DIGIT_NINE, 0x0039 ) \
CHAR( LATIN_CAPITAL_LETTER_A, 0x0041 ) \
CHAR( LATIN_CAPITAL_LETTER_F, 0x0046 ) \
CHAR( LATIN_CAPITAL_LETTER_P, 0x0050 ) \
CHAR( LATIN_CAPITAL_LETTER_S, 0x0053 ) \
CHAR( LATIN_CAPITAL_LETTER_X, 0x0058 ) \
CHAR( LATIN_CAPITAL_LETTER_Z, 0x005A ) \
CHAR( RIGHT_SQUARE_BRACKET, 0x005D ) \
CHAR( GRAVE_ACCENT, 0x0060 ) \
CHAR( LATIN_SMALL_LETTER_A, 0x0061 ) \
CHAR( LATIN_SMALL_LETTER_F, 0x0066 ) \
CHAR( LATIN_SMALL_LETTER_P, 0x0070 ) \
CHAR( LATIN_SMALL_LETTER_S, 0x0073 ) \
CHAR( LATIN_SMALL_LETTER_X, 0x0078 ) \
CHAR( LATIN_SMALL_LETTER_Z, 0x007A ) \
CHAR( HYPHEN_MINUS, 0x002D ) \
@@ -82,13 +87,17 @@ NUMERIC_REPLACEMENT_CHARACTERS
#undef CHAR
};
NS_INLINE BOOL isControlOrUndefinedCharacter(UTF32Char character)
NS_INLINE BOOL isControlCharacter(unsigned long long character)
{
return ((character >= 0x0001 && character <= 0x0008) ||
(character >= 0x000D && character <= 0x001F) ||
(character >= 0x007F && character <= 0x009F) ||
(character >= 0xFDD0 && character <= 0xFDEF) ||
character == 0x000B ||
(character >= 0x000E && character <= 0x001F) ||
(character >= 0x007F && character <= 0x009F));
}
NS_INLINE BOOL isNoncharacter(unsigned long long character)
{
return ((character >= 0xFDD0 && character <= 0xFDEF) ||
character == 0xFFFE ||
character == 0xFFFF ||
character == 0x1FFFE ||
@@ -137,6 +146,18 @@ NS_INLINE BOOL isHexDigit(UTF32Char character)
(character >= LATIN_SMALL_LETTER_A && character <= LATIN_SMALL_LETTER_F));
}
NS_INLINE BOOL isUpperHexDigit(UTF32Char character)
{
return ((character >= LATIN_CAPITAL_LETTER_A && character <= LATIN_CAPITAL_LETTER_F) ||
(character >= DIGIT_ZERO && character <= DIGIT_NINE));
}
NS_INLINE BOOL isLowerHexDigit(UTF32Char character)
{
return ((character >= LATIN_SMALL_LETTER_A && character <= LATIN_SMALL_LETTER_F) ||
(character >= DIGIT_ZERO && character <= DIGIT_NINE));
}
NS_INLINE BOOL isAlphanumeric(UTF32Char character)
{
return ((character >= DIGIT_ZERO && character <= DIGIT_NINE) ||
@@ -151,17 +172,14 @@ NS_INLINE BOOL isStringAlphanumeric(NSString *string)
return ([string rangeOfCharacterFromSet:set].location == NSNotFound);
}
NS_INLINE BOOL isInvalidNumericRange(unsigned long long numeric)
NS_INLINE BOOL isSurrogate(unsigned long long character)
{
return ((numeric >= 0xD800 && numeric <= 0xDFFF) ||
numeric > 0x10FFFF);
return (character >= 0xD800 && character <= 0xDFFF);
}
NS_INLINE unichar NumericReplacementCharacter(UTF32Char character)
{
if (character == NULL_CHAR) {
return REPLACEMENT_CHAR;
} else if (character >= 0x0080 && character <= 0x009F) {
if (character >= 0x0080 && character <= 0x009F) {
return NumericReplacementTable[character - 0x0080];
} else {
return NULL_CHAR;
+16 -3
View File
@@ -12,9 +12,7 @@
#define TOKENIZER_STATES \
STATE_ENTRY( HTMLTokenizerStateData, = 0) \
STATE_ENTRY( HTMLTokenizerStateCharacterReferenceInData, ) \
STATE_ENTRY( HTMLTokenizerStateRCDATA, ) \
STATE_ENTRY( HTMLTokenizerStateCharacterReferenceInRCDATA, ) \
STATE_ENTRY( HTMLTokenizerStateRAWTEXT, ) \
STATE_ENTRY( HTMLTokenizerStateScriptData, ) \
STATE_ENTRY( HTMLTokenizerStatePLAINTEXT, ) \
@@ -59,6 +57,10 @@
STATE_ENTRY( HTMLTokenizerStateCommentStart, ) \
STATE_ENTRY( HTMLTokenizerStateCommentStartDash, ) \
STATE_ENTRY( HTMLTokenizerStateComment, ) \
STATE_ENTRY( HTMLTokenizerStateCommentLessThanSign, ) \
STATE_ENTRY( HTMLTokenizerStateCommentLessThanSignBang, ) \
STATE_ENTRY( HTMLTokenizerStateCommentLessThanSignBangDash, ) \
STATE_ENTRY( HTMLTokenizerStateCommentLessThanSignBangDashDash, ) \
STATE_ENTRY( HTMLTokenizerStateCommentEndDash, ) \
STATE_ENTRY( HTMLTokenizerStateCommentEnd, ) \
STATE_ENTRY( HTMLTokenizerStateCommentEndBang, ) \
@@ -78,7 +80,18 @@
STATE_ENTRY( HTMLTokenizerStateDOCTYPESystemIdentifierSingleQuoted, ) \
STATE_ENTRY( HTMLTokenizerStateAfterDOCTYPESystemIdentifier, ) \
STATE_ENTRY( HTMLTokenizerStateBogusDOCTYPE, ) \
STATE_ENTRY( HTMLTokenizerStateCDATASection, )
STATE_ENTRY( HTMLTokenizerStateCDATASection, ) \
STATE_ENTRY( HTMLTokenizerStateCDATASectionBracket, ) \
STATE_ENTRY( HTMLTokenizerStateCDATASectionEnd, ) \
STATE_ENTRY( HTMLTokenizerStateCharacterReference, ) \
STATE_ENTRY( HTMLTokenizerStateNamedCharacterReference, ) \
STATE_ENTRY( HTMLTokenizerStateAmbiguousAmpersand, ) \
STATE_ENTRY( HTMLTokenizerStateNumericCharacterReference, ) \
STATE_ENTRY( HTMLTokenizerStateHexadecimalCharacterReferenceStart, ) \
STATE_ENTRY( HTMLTokenizerStateDecimalCharacterReferenceStart, ) \
STATE_ENTRY( HTMLTokenizerStateHexadecimalCharacterReference, ) \
STATE_ENTRY( HTMLTokenizerStateDecimalCharacterReference, ) \
STATE_ENTRY( HTMLTokenizerStateNumericCharacterReferenceEnd, )
typedef NS_ENUM(NSUInteger, HTMLTokenizerState)
{
-1
View File
@@ -49,7 +49,6 @@ NS_ASSUME_NONNULL_BEGIN
Initializes a new tree walker with no filter and HTMLNodeFilterShowAll show options.
@param node The root node.
@param filter The node filter to use.
@return A new instance of a tree walker.
*/
- (instancetype)initWithNode:(HTMLNode *)node;
+4 -3
View File
@@ -19,17 +19,18 @@ NS_ASSUME_NONNULL_BEGIN
A character set for HTML whitespace characters: CHARACTER TABULATION U+0009, LINE FEED U+000A, FORM FEED U+000C,
CARRIAGE RETURN U+000D, and SPACE U+0020.
*/
+ (instancetype)HTMLWhitespaceCharacterSet;
+ (instancetype)htmlkit_HTMLWhitespaceCharacterSet;
/**
A character set for HTML HEX-Number characters: The digits 0-9, latin small letters a-f, and latin capital letters A-F.
*/
+ (instancetype)HTMLHexNumberCharacterSet;
+ (instancetype)htmlkit_HTMLHexNumberCharacterSet;
/**
A character set for CSS Nth-Expression: The digits 0-9, space, latin small n, latin capital N, plus sing and minus sign.
*/
+ (instancetype)CSSNthExpressionCharacterSet;
+ (instancetype)htmlkit_CSSNthExpressionCharacterSet;
@end
+2 -23
View File
@@ -15,38 +15,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface NSString (HTMLKit)
/**
Checks whether this string is equal to another ignoring the case.
@return `YES` if the two string are equal ignroing the case, `NO` otherwise.
*/
- (BOOL)isEqualToStringIgnoringCase:(NSString *)aString;
/**
Checks whether this string is equal to any of the given strings.
@return `YES` if there is an equal string, `NO` otherwise.
*/
- (BOOL)isEqualToAny:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION;
/**
Checks whether this string has a prefix ignoring the case.
@return `YES` if this string has a given prefix ignroing the case, `NO` otherwise.
*/
- (BOOL)hasPrefixIgnoringCase:(NSString *)aString;
/**
Checks whether this string is a HTML whitespace string.
@return `YES` if this string is a HTML whitespace string, `NO` otherwise.
*/
- (BOOL)isHTMLWhitespaceString;
- (BOOL)htmlkit_isHTMLWhitespaceString;
/**
@return The length of the leading HTML whitespace characters in this string.
*/
- (NSUInteger)leadingHTMLWhitespaceLength;
- (NSUInteger)htmlkit_leadingHTMLWhitespaceLength;
@end
+41
View File
@@ -0,0 +1,41 @@
//
// NSString+Private.h
// HTMLKit
//
// Created by Iska on 26.03.19.
// Copyright © 2019 BrainCookie. All rights reserved.
//
///------------------------------------------------------
/// HTMLKit private header
///------------------------------------------------------
#import <Foundation/Foundation.h>
/**
NSStirng category for common helper methods.
*/
@interface NSString (Private)
/**
Checks whether this string is equal to another ignoring the case.
@return `YES` if the two string are equal ignroing the case, `NO` otherwise.
*/
- (BOOL)isEqualToStringIgnoringCase:(NSString *)aString;
/**
Checks whether this string is equal to any of the given strings.
@return `YES` if there is an equal string, `NO` otherwise.
*/
- (BOOL)isEqualToAny:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION;
/**
Checks whether this string has a prefix ignoring the case.
@return `YES` if this string has a given prefix ignroing the case, `NO` otherwise.
*/
- (BOOL)hasPrefixIgnoringCase:(NSString *)aString;
@end
@@ -5,7 +5,7 @@ module HTMLKit {
export *
explicit module Private {
header "CSSCodePoints.h"
textual header "CSSCodePoints.h"
header "CSSInputStream.h"
header "HTMLCharacterToken.h"
header "HTMLCommentToken.h"
@@ -22,7 +22,7 @@ module HTMLKit {
header "HTMLTagToken.h"
header "HTMLToken.h"
header "HTMLTokenizer.h"
header "HTMLTokenizerCharacters.h"
textual header "HTMLTokenizerCharacters.h"
header "HTMLTokenizerEntities.h"
header "HTMLTokenizerStates.h"
header "HTMLTokens.h"
@@ -34,5 +34,6 @@ module HTMLKit {
header "HTMLParser+Private.h"
header "HTMLNodeTraversal.h"
header "HTMLDOMUtils.h"
header "NSString+Private.h"
}
}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -7,7 +7,7 @@
//
#import <XCTest/XCTest.h>
#import <HTMLKit/HTMLKit.h>
#import "HTMLKit.h"
#import "CSSSelectorTest.h"
#import "CSSSelectorParser.h"
+2 -2
View File
@@ -11,6 +11,7 @@
#import "HTMLDocument.h"
#import "HTMLElement.h"
#import "CSSSelectors.h"
#import "HTMLKitTestUtil.h"
static NSString * const CSSTests = @"css-tests";
@@ -18,8 +19,7 @@ static NSString * const CSSTests = @"css-tests";
+ (NSArray *)loadCSSSelectorTests
{
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
path = [path stringByAppendingPathComponent:CSSTests];
NSString *path = [HTMLKitTestUtil pathForFixture:CSSTests ofType:nil inDirectory:nil];
NSMutableArray *tests = [NSMutableArray array];
NSArray *testFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
@@ -0,0 +1,41 @@
//
// CSSStructuralPseudoSelectors.m
// HTMLKit
//
// Created by Iska on 18.04.18.
// Copyright © 2018 BrainCookie. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "CSSSelectors.h"
#import "HTMLParser.h"
#import "HTMLDOM.h"
@interface CSSStructuralPseudoSelectors : XCTestCase
@end
@implementation CSSStructuralPseudoSelectors
#pragma mark - Bug Fixes
- (void)testBugFix_Issue_25
{
NSString *html = @"<table><tr><td>TD #0</td><td>TD #1</td><td>TD #2</td><td>TD #3</td></tr></table>";
HTMLDocument *doc = [HTMLDocument documentWithString:html];
NSArray<HTMLElement *> *elements = [doc querySelectorAll:@"td:gt(0)"];
XCTAssertEqual(elements.count, 3);
XCTAssertEqualObjects(elements[0].textContent, @"TD #1");
XCTAssertEqualObjects(elements[1].textContent, @"TD #2");
XCTAssertEqualObjects(elements[2].textContent, @"TD #3");
elements = [doc querySelectorAll:@"td:lt(0)"];
XCTAssertEqual(elements.count, 0);
elements = [doc querySelectorAll:@"td:eq(0)"];
XCTAssertEqual(elements.count, 1);
XCTAssertEqualObjects(elements[0].textContent, @"TD #0");
}
@end
+1 -1
View File
@@ -14,9 +14,9 @@
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *input;
@property (nonatomic, strong) NSArray *output;
@property (nonatomic, strong) NSArray *errors;
@property (nonatomic, strong) NSArray *initialStates;
@property (nonatomic, copy) NSString *lastStartTag;
@property (nonatomic, assign) BOOL ignoreErrorOrder;
+ (NSDictionary *)loadHTML5LibTokenizerTests;
+22 -19
View File
@@ -7,23 +7,22 @@
//
#import "HTML5LibTokenizerTest.h"
#import "HTMLOrderedDictionary.h"
#import "HTMLTokenizerStates.h"
#import "HTMLTokens.h"
#import "HTMLKitTestUtil.h"
static NSString * const HTML5LibTests = @"html5lib-tests";
static NSString * const TOKENIZER = @"tokenizer";
static NSString * const Tokenizer = @"tokenizer";
@implementation HTML5LibTokenizerTest
+ (NSDictionary *)loadHTML5LibTokenizerTests
{
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
path = [path stringByAppendingPathComponent:HTML5LibTests];
path = [path stringByAppendingPathComponent:TOKENIZER];
NSMutableDictionary *testsMap = [NSMutableDictionary dictionary];
NSString *path = [HTMLKitTestUtil pathForFixture:Tokenizer ofType:nil inDirectory:HTML5LibTests];
NSArray *testFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSMutableDictionary *testsMap = [NSMutableDictionary dictionary];
for (NSString *testFile in testFiles) {
if (![testFile.pathExtension isEqualToString:@"test"]) {
continue;
@@ -71,16 +70,16 @@ static NSString * const TOKENIZER = @"tokenizer";
{
BOOL doubleEscaped = [test[@"doubleEscaped"] boolValue];
// Test Title
// Test Title
self.title = test[@"description"];
// Test Input
// Test Input
self.input = test[@"input"];
if (doubleEscaped) {
self.input = [self processDoubleEscaped:self.input];
}
// Test Output
// Test Output
NSMutableArray *tokens = [NSMutableArray array];
NSArray *outputs = test[@"output"];
for (NSArray *output in outputs) {
@@ -90,7 +89,7 @@ static NSString * const TOKENIZER = @"tokenizer";
[tokens addObject:[HTMLEOFToken token]];
self.output = tokens;
// Test Initial States
// Test Initial States
NSMutableArray *initialStates = [NSMutableArray array];
NSArray *states = test[@"initialStates"];
@@ -102,6 +101,10 @@ static NSString * const TOKENIZER = @"tokenizer";
state = HTMLTokenizerStateRCDATA;
} else if ([name isEqualToString:@"RAWTEXT state"]) {
state = HTMLTokenizerStateRAWTEXT;
} else if ([name isEqualToString:@"Script data state"]) {
state = HTMLTokenizerStateScriptData;
} else if ([name isEqualToString:@"CDATA section state"]) {
state = HTMLTokenizerStateCDATASection;
}
[initialStates addObject:@(state)];
}
@@ -111,19 +114,21 @@ static NSString * const TOKENIZER = @"tokenizer";
self.initialStates = initialStates;
// Test Last Start Tag
// Test Last Start Tag
self.lastStartTag = test[@"lastStartTag"];
// Ignore Error Order
self.ignoreErrorOrder = [test[@"ignoreErrorOrder"] boolValue];
// Test errors
NSArray *errors = test[@"errors"];
NSMutableArray *errorTokens = [NSMutableArray new];
for (NSDictionary *error in errors) {
HTMLParseErrorToken *token = [[HTMLParseErrorToken alloc] initWithCode:error[@"code"] details:nil location:0];
[errorTokens addObject:token];
}
self.errors = errorTokens;
}
- (HTMLToken *)processOutputToken:(id)output doubleEscaped:(BOOL)doubleEscaped
{
if ([output isKindOfClass:[NSString class]] && [output isEqualToString:@"ParseError"]) {
return [HTMLParseErrorToken new];
}
NSString *type = [output firstObject];
NSString *data = nil;
@@ -147,8 +152,6 @@ static NSString * const TOKENIZER = @"tokenizer";
return token;
} else if ([type isEqualToString:@"EndTag"]) {
return [[HTMLEndTagToken alloc] initWithTagName:data];
} else if ([type isEqualToString:@"ParseError"]) {
return [HTMLParseErrorToken new];
} else if ([type isEqualToString:@"StartTag"]) {
HTMLStartTagToken *token = [[HTMLStartTagToken alloc] initWithTagName:data];
NSDictionary *attributes = output[2];
@@ -9,10 +9,12 @@
#import "HTML5LibTreeConstructionTest.h"
#import <XCTest/XCTest.h>
#import "HTMLDOM.h"
#import "HTMLDocumentType.h"
#import "HTMLElement.h"
#import "HTMLText.h"
#import "HTMLComment.h"
#import "HTMLKitTestUtil.h"
static NSString * const HTML5LibTests = @"html5lib-tests";
static NSString * const TreeConstruction = @"tree-construction";
@@ -21,13 +23,10 @@ static NSString * const TreeConstruction = @"tree-construction";
+ (NSDictionary *)loadHTML5LibTreeConstructionTests
{
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
path = [path stringByAppendingPathComponent:HTML5LibTests];
path = [path stringByAppendingPathComponent:TreeConstruction];
NSMutableDictionary *testsMap = [NSMutableDictionary dictionary];
NSString *path = [HTMLKitTestUtil pathForFixture:TreeConstruction ofType:nil inDirectory:HTML5LibTests];
NSArray *testFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSMutableDictionary *testsMap = [NSMutableDictionary dictionary];
for (NSString *testFile in testFiles) {
if (![testFile.pathExtension isEqualToString:@"dat"]) {
continue;
@@ -48,7 +47,7 @@ static NSString * const TreeConstruction = @"tree-construction";
NSMutableArray *tests = [NSMutableArray array];
NSScanner *scanner = [NSScanner scannerWithString:contents];
NSString * (^ nextTest)() = ^ NSString * () {
NSString * (^ nextTest)(void) = ^ NSString * () {
NSString *str;
[scanner scanUpToString:@"\n\n#data" intoString:&str];
return str;
@@ -291,6 +290,8 @@ NS_INLINE NSArray * parseAttribute(NSString *str)
NSRange range = [str rangeOfString:@"=" options:0];
NSString *key = [str substringToIndex:range.location];
key = [key stringByReplacingOccurrencesOfString:@" " withString:@":"];
NSString *value = [str substringFromIndex:range.location + 2];
value = [value substringToIndex:value.length - 1];
@@ -0,0 +1,43 @@
//
// HTMLKitParserTests.m
// HTMLKit
//
// Created by Iska on 16.07.18.
// Copyright © 2018 BrainCookie. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "HTMLDOM.h"
@interface HTMLKitParserIssuesTests : XCTestCase
@end
@implementation HTMLKitParserIssuesTests
#pragma mark - Bug Fixes
- (void)testBugFix_Issue_30 {
NSString *html =
@"<body>"
" <svg id='draw_area' width='600' height='800' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1'>"
" <image id='overlay_img' xlink:href='foo.png' width='600' height='800'/>"
" </svg>"
"</body>";
HTMLDocument* document = [HTMLDocument documentWithString:html];
HTMLElement *svg = [document querySelector:@"#draw_area"];
XCTAssertNil(svg.attributes[@"xlink"]);
XCTAssertEqualObjects(svg.attributes[@"xmlns"], @"http://www.w3.org/2000/svg");
XCTAssertEqualObjects(svg.attributes[@"xmlns:xlink"], @"http://www.w3.org/1999/xlink");
HTMLElement *image = [document querySelector:@"#overlay_img"];
XCTAssertNil(image.attributes[@"xlink"]);
XCTAssertNil(image.attributes[@"href"]);
XCTAssertEqualObjects(image.attributes[@"xlink:href"], @"foo.png");
XCTAssertEqualObjects(image.outerHTML, @"<image id=\"overlay_img\" xlink:href=\"foo.png\" width=\"600\" height=\"800\"></image>");
}
@end
@@ -8,6 +8,7 @@
#import <XCTest/XCTest.h>
#import "HTMLParser.h"
#import "HTMLKitTestUtil.h"
@interface HTMLKitParserPerformance : XCTestCase
@@ -17,11 +18,9 @@
#define HTMLKIT_NO_DOM_CHECKS
- (void)testParserPerformance
- (void)_testParserPerformance
{
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
path = [path stringByAppendingPathComponent:@"Fixtures"];
path = [path stringByAppendingPathComponent:@"HTML Standard.html"];
NSString *path = [HTMLKitTestUtil pathForFixture:@"HTML Standard" ofType:@"html" inDirectory:@"Fixtures"];
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
+1
View File
@@ -12,5 +12,6 @@
+ (NSInvocation *)addTestToClass:(Class)cls withName:(NSString *)name block:(id)block;
+ (id)ivarForInstacne:(id)instance name:(NSString *)name;
+ (NSString *)pathForFixture:(NSString *)fixture ofType:(NSString *)type inDirectory:(NSString *)directory;
@end
+19
View File
@@ -32,4 +32,23 @@
return object_getIvar(instance, ivar);
}
+ (NSString *)pathForFixture:(NSString *)fixture ofType:(NSString *)type inDirectory:(NSString *)directory
{
// Try testing bundle first
NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:fixture ofType:type inDirectory:directory];
if (path) {
return path;
}
path = [[@(__FILE__) stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
if (directory) {
path = [path stringByAppendingPathComponent:directory];
}
NSString *resource = type ? [NSString stringWithFormat:@"%@.%@", fixture, type] : fixture;
path = [path stringByAppendingPathComponent:resource];
return path;
}
@end
@@ -10,6 +10,7 @@
#import "HTMLTokenizer.h"
#import "HTMLTokenizerStates.h"
#import "HTMLTokens.h"
#import "HTMLKitTestUtil.h"
@interface HTMLKitTokenizerPerformance : XCTestCase
@@ -17,11 +18,9 @@
@implementation HTMLKitTokenizerPerformance
- (void)testTokenizerPerformance
- (void)_testTokenizerPerformance
{
NSString *path = [[NSBundle bundleForClass:self.class] resourcePath];
path = [path stringByAppendingPathComponent:@"Fixtures"];
path = [path stringByAppendingPathComponent:@"HTML Standard.html"];
NSString *path = [HTMLKitTestUtil pathForFixture:@"HTML Standard" ofType:@"html" inDirectory:@"Fixtures"];
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
+19 -8
View File
@@ -81,20 +81,31 @@
for (NSNumber *state in test.initialStates) {
HTMLTokenizer *tokenizer = [[HTMLTokenizer alloc] initWithString:test.input];
[tokenizer setValue:test.lastStartTag forKey:@"_lastStartTagName"];
[tokenizer setValue:test.lastStartTag forKey:@"_lastStartTagName"];
tokenizer.state = [state integerValue];
NSArray *expectedTokens = test.output;
NSArray *tokens = tokenizer.allObjects;
NSArray *expectedErrors = test.errors;
NSMutableArray *actualErrors = [NSMutableArray new];
tokenizer.parseErrorCallback = ^(HTMLParseErrorToken *token) {
[actualErrors addObject:token];
};
NSString *message = [NSString stringWithFormat:@"HTML5Lib test in file: \'%@\' Title: '%@'\nInput: '%@'\nExpected:\n%@\nActual:\n%@\n",
NSArray *expectedTokens = test.output;
NSArray *actualTokens = tokenizer.allObjects;
NSString *message = [NSString stringWithFormat:@"\nTest file: \'%@\'\nTitle: '%@'\nInput: '%@'\n",
test.testFile,
test.title,
test.input,
expectedTokens,
tokens];
XCTAssertEqualObjects(tokens, expectedTokens, @"%@", message);
test.input];
XCTAssertEqualObjects(actualTokens, expectedTokens, @"%@", message);
message = [NSString stringWithFormat:@"\nTest file: \'%@\'\nTitle: '%@'\nInput: '%@'\n",
test.testFile,
test.title,
test.input];
XCTAssertEqualObjects(actualErrors, expectedErrors, @"%@", message);
}
}
}
@@ -157,7 +157,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLDocument *document = [HTMLDocument new];
HTMLDocumentFragment *fragment = [[HTMLDocumentFragment alloc] initWithDocument:document];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[fragment removeAllChildNodes];
[document removeAllChildNodes];
};
@@ -213,7 +213,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLDocument *document = [HTMLDocument new];
HTMLElement *element = [HTMLElement new];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[element removeAllChildNodes];
[document removeAllChildNodes];
};
@@ -247,7 +247,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLDocument *document = [HTMLDocument new];
HTMLDocumentType *doctype = [HTMLDocumentType new];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[document removeAllChildNodes];
};
@@ -280,7 +280,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLComment *child = [HTMLComment new];
HTMLDocumentFragment *replacement = [[HTMLDocumentFragment alloc] initWithDocument:document];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[replacement removeAllChildNodes];
[document removeAllChildNodes];
[document appendNode:child];
@@ -326,7 +326,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLComment *child = [HTMLComment new];
HTMLElement *replacement = [HTMLElement new];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[replacement removeAllChildNodes];
[document removeAllChildNodes];
[document appendNode:child];
@@ -353,7 +353,7 @@ extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
HTMLComment *child = [HTMLComment new];
HTMLDocumentType *replacement = [HTMLDocumentType new];
void (^ reset)() = ^ {
void (^ reset)(void) = ^ {
[replacement removeAllChildNodes];
[document removeAllChildNodes];
[document appendNode:child];
@@ -592,4 +592,35 @@ static HTMLNode * (^ LastDescendant)(HTMLNode *) = ^ HTMLNode * (HTMLNode *node)
XCTAssertEqual(0, nodeIterators.count);
}
- (void)testBugFix_Issue_22 {
// The issue is applicable only for devices. On simulator the test is passed.
HTMLDocument *document = [HTMLDocument documentWithString:@"<div id=\"id\"></div>"];
NSString *divId = @"id";
HTMLNodeFilterBlock *filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode * _Nonnull node) {
HTMLElement *element = (HTMLElement *)node;
return [element.elementId isEqualToString:divId] ? HTMLNodeFilterAccept : HTMLNodeFilterSkip;
}];
HTMLNodeIterator *iterator = [document nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:filter];
HTMLElement *element = (HTMLElement*)iterator.nextObject;
XCTAssertTrue([element.elementId isEqualToString:divId]);
}
- (void)testBugFix_Issue_28 {
HTMLDocument *document = self.document;
HTMLNodeIterator *iterator = document.body.nodeIterator;
[iterator nextNode]; // Reference node: <body>
HTMLElement *span = (HTMLElement*)iterator.nextNode; // <span>
NSString *spanTag = @"span";
XCTAssertTrue([span.tagName isEqualToString:spanTag]);
HTMLElement *paragraph = span.nextSiblingElement; // <p>
NSString *paragraphTag = @"p";
XCTAssertTrue([paragraph.tagName isEqualToString:paragraphTag]);
}
@end
+56
View File
@@ -512,4 +512,60 @@
XCTAssertTrue([image compareDocumentPositionWithNode:outerDiv] == (HTMLDocumentPositionContainedBy | HTMLDocumentPositionFollowing));
}
- (void)testDeepCloneElement {
HTMLElement *outer = [[HTMLElement alloc] initWithTagName:@"div"
attributes:@{@"id": @"outer",
@"class": @"green"}];
HTMLElement *innerLevel1 = [[HTMLElement alloc] initWithTagName:@"div"
attributes:@{@"id": @"inner1",
@"class": @"red"}];
HTMLElement *innerLevel2 = [[HTMLElement alloc] initWithTagName:@"div"
attributes:@{@"id": @"inner2",
@"class": @"red"}];
[outer appendNode:innerLevel1];
[innerLevel1 appendNode:innerLevel2];
HTMLElement *clone = [outer cloneNodeDeep:YES];
XCTAssertNotEqual(clone, outer);
XCTAssertEqualObjects(clone.elementId, outer.elementId);
XCTAssertEqualObjects(clone.attributes, outer.attributes);
XCTAssertNotEqual(clone.firstChild, innerLevel1);
XCTAssertEqualObjects(clone.firstChild.asElement.elementId, innerLevel1.elementId);
XCTAssertEqualObjects(clone.firstChild.asElement.attributes, innerLevel1.attributes);
XCTAssertNotEqual(clone.firstChild, innerLevel2);
XCTAssertEqualObjects(clone.firstChild.firstChild.asElement.elementId, innerLevel2.elementId);
XCTAssertEqualObjects(clone.firstChild.firstChild.asElement.attributes, innerLevel2.attributes);
}
- (void)testDeepCloneElementAttributes {
HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"
attributes:@{@"id": @"outer",
@"class": @"green",
@"data": @"test"}];
HTMLElement *clone = [div cloneNodeDeep:YES];
XCTAssertEqualObjects(clone.attributes, div.attributes);
XCTAssertTrue([clone.attributes isKindOfClass:[HTMLOrderedDictionary class]]);
}
#pragma mark - Bug Fixes
- (void)testBugFix_Issue_20 {
HTMLElement *element = [HTMLElement new];
element.elementId = @"originalId";
HTMLElement *clone = [element cloneNodeDeep:YES];
NSString *cloneId = @"cloneId";
clone.elementId = cloneId;
XCTAssertTrue([clone.elementId isEqualToString:cloneId]);
}
@end
+69 -69
View File
@@ -90,7 +90,7 @@
- (void)testInitRange
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
XCTAssertEqualObjects(range.startContainer, _document);
XCTAssertEqual(range.startOffset, 0);
@@ -101,7 +101,7 @@
- (void)testSetStartBoundary
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
XCTAssertThrows([range setStartNode:[HTMLElement new] startOffset:0], @"Cannot set boundary to a node outside of the range's document");
XCTAssertThrows([range setStartNode:[HTMLDocumentType new] startOffset:0], @"DOCTYPE as range boundary is invalid");
@@ -130,7 +130,7 @@
- (void)testSetEndBoundary
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
XCTAssertThrows([range setEndNode:[HTMLDocumentType new] endOffset: 0], @"DOCTYPE as range boundary is invalid");
XCTAssertThrows([range setEndNode:_firstText endOffset:_firstText.length + 1], @"Offset is outside the boundary node");
@@ -168,7 +168,7 @@
- (void)testSetStartBeforeNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><!--Second comment--></div>
// |___|
@@ -263,7 +263,7 @@
- (void)testSetStartAfterNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><!--Second comment--></div>
// |___|
@@ -358,7 +358,7 @@
- (void)testSetEndBeforeNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><!--Second comment--></div>
// |___|
@@ -453,7 +453,7 @@
- (void)testSetEndAfterNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><!--Second comment--></div>
// |___|
@@ -548,7 +548,7 @@
- (void)testIsCollapsed
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
XCTAssertTrue(range.isCollapsed);
[range setEndNode:_title endOffset:1];
@@ -560,7 +560,7 @@
- (void)testCollapseToStart
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |______________|
@@ -579,7 +579,7 @@
- (void)testCollapseToEnd
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |______________|
@@ -598,7 +598,7 @@
- (void)testSelectNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// ----------
@@ -651,7 +651,7 @@
- (void)testSelectNodeContents
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// ----------
@@ -704,9 +704,9 @@
- (void)testCompareBoundaries
{
HTMLRange *range1 = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range1 = [[HTMLRange alloc] initWithDocument:_document];
HTMLRange *range2 = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range2 = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// ----------
@@ -776,7 +776,7 @@
- (void)testContainmentAndComparisons
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
/*********** Compare ***********/
@@ -850,7 +850,7 @@
- (void)testIntersections
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
XCTAssertFalse([range intersectsNode:[HTMLText new]]);
XCTAssertTrue([range intersectsNode:_document]);
@@ -882,7 +882,7 @@
- (void)testThatCharacterDataMutationsUpdateRangeCorrectly
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |________|
@@ -980,7 +980,7 @@
- (void)testThatCharacterDataMutationsUpdateRangeCorrectly_DifferentBoundaries
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |___________________________|
@@ -1094,7 +1094,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_BeforeStartTextNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |________|
[range selectNodeContents:_firstText];
@@ -1111,7 +1111,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_AfterEndTextNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |________|
[range selectNodeContents:_firstText];
@@ -1128,7 +1128,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_MidleSameTextNode
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |________|
[range selectNodeContents:_firstText];
@@ -1145,7 +1145,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_MidleDifferentTextNodes
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |______________________________|
[range setStartNode:_firstText startOffset:2];
@@ -1163,7 +1163,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_BeforeStartDifferentTextNodes
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |______________________________|
[range setStartNode:_firstText startOffset:6];
@@ -1181,7 +1181,7 @@
- (void)testThatTextSplitUpdateRangeCorrectly_BeforeEndDifferentTextNodes
{
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:_document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:_document];
// <h1>Title</h1><p>Hello</p><div><div>First text<!--First comment-->Second text</div><--Second comment--></div>
// |_______________________________|
[range setStartNode:_firstText startOffset:6];
@@ -1241,7 +1241,7 @@
- (void)testDeleteContents_SameTextNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1260,7 +1260,7 @@
- (void)testDeleteContents_SameTextNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNode:node];
@@ -1279,7 +1279,7 @@
- (void)testDeleteContents_SameTextNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNodeContents:node];
@@ -1299,7 +1299,7 @@
- (void)testDeleteContents_DifferentTextNodesOfSingleParent
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1318,7 +1318,7 @@
- (void)testDeleteContents_DifferentTextNodesOfDifferentParents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1337,7 +1337,7 @@
- (void)testDeleteContents_DifferentTextNodesOfDifferentParents_HavingContainedNodesInBetween
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1355,7 +1355,7 @@
- (void)testDeleteContents_SameContainerNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:0];
@@ -1374,7 +1374,7 @@
- (void)testDeleteContents_SameContainerNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNode:node];
@@ -1391,7 +1391,7 @@
- (void)testDeleteContents_SameContainerNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNodeContents:node];
@@ -1408,7 +1408,7 @@
- (void)testDeleteContents_StartContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#D1"];
[range setStartNode:start startOffset:0];
@@ -1427,7 +1427,7 @@
- (void)testDeleteContents_EndContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1448,7 +1448,7 @@
- (void)testCloneContents_SameTextNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1464,7 +1464,7 @@
- (void)testCloneContents_SameTextNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNode:node];
@@ -1478,7 +1478,7 @@
- (void)testCloneContents_SameTextNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNodeContents:node];
@@ -1492,7 +1492,7 @@
- (void)testCloneContents_DifferentTextNodesOfSingleParent
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1506,7 +1506,7 @@
- (void)testCloneContents_DifferentTextNodesOfDifferentParents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1520,7 +1520,7 @@
- (void)testCloneContents_DifferentTextNodesOfDifferentParents_HavingContainedNodesInBetween
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1536,7 +1536,7 @@
- (void)testCloneContents_SameContainerNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:0];
@@ -1550,7 +1550,7 @@
- (void)testCloneContents_SameContainerNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNode:node];
@@ -1562,7 +1562,7 @@
- (void)testCloneContents_SameContainerNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNodeContents:node];
@@ -1574,7 +1574,7 @@
- (void)testCloneContents_StartContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#D1"];
[range setStartNode:start startOffset:0];
@@ -1588,7 +1588,7 @@
- (void)testCloneContents_EndContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1604,7 +1604,7 @@
- (void)testExtractContents_SameTextNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1627,7 +1627,7 @@
- (void)testExtractContents_SameTextNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNode:node];
@@ -1650,7 +1650,7 @@
- (void)testExtractContents_SameTextNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"].firstChild;
[range selectNodeContents:node];
@@ -1674,7 +1674,7 @@
- (void)testExtractContents_DifferentTextNodesOfSingleParent
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1695,7 +1695,7 @@
- (void)testExtractContents_DifferentTextNodesOfDifferentParents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1716,7 +1716,7 @@
- (void)testExtractContents_DifferentTextNodesOfDifferentParents_HavingContainedNodesInBetween
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:3];
@@ -1738,7 +1738,7 @@
- (void)testExtractContents_SameContainerNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:0];
@@ -1759,7 +1759,7 @@
- (void)testExtractContents_SameContainerNode_Selected
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNode:node];
@@ -1778,7 +1778,7 @@
- (void)testExtractContents_SameContainerNode_SelectedContents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *node = [document querySelector:@"#P1"];
[range selectNodeContents:node];
@@ -1797,7 +1797,7 @@
- (void)testExtractContents_StartContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#D1"];
[range setStartNode:start startOffset:0];
@@ -1818,7 +1818,7 @@
- (void)testExtractContents_EndContainerIsCommonRoot
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:1];
@@ -1841,7 +1841,7 @@
- (void)testInsertNode_InvalidNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -1860,7 +1860,7 @@
- (void)testInsertNode_TextNodeStart_Begin
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:0];
@@ -1884,7 +1884,7 @@
- (void)testInsertNode_TextNodeStart_Middle
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -1908,7 +1908,7 @@
- (void)testInsertNode_NonTextNodeStart_Begin
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:0];
@@ -1932,7 +1932,7 @@
- (void)testInsertNode_NonTextNodeStart_Middle
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:2];
@@ -1956,7 +1956,7 @@
- (void)testInsertNode_NonTextNodeStart_DifferentParents
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#D1"];
[range setStartNode:start startOffset:1];
@@ -1980,7 +1980,7 @@
- (void)testSurroundContents_InvalidNode
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -1995,7 +1995,7 @@
- (void)testSurroundContents_PartiallySelectedAncestors
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -2016,7 +2016,7 @@
- (void)testSurroundContents_TextNodes
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -2037,7 +2037,7 @@
- (void)testSurroundContents_NonTextNodes
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"];
[range setStartNode:start startOffset:0];
@@ -2060,7 +2060,7 @@
- (void)testRangeStringifier
{
HTMLDocument *document = self.editingDocument;
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *start = [document querySelector:@"#P1"].firstChild;
[range setStartNode:start startOffset:2];
@@ -2110,7 +2110,7 @@
// range should be autoreleased, deallocated and detached after autoreleasepool
@autoreleasepool {
HTMLRange *range = [[HTMLRange alloc] initWithDowcument:document];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
[range cloneContents];
XCTAssertEqual(1, ranges.count);
}
@@ -0,0 +1,44 @@
//
// HTMLSerializationTests.m
// HTMLKit
//
// Created by Iska on 06.11.17.
// Copyright © 2017 BrainCookie. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "HTMLDOM.h"
@interface HTMLSerializationTests : XCTestCase
@end
@implementation HTMLSerializationTests
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
#pragma mark - Bug Fixes
- (void)testBugFix_Issue_16
{
NSString *html = @"<body><div>&lt;test&gt;</div></body>";
HTMLDocument *document = [HTMLDocument documentWithString:html];
XCTAssertEqualObjects(document.body.outerHTML, html);
}
- (void)testBugFix_Issue_17
{
NSString *html = @"<body key='& testing 0x00A0'></body>";
HTMLDocument *document = [HTMLDocument documentWithString:html];
XCTAssertEqualObjects(document.body.outerHTML, @"<body key=\"&amp; testing &nbsp;\"></body>");
}
@end
+20 -19
View File
@@ -7,6 +7,7 @@
//
#import <XCTest/XCTest.h>
#import "NSString+Private.h"
#import "NSString+HTMLKit.h"
@interface HTMLKitStringCategoryTests : XCTestCase
@@ -50,33 +51,33 @@
- (void)testIsHTMLWhitespaceString
{
XCTAssertTrue([@" " isHTMLWhitespaceString]);
XCTAssertTrue([@"\t" isHTMLWhitespaceString]);
XCTAssertTrue([@"\n" isHTMLWhitespaceString]);
XCTAssertTrue([@"\f" isHTMLWhitespaceString]);
XCTAssertTrue([@"\r" isHTMLWhitespaceString]);
XCTAssertTrue([@" \t\n\f\r" isHTMLWhitespaceString]);
XCTAssertTrue([@"\t\n\f\r " isHTMLWhitespaceString]);
XCTAssertTrue([@" \t \n \f \r" isHTMLWhitespaceString]);
XCTAssertFalse([@"html kit" isHTMLWhitespaceString]);
XCTAssertTrue([@" " htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@"\t" htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@"\n" htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@"\f" htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@"\r" htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@" \t\n\f\r" htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@"\t\n\f\r " htmlkit_isHTMLWhitespaceString]);
XCTAssertTrue([@" \t \n \f \r" htmlkit_isHTMLWhitespaceString]);
XCTAssertFalse([@"html kit" htmlkit_isHTMLWhitespaceString]);
}
- (void)testLeadingWhitespaceLength
{
XCTAssertEqual([@"" leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@"\0" leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@"" htmlkit_leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@"\0" htmlkit_leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@" " leadingHTMLWhitespaceLength], 1);
XCTAssertEqual([@"\0 " leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@" " htmlkit_leadingHTMLWhitespaceLength], 1);
XCTAssertEqual([@"\0 " htmlkit_leadingHTMLWhitespaceLength], 0);
XCTAssertEqual([@" " leadingHTMLWhitespaceLength], 2);
XCTAssertEqual([@" \0 " leadingHTMLWhitespaceLength], 1);
XCTAssertEqual([@" " htmlkit_leadingHTMLWhitespaceLength], 2);
XCTAssertEqual([@" \0 " htmlkit_leadingHTMLWhitespaceLength], 1);
XCTAssertEqual([@"\t\r\n\f" leadingHTMLWhitespaceLength], 4);
XCTAssertEqual([@"\t\r\n\0\f" leadingHTMLWhitespaceLength], 3);
XCTAssertEqual([@"\t\r\n\f" htmlkit_leadingHTMLWhitespaceLength], 4);
XCTAssertEqual([@"\t\r\n\0\f" htmlkit_leadingHTMLWhitespaceLength], 3);
XCTAssertEqual([@"\t\r\n\f " leadingHTMLWhitespaceLength], 5);
XCTAssertEqual([@"\t\r\n\f\0 " leadingHTMLWhitespaceLength], 4);
XCTAssertEqual([@"\t\r\n\f " htmlkit_leadingHTMLWhitespaceLength], 5);
XCTAssertEqual([@"\t\r\n\f\0 " htmlkit_leadingHTMLWhitespaceLength], 4);
}
@end