11 Commits

Author SHA1 Message Date
iska 4094f51458 Merge branch 'release/2.0.5' 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
11 changed files with 100 additions and 36 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
module: HTMLKit
module_version: 2.0.4
module_version: 2.0.5
author: Iskandar Abudiab
author_url: https://twitter.com/iabudiab
github_url: https://github.com/iabudiab/HTMLKit
+16
View File
@@ -1,5 +1,21 @@
# Change Log
## [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
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "HTMLKit"
s.version = "2.0.4"
s.version = "2.0.5"
s.summary = "HTMLKit, an Objective-C framework for your everyday HTML needs."
s.license = "MIT"
s.homepage = "https://github.com/iabudiab/HTMLKit"
+15 -5
View File
@@ -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,7 +115,7 @@
[self consumeNextInputCharacter];
}
NSScanner *scanner = [NSScanner scannerWithString:(__bridge NSString *)(hexString)];
NSScanner *scanner = [NSScanner scannerWithString:(__bridge_transfer NSString *)(hexString)];
unsigned int number;
[scanner scanHexInt:&number];
+15 -4
View File
@@ -24,14 +24,25 @@
{
self = [super initWithName:name type:type];
if (self) {
_data = [[NSMutableString alloc] initWithString:data ?: @""];
if (data) {
_data = [[NSMutableString alloc] initWithString:data];
}
}
return self;
}
- (NSString *)data
{
if (_data == nil) {
_data = [[NSMutableString alloc] initWithString:@""];
}
return _data;
}
- (NSString *)textContent
{
return [_data copy];
return [self.data copy];
}
- (void)setTextContent:(NSString *)textContent
@@ -41,7 +52,7 @@
- (NSUInteger)length
{
return _data.length;
return self.data.length;
}
#pragma mark - Data
@@ -81,7 +92,7 @@ NS_INLINE void CheckValidOffset(HTMLCharacterData *node, NSUInteger offset, NSSt
range.length = MIN(range.length, self.length - range.location);
[_data replaceCharactersInRange:range withString:data];
[(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];
}
+20 -10
View File
@@ -32,7 +32,7 @@
- (instancetype)initWithTagName:(NSString *)tagName
{
return [self initWithTagName:tagName attributes:@{}];
return [self initWithTagName:tagName attributes:nil];
}
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary *)attributes
@@ -45,8 +45,9 @@
self = [super initWithName:tagName type:HTMLNodeElement];
if (self) {
_tagName = [tagName copy];
_attributes = [HTMLOrderedDictionary new];
_attributes = nil;
if (attributes != nil) {
_attributes = [HTMLOrderedDictionary new];
[_attributes addEntriesFromDictionary:attributes];
}
_htmlNamespace = htmlNamespace;
@@ -56,24 +57,33 @@
#pragma mark - Special Attributes
- (NSMutableDictionary<NSString *,NSString *> *)attributes
{
if (_attributes == nil) {
_attributes = [HTMLOrderedDictionary new];
}
return _attributes;
}
- (NSString *)elementId
{
return _attributes[@"id"] ?: @"";
return self.attributes[@"id"] ?: @"";
}
- (void)setElementId:(NSString *)elementId
{
_attributes[@"id"] = elementId;
self.attributes[@"id"] = elementId;
}
- (NSString *)className
{
return _attributes[@"class"] ?: @"";
return self.attributes[@"class"] ?: @"";
}
- (void)setClassName:(NSString *)className
{
_attributes[@"class"] = className;
self.attributes[@"class"] = className;
}
- (HTMLDOMTokenList *)classList
@@ -85,22 +95,22 @@
- (BOOL)hasAttribute:(NSString *)name
{
return _attributes[name] != nil;
return self.attributes[name] != nil;
}
- (NSString *)objectForKeyedSubscript:(NSString *)name;
{
return _attributes[name];
return self.attributes[name];
}
- (void)setObject:(NSString *)value forKeyedSubscript:(NSString *)attribute
{
_attributes[attribute] = value;
self.attributes[attribute] = value;
}
- (void)removeAttribute:(NSString *)name
{
[_attributes removeObjectForKey:name];
[self.attributes removeObjectForKey:name];
}
- (NSString *)textContent
+1 -1
View File
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.4</string>
<string>2.0.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+20 -5
View File
@@ -36,13 +36,22 @@
if (self) {
_name = name;
_nodeType = type;
_childNodes = [NSMutableOrderedSet new];
_childNodes = nil;
}
return self;
}
#pragma mark - Properties
- (NSOrderedSet<HTMLNode *> *)childNodes
{
if (_childNodes == nil) {
_childNodes = [NSMutableOrderedSet new];
}
return _childNodes;
}
- (HTMLDocument *)ownerDocument
{
if (_nodeType == HTMLNodeDocument) {
@@ -55,7 +64,9 @@
- (void)setOwnerDocument:(HTMLDocument *)ownerDocument
{
_ownerDocument = ownerDocument;
[self.childNodes.array makeObjectsPerformSelector:@selector(setOwnerDocument:) withObject:ownerDocument];
for (HTMLNode *child in self.childNodes) {
[child setOwnerDocument:ownerDocument];
}
}
- (HTMLNode *)rootNode
@@ -262,7 +273,9 @@
[node removeAllChildNodes];
}
[nodes makeObjectsPerformSelector:@selector(setParentNode:) withObject:self];
for (HTMLNode *node in nodes) {
[node setParentNode:self];
}
return node;
}
@@ -322,7 +335,7 @@
- (void)reparentChildNodesIntoNode:(HTMLNode *)node
{
for (HTMLNode *child in self.childNodes.array) {
for (HTMLNode *child in self.childNodes) {
[node appendNode:child];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
@@ -330,7 +343,9 @@
- (void)removeAllChildNodes
{
[self.childNodes.array makeObjectsPerformSelector:@selector(setParentNode:) withObject:nil];
for (HTMLNode *child in self.childNodes) {
[child setParentNode:nil];
}
[(NSMutableOrderedSet *)self.childNodes removeAllObjects];
}
+9 -7
View File
@@ -77,14 +77,16 @@
- (id)nextObject
{
while (_eof == NO && _tokens.count == 0) {
[self read];
@autoreleasepool {
while (_eof == NO && _tokens.count == 0) {
[self read];
}
HTMLToken *nextToken = [_tokens firstObject];
if (_tokens.count > 0) {
[_tokens removeObjectAtIndex:0];
}
return nextToken;
}
HTMLToken *nextToken = [_tokens firstObject];
if (_tokens.count > 0) {
[_tokens removeObjectAtIndex:0];
}
return nextToken;
}
- (void)read
+2 -2
View File
@@ -75,7 +75,7 @@ NS_ASSUME_NONNULL_BEGIN
@param attributes The attributes.
@return A new HTML element.
*/
- (instancetype)initWithTagName:(NSString *)tagName attributes:(NSDictionary<NSString *, NSString *> *)attributes;
- (instancetype)initWithTagName:(NSString *)tagName attributes:(nullable NSDictionary<NSString *, NSString *> *)attributes;
/**
Initializes a new HTML element with the given tag name, namespace, and attributes.
@@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN
@param attributes The attributes.
@return A new HTML element.
*/
- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(NSDictionary<NSString *, NSString *> *)attributes;
- (instancetype)initWithTagName:(NSString *)tagName namespace:(HTMLNamespace)htmlNamespace attributes:(nullable NSDictionary<NSString *, NSString *> *)attributes;
/**
Checks whether this element has an attribute with the given name.