OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. |
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
10 * | 10 * |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 unsigned length = string.length(); | 61 unsigned length = string.length(); |
62 | 62 |
63 if (!length) | 63 if (!length) |
64 return false; | 64 return false; |
65 | 65 |
66 if (string.is8Bit()) | 66 if (string.is8Bit()) |
67 return isCSSTokenizerIdentifier(string.characters8(), length); | 67 return isCSSTokenizerIdentifier(string.characters8(), length); |
68 return isCSSTokenizerIdentifier(string.characters16(), length); | 68 return isCSSTokenizerIdentifier(string.characters16(), length); |
69 } | 69 } |
70 | 70 |
71 template <typename CharacterType> | |
72 static inline String quoteCSSStringInternal(const CharacterType* characters, uns
igned length) | |
73 { | |
74 // For efficiency, we first pre-calculate the length of the quoted string, t
hen we build the actual one. | |
75 // Please see below for the actual logic. | |
76 unsigned quotedStringSize = 2; // Two quotes surrounding the entire string. | |
77 bool afterEscape = false; | |
78 for (unsigned i = 0; i < length; ++i) { | |
79 CharacterType ch = characters[i]; | |
80 if (ch == '\\' || ch == '\'') { | |
81 quotedStringSize += 2; | |
82 afterEscape = false; | |
83 } else if (ch < 0x20 || ch == 0x7F) { | |
84 quotedStringSize += 2 + (ch >= 0x10); | |
85 afterEscape = true; | |
86 } else { | |
87 quotedStringSize += 1 + (afterEscape && (isASCIIHexDigit(ch) || ch =
= ' ')); | |
88 afterEscape = false; | |
89 } | |
90 } | |
91 | |
92 StringBuffer<CharacterType> buffer(quotedStringSize); | |
93 unsigned index = 0; | |
94 buffer[index++] = '\''; | |
95 afterEscape = false; | |
96 for (unsigned i = 0; i < length; ++i) { | |
97 CharacterType ch = characters[i]; | |
98 if (ch == '\\' || ch == '\'') { | |
99 buffer[index++] = '\\'; | |
100 buffer[index++] = ch; | |
101 afterEscape = false; | |
102 } else if (ch < 0x20 || ch == 0x7F) { // Control characters. | |
103 buffer[index++] = '\\'; | |
104 placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase); | |
105 afterEscape = true; | |
106 } else { | |
107 // Space character may be required to separate backslash-escape sequ
ence and normal characters. | |
108 if (afterEscape && (isASCIIHexDigit(ch) || ch == ' ')) | |
109 buffer[index++] = ' '; | |
110 buffer[index++] = ch; | |
111 afterEscape = false; | |
112 } | |
113 } | |
114 buffer[index++] = '\''; | |
115 | |
116 ASSERT(quotedStringSize == index); | |
117 return String::adopt(buffer); | |
118 } | |
119 | |
120 // We use single quotes for now because Serialization.cpp uses double quotes. | |
121 static String quoteCSSString(const String& string) | |
122 { | |
123 // This function expands each character to at most 3 characters ('\u0010' ->
'\' '1' '0') as well as adds | |
124 // 2 quote characters (before and after). Make sure the resulting size (3 *
length + 2) will not overflow unsigned. | |
125 | |
126 unsigned length = string.length(); | |
127 | |
128 if (!length) | |
129 return String("\'\'"); | |
130 | |
131 if (length > std::numeric_limits<unsigned>::max() / 3 - 2) | |
132 return emptyString(); | |
133 | |
134 if (string.is8Bit()) | |
135 return quoteCSSStringInternal(string.characters8(), length); | |
136 return quoteCSSStringInternal(string.characters16(), length); | |
137 } | |
138 | |
139 String quoteCSSStringIfNeeded(const String& string) | |
140 { | |
141 return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string); | |
142 } | |
143 | |
144 static void serializeCharacter(UChar32 c, StringBuilder& appendTo) | 71 static void serializeCharacter(UChar32 c, StringBuilder& appendTo) |
145 { | 72 { |
146 appendTo.append('\\'); | 73 appendTo.append('\\'); |
147 appendTo.append(c); | 74 appendTo.append(c); |
148 } | 75 } |
149 | 76 |
150 static void serializeCharacterAsCodePoint(UChar32 c, StringBuilder& appendTo) | 77 static void serializeCharacterAsCodePoint(UChar32 c, StringBuilder& appendTo) |
151 { | 78 { |
152 appendTo.append('\\'); | 79 appendTo.append('\\'); |
153 appendUnsignedAsHex(c, appendTo, Lowercase); | 80 appendUnsignedAsHex(c, appendTo, Lowercase); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 } | 118 } |
192 | 119 |
193 void serializeString(const String& string, StringBuilder& appendTo) | 120 void serializeString(const String& string, StringBuilder& appendTo) |
194 { | 121 { |
195 appendTo.append('\"'); | 122 appendTo.append('\"'); |
196 | 123 |
197 unsigned index = 0; | 124 unsigned index = 0; |
198 while (index < string.length()) { | 125 while (index < string.length()) { |
199 UChar32 c = string.characterStartingAt(index); | 126 UChar32 c = string.characterStartingAt(index); |
200 index += U16_LENGTH(c); | 127 index += U16_LENGTH(c); |
201 if (c <= 0x1f) | 128 |
| 129 if (c <= 0x1f || c == 0x7f) |
202 serializeCharacterAsCodePoint(c, appendTo); | 130 serializeCharacterAsCodePoint(c, appendTo); |
203 else if (c == 0x22 || c == 0x5c) | 131 else if (c == 0x22 || c == 0x5c) |
204 serializeCharacter(c, appendTo); | 132 serializeCharacter(c, appendTo); |
205 else | 133 else |
206 appendTo.append(c); | 134 appendTo.append(c); |
207 } | 135 } |
208 | 136 |
209 appendTo.append('\"'); | 137 appendTo.append('\"'); |
210 } | 138 } |
211 | 139 |
212 String serializeString(const String& string) | 140 String serializeString(const String& string) |
213 { | 141 { |
214 StringBuilder builder; | 142 StringBuilder builder; |
215 serializeString(string, builder); | 143 serializeString(string, builder); |
216 return builder.toString(); | 144 return builder.toString(); |
217 } | 145 } |
218 | 146 |
219 String serializeURI(const String& string) | 147 String serializeURI(const String& string) |
220 { | 148 { |
221 return "url(" + serializeString(string) + ")"; | 149 return "url(" + serializeString(string) + ")"; |
222 } | 150 } |
223 | 151 |
| 152 String serializeFontFamily(const String& string) |
| 153 { |
| 154 return isCSSTokenizerIdentifier(string) ? string : serializeString(string); |
| 155 } |
| 156 |
224 } // namespace blink | 157 } // namespace blink |
OLD | NEW |