diff --git a/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..a363d85 --- /dev/null +++ b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift @@ -0,0 +1,80 @@ +//: [Previous](@previous) +/*: +# CSS3 Selectors + +HTMLKit understands CSS3 selectors making node-selection a piece of cake: +*/ + +import HTMLKit + +let htmlString = "

HTMLKit

Hello there!

This is a demo of HTMLKit

" +let document = HTMLDocument(string: htmlString) + +/*: +All CSS3 selectors are supported and you use them the way you always have: +*/ +var paragraphs = document.querySelectorAll("p") +var paragraphsOrHeaders = document.querySelectorAll("p, h1") +var hasClassAttribute = document.querySelectorAll("[class]") +var greetings = document.querySelectorAll(".greeting") +var classNameStartsWith_de = document.querySelectorAll("[class^='de']") + +var hasAdjacentHeader = document.querySelectorAll("h1 + *") +var hasSiblingHeader = document.querySelectorAll("h1 ~ *") +var hasSiblingParagraph = document.querySelectorAll("p ~ *") + +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( + anyOf([ + typeSelector("p"), typeSelector("h1") + ]) +) + +hasClassAttribute = document.elementsMatchingSelector(hasAttributeSelector("class")) +greetings = document.elementsMatchingSelector(classSelector("greeting")) +classNameStartsWith_de = document.elementsMatchingSelector(attributeSelector(.Begins, "class", "de")) + +hasAdjacentHeader = document.elementsMatchingSelector(adjacentSiblingSelector(typeSelector("h1"))) +hasAdjacentHeader = document.elementsMatchingSelector(generalSiblingSelector(typeSelector("h1"))) +hasAdjacentHeader = document.elementsMatchingSelector(generalSiblingSelector(typeSelector("p"))) + +nonParagraphChildOfDiv = document.elementsMatchingSelector( + allOf([ + childOfElementSelector(typeSelector("div")), + nay(typeSelector("p")) + ]) +) + +/*: +Here are more examples +*/ + +let firstDivElement = document.firstElementMatchingSelector(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))) + + +var notParagraphAndNotDiv = firstDivElement.querySelectorAll(":not(p):not(div)") +notParagraphAndNotDiv = firstDivElement.elementsMatchingSelector( + allOf([ + nay(typeSelector("p")), + nay(typeSelector("div")) + ]) +) + +/*: +One more thing! You can also create your own selectors. You either subclass the CSSSelector or just use the block-based wrapper. For example the previous selector can be implemented like this: +*/ +let myAwesomeSelector = namedBlockSelector("myAwesomeSelector", { (element) -> Bool in + return element.tagName != "p" && element.tagName != "div" +}) +firstDivElement.elementsMatchingSelector(myAwesomeSelector) diff --git a/HTMLKit.playground/Pages/Demo.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/timeline.xctimeline similarity index 100% rename from HTMLKit.playground/Pages/Demo.xcplaygroundpage/timeline.xctimeline rename to HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/timeline.xctimeline diff --git a/HTMLKit.playground/Pages/Demo.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Demo.xcplaygroundpage/Contents.swift deleted file mode 100644 index e69de29..0000000 diff --git a/HTMLKit.playground/Pages/Intro.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Intro.xcplaygroundpage/Contents.swift index 3573c6e..439965b 100644 --- a/HTMLKit.playground/Pages/Intro.xcplaygroundpage/Contents.swift +++ b/HTMLKit.playground/Pages/Intro.xcplaygroundpage/Contents.swift @@ -3,11 +3,28 @@ ![Logo](HTMLKit.png) -> An Objective-C kit for your everyday HTML needs. - -HTMLKit is a [WHATWG](https://html.spec.whatwg.org/multipage/) specification-compliant library for parsing and serializing HTML documents and document fragments for OSX and iOS. HTMLKit parses real-world HTML the same way modern web browsers would. - -> HTMLKit is available under the MIT license. **** + +An Objective-C kit for your everyday HTML needs. + +**** + +HTMLKit is a [WHATWG](https://html.spec.whatwg.org/multipage/) specification-compliant 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 is available under the MIT License + +**** + +# Table of Contents + +- [Parsing Document](Parsing%20Documents) +- [Parsing Fragments](Parsing%20Fragments) +- [The DOM](The%20DOM) +- [CSS Selectors](CSS%20Selectors) + +**** + [Next](@next) */ diff --git a/HTMLKit.playground/Pages/Intro.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/Intro.xcplaygroundpage/timeline.xctimeline index 4e83cee..7a7fb84 100644 --- a/HTMLKit.playground/Pages/Intro.xcplaygroundpage/timeline.xctimeline +++ b/HTMLKit.playground/Pages/Intro.xcplaygroundpage/timeline.xctimeline @@ -3,22 +3,22 @@ version = "3.0"> diff --git a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..6b752a4 --- /dev/null +++ b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift @@ -0,0 +1,29 @@ +//: [Previous](@previous) +/*: +# Parsing HTML Documents +*/ + +import HTMLKit + +/*: +Given some HTML content +*/ + +let htmlString = try! String(contentsOfURL: [#FileReference(fileReferenceLiteral: "HTMLKit.html")#]) + +/*: +You can parse it using the HTMLParser: +*/ + +let parser = HTMLParser(string: htmlString) +let documentViaParser = parser.parseDocument() +documentViaParser.innerHTML + +/*: +You can also create a document from a given HTML string directly: +*/ + +let document = HTMLDocument(string: htmlString) +document.innerHTML + +//: [Next](@next) diff --git a/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..c5cb40d --- /dev/null +++ b/HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,12 @@ + + + + + + + diff --git a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..37713c2 --- /dev/null +++ b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift @@ -0,0 +1,38 @@ +//: [Previous](@previous) +/*: +# Parsing Document Fragments +*/ + +import HTMLKit + +/*: +Given some HTML content +*/ + +let htmlString = "

Hello HTMLKit

some table data" + +/*: +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) + +for element in elements { + print(element.outerHTML) +} + +/*: +The same parser instance can be reusued: +*/ + +let bodyContext = HTMLElement(tagName: "body") +elements = parser.parseFragmentWithContextElement(bodyContext) + +for element in elements { + print(element.outerHTML) +} + +//: [Next](@next) diff --git a/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..43c4189 --- /dev/null +++ b/HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + diff --git a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..a67a13f --- /dev/null +++ b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift @@ -0,0 +1,79 @@ +//: [Previous](@previous) +/*: +# The DOM + +HTMLKit provides a rich DOM implementation for manipulating and navigating the document tree. Here are some of the features: +*/ + +import HTMLKit + +let htmlString = "

HTMLKit

Hello there!

" +let document = HTMLDocument(string: htmlString) + +/*: +Create new elements and assign attributes +*/ + +let description = HTMLElement(tagName:"meta", attributes: ["name": "description"]) +description["content"] = "HTMLKit for iOS & OSX" + +/*: +Append nodes to the document +*/ +let head = document.head! +head.appendNode(description) +document.innerHTML + +let body = document.body! +let nodes = [ + HTMLElement(tagName: "div", attributes: ["class": "red"]), + HTMLElement(tagName: "div", attributes: ["class": "green"]), + HTMLElement(tagName: "div", attributes: ["class": "blue"]) +] +body.appendNodes(nodes) +body.innerHTML + +/*: +Enumerate child elements and perform DOM manipulation +*/ +body.enumerateChildElementsUsingBlock { (element, index, stop) -> Void in + if element.tagName == "div" { + let lorem = HTMLElement(tagName: "p") + lorem.textContent = "Lorem ipsum: \(index)" + element.appendNode(lorem) + } +} +body.innerHTML + +/*: +Remove nodes from the document +*/ +body.removeChildNodeAtIndex(1) +body.innerHTML + +/*: +Navigate to child and sibling nodes +*/ +body.lastChild!.removeFromParentNode() +let greenDiv = body.firstChild!.nextSibling! + +/*: +Manipulate the HTML directly +*/ +greenDiv.innerHTML = "