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
This commit is contained in:
iska
2016-11-27 20:18:12 +01:00
parent ef672e1dbb
commit 6be1bd702f
7 changed files with 112 additions and 8 deletions
+10
View File
@@ -534,6 +534,10 @@
62ECBFDE1C0B6E4400AF847B /* HTML Standard.html in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90D19FC702E00BD3C4A /* HTML Standard.html */; };
62ECBFDF1C0B6E4400AF847B /* html5lib-tests in Resources */ = {isa = PBXBuildFile; fileRef = 624AC90419FBFE8A00BD3C4A /* html5lib-tests */; };
62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; };
62F7E5A21DEB63F900DEF09B /* HTMLRange+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */; };
62F7E5A31DEB63F900DEF09B /* HTMLRange+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */; };
62F7E5A41DEB63F900DEF09B /* HTMLRange+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */; };
62F7E5A51DEB63F900DEF09B /* HTMLRange+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -710,6 +714,7 @@
62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSNthExpressionParser.h; path = include/CSSNthExpressionParser.h; sourceTree = "<group>"; };
62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = "<group>"; };
62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNThExpressionSelectorTests.m; sourceTree = "<group>"; };
62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HTMLRange+Private.h"; sourceTree = "<group>"; };
62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLParser.h; path = include/HTMLParser.h; sourceTree = "<group>"; };
62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = "<group>"; };
62FA04E11BCC360D009ABF98 /* CSSCombinatorSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSCombinatorSelector.h; path = include/CSSCombinatorSelector.h; sourceTree = "<group>"; };
@@ -989,6 +994,7 @@
625D0F011C2717DE00D7BEB0 /* HTMLNode+Private.h */,
626679CD1DEA3DAF004353E7 /* HTMLCharacterData+Private.h */,
621CC4991DEA71D800D1992A /* HTMLNodeIterator+Private.h */,
62F7E5A01DEB63F900DEF09B /* HTMLRange+Private.h */,
621CC4A31DEA721A00D1992A /* HTMLParser+Private.h */,
);
name = Private;
@@ -1124,6 +1130,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
62F7E5A21DEB63F900DEF09B /* HTMLRange+Private.h in Headers */,
62ECBF181C0B6A1000AF847B /* HTMLKit.h in Headers */,
62ECBEE11C0B69FD00AF847B /* HTMLKitErrorDomain.h in Headers */,
62ECBEE21C0B69FD00AF847B /* HTMLInputStreamReader.h in Headers */,
@@ -1195,6 +1202,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
62F7E5A51DEB63F900DEF09B /* HTMLRange+Private.h in Headers */,
62857CBE1D398999008DC254 /* NSString+HTMLKit.h in Headers */,
62857CAC1D398973008DC254 /* HTMLKitDOMExceptions.h in Headers */,
62857CD61D3989C2008DC254 /* CSSSelectorParser.h in Headers */,
@@ -1266,6 +1274,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
62F7E5A41DEB63F900DEF09B /* HTMLRange+Private.h in Headers */,
62857D831D39A46D008DC254 /* CSSStructuralPseudoSelectors.h in Headers */,
62857D7D1D39A457008DC254 /* HTMLNodeTraversal.h in Headers */,
62857D841D39A472008DC254 /* CSSSelectorParser.h in Headers */,
@@ -1337,6 +1346,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
62F7E5A31DEB63F900DEF09B /* HTMLRange+Private.h in Headers */,
62ECBF901C0B6D3700AF847B /* HTMLKit.h in Headers */,
62ECBF911C0B6D3700AF847B /* HTMLKitErrorDomain.h in Headers */,
62ECBF9F1C0B6D3900AF847B /* HTMLParser.h in Headers */,
+8 -2
View File
@@ -17,8 +17,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface HTMLCharacterData : HTMLNode
/** @brief The associated mutable data string. */
@property (nonatomic, copy, readonly) NSMutableString *data;
/** @brief The associated data string. */
@property (nonatomic, copy, readonly) NSString *data;
- (void)setData:(NSString *)data;
- (void)appendData:(NSString *)data;
- (void)insertData:(NSString *)data atOffset:(NSUInteger)offset;
- (void)deleteDataInRange:(NSRange)range;
- (void)replaceDataInRange:(NSRange)range withData:(NSString *)data;
@end
+53 -2
View File
@@ -8,8 +8,17 @@
#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
{
@@ -27,7 +36,7 @@
- (void)setTextContent:(NSString *)textContent
{
[_data setString:textContent ?: @""];
[self setData:textContent];
}
- (NSUInteger)length
@@ -35,12 +44,54 @@
return _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);
[_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];
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
HTMLCharacterData *copy = [super copyWithZone:zone];
copy->_data = self.data;
copy->_data = _data;
return copy;
}
+4
View File
@@ -8,6 +8,7 @@
#import "HTMLDocument.h"
#import "HTMLNode.h"
#import "HTMLCharacterData.h"
#import "HTMLNodeIterator.h"
#import "HTMLRange.h"
@@ -58,4 +59,7 @@
*/
- (void)detachRange:(HTMLRange *)range;
- (void)didRemoveCharacterDataInNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length;
- (void)didAddCharacterDataToNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length;
@end
+18 -2
View File
@@ -10,9 +10,11 @@
#import "HTMLParser.h"
#import "HTMLNodeIterator.h"
#import "HTMLRange.h"
#import "HTMLCharacterData.h"
#import "HTMLKitDOMExceptions.h"
#import "HTMLNode+Private.h"
#import "HTMLNodeIterator+Private.h"
#import "HTMLRange+Private.h"
@interface HTMLDocument ()
{
@@ -147,8 +149,8 @@
{
for (HTMLNodeIterator *iterator in _nodeIterators) {
[iterator runRemovingStepsForNode:oldNode
withOldParent:oldParent
andOldPreviousSibling:oldPreviousSibling];
withOldParent:oldParent
andOldPreviousSibling:oldPreviousSibling];
}
}
@@ -164,6 +166,20 @@
[_ranges removeObject:range];
}
- (void)didRemoveCharacterDataInNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length
{
for (HTMLRange *range in _ranges) {
[range didRemoveCharacterDataInNode:node atOffset:offset withLength:length];
}
}
- (void)didAddCharacterDataToNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length
{
for (HTMLRange *range in _ranges) {
[range didAddCharacterDataToNode:node atOffset:offset withLength:length];
}
}
#pragma mark - Mutation Algorithms
- (HTMLNode *)adoptNode:(HTMLNode *)node
+2 -2
View File
@@ -451,10 +451,10 @@
if (adjustedInsertionLocation.nodeType != HTMLNodeDocument) {
if (child != nil && child.previousSibling.nodeType == HTMLNodeText) {
HTMLText *textNode = (HTMLText *)child.previousSibling;
[textNode.data appendString:data];
[textNode appendData:data];
} else if (adjustedInsertionLocation.lastChild.nodeType == HTMLNodeText) {
HTMLText *textNode = (HTMLText *)adjustedInsertionLocation.lastChild;
[textNode.data appendString:data];
[textNode appendData:data];
} else {
HTMLText *text = [[HTMLText alloc] initWithData:data];
[adjustedInsertionLocation insertNode:text beforeChildNode:child];
+17
View File
@@ -0,0 +1,17 @@
//
// HTMLRange+Private.h
// HTMLKit
//
// Created by Iska on 27/11/16.
// Copyright © 2016 BrainCookie. All rights reserved.
//
#import "HTMLRange.h"
#import "HTMLCharacterData.h"
@interface HTMLRange ()
- (void)didRemoveCharacterDataInNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length;
- (void)didAddCharacterDataToNode:(HTMLCharacterData *)node atOffset:(NSUInteger)offset withLength:(NSUInteger)length;
@end