347 Commits

Author SHA1 Message Date
iska 20cf2dc4d0 Merge branch 'hotfix/2.1.1' 2017-10-13 23:05:02 +02:00
iska 0921ebad8a Bump HTMLKit version to 2.1.1 2017-10-13 23:04:33 +02:00
iska c63e2cb8fd Update podspec for 2.1.1 2017-10-13 23:03:49 +02:00
iska 3deeb0138f Update jazzy.yaml for 2.1.1 2017-10-13 23:03:38 +02:00
iska b358a08f30 Add Changelog entry for HTMLKit 2.1.1 2017-10-13 23:03:19 +02:00
iska c1cd1c0831 Merge branch 'release/2.1.0' 2017-10-12 22:44:49 +02:00
iska 1101556cfe Bump HTMLKit version to 2.1.0 2017-10-12 22:44:39 +02:00
iska 839a724432 Update podspec for 2.1.0 2017-10-12 22:44:39 +02:00
iska 300705cb63 Update jazzy.yaml for 2.1.0 2017-10-12 22:44:39 +02:00
iska 1963c010f9 Add Changelog entry for HTMLKit 2.1.0 2017-10-12 22:44:39 +02:00
iska 89ef6bc101 Update README for master branch 2017-10-12 22:44:39 +02:00
iska 9069923e82 Update handling for ParseErrorTokens in the HTML Parser 2017-10-12 22:25:46 +02:00
iska c16c647394 Add codecove.yml and update badges in README 2017-09-28 00:00:23 +02:00
iska 27b8eaac67 Add codecov after-script to upload coverage reports 2017-09-27 18:58:22 +02:00
iska 956c46ec45 Fix travis destinations for iOS 9.3 and 10.3 2017-09-27 00:11:56 +02:00
iska cb7e5d519d Update travis.yml for Xcode 9 and iOS 11 2017-09-26 22:38:09 +02:00
iska 4e1959bd81 Fix strict-prototypes blocks declarations throughout codebase 2017-09-23 02:31:48 +02:00
iska f0d9817c68 Restore default modulemap file name
Closes #13
2017-09-23 02:27:35 +02:00
iska fee2d14ffc Update project for Xcode 9 2017-09-23 02:26:46 +02:00
iska 4291840a53 Update .travis.yml 2017-09-10 15:56:36 +02:00
iska 4b7c260738 Update HTML Spec fixture to source as of 2017.09.09 2017-09-10 02:26:39 +02:00
iska 4a41b89ecf Update tokenizer implementation as per spec as of 2017.09.09
- Use new initial states in tests according to:
https://github.com/html5lib/html5lib-tests/pull/101

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

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

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

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

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

initWithDowcument: -> initWithDocument
2017-03-31 17:19:16 +02:00
Martin Waitz 22de41d912 Fix typo Dowcument -> Document 2017-03-31 08:53:11 +02:00
Iskandar Abudiab 2f47e733bd Merge pull request #8 from tali/develop
Fix tests for Swift 3.1
2017-03-14 00:13:36 +01:00
Martin Waitz 36f5df015a [Tests] fix includes 2017-03-13 23:11:16 +01:00
Martin Waitz bbc5467b33 [modulemap] use textual header for character definitions
Both CSSCodePoints.h and HTMLTokenizerCharacters.h define the same
symbols.
They are never included by the same compilation unit, but when they are
compiled into the same module, they create a conflict.
Fix this conflict by using `textual header`.
2017-03-13 23:11:16 +01:00
iska 7ef19f5e20 Ignore performance tests
For now these are ignored for faster testing/iterations.
The test fixture should also be replaced with several smaller
and more representative ones, since it is relatively big.
2017-03-13 23:04:58 +01:00
iska a102f5cd7d Fix loading of test resources
Building and testing the project via Xcode copies the resources into
the testing bundle, which is not the case for SwiftPM. Hence the helper
method, that tries loading the resource from the bundle first. If it is
nil then the resource is loaded from the test module path directly.
2017-03-13 23:01:53 +01:00
iska 7a40e8bafd Merge branch 'release/2.0.3' 2017-03-06 00:31:03 +01:00
iska 40b057b569 Merge branch 'release/2.0.3' into develop 2017-03-06 00:31:03 +01:00
iska a7ace9929f Bump HTMLKit version to 2.0.3 2017-03-06 00:30:41 +01:00
iska 32b674f786 Update podspec for 2.0.3 2017-03-06 00:30:37 +01:00
iska e9e3f04136 Update jazzy.yaml for 2.0.3 2017-03-06 00:30:32 +01:00
iska 44f1bc6946 Add Changelog entry for HTMLKit 2.0.3 2017-03-06 00:30:26 +01:00
Iskandar Abudiab ef36e674a4 Merge pull request #6 from tali/develop
Fix compilation for Swift 3.1
2017-03-03 10:32:58 +01:00
Martin Waitz b8f1123b86 Fix compilation for Swift 3.1
Move the `module.modulemap` into `Sources/include` and add an exclude
for `Tests/Fixtures`.
2017-03-03 08:25:14 +01:00
iska 17a2e375e0 Merge branch 'release/2.0.2' into develop 2017-02-26 21:46:00 +01:00
iska b5470a61c3 Merge branch 'release/2.0.2' 2017-02-26 21:45:59 +01:00
iska fb60759492 Bump HTMLKit version to 2.0.2 2017-02-26 21:45:47 +01:00
iska f21cbf2a5e Update podspec for 2.0.2 2017-02-26 21:45:27 +01:00
iska 50c48e589a Update jazzy.yaml for 2.0.2 2017-02-26 21:45:16 +01:00
iska bb9987636b Add Changelog entry for HTMLKit 2.0.2 2017-02-26 21:45:05 +01:00
iska 60b086f72e Exclude tests resources from Swift Package 2017-02-25 02:07:03 +01:00
iska f1fd0f3ef6 Move test files into HTMLKitTests subfolder Swift Package Manager 2017-02-25 02:07:02 +01:00
iska 5bb7122d7e Use a weak-memory NSHashTable for referencing ranges in HTML Document
This breaks the retain cycle between the document and the attached range

Fixes #5
2017-02-22 23:55:35 +01:00
iska 356709a096 Use a weak-memory NSHashTable for referencing iterators in HTML Document
This breaks the retain cycle between the document and the attached node
iterator.

Fixes #4
2017-02-22 23:54:55 +01:00
iska 963a2b9c09 Merge branch 'hotfix/2.0.1' 2017-02-20 23:03:40 +01:00
iska 9926179a62 Merge branch 'hotfix/2.0.1' into develop 2017-02-20 23:03:40 +01:00
iska cb9886cbf7 Bump HTMLKit version to 2.0.1 2017-02-20 23:02:55 +01:00
iska 717f62a5f1 Update jazzy.yaml for 2.0.1 2017-02-20 23:02:37 +01:00
iska f5476e0c4c Update podspec for 2.0.1 2017-02-20 23:02:22 +01:00
iska b9099a26ed Add Changelog entry for HTMLKit 2.0.1 2017-02-20 23:01:05 +01:00
iska b57e27137a Set INSTALL_PATH and DYLIB_INSTALL_NAME_BASE to @rpath for macOS target 2017-02-20 22:55:15 +01:00
iska dbe9c575a1 Merge branch 'release/2.0.0' 2017-02-11 19:23:07 +01:00
iska 17961b94a4 Merge branch 'release/2.0.0' into develop 2017-02-11 19:23:07 +01:00
iska d6d1e77471 Bump HTMLKit version to 2.0.0 2017-02-11 19:22:24 +01:00
iska 987d37e042 Update README 2017-02-11 19:22:14 +01:00
iska 6d7e9bca1b Update jazzy.yaml for 2.0.0 2017-02-11 19:22:05 +01:00
iska 0b8b18b675 Update podspec for 2.0.0 2017-02-11 19:21:55 +01:00
iska 325ca47587 Add Changelog entry for HTMLKit 2.0.0 2017-02-11 19:21:44 +01:00
iska 05c6b9d294 Expect <menuitem> to parse like an unknown element
This reverses the parser change introduced in commit:
b0bad5068f

The list of special elements is not reverted

The change was reverted in the spec:
https://github.com/whatwg/html/pull/2319

and the html5lib-tests:
https://github.com/html5lib/html5lib-tests/pull/88
2017-02-11 18:27:25 +01:00
iska 76753b1d95 Update html5lib-tests to latest commit as of 2017.02.11
Commit: 13f1805136f8a6b3883d1cf7c727ad0a6b97eab1
2017-02-11 17:33:22 +01:00
iska daf71a01f3 Merge branch 'release/1.1.0' 2017-01-15 00:01:28 +01:00
iska da2344e5cf Merge branch 'release/1.1.0' into develop 2017-01-15 00:01:28 +01:00
iska 049d7b7148 Bump HTMLKit version to 1.1.0 2017-01-15 00:00:14 +01:00
iska c727ce6643 Update README.md 2017-01-15 00:00:14 +01:00
iska 1a5238863a Add Changelog entry for HTMLKit 1.1.0 2017-01-14 23:54:36 +01:00
iska 46e36e9c24 Update jazzy.yaml for 1.1.0 2017-01-14 23:54:36 +01:00
iska 1919992b0e Update podspec for 1.1.0 2017-01-14 23:54:36 +01:00
iska 28ecfb0278 Update headers in module map 2017-01-14 23:54:36 +01:00
iska 65666a13c0 Remove redundant header file from private group 2017-01-14 23:54:36 +01:00
iska e5237a68c4 Update project headers and targets 2017-01-14 23:54:36 +01:00
iska ea63b38379 Update html5lib-tests to latest commit as of 2017-01-13
Commit:
50568b5664d6b034b752310603b2b664d045ad0f

This commit references a PR adding <plaintext> tests
2017-01-13 19:35:09 +01:00
iska 542bc26ff9 Use AssertEqualObjects instead of AssertEqual in range tests
Better error message on failures.
2017-01-13 18:28:29 +01:00
iska 718e43ff9c Add HTML Range tests for Text split callbacks 2017-01-13 18:23:56 +01:00
iska 472d59546a Add HTML Range stringifier and description
https://dom.spec.whatwg.org/#dom-range-stringifier
2017-01-11 22:48:51 +01:00
iska bdaddc0938 Add travis_retry in travis.yml to fix build issues
So this happened:
https://github.com/travis-ci/travis-ci/issues/6422
2017-01-11 22:38:53 +01:00
iska a38d1e6484 Add HTML CharacterData method for substring data 2017-01-11 19:17:54 +01:00
iska f53ce3464d Add HTML Range tests for node surround and insertion 2017-01-11 18:29:30 +01:00
iska bc94f91c6e Add HTML Character Data & Text tests 2017-01-10 17:55:39 +01:00
iska 1e5517f403 Fix return type of split-text method in HTML Text 2017-01-10 17:55:26 +01:00
iska 925848404b Add implementation for HTML Range surround and insert node 2017-01-08 22:38:41 +01:00
iska fe46b106b2 Add implementation for HTML Text splitting 2017-01-08 22:36:47 +01:00
iska c7edbd3e14 Add HTML Document and Range methods for Text splitting callbacks 2017-01-08 22:35:53 +01:00
iska f1b1f523b8 Add implementation for HTML Range’s extract contents method 2017-01-08 09:44:03 +01:00
iska 51c94d49bd Add implementation for HTML Range’s clone contents method 2017-01-08 09:33:15 +01:00
iska 395ce5e981 Add HTML Range initializer that accepts start and end boundaries 2017-01-08 09:32:15 +01:00
iska e48ccf42ca Add HTML Node deep clone implementation 2017-01-08 09:31:37 +01:00
iska 0ac49f2a0f Add implementation for HTML Range’s delete contents method 2017-01-08 08:09:26 +01:00
iska 07c72f65d9 Add HTML Range methods for contained nodes 2017-01-08 08:07:47 +01:00
iska 8602ad5a7b Add extended documentation for Node’s containsNode method
This will be deprecated and replaced with isInclusiveAncestor in a later
release.
2017-01-05 02:44:05 +01:00
iska 12fc972602 Add HTML Range handling for mutation callback on node removal
See:
https://dom.spec.whatwg.org/#concept-node-remove
2017-01-05 02:43:07 +01:00
iska b66f5264ba Rename some test classes
- Drop the “Kit” from class names
2017-01-04 03:49:05 +01:00
iska 1042571c57 Add Range tests for character data callbacks with different boundaries 2017-01-02 01:04:00 +01:00
iska c294802199 Add HTML Range tests for character data mutation callbacks 2017-01-02 00:39:55 +01:00
iska ea17eeef9d Fix copy methods for CharacterData and DocumentType nodes 2016-12-31 16:26:06 +01:00
iska 9795172c9c Add implementation and tests for Range comparison and intersection methods 2016-12-31 03:11:49 +01:00
iska 0319536a6c Add HTML Range tests for boundary comparison 2016-12-31 00:34:54 +01:00
iska 3f74fcaa7b Use the “iPhone 7 Plus 10.1” destination in travis.yml
It seems that the Xcode8.2 image in travis contains multiple (2)
“iPhone 7 Plus 10.2” destinations
See build log:
https://travis-ci.org/iabudiab/HTMLKit/jobs/187795560
2016-12-30 23:35:00 +01:00
iska 78b3069a25 Fix watchOS and iOS destinations in travis.yml 2016-12-30 22:54:05 +01:00
iska dfd01b1908 Update Xcode image and SDK versions in travis.yml 2016-12-30 22:11:14 +01:00
iska bdacc629eb Add HTML Range tests for node selecting 2016-12-30 22:08:23 +01:00
iska 734c185137 Add HTML Range tests for boundaries logic 2016-12-30 21:55:36 +01:00
iska de6c215550 Fix check in range’s compare-boundaries method 2016-12-30 21:54:58 +01:00
iska b7b29d2af5 Fix HTML Range boundary validations 2016-12-30 03:21:17 +01:00
iska 15acfa06f6 Fix HTML Node’s method to compare document positions 2016-12-30 03:07:59 +01:00
iska 7506ed8cae Refactor method to get a node’s ancestor chain into the utils class 2016-12-30 03:07:33 +01:00
iska 3898ae243c Add HTML Range tests class and setup 2016-12-29 22:54:59 +01:00
iska 6da3f7bd49 Mark HTML Range’s default initializer as unavailable 2016-12-29 22:54:39 +01:00
iska fb04d49693 Add DOM method for computing a common ancestor of two nodes 2016-12-29 22:54:14 +01:00
iska 4d132af99f Update and reorganize private headers and modulemap 2016-12-29 22:53:34 +01:00
iska e4a0669cf2 Fix travis badge on develop branch 2016-11-28 01:32:25 +01:00
iska e60fe36e25 Fix append-string method in HTML Text node 2016-11-27 20:22:21 +01:00
iska 1f6f9d843e Add implementation for range’s update methods on character data mutations 2016-11-27 20:21:16 +01:00
iska 5c2f6527a7 Add implementation for HTML Range’s contains-node method 2016-11-27 20:19:54 +01:00
iska e4b57f3333 Update deprecation message in HTML Text node 2016-11-27 20:19:19 +01:00
iska 6be1bd702f Add implementation for HTML Character Data methods
The data property is longer exposed as a mutable string. Instead all
manipulations must be performed via the provided API in order to ensure
correct updates for the Document’s attached ranges.

See:
https://dom.spec.whatwg.org/#characterdata
2016-11-27 20:18:12 +01:00
iska ef672e1dbb Add range attaching/detaching to the range’s lifecycle 2016-11-27 15:00:13 +01:00
iska 0d95ba33d1 Add HTML Document methods to attach and detach a range to the document 2016-11-27 03:13:21 +01:00
iska 9df89043d3 Refactor all private extensions into own separate categories 2016-11-27 03:12:58 +01:00
iska 6fdc7ff85b Refactor private HTML Document extensions into one separate category 2016-11-27 02:43:10 +01:00
iska c3c7c34310 Deprecate appendString: method in HTML Text node
The data property is mutable and should be used instead
2016-11-27 02:10:10 +01:00
iska fb2952062d Add Character Data implementation as a base for text and comment nodes
https://dom.spec.whatwg.org/#characterdata
2016-11-27 02:09:06 +01:00
iska 49799f8bcd Add methods to select a node and node contents in a HTML Range 2016-11-22 21:42:45 +01:00
iska 9bd9dfbf6b Add methods to collapse a HTML Range 2016-11-22 21:42:15 +01:00
iska 8f0a6d133e Finalize HTML Range methods for setting boundaries 2016-11-22 21:41:41 +01:00
iska cfb1707fc4 Implement collapsed, common ancestor & root properties for HTML Range 2016-11-22 01:25:04 +01:00
iska 733780091d Add method declaration for comparing HTML Ranges 2016-11-22 01:24:02 +01:00
iska 8391a01147 Change HTML Range’s initializer to accept one HTML Document argument
According to spec:
“The Range() constructor, when invoked, must return a new range with
(current global object’s associated Document, 0) as its start and end.”

We don’t have a global object (window) with an associated document, thus
we have to pass one instead.
2016-11-22 01:23:17 +01:00
iska 6ed0238a89 Add implementation for setting HTML Range’s boundaries 2016-11-22 01:20:20 +01:00
iska 80299ad9e0 Change HTMLDocumentPosition to NS_OPTIONS instead of NS_ENUM
Better interop with Swift
2016-11-22 01:17:32 +01:00
iska ffc9e629f2 Add index property for HTML Node 2016-11-22 01:15:23 +01:00
iska 394a1a53c4 Add root-node property for HTML Node 2016-11-22 01:15:09 +01:00
iska 14289f96e5 Add method declarations to collapse and select nodes in the HTML Range
See:
https://dom.spec.whatwg.org/#range
2016-11-21 01:24:26 +01:00
iska c57117670f Add method declarations to initialize and define a HTML Range
See:
https://dom.spec.whatwg.org/#range
2016-11-21 01:24:26 +01:00
iska a08fb84be9 Add properties to HTML Range interface
See:
https://dom.spec.whatwg.org/#range
2016-11-21 01:19:31 +01:00
iska 9fd5d34244 Add HTML Range class stub 2016-11-21 01:17:48 +01:00
iska 2fb871a7ff Add implementation for the length property for HTML Nodes
See:
https://dom.spec.whatwg.org/#concept-node-length
https://heycam.github.io/webidl/#dfn-code-unit
2016-11-20 18:36:55 +01:00
iska 46072a09cc Update html5lib-tests to latest commit as of 2016.11.07
Commit: 27724be8d27a1232a8809a55f9c37b69706cb03e
2016-11-07 21:51:22 +01:00
iska de2d35fbe6 Merge branch 'release/1.0.0' 2016-09-28 02:09:00 +02:00
iska 6ae00f40e1 Merge branch 'release/1.0.0' into develop 2016-09-28 02:09:00 +02:00
iska 76a7930e7d Bump HTMLKit version to 1.0.0 2016-09-28 02:02:51 +02:00
iska 8dc5d0ea50 Update jazzy.yaml for 1.0.0 2016-09-28 02:02:31 +02:00
iska 0e9956efc0 Update podspec for 1.0.0 2016-09-28 02:02:18 +02:00
iska d5888e68a7 Add Changelog entry for HTMLKit 1.0.0 2016-09-28 02:01:10 +02:00
iska 02177e7fac Fix macOS scheme and sdk in travis.yml 2016-09-28 01:55:10 +02:00
iska af76666f3c Add watchOS2.0 and tvOS9.0 destinations to travis.yml 2016-09-28 01:44:09 +02:00
iska 73dc32aae9 Set deployment targets to macOS 10.9, iOS 9.0, tvOS 9.0 and watchOS 2.0 2016-09-28 01:39:38 +02:00
iska 64cba55677 Replace OSX with macOS throughout project 2016-09-28 01:38:59 +02:00
iska 214722c0bf Share example project's scheme 2016-09-28 01:36:05 +02:00
iska b8592630d0 Fix simulator name in travis.yml 2016-09-28 01:10:04 +02:00
iska a641c64f74 Fix typo in travis.yml 2016-09-27 23:34:24 +02:00
iska e20531925a Update travis.yaml for Xcode8 and iOS10 2016-09-27 23:00:45 +02:00
iska 024ab12242 Add docs directory to gitignores 2016-09-27 22:50:02 +02:00
iska c2a11e6f97 Add .jazzy.yaml configuration file 2016-09-27 22:49:49 +02:00
iska 800336d317 Add nullability annotation for CSSSelectorParser's parse method 2016-09-27 22:32:30 +02:00
iska a751cec215 Add example project 2016-09-27 22:30:45 +02:00
iska 87a476e523 Change html5lib-tests submodule name 2016-09-20 19:30:10 +02:00
iska 7e42fd1e08 Add missing lightweight generics in Parser, Element & Node classes
To play nicely with Swift 3
2016-09-20 19:28:08 +02:00
iska 7d1b94219d Add missing deployment target settings in project file 2016-09-20 19:27:21 +02:00
iska 29bd89b808 Update playground to Swift 3 2016-09-20 19:27:05 +02:00
iska 45a8e25028 Update project and schemes for Xcode 8 2016-09-13 22:47:33 +02:00
iska 33bb1e39a4 Merge branch 'release/0.9.4' into develop 2016-09-03 17:23:09 +02:00
iska 44c987ec13 Merge branch 'release/0.9.4'
# Conflicts:
#	Tests/html5lib-tests
2016-09-03 17:21:13 +02:00
iska 3bd5b2d4a2 Fix source code and header paths in podspec file
Source code resides in "Sources" and "Sources/include" now after spm
refactor
2016-09-03 17:08:17 +02:00
iska 8c312e1508 Bump HTMLKit version to 0.9.4 2016-09-03 16:53:23 +02:00
iska 20d8449a94 Update podspec for 0.9.4 2016-09-03 16:51:58 +02:00
iska 16b85af5af Update README.md 2016-09-03 16:51:46 +02:00
iska 3c56a1d694 Add Changelog entry for HTMLKit 0.9.4 2016-09-03 16:51:33 +02:00
iska ca20e6d03f Add HTMLKit modulemap file 2016-09-03 16:18:28 +02:00
iska f58c2e3f94 Remove unused strings plist from tests code 2016-08-28 01:17:53 +02:00
iska 9698919d35 Fix import in private HTMLNode header 2016-08-27 02:07:54 +02:00
iska 9a1a12c788 Remove prefix header and necessary foundation imports 2016-08-27 02:02:43 +02:00
iska e56a980e80 Move header files into include directory 2016-08-27 01:59:53 +02:00
iska a440fd56b2 Add Package.swift 2016-08-24 20:27:50 +02:00
iska 1a3c1dd3d2 Update gitignore 2016-08-24 20:23:20 +02:00
iska 170c298571 Remove unused strings plist 2016-08-24 20:04:13 +02:00
iska f51c76d257 Update project paths for info.plist and prefix header 2016-08-24 20:02:09 +02:00
iska 1df63b8e00 Move test source code to Tests directory 2016-08-24 19:55:59 +02:00
iska 37444d5899 Move source code to Sources directory 2016-08-24 19:54:41 +02:00
iska 85e4941057 Move css-tests to Tests directory 2016-08-24 19:51:41 +02:00
iska c7a339fbed Move html5lib-tests submodule to Tests directory 2016-08-24 19:50:23 +02:00
iska 0f80b0bbe2 Merge branch 'release/0.9.3' 2016-07-16 14:50:07 +02:00
iska b1a9b7ecee Merge branch 'release/0.9.3' into develop 2016-07-16 14:50:07 +02:00
iska f794e04b9f Bump HTMLKit version to 0.9.3 2016-07-16 14:49:23 +02:00
iska 0ffecea0f3 Update podspec for 0.9.3 2016-07-16 14:49:23 +02:00
iska 62fef829d3 Set deployment targets for watchOS 2016-07-16 14:49:23 +02:00
iska 21dd607ec6 Update README.md 2016-07-16 14:48:44 +02:00
iska 7ae337471c Add Changelog entry for HTMLKit 0.9.3 2016-07-16 13:59:36 +02:00
iska 730b8a3239 Fix format arguments in Test Observer class 2016-07-16 13:51:09 +02:00
iska 33a8238513 Fix product name in tvOS scheme 2016-07-16 13:38:36 +02:00
iska 769113ec0e Fix travis.yml
Add missing semicolon to end if-then-statement
2016-07-16 13:37:50 +02:00
iska 4970976485 Exclude watchOS scheme from testing in travis.yml 2016-07-16 02:25:57 +02:00
iska 38fef77be5 Update travis.yml for watchOS & tvOS targets 2016-07-16 01:28:51 +02:00
iska 754b7191b9 Add tvOS target 2016-07-16 01:14:02 +02:00
iska 56cc5b1a3e Add watchOS target 2016-07-16 01:05:43 +02:00
iska ccecc4106d Update html5lib-tests to latest commit as of 2016.07.15
Commit: c305da74fae50fb018870de7a042da36c1a93b65
2016-07-15 22:57:30 +02:00
iska 39dda3aaf5 Update html5lib-tests to latest commit as of 2016.06.29
Commit: 2998f9afa303bfb603c9c97a9565c8bfa71eef4f
2016-06-29 00:43:31 +02:00
iska a136976462 Update html5lib-tests to latest commit as of 2016.06.116
Commit: 927f779be5b9aed4b5a04f404e95f9b3b80bb409
2016-06-16 23:26:54 +02:00
iska 8aabc94fdb Merge branch 'release/0.9.2' 2016-05-18 21:17:44 +02:00
iska 322b42b9d1 Merge branch 'release/0.9.2' into develop 2016-05-18 21:17:44 +02:00
iska c2acbb6344 Bump HTMLKit version to 0.9.2 2016-05-18 21:16:43 +02:00
iska a6e4aac937 Bump Pod version to 0.9.2 2016-05-18 21:15:51 +02:00
iska 899438fa24 Update README.md 2016-05-18 21:14:23 +02:00
iska 137fa8617e Add Changelog entry for HTMLKit 0.9.2 2016-05-18 21:13:14 +02:00
iska 70abd998f7 Fix adoption agency algorithm according to the latest specification
This implements the specification change:
https://github.com/whatwg/html/commit/22ce3c31

Current implementation should pass all new html5lib test cases, including
those from Blink, WebKit, and namespace sensitivity.

See related:
https://github.com/html5lib/html5lib-tests/issues/78
https://bugzilla.mozilla.org/show_bug.cgi?id=901319
https://lists.w3.org/Archives/Public/public-html/2013Aug/0002.html
https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Jul/0401.html
https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Jul/0006.html
2016-05-18 19:59:54 +02:00
iska bb948e0ef8 Check the qualified instead of the local name in the stack of open elements
This fixes the parser's behaviour when handling elements in the MathML and
SVG namespaces.

See:
https://bugs.webkit.org/show_bug.cgi?id=113723
https://www.w3.org/Bugs/Public/show_bug.cgi?id=21308
https://www.w3.org/Bugs/Public/show_bug.cgi?id=21292
2016-05-18 19:48:37 +02:00
iska b0bad5068f Update parsing logic for <menuitem> and <menu> elements
The current spec (2016.05.15) is missing the instruction to "reconstruct
the active formatting elements" to match the handling of the <option>
element

See relevant discussions:
https://github.com/whatwg/html/pull/907
https://github.com/whatwg/html/issues/234
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/MkEDloT-yu8
https://www.w3.org/Bugs/Public/show_bug.cgi?id=25325
2016-05-15 03:44:00 +02:00
iska a01f1c1c5b Remove handling for <isindex> and <input name=isindex>
Everybody else is doing it, so why can't we?
See: https://github.com/whatwg/html/pull/1095

<isindex> is not only deprecated, it is completely removed from the spec
html5lib-tests: f99e2cb1851de9674519a220a1ccb3174b8cb846
2016-05-15 03:44:00 +02:00
iska 6967798823 Update html5lib-tests to latest commit as of 2016.05.15
Commit: b2f4f5844192ed097bd7993dfb0bcbd4c7a4aeb0
2016-05-15 03:44:00 +02:00
iska 58b60dd390 Add test utility class for adding test cases dynamically at runtime 2016-04-12 00:21:20 +02:00
iska 4441b7decd Generate HTMLKit's Tokenizer tests dynamically for better failure reporting
TODO: refactor dynamic tests generation into helper class/method
2016-04-11 01:18:33 +02:00
iska 0b2681f8a8 Generate HTMLKit's Tree Construction tests dynamically for better failure reporting
TODO: refactor dynamic tests generation into helper class/method
2016-04-11 01:14:15 +02:00
iska 1e07acd032 Use tests observer in the HTMLKit Tree Construction tests 2016-04-11 01:13:24 +02:00
iska 432df997b3 Add simple tests observer class for failure reporting 2016-04-11 01:12:40 +02:00
iska c9d72646bc Update htlm5lib-tests to include Blink changes
Commit: 193fa43bd66e9f0c416b6e2b358711644c5f55d6
2016-04-10 16:48:31 +02:00
iska 1af25abadb Fix tags links in the CHANGELOG.md 2016-03-31 13:11:23 +02:00
iska 75138cc35f Add CHANGELOG.md 2016-02-01 22:07:43 +01:00
iska 93401e4054 Update badges in README.md 2016-01-30 14:12:45 +01:00
iska 266621edf2 Merge branch 'release/0.9.1' 2016-01-29 00:56:54 +01:00
iska 25ad5a3f82 Merge branch 'release/0.9.1' into develop 2016-01-29 00:56:54 +01:00
iska cac1e4cedd Add podspec file for HTMLKit 2016-01-29 00:56:45 +01:00
iska abc847a33b Set version to 0.9.1 2016-01-29 00:55:32 +01:00
iska 4680a66fd1 Fix all warnings related to type conversion in NSLog statements 2016-01-29 00:43:01 +01:00
iska 465b78dbba Change build settings to treat warnings as errors 2016-01-29 00:39:11 +01:00
iska a64ff8782e Fix variable types in README.md examples 2016-01-28 23:20:30 +01:00
iska e03a384aa7 Update logo image 2016-01-28 23:17:06 +01:00
iska 6d2cb09082 Add travis build status to README.md 2016-01-28 22:17:18 +01:00
iska 222bfa03e1 Remove iOS 8 simulators from the build matrix in the travis.yml
Till these get fixed:
https://github.com/travis-ci/travis-ci/issues/4906
https://github.com/travis-ci/travis-ci/issues/3040
2016-01-28 22:14:48 +01:00
iska 6254e8a578 Add imports for the public categories in the umbrella header 2016-01-28 22:12:37 +01:00
iska 01be0acc0a Move the private HTMLNode header to the corresponding section 2016-01-28 22:12:13 +01:00
iska 58f0b88ff8 Add simulator-id to the build matrix in travis.yml 2016-01-20 00:33:35 +01:00
iska b90e673dc0 Add command to start the simulator before building and running tests in travis.yml 2016-01-19 21:36:50 +01:00
iska 22f293e718 Fix workspace env variable in tavis.yml 2016-01-19 01:19:39 +01:00
iska 4511335e9b Fix indentation in tavis.yml 2016-01-19 01:17:10 +01:00
iska dd2d29b8f0 Add matrix and destinations to travis.yml 2016-01-19 01:13:28 +01:00
iska f267958e83 Set deployment target to iOS 8.0 2016-01-19 00:50:57 +01:00
iska b94a80bd24 Remove code signing identity 2016-01-19 00:50:39 +01:00
iska 1df0c4ce1f Use debug configuration in travis.yml 2016-01-19 00:41:33 +01:00
iska ac49520ad9 Use correct schemes in travis.yml 2016-01-19 00:37:23 +01:00
iska ee6dbff8d5 Use ipgonesimulator SDK in travis.yml 2016-01-19 00:31:23 +01:00
iska f004e6328c Remove Team ID from project settings 2016-01-19 00:31:23 +01:00
iska f8255c861a Add .travis.yml file 2016-01-19 00:26:55 +01:00
iska 4592037aba Fix "return" attribute in source code documentation
@returns is ignored by jazzy
2016-01-18 21:48:00 +01:00
iska 948c07e4ae Merge branch 'hotfix/fix_readme' 2015-12-24 00:35:15 +01:00
iska 41d9d98201 Merge branch 'hotfix/fix_readme' into develop 2015-12-24 00:35:15 +01:00
iska 8199f647f4 Fix some typos in the README 2015-12-24 00:35:08 +01:00
iska 977737d538 Merge branch 'hotfix/fix_readme' 2015-12-23 21:53:07 +01:00
iska b8d17162d5 Merge branch 'hotfix/fix_readme' into develop 2015-12-23 21:53:07 +01:00
iska 27e1ed2bda Add new line after logo in README 2015-12-23 21:53:00 +01:00
iska d980203741 Merge branch 'release/0.9.0' 2015-12-23 21:49:36 +01:00
iska c169f0ed07 Merge branch 'release/0.9.0' into develop 2015-12-23 21:49:36 +01:00
iska ba02239207 Remove build status from README for now 2015-12-23 21:49:10 +01:00
iska 830fa06a55 Remove travis.yml for now since it is being queued on a linux vm 2015-12-23 21:47:57 +01:00
iska 30c528a220 Add build status to README 2015-12-23 21:44:05 +01:00
iska 695ff67dd8 Use xcodebuild instead of xctool in travis.yml 2015-12-23 21:35:18 +01:00
iska f883b0d906 Update README.md 2015-12-23 21:32:18 +01:00
iska be45558e86 Add travis-ci yaml file 2015-12-23 21:24:35 +01:00
iska 46629ada01 Update html5lib-tests to latest commit before the Blink changes on 16.09.2015 2015-12-23 21:11:06 +01:00
iska 700587b101 Rename the negation selector to "not" 2015-12-23 21:10:40 +01:00
iska 6c28dad930 Finalize parsing for <ruby> elements in the HTML Parser
https://github.com/whatwg/html/pull/101
2015-12-23 20:44:16 +01:00
iska 572918e59b Add HTMLKit Demo playground 2015-12-23 17:17:00 +01:00
iska 85edf33950 Reset the document's ready state on document initialization in the HTML Parser 2015-12-23 16:20:42 +01:00
iska e80188dd00 Specify the generic type of the Node Iterator 2015-12-23 03:02:30 +01:00
iska b64cfc9c1e Remove historic HTML Node types 2015-12-23 03:02:18 +01:00
iska 409b5502ae Add "Intro" page for HTMLKit in the playground 2015-12-22 17:57:21 +01:00
iska 7377ec550f Improve HTML Parser errors 2015-12-22 17:56:25 +01:00
iska 3d9e657be4 Remove performance tests from the HTMLKit OSX scheme 2015-12-22 02:52:46 +01:00
iska 766c901e38 Fix format specifier in the index-based CSS selector names 2015-12-22 02:52:30 +01:00
iska 974e5a1615 Refactor emit-error method in the CSS parser with implicit location reporting 2015-12-22 02:43:04 +01:00
iska 518fd5eacb Add tests for parsing extension selectors 2015-12-22 02:37:28 +01:00
iska f57e265cba Change "lt", "gt" & "eq"-selectors to accept an unsigned integer index 2015-12-22 02:35:00 +01:00
iska 4bb681eb78 Add missing CSS structural selectors to the parser 2015-12-22 02:32:03 +01:00
iska c4a5aa1bd9 Fix assignment in the initializer of attribute selector 2015-12-22 02:31:45 +01:00
iska be34a57e6f Add CSS parsing for "lt", "gt" & "eq"-selectors 2015-12-22 02:19:22 +01:00
iska 01694a5fdf Add CSS parsing for extension selectors 2015-12-22 02:18:48 +01:00
iska b55ca26c7e Add HTML stream method to consume a decimal number 2015-12-22 02:13:50 +01:00
iska 846b6114fc Add source code documentation for the CSS Selector classes 2015-12-21 22:21:55 +01:00
iska 1208ddf5c7 Reorder source code a little bit 2015-12-21 17:19:07 +01:00
iska c2bbb7d9f6 Add source code documentation for the private CSS Selectors related classes 2015-12-21 17:18:45 +01:00
iska 244dd726b4 Add source code documentation for the public CSS Selectors 2015-12-21 17:18:21 +01:00
iska 032c428725 Add source code documentation for the CSS Selectors parsers 2015-12-21 17:17:51 +01:00
iska 8d672cf0cf Fix "lt", "gt" & "eq"-selectors declarations
Added missing index argument
2015-12-21 17:01:38 +01:00
iska 5354c7c934 Fix node filter initialization in HTML Node class 2015-12-21 16:52:11 +01:00
iska b99cb0c9d4 Change ":has" selector's behaviour to include all descendants instead of direct child elements. 2015-12-21 16:25:26 +01:00
iska 3c89df333c Add source code documentation for the ordered dictionary class 2015-12-21 15:42:32 +01:00
iska ad34deb7ac Add source code documentation for HTMLKit categories 2015-12-21 00:18:04 +01:00
iska 7ee8057d38 Add source code documentation for node filter, tree walker, namespaces and quirks modes 2015-12-21 00:07:50 +01:00
iska f2aff5f2ce Remove unused namespaces 2015-12-21 00:06:26 +01:00
iska 7a1bb21b33 Add source code documentation for all HTML Node subclasses 2015-12-20 23:35:34 +01:00
iska fd965e014d Add source documentation for the HTML Node 2015-12-20 19:11:52 +01:00
iska 9670e11fa5 Refactor private HTML Node methods into separate extension to hide them from public API 2015-12-20 19:08:25 +01:00
iska f4bd5420c0 Add source documentation for the Parser classes 2015-12-20 17:27:13 +01:00
iska e773117f1f Fix the returned object of the fragment parsing algorithm
- Return a non-nil empty array instead of nil when context element is nil
- Return a copy of the document root's child nodes instead of the "view"-array
- Use the root selector instead of the index-based access when rerunning the algorithm with the same context element
2015-12-20 16:42:08 +01:00
iska d7476ef22d Add another sample code to the plaground 2015-12-20 00:02:05 +01:00
iska 4fabcdf76a Fix switch-state call in the Tokenizer for RAWTEXT End Tag state 2015-12-20 00:02:05 +01:00
iska bf147a6bb6 Remove redundant switch-state call in the Tokenizer 2015-12-20 00:02:05 +01:00
iska 0a620d74b6 Add source documentation for the Toknizer classes 2015-12-19 23:59:39 +01:00
iska 8893f28e4d Add HTML Element class-list property 2015-11-30 20:22:35 +01:00
iska d924063b02 Add implementation for a DOM Token List
https://dom.spec.whatwg.org/#interface-domtokenlist
2015-11-30 20:22:11 +01:00
iska f9065ab8c3 Add playground with sample code 2015-11-30 02:50:12 +01:00
iska 9815d3b39e Add nullability annotations throughout the code base 2015-11-30 02:49:58 +01:00
iska 1e30e4d86f Add HTML Node's querySelector & querySelectorAll methods 2015-11-29 19:54:23 +01:00
iska 188e5a0e56 Add missing check for nil-reference in the selector parser 2015-11-29 19:53:52 +01:00
iska 991e868d14 Add selector initializer for creating instances with a given selector string 2015-11-29 19:53:39 +01:00
iska f3af320096 Share target schemes 2015-11-29 19:52:15 +01:00
iska 9d60a26622 Organize public headers and build phases for iOS 2015-11-29 18:44:43 +01:00
iska 936348d300 Add iOS Framework target 2015-11-29 18:33:04 +01:00
iska 6410eb672a Organize framework target's build phases 2015-11-29 18:22:02 +01:00
iska 49e060cd3c Organize public header imports 2015-11-29 18:09:58 +01:00
iska dac3cee3d8 Add missing imports to the umbrella CSS Selectors header 2015-11-29 18:04:24 +01:00
iska 5ee3b9b614 Organize CSS Selectors' virtual groups 2015-11-29 18:03:56 +01:00
331 changed files with 20376 additions and 88756 deletions
+5
View File
@@ -0,0 +1,5 @@
codecov:
branch: develop
ignore:
- "Tests/"
+4 -1
View File
@@ -26,6 +26,7 @@ xcuserdata
## Obj-C/Swift specific
*.hmap
*.ipa
.build/
# CocoaPods
#
@@ -39,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
# Jazzy
docs/
+2 -2
View File
@@ -1,3 +1,3 @@
[submodule "HTMLKitTests/html5lib-tests"]
path = HTMLKitTests/html5lib-tests
[submodule "html5lib-tests"]
path = Tests/html5lib-tests
url = https://github.com/html5lib/html5lib-tests.git
+123
View File
@@ -0,0 +1,123 @@
module: HTMLKit
module_version: 2.1.1
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
- HTMLCharacterData
- HTMLText
- HTMLComment
- HTMLTemplate
- HTMLDOMTokenList
- HTMLRange
- 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)
+45
View File
@@ -0,0 +1,45 @@
language: objective-c
osx_image: xcode9
branches:
except:
- gh-pages
install:
- gem install xcpretty
env:
global:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
- WORKSPACE=HTMLKit.xcworkspace
- IOS_FRAMEWORK_SCHEME=HTMLKit-iOS
- MACOS_FRAMEWORK_SCHEME=HTMLKit-macOS
- WATCHOS_FRAMEWORK_SCHEME="HTMLKit-watchOS"
- TVOS_FRAMEWORK_SCHEME="HTMLKit-tvOS"
- IOS_SDK=iphonesimulator11.0
- MACOS_SDK=macosx10.13
- WATCHOS_SDK=watchsimulator4.0
- TVOS_SDK=appletvsimulator11.0
matrix:
- 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
- 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 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)
+299
View File
@@ -0,0 +1,299 @@
# Change Log
## [2.1.1](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.1)
Released on 2017.10.13
### Hotfix
- Fixed documentation comments
- Should fix CocoaDocs generation and percentage
## [2.1.0](https://github.com/iabudiab/HTMLKit/releases/tag/2.1.0)
Released on 2017.10.12
### Added
- Standarized tokenizer error codes:
- [whatwg/html#2701](https://github.com/whatwg/html/pull/2701)
- [html5lib/html5lib-tests#92](https://github.com/html5lib/html5lib-tests/pull/92)
### Updated
- Project for Xcode 9
- Travis config for iOS 11.0, macOS 10.13, tvOS 11.0 and watchOS 4.0
- Updated HTML5Lib-Tests submodule (cbafeba)
## [2.0.6](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.6)
Released on 2017.05.02
### Added
- Memory consumption improvements (issue #10)
- Allocate `childNodes` collection in `HTMLNode` only when inserting child nodes
- Replace `NSStringFromSelector` calls with constants in `HTMLNode` validations
- Improve `reverseObjectEnumerator` usage while parsing HTML
- Rewrite internal logic of the `HTMLStackOfOpenElements` to prevent excessive allocations
## [2.0.5](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.5)
Released on 2017.04.19
### Fixed
- Xcode 8.3 issue with modulemaps
- Temporary workaround (renamed modulemap file)
- Memory Leaks in `CSSInputStream`
### Added
- Minor memory consumption improvements
- Collections for child nodes or attributes of HTML Nodes or Elements are allocated lazily
- Underyling data string of `CharacterData` is allocated on first access
- Autorelease pool for the main `HTMLTokenizer` loop
## [2.0.4](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.4)
Released on 2017.04.2
### Fixed
- Testing with Swift 3.1
- Fixed by @tali in PR #8
### Deprecated
- `HTMLRange` initializers with typo
- `initWithDowcument:startContainer:startOffset:endContainer:endOffset:`
## [2.0.3](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.3)
Released on 2017.03.6
### Fixed
- Compilation for Swift 3.1
- Fixed by @tali in PR #6
## [2.0.2](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.2)
Released on 2017.02.26
### Fixed
- Retain cycles in `HTMLNodeIterator` (issue #4)
- Retain cycles in `HTMLRange` (issue #5)
- The layout of `HTMLKit` tests module for Swift Package Manager
## [2.0.1](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.1)
Released on 2017.02.20
### Hotifx
- Set `INSTALL_PATH` and `DYLIB_INSTALL_NAME_BASE` to `@rpath` for macOS target
- This fixes embedding `HTMLKit` in a Cocoa application
## [2.0.0](https://github.com/iabudiab/HTMLKit/releases/tag/2.0.0)
Released on 2017.02.11
### Spec Change
- Make `<menuitem>` parse like an unkonwn element. See:
- [whatwg/html#2319](https://github.com/whatwg/html/pull/2319)
- [html5lib/html5lib-tests#88](https://github.com/html5lib/html5lib-tests/pull/88)
### Updated
- Updated HTML5Lib-Tests submodule (13f1805)
## [1.1.0](https://github.com/iabudiab/HTMLKit/releases/tag/1.1.0)
Released on 2017.01.14
### Added
- `DOM Ranges` implementation ([spec](https://dom.spec.whatwg.org/#ranges))
- `HTMLChatacterData` as base class for `HTMLText` & `HTMLComment`
- `HTMLText` and `HTMLComment` no longer extend `HTMLNode` directly
- `splitText` implementation for `HTMLText` nodes
- `index` property for `HTMLNode`
- `cloneNodeDeep` method for `HTMLNode`
### Deprecated
- `appendString` method in `HTMLText` in favor of `appendData` from the supperclass `HTMLCharacterData`
## [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
### Added
- `Swift Package Manager` support
## [0.9.3](https://github.com/iabudiab/HTMLKit/releases/tag/0.9.3)
Released on 2016.07.16
This release passes all tokenizer and tree construction html5lib-tests as of 2016.07.16
### Added
- `watchOS` and `tvOS` targets
- Updated HTML5Lib-Tests submodule (c305da7)
## [0.9.2](https://github.com/iabudiab/HTMLKit/releases/tag/0.9.2)
Released on 2016.05.18
This release passes all tokenizer and tree construction html5lib-tests as of 2016.05.18
### Added
- Handling for `<menu>` and `<menuitem>`
- Changelog
### Changed
- Updated adoption agency algorithm according to the latest specification, see:
- [whatwg/html@22ce3c3](https://github.com/whatwg/html/commit/22ce3c3)
- [Mozilla Bug 901319](https://bugzilla.mozilla.org/show_bug.cgi?id=901319)
- [Chrome Issue 268121](https://bugs.chromium.org/p/chromium/issues/detail?id=268121)
- [WebKit Bug 119478](https://bugs.webkit.org/show_bug.cgi?id=119478)
- `<isindex>` is completely removed from the spec now, therefore it is dropped from the implementation
- `Tokenizer` and `Tree-Construction` tests are now generated dynamically
- Test failures are collected by a `XCTestObservation` for better reporting
### Fixed
- 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
### Added
- Travis-CI integration.
- CocoaPods spec.
### Changed
- Warnings are treated as errors.
### Fixed
- Warnings related to format specifier and loss of precision due to NS(U)-integer usage.
- Replaced `@returns` with `@return` throughout the documentation to play nicely with Jazzy.
- Some README examples used Swift syntax.
## [0.9.0](https://github.com/iabudiab/HTMLKit/releases/tag/0.9.0)
Released on 2015.12.23
This is the first public release of `HTMLKit`.
### Added
- `iOS` & `OSX` Frameworks.
- Source code documentation.
- CSS Selectors extension (analogous to jQuery selectors).
- `DOMTokenList` for malipulating `HTMLElements` attributes as a list, e.g. `class`.
- Handling for `<ruby>` elements in the Parser implementation.
- Updated HTML5Lib-Tests submodule (56c435f)
- Xcode Playground with Swift documentation.
### Removed
- Unused namespaces.
- Historical node types.
### Fixed
- `lt`, `gt` & `eq` CSS Selectors method declarations.
## [0.3.0](https://github.com/iabudiab/HTMLKit/releases/tag/0.3.0)
Released on 2015.11.29
### Added
- CSS3 Selectors support.
- Nullability annotations.
- `HTMLNode` properties for previous and next sibling elements.
- `HTMLNode` methods for accessing child elements (analogous to child nodes).
- `NSCharacterSet` category for HTML-related character sets.
### Fixed
- `InputStreaReader`'s reconsume-logic that is required by the CSS Parser.
## [0.2.0](https://github.com/iabudiab/HTMLKit/releases/tag/0.1.0)
Released on 2015.06.06
### Added
- `HTMLDocument` methods to access `root`, `head` & `body` elements.
- `innerHTML` implementation for the `HTMLElement`.
- `HTMLNode` methods to append, prepend, check containment and descendancy of nodes.
- `HTMLNode` methods to enumerate child nodes.
- Implementations for `NodeIterator` and `NodeFilter`
- Implementation for `TreeWalker`
- Validation for DOM manipulations.
- Tests for the DOM implementation.
### Changed
- `type` property renamed to `nodeType` in `HTMLNode`.
- `firstChildNode` and `lastChildNode` renamed to `firtChild` and `lastChild` in `HTMLNode`.
### Removed
- `baseURI` proeprty from `HTMLNode`
- `HTMLNodeTreeEnumerator` is superseded by the `HTMLNodeIterator`.
## [0.1.0](https://github.com/iabudiab/HTMLKit/releases/tag/0.1.0)
Released on 2015.04.20
### Added
- Initial release.
- Initial DOM implementation.
- Tokenizer and Parser pass all [HTML5Lib](https://github.com/html5lib/html5lib-tests) tokenizer and tree construction tests except for `<ruby>` elements.
@@ -0,0 +1,273 @@
// !$*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 = "<group>"; };
/* 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 = "<group>";
};
629A63CA1D9AFE0E0089679F /* Products */ = {
isa = PBXGroup;
children = (
629A63C91D9AFE0E0089679F /* HTMLKitExample */,
);
name = Products;
sourceTree = "<group>";
};
629A63CB1D9AFE0E0089679F /* HTMLKitExample */ = {
isa = PBXGroup;
children = (
629A63CC1D9AFE0E0089679F /* main.swift */,
);
path = HTMLKitExample;
sourceTree = "<group>";
};
/* 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 = 0900;
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_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;
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_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_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;
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_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;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
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;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 629A63C11D9AFE0E0089679F /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:HTMLKitExample.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "629A63C81D9AFE0E0089679F"
BuildableName = "HTMLKitExample"
BlueprintName = "HTMLKitExample"
ReferencedContainer = "container:HTMLKitExample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "629A63C81D9AFE0E0089679F"
BuildableName = "HTMLKitExample"
BlueprintName = "HTMLKitExample"
ReferencedContainer = "container:HTMLKitExample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "629A63C81D9AFE0E0089679F"
BuildableName = "HTMLKitExample"
BlueprintName = "HTMLKitExample"
ReferencedContainer = "container:HTMLKitExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "629A63C81D9AFE0E0089679F"
BuildableName = "HTMLKitExample"
BlueprintName = "HTMLKitExample"
ReferencedContainer = "container:HTMLKitExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -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 <p>Hello</p> and <a href='example.com'>Hello</a>
// but wont match <div>World</div> or <p>Hello there</p>
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 <td> elements of class "content" i.e. <td class='content'>
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)
}
@@ -0,0 +1,80 @@
//: [Previous](@previous)
/*:
# CSS3 Selectors
HTMLKit understands CSS3 selectors making node-selection a piece of cake:
*/
import HTMLKit
let htmlString = "<div><h1>HTMLKit</h1><p class='greeting'>Hello there!</p><p class='description'>This is a demo of HTMLKit</p></div>"
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.elements(matching: typeSelector("p"))
paragraphsOrHeaders = document.elements(matching:
anyOf([
typeSelector("p"), typeSelector("h1")
])
)
hasClassAttribute = document.elements(matching: hasAttributeSelector("class"))
greetings = document.elements(matching: classSelector("greeting"))
classNameStartsWith_de = document.elements(matching: attributeSelector(.begins, "class", "de"))
hasAdjacentHeader = document.elements(matching: adjacentSiblingSelector(typeSelector("h1")))
hasAdjacentHeader = document.elements(matching: generalSiblingSelector(typeSelector("h1")))
hasAdjacentHeader = document.elements(matching: generalSiblingSelector(typeSelector("p")))
nonParagraphChildOfDiv = document.elements(matching:
allOf([
childOfElementSelector(typeSelector("div")),
not(typeSelector("p"))
])
)
/*:
Here are more examples
*/
let firstDivElement = document.firstElement(matching: typeSelector("div"))!
var secondChildOfDiv = firstDivElement.querySelectorAll(":nth-child(2)")
var secondOfType = firstDivElement.querySelectorAll(":nth-of-type(2n)")
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.elements(matching:
allOf([
not(typeSelector("p")),
not(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.elements(matching: myAwesomeSelector)
@@ -0,0 +1,30 @@
/*:
# HTMLKit
![Logo](HTMLKit.png)
****
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)
*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=572&amp;EndingColumnNumber=5&amp;EndingLineNumber=27&amp;StartingColumnNumber=1&amp;StartingLineNumber=26&amp;Timestamp=472575682.16404"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=572&amp;EndingColumnNumber=9&amp;EndingLineNumber=27&amp;StartingColumnNumber=5&amp;StartingLineNumber=26&amp;Timestamp=472575682.164357"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=572&amp;EndingColumnNumber=9&amp;EndingLineNumber=27&amp;StartingColumnNumber=5&amp;StartingLineNumber=26&amp;Timestamp=472575682.16458"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=572&amp;EndingColumnNumber=9&amp;EndingLineNumber=1&amp;StartingColumnNumber=5&amp;StartingLineNumber=1&amp;Timestamp=472575682.164803"
lockedSize = "{309, 236}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
@@ -0,0 +1,30 @@
//: [Previous](@previous)
/*:
# Parsing HTML Documents
*/
import HTMLKit
/*:
Given some HTML content
*/
let htmlString = "<div><h1>HTMLKit</h1><p class='greeting'>Hello there!</p><p class='description'>This is a demo of HTMLKit</p></div>"
htmlString
/*:
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)
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=581&amp;EndingColumnNumber=26&amp;EndingLineNumber=11&amp;StartingColumnNumber=1&amp;StartingLineNumber=11&amp;Timestamp=496084829.845787"
lockedSize = "{800, 186}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=27&amp;CharacterRangeLoc=393&amp;EndingColumnNumber=28&amp;EndingLineNumber=20&amp;StartingColumnNumber=1&amp;StartingLineNumber=20&amp;Timestamp=496084834.772773"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=18&amp;CharacterRangeLoc=544&amp;EndingColumnNumber=19&amp;EndingLineNumber=27&amp;StartingColumnNumber=1&amp;StartingLineNumber=27&amp;Timestamp=496084834.772773"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
@@ -0,0 +1,38 @@
//: [Previous](@previous)
/*:
# Parsing Document Fragments
*/
import HTMLKit
/*:
Given some HTML content
*/
let htmlString = "<div><p>Hello HTMLKit</p></div><td>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.parseFragment(withContextElement: tableContext)
for element in elements {
print(element.outerHTML)
}
/*:
The same parser instance can be reusued:
*/
let bodyContext = HTMLElement(tagName: "body")
elements = parser.parseFragment(withContextElement: bodyContext)
for element in elements {
print(element.outerHTML)
}
//: [Next](@next)
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=356&amp;EndingColumnNumber=16&amp;EndingLineNumber=23&amp;StartingColumnNumber=2&amp;StartingLineNumber=23&amp;Timestamp=472578641.006172"
lockedSize = "{775, 114}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=356&amp;EndingColumnNumber=23&amp;EndingLineNumber=23&amp;StartingColumnNumber=2&amp;StartingLineNumber=23&amp;Timestamp=472578641.006502"
lockedSize = "{775, 80}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=21&amp;CharacterRangeLoc=262&amp;EndingColumnNumber=23&amp;EndingLineNumber=13&amp;StartingColumnNumber=2&amp;StartingLineNumber=13&amp;Timestamp=472578641.006717"
lockedSize = "{775, 76}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=24&amp;CharacterRangeLoc=455&amp;EndingColumnNumber=26&amp;EndingLineNumber=23&amp;StartingColumnNumber=2&amp;StartingLineNumber=23&amp;Timestamp=495492881.371878"
lockedSize = "{775, 83}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=24&amp;CharacterRangeLoc=672&amp;EndingColumnNumber=26&amp;EndingLineNumber=34&amp;StartingColumnNumber=2&amp;StartingLineNumber=34&amp;Timestamp=495493308.359844"
lockedSize = "{775, 76}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=24&amp;CharacterRangeLoc=281&amp;EndingColumnNumber=26&amp;EndingLineNumber=13&amp;StartingColumnNumber=2&amp;StartingLineNumber=13&amp;Timestamp=472579861.71569"
lockedSize = "{775, 68}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=24&amp;CharacterRangeLoc=450&amp;EndingColumnNumber=26&amp;EndingLineNumber=21&amp;StartingColumnNumber=2&amp;StartingLineNumber=21&amp;Timestamp=495492881.372527"
lockedSize = "{775, 68}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
@@ -0,0 +1,81 @@
//: [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 = "<div><h1>HTMLKit</h1><p>Hello there!</p></div>"
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.append(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.append(nodes)
body.innerHTML
/*:
Enumerate child elements and perform DOM manipulation
*/
body.enumerateChildElements { (element, index, stop) -> Void in
if element.tagName == "div" {
let lorem = HTMLElement(tagName: "p")
lorem.textContent = "Lorem ipsum: \(index)"
element.append(lorem)
}
}
body.innerHTML
/*:
Remove nodes from the document
*/
body.removeChildNode(at: 1)
body.innerHTML
/*:
Navigate to child and sibling nodes
*/
body.lastChild!.removeFromParentNode()
let greenDiv = body.firstChild!.nextSibling!
greenDiv.outerHTML
/*:
Manipulate the HTML directly
*/
greenDiv.innerHTML = "<ul><li>item 1<li>item 2"
greenDiv.outerHTML
/*:
Iterate the DOM tree with custom filters
*/
let filter = HTMLNodeFilterBlock.filter { (node) -> HTMLNodeFilterValue in
if node.childNodesCount() != 1 {
return .reject
}
return .accept
}
for element in body.nodeIterator(showOptions: .element, filter: filter) {
(element as! AnyObject).outerHTML
}
//: [Next](@next)
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=19&amp;CharacterRangeLoc=571&amp;EndingColumnNumber=26&amp;EndingLineNumber=24&amp;StartingColumnNumber=1&amp;StartingLineNumber=24&amp;Timestamp=495493395.434491"
lockedSize = "{763, 104}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=15&amp;CharacterRangeLoc=834&amp;EndingColumnNumber=22&amp;EndingLineNumber=33&amp;StartingColumnNumber=1&amp;StartingLineNumber=33&amp;Timestamp=495493408.111041"
lockedSize = "{763, 75}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=1&amp;CharacterRangeLoc=1774&amp;EndingColumnNumber=44&amp;EndingLineNumber=77&amp;StartingColumnNumber=2&amp;StartingLineNumber=77&amp;Timestamp=496085091.150842"
lockedSize = "{763, 176}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=835&amp;EndingColumnNumber=15&amp;EndingLineNumber=33&amp;StartingColumnNumber=1&amp;StartingLineNumber=33&amp;Timestamp=495493408.111552"
lockedSize = "{762, 70}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=18&amp;CharacterRangeLoc=572&amp;EndingColumnNumber=19&amp;EndingLineNumber=24&amp;StartingColumnNumber=1&amp;StartingLineNumber=24&amp;Timestamp=495493395.435449"
lockedSize = "{752, 99}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=1&amp;CharacterRangeLoc=1774&amp;EndingColumnNumber=16&amp;EndingLineNumber=77&amp;StartingColumnNumber=2&amp;StartingLineNumber=77&amp;Timestamp=496085091.151491"
lockedSize = "{763, 102}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=33&amp;CharacterRangeLoc=1742&amp;EndingColumnNumber=39&amp;EndingLineNumber=77&amp;StartingColumnNumber=2&amp;StartingLineNumber=77&amp;Timestamp=496085091.151711"
lockedSize = "{759, 149}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=32&amp;CharacterRangeLoc=1743&amp;EndingColumnNumber=19&amp;EndingLineNumber=77&amp;StartingColumnNumber=2&amp;StartingLineNumber=77&amp;Timestamp=496085091.151931"
lockedSize = "{763, 120}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=1204&amp;EndingColumnNumber=15&amp;EndingLineNumber=51&amp;StartingColumnNumber=1&amp;StartingLineNumber=51&amp;Timestamp=495493441.437517"
lockedSize = "{763, 94}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=1122&amp;EndingColumnNumber=15&amp;EndingLineNumber=45&amp;StartingColumnNumber=1&amp;StartingLineNumber=45&amp;Timestamp=495493427.982381"
lockedSize = "{760, 97}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=18&amp;CharacterRangeLoc=397&amp;EndingColumnNumber=19&amp;EndingLineNumber=14&amp;StartingColumnNumber=1&amp;StartingLineNumber=14&amp;Timestamp=472578662.199111"
lockedSize = "{762, 90}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=697&amp;EndingColumnNumber=15&amp;EndingLineNumber=26&amp;StartingColumnNumber=1&amp;StartingLineNumber=26&amp;Timestamp=495493395.437213"
lockedSize = "{763, 76}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=983&amp;EndingColumnNumber=15&amp;EndingLineNumber=38&amp;StartingColumnNumber=1&amp;StartingLineNumber=38&amp;Timestamp=495493427.983236"
lockedSize = "{763, 92}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=1030&amp;EndingColumnNumber=15&amp;EndingLineNumber=41&amp;StartingColumnNumber=1&amp;StartingLineNumber=41&amp;Timestamp=495493427.983458"
lockedSize = "{763, 83}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=8&amp;CharacterRangeLoc=1089&amp;EndingColumnNumber=13&amp;EndingLineNumber=44&amp;StartingColumnNumber=5&amp;StartingLineNumber=44&amp;Timestamp=495493427.983688"
lockedSize = "{763, 73}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=17&amp;CharacterRangeLoc=1601&amp;EndingColumnNumber=19&amp;EndingLineNumber=70&amp;StartingColumnNumber=2&amp;StartingLineNumber=70&amp;Timestamp=496085091.153628"
lockedSize = "{763, 92}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=586&amp;EndingColumnNumber=15&amp;EndingLineNumber=21&amp;StartingColumnNumber=1&amp;StartingLineNumber=21&amp;Timestamp=495493395.438545"
lockedSize = "{763, 50}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=9&amp;CharacterRangeLoc=826&amp;EndingColumnNumber=15&amp;EndingLineNumber=30&amp;StartingColumnNumber=1&amp;StartingLineNumber=30&amp;Timestamp=495493408.115325"
lockedSize = "{763, 50}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=14&amp;CharacterRangeLoc=868&amp;EndingColumnNumber=15&amp;EndingLineNumber=33&amp;StartingColumnNumber=1&amp;StartingLineNumber=33&amp;Timestamp=495493408.115547"
lockedSize = "{763, 50}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=8&amp;CharacterRangeLoc=927&amp;EndingColumnNumber=13&amp;EndingLineNumber=36&amp;StartingColumnNumber=5&amp;StartingLineNumber=36&amp;Timestamp=495493408.115762"
lockedSize = "{763, 50}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=8&amp;CharacterRangeLoc=959&amp;EndingColumnNumber=9&amp;EndingLineNumber=38&amp;StartingColumnNumber=1&amp;StartingLineNumber=38&amp;Timestamp=495493427.985192"
lockedSize = "{763, 50}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=17&amp;CharacterRangeLoc=1235&amp;EndingColumnNumber=19&amp;EndingLineNumber=48&amp;StartingColumnNumber=2&amp;StartingLineNumber=48&amp;Timestamp=495493441.440785"
lockedSize = "{763, 92}"
selectedRepresentationIndex = "1"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=18&amp;CharacterRangeLoc=1451&amp;EndingColumnNumber=19&amp;EndingLineNumber=64&amp;StartingColumnNumber=1&amp;StartingLineNumber=64&amp;Timestamp=496085091.155099"
lockedSize = "{740, 65}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "YES">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=18&amp;CharacterRangeLoc=1347&amp;EndingColumnNumber=19&amp;EndingLineNumber=58&amp;StartingColumnNumber=1&amp;StartingLineNumber=58&amp;Timestamp=496085092.425909"
lockedSize = "{740, 69}"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='6.0' target-platform='macos' display-mode='rendered' last-migration='0800'>
<pages>
<page name='Intro'/>
<page name='Parsing Documents'/>
<page name='Parsing Fragments'/>
<page name='The DOM'/>
<page name='CSS Selectors'/>
</pages>
</playground>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

+23
View File
@@ -0,0 +1,23 @@
Pod::Spec.new do |s|
s.name = "HTMLKit"
s.version = "2.1.1"
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
s.license = "MIT"
s.homepage = "https://github.com/iabudiab/HTMLKit"
s.author = "iabudiab"
s.social_media_url = "https://twitter.com/_iabudiab"
s.ios.deployment_target = "8.0"
s.osx.deployment_target = "10.9"
s.watchos.deployment_target = "2.0"
s.tvos.deployment_target = "9.0"
s.source = { :git => "https://github.com/iabudiab/HTMLKit.git", :tag => s.version }
s.source_files = "Sources", "Sources/**/*.{h,m}"
s.private_header_files = [
'Sources/**/*{HTMLToken,HTMLTokens,HTMLTagToken,HTMLCharacterToken,HTMLCommentToken,HTMLDOCTYPEToken,HTMLEOFToken,HTMLTokenizer,HTMLTokenizerCharacters,HTMLTokenizerEntities,HTMLTokenizerStates,HTMLElementAdjustment,HTMLElementTypes,HTMLInputStreamReader,HTMLListOfActiveFormattingElements,HTMLParseErrorToken,HTMLParserInsertionModes,HTMLStackOfOpenElements,HTMLMarker,HTMLNode+Private,HTMLDocument+Private,HTMLCharacterData+Private,HTMLRange+Private,HTMLParser+Private,HTMLNodeIterator+Private,HTMLNodeTraversal,HTMLDOMUtils,CSSCodePoints,CSSInputStream}.h'
]
s.requires_arc = true
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62ECBF4C1C0B6C7600AF847B"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-iOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62ECBF551C0B6C7600AF847B"
BuildableName = "HTMLKitTests-iOS.xctest"
BlueprintName = "HTMLKitTests-iOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "HTMLKitParserPerformance">
</Test>
<Test
Identifier = "HTMLKitParserPerformance/testParserPerformance">
</Test>
<Test
Identifier = "HTMLKitTokenizerPerformance">
</Test>
<Test
Identifier = "HTMLKitTokenizerPerformance/testTokenizerPerformance">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62ECBF4C1C0B6C7600AF847B"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-iOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62ECBF4C1C0B6C7600AF847B"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-iOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62ECBF4C1C0B6C7600AF847B"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-iOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "625A14AB19C7829400AD0C32"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-macOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "625A14C219C7829400AD0C32"
BuildableName = "HTMLKitTests-macOS.xctest"
BlueprintName = "HTMLKitTests-macOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "HTMLKitParserPerformance">
</Test>
<Test
Identifier = "HTMLKitParserPerformance/testParserPerformance">
</Test>
<Test
Identifier = "HTMLKitTokenizerPerformance">
</Test>
<Test
Identifier = "HTMLKitTokenizerPerformance/testTokenizerPerformance">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "625A14AB19C7829400AD0C32"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-macOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "625A14AB19C7829400AD0C32"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-macOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "625A14AB19C7829400AD0C32"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-macOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857CE91D39A262008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-tvOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857CF21D39A262008DC254"
BuildableName = "HTMLKit-tvOSTests.xctest"
BlueprintName = "HTMLKit-tvOSTests"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "HTMLKitParserPerformance">
</Test>
<Test
Identifier = "HTMLKitTokenizerPerformance">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857CE91D39A262008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-tvOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857CE91D39A262008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-tvOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857CE91D39A262008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-tvOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857C4D1D398642008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-watchOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857C4D1D398642008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-watchOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "62857C4D1D398642008DC254"
BuildableName = "HTMLKit.framework"
BlueprintName = "HTMLKit-watchOS"
ReferencedContainer = "container:HTMLKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+6
View File
@@ -4,4 +4,10 @@
<FileRef
location = "group:HTMLKit.xcodeproj">
</FileRef>
<FileRef
location = "group:HTMLKit.playground">
</FileRef>
<FileRef
location = "group:Example/HTMLKitExample/HTMLKitExample.xcodeproj">
</FileRef>
</Workspace>
-30
View File
@@ -1,30 +0,0 @@
//
// CSSAttributeSelector.h
// HTMLKit
//
// Created by Iska on 14/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "CSSSelector.h"
NS_ASSUME_NONNULL_BEGIN
@interface CSSAttributeSelector : CSSSelector
@property (nonatomic, assign) CSSAttributeSelectorType type;
@property (nonatomic, strong, readonly) NSString *name;
@property (nonatomic, strong, readonly) NSString *value;
+ (instancetype)classSelector:(NSString *)className;
+ (instancetype)idSelector:(NSString *)elementId;
+ (instancetype)hasAttributeSelector:(NSString *)attributeName;
- (instancetype)initWithType:(CSSAttributeSelectorType)type
attributeName:(NSString *)name
attrbiuteValue:(NSString *)value;
@end
NS_ASSUME_NONNULL_END
-22
View File
@@ -1,22 +0,0 @@
//
// CSSCombinatorSelector.h
// HTMLKit
//
// Created by Iska on 12/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import "CSSSelector.h"
NS_ASSUME_NONNULL_BEGIN
@interface CSSCombinatorSelector : CSSSelector
+ (instancetype)childOfElementCombinator:(CSSSelector *)selector;
+ (instancetype)descendantOfElementCombinator:(CSSSelector *)selector;
+ (instancetype)adjacentSiblingCombinator:(CSSSelector *)selector;
+ (instancetype)generalSiblingCombinator:(CSSSelector *)selector;
@end
NS_ASSUME_NONNULL_END
-22
View File
@@ -1,22 +0,0 @@
//
// CSSCompoundSelector.h
// HTMLKit
//
// Created by Iska on 18/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import "CSSSelector.h"
NS_ASSUME_NONNULL_BEGIN
@interface CSSCompoundSelector : CSSSelector
+ (instancetype)andSelector:(NSArray<CSSSelector *> *)selectors;
+ (instancetype)orSelector:(NSArray<CSSSelector *> *)selectors;
- (void)addSelector:(CSSSelector *)selector;
@end
NS_ASSUME_NONNULL_END
-20
View File
@@ -1,20 +0,0 @@
//
// CSSInputStream.h
// HTMLKit
//
// Created by Iska on 07/06/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLInputStreamReader.h"
@interface CSSInputStream : HTMLInputStreamReader
- (void)consumeWhitespace;
- (NSString *)consumeIdentifier;
- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint;
- (UTF32Char)consumeEscapedCodePoint;
- (NSString *)consumeCombinator;
@end
-25
View File
@@ -1,25 +0,0 @@
//
// CSSNthExpressionSelector.h
// HTMLKit
//
// Created by Iska on 10/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import "CSSSelector.h"
NS_ASSUME_NONNULL_BEGIN
@interface CSSNthExpressionSelector : CSSSelector
@property (nonatomic, strong, readonly) NSString *className;
@property (nonatomic, assign, readonly) CSSNthExpression expression;
+ (instancetype)nthChildSelector:(CSSNthExpression)expression;
+ (instancetype)nthLastChildSelector:(CSSNthExpression)expression;
+ (instancetype)nthOfTypeSelector:(CSSNthExpression)expression;
+ (instancetype)nthLastOfTypeSelector:(CSSNthExpression)expression;
@end
NS_ASSUME_NONNULL_END
-20
View File
@@ -1,20 +0,0 @@
//
// CSSPseudoFunctionSelector.h
// HTMLKit
//
// Created by Iska on 07/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import "CSSSelector.h"
NS_ASSUME_NONNULL_BEGIN
@interface CSSPseudoFunctionSelector : CSSSelector
+ (instancetype)notSelector:(CSSSelector *)selector;
+ (instancetype)hasSelector:(CSSSelector *)selector;
@end
NS_ASSUME_NONNULL_END
-49
View File
@@ -1,49 +0,0 @@
//
// HTMLSelector.h
// HTMLKit
//
// Created by Iska on 02/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#pragma mark - Attribute Selector Type
typedef NS_ENUM(NSUInteger, CSSAttributeSelectorType)
{
CSSAttributeSelectorExists,
CSSAttributeSelectorExactMatch,
CSSAttributeSelectorIncludes,
CSSAttributeSelectorBegins,
CSSAttributeSelectorEnds,
CSSAttributeSelectorContains,
CSSAttributeSelectorHyphen,
CSSAttributeSelectorNot
};
#pragma mark - CSS Nth-Expression
typedef struct CSSNthExpression
{
NSInteger an;
NSInteger b;
} CSSNthExpression;
NS_INLINE CSSNthExpression CSSNthExpressionMake(NSInteger an, NSInteger b) {
return (CSSNthExpression){ .an = an, .b = b };
}
extern const CSSNthExpression CSSNthExpressionOdd;
extern const CSSNthExpression CSSNthExpressionEven;
extern NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression);
#pragma mark - Base Selector Class
@class HTMLElement;
@interface CSSSelector : NSObject
- (BOOL)acceptElement:(nonnull HTMLElement *)element;
@end
-17
View File
@@ -1,17 +0,0 @@
//
// CSSSelectorParser.h
// HTMLKit
//
// Created by Iska on 02/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@class CSSSelector;
@interface CSSSelectorParser : NSObject
+ (CSSSelector *)parseSelector:(NSString *)string error:(NSError **)error;
@end
-71
View File
@@ -1,71 +0,0 @@
//
// CSSSelectors.h
// HTMLKit
//
// Created by Iska on 14/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "CSSSelector.h"
#import "CSSStructuralPseudoSelectors.h"
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Type Selectors
extern CSSSelector * universalSelector();
extern CSSSelector * typeSelector(NSString *type);
#pragma mark - Atribute Selectors
extern CSSSelector * idSelector(NSString *elementId);
extern CSSSelector * classSelector(NSString *className);
extern CSSSelector * hasAttributeSelector(NSString *attribute);
extern CSSSelector * attributeSelector(CSSAttributeSelectorType type,
NSString *attribute,
NSString *value);
#pragma mark - Nth-Expression Selectors
extern CSSSelector * nthChildSelector(CSSNthExpression expression);
extern CSSSelector * nthLastChildSelector(CSSNthExpression expression);
extern CSSSelector * nthOfTypeSelector(CSSNthExpression expression);
extern CSSSelector * nthLastOfTypeSelector(CSSNthExpression expression);
extern CSSSelector * oddSelector();
extern CSSSelector * evenSlector();
extern CSSSelector * firstChildSelector();
extern CSSSelector * lastChildSelector();
extern CSSSelector * firstOfTypeSelector();
extern CSSSelector * lastOfTypeSelector();
extern CSSSelector * onlyChildSelector();
extern CSSSelector * onlyOfTypeSelector();
#pragma mark - Combinators
extern CSSSelector * childOfElementSelector(CSSSelector *selector);
extern CSSSelector * descendantOfElementSelector(CSSSelector *selector);
extern CSSSelector * adjacentSiblingSelector(CSSSelector *selector);
extern CSSSelector * generalSiblingSelector(CSSSelector *selector);
#pragma mark - Pseudo Functions
extern CSSSelector * nay(CSSSelector *selector);
extern CSSSelector * has(CSSSelector *selector);
#pragma mark - Compound Selectors
extern CSSSelector * allOf(NSArray<CSSSelector *> *selectors);
extern CSSSelector * anyOf(NSArray<CSSSelector *> *selectors);
#pragma mark - Pseudo
extern CSSSelector * namedPseudoSelector(NSString *name, CSSSelector *selector);
#pragma mark - Block
extern CSSSelector * namedBlockSelector(NSString *name, BOOL (^ acceptBlock)(HTMLElement *element));
NS_ASSUME_NONNULL_END
-40
View File
@@ -1,40 +0,0 @@
//
// CSSStructuralPseudoSelector.h
// HTMLKit
//
// Created by Iska on 11/10/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
@class CSSSelector;
NS_ASSUME_NONNULL_BEGIN
extern CSSSelector * rootSelector();
extern CSSSelector * emptySelector();
extern CSSSelector * parentSelector();
extern CSSSelector * buttonSelector();
extern CSSSelector * checkboxSelector();
extern CSSSelector * fileSelector();
extern CSSSelector * headerSelector();
extern CSSSelector * imageSelector();
extern CSSSelector * inputSelector();
extern CSSSelector * linkSelector();
extern CSSSelector * passwordSelector();
extern CSSSelector * radioSelector();
extern CSSSelector * resetSelector();
extern CSSSelector * submitSelector();
extern CSSSelector * textSelector();
extern CSSSelector * enabledSelector();
extern CSSSelector * disabledSelector();
extern CSSSelector * checkedSelector();
extern CSSSelector * optionalSelector();
extern CSSSelector * requiredSelector();
extern CSSSelector * ltSelector();
extern CSSSelector * gtSelector();
extern CSSSelector * eqSelector();
NS_ASSUME_NONNULL_END
-27
View File
@@ -1,27 +0,0 @@
//
// HTMLCharacterToken.h
// HTMLKit
//
// Created by Iska on 23/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLToken.h"
@interface HTMLCharacterToken : HTMLToken
@property (nonatomic, copy) NSString *characters;
- (instancetype)initWithString:(NSString *)string;
- (void)appendString:(NSString *)string;
- (BOOL)isWhitespaceToken;
- (BOOL)isEmpty;
- (void)retainLeadingWhitespace;
- (void)trimLeadingWhitespace;
- (void)trimFormIndex:(NSUInteger)index;
- (HTMLCharacterToken *)tokenBySplitingLeadingWhiteSpace;
@end
-17
View File
@@ -1,17 +0,0 @@
//
// HTMLComment.h
// HTMLKit
//
// Created by Iska on 25/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLNode.h"
@interface HTMLComment : HTMLNode
@property (nonatomic, copy) NSString *data;
- (instancetype)initWithData:(NSString *)data;
@end
-20
View File
@@ -1,20 +0,0 @@
//
// HTMLCommentToken.h
// HTMLKit
//
// Created by Iska on 23/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLToken.h"
@interface HTMLCommentToken : HTMLToken
@property (nonatomic, copy) NSString *data;
- (instancetype)initWithData:(NSString *)data;
- (void)appendStringToData:(NSString *)string;
@end
-25
View File
@@ -1,25 +0,0 @@
//
// HTMLDOCTYPEToken.h
// HTMLKit
//
// Created by Iska on 23/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLToken.h"
@interface HTMLDOCTYPEToken : HTMLToken
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSMutableString *publicIdentifier;
@property (nonatomic, strong) NSMutableString *systemIdentifier;
@property (nonatomic, assign) BOOL forceQuirks;
- (instancetype)initWithName:(NSString *)name;
- (void)appendStringToName:(NSString *)string;
- (void)appendStringToPublicIdentifier:(NSString *)string;
- (void)appendStringToSystemIdentifier:(NSString *)string;
@end
-44
View File
@@ -1,44 +0,0 @@
//
// HTMLDocument.h
// HTMLKit
//
// Created by Iska on 25/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLNode.h"
#import "HTMLDocumentType.h"
#import "HTMLQuirksMode.h"
typedef NS_ENUM(short, HTMLDocumentReadyState)
{
HTMLDocumentLoading,
HTMLDocumentInteractive, // Not used
HTMLDocumentComplete
};
@interface HTMLDocument : HTMLNode
@property (nonatomic, strong) HTMLDocumentType *documentType;
@property (nonatomic, assign) HTMLQuirksMode quirksMode;
@property (nonatomic, copy, readonly) NSString *compatMode;
@property (nonatomic, assign, readonly) HTMLDocumentReadyState readyState;
@property (nonatomic, strong) HTMLElement *rootElement;
@property (nonatomic, strong) HTMLElement *documentElement;
@property (nonatomic, strong) HTMLElement *head;
@property (nonatomic, strong) HTMLElement *body;
+ (instancetype)documentWithString:(NSString *)string;
- (HTMLNode *)adoptNode:(HTMLNode *)node;
- (HTMLDocument *)associatedInertTemplateDocument;
@end
-15
View File
@@ -1,15 +0,0 @@
//
// HTMLDocumentFragment.h
// HTMLKit
//
// Created by Iska on 12/04/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLNode.h"
@interface HTMLDocumentFragment : HTMLNode
- (instancetype)initWithDocument:(HTMLDocument *)document;
@end
-25
View File
@@ -1,25 +0,0 @@
//
// HTMLDocumentType.h
// HTMLKit
//
// Created by Iska on 25/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLNode.h"
#import "HTMLQuirksMode.h"
@interface HTMLDocumentType : HTMLNode
@property (nonatomic, copy, readonly) NSString *publicIdentifier;
@property (nonatomic, copy, readonly) NSString *systemIdentifier;
- (instancetype)initWithName:(NSString *)name
publicIdentifier:(NSString *)publicIdentifier
systemIdentifier:(NSString *)systemIdentifier;
- (BOOL)isValid;
- (HTMLQuirksMode)quirksMode;
@end
-15
View File
@@ -1,15 +0,0 @@
//
// HTMLEOFToken.h
// HTMLKit
//
// Created by Iska on 15/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLToken.h"
@interface HTMLEOFToken : HTMLToken
+ (instancetype)token;
@end
-34
View File
@@ -1,34 +0,0 @@
//
// HTMLElement.h
// HTMLKit
//
// Created by Iska on 05/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLNamespaces.h"
#import "HTMLNode.h"
@interface HTMLElement : HTMLNode
@property (nonatomic, assign, readonly) HTMLNamespace htmlNamespace;
@property (nonatomic, copy, readonly) NSString *tagName;
@property (nonatomic, strong) NSMutableDictionary *attributes;
@property (nonatomic, copy) NSString *elementId;
@property (nonatomic, copy) NSString *className;
- (instancetype)initWithTagName:(NSString *)tagName;
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes;
- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary *)attributes;
- (BOOL)hasAttribute:(NSString *)name;
- (NSString *)objectForKeyedSubscript:(NSString *)name;
- (void)setObject:(NSString *)value forKeyedSubscript:(NSString *)attribute;
- (void)removeAttribute:(NSString *)name;
@end
-46
View File
@@ -1,46 +0,0 @@
//
// HTMLInputStreamReader.h
// HTMLKit
//
// Created by Iska on 15/09/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason);
/**
* HTML Input Stream Reader processor conforming to the HTML standard
* http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#preprocessing-the-input-stream
*/
@interface HTMLInputStreamReader : NSObject
@property (nonatomic, readonly) NSString *string;
@property (nonatomic, readonly) NSUInteger currentLocation;
@property (nonatomic, copy) HTMLStreamReaderErrorCallback errorCallback;
- (id)initWithString:(NSString *)string;
- (UTF32Char)currentInputCharacter;
- (UTF32Char)nextInputCharacter;
- (UTF32Char)inputCharacterPointAtOffset:(NSUInteger)offset;
- (UTF32Char)consumeNextInputCharacter;
- (void)reconsumeCurrentInputCharacter;
- (void)unconsumeCurrentInputCharacter;
- (BOOL)consumeCharacter:(UTF32Char)character;
- (BOOL)consumeNumber:(unsigned long long *)result;
- (BOOL)consumeHexNumber:(unsigned long long *)result;
- (BOOL)consumeString:(NSString *)string caseSensitive:(BOOL)caseSensitive;
- (NSString *)consumeCharactersUpToCharactersInString:(NSString *)characters;
- (NSString *)consumeCharactersUpToString:(NSString *)string;
- (NSString *)consumeCharactersInString:(NSString *)characters;
- (NSString *)consumeAlphanumericCharacters;
- (void)markCurrentLocation;
- (void)rewindToMarkedLocation;
- (void)reset;
@end
-9
View File
@@ -1,9 +0,0 @@
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif
-12
View File
@@ -1,12 +0,0 @@
//
// HTMLKit.h
// HTMLKit
//
// Created by Iska on 15/09/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import "HTMLParser.h"
#import "HTMLDOM.h"
#import "CSSSelectors.h"
#import "HTMLKitErrorDomain.h"
-11
View File
@@ -1,11 +0,0 @@
//
// HTMLKitExceptions.h
// HTMLKit
//
// Created by Iska on 17/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
FOUNDATION_EXPORT NSString * const HTMLKitHierarchyRequestError;
FOUNDATION_EXPORT NSString * const HTMLKitNotFoundError;
FOUNDATION_EXPORT NSString * const HTMLKitNotSupportedError;
-13
View File
@@ -1,13 +0,0 @@
//
// HTMLKitExceptions.m
// HTMLKit
//
// Created by Iska on 17/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLKitDOMExceptions.h"
NSString * const HTMLKitHierarchyRequestError = @"HierarchyRequestError";
NSString * const HTMLKitNotFoundError = @"NotFoundError";
NSString * const HTMLKitNotSupportedError = @"NotSupportedError";
@@ -1,38 +0,0 @@
//
// HTMLListOfActiveFormattingElements.h
// HTMLKit
//
// Created by Iska on 22/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLElement.h"
@interface HTMLListOfActiveFormattingElements : NSObject
- (id)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
- (NSUInteger)indexOfElement:(id)node;
- (void)addElement:(HTMLElement *)element;
- (void)removeElement:(id)element;
- (BOOL)containsElement:(id)element;
- (void)insertElement:(HTMLElement *)element atIndex:(NSUInteger)index;
- (void)replaceElementAtIndex:(NSUInteger)index withElement:(HTMLElement *)element;
- (id)lastEntry;
- (void)addMarker;
- (void)clearUptoLastMarker;
- (HTMLElement *)formattingElementWithTagName:(NSString *)tagName;
- (NSUInteger)count;
- (BOOL)isEmpty;
- (NSEnumerator *)enumerator;
- (NSEnumerator *)reverseObjectEnumerator;
@end
-15
View File
@@ -1,15 +0,0 @@
//
// HTMLMarker.h
// HTMLKit
//
// Created by Iska on 02/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface HTMLMarker : NSObject
+ (instancetype)marker;
@end
-17
View File
@@ -1,17 +0,0 @@
//
// HTMLNamespaces.h
// HTMLKit
//
// Created by Iska on 03/11/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
typedef NS_ENUM(NSInteger, HTMLNamespace)
{
HTMLNamespaceHTML,
HTMLNamespaceMathML,
HTMLNamespaceSVG,
HTMLNamespaceXLink,
HTMLNamespaceXML,
HTMLNamespaceXMLNS,
};
-140
View File
@@ -1,140 +0,0 @@
//
// HTMLNode.h
// HTMLKit
//
// Created by Iska on 24/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLNodeIterator.h"
typedef NS_ENUM(short, HTMLNodeType)
{
HTMLNodeElement = 1,
HTMLNodeAttribute = 2, // historical
HTMLNodeText = 3,
HTMLNodeCDATASection = 4, // historical
HTMLNodeEntityReference = 5, // historical
HTMLNodeEntity = 6, // historical
HTMLNodeProcessingInstruction = 7,
HTMLNodeComment = 8,
HTMLNodeDocument = 9,
HTMLNodeDocumentType = 10,
HTMLNodeDocumentFragment = 11,
HTMLNodeNotation = 12 // historical
};
typedef NS_ENUM(unsigned short, HTMLDocumentPosition)
{
HTMLDocumentPositionEquivalent = 0x0,
HTMLDocumentPositionDisconnected = 0x01,
HTMLDocumentPositionPreceding = 0x02,
HTMLDocumentPositionFollowing = 0x04,
HTMLDocumentPositionContains = 0x08,
HTMLDocumentPositionContainedBy = 0x10,
HTMLDocumentPositionImplementationSpecific = 0x20
};
@class HTMLDocument;
@class HTMLElement;
@class CSSSelector;
@interface HTMLNode : NSObject <NSCopying>
@property (nonatomic, assign, readonly) HTMLNodeType nodeType;
@property (nonatomic, strong, readonly) NSString *name;
@property (nonatomic, weak, readonly) HTMLDocument *ownerDocument;
@property (nonatomic, weak, readonly) HTMLNode *parentNode;
@property (nonatomic, weak, readonly) HTMLElement *parentElement;
@property (nonatomic, strong, readonly) NSOrderedSet *childNodes;
@property (nonatomic, strong, readonly) HTMLNode *firstChild;
@property (nonatomic, strong, readonly) HTMLNode *lastChild;
@property (nonatomic, strong, readonly) HTMLNode *previousSibling;
@property (nonatomic, strong, readonly) HTMLNode *nextSibling;
@property (nonatomic, strong, readonly) HTMLElement *previousSiblingElement;
@property (nonatomic, strong, readonly) HTMLElement *nextSiblingElement;
@property (nonatomic, copy) NSString *textContent;
@property (nonatomic, strong, readonly) NSString *outerHTML;
@property (nonatomic, copy) NSString *innerHTML;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithName:(NSString *)name type:(HTMLNodeType)type;
- (HTMLElement *)asElement;
- (BOOL)hasChildNodes;
- (BOOL)hasChildNodeOfType:(HTMLNodeType)type;
- (NSUInteger)childNodesCount;
- (HTMLNode *)childNodeAtIndex:(NSUInteger)index;
- (NSUInteger)indexOfChildNode:(HTMLNode *)node;
- (NSUInteger)childElementsCount;
- (HTMLElement *)childElementAtIndex:(NSUInteger)index;
- (NSUInteger)indexOfChildElement:(HTMLElement *)element;
- (HTMLNode *)prependNode:(HTMLNode *)node;
- (void)prependNodes:(NSArray *)nodes;
- (HTMLNode *)appendNode:(HTMLNode *)node;
- (void)appendNodes:(NSArray *)nodes;
- (HTMLNode *)insertNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child;
- (HTMLNode *)replaceChildNode:(HTMLNode *)node withNode:(HTMLNode *)replacement;
- (void)replaceAllChildNodesWithNode:(HTMLNode *)node;
- (void)removeFromParentNode;
- (HTMLNode *)removeChildNode:(HTMLNode *)node;
- (HTMLNode *)removeChildNodeAtIndex:(NSUInteger)index;
- (void)reparentChildNodesIntoNode:(HTMLNode *)node;
- (void)removeAllChildNodes;
- (HTMLDocumentPosition)compareDocumentPositionWithNode:(HTMLNode *)node;
- (BOOL)isDescendantOfNode:(HTMLNode *)node;
- (BOOL)containsNode:(HTMLNode *)node;
- (void)enumerateChildNodesUsingBlock:(void (^)(HTMLNode *node, NSUInteger idx, BOOL *stop))block;
- (void)enumerateChildElementsUsingBlock:(void (^)(HTMLElement *element, NSUInteger idx, BOOL *stop))block;
- (HTMLNodeIterator *)nodeIterator;
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(id<HTMLNodeFilter>)filter;
- (HTMLNodeIterator *)nodeIteratorWithShowOptions:(HTMLNodeFilterShowOptions)showOptions
filterBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))filter;
- (HTMLElement *)firstElementMatchingSelector:(CSSSelector *)selector;
- (NSArray<HTMLElement *> *)elementsMatchingSelector:(CSSSelector *)selector;
- (NSString *)treeDescription;
@end
-56
View File
@@ -1,56 +0,0 @@
//
// HTMLNodeFilter.h
// HTMLKit
//
// Created by Iska on 27/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(unsigned short, HTMLNodeFilterValue)
{
HTMLNodeFilterAccept = 1,
HTMLNodeFilterReject = 2,
HTMLNodeFilterSkip = 3
};
typedef NS_OPTIONS(unsigned long, HTMLNodeFilterShowOptions)
{
HTMLNodeFilterShowAll = 0xFFFFFFFF,
HTMLNodeFilterShowElement = 0x1,
HTMLNodeFilterShowText = 0x4,
HTMLNodeFilterShowComment = 0x80,
HTMLNodeFilterShowDocument = 0x100,
HTMLNodeFilterShowDocumentType = 0x200,
HTMLNodeFilterShowDocumentFragment = 0x400
};
#pragma mark - Node Filter
@class HTMLNode;
@protocol HTMLNodeFilter <NSObject>
- (HTMLNodeFilterValue)acceptNode:(HTMLNode *)node;
@end
#pragma mark - Block Filter
@interface HTMLNodeFilterBlock : NSObject <HTMLNodeFilter>
+ (instancetype)filterWithBlock:(HTMLNodeFilterValue (^)(HTMLNode *node))block;
@end
#pragma mark - CSS Selector Filter
@class CSSSelector;
@interface HTMLSelectorNodeFilter : NSObject <HTMLNodeFilter>
+ (instancetype)filterWithSelector:(CSSSelector *)selector;
@end
-36
View File
@@ -1,36 +0,0 @@
//
// HTMLNodeIterator.h
// HTMLKit
//
// Created by Iska on 27/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLNodeFilter.h"
@class HTMLNode;
@interface HTMLNodeIterator : NSEnumerator
@property (nonatomic, strong, readonly) HTMLNode *root;
@property (nonatomic, strong, readonly) HTMLNode *referenceNode;
@property (nonatomic, assign, readonly) BOOL pointerBeforeReferenceNode;
@property (nonatomic, assign, readonly) HTMLNodeFilterShowOptions whatToShow;
@property (nonatomic, strong, readonly) id<HTMLNodeFilter> filter;
+ (instancetype)iteratorWithNode:(HTMLNode *)node
showOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(HTMLNodeFilterValue (^)(HTMLNode *node))filter;
- (instancetype)initWithNode:(HTMLNode *)node;
- (instancetype)initWithNode:(HTMLNode *)node
filter:(id<HTMLNodeFilter>)filter;
- (instancetype)initWithNode:(HTMLNode *)node
showOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(id<HTMLNodeFilter>)filter;
- (HTMLNode *)nextNode;
- (HTMLNode *)previousNode;
@end
-29
View File
@@ -1,29 +0,0 @@
//
// HTMLOrderedDictionary.h
// HTMLKit
//
// Created by Iska on 14/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface HTMLOrderedDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType>
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (void)setObject:(ObjectType)anObject forKey:(KeyType<NSCopying>)aKey atIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceKeyValueAtIndex:(NSUInteger)index withObject:(ObjectType)anObject andKey:(KeyType<NSCopying>)aKey;
- (void)replaceKey:(KeyType<NSCopying>)aKey withKey:(KeyType<NSCopying>)newKey;
- (NSUInteger)indexOfKey:(KeyType<NSCopying>)aKey;
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)index;
- (NSEnumerator *)reverseKeyEnumerator;
@end
NS_ASSUME_NONNULL_END
-19
View File
@@ -1,19 +0,0 @@
//
// HTMLParseErrorToken.h
// HTMLKit
//
// Created by Iska on 23/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLToken.h"
@interface HTMLParseErrorToken : HTMLToken
@property (nonatomic, copy) NSString *reason;
@property (nonatomic, assign) NSUInteger location;
- (instancetype)initWithReasonMessage:(NSString *)reason andStreamLocation:(NSUInteger)location;
@end
-38
View File
@@ -1,38 +0,0 @@
//
// HTMLParseErrorToken.m
// HTMLKit
//
// Created by Iska on 23/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import "HTMLParseErrorToken.h"
@interface HTMLParseErrorToken ()
{
NSString *_reason;
NSUInteger _location;
}
@end
@implementation HTMLParseErrorToken
@synthesize reason = _reason;
@synthesize location = _location;
- (instancetype)initWithReasonMessage:(NSString *)reason andStreamLocation:(NSUInteger)location
{
self = [super init];
if (self) {
self.type = HTMLTokenTypeParseError;
_reason = [reason copy];
_location = location;
}
return self;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p Reason='%@' Location='%lu'>", self.class, self, _reason, _location];
}
@end
-22
View File
@@ -1,22 +0,0 @@
//
// HTMLParser.h
// HTMLKit
//
// Created by Iska on 04/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLElement.h"
@interface HTMLParser : NSObject
@property (nonatomic, strong, readonly) NSArray *parseErrors;
@property (nonatomic, strong, readonly) HTMLDocument *document;
- (instancetype)initWithString:(NSString *)string;
- (HTMLDocument *)parseDocument;
- (NSArray *)parseFragmentWithContextElement:(HTMLElement *)contextElement;
@end
-55
View File
@@ -1,55 +0,0 @@
//
// HTMLStackOfOpenElements.h
// HTMLKit
//
// Created by Iska on 08/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLElement.h"
@interface HTMLStackOfOpenElements : NSObject <NSFastEnumeration>
- (HTMLElement *)currentNode;
- (HTMLElement *)firstNode;
- (HTMLElement *)lastNode;
- (id)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
- (NSUInteger)indexOfElement:(id)node;
- (void)pushElement:(HTMLElement *)element;
- (void)removeElement:(id)element;
- (BOOL)containsElement:(id)element;
- (BOOL)containsElementWithTagName:(NSString *)tagName;
- (void)insertElement:(HTMLElement *)element atIndex:(NSUInteger)index;
- (void)replaceElementAtIndex:(NSUInteger)index withElement:(HTMLElement *)element;
- (void)popCurrentNode;
- (void)popElementsUntilElementPoppedWithTagName:(NSString *)tagName;
- (void)popElementsUntilAnElementPoppedWithAnyOfTagNames:(NSArray *)tagNames;
- (void)popElementsUntilElementPopped:(HTMLElement *)element;
- (void)popElementsUntilTemplateElementPopped;
- (void)clearBackToTableContext;
- (void)clearBackToTableBodyContext;
- (void)clearBackToTableRowContext;
- (void)popAll;
- (HTMLElement *)hasElementInScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasAnyElementInScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInListItemScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInButtonScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInTableScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)hasElementInTableScopeWithAnyOfTagNames:(NSArray *)tagNames;
- (HTMLElement *)hasElementInSelectScopeWithTagName:(NSString *)tagName;
- (HTMLElement *)furthestBlockAfterIndex:(NSUInteger)index;
- (NSUInteger)count;
- (BOOL)isEmpy;
- (NSEnumerator *)enumerator;
- (NSEnumerator *)reverseObjectEnumerator;
@end
-19
View File
@@ -1,19 +0,0 @@
//
// HTMLText.h
// HTMLKit
//
// Created by Iska on 26/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLNode.h"
@interface HTMLText : HTMLNode
@property (nonatomic, copy) NSMutableString *data;
- (instancetype)initWithData:(NSString *)data;
- (void)appendString:(NSString *)string;
@end
-78
View File
@@ -1,78 +0,0 @@
//
// HTMLText.m
// HTMLKit
//
// Created by Iska on 26/02/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import "HTMLText.h"
#import "HTMLElement.h"
#import "NSString+HTMLKit.h"
@implementation HTMLText
- (instancetype)init
{
return [self initWithData:@""];
}
- (instancetype)initWithData:(NSString *)data
{
self = [super initWithName:@"#text" type:HTMLNodeText];
if (self) {
_data = [[NSMutableString alloc] initWithString:data ?: @""];
}
return self;
}
- (NSString *)textContent
{
return [self.data copy];
}
- (void)setTextContent:(NSString *)textContent
{
[self.data setString:textContent ?: @""];
}
- (void)appendString:(NSString *)string
{
[self.data appendString:string];
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
HTMLText *copy = [super copyWithZone:zone];
copy.data = self.data;
return copy;
}
#pragma mark - Serialization
- (NSString *)outerHTML
{
if ([self.parentElement.tagName isEqualToAny:@"style", @"script", @"xmp", @"iframe", @"noembed", @"noframes",
@"plaintext", @"noscript", nil]) {
return self.data;
} else {
NSRange range = NSMakeRange(0, self.data.length);
NSMutableString *escaped = [self.data mutableCopy];
[escaped replaceOccurrencesOfString:@"&" withString:@"&amp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"\00A0" withString:@"&nbsp;" options:0 range:range];
[escaped replaceOccurrencesOfString:@"<" withString:@"&lt;" options:0 range:range];
[escaped replaceOccurrencesOfString:@">" withString:@"&gt;" options:0 range:range];
return escaped;
}
}
#pragma mark - Description
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p \"%@\">", self.class, self, self.data];
}
@end
-54
View File
@@ -1,54 +0,0 @@
//
// HTMLToken.h
// HTMLKit
//
// Created by Iska on 20/09/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@class HTMLDOCTYPEToken;
@class HTMLTagToken;
@class HTMLStartTagToken;
@class HTMLEndTagToken;
@class HTMLCommentToken;
@class HTMLCharacterToken;
@class HTMLParseErrorToken;
NS_INLINE BOOL bothNilOrEqual(id first, id second) {
return (first == nil && second == nil) || ([first isEqual:second]);
}
typedef NS_ENUM(NSUInteger, HTMLTokenType)
{
HTMLTokenTypeCharacter,
HTMLTokenTypeComment,
HTMLTokenTypeDoctype,
HTMLTokenTypeEndTag,
HTMLTokenTypeEOF,
HTMLTokenTypeParseError,
HTMLTokenTypeStartTag
};
@interface HTMLToken : NSObject
@property (nonatomic, assign) HTMLTokenType type;
- (BOOL)isDoctypeToken;
- (BOOL)isStartTagToken;
- (BOOL)isEndTagToken;
- (BOOL)isCommentToken;
- (BOOL)isCharacterToken;
- (BOOL)isEOFToken;
- (BOOL)isParseError;
- (HTMLDOCTYPEToken *)asDoctypeToken;
- (HTMLTagToken *)asTagToken;
- (HTMLStartTagToken *)asStartTagToken;
- (HTMLEndTagToken *)asEndTagToken;
- (HTMLCommentToken *)asCommentToken;
- (HTMLCharacterToken *)asCharacterToken;
- (HTMLParseErrorToken *)asParseError;
@end
-28
View File
@@ -1,28 +0,0 @@
//
// HTMLTokenizer.h
// HTMLKit
//
// Created by Iska on 19/09/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLToken.h"
#import "HTMLTokenizerStates.h"
/**
* HTML Tokenizer
* https://html.spec.whatwg.org/multipage/syntax.html#tokenization
*/
@class HTMLParser;
@interface HTMLTokenizer : NSEnumerator
@property (nonatomic, readonly) NSString *string;
@property (nonatomic, assign) HTMLTokenizerState state;
@property (nonatomic, weak, readonly) HTMLParser *parser;
- (instancetype)initWithString:(NSString *)string;
@end
-16
View File
@@ -1,16 +0,0 @@
//
// HTMLTokenizerEntities.h
// HTMLKit
//
// Created by Iska on 11/10/14.
// Copyright (c) 2014 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface HTMLTokenizerEntities : NSObject
+ (NSArray *)entities;
+ (NSString *)replacementAtIndex:(NSUInteger)index;
@end
-36
View File
@@ -1,36 +0,0 @@
//
// HTMLTreeWalker.h
// HTMLKit
//
// Created by Iska on 05/06/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "HTMLNodeFilter.h"
@class HTMLNode;
@interface HTMLTreeWalker : NSObject
@property (nonatomic, strong, readonly) HTMLNode *root;
@property (nonatomic, assign, readonly) HTMLNodeFilterShowOptions whatToShow;
@property (nonatomic, strong, readonly) id<HTMLNodeFilter> filter;
@property (nonatomic, strong) HTMLNode *currentNode;
- (instancetype)initWithNode:(HTMLNode *)node;
- (instancetype)initWithNode:(HTMLNode *)node
filter:(id<HTMLNodeFilter>)filter;
- (instancetype)initWithNode:(HTMLNode *)node
showOptions:(HTMLNodeFilterShowOptions)showOptions
filter:(id<HTMLNodeFilter>)filter;
- (HTMLNode *)parentNode;
- (HTMLNode *)firstChild;
- (HTMLNode *)lastChild;
- (HTMLNode *)previousSibling;
- (HTMLNode *)nextSibling;
- (HTMLNode *)previousNode;
- (HTMLNode *)nextNode;
@end
-17
View File
@@ -1,17 +0,0 @@
//
// NSCharacterSet+HTMLKit.h
// HTMLKit
//
// Created by Iska on 14/05/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSCharacterSet (HTMLKit)
+ (instancetype)HTMLWhitespaceCharacterSet;
+ (instancetype)HTMLHexNumberCharacterSet;
+ (instancetype)CSSNthExpressionCharacterSet;
@end
-19
View File
@@ -1,19 +0,0 @@
//
// NSString+HTMLKit.h
// HTMLKit
//
// Created by Iska on 02/03/15.
// Copyright (c) 2015 BrainCookie. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (HTMLKit)
- (BOOL)isEqualToStringIgnoringCase:(NSString *)aString;
- (BOOL)isEqualToAny:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION;
- (BOOL)hasPrefixIgnoringCase:(NSString *)aString;
- (BOOL)isHTMLWhitespaceString;
- (NSUInteger)leadingHTMLWhitespaceLength;
@end
-2
View File
@@ -1,2 +0,0 @@
/* Localized versions of Info.plist keys */
File diff suppressed because one or more lines are too long
-2
View File
@@ -1,2 +0,0 @@
/* Localized versions of Info.plist keys */
+6
View File
@@ -0,0 +1,6 @@
import PackageDescription
let package = Package(
name: "HTMLKit",
exclude: ["Tests/Fixtures", "Tests/css-tests", "Tests/html5lib-tests"]
)
+319 -3
View File
@@ -1,11 +1,327 @@
# HTMLKit
An Objective-C kit for your everyday HTML needs.
![HTMLKit Logo](https://raw.githubusercontent.com/iabudiab/HTMLKit/master/HTMLKit.png)
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)
[![Platform](https://img.shields.io/cocoapods/p/HTMLKit.svg?style=flat)](http://cocoadocs.org/docsets/HTMLKit)
[![License MIT](https://img.shields.io/badge/license-MIT-4481C7.svg?style=flat)](https://opensource.org/licenses/MIT)
- [Quick Overview](#overview)
- [Installation](#installation)
- [Parsing](#parsing)
- [The DOM](#the-dom)
- [CSS3 Selectors](#css3-selectors)
# Quick Overview
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 a [WHATWG specification](https://html.spec.whatwg.org/multipage/)-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 provides a rich DOM implementation for manipulating and navigating the document tree. It also understands [CSS3 selectors](http://www.w3.org/TR/css3-selectors/) making node-selection and querying the DOM a piece of cake.
## DOM Validation
DOM mutations are validated as described in the [WHATWG DOM Standard](https://dom.spec.whatwg.org). Invalid DOM manipulations throw hierarchy-related exceptions. You can disable these validations, which will also increase the performance by about 20-30%, by defining the `HTMLKIT_NO_DOM_CHECKS` compiler constant.
## Tests
HTMLKit passes all of the [HTML5Lib](https://github.com/html5lib/html5lib-tests) Tokenizer and Tree Construction tests. The `html5lib-tests` is configured as a git-submodule. If you plan to run the tests, do not forget to pull it too.
The CSS3 Selector implementation is tested with an adapted version of the [CSS3 Selectors Test Suite](http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/full/flat/index.html), ignoring the tests that require user interaction, session history, and scripting.
## Does it Swift?
Check out the playground!
# Installation
## Carthage
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
If you don't have Carthage yet, you can install it with Homebrew using the following command:
```bash
$ brew update
$ brew install carthage
```
To add `HTMLKit` as a dependency into your project using Carthage just add the following line in your `Cartfile`:
```
github "iabudiab/HTMLKit"
```
Then run the following command to build the framework and drag the built `HTMLKit.framework` into your Xcode project.
```bash
$ carthage update
```
## CocoaPods
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects.
If you don't have CocoaPods yet, you can install it with the following command:
```bash
$ gem install cocoapods
```
To add `HTMLKit` as a dependency into your project using CocoaPods just add the following in your `Podfile`:
```ruby
use_frameworks!
target 'MyTarget' do
pod 'HTMLKit', '~> 2.0'
end
```
Then, run the following command:
```bash
$ pod install
```
## Swift Package Manager
[Swift Package Manager](https://github.com/apple/swift-package-manager) is the package manager for the Swift programming language.
Add `HTMLKit` to your `Package.swift` dependecies:
```swift
.Package(url: "https://github.com/iabudiab/HTMLKit", majorVersion: 2)
```
Then run:
```bash
$ swift build
```
## Manually
1- Add `HTMLKit` as git submodule
```bash
$ git submodule add https://github.com/iabudiab/HTMLKit.git
```
2- Open the `HTMLKit` folder and drag'n'drop the `HTMLKit.xcodeproj` into the Project Navigator in Xcode to add it as a sub-project.
3- In the General panel of your target add `HTMLKit.framework` under the `Embedded Binaries`
# Parsing
## Parsing Documents
Given some HTML content, you can parse it either via the `HTMLParser` or instatiate a `HTMLDocument` directly:
```objective-c
NSString *htmlString = @"<div><h1>HTMLKit</h1><p>Hello there!</p></div>";
// Via parser
HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlString];
HTMLDocument *document = [parser parseDocument];
// Via static initializer
HTMLDocument *document = [HTMLDocument documentWithString:htmlString];
```
## Parsing Fragments
You can also prase HTML content as a document fragment with a specified context element:
```objective-c
NSString *htmlString = @"<div><h1>HTMLKit</h1><p>Hello there!</p></div>";
HTMLParser *parser = [[HTMLParser alloc] initWithString: htmlString];
HTMLElement *tableContext = [[HTMLElement alloc] initWithTagName:@"table"];
NSArray *nodes = [parser parseFragmentWithContextElement:tableContext];
for (HTMLNode *node in nodes) {
NSLog(@"%@", node.outerHTML);
}
// The same parser instance can be reusued:
HTMLElement *bodyContext = [[HTMLElement alloc] initWithTagName:@"body"];
nodes = [parser parseFragmentWithContextElement:bodyContext];
```
# The DOM
The DOM tree can be manipulated in several ways, here are just a few:
* Create new elements and assign attributes
```objective-c
HTMLElement *description = [[HTMLElement alloc] initWithTagName:@"meta" attributes: @{@"name": @"description"}];
description[@"content"] = @"HTMLKit for iOS & OSX";
```
* Append nodes to the document
```objective-c
HTMLElement *head = document.head;
[head appendNode:description];
HTMLElement *body = document.body;
NSArray *nodes = @[
[[HTMLElement alloc] initWithTagName:@"div" attributes: @{@"class": @"red"}],
[[HTMLElement alloc] initWithTagName:@"div" attributes: @{@"class": @"green"}],
[[HTMLElement alloc] initWithTagName:@"div" attributes: @{@"class": @"blue"}]
];
[body appendNodes:nodes];
```
* Enumerate child elements and perform DOM editing
```objective-c
[body enumerateChildElementsUsingBlock:^(HTMLElement *element, NSUInteger idx, BOOL *stop) {
if ([element.tagName isEqualToString:@"div"]) {
HTMLElement *lorem = [[HTMLElement alloc] initWithTagName:@"p"];
lorem.textContent = [NSString stringWithFormat:@"Lorem ipsum: %lu", (unsigned long)idx];
[element appendNode:lorem];
}
}];
```
* Remove nodes from the document
```objective-c
[body removeChildNodeAtIndex:1];
[head removeAllChildNodes];
[body.lastChild removeFromParentNode];
```
* Manipulate the HTML directly
```objective-c
greenDiv.innerHTML = @"<ul><li>item 1<li>item 2";
```
* Navigate to child and sibling nodes
```objective-c
HTMLNode *firstChild = body.firstChild;
HTMLNode *greenDiv = firstChild.nextSibling;
```
* Iterate the DOM tree with custom filters
```objective-c
HTMLNodeFilterBlock *filter =[HTMLNodeFilterBlock filterWithBlock:^ HTMLNodeFilterValue (HTMLNode *node) {
if (node.childNodesCount != 1) {
return HTMLNodeFilterReject;
}
return HTMLNodeFilterAccept;
}];
for (HTMLElement *element in [body nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:filter]) {
NSLog(@"%@", element.outerHTML);
}
```
* Create and manipulate DOM Ranges
```objective-c
HTMLDocument *document = [HTMLDocument documentWithString:@"<div><h1>HTMLKit</h1><p id='foo'>Hello there!</p></div>"];
HTMLRange *range = [[HTMLRange alloc] initWithDocument:document];
HTMLNode *paragraph = [document querySelector:@"#foo"];
[range selectNode:paragraph];
[range extractContents];
```
# CSS3 Selectors
All CSS3 Selectors are supported except for the pseudo-elements (`::first-line`, `::first-letter`, ...etc.). You can use them the way you always have:
```objective-c
// Given the document:
NSString *htmlString = @"<div><h1>HTMLKit</h1><p class='greeting'>Hello there!</p><p class='description'>This is a demo of HTMLKit</p></div>";
HTMLDocument *document = [HTMLDocument documentWithString: htmlString];
// Here are some of the supported selectors
NSArray *paragraphs = [document querySelectorAll:@"p"];
NSArray *paragraphsOrHeaders = [document querySelectorAll:@"p, h1"];
NSArray *hasClassAttribute = [document querySelectorAll:@"[class]"];
NSArray *greetings = [document querySelectorAll:@".greeting"];
NSArray *classNameStartsWith_de = [document querySelectorAll:@"[class^='de']"];
NSArray *hasAdjacentHeader = [document querySelectorAll:@"h1 + *"];
NSArray *hasSiblingHeader = [document querySelectorAll:@"h1 ~ *"];
NSArray *hasSiblingParagraph = [document querySelectorAll:@"p ~ *"];
NSArray *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:
```objective-c
NSArray *paragraphs = [document elementsMatchingSelector:typeSelector(@"p")];
NSArray *paragraphsOrHeaders = [document elementsMatchingSelector:
anyOf(@[
typeSelector(@"p"), typeSelector(@"h1")
])
];
NSArray *hasClassAttribute = [document elementsMatchingSelector:hasAttributeSelector(@"class")];
NSArray *greetings = [document elementsMatchingSelector:classSelector(@"greeting")];
NSArray *classNameStartsWith_de = [document elementsMatchingSelector:attributeSelector(CSSAttributeSelectorBegins, @"class", @"de")];
NSArray *hasAdjacentHeader = [document elementsMatchingSelector:adjacentSiblingSelector(typeSelector(@"h1"))];
NSArray *hasSiblingHeader = [document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"h1"))];
NSArray *hasSiblingParagraph = [document elementsMatchingSelector:generalSiblingSelector(typeSelector(@"p"))];
NSArray *nonParagraphChildOfDiv = [document elementsMatchingSelector:
allOf(@[
childOfElementSelector(typeSelector(@"div")),
not(typeSelector(@"p"))
])
];
```
Here are more examples:
```objective-c
HTMLNode *firstDivElement = [document firstElementMatchingSelector:typeSelector(@"div")];
NSArray *secondChildOfDiv = [firstDivElement querySelectorAll:@":nth-child(2)"];
NSArray *secondOfType = [firstDivElement querySelectorAll:@":nth-of-type(2n)"];
secondChildOfDiv = [firstDivElement elementsMatchingSelector:nthChildSelector(CSSNthExpressionMake(0, 2))];
secondOfType = [firstDivElement elementsMatchingSelector:nthOfTypeSelector(CSSNthExpressionMake(2, 0))];
NSArray *notParagraphAndNotDiv = [firstDivElement querySelectorAll:@":not(p):not(div)"];
notParagraphAndNotDiv = [firstDivElement elementsMatchingSelector:
allOf([
not(typeSelector(@"p")),
not(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:
```objective-c
CSSSelector *myAwesomeSelector = namedBlockSelector(@"myAwesomeSelector", ^BOOL (HTMLElement *element) {
return ![element.tagName isEqualToString:@"p"] && ![element.tagName isEqualToString:@"div"];
});
notParagraphAndNotDiv = [firstDivElement elementsMatchingSelector:myAwesomeSelector];
```
# Change Log
See the [CHANGELOG.md](CHANGELOG.md) for more info.
# License
HTMLKit is available under the MIT license. See the LICENSE file for more info.
HTMLKit is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
@@ -41,7 +41,7 @@
{
self = [super init];
if (self) {
self.type = type;
_type = type;
_name = [name copy];
_value = value ? [value copy]: @"";
}
@@ -8,6 +8,7 @@
#import "CSSCombinatorSelector.h"
#import "HTMLElement.h"
#import "HTMLNode+Private.h"
#pragma mark - Declarations
@@ -24,14 +24,14 @@
- (NSString *)consumeIdentifier
{
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
if (!isValidIdentifierStart([self inputCharacterPointAtOffset:0],
[self inputCharacterPointAtOffset:1],
[self inputCharacterPointAtOffset:2])) {
return nil;
}
CFMutableStringRef value = CFStringCreateMutable(kCFAllocatorDefault, 0);
while (YES) {
UTF32Char codePoint = [self consumeNextInputCharacter];
if (codePoint == EOF) {
@@ -47,7 +47,12 @@
}
}
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
if (CFStringGetLength(value) > 0) {
return (__bridge_transfer NSString *)value;
}
CFRelease(value);
return nil;
}
- (NSString *)consumeStringWithEndingCodePoint:(UTF32Char)endingCodePoint
@@ -85,7 +90,12 @@
}
}
return (__bridge NSString *)(CFStringGetLength(value) > 0 ? value : nil);
if (CFStringGetLength(value) > 0) {
return (__bridge_transfer NSString *)value;
}
CFRelease(value);
return nil;
}
- (UTF32Char)consumeEscapedCodePoint
@@ -105,8 +115,8 @@
[self consumeNextInputCharacter];
}
NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexString)];
UTF32Char number;
NSScanner *scanner = [NSScanner scannerWithString:(__bridge_transfer NSString *)(hexString)];
unsigned int number;
[scanner scanHexInt:&number];
return isValidEscapedCodePoint(number) ? number : REPLACEMENT_CHARACTER;
@@ -8,6 +8,7 @@
#import "CSSNthExpressionSelector.h"
#import "HTMLElement.h"
#import "HTMLNode+Private.h"
#pragma mark - Nth-Expression
@@ -26,13 +27,13 @@ NSString * _Nonnull NSStringFromNthExpression(CSSNthExpression expression)
}
if (expression.an == 0) {
return [NSString stringWithFormat:@"%ld", expression.b];
return [NSString stringWithFormat:@"%ld", (long)expression.b];
}
if (expression.b == 0) {
return [NSString stringWithFormat:@"%ldn", expression.an];
return [NSString stringWithFormat:@"%ldn", (long)expression.an];
}
return [NSString stringWithFormat:@"%ldn%+ld", expression.an, expression.b];
return [NSString stringWithFormat:@"%ldn%+ld", (long)expression.an, (long)expression.b];
}
#pragma mark - Implementation
@@ -8,6 +8,7 @@
#import "CSSPseudoFunctionSelector.h"
#import "HTMLElement.h"
#import "HTMLNode+Private.h"
#pragma mark - Declarations
@@ -72,8 +73,9 @@
- (BOOL)acceptElement:(HTMLElement *)element
{
for (HTMLNode *child in element.childNodes) {
if (child.nodeType == HTMLNodeElement && [self.selector acceptElement:child.asElement]) {
HTMLNodeIterator *iterator = [element nodeIteratorWithShowOptions:HTMLNodeFilterShowAll filter:nil];
for (HTMLNode *descendant in iterator) {
if (descendant.nodeType == HTMLNodeElement && [self.selector acceptElement:descendant.asElement]) {
return YES;
}
}
@@ -8,9 +8,20 @@
#import <Foundation/Foundation.h>
#import "CSSSelector.h"
#import "CSSSelectorParser.h"
@implementation CSSSelector
+ (instancetype)selectorWithString:(NSString *)string
{
NSError *error = nil;
CSSSelector *instance = [CSSSelectorParser parseSelector:string error:&error];
if (error) {
return nil;
}
return instance;
}
- (BOOL)acceptElement:(HTMLElement *)element
{
[self doesNotRecognizeSelector:_cmd];
@@ -61,6 +61,11 @@
#pragma mark - Errors
- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason
{
[self emitError:error reason:reason location:_location + _inputStream.currentLocation];
}
- (void)emitError:(NSError * __autoreleasing *)error reason:(NSString *)reason location:(NSUInteger)location
{
NSDictionary *userInfo = @{
@@ -70,7 +75,7 @@
CSSSelectorErrorLocationKey: @(location)
};
if(error) {
if(error && *error == nil) {
*error = [NSError errorWithDomain:HTMLKitSelectorErrorDomain code:HTMLKitSelectorParseError userInfo:userInfo];
}
}
@@ -102,7 +107,7 @@
_location += subSelector.length;
}
if (*error != nil) {
if (error && *error != nil) {
return nil;
}
@@ -204,7 +209,7 @@
{
NSString *elementId = [_inputStream consumeIdentifier];
if (elementId == nil) {
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Invalid character"];
return nil;
}
return idSelector(elementId);
@@ -213,7 +218,7 @@
{
NSString *className = [_inputStream consumeIdentifier];
if (className == nil) {
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Invalid character"];
return nil;
}
return classSelector(className);
@@ -228,7 +233,7 @@
}
default:
{
[self emitError:error reason:@"Invalid character" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Invalid character"];
return nil;
}
}
@@ -278,7 +283,7 @@
// Consume RIGHT_SQUARE_BRACKET
if (![_inputStream consumeCharacter:RIGHT_SQUARE_BRACKET]) {
[self emitError:error reason:@"Expected closing right square bracket ']'" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Expected closing right square bracket ']'"];
}
if (type == CSSAttributeSelectorExists) {
@@ -295,7 +300,7 @@
if ([pseudoClass hasPrefix:@"nth"]) {
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) {
[self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Expected opening left parenthesis '('"];
}
NSString *functionExpression = [_inputStream consumeCharactersUpToString:@")"];
@@ -303,7 +308,7 @@
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) {
[self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Expected closing right parenthesis ')'"];
}
if ([pseudoClass isEqualToString:@"nth-child"]) {
@@ -318,16 +323,40 @@
} else if ([pseudoClass isEqualToString:@"not"]) {
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) {
[self emitError:error reason:@"Expected opening left parenthesis '('" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Expected opening left parenthesis '('"];
}
CSSSelector *subSelector = [self parseSimpleSelector:error];
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) {
[self emitError:error reason:@"Expected closing right parenthesis ')'" location:_location + _inputStream.currentLocation];
[self emitError:error reason:@"Expected closing right parenthesis ')'"];
}
return nay(subSelector);
return not(subSelector);
} else if ([pseudoClass isEqualToAny:@"lt", @"gt", @"eq", nil]) {
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:LEFT_PARENTHESIS]) {
[self emitError:error reason:@"Expected opening left parenthesis '('"];
}
NSDecimal decimal;
if (![_inputStream consumeDecimalNumber:&decimal]) {
[self emitError:error reason:@"Expected a decimal number"];
}
[_inputStream consumeWhitespace];
if (![_inputStream consumeCharacter:RIGHT_PARENTHESIS]) {
[self emitError:error reason:@"Expected closing right parenthesis ')'"];
}
NSDecimalNumber *number = [[NSDecimalNumber alloc] initWithDecimal:decimal];
if ([pseudoClass isEqualToString:@"lt"]) {
return ltSelector(number.integerValue);
} else if ([pseudoClass isEqualToString:@"gt"]) {
return gtSelector(number.integerValue);
} else if ([pseudoClass isEqualToString:@"eq"]) {
return eqSelector(number.integerValue);
}
} else {
if ([pseudoClass isEqualToString:@"even"]) {
return evenSlector();
@@ -358,9 +387,39 @@
} else if ([pseudoClass isEqualToString:@"checked"]) {
return checkedSelector();
}
else if ([pseudoClass isEqualToString:@"button"]) {
return buttonSelector();
} else if ([pseudoClass isEqualToString:@"checkbox"]) {
return checkboxSelector();
} else if ([pseudoClass isEqualToString:@"file"]) {
return fileSelector();
} else if ([pseudoClass isEqualToString:@"header"]) {
return headerSelector();
} else if ([pseudoClass isEqualToString:@"image"]) {
return imageSelector();
} else if ([pseudoClass isEqualToString:@"optional"]) {
return optionalSelector();
} else if ([pseudoClass isEqualToString:@"parent"]) {
return parentSelector();
} else if ([pseudoClass isEqualToString:@"password"]) {
return passwordSelector();
} else if ([pseudoClass isEqualToString:@"radio"]) {
return radioSelector();
} else if ([pseudoClass isEqualToString:@"reset"]) {
return resetSelector();
} else if ([pseudoClass isEqualToString:@"submit"]) {
return submitSelector();
} else if ([pseudoClass isEqualToString:@"text"]) {
return textSelector();
} else if ([pseudoClass isEqualToString:@"required"]) {
return requiredSelector();
} else if ([pseudoClass isEqualToString:@"reset"]) {
return resetSelector();
}
}
NSString *reason = [NSString stringWithFormat:@"Unknown pseudo class: %@", pseudoClass];
[self emitError:error reason:reason location:_location + _inputStream.currentLocation];
[self emitError:error reason:reason];
return nil;
}
@@ -140,7 +140,7 @@ CSSSelector * generalSiblingSelector(CSSSelector *selector)
#pragma mark - Pseudo Functions
CSSSelector * nay(CSSSelector *selector)
CSSSelector * not(CSSSelector *selector)
{
return [CSSPseudoFunctionSelector notSelector:selector];
}
@@ -183,7 +183,7 @@ CSSSelector * enabledSelector()
typeSelector(@"menuitem"),
typeSelector(@"fieldset"),
]);
return namedPseudoSelector(@"enabled", allOf(@[candiate, nay(disabledSelector())]));
return namedPseudoSelector(@"enabled", allOf(@[candiate, not(disabledSelector())]));
}
CSSSelector * disabledSelector()
@@ -206,7 +206,7 @@ CSSSelector * disabledSelector()
]),
allOf(@[
descendantOfElementSelector(disabledFieldset),
nay(firstLegendDecendantDisabledFieldSet)
not(firstLegendDecendantDisabledFieldSet)
])
]);
@@ -249,7 +249,7 @@ CSSSelector * optionalSelector()
typeSelector(@"select"),
typeSelector(@"textarea")
]);
CSSSelector *noAttribute = nay(hasAttributeSelector(@"required"));
CSSSelector *noAttribute = not(hasAttributeSelector(@"required"));
return namedPseudoSelector(@"optional", allOf(@[candidate, noAttribute]));
}
@@ -270,25 +270,37 @@ CSSSelector * requiredSelector()
#pragma mark - Positional
CSSSelector * ltSelector(NSUInteger index)
CSSSelector * ltSelector(NSInteger index)
{
NSString *name = [NSString stringWithFormat:@":lt(%lu)", (unsigned long)index];
NSString *name = [NSString stringWithFormat:@":lt(%ld)", (long)index];
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
return [element.parentElement indexOfChildNode:element] < index;
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
if (index > 0) {
return elementIndex < index;
} else {
return elementIndex < element.parentElement.childNodesCount - index - 1;
}
});
}
CSSSelector * gtSelector(NSUInteger index)
CSSSelector * gtSelector(NSInteger index)
{
NSString *name = [NSString stringWithFormat:@":gt(%lu)", (unsigned long)index];
NSString *name = [NSString stringWithFormat:@":gt(%ld)", (long)index];
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
return [element.parentElement indexOfChildNode:element] > index;
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
if (index > 0) {
return elementIndex > index;
} else {
return elementIndex > element.parentElement.childNodesCount - index - 1;
}
});
}
CSSSelector * eqSelector(NSInteger index)
{
NSString *name = [NSString stringWithFormat:@":eq(%lu)", (unsigned long)index];
NSString *name = [NSString stringWithFormat:@":eq(%ld)", (long)index];
return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
+114
View File
@@ -0,0 +1,114 @@
//
// HTMLCharacterData.m
// HTMLKit
//
// Created by Iska on 26/11/16.
// Copyright © 2016 BrainCookie. All rights reserved.
//
#import "HTMLCharacterData.h"
#import "HTMLNode+Private.h"
#import "HTMLDocument+Private.h"
#import "HTMLKitDOMExceptions.h"
@interface HTMLCharacterData ()
{
NSMutableString *_data;
}
@end
@implementation HTMLCharacterData
@synthesize data = _data;
- (instancetype)initWithName:(NSString *)name type:(HTMLNodeType)type data:(NSString *)data
{
self = [super initWithName:name type:type];
if (self) {
if (data) {
_data = [[NSMutableString alloc] initWithString:data];
}
}
return self;
}
- (NSString *)data
{
if (_data == nil) {
_data = [[NSMutableString alloc] initWithString:@""];
}
return _data;
}
- (NSString *)textContent
{
return [self.data copy];
}
- (void)setTextContent:(NSString *)textContent
{
[self setData:textContent];
}
- (NSUInteger)length
{
return self.data.length;
}
#pragma mark - Data
NS_INLINE void CheckValidOffset(HTMLCharacterData *node, NSUInteger offset, NSString *cmd)
{
if (offset > node.length) {
[NSException raise:HTMLKitIndexSizeError
format:@"%@: Index Size Error, invalid index %lu for character data node %@.",
cmd, (unsigned long)offset, node];
}
}
- (void)setData:(NSString *)data
{
[self replaceDataInRange:NSMakeRange(0, self.length) withData:data];
}
- (void)appendData:(NSString *)data
{
[self replaceDataInRange:NSMakeRange(self.length, 0) withData:data];
}
- (void)insertData:(NSString *)data atOffset:(NSUInteger)offset
{
[self replaceDataInRange:NSMakeRange(offset, 0) withData:data];
}
- (void)deleteDataInRange:(NSRange)range
{
[self replaceDataInRange:range withData:@""];
}
- (void)replaceDataInRange:(NSRange)range withData:(NSString *)data
{
CheckValidOffset(self, range.location, NSStringFromSelector(_cmd));
range.length = MIN(range.length, self.length - range.location);
[(NSMutableString *)self.data replaceCharactersInRange:range withString:data];
[self.ownerDocument didRemoveCharacterDataInNode:self atOffset:range.location withLength:range.length];
[self.ownerDocument didAddCharacterDataToNode:self atOffset:range.location withLength:data.length];
}
- (NSString *)substringDataWithRange:(NSRange)range
{
return [_data substringWithRange:range];
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
HTMLCharacterData *copy = [super copyWithZone:zone];
copy->_data = [_data mutableCopy];
return copy;
}
@end
@@ -7,40 +7,18 @@
//
#import "HTMLComment.h"
#import "HTMLCharacterData+Private.h"
@implementation HTMLComment
- (instancetype)init
{
return [self initWithData:nil];
return [self initWithData:@""];
}
- (instancetype)initWithData:(NSString *)data
{
self = [super initWithName:@"#comment" type:HTMLNodeComment];
if (self) {
self.data = data ?: @"";
}
return self;
}
- (NSString *)textContent
{
return self.data;
}
- (void)setTextContent:(NSString *)textContent
{
self.data = textContent ?: @"";
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
HTMLComment *copy = [super copyWithZone:zone];
copy.data = self.data;
return copy;
return [super initWithName:@"#comment" type:HTMLNodeComment data:data];
}
#pragma mark - Serialization
+109
View File
@@ -0,0 +1,109 @@
//
// HTMLDOMTokenList.m
// HTMLKit
//
// Created by Iska on 30/11/15.
// Copyright © 2015 BrainCookie. All rights reserved.
//
#import "HTMLDOMTokenList.h"
#import "HTMLElement.h"
@interface HTMLDOMTokenList ()
{
HTMLElement *_element;
NSString *_attribute;
NSMutableOrderedSet *_tokens;
}
@end
@implementation HTMLDOMTokenList
@synthesize element = _element;
@synthesize attribute = _attribute;
#pragma mark - Init
- (instancetype)initWithElement:(HTMLElement *)element attribute:(NSString *)attribute value:(NSString *)value
{
self = [super init];
if (self) {
_element = element;
_attribute = [attribute copy];
_tokens = [NSMutableOrderedSet new];
[self add:[value componentsSeparatedByString:@" "]];
}
return self;
}
#pragma mark - Access
- (void)updateValue
{
_element[_attribute] = self.stringify;
}
- (NSUInteger)length
{
return _tokens.count;
}
- (BOOL)contains:(NSString *)token
{
return [_tokens containsObject:token];
}
- (void)add:(NSArray<NSString *> *)tokens
{
for (NSString *token in tokens) {
if (![token isEqualToString:@""]) {
[_tokens addObject:token];
}
}
[self updateValue];
}
- (void)remove:(NSArray<NSString *> *)tokens
{
for (NSString *token in tokens) {
[_tokens removeObject:token];
}
[self updateValue];
}
- (BOOL)toggle:(NSString *)token
{
if ([_tokens containsObject:token]) {
[_tokens removeObject:token];
[self updateValue];
return NO;
} else {
[_tokens addObject:token];
[self updateValue];
return YES;
}
}
- (void)replaceToken:(NSString *)token withToken:(NSString *)newToken
{
NSUInteger index = [_tokens indexOfObject:token];
_tokens[index] = newToken;
[self updateValue];
}
- (NSString *)objectAtIndexedSubscript:(NSUInteger)index
{
return _tokens[index];
}
- (void)setObject:(NSString *)obj atIndexedSubscript:(NSUInteger)index
{
_tokens[index] = obj;
[self updateValue];
}
- (NSString *)stringify
{
return [_tokens.array componentsJoinedByString:@" "];
}
@end
+32
View File
@@ -0,0 +1,32 @@
//
// HTMLDOMUtils.m
// HTMLKit
//
// Created by Iska on 03/12/16.
// Copyright © 2016 BrainCookie. All rights reserved.
//
#import "HTMLDOMUtils.h"
#import "HTMLNode.h"
extern HTMLNode * GetCommonAncestorContainer(HTMLNode *nodeA, HTMLNode *nodeB)
{
for (HTMLNode *parentA = nodeA; parentA != nil; parentA = parentA.parentNode) {
for (HTMLNode *parentB = nodeB; parentB != nil; parentB = parentB.parentNode) {
if (parentA == parentB) {
return parentA;
}
}
}
return nil;
}
extern NSArray<HTMLNode *> * GetAncestorNodes(HTMLNode *node)
{
NSMutableArray *ancestors = [NSMutableArray array];
for (HTMLNode *it = node; it; it = it.parentNode) {
[ancestors addObject:it];
}
return ancestors;
}

Some files were not shown because too many files have changed in this diff Show More