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:
@@ -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 */,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user