OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> | 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
3 * 1999 Lars Knoll <knoll@kde.org> | 3 * 1999 Lars Knoll <knoll@kde.org> |
4 * 1999 Antti Koivisto <koivisto@kde.org> | 4 * 1999 Antti Koivisto <koivisto@kde.org> |
5 * 2000 Dirk Mueller <mueller@kde.org> | 5 * 2000 Dirk Mueller <mueller@kde.org> |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * Copyright (C) 2009 Google Inc. All rights reserved. | 9 * Copyright (C) 2009 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 m_isPainting = false; | 218 m_isPainting = false; |
219 m_visuallyNonEmptyCharacterCount = 0; | 219 m_visuallyNonEmptyCharacterCount = 0; |
220 m_visuallyNonEmptyPixelCount = 0; | 220 m_visuallyNonEmptyPixelCount = 0; |
221 m_isVisuallyNonEmpty = false; | 221 m_isVisuallyNonEmpty = false; |
222 clearScrollAnchor(); | 222 clearScrollAnchor(); |
223 m_viewportConstrainedObjects.clear(); | 223 m_viewportConstrainedObjects.clear(); |
224 m_layoutSubtreeRootList.clear(); | 224 m_layoutSubtreeRootList.clear(); |
225 } | 225 } |
226 | 226 |
227 template <typename Function> | 227 template <typename Function> |
228 void FrameView::forAllFrameViews(Function function) | 228 void FrameView::forAllNonThrottledFrameViews(Function function) |
229 { | 229 { |
230 for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext
(m_frame.get())) { | 230 if (shouldThrottleRendering()) |
231 if (!frame->isLocalFrame()) | 231 return; |
| 232 |
| 233 function(*this); |
| 234 |
| 235 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree
().nextSibling()) { |
| 236 if (!child->isLocalFrame()) |
232 continue; | 237 continue; |
233 if (FrameView* view = toLocalFrame(frame)->view()) | 238 if (FrameView* childView = toLocalFrame(child)->view()) |
234 function(*view); | 239 childView->forAllNonThrottledFrameViews(function); |
235 } | 240 } |
236 } | 241 } |
237 | 242 |
238 void FrameView::removeFromAXObjectCache() | 243 void FrameView::removeFromAXObjectCache() |
239 { | 244 { |
240 if (AXObjectCache* cache = axObjectCache()) { | 245 if (AXObjectCache* cache = axObjectCache()) { |
241 cache->remove(this); | 246 cache->remove(this); |
242 cache->childrenChanged(m_frame->pagePopupOwner()); | 247 cache->childrenChanged(m_frame->pagePopupOwner()); |
243 } | 248 } |
244 } | 249 } |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 } | 1290 } |
1286 | 1291 |
1287 bool FrameView::shouldSetCursor() const | 1292 bool FrameView::shouldSetCursor() const |
1288 { | 1293 { |
1289 Page* page = frame().page(); | 1294 Page* page = frame().page(); |
1290 return page && page->visibilityState() != PageVisibilityStateHidden && page-
>focusController().isActive() && page->settings().deviceSupportsMouse(); | 1295 return page && page->visibilityState() != PageVisibilityStateHidden && page-
>focusController().isActive() && page->settings().deviceSupportsMouse(); |
1291 } | 1296 } |
1292 | 1297 |
1293 void FrameView::scrollContentsIfNeededRecursive() | 1298 void FrameView::scrollContentsIfNeededRecursive() |
1294 { | 1299 { |
1295 forAllFrameViews([](FrameView& frameView) { | 1300 forAllNonThrottledFrameViews([](FrameView& frameView) { |
1296 if (frameView.shouldThrottleRendering()) | |
1297 return; | |
1298 frameView.scrollContentsIfNeeded(); | 1301 frameView.scrollContentsIfNeeded(); |
1299 }); | 1302 }); |
1300 } | 1303 } |
1301 | 1304 |
1302 void FrameView::invalidateBackgroundAttachmentFixedObjects() | 1305 void FrameView::invalidateBackgroundAttachmentFixedObjects() |
1303 { | 1306 { |
1304 for (const auto& layoutObject : m_backgroundAttachmentFixedObjects) | 1307 for (const auto& layoutObject : m_backgroundAttachmentFixedObjects) |
1305 layoutObject->setShouldDoFullPaintInvalidation(); | 1308 layoutObject->setShouldDoFullPaintInvalidation(); |
1306 } | 1309 } |
1307 | 1310 |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 CompositedLayerMapping* compositedLayerMapping = layoutView()->layer()->
compositedLayerMapping(); | 1820 CompositedLayerMapping* compositedLayerMapping = layoutView()->layer()->
compositedLayerMapping(); |
1818 compositedLayerMapping->updateContentsOpaque(); | 1821 compositedLayerMapping->updateContentsOpaque(); |
1819 if (compositedLayerMapping->mainGraphicsLayer()) | 1822 if (compositedLayerMapping->mainGraphicsLayer()) |
1820 compositedLayerMapping->mainGraphicsLayer()->setNeedsDisplay(); | 1823 compositedLayerMapping->mainGraphicsLayer()->setNeedsDisplay(); |
1821 } | 1824 } |
1822 recalculateScrollbarOverlayStyle(); | 1825 recalculateScrollbarOverlayStyle(); |
1823 } | 1826 } |
1824 | 1827 |
1825 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool t
ransparent) | 1828 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool t
ransparent) |
1826 { | 1829 { |
1827 forAllFrameViews([backgroundColor, transparent](FrameView& frameView) { | 1830 forAllNonThrottledFrameViews([backgroundColor, transparent](FrameView& frame
View) { |
1828 frameView.setTransparent(transparent); | 1831 frameView.setTransparent(transparent); |
1829 frameView.setBaseBackgroundColor(backgroundColor); | 1832 frameView.setBaseBackgroundColor(backgroundColor); |
1830 }); | 1833 }); |
1831 } | 1834 } |
1832 | 1835 |
1833 void FrameView::scrollToAnchor() | 1836 void FrameView::scrollToAnchor() |
1834 { | 1837 { |
1835 RefPtrWillBeRawPtr<Node> anchorNode = m_scrollAnchor; | 1838 RefPtrWillBeRawPtr<Node> anchorNode = m_scrollAnchor; |
1836 if (!anchorNode) | 1839 if (!anchorNode) |
1837 return; | 1840 return; |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2450 invalidateTreeIfNeededRecursive(); | 2453 invalidateTreeIfNeededRecursive(); |
2451 | 2454 |
2452 if (view->compositor()->inCompositingMode()) | 2455 if (view->compositor()->inCompositingMode()) |
2453 scrollingCoordinator()->updateAfterCompositingChangeIfNeeded(); | 2456 scrollingCoordinator()->updateAfterCompositingChangeIfNeeded(); |
2454 | 2457 |
2455 updateCompositedSelectionIfNeeded(); | 2458 updateCompositedSelectionIfNeeded(); |
2456 | 2459 |
2457 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 2460 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
2458 updatePaintProperties(); | 2461 updatePaintProperties(); |
2459 | 2462 |
2460 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled
()) { | 2463 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled
() && !m_frame->document()->printing()) { |
2461 synchronizedPaint(); | 2464 synchronizedPaint(); |
2462 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 2465 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
2463 compositeForSlimmingPaintV2(); | 2466 compositeForSlimmingPaintV2(); |
2464 } | 2467 } |
2465 | 2468 |
2466 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) | 2469 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) |
2467 updateFrameTimingRequestsIfNeeded(); | 2470 updateFrameTimingRequestsIfNeeded(); |
2468 | 2471 |
2469 ASSERT(!view->hasPendingSelection()); | 2472 ASSERT(!view->hasPendingSelection()); |
2470 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl
ean | 2473 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl
ean |
2471 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl
e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) | 2474 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl
e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) |
2472 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna
bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); | 2475 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna
bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); |
2473 } | 2476 } |
2474 } | 2477 } |
2475 | 2478 |
2476 updateViewportIntersectionsForSubtree(); | 2479 updateViewportIntersectionsForSubtree(); |
2477 } | 2480 } |
2478 | 2481 |
2479 void FrameView::updatePaintProperties() | 2482 void FrameView::updatePaintProperties() |
2480 { | 2483 { |
2481 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 2484 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
2482 | 2485 |
2483 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(
DocumentLifecycle::InUpdatePaintProperties); }); | 2486 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle(
).advanceTo(DocumentLifecycle::InUpdatePaintProperties); }); |
2484 PaintPropertyTreeBuilder().buildPropertyTrees(*this); | 2487 PaintPropertyTreeBuilder().buildPropertyTrees(*this); |
2485 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(
DocumentLifecycle::UpdatePaintPropertiesClean); }); | 2488 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle(
).advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); }); |
2486 } | 2489 } |
2487 | 2490 |
2488 void FrameView::synchronizedPaint() | 2491 void FrameView::synchronizedPaint() |
2489 { | 2492 { |
2490 ASSERT(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()); | 2493 ASSERT(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()); |
2491 ASSERT(frame() == page()->mainFrame() || (!frame().tree().parent()->isLocalF
rame())); | 2494 ASSERT(frame() == page()->mainFrame() || (!frame().tree().parent()->isLocalF
rame())); |
2492 | 2495 |
2493 LayoutView* view = layoutView(); | 2496 LayoutView* view = layoutView(); |
2494 ASSERT(view); | 2497 ASSERT(view); |
2495 // TODO(chrishtr): figure out if there can be any GraphicsLayer above this o
ne that draws content. | 2498 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle(
).advanceTo(DocumentLifecycle::InPaint); }); |
2496 GraphicsLayer* rootGraphicsLayer = view->layer()->graphicsLayerBacking(); | |
2497 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(
DocumentLifecycle::InPaint); }); | |
2498 | 2499 |
2499 // A null graphics layer can occur for painting of SVG images that are not p
arented into the main frame tree. | 2500 // A null graphics layer can occur for painting of SVG images that are not p
arented into the main frame tree. |
2500 if (rootGraphicsLayer) { | 2501 if (GraphicsLayer* rootGraphicsLayer = view->layer()->graphicsLayerBacking()
) { |
2501 synchronizedPaintRecursively(rootGraphicsLayer); | 2502 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 2503 // TODO(wangxianzhu,chrishtr): What about the extra graphics layers
for overflow control, virtual viewport, etc? |
| 2504 GraphicsContext context(*rootGraphicsLayer->paintController()); |
| 2505 rootGraphicsLayer->paint(context, nullptr); |
| 2506 } else { |
| 2507 // Find the real root GraphicsLayer because we also need to paint la
yers not under the root graphics layer of |
| 2508 // the LayoutView, e.g. scrollbar layers created by PaintLayerCompos
itor and VisualViewport. |
| 2509 // We could ask PaintLayerCompositor and VisualViewport for the real
root GraphicsLayer, but the following loop |
| 2510 // has the least dependency to those things which might change for s
limming paint v2. |
| 2511 while (GraphicsLayer* parent = rootGraphicsLayer->parent()) |
| 2512 rootGraphicsLayer = parent; |
| 2513 synchronizedPaintRecursively(rootGraphicsLayer); |
| 2514 } |
2502 } | 2515 } |
2503 | 2516 |
2504 forAllFrameViews([](FrameView& frameView) { | 2517 forAllNonThrottledFrameViews([](FrameView& frameView) { |
2505 frameView.lifecycle().advanceTo(DocumentLifecycle::PaintClean); | 2518 frameView.lifecycle().advanceTo(DocumentLifecycle::PaintClean); |
2506 frameView.layoutView()->layer()->clearNeedsRepaintRecursively(); | 2519 frameView.layoutView()->layer()->clearNeedsRepaintRecursively(); |
2507 }); | 2520 }); |
2508 } | 2521 } |
2509 | 2522 |
2510 void FrameView::synchronizedPaintRecursively(GraphicsLayer* graphicsLayer) | 2523 void FrameView::synchronizedPaintRecursively(GraphicsLayer* graphicsLayer) |
2511 { | 2524 { |
| 2525 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
2512 ASSERT(graphicsLayer->paintController()); | 2526 ASSERT(graphicsLayer->paintController()); |
2513 GraphicsContext context(*graphicsLayer->paintController()); | 2527 GraphicsContext context(*graphicsLayer->paintController()); |
2514 | 2528 |
| 2529 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) |
| 2530 synchronizedPaintRecursively(maskLayer); |
| 2531 if (GraphicsLayer* contentsClippingMaskLayer = graphicsLayer->contentsClippi
ngMaskLayer()) |
| 2532 synchronizedPaintRecursively(contentsClippingMaskLayer); |
| 2533 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) |
| 2534 synchronizedPaintRecursively(replicaLayer); |
| 2535 |
| 2536 // TODO(chrishtr): fix unit tests to not inject one-off interest rects. |
2515 graphicsLayer->paint(context, nullptr); | 2537 graphicsLayer->paint(context, nullptr); |
2516 | 2538 graphicsLayer->paintController()->commitNewDisplayItems(); |
2517 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
2518 graphicsLayer->paintController()->commitNewDisplayItems(); | |
2519 | 2539 |
2520 for (auto& child : graphicsLayer->children()) | 2540 for (auto& child : graphicsLayer->children()) |
2521 synchronizedPaintRecursively(child); | 2541 synchronizedPaintRecursively(child); |
2522 } | 2542 } |
2523 | 2543 |
2524 void FrameView::compositeForSlimmingPaintV2() | 2544 void FrameView::compositeForSlimmingPaintV2() |
2525 { | 2545 { |
2526 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 2546 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
2527 ASSERT(frame() == page()->mainFrame() || (!frame().tree().parent()->isLocalF
rame())); | 2547 ASSERT(frame() == page()->mainFrame() || (!frame().tree().parent()->isLocalF
rame())); |
2528 | 2548 |
2529 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(
DocumentLifecycle::InCompositingForSlimmingPaintV2); }); | 2549 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle(
).advanceTo(DocumentLifecycle::InCompositingForSlimmingPaintV2); }); |
2530 | 2550 |
2531 // Detached frames can have no root graphics layer. | |
2532 if (GraphicsLayer* rootGraphicsLayer = layoutView()->layer()->graphicsLayerB
acking()) | 2551 if (GraphicsLayer* rootGraphicsLayer = layoutView()->layer()->graphicsLayerB
acking()) |
2533 rootGraphicsLayer->paintController()->commitNewDisplayItems(); | 2552 rootGraphicsLayer->paintController()->commitNewDisplayItems(); |
2534 | 2553 |
2535 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo(
DocumentLifecycle::CompositingForSlimmingPaintV2Clean); }); | 2554 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle(
).advanceTo(DocumentLifecycle::CompositingForSlimmingPaintV2Clean); }); |
2536 } | 2555 } |
2537 | 2556 |
2538 void FrameView::updateFrameTimingRequestsIfNeeded() | 2557 void FrameView::updateFrameTimingRequestsIfNeeded() |
2539 { | 2558 { |
2540 GraphicsLayerFrameTimingRequests graphicsLayerTimingRequests; | 2559 GraphicsLayerFrameTimingRequests graphicsLayerTimingRequests; |
2541 // TODO(mpb) use a 'dirty' bit to not call this every time. | 2560 // TODO(mpb) use a 'dirty' bit to not call this every time. |
2542 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); | 2561 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); |
2543 | 2562 |
2544 for (const auto& iter : graphicsLayerTimingRequests) { | 2563 for (const auto& iter : graphicsLayerTimingRequests) { |
2545 const GraphicsLayer* graphicsLayer = iter.key; | 2564 const GraphicsLayer* graphicsLayer = iter.key; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 | 2628 |
2610 // We need to stop recursing here since a child frame view might not be thro
ttled | 2629 // We need to stop recursing here since a child frame view might not be thro
ttled |
2611 // even though we are (e.g., it didn't compute its visibility yet). | 2630 // even though we are (e.g., it didn't compute its visibility yet). |
2612 if (shouldThrottleRendering()) | 2631 if (shouldThrottleRendering()) |
2613 return; | 2632 return; |
2614 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root",
layoutView()->debugName().ascii()); | 2633 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root",
layoutView()->debugName().ascii()); |
2615 | 2634 |
2616 Vector<LayoutObject*> pendingDelayedPaintInvalidations; | 2635 Vector<LayoutObject*> pendingDelayedPaintInvalidations; |
2617 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela
yedPaintInvalidations); | 2636 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela
yedPaintInvalidations); |
2618 | 2637 |
2619 invalidateTreeIfNeeded(rootPaintInvalidationState); | 2638 if (lifecycle().state() < DocumentLifecycle::PaintInvalidationClean) |
| 2639 invalidateTreeIfNeeded(rootPaintInvalidationState); |
2620 | 2640 |
2621 // Some frames may be not reached during the above invalidateTreeIfNeeded be
cause | 2641 // Some frames may be not reached during the above invalidateTreeIfNeeded be
cause |
2622 // - the frame is a detached frame; or | 2642 // - the frame is a detached frame; or |
2623 // - it didn't need paint invalidation. | 2643 // - it didn't need paint invalidation. |
2624 // We need to call invalidateTreeIfNeededRecursive() for such frames to fini
sh required | 2644 // We need to call invalidateTreeIfNeededRecursive() for such frames to fini
sh required |
2625 // paint invalidation and advance their life cycle state. | 2645 // paint invalidation and advance their life cycle state. |
2626 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree
().nextSibling()) { | 2646 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree
().nextSibling()) { |
2627 if (!child->isLocalFrame()) | 2647 if (child->isLocalFrame()) |
2628 continue; | 2648 toLocalFrame(child)->view()->invalidateTreeIfNeededRecursive(); |
2629 FrameView* childFrameView = toLocalFrame(child)->view(); | |
2630 if (childFrameView->lifecycle().state() < DocumentLifecycle::PaintInvali
dationClean) | |
2631 childFrameView->invalidateTreeIfNeededRecursive(); | |
2632 } | 2649 } |
2633 | 2650 |
2634 // Process objects needing paint invalidation on the next frame. See the def
inition of PaintInvalidationDelayedFull for more details. | 2651 // Process objects needing paint invalidation on the next frame. See the def
inition of PaintInvalidationDelayedFull for more details. |
2635 for (auto& target : pendingDelayedPaintInvalidations) | 2652 for (auto& target : pendingDelayedPaintInvalidations) |
2636 target->setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); | 2653 target->setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); |
2637 } | 2654 } |
2638 | 2655 |
2639 void FrameView::enableAutoSizeMode(const IntSize& minSize, const IntSize& maxSiz
e) | 2656 void FrameView::enableAutoSizeMode(const IntSize& minSize, const IntSize& maxSiz
e) |
2640 { | 2657 { |
2641 if (!m_autoSizeInfo) | 2658 if (!m_autoSizeInfo) |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4078 } | 4095 } |
4079 | 4096 |
4080 bool FrameView::canThrottleRendering() const | 4097 bool FrameView::canThrottleRendering() const |
4081 { | 4098 { |
4082 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled()) | 4099 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled()) |
4083 return false; | 4100 return false; |
4084 return m_hiddenForThrottling && m_crossOriginForThrottling; | 4101 return m_hiddenForThrottling && m_crossOriginForThrottling; |
4085 } | 4102 } |
4086 | 4103 |
4087 } // namespace blink | 4104 } // namespace blink |
OLD | NEW |