An Objective-C framework for your everyday HTML needs.

Overview

HTMLKit

HTMLKit Logo

An Objective-C framework for your everyday HTML needs.

HTMLKit CI codecov Carthage Compatible CocoaPods Compatible Platform License MIT

Quick Overview

HTMLKit is a WHATWG 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 provides a rich DOM implementation for manipulating and navigating the document tree. It also understands 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. 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 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, ignoring the tests that require user interaction, session history, and scripting.

Does it Swift?

Check out the playground!

Installation

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:

$ 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.

$ carthage update

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

If you don't have CocoaPods yet, you can install it with the following command:

$ gem install cocoapods

To add HTMLKit as a dependency into your project using CocoaPods just add the following in your Podfile:

target 'MyTarget' do
  pod 'HTMLKit', '~> 4.2'
end

Then, run the following command:

$ pod install

Swift Package Manager

Swift Package Manager is the package manager for the Swift programming language.

Add HTMLKit to your Package.swift dependecies:

.package(url: "https://github.com/iabudiab/HTMLKit", .upToNextMajor(from: "4.0.0")),

Then run:

$ swift build

Manually

1- Add HTMLKit as git submodule

$ 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:

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:

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
HTMLElement *description = [[HTMLElement alloc] initWithTagName:@"meta"  attributes: @{@"name": @"description"}];
description[@"content"] = @"HTMLKit for iOS & OSX";
  • Append nodes to the document
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
[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
[body removeChildNodeAtIndex:1];
[head removeAllChildNodes];
[body.lastChild removeFromParentNode];
  • Manipulate the HTML directly
greenDiv.innerHTML = @"<ul><li>item 1<li>item 2";
  • Navigate to child and sibling nodes
HTMLNode *firstChild = body.firstChild;
HTMLNode *greenDiv = firstChild.nextSibling;
  • Iterate the DOM tree with custom filters
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
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:

// 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:

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:

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:

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 for more info.

License

HTMLKit is available under the MIT license. See the LICENSE file for more info.

Comments
  • Large memory consumption (spikes) by HTMLParser

    Large memory consumption (spikes) by HTMLParser

    If you load a lot of html into HTMLParser, it uses upwards of 500-600MB for parsing at peak. More autorelease pools need to be added. I found a couple of places that are the worst offenders:

    - (void)HTMLInsertionModeInBody:(HTMLToken *)token

    - (NSString *)innerHTML

    HTMLTokenizer nextObject

    Also, for a high number of nodes, always creating NSMutableOrderedSet is not ideal - that uses about 40-50MB.

    enhancement 
    opened by dsanghan 12
  • Swift 2.3 - Build Issue

    Swift 2.3 - Build Issue

    I installed your library as you suggested by using cocoa-pods, but after I tried to include it in my project in my bridge-header I keep getting bunch of errors that these *.h files like HTMLElement.h etc. does not exist, even doe I see them in pod folder. Any idea why?

    I'm using XCode 8 and Swift 2.3.

    UPDATE What I had to do to make it works (for now), I had to mark each of these "missing" files as "public" in cocoa-pod.

    support 
    opened by vsavic 9
  • Circular references between parent and child cause infinite recursion

    Circular references between parent and child cause infinite recursion

    Example Stacktrace:

    Crashed: com.app.imap.download
    0    CoreFoundation                 0x19d7b39f4 __CFStringChangeSizeMultiple + 244
    1    CoreFoundation                 0x19d7ae61c __CFStringAppendBytes + 620
    2    CoreFoundation                 0x19d79fa78 __CFStringAppendFormatCore + 12648
    3    CoreFoundation                 0x19d7b2224 _CFStringAppendFormatAndArgumentsAux2 + 48
    4    CoreFoundation                 0x19d6dbcf8 -[__NSCFString appendFormat:] + 100
    5    App                            0x1029faec4 -[HTMLElement outerHTML] (HTMLElement.m:158)
    6    Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    7    Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    8    App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    9    App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    10   Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    ...
    2548 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2549 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2550 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2551 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2552 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2553 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2554 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2555 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2556 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2557 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2558 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2559 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2560 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2561 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2562 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2563 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2564 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2565 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2566 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2567 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2568 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2569 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2570 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2571 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2572 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2573 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2574 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2575 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2576 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2577 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2578 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2579 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2580 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2581 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2582 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2583 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2584 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2585 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2586 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2587 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2588 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2589 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2590 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2591 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2592 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2593 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2594 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2595 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2596 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2597 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2598 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2599 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2600 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2601 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2602 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2603 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2604 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2605 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2606 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2607 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2608 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2609 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2610 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2611 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2612 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2613 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2614 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2615 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2616 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2617 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2618 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2619 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2620 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2621 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2622 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2623 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2624 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2625 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2626 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2627 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2628 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2629 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2630 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2631 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2632 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2633 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2634 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2635 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2636 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2637 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2638 Foundation                     0x19e16d7d0 -[NSObject(NSKeyValueCoding) valueForKey:] + 268
    2639 Foundation                     0x19e1c9940 -[NSArray(NSKeyValueCoding) valueForKey:] + 392
    2640 App                            0x102a00848 -[HTMLNode innerHTML] (HTMLNode.m:727)
    2641 App                            0x1029fb16c -[HTMLElement outerHTML] (HTMLElement.m:182)
    2642 App                            0x1026c74d8 -[MRLinkParser parseUnsubscribeWithDocument:] (MRLinkParser.m:123)
    

    Maybe put in a check for that? Not sure how to reproduce but seeing this out in the wild.

    opened by dsanghan 8
  • How to find and highlight desired text using DOMRanges

    How to find and highlight desired text using DOMRanges

    Hi I am implementing text highlight feature for my UIWebView page, and I wanted to use your library to find all DOM ranges for the desired text and then use rangy library to highlight them. Could you assist me?

    question support 
    opened by matcodes 8
  • HTMLKit use non public API ?

    HTMLKit use non public API ?

    Hi, I have a app using HTMLKit. When I sent my app to app store to review , app store reported "querySelectAll: " referenced non public API. It's really true ? If it's true , is it possible to fix it ?

    question support 
    opened by FengStyle 7
  • Occasional Internal Consistency Error

    Occasional Internal Consistency Error

    Every once in a while, I get a crash on an "internal consistency" error.

    My app is fetching some HTML pages in a background process and pulling out some interesting stuff. A few times, I've had the app (in the simulator) crash on the following:

    2019-07-13 21:30:37.026686-0400 dreamwidth[65452:90258127] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[NSHashTable NSHashTable {
    [10] <HTMLNodeIterator: 0x60000eae1680>
    }
    ] count underflow'
    *** First throw call stack:
    (
    	0   CoreFoundation                      0x000000010af6a6fb __exceptionPreprocess + 331
    	1   libobjc.A.dylib                     0x00000001098abac5 objc_exception_throw + 48
    	2   CoreFoundation                      0x000000010af6a555 +[NSException raise:format:] + 197
    	3   Foundation                          0x000000010827f9d7 hashProbe + 407
    	4   Foundation                          0x000000010827fe5c -[NSConcreteHashTable removeItem:] + 49
    	5   myapp                               0x0000000106d01e3d -[HTMLDocument detachNodeIterator:] + 93
    	6   myapp                               0x0000000106d115b7 -[HTMLNodeIterator dealloc] + 87
    

    I suspect that it's something to do with timing: it doesn't happen all the time, but when it does, it crashes my app. I suspect that the HTML document is being deallocated when this happens.

    I've tried to avoid iterating on, say, .childNodes to avoid creating node iterators, but the crash still happens every so often.

    opened by bcholmes 6
  • Best way to loop through the HTML contents?

    Best way to loop through the HTML contents?

    I've created a small testing app with HTMLKit inside it. I want to present a UITableView with all the HTML in it. I load the HTML as follows:

    NSString *htmlString = @"<div><div><p>Test!</p></div><p>Test!</p><h1>HTMLKit</h1><p>Hello there!</p></div>";
            
     // Via parser
    HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlString];
    HTMLDocument *document = [parser parseDocument];
    HTMLElement *head = document.body;
    [self.items addObject:[self addElement:head]];
    HTMLElement *body = document.body;
    [self.items addObject:[self addElement:body]];
    

    And these are the addElement related functions:

    - (Entry *)addElement:(HTMLElement *)element {
        Entry *entry = [[Entry alloc] init];
        
        if (element.childElementsCount > 0) {
            entry.tags = [self enumerate:element];
        }
        entry.tag = element.outerHTML;
        
        return entry;
    }
    
    - (NSArray *)enumerate:(HTMLElement *)element {
        NSMutableArray *items = [@[] mutableCopy];
        for (int i = 0; i < element.childElementsCount; i++) {
            HTMLElement *child = [element childElementAtIndex:i];
            
            [items addObject:[self addElement:child]];
        }
        
        return items;
    }
    

    This has the screenshot below as a result: screen shot 2017-05-15 at 15 06 58

    Ideally, I'd like for <body> to not contain the <div><div>..etc. What's the best way to achieve this with HTMLKit?

    question 
    opened by Sjoerdjanssenen 5
  • Redefinition of module 'HTMLKit' Xcode 8.3

    Redefinition of module 'HTMLKit' Xcode 8.3

    There was such error after updating Xcode.

    2017-04-04 14 10 40

    In the Source/include project folder is the file module.modulemap. After the removal of this file, the project is built without errors.

    bug 
    opened by aimalygin 5
  • :gt(0) can't get elements

    :gt(0) can't get elements

    When I write the code as follow, it works:

    CSSSelector * gtSelector(NSInteger index)
    {
    	NSString *name = [NSString stringWithFormat:@":gt(%ld)", (long)index];
    	return namedBlockSelector(name, ^BOOL(HTMLElement * _Nonnull element) {
    		NSUInteger elementIndex = [element.parentElement indexOfChildNode:element];
    
    		if (index > 0) {
    			return elementIndex > index;
    		} else {
                return (elementIndex > index && elementIndex < element.parentElement.childNodesCount);
    		}
    	});
    }
    
    bug 
    opened by samhuangszu 4
  • Not being able to use HTMLKit via Xcode Package Manager

    Not being able to use HTMLKit via Xcode Package Manager

    When I try to add HTMLKit as a dependency I get an error message at the Resolving package dependencies stage:

    because HTMLKit >=0.9.4 contains incompatible tools version and root depends on HTMLKit 3.1.0..<4.0.0, version solving failed.
    

    Tested on Xcode 11.4 and 12 beta.

    opened by pendowski 3
  • Collision with Category Names

    Collision with Category Names

    The NSString+HTMLKit.h and NSCharacterSet+HTMLKit.h categories contain generic named category methods. They are causing collisions with other methods I've already been using. It would be great if you could prefix the methods to reduce potential collisions. Perhaps the prefix could be "html_" or something similar. Thanks!

    opened by jerelevine 3
  • Custom self closing tags are not detected properly.

    Custom self closing tags are not detected properly.

    Hi,

    I have an issue with HTML-Kit. When I parse an HTML content which has few self-closing custom tags, it is not detected properly.

    Here is the sample code,

    Screenshot 2020-05-11 at 11 24 22 AM

    NSArray *images = [self.document querySelectorAll:@"MyTag"];

    Pls, see the array results in below image

    Screenshot 2020-05-11 at 11 24 27 AM
    opened by MohideenSheikSulaiman 3
  • Recursion crash

    Recursion crash

    frame #8386: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8387: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8388: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8389: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8390: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8391: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8392: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8393: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8394: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8395: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8396: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8397: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8398: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8399: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8400: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8401: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8402: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8403: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8404: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8405: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8406: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8407: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8408: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8409: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8410: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8411: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8412: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8413: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8414: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8415: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8416: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8417: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8418: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8419: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8420: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8421: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8422: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8423: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8424: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8425: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8426: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8427: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8428: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8429: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8430: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8431: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8432: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8433: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8434: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8435: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8436: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8437: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8438: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8439: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8440: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8441: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8442: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8443: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8444: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8445: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8446: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8447: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8448: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8449: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8450: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8451: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8452: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8453: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8454: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8455: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8456: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8457: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8458: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8459: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8460: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8461: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8462: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8463: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8464: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8465: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8466: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8467: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8468: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8469: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8470: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8471: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8472: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8473: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8474: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8475: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8476: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8477: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8478: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8479: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8480: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8481: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8482: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8483: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8484: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8485: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8486: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8487: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8488: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8489: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8490: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8491: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8492: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8493: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8494: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8495: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8496: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8497: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8498: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8499: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8500: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8501: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8502: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8503: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8504: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8505: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8506: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8507: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8508: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8509: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8510: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8511: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8512: 0x00007fff36033e0f CoreFoundation`__RELEASE_OBJECTS_IN_THE_ARRAY__ + 122
    frame #8513: 0x00007fff35f32e3e CoreFoundation`-[__NSArrayM dealloc] + 289
    frame #8514: 0x00007fff35fd592d CoreFoundation`-[__NSOrderedSetM dealloc] + 157
    frame #8515: 0x00007fff6c50dd16 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 83
    frame #8516: 0x00007fff6c5076c3 libobjc.A.dylib`objc_destructInstance + 94
    frame #8517: 0x00007fff6c50762b libobjc.A.dylib`_objc_rootDealloc + 62
    frame #8518: 0x00007fff6c52152a libobjc.A.dylib`AutoreleasePoolPage::releaseUntil(objc_object**) + 134
    frame #8519: 0x00007fff6c507c30 libobjc.A.dylib`objc_autoreleasePoolPop + 175
    frame #8520: 0x00007fff35aa998b CoreData`developerSubmittedBlockToNSManagedObjectContextPerform + 411
    frame #8521: 0x0000000103c8f84f libdispatch.dylib`_dispatch_client_callout + 8
    frame #8522: 0x0000000103c96df1 libdispatch.dylib`_dispatch_lane_serial_drain + 777
    frame #8523: 0x0000000103c97ba8 libdispatch.dylib`_dispatch_lane_invoke + 438
    frame #8524: 0x0000000103ca5045 libdispatch.dylib`_dispatch_workloop_worker_thread + 676
    frame #8525: 0x0000000103d1b0b3 libsystem_pthread.dylib`_pthread_wqthread + 290
    frame #8526: 0x0000000103d1af1b libsystem_pthread.dylib`start_wqthread + 15
    
    opened by sekharchandra 0
  • some tags in XHTML are not closed after being parsed

    some tags in XHTML are not closed after being parsed

    When I parse an XHTML, I discovered that the tags in the are not being closed:

    <head>
     <title>page</title>
     <meta charset="utf-8"></meta>
    <link href="css/template.css" rel="stylesheet" type="text/css"></link>
    </head>
    

    the innerHTML returns:

    <head>
     <title>page</title>
     <meta charset="utf-8">
    <link href="css/template.css" rel="stylesheet" type="text/css">
    </head>
    

    and for example if I query [document querySelector:@"link"].outerHTML I get <link href="css/template.css" rel="stylesheet" type="text/css">

    [document querySelector:@"meta"].innerHTML <object returned empty description>

    [document querySelector:@"meta"].outerHTML <meta charset="utf-8">

    Title is correct, though. My XHTML is not valid anymore and the Webview fails parsing it. Is there a way to avoid this loss of information? thanks!

    opened by ecarnevale 0
  • textContent strips <br/>s

    textContent strips
    s

    let element:HTMLElement = HTMLElement(tagName: "div")
    element.innerHTML = "Line<br/>Breaks"
    print("\(element.textContent)")
    

    output:

    LineBreaks
    

    desired:

    Line\nBreaks
    

    At leas this is how NSAttributedString's initWithHTML works. Anything I need to do to get this to work properly?

    opened by guidedways 5
  • Implement HTML escaping for arbitrary string input

    Implement HTML escaping for arbitrary string input

    This looks like a powerful library to navigate around HTML nodes, however what would be the simplest method of obtaining cleaned up 'plain text' from HTML input? I'd like it to preserve any 'invalid' non-html tags such as John Do <[email protected]> and not try and parse it as NSAttributedString's initWithHTML does.

    question feature request 
    opened by guidedways 6
Releases(4.2.0)
  • 4.2.0(Apr 29, 2021)

    • Fix test compilation under Xcode 12.5 (issue #43)
    • Updated HTML5Lib-Tests submodule (082a4be)
    • Updated parser and tokenizer for latest spec changes to pass test suite
    Source code(tar.gz)
    Source code(zip)
  • 4.1.0(Apr 28, 2021)

  • 4.0.0(Jul 16, 2020)

  • 3.1.0(Aug 20, 2019)

    Release on 2019.08.20

    Added

    • HTMLTreeVisitor that walks the DOM in tree order
    • New HTML serialization implementation based on visitor pattern

    Fixes

    • HTML serialization for deeply nested DOM trees (issue #33)
    • Occasional Internal Consistency exceptions when deallocating node iterator (issue #36)
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Mar 28, 2019)

    Released on 2019.03.28

    Breaking Change

    • Introduce prefix for NSString and NSCharacterSet categories to prevent collision with existing code (issue #35)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.5(Jul 16, 2018)

  • 2.1.4(May 1, 2018)

  • 2.1.3(Mar 21, 2018)

    Released on 2018.03.21

    Fixes

    • HTMLElement clone would return an immutable dictionary for attributes (issue #20)
      • Fixed by @CRivlaldo in PR #24
    • HTMLNodeFilterBlock would behave differently on simulator and device (issue #22)
      • Fixed by @CRivlaldo in PR #23
    Source code(tar.gz)
    Source code(zip)
  • 2.1.2(Nov 6, 2017)

  • 2.1.1(Oct 13, 2017)

  • 2.1.0(Oct 12, 2017)

  • 2.0.6(May 2, 2017)

    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
    Source code(tar.gz)
    Source code(zip)
  • 2.0.5(Apr 19, 2017)

    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
      • Underlying data string of CharacterData is allocated on first access
      • Autorelease pool for the main HTMLTokenizer loop
    Source code(tar.gz)
    Source code(zip)
  • 2.0.4(Apr 19, 2017)

    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:
    Source code(tar.gz)
    Source code(zip)
  • 2.0.3(Mar 5, 2017)

  • 2.0.2(Feb 26, 2017)

    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
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Feb 20, 2017)

    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
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Feb 11, 2017)

  • 1.1.0(Jan 14, 2017)

    Released on 2017.01.14

    Added

    • DOM Ranges implementation (spec)
    • 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
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Sep 28, 2016)

    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
    Source code(tar.gz)
    Source code(zip)
  • 0.9.4(Sep 3, 2016)

  • 0.9.3(Jul 16, 2016)

    Released on 2016.07.16

    This release passes all html5lib-tests as of 2016.07.16

    Added

    • watchOS and tvOS targets
    • Updated HTML5Lib-Tests submodule (c305da7)
    Source code(tar.gz)
    Source code(zip)
  • 0.9.2(May 18, 2016)

    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:
    • <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
    Source code(tar.gz)
    Source code(zip)
  • 0.9.1(Feb 1, 2016)

    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.
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Feb 1, 2016)

    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.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Feb 1, 2016)

    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

    • InputStreamReader's reconsume-logic that is required by the CSS Parser.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Feb 1, 2016)

    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.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Feb 1, 2016)

    Released on 2015.04.20

    Added

    • Initial release.
    • Initial DOM implementation.
    • Tokenizer and Parser pass all HTML5Lib tokenizer and tree construction tests except for <ruby> elements.
    Source code(tar.gz)
    Source code(zip)
Owner
Iskandar Abudiab
Iskandar Abudiab
Ji (戟) is an XML/HTML parser for Swift

Ji 戟 Ji (戟) is a Swift wrapper on libxml2 for parsing XML/HTML. Features Build XML/HTML Tree and Navigate. XPath Query Supported. Comprehensive Unit T

HongHao Zhang 824 Dec 15, 2022
Kanna(鉋) is an XML/HTML parser for Swift.

Kanna(鉋) Kanna(鉋) is an XML/HTML parser for cross-platform(macOS, iOS, tvOS, watchOS and Linux!). It was inspired by Nokogiri(鋸). ℹ️ Documentation Fea

Atsushi Kiwaki 2.3k Dec 31, 2022
SwiftSoup: Pure Swift HTML Parser, with best of DOM, CSS, and jquery (Supports Linux, iOS, Mac, tvOS, watchOS)

SwiftSoup is a pure Swift library, cross-platform (macOS, iOS, tvOS, watchOS and Linux!), for working with real-world HTML. It provides a very conveni

Nabil Chatbi 3.7k Jan 6, 2023
📄 A Swift DSL for writing type-safe HTML/CSS in SwiftUI way

?? swift-web-page (swep) Swep is a Swift DSL for writing type-safe HTML/CSS in SwiftUI way. Table of Contents Motivation Examples Safety Design FAQ In

Abdullah Aljahdali 14 Dec 31, 2022
Convert text with HTML tags, links, hashtags, mentions into NSAttributedString. Make them clickable with UILabel drop-in replacement.

Convert text with HTML tags, links, hashtags, mentions into NSAttributedString. Make them clickable with UILabel drop-in replacement.

Pavel Sharanda 1.1k Dec 26, 2022
Swift package to convert a HTML table into an array of dictionaries.

Swift package to convert a HTML table into an array of dictionaries.

null 1 Jun 18, 2022
Mongrel is a Swift and HTML hybrid with a bit of support for CSS and Javascript.

Mongrel is a Swift and HTML hybrid with a bit of support for CSS and Javascript. Using a declaritive style of programming, Mongrel makes writing HTML feel natural and easy. Mongrel also uses a SwiftUI like body structure allowing structs to be completely dedicated as an HTML page or element.

Nicholas Bellucci 12 Sep 22, 2022
A sensible way to deal with XML & HTML for iOS & macOS

Ono (斧) Foundation lacks a convenient, cross-platform way to work with HTML and XML. NSXMLParser is an event-driven, SAX-style API that can be cumbers

Mattt 2.6k Dec 14, 2022
CheatyXML is a Swift framework designed to manage XML easily

CheatyXML CheatyXML is a Swift framework designed to manage XML easily. Requirements iOS 8.0 or later tvOS 9.0 or later Installation Cocoapods If you'

Louis Bodart 24 Mar 31, 2022
Mathias Köhnke 1.1k Dec 16, 2022
A result builder that build HTML parser and transform HTML elements to strongly-typed result, inspired by RegexBuilder.

HTMLParserBuilder A result builder that build HTML parser and transform HTML elements to strongly-typed result, inspired by RegexBuilder. Note: Captur

null 4 Aug 25, 2022
A quick and "lean" way to swizzle methods for your Objective-C development needs.

Swizzlean A quick and "lean" way to swizzle methods for your Objective-C development needs. Adding Swizzlean to your project Cocoapods CocoaPods is th

Ryan Baumbach 104 Oct 11, 2022
Perspective is a friendly charting iOS App for your everyday use.

Perspective Perspective is a friendly charting iOS App for your everyday use. Nowadays, Data is everywhere, and we tend to feel like we have a picture

Csaba Kuti 1 Dec 20, 2021
App in Swift that shows a picture of an astronomical phenomenon and a brief explanation of it everyday, allowing you to save that data or share it on a social network.

DailyUniverse ??‍♂️ ?? App under construction iOS App that shows a picture of an astronomical phenomenon and a brief explanation of it everyday. Daily

Pedro Muniz 5 Nov 3, 2022
An Objective-C framework for converting Markdown to HTML.

MMMarkdown MMMarkdown is an Objective-C framework for converting Markdown to HTML. It is compatible with OS X 10.7+, iOS 8.0+, tvOS, and watchOS. Unli

Matt Diephouse 1.2k Dec 14, 2022
JSPatch bridge Objective-C and Javascript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. JSPatch is generally used to hotfix iOS App.

JSPatch 中文介绍 | 文档 | JSPatch平台 请大家不要自行接入 JSPatch,统一接入 JSPatch 平台,让热修复在一个安全和可控的环境下使用。原因详见 这里 JSPatch bridges Objective-C and JavaScript using the Object

bang 11.4k Jan 1, 2023
An iOS picker view to serve all your "picking" needs

Mandoline The PickerView is a UICollectionView that provides a smooth "picking" interface. In order to get the most out of it, a consuming view contro

Blue Apron 883 Nov 28, 2022
An iOS picker view to serve all your "picking" needs

Mandoline The PickerView is a UICollectionView that provides a smooth "picking" interface. In order to get the most out of it, a consuming view contro

Blue Apron 883 Nov 28, 2022
A modern iOS toast view that can fit your notification needs

CRToast CRToast is a library that allows you to easily create notifications that appear on top of or by pushing out the status bar or navigation bar.

Collin Ruffenach 4.2k Dec 30, 2022