From 572918e59b27391662801da69a9286acd1f19054 Mon Sep 17 00:00:00 2001 From: iska Date: Wed, 23 Dec 2015 17:17:00 +0100 Subject: [PATCH] Add HTMLKit Demo playground --- .../Contents.swift | 80 ++++++++++ .../timeline.xctimeline | 0 .../Demo.xcplaygroundpage/Contents.swift | 0 .../Intro.xcplaygroundpage/Contents.swift | 27 +++- .../timeline.xctimeline | 8 +- .../Contents.swift | 29 ++++ .../timeline.xctimeline | 12 ++ .../Contents.swift | 38 +++++ .../timeline.xctimeline | 48 ++++++ .../The DOM.xcplaygroundpage/Contents.swift | 79 +++++++++ .../timeline.xctimeline | 150 ++++++++++++++++++ .../Resources/HTMLKit.html | 2 +- HTMLKit.playground/contents.xcplayground | 7 +- 13 files changed, 468 insertions(+), 12 deletions(-) create mode 100644 HTMLKit.playground/Pages/CSS Selectors.xcplaygroundpage/Contents.swift rename HTMLKit.playground/Pages/{Demo.xcplaygroundpage => CSS Selectors.xcplaygroundpage}/timeline.xctimeline (100%) delete mode 100644 HTMLKit.playground/Pages/Demo.xcplaygroundpage/Contents.swift create mode 100644 HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/Contents.swift create mode 100644 HTMLKit.playground/Pages/Parsing Documents.xcplaygroundpage/timeline.xctimeline create mode 100644 HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/Contents.swift create mode 100644 HTMLKit.playground/Pages/Parsing Fragments.xcplaygroundpage/timeline.xctimeline create mode 100644 HTMLKit.playground/Pages/The DOM.xcplaygroundpage/Contents.swift create mode 100644 HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline rename HTMLKit.playground/{Pages/Demo.xcplaygroundpage => }/Resources/HTMLKit.html (71%) 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 = "
  • item 1
  • item 2" + +/*: +Iterate the DOM tree with custom filters +*/ +let filter = HTMLNodeFilterBlock.filterWithBlock { (node) -> HTMLNodeFilterValue in + if node.childNodesCount() != 1 { + return .Reject + } + return .Accept +} + +for element in body.nodeIteratorWithShowOptions(.Element, filter: filter) { + element.outerHTML +} + +//: [Next](@next) diff --git a/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..cebe428 --- /dev/null +++ b/HTMLKit.playground/Pages/The DOM.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HTMLKit.playground/Pages/Demo.xcplaygroundpage/Resources/HTMLKit.html b/HTMLKit.playground/Resources/HTMLKit.html similarity index 71% rename from HTMLKit.playground/Pages/Demo.xcplaygroundpage/Resources/HTMLKit.html rename to HTMLKit.playground/Resources/HTMLKit.html index cff82fd..a9ca358 100644 --- a/HTMLKit.playground/Pages/Demo.xcplaygroundpage/Resources/HTMLKit.html +++ b/HTMLKit.playground/Resources/HTMLKit.html @@ -4,7 +4,7 @@

    HTMLKit

    -

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

    +

    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 19f1126..d961153 100644 --- a/HTMLKit.playground/contents.xcplayground +++ b/HTMLKit.playground/contents.xcplayground @@ -1,7 +1,10 @@ - + - + + + + \ No newline at end of file