Skip to content

Commit

Permalink
Added support for decoding unicode sequences in CSS content attribute.
Browse files Browse the repository at this point in the history
e.g. \0009 for a tab
  • Loading branch information
odrobnik committed May 28, 2012
1 parent d38911d commit 2682488
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Core/Source/DTHTMLElement.m
Expand Up @@ -273,7 +273,7 @@ - (void)applyStyleDictionary:(NSDictionary *)styles
_styles = styles;

// register pseudo-selector contents
self.beforeContent = [_styles objectForKey:@"before:content"];
self.beforeContent = [[_styles objectForKey:@"before:content"] stringByDecodingCSSContentAttribute];

NSString *fontSize = [styles objectForKey:@"font-size"];
if (fontSize)
Expand Down
5 changes: 5 additions & 0 deletions Core/Source/NSString+CSS.h
Expand Up @@ -43,4 +43,9 @@
*/
- (CGFloat)CSSpixelSize;

/**
Decodes a content attribute which might contained unicode sequences.
*/
- (NSString *)stringByDecodingCSSContentAttribute;

@end
95 changes: 95 additions & 0 deletions Core/Source/NSString+CSS.m
Expand Up @@ -223,4 +223,99 @@ - (CGFloat)CSSpixelSize
return [self floatValue];
}

- (NSString *)stringByDecodingCSSContentAttribute
{
NSUInteger length = [self length];

unichar *characters = calloc(length, sizeof(unichar));
unichar *final = calloc(length, sizeof(unichar));

[self getCharacters:characters range:NSMakeRange(0, length)];

NSUInteger outChars = 0;

BOOL inEscapedSequence = NO;
unichar decodedChar = 0;
NSUInteger escapedCharacterCount = 0;

for (NSUInteger idx=0; idx<length;idx++)
{
unichar character = characters[idx];

if (inEscapedSequence && (escapedCharacterCount<4))
{
if (character=='\\')
{
// escaped backslash
final[outChars++] = '\\';
inEscapedSequence = NO;
}
else if ((character>='0' && character<='9') || (character>='A' && character<='F') || (character>='a' && character<='f'))
{
// hex digit
decodedChar *= 16;

if (character>='0' && character<='9')
{
decodedChar += (character - '0');
}
else if (character>='A' && character<='F')
{
decodedChar += (character - 'A' + 10);
}
else if (character>='a' && character<='f')
{
decodedChar += (character - 'a' + 10);
}

escapedCharacterCount++;
}
else
{
// illegal character following slash
final[outChars++] = '\\';
final[outChars++] = character;

inEscapedSequence = NO;
}
}
else
{
if (character == '\\')
{
// begin of escape sequence
decodedChar = 0;
escapedCharacterCount = 0;
inEscapedSequence = YES;
}
else
{
if (inEscapedSequence)
{
// output what we have decoded so far
final[outChars++] = decodedChar;
}

inEscapedSequence = NO;

// just copy
final[outChars++] = character;
}
}
}

// if string ended in escaped sequence we still need to output
if (inEscapedSequence)
{
// output what we have decoded so far
final[outChars++] = decodedChar;
}

free(characters);
NSString *clean = [[NSString alloc] initWithCharacters:final length:outChars];
free(final);

return clean;
}

@end

0 comments on commit 2682488

Please sign in to comment.