OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/memory/weak_ptr.h" | 5 #include "base/memory/weak_ptr.h" |
6 #include "content/browser/frame_host/navigation_handle_impl.h" | 6 #include "content/browser/frame_host/navigation_handle_impl.h" |
7 #include "content/browser/web_contents/web_contents_impl.h" | 7 #include "content/browser/web_contents/web_contents_impl.h" |
8 #include "content/public/browser/web_contents.h" | 8 #include "content/public/browser/web_contents.h" |
9 #include "content/public/browser/web_contents_observer.h" | 9 #include "content/public/browser/web_contents_observer.h" |
10 #include "content/public/common/request_context_type.h" | 10 #include "content/public/common/request_context_type.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 handle_ = navigation_handle; | 40 handle_ = navigation_handle; |
41 has_committed_ = false; | 41 has_committed_ = false; |
42 is_error_ = false; | 42 is_error_ = false; |
43 page_transition_ = ui::PAGE_TRANSITION_LINK; | 43 page_transition_ = ui::PAGE_TRANSITION_LINK; |
44 last_committed_url_ = GURL(); | 44 last_committed_url_ = GURL(); |
45 | 45 |
46 is_main_frame_ = navigation_handle->IsInMainFrame(); | 46 is_main_frame_ = navigation_handle->IsInMainFrame(); |
47 is_parent_main_frame_ = navigation_handle->IsParentMainFrame(); | 47 is_parent_main_frame_ = navigation_handle->IsParentMainFrame(); |
48 is_renderer_initiated_ = navigation_handle->IsRendererInitiated(); | 48 is_renderer_initiated_ = navigation_handle->IsRendererInitiated(); |
49 is_same_page_ = navigation_handle->IsSamePage(); | 49 is_same_document_ = navigation_handle->IsSameDocument(); |
50 was_redirected_ = navigation_handle->WasServerRedirect(); | 50 was_redirected_ = navigation_handle->WasServerRedirect(); |
51 frame_tree_node_id_ = navigation_handle->GetFrameTreeNodeId(); | 51 frame_tree_node_id_ = navigation_handle->GetFrameTreeNodeId(); |
52 } | 52 } |
53 | 53 |
54 void DidFinishNavigation(NavigationHandle* navigation_handle) override { | 54 void DidFinishNavigation(NavigationHandle* navigation_handle) override { |
55 if (navigation_handle != handle_) | 55 if (navigation_handle != handle_) |
56 return; | 56 return; |
57 | 57 |
58 DCHECK_EQ(is_main_frame_, navigation_handle->IsInMainFrame()); | 58 DCHECK_EQ(is_main_frame_, navigation_handle->IsInMainFrame()); |
59 DCHECK_EQ(is_parent_main_frame_, navigation_handle->IsParentMainFrame()); | 59 DCHECK_EQ(is_parent_main_frame_, navigation_handle->IsParentMainFrame()); |
60 DCHECK_EQ(is_same_page_, navigation_handle->IsSamePage()); | 60 DCHECK_EQ(is_same_document_, navigation_handle->IsSameDocument()); |
61 DCHECK_EQ(is_renderer_initiated_, navigation_handle->IsRendererInitiated()); | 61 DCHECK_EQ(is_renderer_initiated_, navigation_handle->IsRendererInitiated()); |
62 DCHECK_EQ(frame_tree_node_id_, navigation_handle->GetFrameTreeNodeId()); | 62 DCHECK_EQ(frame_tree_node_id_, navigation_handle->GetFrameTreeNodeId()); |
63 | 63 |
64 was_redirected_ = navigation_handle->WasServerRedirect(); | 64 was_redirected_ = navigation_handle->WasServerRedirect(); |
65 net_error_code_ = navigation_handle->GetNetErrorCode(); | 65 net_error_code_ = navigation_handle->GetNetErrorCode(); |
66 | 66 |
67 if (navigation_handle->HasCommitted()) { | 67 if (navigation_handle->HasCommitted()) { |
68 has_committed_ = true; | 68 has_committed_ = true; |
69 if (!navigation_handle->IsErrorPage()) { | 69 if (!navigation_handle->IsErrorPage()) { |
70 page_transition_ = navigation_handle->GetPageTransition(); | 70 page_transition_ = navigation_handle->GetPageTransition(); |
71 last_committed_url_ = navigation_handle->GetURL(); | 71 last_committed_url_ = navigation_handle->GetURL(); |
72 } else { | 72 } else { |
73 is_error_ = true; | 73 is_error_ = true; |
74 } | 74 } |
75 } else { | 75 } else { |
76 has_committed_ = false; | 76 has_committed_ = false; |
77 is_error_ = true; | 77 is_error_ = true; |
78 } | 78 } |
79 | 79 |
80 handle_ = nullptr; | 80 handle_ = nullptr; |
81 } | 81 } |
82 | 82 |
83 bool has_committed() { return has_committed_; } | 83 bool has_committed() { return has_committed_; } |
84 bool is_error() { return is_error_; } | 84 bool is_error() { return is_error_; } |
85 bool is_main_frame() { return is_main_frame_; } | 85 bool is_main_frame() { return is_main_frame_; } |
86 bool is_parent_main_frame() { return is_parent_main_frame_; } | 86 bool is_parent_main_frame() { return is_parent_main_frame_; } |
87 bool is_renderer_initiated() { return is_renderer_initiated_; } | 87 bool is_renderer_initiated() { return is_renderer_initiated_; } |
88 bool is_same_page() { return is_same_page_; } | 88 bool is_same_document() { return is_same_document_; } |
89 bool was_redirected() { return was_redirected_; } | 89 bool was_redirected() { return was_redirected_; } |
90 int frame_tree_node_id() { return frame_tree_node_id_; } | 90 int frame_tree_node_id() { return frame_tree_node_id_; } |
91 | 91 |
92 const GURL& last_committed_url() { return last_committed_url_; } | 92 const GURL& last_committed_url() { return last_committed_url_; } |
93 | 93 |
94 ui::PageTransition page_transition() { return page_transition_; } | 94 ui::PageTransition page_transition() { return page_transition_; } |
95 | 95 |
96 net::Error net_error_code() { return net_error_code_; } | 96 net::Error net_error_code() { return net_error_code_; } |
97 | 97 |
98 private: | 98 private: |
99 // A reference to the NavigationHandle so this class will track only | 99 // A reference to the NavigationHandle so this class will track only |
100 // one navigation at a time. It is set at DidStartNavigation and cleared | 100 // one navigation at a time. It is set at DidStartNavigation and cleared |
101 // at DidFinishNavigation before the NavigationHandle is destroyed. | 101 // at DidFinishNavigation before the NavigationHandle is destroyed. |
102 NavigationHandle* handle_ = nullptr; | 102 NavigationHandle* handle_ = nullptr; |
103 bool has_committed_ = false; | 103 bool has_committed_ = false; |
104 bool is_error_ = false; | 104 bool is_error_ = false; |
105 bool is_main_frame_ = false; | 105 bool is_main_frame_ = false; |
106 bool is_parent_main_frame_ = false; | 106 bool is_parent_main_frame_ = false; |
107 bool is_renderer_initiated_ = true; | 107 bool is_renderer_initiated_ = true; |
108 bool is_same_page_ = false; | 108 bool is_same_document_ = false; |
109 bool was_redirected_ = false; | 109 bool was_redirected_ = false; |
110 int frame_tree_node_id_ = -1; | 110 int frame_tree_node_id_ = -1; |
111 ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK; | 111 ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK; |
112 GURL expected_start_url_; | 112 GURL expected_start_url_; |
113 GURL last_committed_url_; | 113 GURL last_committed_url_; |
114 net::Error net_error_code_ = net::OK; | 114 net::Error net_error_code_ = net::OK; |
115 }; | 115 }; |
116 | 116 |
117 // A test NavigationThrottle that will return pre-determined checks and run | 117 // A test NavigationThrottle that will return pre-determined checks and run |
118 // callbacks when the various NavigationThrottle methods are called. It is | 118 // callbacks when the various NavigationThrottle methods are called. It is |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 NavigationHandleObserver observer(shell()->web_contents(), | 508 NavigationHandleObserver observer(shell()->web_contents(), |
509 GURL(kAboutSrcDocURL)); | 509 GURL(kAboutSrcDocURL)); |
510 | 510 |
511 EXPECT_TRUE(NavigateToURL(shell(), url)); | 511 EXPECT_TRUE(NavigateToURL(shell(), url)); |
512 | 512 |
513 EXPECT_TRUE(observer.has_committed()); | 513 EXPECT_TRUE(observer.has_committed()); |
514 EXPECT_FALSE(observer.is_error()); | 514 EXPECT_FALSE(observer.is_error()); |
515 EXPECT_EQ(GURL(kAboutSrcDocURL), observer.last_committed_url()); | 515 EXPECT_EQ(GURL(kAboutSrcDocURL), observer.last_committed_url()); |
516 } | 516 } |
517 | 517 |
518 // Ensure that the IsSamePage() method on NavigationHandle behaves correctly. | 518 // Ensure that the IsSameDocument() method on NavigationHandle behaves |
519 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, VerifySamePage) { | 519 // correctly. |
| 520 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, VerifySameDocument) { |
520 GURL url(embedded_test_server()->GetURL( | 521 GURL url(embedded_test_server()->GetURL( |
521 "a.com", "/cross_site_iframe_factory.html?a(a())")); | 522 "a.com", "/cross_site_iframe_factory.html?a(a())")); |
522 EXPECT_TRUE(NavigateToURL(shell(), url)); | 523 EXPECT_TRUE(NavigateToURL(shell(), url)); |
523 | 524 |
524 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | 525 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
525 ->GetFrameTree() | 526 ->GetFrameTree() |
526 ->root(); | 527 ->root(); |
527 { | 528 { |
528 NavigationHandleObserver observer( | 529 NavigationHandleObserver observer( |
529 shell()->web_contents(), | 530 shell()->web_contents(), |
530 embedded_test_server()->GetURL("a.com", "/foo")); | 531 embedded_test_server()->GetURL("a.com", "/foo")); |
531 EXPECT_TRUE(ExecuteScript(root->child_at(0), | 532 EXPECT_TRUE(ExecuteScript(root->child_at(0), |
532 "window.history.pushState({}, '', 'foo');")); | 533 "window.history.pushState({}, '', 'foo');")); |
533 | 534 |
534 EXPECT_TRUE(observer.has_committed()); | 535 EXPECT_TRUE(observer.has_committed()); |
535 EXPECT_FALSE(observer.is_error()); | 536 EXPECT_FALSE(observer.is_error()); |
536 EXPECT_TRUE(observer.is_same_page()); | 537 EXPECT_TRUE(observer.is_same_document()); |
537 } | 538 } |
538 { | 539 { |
539 NavigationHandleObserver observer( | 540 NavigationHandleObserver observer( |
540 shell()->web_contents(), | 541 shell()->web_contents(), |
541 embedded_test_server()->GetURL("a.com", "/bar")); | 542 embedded_test_server()->GetURL("a.com", "/bar")); |
542 EXPECT_TRUE(ExecuteScript(root->child_at(0), | 543 EXPECT_TRUE(ExecuteScript(root->child_at(0), |
543 "window.history.replaceState({}, '', 'bar');")); | 544 "window.history.replaceState({}, '', 'bar');")); |
544 | 545 |
545 EXPECT_TRUE(observer.has_committed()); | 546 EXPECT_TRUE(observer.has_committed()); |
546 EXPECT_FALSE(observer.is_error()); | 547 EXPECT_FALSE(observer.is_error()); |
547 EXPECT_TRUE(observer.is_same_page()); | 548 EXPECT_TRUE(observer.is_same_document()); |
548 } | 549 } |
549 { | 550 { |
550 NavigationHandleObserver observer( | 551 NavigationHandleObserver observer( |
551 shell()->web_contents(), | 552 shell()->web_contents(), |
552 embedded_test_server()->GetURL("a.com", "/bar#frag")); | 553 embedded_test_server()->GetURL("a.com", "/bar#frag")); |
553 EXPECT_TRUE( | 554 EXPECT_TRUE( |
554 ExecuteScript(root->child_at(0), "window.location.replace('#frag');")); | 555 ExecuteScript(root->child_at(0), "window.location.replace('#frag');")); |
555 | 556 |
556 EXPECT_TRUE(observer.has_committed()); | 557 EXPECT_TRUE(observer.has_committed()); |
557 EXPECT_FALSE(observer.is_error()); | 558 EXPECT_FALSE(observer.is_error()); |
558 EXPECT_TRUE(observer.is_same_page()); | 559 EXPECT_TRUE(observer.is_same_document()); |
559 } | 560 } |
560 | 561 |
561 GURL about_blank_url(url::kAboutBlankURL); | 562 GURL about_blank_url(url::kAboutBlankURL); |
562 { | 563 { |
563 NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); | 564 NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); |
564 EXPECT_TRUE(ExecuteScript( | 565 EXPECT_TRUE(ExecuteScript( |
565 root, "document.body.appendChild(document.createElement('iframe'));")); | 566 root, "document.body.appendChild(document.createElement('iframe'));")); |
566 | 567 |
567 EXPECT_TRUE(observer.has_committed()); | 568 EXPECT_TRUE(observer.has_committed()); |
568 EXPECT_FALSE(observer.is_error()); | 569 EXPECT_FALSE(observer.is_error()); |
569 EXPECT_FALSE(observer.is_same_page()); | 570 EXPECT_FALSE(observer.is_same_document()); |
570 EXPECT_EQ(about_blank_url, observer.last_committed_url()); | 571 EXPECT_EQ(about_blank_url, observer.last_committed_url()); |
571 } | 572 } |
572 { | 573 { |
573 NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); | 574 NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); |
574 NavigateFrameToURL(root->child_at(0), about_blank_url); | 575 NavigateFrameToURL(root->child_at(0), about_blank_url); |
575 | 576 |
576 EXPECT_TRUE(observer.has_committed()); | 577 EXPECT_TRUE(observer.has_committed()); |
577 EXPECT_FALSE(observer.is_error()); | 578 EXPECT_FALSE(observer.is_error()); |
578 EXPECT_FALSE(observer.is_same_page()); | 579 EXPECT_FALSE(observer.is_same_document()); |
579 EXPECT_EQ(about_blank_url, observer.last_committed_url()); | 580 EXPECT_EQ(about_blank_url, observer.last_committed_url()); |
580 } | 581 } |
581 } | 582 } |
582 | 583 |
583 // Ensure that a NavigationThrottle can cancel the navigation at navigation | 584 // Ensure that a NavigationThrottle can cancel the navigation at navigation |
584 // start. | 585 // start. |
585 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleCancelStart) { | 586 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleCancelStart) { |
586 GURL start_url(embedded_test_server()->GetURL("/title1.html")); | 587 GURL start_url(embedded_test_server()->GetURL("/title1.html")); |
587 EXPECT_TRUE(NavigateToURL(shell(), start_url)); | 588 EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
588 | 589 |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 GURL start_url( | 963 GURL start_url( |
963 embedded_test_server()->GetURL("/https_upgrade_cross_site.html")); | 964 embedded_test_server()->GetURL("/https_upgrade_cross_site.html")); |
964 GURL cross_site_iframe_secure_url("https://other.com/title1.html"); | 965 GURL cross_site_iframe_secure_url("https://other.com/title1.html"); |
965 | 966 |
966 CheckHttpsUpgradedIframeNavigation(start_url, cross_site_iframe_secure_url); | 967 CheckHttpsUpgradedIframeNavigation(start_url, cross_site_iframe_secure_url); |
967 } | 968 } |
968 | 969 |
969 // Ensure that browser-initiated same-document navigations are detected and | 970 // Ensure that browser-initiated same-document navigations are detected and |
970 // don't issue network requests. See crbug.com/663777. | 971 // don't issue network requests. See crbug.com/663777. |
971 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, | 972 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, |
972 SamePageBrowserInitiatedNoReload) { | 973 SameDocumentBrowserInitiatedNoReload) { |
973 GURL url(embedded_test_server()->GetURL("/title1.html")); | 974 GURL url(embedded_test_server()->GetURL("/title1.html")); |
974 GURL url_fragment_1(embedded_test_server()->GetURL("/title1.html#id_1")); | 975 GURL url_fragment_1(embedded_test_server()->GetURL("/title1.html#id_1")); |
975 GURL url_fragment_2(embedded_test_server()->GetURL("/title1.html#id_2")); | 976 GURL url_fragment_2(embedded_test_server()->GetURL("/title1.html#id_2")); |
976 | 977 |
977 // 1) Perform a new-document navigation. | 978 // 1) Perform a new-document navigation. |
978 { | 979 { |
979 TestNavigationThrottleInstaller installer( | 980 TestNavigationThrottleInstaller installer( |
980 shell()->web_contents(), NavigationThrottle::PROCEED, | 981 shell()->web_contents(), NavigationThrottle::PROCEED, |
981 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); | 982 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
982 NavigationHandleObserver observer(shell()->web_contents(), url); | 983 NavigationHandleObserver observer(shell()->web_contents(), url); |
983 EXPECT_TRUE(NavigateToURL(shell(), url)); | 984 EXPECT_TRUE(NavigateToURL(shell(), url)); |
984 EXPECT_EQ(1, installer.will_start_called()); | 985 EXPECT_EQ(1, installer.will_start_called()); |
985 EXPECT_EQ(1, installer.will_process_called()); | 986 EXPECT_EQ(1, installer.will_process_called()); |
986 EXPECT_FALSE(observer.is_same_page()); | 987 EXPECT_FALSE(observer.is_same_document()); |
987 } | 988 } |
988 | 989 |
989 // 2) Perform a same-document navigation by adding a fragment. | 990 // 2) Perform a same-document navigation by adding a fragment. |
990 { | 991 { |
991 TestNavigationThrottleInstaller installer( | 992 TestNavigationThrottleInstaller installer( |
992 shell()->web_contents(), NavigationThrottle::PROCEED, | 993 shell()->web_contents(), NavigationThrottle::PROCEED, |
993 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); | 994 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
994 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_1); | 995 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_1); |
995 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_1)); | 996 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_1)); |
996 EXPECT_EQ(0, installer.will_start_called()); | 997 EXPECT_EQ(0, installer.will_start_called()); |
997 EXPECT_EQ(0, installer.will_process_called()); | 998 EXPECT_EQ(0, installer.will_process_called()); |
998 EXPECT_TRUE(observer.is_same_page()); | 999 EXPECT_TRUE(observer.is_same_document()); |
999 } | 1000 } |
1000 | 1001 |
1001 // 3) Perform a same-document navigation by modifying the fragment. | 1002 // 3) Perform a same-document navigation by modifying the fragment. |
1002 { | 1003 { |
1003 TestNavigationThrottleInstaller installer( | 1004 TestNavigationThrottleInstaller installer( |
1004 shell()->web_contents(), NavigationThrottle::PROCEED, | 1005 shell()->web_contents(), NavigationThrottle::PROCEED, |
1005 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); | 1006 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
1006 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); | 1007 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); |
1007 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); | 1008 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); |
1008 EXPECT_EQ(0, installer.will_start_called()); | 1009 EXPECT_EQ(0, installer.will_start_called()); |
1009 EXPECT_EQ(0, installer.will_process_called()); | 1010 EXPECT_EQ(0, installer.will_process_called()); |
1010 EXPECT_TRUE(observer.is_same_page()); | 1011 EXPECT_TRUE(observer.is_same_document()); |
1011 } | 1012 } |
1012 | 1013 |
1013 // 4) Redo the last navigation, but this time it should trigger a reload. | 1014 // 4) Redo the last navigation, but this time it should trigger a reload. |
1014 { | 1015 { |
1015 TestNavigationThrottleInstaller installer( | 1016 TestNavigationThrottleInstaller installer( |
1016 shell()->web_contents(), NavigationThrottle::PROCEED, | 1017 shell()->web_contents(), NavigationThrottle::PROCEED, |
1017 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); | 1018 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
1018 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); | 1019 NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); |
1019 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); | 1020 EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); |
1020 EXPECT_EQ(1, installer.will_start_called()); | 1021 EXPECT_EQ(1, installer.will_start_called()); |
1021 EXPECT_EQ(1, installer.will_process_called()); | 1022 EXPECT_EQ(1, installer.will_process_called()); |
1022 EXPECT_FALSE(observer.is_same_page()); | 1023 EXPECT_FALSE(observer.is_same_document()); |
1023 } | 1024 } |
1024 | 1025 |
1025 // 5) Perform a new-document navigation by removing the fragment. | 1026 // 5) Perform a new-document navigation by removing the fragment. |
1026 { | 1027 { |
1027 TestNavigationThrottleInstaller installer( | 1028 TestNavigationThrottleInstaller installer( |
1028 shell()->web_contents(), NavigationThrottle::PROCEED, | 1029 shell()->web_contents(), NavigationThrottle::PROCEED, |
1029 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); | 1030 NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); |
1030 NavigationHandleObserver observer(shell()->web_contents(), url); | 1031 NavigationHandleObserver observer(shell()->web_contents(), url); |
1031 EXPECT_TRUE(NavigateToURL(shell(), url)); | 1032 EXPECT_TRUE(NavigateToURL(shell(), url)); |
1032 EXPECT_EQ(1, installer.will_start_called()); | 1033 EXPECT_EQ(1, installer.will_start_called()); |
1033 EXPECT_EQ(1, installer.will_process_called()); | 1034 EXPECT_EQ(1, installer.will_process_called()); |
1034 EXPECT_FALSE(observer.is_same_page()); | 1035 EXPECT_FALSE(observer.is_same_document()); |
1035 } | 1036 } |
1036 } | 1037 } |
1037 | 1038 |
1038 } // namespace content | 1039 } // namespace content |
OLD | NEW |