Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1279)

Side by Side Diff: third_party/WebKit/Source/core/css/CSSCalculationValue.cpp

Issue 2755493004: Replace ASSERT, ASSERT_NOT_REACHED, and RELEASE_ASSERT in core/css/ (Closed)
Patch Set: Worked on Review Comments done Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 return true; 115 return true;
116 case CSSPrimitiveValue::UnitType::Unknown: 116 case CSSPrimitiveValue::UnitType::Unknown:
117 case CSSPrimitiveValue::UnitType::Calc: 117 case CSSPrimitiveValue::UnitType::Calc:
118 case CSSPrimitiveValue::UnitType::CalcPercentageWithNumber: 118 case CSSPrimitiveValue::UnitType::CalcPercentageWithNumber:
119 case CSSPrimitiveValue::UnitType::CalcPercentageWithLength: 119 case CSSPrimitiveValue::UnitType::CalcPercentageWithLength:
120 case CSSPrimitiveValue::UnitType::CalcLengthWithNumber: 120 case CSSPrimitiveValue::UnitType::CalcLengthWithNumber:
121 case CSSPrimitiveValue::UnitType::CalcPercentageWithLengthAndNumber: 121 case CSSPrimitiveValue::UnitType::CalcPercentageWithLengthAndNumber:
122 case CSSPrimitiveValue::UnitType::QuirkyEms: 122 case CSSPrimitiveValue::UnitType::QuirkyEms:
123 return false; 123 return false;
124 }; 124 };
125 ASSERT_NOT_REACHED(); 125 NOTREACHED();
126 return false; 126 return false;
127 } 127 }
128 128
129 static String buildCSSText(const String& expression) { 129 static String buildCSSText(const String& expression) {
130 StringBuilder result; 130 StringBuilder result;
131 result.append("calc"); 131 result.append("calc");
132 bool expressionHasSingleTerm = expression[0] != '('; 132 bool expressionHasSingleTerm = expression[0] != '(';
133 if (expressionHasSingleTerm) 133 if (expressionHasSingleTerm)
134 result.append('('); 134 result.append('(');
135 result.append(expression); 135 result.append(expression);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 const CSSToLengthConversionData& conversionData, 183 const CSSToLengthConversionData& conversionData,
184 PixelsAndPercent& value, 184 PixelsAndPercent& value,
185 float multiplier) const override { 185 float multiplier) const override {
186 switch (m_category) { 186 switch (m_category) {
187 case CalcLength: 187 case CalcLength:
188 value.pixels = clampTo<float>( 188 value.pixels = clampTo<float>(
189 value.pixels + 189 value.pixels +
190 m_value->computeLength<double>(conversionData) * multiplier); 190 m_value->computeLength<double>(conversionData) * multiplier);
191 break; 191 break;
192 case CalcPercent: 192 case CalcPercent:
193 ASSERT(m_value->isPercentage()); 193 DCHECK(m_value->isPercentage());
194 value.percent = clampTo<float>(value.percent + 194 value.percent = clampTo<float>(value.percent +
195 m_value->getDoubleValue() * multiplier); 195 m_value->getDoubleValue() * multiplier);
196 break; 196 break;
197 case CalcNumber: 197 case CalcNumber:
198 // TODO(alancutter): Stop treating numbers like pixels unconditionally 198 // TODO(alancutter): Stop treating numbers like pixels unconditionally
199 // in calcs to be able to accomodate border-image-width 199 // in calcs to be able to accomodate border-image-width
200 // https://drafts.csswg.org/css-backgrounds-3/#the-border-image-width 200 // https://drafts.csswg.org/css-backgrounds-3/#the-border-image-width
201 value.pixels = clampTo<float>(value.pixels + 201 value.pixels = clampTo<float>(value.pixels +
202 m_value->getDoubleValue() * 202 m_value->getDoubleValue() *
203 conversionData.zoom() * multiplier); 203 conversionData.zoom() * multiplier);
204 break; 204 break;
205 default: 205 default:
206 ASSERT_NOT_REACHED(); 206 NOTREACHED();
207 } 207 }
208 } 208 }
209 209
210 double doubleValue() const override { 210 double doubleValue() const override {
211 if (hasDoubleValue(typeWithCalcResolved())) 211 if (hasDoubleValue(typeWithCalcResolved()))
212 return m_value->getDoubleValue(); 212 return m_value->getDoubleValue();
213 ASSERT_NOT_REACHED(); 213 NOTREACHED();
214 return 0; 214 return 0;
215 } 215 }
216 216
217 double computeLengthPx( 217 double computeLengthPx(
218 const CSSToLengthConversionData& conversionData) const override { 218 const CSSToLengthConversionData& conversionData) const override {
219 switch (m_category) { 219 switch (m_category) {
220 case CalcLength: 220 case CalcLength:
221 return m_value->computeLength<double>(conversionData); 221 return m_value->computeLength<double>(conversionData);
222 case CalcNumber: 222 case CalcNumber:
223 case CalcPercent: 223 case CalcPercent:
224 return m_value->getDoubleValue(); 224 return m_value->getDoubleValue();
225 case CalcAngle: 225 case CalcAngle:
226 case CalcFrequency: 226 case CalcFrequency:
227 case CalcPercentLength: 227 case CalcPercentLength:
228 case CalcPercentNumber: 228 case CalcPercentNumber:
229 case CalcTime: 229 case CalcTime:
230 case CalcLengthNumber: 230 case CalcLengthNumber:
231 case CalcPercentLengthNumber: 231 case CalcPercentLengthNumber:
232 case CalcOther: 232 case CalcOther:
233 ASSERT_NOT_REACHED(); 233 NOTREACHED();
234 break; 234 break;
235 } 235 }
236 ASSERT_NOT_REACHED(); 236 NOTREACHED();
237 return 0; 237 return 0;
238 } 238 }
239 239
240 void accumulateLengthArray(CSSLengthArray& lengthArray, 240 void accumulateLengthArray(CSSLengthArray& lengthArray,
241 double multiplier) const override { 241 double multiplier) const override {
242 ASSERT(category() != CalcNumber); 242 DCHECK_NE(category(), CalcNumber);
243 m_value->accumulateLengthArray(lengthArray, multiplier); 243 m_value->accumulateLengthArray(lengthArray, multiplier);
244 } 244 }
245 245
246 bool operator==(const CSSCalcExpressionNode& other) const override { 246 bool operator==(const CSSCalcExpressionNode& other) const override {
247 if (getType() != other.getType()) 247 if (getType() != other.getType())
248 return false; 248 return false;
249 249
250 return dataEquivalent( 250 return dataEquivalent(
251 m_value, static_cast<const CSSCalcPrimitiveValue&>(other).m_value); 251 m_value, static_cast<const CSSCalcPrimitiveValue&>(other).m_value);
252 } 252 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 case CalcMultiply: 338 case CalcMultiply:
339 if (leftCategory != CalcNumber && rightCategory != CalcNumber) 339 if (leftCategory != CalcNumber && rightCategory != CalcNumber)
340 return CalcOther; 340 return CalcOther;
341 return leftCategory == CalcNumber ? rightCategory : leftCategory; 341 return leftCategory == CalcNumber ? rightCategory : leftCategory;
342 case CalcDivide: 342 case CalcDivide:
343 if (rightCategory != CalcNumber || rightSide.isZero()) 343 if (rightCategory != CalcNumber || rightSide.isZero())
344 return CalcOther; 344 return CalcOther;
345 return leftCategory; 345 return leftCategory;
346 } 346 }
347 347
348 ASSERT_NOT_REACHED(); 348 NOTREACHED();
349 return CalcOther; 349 return CalcOther;
350 } 350 }
351 351
352 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, 352 static bool isIntegerResult(const CSSCalcExpressionNode* leftSide,
353 const CSSCalcExpressionNode* rightSide, 353 const CSSCalcExpressionNode* rightSide,
354 CalcOperator op) { 354 CalcOperator op) {
355 // Not testing for actual integer values. 355 // Not testing for actual integer values.
356 // Performs W3C spec's type checking for calc integers. 356 // Performs W3C spec's type checking for calc integers.
357 // http://www.w3.org/TR/css3-values/#calc-type-checking 357 // http://www.w3.org/TR/css3-values/#calc-type-checking
358 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger(); 358 return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger();
359 } 359 }
360 360
361 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode { 361 class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
362 public: 362 public:
363 static CSSCalcExpressionNode* create(CSSCalcExpressionNode* leftSide, 363 static CSSCalcExpressionNode* create(CSSCalcExpressionNode* leftSide,
364 CSSCalcExpressionNode* rightSide, 364 CSSCalcExpressionNode* rightSide,
365 CalcOperator op) { 365 CalcOperator op) {
366 ASSERT(leftSide->category() != CalcOther && 366 DCHECK_NE(leftSide->category(), CalcOther);
367 rightSide->category() != CalcOther); 367 DCHECK_NE(rightSide->category(), CalcOther);
368 368
369 CalculationCategory newCategory = 369 CalculationCategory newCategory =
370 determineCategory(*leftSide, *rightSide, op); 370 determineCategory(*leftSide, *rightSide, op);
371 if (newCategory == CalcOther) 371 if (newCategory == CalcOther)
372 return nullptr; 372 return nullptr;
373 373
374 return new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory); 374 return new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory);
375 } 375 }
376 376
377 static CSSCalcExpressionNode* createSimplified( 377 static CSSCalcExpressionNode* createSimplified(
378 CSSCalcExpressionNode* leftSide, 378 CSSCalcExpressionNode* leftSide,
379 CSSCalcExpressionNode* rightSide, 379 CSSCalcExpressionNode* rightSide,
380 CalcOperator op) { 380 CalcOperator op) {
381 CalculationCategory leftCategory = leftSide->category(); 381 CalculationCategory leftCategory = leftSide->category();
382 CalculationCategory rightCategory = rightSide->category(); 382 CalculationCategory rightCategory = rightSide->category();
383 ASSERT(leftCategory != CalcOther && rightCategory != CalcOther); 383 DCHECK_NE(leftCategory, CalcOther);
384 DCHECK_NE(rightCategory, CalcOther);
384 385
385 bool isInteger = isIntegerResult(leftSide, rightSide, op); 386 bool isInteger = isIntegerResult(leftSide, rightSide, op);
386 387
387 // Simplify numbers. 388 // Simplify numbers.
388 if (leftCategory == CalcNumber && rightCategory == CalcNumber) { 389 if (leftCategory == CalcNumber && rightCategory == CalcNumber) {
389 return CSSCalcPrimitiveValue::create( 390 return CSSCalcPrimitiveValue::create(
390 evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), 391 evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(),
391 op), 392 op),
392 CSSPrimitiveValue::UnitType::Number, isInteger); 393 CSSPrimitiveValue::UnitType::Number, isInteger);
393 } 394 }
(...skipping 29 matching lines...) Expand all
423 rightType)); 424 rightType));
424 return CSSCalcPrimitiveValue::create( 425 return CSSCalcPrimitiveValue::create(
425 evaluateOperator(leftValue, rightValue, op), canonicalType, 426 evaluateOperator(leftValue, rightValue, op), canonicalType,
426 isInteger); 427 isInteger);
427 } 428 }
428 } 429 }
429 } 430 }
430 } 431 }
431 } else { 432 } else {
432 // Simplify multiplying or dividing by a number for simplifiable types. 433 // Simplify multiplying or dividing by a number for simplifiable types.
433 ASSERT(op == CalcMultiply || op == CalcDivide); 434 DCHECK(op == CalcMultiply || op == CalcDivide);
434 CSSCalcExpressionNode* numberSide = getNumberSide(leftSide, rightSide); 435 CSSCalcExpressionNode* numberSide = getNumberSide(leftSide, rightSide);
435 if (!numberSide) 436 if (!numberSide)
436 return create(leftSide, rightSide, op); 437 return create(leftSide, rightSide, op);
437 if (numberSide == leftSide && op == CalcDivide) 438 if (numberSide == leftSide && op == CalcDivide)
438 return nullptr; 439 return nullptr;
439 CSSCalcExpressionNode* otherSide = 440 CSSCalcExpressionNode* otherSide =
440 leftSide == numberSide ? rightSide : leftSide; 441 leftSide == numberSide ? rightSide : leftSide;
441 442
442 double number = numberSide->doubleValue(); 443 double number = numberSide->doubleValue();
443 if (std::isnan(number) || std::isinf(number)) 444 if (std::isnan(number) || std::isinf(number))
(...skipping 24 matching lines...) Expand all
468 m_rightSide->accumulatePixelsAndPercent(conversionData, value, 469 m_rightSide->accumulatePixelsAndPercent(conversionData, value,
469 multiplier); 470 multiplier);
470 break; 471 break;
471 case CalcSubtract: 472 case CalcSubtract:
472 m_leftSide->accumulatePixelsAndPercent(conversionData, value, 473 m_leftSide->accumulatePixelsAndPercent(conversionData, value,
473 multiplier); 474 multiplier);
474 m_rightSide->accumulatePixelsAndPercent(conversionData, value, 475 m_rightSide->accumulatePixelsAndPercent(conversionData, value,
475 -multiplier); 476 -multiplier);
476 break; 477 break;
477 case CalcMultiply: 478 case CalcMultiply:
478 ASSERT((m_leftSide->category() == CalcNumber) != 479 DCHECK_NE((m_leftSide->category() == CalcNumber), (m_rightSide->category () == CalcNumber));
479 (m_rightSide->category() == CalcNumber));
480 if (m_leftSide->category() == CalcNumber) 480 if (m_leftSide->category() == CalcNumber)
481 m_rightSide->accumulatePixelsAndPercent( 481 m_rightSide->accumulatePixelsAndPercent(
482 conversionData, value, multiplier * m_leftSide->doubleValue()); 482 conversionData, value, multiplier * m_leftSide->doubleValue());
483 else 483 else
484 m_leftSide->accumulatePixelsAndPercent( 484 m_leftSide->accumulatePixelsAndPercent(
485 conversionData, value, multiplier * m_rightSide->doubleValue()); 485 conversionData, value, multiplier * m_rightSide->doubleValue());
486 break; 486 break;
487 case CalcDivide: 487 case CalcDivide:
488 ASSERT(m_rightSide->category() == CalcNumber); 488 DCHECK_EQ(m_rightSide->category(), CalcNumber);
489 m_leftSide->accumulatePixelsAndPercent( 489 m_leftSide->accumulatePixelsAndPercent(
490 conversionData, value, multiplier / m_rightSide->doubleValue()); 490 conversionData, value, multiplier / m_rightSide->doubleValue());
491 break; 491 break;
492 default: 492 default:
493 ASSERT_NOT_REACHED(); 493 NOTREACHED();
494 } 494 }
495 } 495 }
496 496
497 double doubleValue() const override { 497 double doubleValue() const override {
498 return evaluate(m_leftSide->doubleValue(), m_rightSide->doubleValue()); 498 return evaluate(m_leftSide->doubleValue(), m_rightSide->doubleValue());
499 } 499 }
500 500
501 double computeLengthPx( 501 double computeLengthPx(
502 const CSSToLengthConversionData& conversionData) const override { 502 const CSSToLengthConversionData& conversionData) const override {
503 const double leftValue = m_leftSide->computeLengthPx(conversionData); 503 const double leftValue = m_leftSide->computeLengthPx(conversionData);
504 const double rightValue = m_rightSide->computeLengthPx(conversionData); 504 const double rightValue = m_rightSide->computeLengthPx(conversionData);
505 return evaluate(leftValue, rightValue); 505 return evaluate(leftValue, rightValue);
506 } 506 }
507 507
508 void accumulateLengthArray(CSSLengthArray& lengthArray, 508 void accumulateLengthArray(CSSLengthArray& lengthArray,
509 double multiplier) const override { 509 double multiplier) const override {
510 switch (m_operator) { 510 switch (m_operator) {
511 case CalcAdd: 511 case CalcAdd:
512 m_leftSide->accumulateLengthArray(lengthArray, multiplier); 512 m_leftSide->accumulateLengthArray(lengthArray, multiplier);
513 m_rightSide->accumulateLengthArray(lengthArray, multiplier); 513 m_rightSide->accumulateLengthArray(lengthArray, multiplier);
514 break; 514 break;
515 case CalcSubtract: 515 case CalcSubtract:
516 m_leftSide->accumulateLengthArray(lengthArray, multiplier); 516 m_leftSide->accumulateLengthArray(lengthArray, multiplier);
517 m_rightSide->accumulateLengthArray(lengthArray, -multiplier); 517 m_rightSide->accumulateLengthArray(lengthArray, -multiplier);
518 break; 518 break;
519 case CalcMultiply: 519 case CalcMultiply:
520 ASSERT((m_leftSide->category() == CalcNumber) != 520 DCHECK_NE((m_leftSide->category() == CalcNumber), (m_rightSide->category () == CalcNumber));
521 (m_rightSide->category() == CalcNumber));
522 if (m_leftSide->category() == CalcNumber) 521 if (m_leftSide->category() == CalcNumber)
523 m_rightSide->accumulateLengthArray( 522 m_rightSide->accumulateLengthArray(
524 lengthArray, multiplier * m_leftSide->doubleValue()); 523 lengthArray, multiplier * m_leftSide->doubleValue());
525 else 524 else
526 m_leftSide->accumulateLengthArray( 525 m_leftSide->accumulateLengthArray(
527 lengthArray, multiplier * m_rightSide->doubleValue()); 526 lengthArray, multiplier * m_rightSide->doubleValue());
528 break; 527 break;
529 case CalcDivide: 528 case CalcDivide:
530 ASSERT(m_rightSide->category() == CalcNumber); 529 DCHECK_EQ(m_rightSide->category(), CalcNumber);
531 m_leftSide->accumulateLengthArray( 530 m_leftSide->accumulateLengthArray(
532 lengthArray, multiplier / m_rightSide->doubleValue()); 531 lengthArray, multiplier / m_rightSide->doubleValue());
533 break; 532 break;
534 default: 533 default:
535 ASSERT_NOT_REACHED(); 534 NOTREACHED();
536 } 535 }
537 } 536 }
538 537
539 static String buildCSSText(const String& leftExpression, 538 static String buildCSSText(const String& leftExpression,
540 const String& rightExpression, 539 const String& rightExpression,
541 CalcOperator op) { 540 CalcOperator op) {
542 StringBuilder result; 541 StringBuilder result;
543 result.append('('); 542 result.append('(');
544 result.append(leftExpression); 543 result.append(leftExpression);
545 result.append(' '); 544 result.append(' ');
(...skipping 26 matching lines...) Expand all
572 571
573 const CSSCalcExpressionNode* rightExpressionNode() const { 572 const CSSCalcExpressionNode* rightExpressionNode() const {
574 return m_rightSide; 573 return m_rightSide;
575 } 574 }
576 575
577 CalcOperator operatorType() const { return m_operator; } 576 CalcOperator operatorType() const { return m_operator; }
578 577
579 CSSPrimitiveValue::UnitType typeWithCalcResolved() const override { 578 CSSPrimitiveValue::UnitType typeWithCalcResolved() const override {
580 switch (m_category) { 579 switch (m_category) {
581 case CalcNumber: 580 case CalcNumber:
582 ASSERT(m_leftSide->category() == CalcNumber && 581 DCHECK_EQ(m_leftSide->category(), CalcNumber);
583 m_rightSide->category() == CalcNumber); 582 DCHECK_EQ(m_rightSide->category(), CalcNumber);
584 return CSSPrimitiveValue::UnitType::Number; 583 return CSSPrimitiveValue::UnitType::Number;
585 case CalcLength: 584 case CalcLength:
586 case CalcPercent: { 585 case CalcPercent: {
587 if (m_leftSide->category() == CalcNumber) 586 if (m_leftSide->category() == CalcNumber)
588 return m_rightSide->typeWithCalcResolved(); 587 return m_rightSide->typeWithCalcResolved();
589 if (m_rightSide->category() == CalcNumber) 588 if (m_rightSide->category() == CalcNumber)
590 return m_leftSide->typeWithCalcResolved(); 589 return m_leftSide->typeWithCalcResolved();
591 CSSPrimitiveValue::UnitType leftType = 590 CSSPrimitiveValue::UnitType leftType =
592 m_leftSide->typeWithCalcResolved(); 591 m_leftSide->typeWithCalcResolved();
593 if (leftType == m_rightSide->typeWithCalcResolved()) 592 if (leftType == m_rightSide->typeWithCalcResolved())
594 return leftType; 593 return leftType;
595 return CSSPrimitiveValue::UnitType::Unknown; 594 return CSSPrimitiveValue::UnitType::Unknown;
596 } 595 }
597 case CalcAngle: 596 case CalcAngle:
598 return CSSPrimitiveValue::UnitType::Degrees; 597 return CSSPrimitiveValue::UnitType::Degrees;
599 case CalcTime: 598 case CalcTime:
600 return CSSPrimitiveValue::UnitType::Milliseconds; 599 return CSSPrimitiveValue::UnitType::Milliseconds;
601 case CalcFrequency: 600 case CalcFrequency:
602 return CSSPrimitiveValue::UnitType::Hertz; 601 return CSSPrimitiveValue::UnitType::Hertz;
603 case CalcPercentLength: 602 case CalcPercentLength:
604 case CalcPercentNumber: 603 case CalcPercentNumber:
605 case CalcLengthNumber: 604 case CalcLengthNumber:
606 case CalcPercentLengthNumber: 605 case CalcPercentLengthNumber:
607 case CalcOther: 606 case CalcOther:
608 return CSSPrimitiveValue::UnitType::Unknown; 607 return CSSPrimitiveValue::UnitType::Unknown;
609 } 608 }
610 ASSERT_NOT_REACHED(); 609 NOTREACHED();
611 return CSSPrimitiveValue::UnitType::Unknown; 610 return CSSPrimitiveValue::UnitType::Unknown;
612 } 611 }
613 612
614 DEFINE_INLINE_VIRTUAL_TRACE() { 613 DEFINE_INLINE_VIRTUAL_TRACE() {
615 visitor->trace(m_leftSide); 614 visitor->trace(m_leftSide);
616 visitor->trace(m_rightSide); 615 visitor->trace(m_rightSide);
617 CSSCalcExpressionNode::trace(visitor); 616 CSSCalcExpressionNode::trace(visitor);
618 } 617 }
619 618
620 private: 619 private:
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 835
837 return expression ? new CSSCalcValue(expression, range) : nullptr; 836 return expression ? new CSSCalcValue(expression, range) : nullptr;
838 } 837 }
839 838
840 CSSCalcValue* CSSCalcValue::create(CSSCalcExpressionNode* expression, 839 CSSCalcValue* CSSCalcValue::create(CSSCalcExpressionNode* expression,
841 ValueRange range) { 840 ValueRange range) {
842 return new CSSCalcValue(expression, range); 841 return new CSSCalcValue(expression, range);
843 } 842 }
844 843
845 } // namespace blink 844 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698