34 Commits

Author SHA1 Message Date
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 57c931aece Merge branch 'release/2.0.5' into develop 2017-04-19 00:02:10 +02:00
37 changed files with 3537 additions and 82202 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.5
module_version: 2.1.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)
+35
View File
@@ -1,15 +1,46 @@
# Change Log
## [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
@@ -21,10 +52,12 @@ Released on 2017.04.19
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:`
@@ -34,6 +67,7 @@ Released on 2017.04.2
Released on 2017.03.6
### Fixed
- Compilation for Swift 3.1
- Fixed by @tali in PR #6
@@ -43,6 +77,7 @@ Released on 2017.03.6
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.5"
s.version = "2.1.0"
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
s.license = "MIT"
s.homepage = "https://github.com/iabudiab/HTMLKit"
+13 -1
View File
@@ -1573,7 +1573,7 @@
625A14A319C7829400AD0C32 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = BrainCookie;
TargetAttributes = {
625A14C219C7829400AD0C32 = {
@@ -2030,14 +2030,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 +2080,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;
@@ -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
View File
@@ -5,6 +5,7 @@
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)
[![codecov](https://codecov.io/gh/iabudiab/HTMLKit/branch/master/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)
+14 -9
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;
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.5</string>
<string>2.1.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;
}
+42 -34
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;
@@ -64,7 +68,7 @@
- (void)setOwnerDocument:(HTMLDocument *)ownerDocument
{
_ownerDocument = ownerDocument;
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[child setOwnerDocument:ownerDocument];
}
}
@@ -86,12 +90,12 @@
- (HTMLNode *)firstChild
{
return self.childNodes.firstObject;
return _childNodes.firstObject;
}
- (HTMLNode *)lastChild
{
return self.childNodes.lastObject;
return _childNodes.lastObject;
}
- (HTMLNode *)previousSibling
@@ -132,7 +136,7 @@
- (NSUInteger)index
{
return [self.parentNode indexOfChildNode:self];
return [_parentNode indexOfChildNode:self];
}
- (NSString *)textContent
@@ -156,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;
@@ -174,7 +182,7 @@
- (NSUInteger)childNodesCount
{
return self.childNodes.count;
return _childNodes.count;
}
- (BOOL)isEmpty
@@ -184,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;
@@ -216,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;
@@ -303,7 +311,7 @@
- (void)removeFromParentNode
{
[self.parentNode removeChildNode:self];
[_parentNode removeChildNode:self];
}
- (HTMLNode *)removeChildNode:(HTMLNode *)child
@@ -311,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;
@@ -335,18 +343,18 @@
- (void)reparentChildNodesIntoNode:(HTMLNode *)node
{
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[node appendNode:child];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (void)removeAllChildNodes
{
for (HTMLNode *child in self.childNodes) {
for (HTMLNode *child in _childNodes) {
[child setParentNode:nil];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
[(NSMutableOrderedSet *)_childNodes removeAllObjects];
}
- (HTMLDocumentPosition)compareDocumentPositionWithNode:(HTMLNode *)otherNode
@@ -417,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;
}
@@ -439,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);
}];
}
@@ -450,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);
}
@@ -573,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) {
@@ -623,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) {
@@ -690,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]];
}
}
+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
+15 -12
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) {
@@ -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]) {
@@ -1529,7 +1532,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 +1552,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 +1572,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 +1593,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]) {
@@ -2530,7 +2533,7 @@
return;
case HTMLTokenTypeStartTag:
{
void (^ anythingElse)() = ^ {
void (^ anythingElse)(void) = ^ {
if (self.adjustedCurrentNode.htmlNamespace == HTMLNamespaceMathML) {
AdjustMathMLAttributes(token.asTagToken);
}
@@ -2545,7 +2548,7 @@
}
};
void (^ matchedCase)() = ^ {
void (^ matchedCase)(void) = ^ {
[self emitParseError:@"Unexpected start tag <%@> in foreign content", token.asTagToken.tagName];
if (_fragmentParsingAlgorithm) {
anythingElse();
+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;
}
}
+812 -643
View File
File diff suppressed because it is too large Load Diff
+9 -9
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
+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
@@ -17,7 +17,7 @@
@param reason 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
+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
+3 -3
View File
@@ -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)
{
File diff suppressed because one or more lines are too long
+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;
+17 -13
View File
@@ -70,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) {
@@ -89,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"];
@@ -101,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)];
}
@@ -110,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;
@@ -146,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];
@@ -46,7 +46,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;
+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];