OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/css/parser/MediaQueryTokenizer.h" | 6 #include "core/css/parser/MediaQueryTokenizer.h" |
7 | 7 |
8 namespace WebCore { | 8 namespace WebCore { |
9 #include "MediaQueryTokenizerCodepoints.cpp" | 9 #include "MediaQueryTokenizerCodepoints.cpp" |
10 } | 10 } |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 return true; | 326 return true; |
327 } | 327 } |
328 return false; | 328 return false; |
329 } | 329 } |
330 | 330 |
331 // http://www.w3.org/TR/css3-syntax/#consume-a-name | 331 // http://www.w3.org/TR/css3-syntax/#consume-a-name |
332 String MediaQueryTokenizer::consumeName() | 332 String MediaQueryTokenizer::consumeName() |
333 { | 333 { |
334 // FIXME: Is this as efficient as it can be? | 334 // FIXME: Is this as efficient as it can be? |
335 // The possibility of escape chars mandates a copy AFAICT. | 335 // The possibility of escape chars mandates a copy AFAICT. |
336 Vector<UChar> result; | 336 StringBuilder result; |
337 while (true) { | 337 while (true) { |
338 if (isNameChar(m_input.currentInputChar())) { | 338 UChar cc = consume(); |
339 result.append(consume()); | 339 if (isNameChar(cc)) { |
| 340 result.append(cc); |
340 continue; | 341 continue; |
341 } | 342 } |
342 if (nextTwoCharsAreValidEscape()) { | 343 if (twoCharsAreValidEscape(cc, m_input.currentInputChar())) { |
343 // "consume()" fixes a spec bug. | |
344 // The first code point should be consumed before consuming the esca
ped code point. | |
345 consume(); | |
346 result.append(consumeEscape()); | 344 result.append(consumeEscape()); |
347 continue; | 345 continue; |
348 } | 346 } |
349 return String(result); | 347 reconsume(cc); |
| 348 return result.toString(); |
350 } | 349 } |
351 } | 350 } |
352 | 351 |
353 // http://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point | 352 // http://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point |
354 UChar MediaQueryTokenizer::consumeEscape() | 353 UChar MediaQueryTokenizer::consumeEscape() |
355 { | 354 { |
356 UChar cc = consume(); | 355 UChar cc = consume(); |
357 ASSERT(cc != '\n'); | 356 ASSERT(cc != '\n'); |
358 if (isASCIIHexDigit(cc)) { | 357 if (isASCIIHexDigit(cc)) { |
359 unsigned consumedHexDigits = 1; | 358 unsigned consumedHexDigits = 1; |
360 String hexChars; | 359 StringBuilder hexChars; |
361 do { | 360 hexChars.append(cc); |
| 361 while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.currentInputChar
())) { |
| 362 cc = consume(); |
362 hexChars.append(cc); | 363 hexChars.append(cc); |
363 cc = consume(); | |
364 consumedHexDigits++; | 364 consumedHexDigits++; |
365 } while (consumedHexDigits < 6 && isASCIIHexDigit(cc)); | 365 }; |
366 bool ok = false; | 366 bool ok = false; |
367 UChar codePoint = hexChars.toUIntStrict(&ok, 16); | 367 UChar codePoint = hexChars.toString().toUIntStrict(&ok, 16); |
368 if (!ok) | 368 if (!ok) |
369 return WTF::Unicode::replacementCharacter; | 369 return WTF::Unicode::replacementCharacter; |
370 return codePoint; | 370 return codePoint; |
371 } | 371 } |
372 | 372 |
373 // Replaces NULLs with replacement characters, since we do not perform prepr
ocessing | 373 // Replaces NULLs with replacement characters, since we do not perform prepr
ocessing |
374 if (cc == kEndOfFileMarker) | 374 if (cc == kEndOfFileMarker) |
375 return WTF::Unicode::replacementCharacter; | 375 return WTF::Unicode::replacementCharacter; |
376 return cc; | 376 return cc; |
377 } | 377 } |
378 | 378 |
379 bool MediaQueryTokenizer::nextTwoCharsAreValidEscape() | 379 bool MediaQueryTokenizer::nextTwoCharsAreValidEscape(unsigned offset) |
380 { | 380 { |
381 if (m_input.leftChars() < 2) | 381 if (m_input.leftChars() < offset + 1) |
382 return false; | 382 return false; |
383 return twoCharsAreValidEscape(m_input.peek(1), m_input.peek(2)); | 383 return twoCharsAreValidEscape(m_input.peek(offset), m_input.peek(offset + 1)
); |
384 } | 384 } |
385 | 385 |
386 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number | 386 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number |
387 bool MediaQueryTokenizer::nextCharsAreNumber() | 387 bool MediaQueryTokenizer::nextCharsAreNumber() |
388 { | 388 { |
389 UChar first = m_input.currentInputChar(); | 389 UChar first = m_input.currentInputChar(); |
390 UChar second = m_input.peek(1); | 390 UChar second = m_input.peek(1); |
391 if (isASCIIDigit(first)) | 391 if (isASCIIDigit(first)) |
392 return true; | 392 return true; |
393 if (first == '+' || first == '-') | 393 if (first == '+' || first == '-') |
394 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peek(2)))); | 394 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peek(2)))); |
395 if (first =='.') | 395 if (first =='.') |
396 return (isASCIIDigit(second)); | 396 return (isASCIIDigit(second)); |
397 return false; | 397 return false; |
398 } | 398 } |
399 | 399 |
400 // http://www.w3.org/TR/css3-syntax/#would-start-an-identifier | 400 // http://www.w3.org/TR/css3-syntax/#would-start-an-identifier |
401 bool MediaQueryTokenizer::nextCharsAreIdentifier() | 401 bool MediaQueryTokenizer::nextCharsAreIdentifier() |
402 { | 402 { |
403 UChar firstChar = m_input.currentInputChar(); | 403 UChar firstChar = m_input.currentInputChar(); |
404 if (isNameStart(firstChar) || nextTwoCharsAreValidEscape()) | 404 if (isNameStart(firstChar) || nextTwoCharsAreValidEscape(0)) |
405 return true; | 405 return true; |
406 | 406 |
407 if (firstChar == '-') { | 407 if (firstChar == '-') { |
408 if (isNameStart(m_input.peek(1))) | 408 if (isNameStart(m_input.peek(1))) |
409 return true; | 409 return true; |
410 return nextTwoCharsAreValidEscape(); | 410 return nextTwoCharsAreValidEscape(1); |
411 } | 411 } |
412 | 412 |
413 return false; | 413 return false; |
414 } | 414 } |
415 | 415 |
416 } // namespace WebCore | 416 } // namespace WebCore |
OLD | NEW |