OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/shell/webkit_test_runner.h" | 5 #include "content/shell/webkit_test_runner.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/debug/debugger.h" |
10 #include "base/md5.h" | 11 #include "base/md5.h" |
11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
13 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
14 #include "base/sys_string_conversions.h" | 15 #include "base/sys_string_conversions.h" |
15 #include "base/time.h" | 16 #include "base/time.h" |
16 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
17 #include "content/public/renderer/render_view.h" | 18 #include "content/public/renderer/render_view.h" |
18 #include "content/public/test/layouttest_support.h" | 19 #include "content/public/test/layouttest_support.h" |
19 #include "content/shell/shell_messages.h" | 20 #include "content/shell/shell_messages.h" |
20 #include "content/shell/shell_render_process_observer.h" | 21 #include "content/shell/shell_render_process_observer.h" |
21 #include "content/shell/webkit_test_helpers.h" | 22 #include "content/shell/webkit_test_helpers.h" |
22 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
23 #include "net/base/net_util.h" | 24 #include "net/base/net_util.h" |
24 #include "skia/ext/platform_canvas.h" | 25 #include "skia/ext/platform_canvas.h" |
25 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" | 26 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" |
26 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" | 27 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" |
27 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" | 28 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" |
28 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" | 29 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" |
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | 30 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" |
30 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | 31 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" |
31 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" | 32 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" |
32 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h" | 33 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h" |
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" |
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h" |
| 37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientation.
h" |
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | 41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" |
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
41 #include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/Web
Task.h" | 43 #include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/Web
Task.h" |
42 #include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/Web
TestProxy.h" | 44 #include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/Web
TestProxy.h" |
43 #include "webkit/base/file_path_string_conversions.h" | 45 #include "webkit/base/file_path_string_conversions.h" |
44 #include "webkit/glue/webkit_glue.h" | 46 #include "webkit/glue/webkit_glue.h" |
45 #include "webkit/glue/webpreferences.h" | 47 #include "webkit/glue/webpreferences.h" |
46 | 48 |
47 using WebKit::Platform; | 49 using WebKit::Platform; |
48 using WebKit::WebContextMenuData; | 50 using WebKit::WebContextMenuData; |
49 using WebKit::WebDevToolsAgent; | 51 using WebKit::WebDevToolsAgent; |
| 52 using WebKit::WebDeviceOrientation; |
50 using WebKit::WebElement; | 53 using WebKit::WebElement; |
51 using WebKit::WebFrame; | 54 using WebKit::WebFrame; |
52 using WebKit::WebGamepads; | 55 using WebKit::WebGamepads; |
53 using WebKit::WebRect; | 56 using WebKit::WebRect; |
54 using WebKit::WebSize; | 57 using WebKit::WebSize; |
55 using WebKit::WebString; | 58 using WebKit::WebString; |
56 using WebKit::WebURL; | 59 using WebKit::WebURL; |
57 using WebKit::WebURLError; | 60 using WebKit::WebURLError; |
58 using WebKit::WebVector; | 61 using WebKit::WebVector; |
59 using WebKit::WebView; | 62 using WebKit::WebView; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 | 154 |
152 #if !defined(OS_MACOSX) | 155 #if !defined(OS_MACOSX) |
153 // Only the expected PNGs for Mac have a valid alpha channel. | 156 // Only the expected PNGs for Mac have a valid alpha channel. |
154 MakeBitmapOpaque(snapshot); | 157 MakeBitmapOpaque(snapshot); |
155 #endif | 158 #endif |
156 | 159 |
157 } | 160 } |
158 | 161 |
159 } // namespace | 162 } // namespace |
160 | 163 |
| 164 // static |
| 165 int WebKitTestRunner::window_count_ = 0; |
| 166 |
161 WebKitTestRunner::WebKitTestRunner(RenderView* render_view) | 167 WebKitTestRunner::WebKitTestRunner(RenderView* render_view) |
162 : RenderViewObserver(render_view) { | 168 : RenderViewObserver(render_view) { |
163 Reset(); | 169 Reset(); |
| 170 ++window_count_; |
164 } | 171 } |
165 | 172 |
166 WebKitTestRunner::~WebKitTestRunner() { | 173 WebKitTestRunner::~WebKitTestRunner() { |
| 174 --window_count_; |
167 } | 175 } |
168 | 176 |
169 // WebTestDelegate ----------------------------------------------------------- | 177 // WebTestDelegate ----------------------------------------------------------- |
170 | 178 |
171 void WebKitTestRunner::clearContextMenuData() { | |
172 last_context_menu_data_.reset(); | |
173 } | |
174 | |
175 WebContextMenuData* WebKitTestRunner::lastContextMenuData() const { | |
176 return last_context_menu_data_.get(); | |
177 } | |
178 | |
179 void WebKitTestRunner::clearEditCommand() { | 179 void WebKitTestRunner::clearEditCommand() { |
180 render_view()->ClearEditCommands(); | 180 render_view()->ClearEditCommands(); |
181 } | 181 } |
182 | 182 |
183 void WebKitTestRunner::setEditCommand(const std::string& name, | 183 void WebKitTestRunner::setEditCommand(const std::string& name, |
184 const std::string& value) { | 184 const std::string& value) { |
185 render_view()->SetEditCommandForNextKeyEvent(name, value); | 185 render_view()->SetEditCommandForNextKeyEvent(name, value); |
186 } | 186 } |
187 | 187 |
188 void WebKitTestRunner::fillSpellingSuggestionList( | |
189 const WebString& word, WebVector<WebString>* suggestions) { | |
190 if (word == WebString::fromUTF8("wellcome")) { | |
191 WebVector<WebString> result(suggestions->size() + 1); | |
192 for (size_t i = 0; i < suggestions->size(); ++i) | |
193 result[i] = (*suggestions)[i]; | |
194 result[suggestions->size()] = WebString::fromUTF8("welcome"); | |
195 suggestions->swap(result); | |
196 } | |
197 } | |
198 | |
199 void WebKitTestRunner::setGamepadData(const WebGamepads& gamepads) { | 188 void WebKitTestRunner::setGamepadData(const WebGamepads& gamepads) { |
200 SetMockGamepads(gamepads); | 189 SetMockGamepads(gamepads); |
201 } | 190 } |
202 | 191 |
203 void WebKitTestRunner::printMessage(const std::string& message) { | 192 void WebKitTestRunner::printMessage(const std::string& message) { |
204 Send(new ShellViewHostMsg_PrintMessage(routing_id(), message)); | 193 Send(new ShellViewHostMsg_PrintMessage(routing_id(), message)); |
205 } | 194 } |
206 | 195 |
207 void WebKitTestRunner::postTask(WebTask* task) { | 196 void WebKitTestRunner::postTask(WebTask* task) { |
208 Platform::current()->callOnMainThread(InvokeTaskHelper, task); | 197 Platform::current()->callOnMainThread(InvokeTaskHelper, task); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 break; | 309 break; |
321 } | 310 } |
322 } else { | 311 } else { |
323 DLOG(WARNING) << "Unknown error domain"; | 312 DLOG(WARNING) << "Unknown error domain"; |
324 } | 313 } |
325 | 314 |
326 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">", | 315 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">", |
327 domain.c_str(), code, error.unreachableURL.spec().data()); | 316 domain.c_str(), code, error.unreachableURL.spec().data()); |
328 } | 317 } |
329 | 318 |
| 319 void WebKitTestRunner::setClientWindowRect(const WebRect& rect) { |
| 320 Send(new ShellViewHostMsg_NotImplemented( |
| 321 routing_id(), "WebKitTestRunner", "setClientWindowRect")); |
| 322 } |
| 323 |
| 324 void WebKitTestRunner::showDevTools() { |
| 325 Send(new ShellViewHostMsg_NotImplemented( |
| 326 routing_id(), "WebKitTestRunner", "showDevTools")); |
| 327 } |
| 328 |
| 329 void WebKitTestRunner::closeDevTools() { |
| 330 Send(new ShellViewHostMsg_NotImplemented( |
| 331 routing_id(), "WebKitTestRunner", "closeDevTools")); |
| 332 } |
| 333 |
| 334 void WebKitTestRunner::evaluateInWebInspector(long call_id, |
| 335 const std::string& script) { |
| 336 Send(new ShellViewHostMsg_NotImplemented( |
| 337 routing_id(), "WebKitTestRunner", "evaluateInWebInspector")); |
| 338 } |
| 339 |
| 340 void WebKitTestRunner::clearAllDatabases() { |
| 341 Send(new ShellViewHostMsg_NotImplemented( |
| 342 routing_id(), "WebKitTestRunner", "clearAllDatabases")); |
| 343 } |
| 344 |
| 345 void WebKitTestRunner::setDatabaseQuota(int quota) { |
| 346 Send(new ShellViewHostMsg_NotImplemented( |
| 347 routing_id(), "WebKitTestRunner", "setDatabaseQuota")); |
| 348 } |
| 349 |
| 350 void WebKitTestRunner::setDeviceScaleFactor(float factor) { |
| 351 Send(new ShellViewHostMsg_NotImplemented( |
| 352 routing_id(), "WebKitTestRunner", "setDeviceScaleFactor")); |
| 353 } |
| 354 |
| 355 void WebKitTestRunner::setFocus(bool focus) { |
| 356 Send(new ShellViewHostMsg_NotImplemented( |
| 357 routing_id(), "WebKitTestRunner", "setFocus")); |
| 358 } |
| 359 |
| 360 void WebKitTestRunner::setAcceptAllCookies(bool accept) { |
| 361 Send(new ShellViewHostMsg_NotImplemented( |
| 362 routing_id(), "WebKitTestRunner", "setAcceptAllCookies")); |
| 363 } |
| 364 |
| 365 std::string WebKitTestRunner::pathToLocalResource(const std::string& resource) { |
| 366 Send(new ShellViewHostMsg_NotImplemented( |
| 367 routing_id(), "WebKitTestRunner", "pathToLocalResource")); |
| 368 return std::string(); |
| 369 } |
| 370 |
| 371 void WebKitTestRunner::setLocale(const std::string& locale) { |
| 372 Send(new ShellViewHostMsg_NotImplemented( |
| 373 routing_id(), "WebKitTestRunner", "setLocale")); |
| 374 } |
| 375 |
| 376 void WebKitTestRunner::setDeviceOrientation(WebDeviceOrientation& orientation) { |
| 377 Send(new ShellViewHostMsg_NotImplemented( |
| 378 routing_id(), "WebKitTestRunner", "setDeviceOrientation")); |
| 379 } |
| 380 |
| 381 void WebKitTestRunner::didAcquirePointerLock() { |
| 382 Send(new ShellViewHostMsg_NotImplemented( |
| 383 routing_id(), "WebKitTestRunner", "didAcquirePointerLock")); |
| 384 } |
| 385 |
| 386 void WebKitTestRunner::didNotAcquirePointerLock() { |
| 387 Send(new ShellViewHostMsg_NotImplemented( |
| 388 routing_id(), "WebKitTestRunner", "didNotAcquirePointerLock")); |
| 389 } |
| 390 |
| 391 void WebKitTestRunner::didLosePointerLock() { |
| 392 Send(new ShellViewHostMsg_NotImplemented( |
| 393 routing_id(), "WebKitTestRunner", "didLosePointerLock")); |
| 394 } |
| 395 |
| 396 void WebKitTestRunner::setPointerLockWillRespondAsynchronously() { |
| 397 Send(new ShellViewHostMsg_NotImplemented( |
| 398 routing_id(), |
| 399 "WebKitTestRunner", |
| 400 "setPointerLockWillRespondAsynchronously")); |
| 401 } |
| 402 |
| 403 void WebKitTestRunner::setPointerLockWillFailSynchronously() { |
| 404 Send(new ShellViewHostMsg_NotImplemented( |
| 405 routing_id(), "WebKitTestRunner", "setPointerLockWillFailSynchronously")); |
| 406 } |
| 407 |
| 408 int WebKitTestRunner::numberOfPendingGeolocationPermissionRequests() { |
| 409 Send(new ShellViewHostMsg_NotImplemented( |
| 410 routing_id(), |
| 411 "WebKitTestRunner", |
| 412 "numberOfPendingGeolocationPermissionRequests")); |
| 413 return 0; |
| 414 } |
| 415 |
| 416 void WebKitTestRunner::setGeolocationPermission(bool allowed) { |
| 417 Send(new ShellViewHostMsg_NotImplemented( |
| 418 routing_id(), "WebKitTestRunner", "setGeolocationPermission")); |
| 419 } |
| 420 |
| 421 void WebKitTestRunner::setMockGeolocationPosition(double latitude, |
| 422 double longitude, |
| 423 double precision) { |
| 424 Send(new ShellViewHostMsg_NotImplemented( |
| 425 routing_id(), "WebKitTestRunner", "setMockGeolocationPosition")); |
| 426 } |
| 427 |
| 428 void WebKitTestRunner::setMockGeolocationPositionUnavailableError( |
| 429 const std::string& message) { |
| 430 Send(new ShellViewHostMsg_NotImplemented( |
| 431 routing_id(), |
| 432 "WebKitTestRunner", |
| 433 "setMockGeolocationPositionUnavailableError")); |
| 434 } |
| 435 |
| 436 void WebKitTestRunner::addMockSpeechInputResult(const std::string& result, |
| 437 double confidence, |
| 438 const std::string& language) { |
| 439 Send(new ShellViewHostMsg_NotImplemented( |
| 440 routing_id(), "WebKitTestRunner", "addMockSpeechInputResult")); |
| 441 } |
| 442 |
| 443 void WebKitTestRunner::setMockSpeechInputDumpRect(bool dump_rect) { |
| 444 Send(new ShellViewHostMsg_NotImplemented( |
| 445 routing_id(), "WebKitTestRunner", "setMockSpeechInputDumpRect")); |
| 446 } |
| 447 |
| 448 void WebKitTestRunner::addMockSpeechRecognitionResult( |
| 449 const std::string& transcript, |
| 450 double confidence) { |
| 451 Send(new ShellViewHostMsg_NotImplemented( |
| 452 routing_id(), "WebKitTestRunner", "addMockSpeechRecognitionResult")); |
| 453 } |
| 454 |
| 455 void WebKitTestRunner::setMockSpeechRecognitionError( |
| 456 const std::string& error, |
| 457 const std::string& message) { |
| 458 Send(new ShellViewHostMsg_NotImplemented( |
| 459 routing_id(), "WebKitTestRunner", "setMockSpeechRecognitionError")); |
| 460 } |
| 461 |
| 462 bool WebKitTestRunner::wasMockSpeechRecognitionAborted() { |
| 463 Send(new ShellViewHostMsg_NotImplemented( |
| 464 routing_id(), "WebKitTestRunner", "wasMockSpeechRecognitionAborted")); |
| 465 return false; |
| 466 } |
| 467 |
| 468 void WebKitTestRunner::testFinished() { |
| 469 CaptureDump(); |
| 470 } |
| 471 |
| 472 void WebKitTestRunner::testTimedOut() { |
| 473 Send(new ShellViewHostMsg_TestFinished(routing_id(), true)); |
| 474 } |
| 475 |
| 476 bool WebKitTestRunner::isBeingDebugged() { |
| 477 return base::debug::BeingDebugged(); |
| 478 } |
| 479 |
| 480 int WebKitTestRunner::layoutTestTimeout() { |
| 481 return layout_test_timeout_; |
| 482 } |
| 483 |
| 484 void WebKitTestRunner::closeRemainingWindows() { |
| 485 Send(new ShellViewHostMsg_NotImplemented( |
| 486 routing_id(), "WebKitTestRunner", "closeRemainingWindows")); |
| 487 } |
| 488 |
| 489 int WebKitTestRunner::navigationEntryCount() { |
| 490 Send(new ShellViewHostMsg_NotImplemented( |
| 491 routing_id(), "WebKitTestRunner", "navigationEntryCount")); |
| 492 return 0; |
| 493 } |
| 494 |
| 495 int WebKitTestRunner::windowCount() { |
| 496 return window_count_; |
| 497 } |
| 498 |
| 499 void WebKitTestRunner::goToOffset(int offset) { |
| 500 Send(new ShellViewHostMsg_NotImplemented( |
| 501 routing_id(), "WebKitTestRunner", "goToOffset")); |
| 502 } |
| 503 |
| 504 void WebKitTestRunner::reload() { |
| 505 Send(new ShellViewHostMsg_NotImplemented( |
| 506 routing_id(), "WebKitTestRunner", "reload")); |
| 507 } |
| 508 |
| 509 void WebKitTestRunner::loadURLForFrame(const WebURL& url, |
| 510 const std::string& frame_name) { |
| 511 Send(new ShellViewHostMsg_NotImplemented( |
| 512 routing_id(), "WebKitTestRunner", "loadURLForFrame")); |
| 513 } |
| 514 |
| 515 bool WebKitTestRunner::allowExternalPages() { |
| 516 return allow_external_pages_; |
| 517 } |
| 518 |
| 519 void WebKitTestRunner::captureHistoryForWindow( |
| 520 size_t windowIndex, |
| 521 WebVector<WebKit::WebHistoryItem>* history, |
| 522 size_t* currentEntryIndex) { |
| 523 Send(new ShellViewHostMsg_NotImplemented( |
| 524 routing_id(), "WebKitTestRunner", "captureHistoryForWindow")); |
| 525 } |
| 526 |
330 // RenderViewObserver -------------------------------------------------------- | 527 // RenderViewObserver -------------------------------------------------------- |
331 | 528 |
332 void WebKitTestRunner::DidClearWindowObject(WebFrame* frame) { | 529 void WebKitTestRunner::DidClearWindowObject(WebFrame* frame) { |
333 ShellRenderProcessObserver::GetInstance()->BindTestRunnersToWindow(frame); | 530 ShellRenderProcessObserver::GetInstance()->BindTestRunnersToWindow(frame); |
334 } | 531 } |
335 | 532 |
336 void WebKitTestRunner::DidFinishLoad(WebFrame* frame) { | 533 void WebKitTestRunner::DidFinishLoad(WebFrame* frame) { |
337 if (!frame->parent()) { | 534 if (!frame->parent()) { |
338 if (!wait_until_done_) { | 535 if (!wait_until_done_) { |
339 test_is_running_ = false; | 536 test_is_running_ = false; |
340 CaptureDump(); | 537 CaptureDump(); |
341 } | 538 } |
342 load_finished_ = true; | 539 load_finished_ = true; |
343 } | 540 } |
344 } | 541 } |
345 | 542 |
346 void WebKitTestRunner::DidRequestShowContextMenu( | |
347 WebFrame* frame, | |
348 const WebContextMenuData& data) { | |
349 last_context_menu_data_.reset(new WebContextMenuData(data)); | |
350 } | |
351 | |
352 bool WebKitTestRunner::OnMessageReceived(const IPC::Message& message) { | 543 bool WebKitTestRunner::OnMessageReceived(const IPC::Message& message) { |
353 bool handled = true; | 544 bool handled = true; |
354 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunner, message) | 545 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunner, message) |
355 IPC_MESSAGE_HANDLER(ShellViewMsg_SetTestConfiguration, | 546 IPC_MESSAGE_HANDLER(ShellViewMsg_SetTestConfiguration, |
356 OnSetTestConfiguration) | 547 OnSetTestConfiguration) |
357 IPC_MESSAGE_UNHANDLED(handled = false) | 548 IPC_MESSAGE_UNHANDLED(handled = false) |
358 IPC_END_MESSAGE_MAP() | 549 IPC_END_MESSAGE_MAP() |
359 | 550 |
360 return handled; | 551 return handled; |
361 } | 552 } |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 bool allow_external_pages, | 694 bool allow_external_pages, |
504 const std::string& expected_pixel_hash) { | 695 const std::string& expected_pixel_hash) { |
505 current_working_directory_ = current_working_directory; | 696 current_working_directory_ = current_working_directory; |
506 enable_pixel_dumping_ = enable_pixel_dumping; | 697 enable_pixel_dumping_ = enable_pixel_dumping; |
507 layout_test_timeout_ = layout_test_timeout; | 698 layout_test_timeout_ = layout_test_timeout; |
508 allow_external_pages_ = allow_external_pages; | 699 allow_external_pages_ = allow_external_pages; |
509 expected_pixel_hash_ = expected_pixel_hash; | 700 expected_pixel_hash_ = expected_pixel_hash; |
510 } | 701 } |
511 | 702 |
512 } // namespace content | 703 } // namespace content |
OLD | NEW |