| 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 |