diff --git a/.gitignore b/.gitignore index 49b29bc..9e0d5ba 100644 --- a/.gitignore +++ b/.gitignore @@ -40,5 +40,7 @@ Pods/ # # Add this line if you want to avoid checking in source code from Carthage dependencies. Carthage/Checkouts +Carthage/Build -Carthage/Build \ No newline at end of file +# Jazzy +docs/ diff --git a/.gitmodules b/.gitmodules index 26a7980..e29c1b0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "HTMLKitTests/html5lib-tests"] +[submodule "html5lib-tests"] path = Tests/html5lib-tests url = https://github.com/html5lib/html5lib-tests.git diff --git a/.jazzy.yaml b/.jazzy.yaml new file mode 100644 index 0000000..9fab102 --- /dev/null +++ b/.jazzy.yaml @@ -0,0 +1,121 @@ +module: HTMLKit +module_version: 1.0.0 +author: Iskandar Abudiab +author_url: https://twitter.com/iabudiab +github_url: https://github.com/iabudiab/HTMLKit +github_file_prefix: https://github.com/iabudiab/HTMLKit/tree/master +output: docs +umbrella_header: Sources/include/HTMLKit.h +clean: true +objc: true +skip_undocumented: true + +custom_categories: + - name: Parsing + children: + - HTMLParser + + - name: DOM + children: + - HTMLNamespace + - HTMLNode + - HTMLNodeType + - HTMLElement + - HTMLDocument + - HTMLDocumentReadyState + - HTMLQuirksMode + - HTMLDocumentType + - HTMLDocumentFragment + - HTMLDocumentPosition + - HTMLText + - HTMLComment + - HTMLTemplate + - HTMLDOMTokenList + + - name: Iteration & Filtering + children: + - HTMLNodeIterator + - HTMLNodeFilter + - HTMLNodeFilterShowOptions + - HTMLNodeFilterValue + - HTMLNodeFilterBlock + - HTMLSelectorNodeFilter + - HTMLTreeWalker + + - name: Structures + children: + - HTMLOrderedDictionary + - CSSNthExpression + + - name: CSS Selectors Implementation + children: + - CSSSelector + - CSSSelectorParser + - CSSTypeSelector + - CSSAttributeSelector + - CSSNthExpressionParser + - CSSNthExpressionSelector + - CSSPseudoClassSelector + - CSSPseudoFunctionSelector + - CSSSelectorBlock + - CSSCombinatorSelector + - CSSCompoundSelector + + - name: Typed Selectors and Extensions + children: + - adjacentSiblingSelector + - allOf + - anyOf + - attributeSelector + - buttonSelector + - checkboxSelector + - checkedSelector + - childOfElementSelector + - classSelector + - descendantOfElementSelector + - disabledSelector + - emptySelector + - enabledSelector + - eqSelector + - evenSlector + - fileSelector + - firstChildSelector + - firstOfTypeSelector + - generalSiblingSelector + - gtSelector + - has + - hasAttributeSelector + - headerSelector + - idSelector + - imageSelector + - inputSelector + - lastChildSelector + - lastOfTypeSelector + - linkSelector + - ltSelector + - namedBlockSelector + - namedPseudoSelector + - not + - nthChildSelector + - nthLastChildSelector + - nthLastOfTypeSelector + - nthOfTypeSelector + - oddSelector + - onlyChildSelector + - onlyOfTypeSelector + - optionalSelector + - parentSelector + - passwordSelector + - radioSelector + - requiredSelector + - resetSelector + - rootSelector + - submitSelector + - textSelector + - typeSelector + - universalSelector + + - name: Categories + children: + - NSCharacterSet(HTMLKit) + - NSString(HTMLKit) diff --git a/.travis.yml b/.travis.yml index 1767886..095d84f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode7.3 +osx_image: xcode8 branches: except: @@ -14,21 +14,24 @@ env: - LANG=en_US.UTF-8 - WORKSPACE=HTMLKit.xcworkspace - IOS_FRAMEWORK_SCHEME=HTMLKit-iOS - - OSX_FRAMEWORK_SCHEME=HTMLKit-OSX + - MACOS_FRAMEWORK_SCHEME=HTMLKit-macOS - WATCHOS_FRAMEWORK_SCHEME="HTMLKit-watchOS" - TVOS_FRAMEWORK_SCHEME="HTMLKit-tvOS" - - IOS_SDK=iphonesimulator9.3 - - OSX_SDK=macosx10.11 - - WATCHOS_SDK=watchsimulator2.2 - - TVOS_SDK=appletvsimulator9.2 + - IOS_SDK=iphonesimulator10.0 + - MACOS_SDK=macosx10.12 + - WATCHOS_SDK=watchsimulator3.0 + - TVOS_SDK=appletvsimulator10.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="arch=x86_64" SIMULATOR="" SCHEME="$OSX_FRAMEWORK_SCHEME" SDK="$OSX_SDK" - - DESTINATION="OS=2.2,name=Apple Watch - 42mm" SIMULATOR="Apple Watch - 42mm (2.2)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK" - - DESTINATION="OS=9.2,name=Apple TV 1080p" SIMULATOR="Apple TV 1080p (9.2)" SCHEME="$TVOS_FRAMEWORK_SCHEME" SDK="$TVOS_SDK" + - DESTINATION="OS=10.0,name=iPhone 7 Plus" SIMULATOR="iPhone 7 Plus (10.0)" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" + - DESTINATION="OS=2.0,name=Apple Watch - 42mm" SIMULATOR="Apple Watch - 42mm (2.2)" SCHEME="$WATCHOS_FRAMEWORK_SCHEME" SDK="$WATCHOS_SDK" + - DESTINATION="OS=3.0,name=Apple Watch - 42mm" SIMULATOR="Apple Watch - 42mm (3.0)" 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" script: - set -o pipefail diff --git a/CHANGELOG.md b/CHANGELOG.md index fd27981..6e8cb29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Change Log +## [1.0.0](https://github.com/iabudiab/HTMLKit/releases/tag/1.0.0) + +Released on 2016.09.28 + +### Added + +- Jazzy configuration file +- Example HTMLKit project + +### Updated + +- Project for Xcode 8 +- Playground syntax for Swift 3 +- Travis config for iOS 10.0, macOS 10.12, tvOS 10.0 and watchOS 3.0 +- Deployment targets to macOS 10.9, iOS 9.0, tvOS 9.0 and watchOS 2.0 + +### Fixed + +- Nullability annotation in `CSSSelectorParser` class +- Missing lightweight generics in `HTMLParser`, `HTMLNode` & `HTMLElement` + ## [0.9.4](https://github.com/iabudiab/HTMLKit/releases/tag/0.9.4) Released on 2016.09.03 @@ -49,7 +70,6 @@ This release passes all tokenizer and tree construction html5lib-tests as of 201 - Parser now checks the qualified name instead of the local name when handling elements in the `MathML` and `SVG` namespaces - ## [0.9.1](https://github.com/iabudiab/HTMLKit/releases/tag/0.9.1) Released on 2016.01.29 @@ -59,7 +79,6 @@ Released on 2016.01.29 - Travis-CI integration. - CocoaPods spec. - ### Changed - Warnings are treated as errors. @@ -91,7 +110,6 @@ This is the first public release of `HTMLKit`. - Unused namespaces. - Historical node types. - ### Fixed - `lt`, `gt` & `eq` CSS Selectors method declarations. diff --git a/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.pbxproj b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e6f0864 --- /dev/null +++ b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.pbxproj @@ -0,0 +1,257 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 629A63CD1D9AFE0E0089679F /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 629A63CC1D9AFE0E0089679F /* main.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 629A63C71D9AFE0E0089679F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 629A63C91D9AFE0E0089679F /* HTMLKitExample */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = HTMLKitExample; sourceTree = BUILT_PRODUCTS_DIR; }; + 629A63CC1D9AFE0E0089679F /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 629A63C61D9AFE0E0089679F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 629A63C01D9AFE0E0089679F = { + isa = PBXGroup; + children = ( + 629A63CB1D9AFE0E0089679F /* HTMLKitExample */, + 629A63CA1D9AFE0E0089679F /* Products */, + ); + sourceTree = ""; + }; + 629A63CA1D9AFE0E0089679F /* Products */ = { + isa = PBXGroup; + children = ( + 629A63C91D9AFE0E0089679F /* HTMLKitExample */, + ); + name = Products; + sourceTree = ""; + }; + 629A63CB1D9AFE0E0089679F /* HTMLKitExample */ = { + isa = PBXGroup; + children = ( + 629A63CC1D9AFE0E0089679F /* main.swift */, + ); + path = HTMLKitExample; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 629A63C81D9AFE0E0089679F /* HTMLKitExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 629A63D01D9AFE0E0089679F /* Build configuration list for PBXNativeTarget "HTMLKitExample" */; + buildPhases = ( + 629A63C51D9AFE0E0089679F /* Sources */, + 629A63C61D9AFE0E0089679F /* Frameworks */, + 629A63C71D9AFE0E0089679F /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HTMLKitExample; + productName = HTMLKitExample; + productReference = 629A63C91D9AFE0E0089679F /* HTMLKitExample */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 629A63C11D9AFE0E0089679F /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = iabudiab; + TargetAttributes = { + 629A63C81D9AFE0E0089679F = { + CreatedOnToolsVersion = 8.0; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 629A63C41D9AFE0E0089679F /* Build configuration list for PBXProject "HTMLKitExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 629A63C01D9AFE0E0089679F; + productRefGroup = 629A63CA1D9AFE0E0089679F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 629A63C81D9AFE0E0089679F /* HTMLKitExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 629A63C51D9AFE0E0089679F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 629A63CD1D9AFE0E0089679F /* main.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 629A63CE1D9AFE0E0089679F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 629A63CF1D9AFE0E0089679F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 629A63D11D9AFE0E0089679F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 629A63D21D9AFE0E0089679F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 629A63C41D9AFE0E0089679F /* Build configuration list for PBXProject "HTMLKitExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 629A63CE1D9AFE0E0089679F /* Debug */, + 629A63CF1D9AFE0E0089679F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 629A63D01D9AFE0E0089679F /* Build configuration list for PBXNativeTarget "HTMLKitExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 629A63D11D9AFE0E0089679F /* Debug */, + 629A63D21D9AFE0E0089679F /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 629A63C11D9AFE0E0089679F /* Project object */; +} diff --git a/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..8a71bc6 --- /dev/null +++ b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example/HTMLKitExample/HTMLKitExample.xcodeproj/xcshareddata/xcschemes/HTMLKitExample.xcscheme b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/xcshareddata/xcschemes/HTMLKitExample.xcscheme new file mode 100644 index 0000000..d48b587 --- /dev/null +++ b/Example/HTMLKitExample/HTMLKitExample.xcodeproj/xcshareddata/xcschemes/HTMLKitExample.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/HTMLKitExample/HTMLKitExample/main.swift b/Example/HTMLKitExample/HTMLKitExample/main.swift new file mode 100644 index 0000000..2e51ce9 --- /dev/null +++ b/Example/HTMLKitExample/HTMLKitExample/main.swift @@ -0,0 +1,167 @@ +// +// main.swift +// HTMLKitExample +// +// Created by Iska on 27/09/16. +// Copyright © 2016 iabudiab. All rights reserved. +// + +import HTMLKit + +// Simple scraper that is able to load a page, query via CSS Selectors, and following links +class Scraper { + + enum ScrapingError: Error { + case DocumentNotLoaded + case ElementNotFound(String) + case InvalidAnchorUrl(String) + case CouldNotLoadPage(URL) + } + + private var url: URL + private(set) var document: HTMLDocument? + + init(url: URL) { + self.url = url + self.document = nil + } + + func load() throws { + try loadDocument(at: url) + } + + func listElements(matching selector: CSSSelector) throws -> [HTMLElement] { + guard let document = document else { + throw ScrapingError.DocumentNotLoaded + } + + return document.elements(matching: selector) + } + + func followLink(matchingSelector selector: CSSSelector) throws { + guard let document = document else { + throw ScrapingError.DocumentNotLoaded + } + + guard let link = document.firstElement(matching: selector) else { + throw ScrapingError.ElementNotFound(selector.debugDescription) + } + + guard let targetUrl = URL(string: link["href"], relativeTo: url) else { + throw ScrapingError.InvalidAnchorUrl(link["href"]) + } + + try loadDocument(at: targetUrl) + } + + private func loadDocument(at url: URL) throws { + guard let content = try? String(contentsOf: url) else { + throw ScrapingError.CouldNotLoadPage(url) + } + document = HTMLDocument(string: content) + } +} + +// A custom block-based selector, that matches only elements having the given text content: +// i.e. textContentSelector("Hello") will match

Hello

and Hello +// but wont match
World
or

Hello there

+func textContentSelector(text: String) -> CSSSelector { + return namedBlockSelector("[@textContent='\(text)']") { (element) -> Bool in + return element.textContent == text + } +} + +// Helper function to create a typed-selector matching an anchor element that has the given +// text content. +func anchorElement(havingContent: String) -> CSSSelector { + return allOf( + [ + typeSelector("a"), + textContentSelector(text: havingContent) + ] + ) +} + +// Helper function to print the content of a github repository file content +func printRepositoryFile(element: HTMLElement) { + + // A node iterator filter that iterates only elements of class "content" i.e. + let contentIterator = element.nodeIterator(showOptions: .element) { (node) -> HTMLNodeFilterValue in + guard let element = node as? HTMLElement else { return .reject } + + if element.tagName == "td" && element["class"] == "content" { + return .accept + } + + return .reject + } + + for td in contentIterator { + // The cast is necessary because Swift3 wont import the generics info of the NSEnumerator class + // i.e. the nextObject() function alwasy has the following signature 'func nextObject() -> Any?' + let title = (td as AnyObject).textContent.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) + print("- \(title)") + } +} + +let htmlKitUrl = URL(string: "https://github.com/iabudiab/HTMLKit")! +let scraper = Scraper(url: htmlKitUrl) + +do { + // Load the page + try scraper.load() + + // Parse the selector + let repositoryContent = try CSSSelectorParser.parseSelector("[role='main'] .repository-content > .file-wrap > .files tr.js-navigation-item") + + // Query matching elements + let files = try scraper.listElements(matching: repositoryContent) + + print("HTMLKit repositroy root:") + files.forEach(printRepositoryFile) +} catch let error { + print(error) +} + +do { + // Follow some links + try scraper.followLink(matchingSelector: anchorElement(havingContent: "Sources")) + try scraper.followLink(matchingSelector: anchorElement(havingContent: "HTMLEOFToken.m")) + + // The following selector: "[role='main'] div.file table.js-file-line-container td:nth-child(2)" + // can be defined in type-safe manner: + let selector = allOf([ + descendantOfElementSelector( + attributeSelector(.exactMatch, "role", "main") + ), + descendantOfElementSelector( + allOf([ + typeSelector("div"), + classSelector("file") + ]) + ), + descendantOfElementSelector( + allOf([ + typeSelector("table"), + classSelector("js-file-line-container") + ]) + ), + typeSelector("td"), + nthChildSelector( + CSSNthExpressionMake(0, 2) + ) + ]) + + // Query matching elements + let elements = try scraper.listElements(matching: selector) + + // This will print the source code for the "HTMLEOFToken.m" file under this url: + // https://github.com/iabudiab/HTMLKit/blob/master/Sources/HTMLEOFToken.m + + print("\nHTMLEOFToken:") + elements.forEach { + print($0.textContent) + } +} catch let error { + print(error) +} diff --git a/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift index 3a4b40f..0315850 100644 --- a/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift +++ b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift @@ -28,22 +28,22 @@ var nonParagraphChildOfDiv = document.querySelectorAll("div :not(p)") /*: HTMLKit also provides API to create selector instances in a type-safe manner without the need to parse them first. The previous examples would like this: */ -paragraphs = document.elementsMatchingSelector(typeSelector("p")) -paragraphsOrHeaders = document.elementsMatchingSelector( +paragraphs = document.elements(matching: typeSelector("p")) +paragraphsOrHeaders = document.elements(matching: anyOf([ typeSelector("p"), typeSelector("h1") ]) ) -hasClassAttribute = document.elementsMatchingSelector(hasAttributeSelector("class")) -greetings = document.elementsMatchingSelector(classSelector("greeting")) -classNameStartsWith_de = document.elementsMatchingSelector(attributeSelector(.Begins, "class", "de")) +hasClassAttribute = document.elements(matching: hasAttributeSelector("class")) +greetings = document.elements(matching: classSelector("greeting")) +classNameStartsWith_de = document.elements(matching: attributeSelector(.begins, "class", "de")) -hasAdjacentHeader = document.elementsMatchingSelector(adjacentSiblingSelector(typeSelector("h1"))) -hasAdjacentHeader = document.elementsMatchingSelector(generalSiblingSelector(typeSelector("h1"))) -hasAdjacentHeader = document.elementsMatchingSelector(generalSiblingSelector(typeSelector("p"))) +hasAdjacentHeader = document.elements(matching: adjacentSiblingSelector(typeSelector("h1"))) +hasAdjacentHeader = document.elements(matching: generalSiblingSelector(typeSelector("h1"))) +hasAdjacentHeader = document.elements(matching: generalSiblingSelector(typeSelector("p"))) -nonParagraphChildOfDiv = document.elementsMatchingSelector( +nonParagraphChildOfDiv = document.elements(matching: allOf([ childOfElementSelector(typeSelector("div")), not(typeSelector("p")) @@ -54,17 +54,17 @@ nonParagraphChildOfDiv = document.elementsMatchingSelector( Here are more examples */ -let firstDivElement = document.firstElementMatchingSelector(typeSelector("div"))! +let firstDivElement = document.firstElement(matching: typeSelector("div"))! var secondChildOfDiv = firstDivElement.querySelectorAll(":nth-child(2)") var secondOfType = firstDivElement.querySelectorAll(":nth-of-type(2n)") -secondChildOfDiv = firstDivElement.elementsMatchingSelector(nthChildSelector(CSSNthExpression(an: 0, b: 2))) -secondOfType = firstDivElement.elementsMatchingSelector(nthOfTypeSelector(CSSNthExpression(an: 2, b: 0))) +secondChildOfDiv = firstDivElement.elements(matching: nthChildSelector(CSSNthExpression(an: 0, b: 2))) +secondOfType = firstDivElement.elements(matching: nthOfTypeSelector(CSSNthExpression(an: 2, b: 0))) var notParagraphAndNotDiv = firstDivElement.querySelectorAll(":not(p):not(div)") -notParagraphAndNotDiv = firstDivElement.elementsMatchingSelector( +notParagraphAndNotDiv = firstDivElement.elements(matching: allOf([ not(typeSelector("p")), not(typeSelector("div")) @@ -77,4 +77,4 @@ One more thing! You can also create your own selectors. You either subclass the let myAwesomeSelector = namedBlockSelector("myAwesomeSelector", { (element) -> Bool in return element.tagName != "p" && element.tagName != "div" }) -firstDivElement.elementsMatchingSelector(myAwesomeSelector) +firstDivElement.elements(matching: myAwesomeSelector) diff --git a/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/timeline.xctimeline deleted file mode 100644 index bf468af..0000000 --- a/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/timeline.xctimeline +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift index 6b752a4..2e53331 100644 --- a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift +++ b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift @@ -9,7 +9,8 @@ import HTMLKit Given some HTML content */ -let htmlString = try! String(contentsOfURL: [#FileReference(fileReferenceLiteral: "HTMLKit.html")#]) +let htmlString = "

HTMLKit

Hello there!

This is a demo of HTMLKit

" +htmlString /*: You can parse it using the HTMLParser: diff --git a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline index c5cb40d..a1e8da4 100644 --- a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline +++ b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline @@ -3,10 +3,20 @@ version = "3.0"> + + + + diff --git a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift index 37713c2..08dc5b1 100644 --- a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift +++ b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift @@ -18,7 +18,7 @@ You can prase it as a document fragment in a specified context element: let parser = HTMLParser(string: htmlString) let tableContext = HTMLElement(tagName: "table") -var elements = parser.parseFragmentWithContextElement(tableContext) +var elements = parser.parseFragment(withContextElement: tableContext) for element in elements { print(element.outerHTML) @@ -29,7 +29,7 @@ The same parser instance can be reusued: */ let bodyContext = HTMLElement(tagName: "body") -elements = parser.parseFragmentWithContextElement(bodyContext) +elements = parser.parseFragment(withContextElement: bodyContext) for element in elements { print(element.outerHTML) diff --git a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline index 43c4189..f4d8ea9 100644 --- a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline +++ b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline @@ -21,13 +21,13 @@ shouldTrackSuperviewWidth = "YES"> @@ -39,7 +39,7 @@ shouldTrackSuperviewWidth = "NO"> diff --git a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift index a67a13f..224ff28 100644 --- a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift +++ b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift @@ -21,7 +21,7 @@ description["content"] = "HTMLKit for iOS & OSX" Append nodes to the document */ let head = document.head! -head.appendNode(description) +head.append(description) document.innerHTML let body = document.body! @@ -30,17 +30,17 @@ let nodes = [ HTMLElement(tagName: "div", attributes: ["class": "green"]), HTMLElement(tagName: "div", attributes: ["class": "blue"]) ] -body.appendNodes(nodes) +body.append(nodes) body.innerHTML /*: Enumerate child elements and perform DOM manipulation */ -body.enumerateChildElementsUsingBlock { (element, index, stop) -> Void in +body.enumerateChildElements { (element, index, stop) -> Void in if element.tagName == "div" { let lorem = HTMLElement(tagName: "p") lorem.textContent = "Lorem ipsum: \(index)" - element.appendNode(lorem) + element.append(lorem) } } body.innerHTML @@ -48,7 +48,7 @@ body.innerHTML /*: Remove nodes from the document */ -body.removeChildNodeAtIndex(1) +body.removeChildNode(at: 1) body.innerHTML /*: @@ -56,24 +56,26 @@ Navigate to child and sibling nodes */ body.lastChild!.removeFromParentNode() let greenDiv = body.firstChild!.nextSibling! +greenDiv.outerHTML /*: Manipulate the HTML directly */ greenDiv.innerHTML = "
  • item 1
  • item 2" +greenDiv.outerHTML /*: Iterate the DOM tree with custom filters */ -let filter = HTMLNodeFilterBlock.filterWithBlock { (node) -> HTMLNodeFilterValue in +let filter = HTMLNodeFilterBlock.filter { (node) -> HTMLNodeFilterValue in if node.childNodesCount() != 1 { - return .Reject + return .reject } - return .Accept + return .accept } -for element in body.nodeIteratorWithShowOptions(.Element, filter: filter) { - element.outerHTML +for element in body.nodeIterator(showOptions: .element, filter: filter) { + (element as! AnyObject).outerHTML } //: [Next](@next) diff --git a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline index cebe428..33cfccb 100644 --- a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline +++ b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline @@ -3,71 +3,65 @@ version = "3.0"> - - - - + + + + diff --git a/HTMLKit.playground/Resources/HTMLKit.html b/HTMLKit.playground/Resources/HTMLKit.html deleted file mode 100644 index a9ca358..0000000 --- a/HTMLKit.playground/Resources/HTMLKit.html +++ /dev/null @@ -1,11 +0,0 @@ - - - HTMLKit - - -

    HTMLKit

    -

    HTMLKit is a WHATWG specification-compliant Objective-C framework for parsing and serializing HTML documents and document fragments for iOS and OSX.

    -

    HTMLKit parses real-world HTML the same way modern web browsers would.

    -

    HTMLKit comes armed with a CSS3 Selectors engine for querying the DOM.

    - - diff --git a/HTMLKit.playground/contents.xcplayground b/HTMLKit.playground/contents.xcplayground index d961153..0491d26 100644 --- a/HTMLKit.playground/contents.xcplayground +++ b/HTMLKit.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/HTMLKit.podspec b/HTMLKit.podspec index f3a45c6..8025949 100644 --- a/HTMLKit.podspec +++ b/HTMLKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "HTMLKit" - s.version = "0.9.4" + s.version = "1.0.0" s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs." s.license = "MIT" s.homepage = "https://github.com/iabudiab/HTMLKit" diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index efed1e3..000f546 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -623,7 +623,7 @@ 625A14B419C7829400AD0C32 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 625A14B719C7829400AD0C32 /* HTMLKit-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HTMLKit-Info.plist"; sourceTree = ""; }; 625A14BC19C7829400AD0C32 /* HTMLKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HTMLKit.h; path = include/HTMLKit.h; sourceTree = ""; }; - 625A14C319C7829400AD0C32 /* HTMLKitTests-OSX.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HTMLKitTests-OSX.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 625A14C319C7829400AD0C32 /* HTMLKitTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HTMLKitTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 625A14C419C7829400AD0C32 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 625A14CC19C7829400AD0C32 /* HTMLKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HTMLKitTests-Info.plist"; sourceTree = ""; }; 625A14DF19C7834100AD0C32 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -854,7 +854,7 @@ isa = PBXGroup; children = ( 625A14AC19C7829400AD0C32 /* HTMLKit.framework */, - 625A14C319C7829400AD0C32 /* HTMLKitTests-OSX.xctest */, + 625A14C319C7829400AD0C32 /* HTMLKitTests-macOS.xctest */, 62ECBF4D1C0B6C7600AF847B /* HTMLKit.framework */, 62ECBF561C0B6C7600AF847B /* HTMLKitTests-iOS.xctest */, 62857C4E1D398642008DC254 /* HTMLKit.framework */, @@ -1335,9 +1335,9 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 625A14AB19C7829400AD0C32 /* HTMLKit-OSX */ = { + 625A14AB19C7829400AD0C32 /* HTMLKit-macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 625A14D419C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKit-OSX" */; + buildConfigurationList = 625A14D419C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKit-macOS" */; buildPhases = ( 625A14A719C7829400AD0C32 /* Sources */, 625A14A819C7829400AD0C32 /* Frameworks */, @@ -1348,14 +1348,14 @@ ); dependencies = ( ); - name = "HTMLKit-OSX"; + name = "HTMLKit-macOS"; productName = HTMLKit; productReference = 625A14AC19C7829400AD0C32 /* HTMLKit.framework */; productType = "com.apple.product-type.framework"; }; - 625A14C219C7829400AD0C32 /* HTMLKitTests-OSX */ = { + 625A14C219C7829400AD0C32 /* HTMLKitTests-macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 625A14D719C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKitTests-OSX" */; + buildConfigurationList = 625A14D719C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKitTests-macOS" */; buildPhases = ( 625A14BF19C7829400AD0C32 /* Sources */, 625A14C019C7829400AD0C32 /* Frameworks */, @@ -1366,9 +1366,9 @@ dependencies = ( 625A14C819C7829400AD0C32 /* PBXTargetDependency */, ); - name = "HTMLKitTests-OSX"; + name = "HTMLKitTests-macOS"; productName = HTMLKitTests; - productReference = 625A14C319C7829400AD0C32 /* HTMLKitTests-OSX.xctest */; + productReference = 625A14C319C7829400AD0C32 /* HTMLKitTests-macOS.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 62857C4D1D398642008DC254 /* HTMLKit-watchOS */ = { @@ -1467,7 +1467,7 @@ 625A14A319C7829400AD0C32 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = BrainCookie; TargetAttributes = { 625A14C219C7829400AD0C32 = { @@ -1506,8 +1506,8 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 625A14AB19C7829400AD0C32 /* HTMLKit-OSX */, - 625A14C219C7829400AD0C32 /* HTMLKitTests-OSX */, + 625A14AB19C7829400AD0C32 /* HTMLKit-macOS */, + 625A14C219C7829400AD0C32 /* HTMLKitTests-macOS */, 62ECBF4C1C0B6C7600AF847B /* HTMLKit-iOS */, 62ECBF551C0B6C7600AF847B /* HTMLKitTests-iOS */, 62857CE91D39A262008DC254 /* HTMLKit-tvOS */, @@ -1882,7 +1882,7 @@ /* Begin PBXTargetDependency section */ 625A14C819C7829400AD0C32 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 625A14AB19C7829400AD0C32 /* HTMLKit-OSX */; + target = 625A14AB19C7829400AD0C32 /* HTMLKit-macOS */; targetProxy = 625A14C719C7829400AD0C32 /* PBXContainerItemProxy */; }; 62857CF61D39A262008DC254 /* PBXTargetDependency */ = { @@ -1911,14 +1911,19 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -1950,14 +1955,19 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -1983,8 +1993,11 @@ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "Sources/HTMLKit-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; PRODUCT_BUNDLE_IDENTIFIER = de.iabudiab.HTMLKit; PRODUCT_NAME = HTMLKit; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -2003,8 +2016,11 @@ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "Sources/HTMLKit-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; PRODUCT_BUNDLE_IDENTIFIER = de.iabudiab.HTMLKit; PRODUCT_NAME = HTMLKit; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; WRAPPER_EXTENSION = framework; }; name = Release; @@ -2025,9 +2041,12 @@ "$(inherited)", ); INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; WRAPPER_EXTENSION = xctest; }; name = Debug; @@ -2044,9 +2063,12 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ""; INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; WRAPPER_EXTENSION = xctest; }; name = Release; @@ -2057,6 +2079,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; @@ -2091,6 +2114,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -2127,6 +2151,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; @@ -2161,6 +2186,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -2198,12 +2224,14 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.HTMLKit-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; @@ -2216,13 +2244,15 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.HTMLKit-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.2; + TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; @@ -2231,7 +2261,7 @@ buildSettings = { CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; @@ -2255,8 +2285,10 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; @@ -2265,7 +2297,7 @@ buildSettings = { CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -2289,9 +2321,11 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; @@ -2304,12 +2338,14 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.HTMLKit-iOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; + TVOS_DEPLOYMENT_TARGET = 9.0; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; @@ -2322,13 +2358,15 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Tests/HTMLKitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "de.iabudiab.HTMLKit-iOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; + TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; @@ -2344,7 +2382,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 625A14D419C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKit-OSX" */ = { + 625A14D419C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKit-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 625A14D519C7829400AD0C32 /* Debug */, @@ -2353,7 +2391,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 625A14D719C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKitTests-OSX" */ = { + 625A14D719C7829400AD0C32 /* Build configuration list for PBXNativeTarget "HTMLKitTests-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 625A14D819C7829400AD0C32 /* Debug */, diff --git a/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-iOS.xcscheme b/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-iOS.xcscheme index 55ae98a..23693ab 100644 --- a/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-iOS.xcscheme +++ b/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-iOS.xcscheme @@ -1,6 +1,6 @@ @@ -33,8 +33,8 @@ @@ -58,7 +58,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "625A14AB19C7829400AD0C32" BuildableName = "HTMLKit.framework" - BlueprintName = "HTMLKit-OSX" + BlueprintName = "HTMLKit-macOS" ReferencedContainer = "container:HTMLKit.xcodeproj"> @@ -80,7 +80,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "625A14AB19C7829400AD0C32" BuildableName = "HTMLKit.framework" - BlueprintName = "HTMLKit-OSX" + BlueprintName = "HTMLKit-macOS" ReferencedContainer = "container:HTMLKit.xcodeproj"> @@ -98,7 +98,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "625A14AB19C7829400AD0C32" BuildableName = "HTMLKit.framework" - BlueprintName = "HTMLKit-OSX" + BlueprintName = "HTMLKit-macOS" ReferencedContainer = "container:HTMLKit.xcodeproj"> diff --git a/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-tvOS.xcscheme b/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-tvOS.xcscheme index ed21d23..883c1b3 100644 --- a/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-tvOS.xcscheme +++ b/HTMLKit.xcodeproj/xcshareddata/xcschemes/HTMLKit-tvOS.xcscheme @@ -1,6 +1,6 @@ + + diff --git a/Sources/HTMLKit-Info.plist b/Sources/HTMLKit-Info.plist index 0f7490b..ecef4c7 100644 --- a/Sources/HTMLKit-Info.plist +++ b/Sources/HTMLKit-Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.4 + 1.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Sources/include/CSSSelectorParser.h b/Sources/include/CSSSelectorParser.h index 5f43675..efe8633 100644 --- a/Sources/include/CSSSelectorParser.h +++ b/Sources/include/CSSSelectorParser.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN @see CSSelector */ -+ (CSSSelector *)parseSelector:(NSString *)string error:(NSError **)error; ++ (nullable CSSSelector *)parseSelector:(NSString *)string error:(NSError **)error; @end diff --git a/Sources/include/HTMLElement.h b/Sources/include/HTMLElement.h index 0975bc2..dcf5372 100644 --- a/Sources/include/HTMLElement.h +++ b/Sources/include/HTMLElement.h @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN /** The element's attribites. */ -@property (nonatomic, strong) NSMutableDictionary *attributes; +@property (nonatomic, strong) NSMutableDictionary *attributes; /** @warning Use one of the initWithTagName: methods instead. @@ -75,7 +75,7 @@ NS_ASSUME_NONNULL_BEGIN @param attributes The attributes. @return A new HTML element. */ -- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes; +- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes; /** Initializes a new HTML element with the given tag name, namespace, and attributes. @@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN @param attributes The attributes. @return A new HTML element. */ -- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary *)attributes; +- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary *)attributes; /** Checks whether this element has an attribute with the given name. diff --git a/Sources/include/HTMLNode.h b/Sources/include/HTMLNode.h index dc22705..da1a5c5 100644 --- a/Sources/include/HTMLNode.h +++ b/Sources/include/HTMLNode.h @@ -86,7 +86,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) /** A read-only ordered set of child nodes. */ -@property (nonatomic, strong, readonly) NSOrderedSet *childNodes; +@property (nonatomic, strong, readonly) NSOrderedSet *childNodes; /** The first child node, if any. @@ -220,7 +220,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) @param node The nodes to prepend. */ -- (void)prependNodes:(NSArray *)nodes; +- (void)prependNodes:(NSArray *)nodes; /** Appends the given node to the set of child nodes. @@ -235,7 +235,7 @@ typedef NS_ENUM(unsigned short, HTMLDocumentPosition) @param nodes The nodes to append. */ -- (void)appendNodes:(NSArray *)nodes; +- (void)appendNodes:(NSArray *)nodes; /** Inserts a given node before a child node. diff --git a/Sources/include/HTMLParser.h b/Sources/include/HTMLParser.h index 18858e8..d5fe596 100644 --- a/Sources/include/HTMLParser.h +++ b/Sources/include/HTMLParser.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN /** An array of errors that occurred during document parsing. */ -@property (nonatomic, strong, readonly) NSArray *parseErrors; +@property (nonatomic, strong, readonly) NSArray *parseErrors; /** The parsed HTML Document. @@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN @see HTMLElement */ -- (NSArray *)parseFragmentWithContextElement:(HTMLElement *)contextElement; +- (NSArray *)parseFragmentWithContextElement:(HTMLElement *)contextElement; @end