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 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 return true; | 346 return true; |
347 } | 347 } |
348 return false; | 348 return false; |
349 } | 349 } |
350 | 350 |
351 // http://www.w3.org/TR/css3-syntax/#consume-a-name | 351 // http://www.w3.org/TR/css3-syntax/#consume-a-name |
352 String MediaQueryTokenizer::consumeName() | 352 String MediaQueryTokenizer::consumeName() |
353 { | 353 { |
354 // FIXME: Is this as efficient as it can be? | 354 // FIXME: Is this as efficient as it can be? |
355 // The possibility of escape chars mandates a copy AFAICT. | 355 // The possibility of escape chars mandates a copy AFAICT. |
356 Vector<UChar> result; | 356 StringBuilder result; |
357 while (true) { | 357 while (true) { |
358 if (isNameChar(m_input.currentInputChar())) { | 358 UChar cc = consume(); |
359 result.append(consume()); | 359 if (isNameChar(cc)) { |
| 360 result.append(cc); |
360 continue; | 361 continue; |
361 } | 362 } |
362 if (nextTwoCharsAreValidEscape()) { | 363 if (twoCharsAreValidEscape(cc, m_input.currentInputChar())) { |
363 // "consume()" fixes a spec bug. | |
364 // The first code point should be consumed before consuming the esca
ped code point. | |
365 consume(); | |
366 result.append(consumeEscape()); | 364 result.append(consumeEscape()); |
367 continue; | 365 continue; |
368 } | 366 } |
369 return String(result); | 367 reconsume(cc); |
| 368 return result.toString(); |
370 } | 369 } |
371 } | 370 } |
372 | 371 |
373 // http://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point | 372 // http://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point |
374 UChar MediaQueryTokenizer::consumeEscape() | 373 UChar MediaQueryTokenizer::consumeEscape() |
375 { | 374 { |
376 UChar cc = consume(); | 375 UChar cc = consume(); |
377 ASSERT(cc != '\n'); | 376 ASSERT(cc != '\n'); |
378 if (isASCIIHexDigit(cc)) { | 377 if (isASCIIHexDigit(cc)) { |
379 unsigned consumedHexDigits = 1; | 378 unsigned consumedHexDigits = 1; |
380 String hexChars; | 379 StringBuilder hexChars; |
381 do { | 380 hexChars.append(cc); |
| 381 while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.currentInputChar
())) { |
| 382 cc = consume(); |
382 hexChars.append(cc); | 383 hexChars.append(cc); |
383 cc = consume(); | |
384 consumedHexDigits++; | 384 consumedHexDigits++; |
385 } while (consumedHexDigits < 6 && isASCIIHexDigit(cc)); | 385 }; |
386 bool ok = false; | 386 bool ok = false; |
387 UChar codePoint = hexChars.toUIntStrict(&ok, 16); | 387 UChar codePoint = hexChars.toString().toUIntStrict(&ok, 16); |
388 if (!ok) | 388 if (!ok) |
389 return WTF::Unicode::replacementCharacter; | 389 return WTF::Unicode::replacementCharacter; |
390 return codePoint; | 390 return codePoint; |
391 } | 391 } |
392 | 392 |
393 // Replaces NULLs with replacement characters, since we do not perform prepr
ocessing | 393 // Replaces NULLs with replacement characters, since we do not perform prepr
ocessing |
394 if (cc == kEndOfFileMarker) | 394 if (cc == kEndOfFileMarker) |
395 return WTF::Unicode::replacementCharacter; | 395 return WTF::Unicode::replacementCharacter; |
396 return cc; | 396 return cc; |
397 } | 397 } |
398 | 398 |
399 bool MediaQueryTokenizer::nextTwoCharsAreValidEscape() | 399 bool MediaQueryTokenizer::nextTwoCharsAreValidEscape(unsigned offset) |
400 { | 400 { |
401 if (m_input.leftChars() < 2) | 401 if (m_input.leftChars() < offset + 1) |
402 return false; | 402 return false; |
403 return twoCharsAreValidEscape(m_input.peek(1), m_input.peek(2)); | 403 return twoCharsAreValidEscape(m_input.peek(offset), m_input.peek(offset + 1)
); |
404 } | 404 } |
405 | 405 |
406 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number | 406 // http://www.w3.org/TR/css3-syntax/#starts-with-a-number |
407 bool MediaQueryTokenizer::nextCharsAreNumber() | 407 bool MediaQueryTokenizer::nextCharsAreNumber() |
408 { | 408 { |
409 UChar first = m_input.currentInputChar(); | 409 UChar first = m_input.currentInputChar(); |
410 UChar second = m_input.peek(1); | 410 UChar second = m_input.peek(1); |
411 if (isASCIIDigit(first)) | 411 if (isASCIIDigit(first)) |
412 return true; | 412 return true; |
413 if (first == '+' || first == '-') | 413 if (first == '+' || first == '-') |
414 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peek(2)))); | 414 return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input
.peek(2)))); |
415 if (first =='.') | 415 if (first =='.') |
416 return (isASCIIDigit(second)); | 416 return (isASCIIDigit(second)); |
417 return false; | 417 return false; |
418 } | 418 } |
419 | 419 |
420 // http://www.w3.org/TR/css3-syntax/#would-start-an-identifier | 420 // http://www.w3.org/TR/css3-syntax/#would-start-an-identifier |
421 bool MediaQueryTokenizer::nextCharsAreIdentifier() | 421 bool MediaQueryTokenizer::nextCharsAreIdentifier() |
422 { | 422 { |
423 UChar firstChar = m_input.currentInputChar(); | 423 UChar firstChar = m_input.currentInputChar(); |
424 if (isNameStart(firstChar) || nextTwoCharsAreValidEscape()) | 424 if (isNameStart(firstChar) || nextTwoCharsAreValidEscape(0)) |
425 return true; | 425 return true; |
426 | 426 |
427 if (firstChar == '-') { | 427 if (firstChar == '-') { |
428 if (isNameStart(m_input.peek(1))) | 428 if (isNameStart(m_input.peek(1))) |
429 return true; | 429 return true; |
430 return nextTwoCharsAreValidEscape(); | 430 return nextTwoCharsAreValidEscape(1); |
431 } | 431 } |
432 | 432 |
433 return false; | 433 return false; |
434 } | 434 } |
435 | 435 |
436 } // namespace WebCore | 436 } // namespace WebCore |
OLD | NEW |