diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-29 10:46:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-02 12:02:10 +0000 |
commit | 99677208ff3b216fdfec551fbe548da5520cd6fb (patch) | |
tree | 476a4865c10320249360e859d8fdd3e01833b03a /chromium/chrome/browser/resources | |
parent | c30a6232df03e1efbd9f3b226777b07e087a1122 (diff) | |
download | qtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz |
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources')
389 files changed, 15186 insertions, 3147 deletions
diff --git a/chromium/chrome/browser/resources/BUILD.gn b/chromium/chrome/browser/resources/BUILD.gn index 0f428df836e..367c87b1701 100644 --- a/chromium/chrome/browser/resources/BUILD.gn +++ b/chromium/chrome/browser/resources/BUILD.gn @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//chrome/browser/buildflags.gni") import("//chrome/common/features.gni") import("//chrome/test/base/js2gtest.gni") import("//chrome/test/include_js_tests.gni") @@ -22,7 +23,7 @@ if (enable_js_type_check) { "memory_internals:closure_compile", "reset_password:closure_compile", ] - if (is_linux || is_win || is_mac) { + if (is_linux || is_chromeos || is_win || is_mac) { deps += [ "bluetooth_internals:closure_compile", "bookmarks:closure_compile", @@ -31,12 +32,15 @@ if (enable_js_type_check) { "downloads:closure_compile", "gaia_auth_host:closure_compile", "history:closure_compile", + "inline_login:closure_compile", "local_ntp:closure_compile", "local_state:closure_compile", "management:closure_compile", "media_router:closure_compile", "nearby_internals:closure_compile", "nearby_share:closure_compile", + "nearby_share/shared:closure_compile", + "nearby_share/shared:closure_compile_module", "new_tab_page:closure_compile", "ntp4:closure_compile", "omnibox:closure_compile", @@ -52,7 +56,7 @@ if (enable_js_type_check) { "welcome:closure_compile", ] } - if (is_win || is_android || is_linux) { + if (is_win || is_android || is_linux || is_chromeos) { deps += [ "sandbox_internals:closure_compile" ] } if (is_chromeos) { @@ -64,13 +68,20 @@ if (enable_js_type_check) { if (enable_nacl) { deps += [ "about_nacl:closure_compile" ] } + if (enable_tab_search) { + deps += [ "tab_search:closure_compile" ] + } if (enable_webui_tab_strip) { deps += [ "tab_strip:closure_compile" ] } + if (enable_kaleidoscope) { + deps += [ "kaleidoscope:closure_compile" ] + } if (is_android) { deps += [ "explore_sites_internals:closure_compile", "feed_internals:closure_compile", + "internals/notifications:closure_compile", "internals/query_tiles:closure_compile", "offline_pages:closure_compile", "snippets_internals:closure_compile", @@ -85,7 +96,7 @@ if (enable_js_type_check) { # but because Window bots don't depend on Java, |closure_compile| is off on # Windows. Adding |is_linux| so that these targets are type-checked on at # least one platform. - if (is_win || is_linux) { + if (is_win || is_linux || is_chromeos) { deps += [ "conflicts:closure_compile" ] } } @@ -225,7 +236,11 @@ if (!is_android) { "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), ] - deps = [ "//chrome/browser/resources/nearby_share:web_components" ] + deps = [ + "//chrome/browser/resources/nearby_share:web_components", + "//chrome/browser/resources/nearby_share/shared:polymer3_elements", + "//chrome/browser/ui/webui/nearby_share:mojom_js", + ] defines = chrome_grit_defines outputs = [ @@ -245,6 +260,7 @@ if (!is_android) { } deps = [ + "//chrome/browser/promo_browser_command:mojo_bindings_js", "//chrome/browser/ui/webui/new_tab_page:mojo_bindings_js", "//skia/public/mojom:mojom_js", ] @@ -323,6 +339,27 @@ if (!is_android) { } if (is_chromeos) { + grit("multidevice_internals_resources") { + source = + "chromeos/multidevice_internals/multidevice_internals_resources.grd" + + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + ] + + deps = [ "//chrome/browser/resources/chromeos/multidevice_internals:web_components" ] + + defines = chrome_grit_defines + outputs = [ + "grit/multidevice_internals_resources.h", + "grit/multidevice_internals_resources_map.cc", + "grit/multidevice_internals_resources_map.h", + "multidevice_internals_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + } + grit("os_settings_resources") { grit_flags = [ "-E", @@ -508,6 +545,28 @@ if (enable_print_preview) { } } +if (enable_tab_search) { + grit("tab_search_resources") { + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + ] + source = "tab_search/tab_search_resources.grd" + deps = [ + "//chrome/browser/resources/tab_search:web_components", + "//chrome/browser/ui/webui/tab_search:mojo_bindings_js", + ] + defines = chrome_grit_defines + outputs = [ + "grit/tab_search_resources.h", + "grit/tab_search_resources_map.cc", + "grit/tab_search_resources_map.h", + "tab_search_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + } +} + if (enable_webui_tab_strip) { grit("tab_strip_resources") { source = "tab_strip/tab_strip_resources.grd" diff --git a/chromium/chrome/browser/resources/accessibility/accessibility.js b/chromium/chrome/browser/resources/accessibility/accessibility.js index d0b0b7f9b92..bfa74623331 100644 --- a/chromium/chrome/browser/resources/accessibility/accessibility.js +++ b/chromium/chrome/browser/resources/accessibility/accessibility.js @@ -80,7 +80,7 @@ cr.define('accessibility', function() { // function with the result. const requestType = element.id.split(':')[1]; if (data.type == 'browser') { - const delay = $('native_ui_delay').value; + const delay = $('native-ui-delay').value; setTimeout(() => { chrome.send( 'requestNativeUITree', [{ diff --git a/chromium/chrome/browser/resources/bookmarks/toolbar.html b/chromium/chrome/browser/resources/bookmarks/toolbar.html index 764da792202..91cc1b3e836 100644 --- a/chromium/chrome/browser/resources/bookmarks/toolbar.html +++ b/chromium/chrome/browser/resources/bookmarks/toolbar.html @@ -31,6 +31,7 @@ clear-label="$i18n{clearSearch}" search-prompt="$i18n{searchPrompt}" narrow="{{narrow_}}" + autofocus on-search-changed="onSearchChanged_"> <cr-icon-button iron-icon="cr:more-vert" id="menuButton" diff --git a/chromium/chrome/browser/resources/certificate_viewer.html b/chromium/chrome/browser/resources/certificate_viewer.html index 8d7d2e22a0e..ac5653f9a79 100644 --- a/chromium/chrome/browser/resources/certificate_viewer.html +++ b/chromium/chrome/browser/resources/certificate_viewer.html @@ -32,13 +32,13 @@ <!-- General --> <tabpanel id="general" aria-labelledby="general-tab"> <!-- Usages --> - <h3 id="usages-title" role="group">$i18n{usages}</h3> + <h3 id="usages-title" role="heading">$i18n{usages}</h3> <div id="usages"></div> <div class="groups"> <!-- Issued to --> <div> - <h3 role="group">$i18n{issuedTo}</h3> + <h3 role="heading">$i18n{issuedTo}</h3> </div> <div> <div class="attribute">$i18n{cn}</div> @@ -55,7 +55,7 @@ <!-- Issued by --> <div> - <h3 role="group">$i18n{issuedBy}</h3> + <h3 role="heading">$i18n{issuedBy}</h3> </div> <div> <div class="attribute">$i18n{cn}</div> @@ -72,7 +72,7 @@ <!-- Validity --> <div> - <h3 role="group">$i18n{validity}</h3> + <h3 role="heading">$i18n{validity}</h3> </div> <div> <div class="attribute">$i18n{issuedOn}</div> @@ -85,7 +85,7 @@ <!-- Fingerprints --> <div> - <h3 role="group">$i18n{fingerprints}</h3> + <h3 role="heading">$i18n{fingerprints}</h3> </div> <div> <div class="attribute">$i18n{sha256}</div> @@ -101,19 +101,19 @@ <!-- Details --> <tabpanel id="details" aria-labelledby="details-tab"> <div id="hierarchy-section" class="vertical-box"> - <h3 id="hierarchy-label" role="group">$i18n{hierarchy}</h3> + <h3 id="hierarchy-label" role="heading">$i18n{hierarchy}</h3> <tree id="hierarchy" class="section-contents" aria-labelledby="hierarchy-label" icon-visibility='hidden'></tree> </div> <div id="cert-fields-section" class="vertical-box"> - <h3 id="cert-fields-label" role="group">$i18n{certFields}</h3> + <h3 id="cert-fields-label" role="heading">$i18n{certFields}</h3> <tree id="cert-fields" class="section-contents" aria-labelledby="cert-fields-label" icon-visibility='hidden'></tree> </div> <div id="cert-field-value-section" class="vertical-box"> - <h3 id="cert-field-value-label" role="group"> + <h3 id="cert-field-value-label" role="heading"> $i18n{certFieldVal} </h3> <div id="cert-field-value" class="section-contents" tabindex="0" diff --git a/chromium/chrome/browser/resources/certificate_viewer.js b/chromium/chrome/browser/resources/certificate_viewer.js index 0d27d0c4243..215f4b2d082 100644 --- a/chromium/chrome/browser/resources/certificate_viewer.js +++ b/chromium/chrome/browser/resources/certificate_viewer.js @@ -185,7 +185,7 @@ // Ensure the list is scrolled to the top by selecting the first item. treeItem.children[0].selected = true; document.body.dispatchEvent( - new CustomEvent('certificate-fields-updated-for-tesing')); + new CustomEvent('certificate-fields-updated-for-testing')); } /** diff --git a/chromium/chrome/browser/resources/chrome_urls_disabled_page/app.html b/chromium/chrome/browser/resources/chrome_urls_disabled_page/app.html deleted file mode 100644 index 848d6429806..00000000000 --- a/chromium/chrome/browser/resources/chrome_urls_disabled_page/app.html +++ /dev/null @@ -1,62 +0,0 @@ -<!doctype html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> - <head> - <meta charset="utf-8"> - <meta name="viewport" - content="initial-scale=1, minimum-scale=1,width=device-width"> - <title>$i18n{disabledPageHeader}</title> - <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="chrome://resources/cr_elements/icons.html"> - <link rel="import" href="chrome://resources/html/i18n_behavior.html"> - <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> - <style> - body { - --header-color: #202124; - --paragraph-color: #5f6368; - --iron-icon-width: 40px; - --iron-icon-height: 40px; - font-family: sans-serif; - padding: 24px 24px 20px 24px; - } - - h1 { - color: var(--header-color); - font-size: 30px; - font-weight: normal; - margin-bottom: 16px; - } - - p { - color: var(--paragraph-color); - font-size: 20px; - } - - .frame-disabled { - margin: 100px auto 0; - text-align: center; - } - - .information-container { - display: inline-block; - font-size: 125%; - letter-spacing: -0.35px; - text-align: start; - } - - #main-message { - margin-top: 36px; - } - </style> - </head> - <body id="chrome-urls-disabled-block"> - <div class="frame-disabled"> - <div class="information-container"> - <iron-icon icon="cr:domain" size="24"></iron-icon> - <div id="main-message"> - <h1 id="disabled-page-header">$i18n{disabledPageTitle}</h1> - <p id="disabled-message"> $i18n{disabledPageMessage}</p> - </div> - </div> - </div> - </body> -</html> diff --git a/chromium/chrome/browser/resources/chromeos/BUILD.gn b/chromium/chrome/browser/resources/chromeos/BUILD.gn index 675d9ee14d8..f7fe84ec09e 100644 --- a/chromium/chrome/browser/resources/chromeos/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/BUILD.gn @@ -36,19 +36,24 @@ grit("multidevice_setup_resources") { group("closure_compile") { deps = [ + "accessibility/accessibility_common:closure_compile", "accessibility/braille_ime:closure_compile", "accessibility/select_to_speak:closure_compile", "accessibility/switch_access:closure_compile", + "account_manager:closure_compile", + "account_manager/components:closure_compile", "add_supervision:closure_compile", "bluetooth_pairing_dialog:closure_compile", "crostini_installer:closure_compile", "edu_login:closure_compile", "emulator:closure_compile", + "gaia_action_buttons:closure_compile", "internet_config_dialog:closure_compile", "internet_detail_dialog:closure_compile", "login:closure_compile", "login/components:closure_compile", "machine_learning:closure_compile", + "multidevice_internals:closure_compile", "multidevice_setup:closure_compile", "network_ui:closure_compile", "set_time_dialog:closure_compile", diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/BUILD.gn index 31961f1aae2..7baa912e6c1 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/BUILD.gn @@ -4,6 +4,7 @@ import("//build/config/features.gni") import("//chrome/common/features.gni") +import("//chrome/test/base/js2gtest.gni") import("//chromecast/chromecast.gni") import("strings/accessibility_strings.gni") @@ -69,7 +70,7 @@ manifest("accessibility_common_manifest") { manifest("accessibility_common_guest_manifest") { input_file = "accessibility_common_manifest.json.jinja2" output_file = - "$accessibility_out_dir/accessibility_common_guest_manifest.json" + "$accessibility_out_dir/accessibility_common_manifest_guest.json" key = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6SX/t6kDEi9UiG4fULwjbEW1uJmQoiJPtxvSZ/SDH14OjSzmfP6xfE97Hus3EY8uSIMxTHkGaZliGbFbIQXQn6/XwBpQRu2gPlrfz7TWR1Hw6SboBBMOpltM9A2nx+d3jLtz+YtKNYVcHyNil9hXfFeyFe6g5kLHapKb1UO0jo3q3kovo1a1z7ujzGwogfLmb58w1hkdFBnnqumRlT55dKLN8AQ6cSdB1sjDVoMgPYeWgkzXr9cR3A8UVJookSO0sDAmD+W8BtBijapt3UVkHiIL1NTPuXvGGUHL7TPFo5WcBXFMkTz74gJqqFdO5hQ2YWXAaCxQJwgJrQPrvPMSJAgMBAAECggEADDhEDww9wWbWzUz3BQEs2In1HrOgAFStN3zEkNFc9B78AJsvpXWczgPUqk9jrg1JzkUeghlK/mDWT8MNkkdQ4kmFMYCM9/jOI6+kU3js+arxlzU84VI5r4c4RhlSOtBEMOHjF0DORP3sopMXOxPAbYjXog3xhA0szYXdedwcIik7Xu3lt1Hl5FfVZbvVLdf4vw0jTfHcp8SmHy/BDVnSCrhC3pnPGi6o+lUaSK0ca3uvcJDZGLXJ/6LyFb6uLlS2XUoBMYsombioRKrerJJSOmMTLHvfu1cM6+iQ+J0wdBnJQpgmDoSVGjnksPU2SMpWgG2OzwuZYIUGI745s19wLQKBgQDvdHsMZ4ttBr9bjydzeZVATWTICHZgXdAYgfgrbGwppYDUjfKoAuJ6bHTvff4nj8aZrY+Y1SwuvqxgHHfiggUgqg+JyeaAdQG+CLdfl1M8An+6H0x/hx0nk0oOJQhu0y1R/SbtnDJ6JASszg/VrTwHIYbzUl6xKHbZ6X41apyLYwKBgQDHKJOeZdxuYj7AsAqFGreuPoAEh0S+2VHHi4rjNz5dC1z7o/8siixfkHg7ONM2hqCKo55XYj4UWtprEFZJ9ohbizHELNzpnTxjdS0cG/VfItml6CDJaUtrkShIx17yGjNi0u/7ywHQ3slJsUXu7CbEcESwEzdoSrsC048dyxBSIwKBgF0141wtxklXcg/LBtldf6q7NbrkCGh0vDd+CEOm/eesRBz5cHbUQKLVKyO60L9HqVBTDm24tW0wzdrP2h7y69oOOOQzEqX4Zgg6Tl9IgZ7/fgbOfjG6P7ATFqWw5rp1O9QJjii6P6/p62P1Bpbvy0kfVO/MpY2iqbkjufxDFtLvAoGBAMC5p4CVGedH82oL8WI1JKLdoIzBSelV7CmqA9E1WIg5wtVRMlIrtB0WdQL6ToppZVpEU6pES8bu1Ibe3GHezL2pyZMJxw3bNuEYN3sIIz7ZPr2qEHBYEMAbTFyBcoPejvOHJO0I2s0BitBhWEeJB0r5Sb8KGYg3KRnnGIvAQh75AoGBANEC/k1umGrnMO3rwHJF7R+aTHzeMnO6oi11pmSnT7eJcF+oi7OwHS3ickU6sGrIb5QmnwCY9ES1qY6mP7N++KQGsdQM2l13MpCn8cBZgrfpQg2slP1dz8LCDW/PB+6MF7qwEHN2afVA2muQaez+q0eXZjMXmGJ3VZIXz/cxBLD6" is_guest_manifest = true } @@ -129,3 +130,36 @@ group("browser_tests") { ] } } + +group("unit_tests_js") { + testonly = true + if (is_chromeos) { + deps = [ + ":misc_unit_tests_js", + "chromevox:chromevox_unit_js_tests", + ] + } +} + +js2gtest("misc_unit_tests_js") { + test_type = "unit" + sources = [ + "braille_ime/braille_ime_unittest.js", + "select_to_speak/node_utils_unittest.js", + "select_to_speak/paragraph_utils_unittest.js", + "select_to_speak/rect_utils_unittest.js", + "select_to_speak/select_to_speak_unittest.js", + "select_to_speak/word_utils_unittest.js", + "switch_access/rect_helper_unittest.js", + ] + extra_js_files = [ + "braille_ime/braille_ime.js", + "select_to_speak/paragraph_utils.js", + "select_to_speak/rect_utils.js", + "select_to_speak/select_to_speak.js", + "select_to_speak/test_support.js", + "select_to_speak/word_utils.js", + "select_to_speak/node_utils.js", + "switch_access/rect_helper.js", + ] +} diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn index 9cb8ce6e600..6bad1429751 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn @@ -25,6 +25,7 @@ run_jsbundler("accessibility_common_copied_files") { sources = [ "accessibility_common_loader.js", "autoclick/autoclick.js", + "magnifier/magnifier.js", ] rewrite_rules = [ rebase_path(".", root_build_dir) + ":", @@ -56,10 +57,14 @@ source_set("browser_tests") { js2gtest("accessibility_common_extjs_tests") { test_type = "extension" - sources = [ "autoclick_test.js" ] + sources = [ + "accessibility_common_test.js", + "autoclick/autoclick_test.js", + ] gen_include_files = [ "../common/testing/callback_helper.js", - "mock_accessibility_private.js", + "../common/testing/e2e_test_base.js", + "../common/testing/mock_accessibility_private.js", ] # The test base classes generate C++ code with these deps. @@ -78,10 +83,26 @@ js_type_check("closure_compile") { } js_library("accessibility_common") { - deps = [] + sources = [ "accessibility_common_loader.js" ] + deps = [ + ":autoclick", + ":magnifier", + ] + externs_list = [ + "$externs_path/chrome_extensions.js", + "$externs_path/accessibility_private.js", + "$externs_path/automation.js", + ] +} + +js_library("autoclick") { + sources = [ "autoclick/autoclick.js" ] externs_list = [ "$externs_path/accessibility_private.js", "$externs_path/automation.js", - "$externs_path/accessibility_features.js", ] } + +js_library("magnifier") { + sources = [ "magnifier/magnifier.js" ] +} diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 4b6d105774b..098db904966 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn @@ -66,7 +66,7 @@ chromevox_modules = [ "background/logging/tree_dumper.js", "background/math_handler.js", "background/media_automation_handler.js", - "background/mouse_handler.js", + "background/pointer_handler.js", "background/next_earcons.js", "background/notifications.js", "background/output.js", @@ -77,6 +77,7 @@ chromevox_modules = [ "background/recovery_strategy.js", "background/smart_sticky_mode.js", "background/tabs_api_handler.js", + "background/user_action_monitor.js", "braille/bluetooth_braille_display_manager.js", "braille/bluetooth_braille_display_ui.js", "braille/braille_display_manager.js", @@ -195,6 +196,7 @@ run_jsbundler("chromevox_copied_files") { "i_tutorial/components/tutorial_lesson.js", "i_tutorial/lessons/basic_navigation.html", "i_tutorial/lessons/jump_commands.html", + "i_tutorial/lessons/selects.html", "i_tutorial/lessons/text_fields.html", "images/chromevox-128.png", "images/chromevox-16.png", @@ -338,8 +340,8 @@ if (is_chromeos) { assert(enable_extensions) deps = [ - ":chromevox_extjs_tests", - ":chromevox_unitjs_tests", + ":chromevox_extension_js_tests", + ":chromevox_webui_js_tests", ] # TODO(jamescook): Figure out which of these are really necessary. @@ -387,23 +389,49 @@ if (is_chromeos) { deps = [ ":chromevox_test_messages_js" ] } - js2gtest("chromevox_unitjs_tests") { - test_type = "webui" + # These tests can run in a pure V8 renderer (e.g. no DOM). + js2gtest("chromevox_unit_js_tests") { + test_type = "unit" sources = [ - "braille/bluetooth_braille_display_manager_test.js", - "braille/bluetooth_braille_display_ui_test.js", - "braille/braille_display_manager_test.js", - "braille/braille_input_handler_test.js", "braille/expanding_braille_translator_test.js", "braille/pan_strategy_test.js", "common/key_sequence_test.js", "common/spannable_test.js", "testing/mock_feedback_test.js", ] + extra_js_files = [ + "../common/testing/assert_additions.js", + "../common/testing/callback_helper.js", + "braille/expanding_braille_translator.js", + "braille/nav_braille.js", + "braille/pan_strategy.js", + "braille/spans.js", + "braille/liblouis.js", + "common/abstract_earcons.js", + "common/braille_interface.js", + "common/chromevox.js", + "common/key_sequence.js", + "common/spannable.js", + "common/tts_interface.js", + "testing/fake_dom.js", + "testing/mock_feedback.js", + ] + } + + # These tests need a Blink renderer (e.g. DOM), but not a full extension + # renderer. + js2gtest("chromevox_webui_js_tests") { + test_type = "webui" + sources = [ + "braille/bluetooth_braille_display_manager_test.js", + "braille/bluetooth_braille_display_ui_test.js", + "braille/braille_display_manager_test.js", + "braille/braille_input_handler_test.js", + ] gen_include_files = [ "../common/testing/assert_additions.js", "../common/testing/callback_helper.js", - "testing/chromevox_unittest_base.js", + "testing/chromevox_webui_test_base.js", "testing/mock_feedback.js", ] test_deps_js_outputs = get_target_outputs(":chromevox_test_deps_js") @@ -412,7 +440,8 @@ if (is_chromeos) { defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } - js2gtest("chromevox_extjs_tests") { + # These tests need a full extension renderer. + js2gtest("chromevox_extension_js_tests") { test_type = "extension" sources = [ "background/annotation/node_identifier_test.js", @@ -431,10 +460,12 @@ if (is_chromeos) { "background/portals_test.js", "background/recovery_strategy_test.js", "background/smart_sticky_mode_test.js", + "background/user_action_monitor_test.js", "braille/braille_table_test.js", "braille/braille_translator_manager_test.js", "braille/liblouis_test.js", "common/tts_background_test.js", + "learn_mode/learn_mode_test.js", "options/options_test.js", "panel/i_search_test.js", "panel/panel_test.js", @@ -442,6 +473,7 @@ if (is_chromeos) { gen_include_files = [ "../common/testing/assert_additions.js", "../common/testing/callback_helper.js", + "../common/testing/e2e_test_base.js", "testing/chromevox_e2e_test_base.js", "testing/chromevox_next_e2e_test_base.js", "testing/mock_feedback.js", diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn index af38f4fb21f..cedc32306e7 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn @@ -29,7 +29,9 @@ run_jsbundler("accessibility_common_copied_files") { "automation_util.js", "closure_shim.js", "constants.js", + "event_handler.js", "repeated_event_handler.js", + "repeated_tree_change_handler.js", "tree_walker.js", ] rewrite_rules = [ rebase_path(".", root_build_dir) + ":" ] @@ -79,10 +81,18 @@ js_library("automation_util") { ] } +js_library("event_handler") { + externs_list = [ "$externs_path/automation.js" ] +} + js_library("repeated_event_handler") { externs_list = [ "$externs_path/automation.js" ] } +js_library("repeated_tree_change_handler") { + externs_list = [ "$externs_path/automation.js" ] +} + source_set("browser_tests") { testonly = true assert(enable_extensions) @@ -114,6 +124,7 @@ js2gtest("accessibility_tests") { "array_util_test.js", "automation_util_test.js", "repeated_event_handler_test.js", + "repeated_tree_change_handler_test.js", "tree_walker_test.js", ] gen_include_files = [ @@ -123,6 +134,8 @@ js2gtest("accessibility_tests") { "array_util.js", "testing/assert_additions.js", "testing/callback_helper.js", + "testing/doc_utils.js", + "testing/e2e_test_base.js", ] if (is_chromeos) { diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn index 63356e98621..bc257dc5d79 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/select_to_speak/BUILD.gn @@ -75,12 +75,14 @@ source_set("browser_tests") { js2gtest("select_to_speak_extjs_tests") { test_type = "extension" sources = [ + "paragraph_utils_overflow_test.js", "select_to_speak_keystroke_selection_test.js", "select_to_speak_mouse_selection_test.js", "select_to_speak_prefs_test.js", ] gen_include_files = [ "../common/testing/callback_helper.js", + "../common/testing/e2e_test_base.js", "mock_storage.js", "mock_tts.js", "select_to_speak_e2e_test_base.js", diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp b/chromium/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp index c7bf4b862b0..55ce0b4113d 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp +++ b/chromium/chrome/browser/resources/chromeos/accessibility/strings/chromevox_strings.grdp @@ -2308,8 +2308,8 @@ <message desc="Hint for how to start editing a text field while exploring the screen using touch exploration." name="IDS_CHROMEVOX_HINT_DOUBLE_TAP_TO_EDIT"> Double tap to start editing </message> - <message desc="Describes Learn Mode when the mode is initially entered." name="IDS_CHROMEVOX_LEARN_MODE_INTRO"> - Starting Learn Mode. Press a qwerty key, refreshable braille key, or touch gesture to learn its function. Press control with w or escape to exit. + <message desc="Describes Learn Mode when the mode is initially entered with text-to-speech." name="IDS_CHROMEVOX_LEARN_MODE_INTRO" is_accessibility_with_no_ui="true"> + Press a qwerty key, refreshable braille key, or touch gesture to learn its function. Press control with w or escape to exit. </message> <message desc="Output when leaving Learn Mode." name="IDS_CHROMEVOX_LEARN_MODE_OUTTRO"> Stopping Learn Mode @@ -2981,5 +2981,14 @@ <message desc="The text label for the use pitch changes checkbox." name="IDS_CHROMEVOX_OPTIONS_USE_PITCH_CHANGES_CHECKBOX_LABEL"> Change pitch when speaking element types and quoted, deleted, bolded, parenthesized, or capitalized text. </message> + <message desc="Describes the current web page position of the ChromeVox focus." is_accessibility_with_no_ui="true" name="IDS_CHROMEVOX_DESCRIBE_POS_BY_PAGE"> + Page <ph name="currentPage">$1<ex>1</ex></ph> of <ph name="totalPages">$2<ex>10</ex></ph> + </message> + <message desc="Describes a gesture to be performed on a touch screen. The gesture is to touch and drag with one finger and have items under the finger read using text-to-speech. No associated UI with this string which is spoken using text-to-speech." name="IDS_CHROMEVOX_TOUCH_EXPLORE_GESTURE" is_accessibility_with_no_ui="true"> + Touch explore + </message> + <message desc="Describes the media play/pause key on a Chromebook. No associated UI with this string which is spoken using text-to-speech." name="IDS_CHROMEVOX_MEDIA_PLAY_PAUSE" is_accessibility_with_no_ui="true"> + Media Play/Pause + </message> </grit-part> diff --git a/chromium/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn b/chromium/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn index 8f75b17ff43..eaa633ae635 100644 --- a/chromium/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/accessibility/switch_access/BUILD.gn @@ -27,6 +27,7 @@ run_jsbundler("switch_access_copied_files") { sources = [ "auto_scan_manager.js", "background.js", + "cache.js", "commands.js", "event_helper.js", "focus_ring_manager.js", @@ -133,6 +134,7 @@ js_type_check("closure_compile") { ":auto_scan_manager", ":back_button_node", ":background", + ":cache", ":combo_box_node", ":commands", ":desktop_node", @@ -161,6 +163,7 @@ js_type_check("closure_compile") { "../common:closure_shim", "../common:constants", "../common:repeated_event_handler", + "../common:repeated_tree_change_handler", "../common:tree_walker", ] } @@ -187,6 +190,10 @@ js_library("back_button_node") { ] } +js_library("cache") { + externs_list = [ "$externs_path/automation.js" ] +} + js_library("combo_box_node") { sources = [ "nodes/combo_box_node.js" ] deps = [ @@ -255,6 +262,7 @@ js_library("group_node") { js_library("history") { deps = [ + ":cache", ":desktop_node", ":node_wrapper", ":switch_access_node", @@ -323,6 +331,8 @@ js_library("navigation_manager") { ":switch_access_constants", ":switch_access_node", ":switch_access_predicate", + "../common:automation_util", + "../common:event_handler", "../common:repeated_event_handler", ] externs_list = [ @@ -335,6 +345,7 @@ js_library("node_wrapper") { sources = [ "nodes/node_wrapper.js" ] deps = [ ":back_button_node", + ":cache", ":switch_access_constants", ":switch_access_node", ":switch_access_predicate", @@ -401,6 +412,7 @@ js_library("switch_access_node") { js_library("switch_access_predicate") { deps = [ + ":cache", ":switch_access_constants", ":switch_access_node", "../common:automation_predicate", diff --git a/chromium/chrome/browser/resources/chromeos/account_manager/BUILD.gn b/chromium/chrome/browser/resources/chromeos/account_manager/BUILD.gn new file mode 100644 index 00000000000..ea22e436f81 --- /dev/null +++ b/chromium/chrome/browser/resources/chromeos/account_manager/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ + ":account_manager_browser_proxy", + ":account_manager_error_app", + ":account_manager_welcome_app", + ":account_migration_welcome_app", + ] +} + +js_library("account_manager_welcome_app") { + deps = [ + ":account_manager_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("account_migration_welcome_app") { + deps = [ + ":account_manager_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + +js_library("account_manager_error_app") { + deps = [ + ":account_manager_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + +js_library("account_manager_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/chrome_send.js" ] +} + +html_to_js("web_components") { + js_files = [ + "account_manager_shared_css.js", + "account_manager_welcome_app.js", + "account_migration_welcome_app.js", + "account_manager_error_app.js", + ] +} diff --git a/chromium/chrome/browser/resources/chromeos/account_manager/components/BUILD.gn b/chromium/chrome/browser/resources/chromeos/account_manager/components/BUILD.gn new file mode 100644 index 00000000000..7172392b685 --- /dev/null +++ b/chromium/chrome/browser/resources/chromeos/account_manager/components/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ ":error_screen" ] +} + +js_library("error_screen") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +html_to_js("web_components") { + js_files = [ "error_screen.js" ] +} diff --git a/chromium/chrome/browser/resources/chromeos/edu_login/BUILD.gn b/chromium/chrome/browser/resources/chromeos/edu_login/BUILD.gn index 842582276e7..c3799270451 100644 --- a/chromium/chrome/browser/resources/chromeos/edu_login/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/edu_login/BUILD.gn @@ -17,6 +17,7 @@ js_type_check("closure_compile") { ":browser_proxy", ":edu_login_button", ":edu_login_coexistence_info", + ":edu_login_error", ":edu_login_parent_info", ":edu_login_parent_signin", ":edu_login_parents", @@ -105,6 +106,7 @@ js_library("edu_login_parent_info") { js_library("edu_login_signin") { deps = [ + ":browser_proxy", ":edu_login_button", ":edu_login_template", "//chrome/browser/resources/gaia_auth_host:authenticator.m", @@ -114,6 +116,16 @@ js_library("edu_login_signin") { ] } +js_library("edu_login_error") { + deps = [ + ":browser_proxy", + ":edu_login_button", + ":edu_login_template", + "//chrome/browser/resources/chromeos/account_manager/components:error_screen", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + polymer_modulizer("app") { js_file = "app.js" html_file = "app.html" @@ -174,12 +186,19 @@ polymer_modulizer("edu_login_signin") { html_type = "v3-ready" } +polymer_modulizer("edu_login_error") { + js_file = "edu_login_error.js" + html_file = "edu_login_error.html" + html_type = "v3-ready" +} + group("polymer3_elements") { public_deps = [ ":app_module", ":edu_login_button_module", ":edu_login_coexistence_info_module", ":edu_login_css_module", + ":edu_login_error_module", ":edu_login_parent_info_module", ":edu_login_parent_signin_module", ":edu_login_parents_module", diff --git a/chromium/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn b/chromium/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn new file mode 100644 index 00000000000..e3feb028e1e --- /dev/null +++ b/chromium/chrome/browser/resources/chromeos/gaia_action_buttons/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/gaia_auth_host/", + "js_module_root=./gen/chrome/browser/resources/gaia_auth_host/", + ] + deps = [ ":gaia_action_buttons" ] +} + +js_library("gaia_action_buttons") { + deps = [ + "//chrome/browser/resources/gaia_auth_host:authenticator.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + ] +} + +html_to_js("web_components") { + js_files = [ "gaia_action_buttons.js" ] +} diff --git a/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn b/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn index af80c45ce88..1e2776b1380 100644 --- a/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn @@ -23,9 +23,9 @@ js_type_check("closure_compile") { js_library("internet_config_dialog") { deps = [ + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:network_config", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", ] diff --git a/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn b/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn index a4dd8090983..1f92f2e5320 100644 --- a/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn @@ -23,9 +23,9 @@ js_type_check("closure_compile") { js_library("internet_detail_dialog") { deps = [ + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", ] diff --git a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn index 6e02f0073a2..97113d3284b 100644 --- a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn @@ -13,6 +13,7 @@ js_type_check("closure_compile") { ":demo_preferences", ":demo_setup", ":encryption_migration", + ":family_link_notice", ":fingerprint_setup", ":gaia_buttons", ":gaia_card", @@ -42,6 +43,7 @@ js_type_check("closure_compile") { ":sync_consent", ":throbber_notice", ":update_required_card", + ":user_creation", ] } @@ -57,6 +59,7 @@ js_library("oobe_welcome") { "components:login_screen_behavior", "components:oobe_dialog_host_behavior", "components:oobe_i18n_behavior", + "//ui/webui/resources/js/cr/ui:dialogs", ] } @@ -119,6 +122,14 @@ js_library("encryption_migration") { ] } +js_library("family_link_notice") { + deps = [ + "components:login_screen_behavior", + "components:oobe_dialog_host_behavior", + "components:oobe_i18n_behavior", + ] +} + js_library("fingerprint_setup") { deps = [ "components:oobe_dialog_host_behavior", @@ -206,6 +217,8 @@ js_library("oobe_enable_kiosk") { js_library("oobe_eula") { deps = [ + ":web_view_helper", + "components:login_screen_behavior", "components:oobe_dialog", "components:oobe_dialog_host_behavior", "components:oobe_i18n_behavior", @@ -255,6 +268,15 @@ js_library("recommend_apps") { ] } +js_library("user_creation") { + deps = [ + "components:login_screen_behavior", + "components:multi_step_behavior", + "components:oobe_dialog_host_behavior", + "components:oobe_i18n_behavior", + ] +} + js_library("saml_confirm_password") { deps = [ "components:oobe_dialog_host_behavior", @@ -274,3 +296,6 @@ js_library("throbber_notice") { js_library("update_required_card") { } + +js_library("web_view_helper") { +} diff --git a/chromium/chrome/browser/resources/chromeos/login/components/BUILD.gn b/chromium/chrome/browser/resources/chromeos/login/components/BUILD.gn index a104ef10d39..da383bc7f08 100644 --- a/chromium/chrome/browser/resources/chromeos/login/components/BUILD.gn +++ b/chromium/chrome/browser/resources/chromeos/login/components/BUILD.gn @@ -13,6 +13,7 @@ js_type_check("closure_compile") { ":login_screen_behavior", ":multi_step_behavior", ":oobe_buttons", + ":oobe_carousel", ":oobe_dialog", ":oobe_dialog_host_behavior", ":oobe_help_dialog", @@ -72,6 +73,9 @@ js_library("oobe_help_dialog") { deps = [ ":oobe_i18n_behavior" ] } +js_library("oobe_carousel") { +} + js_library("hd-iron-icon") { } diff --git a/chromium/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn b/chromium/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn new file mode 100644 index 00000000000..919056d2c6a --- /dev/null +++ b/chromium/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ ":multidevice_internals" ] +} + +js_library("multidevice_internals") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +html_to_js("web_components") { + js_files = [ "multidevice_internals.js" ] +} diff --git a/chromium/chrome/browser/resources/chromeos/multidevice_internals/multidevice_internals_resources.grd b/chromium/chrome/browser/resources/chromeos/multidevice_internals/multidevice_internals_resources.grd new file mode 100644 index 00000000000..e556ece55e9 --- /dev/null +++ b/chromium/chrome/browser/resources/chromeos/multidevice_internals/multidevice_internals_resources.grd @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/multidevice_internals_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/multidevice_internals_resources_map.cc" + type="resource_file_map_source" /> + <output filename="grit/multidevice_internals_resources_map.h" + type="resource_map_header" /> + <output filename="multidevice_internals_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <includes> + <include name="IDR_MULTIDEVICE_INTERNALS_INDEX_HTML" + file="index.html" + type="BINDATA"/> + <include name="IDR_MULTIDEVICE_INTERNALS_MULTIDEVICE_INTERNALS_JS" + file="${root_gen_dir}\chrome\browser\resources\chromeos\multidevice_internals\multidevice_internals.js" + use_base_dir="false" + type="BINDATA"/> + </includes> + </release> +</grit> diff --git a/chromium/chrome/browser/resources/component_extension_resources.grd b/chromium/chrome/browser/resources/component_extension_resources.grd index 7989a4c8ebe..d75aad3cbfa 100644 --- a/chromium/chrome/browser/resources/component_extension_resources.grd +++ b/chromium/chrome/browser/resources/component_extension_resources.grd @@ -118,12 +118,17 @@ <include name="IDR_PDF_GESTURE_DETECTOR_JS" file="pdf/gesture_detector.js" type="BINDATA" /> <include name="IDR_PDF_BROWSER_API_JS" file="pdf/browser_api.js" type="BINDATA" /> <include name="IDR_PDF_METRICS_JS" file="pdf/metrics.js" type="BINDATA" /> + <include name="IDR_PDF_LOCAL_STORAGE_PROXY_JS" file="pdf/local_storage_proxy.js" type="BINDATA" /> + <include name="IDR_PDF_ELEMENTS_SHARED_CSS_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/shared-css.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_SHARED_VARS_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/shared-vars.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_ICONS_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/icons.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_VIEWER_BOOKMARK_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-bookmark.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_PDF_VIEWER_DOCUMENT_OUTLINE_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-document-outline.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_PDF_VIEWER_DOWNLOADS_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-download-controls.js" use_base_dir="false" type="BINDATA"/> <include name="IDR_PDF_VIEWER_ERROR_SCREEN_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-error-screen.js" use_base_dir="false" type="BINDATA" /> <if expr="chromeos"> + <include name="IDR_PDF_VIEWER_ANNOTATIONS_BAR_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js" use_base_dir="false" type="BINDATA"/> <include name="IDR_PDF_VIEWER_INK_CONTROLLER_JS" file="pdf/ink_controller.js" type="BINDATA" /> <include name="IDR_PDF_VIEWER_INK_INDEX_HTML" file="pdf/ink/index.html" type="BINDATA" /> <include name="IDR_PDF_VIEWER_INK_INK_API_JS" file="pdf/ink/ink_api.js" type="BINDATA" /> @@ -133,8 +138,11 @@ </if> <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-page-selector.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-password-screen.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_PDF_VIEWER_PDF_SIDENAV_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.js" use_base_dir="false" type="BINDATA"/> <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js" use_base_dir="false" type="BINDATA" preprocess="true"/> <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_NEW_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js" use_base_dir="false" type="BINDATA" preprocess="true"/> + <include name="IDR_PDF_VIEWER_THUMBNAIL_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-thumbnail.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_PDF_VIEWER_THUMBNAIL_BAR_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_VIEWER_ZOOM_BUTTON_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-zoom-button.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js" use_base_dir="false" type="BINDATA" /> diff --git a/chromium/chrome/browser/resources/discards/database_tab.js b/chromium/chrome/browser/resources/discards/database_tab.js index c93db1e49ac..893b0710130 100644 --- a/chromium/chrome/browser/resources/discards/database_tab.js +++ b/chromium/chrome/browser/resources/discards/database_tab.js @@ -15,10 +15,8 @@ import {SortedTableBehavior} from './sorted_table_behavior.js'; /** * Compares two db rows by their origin. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -28,10 +26,8 @@ function compareRowsByOrigin(a, b) { /** * Compares two db rows by their dirty bit. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -41,10 +37,8 @@ function compareRowsByIsDirty(a, b) { /** * Compares two db rows by their last load time. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -54,10 +48,8 @@ function compareRowsByLastLoaded(a, b) { /** * Compares two db rows by their CPU usage. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -71,10 +63,8 @@ function compareRowsByCpuUsage(a, b) { /** * Compares two db rows by their memory usage. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -88,10 +78,8 @@ function compareRowsByMemoryUsage(a, b) { /** * Compares two db rows by their load duration. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value - * being compared. - * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value - * being compared. + * @param {discards.mojom.SiteDataEntry} a The first value being compared. + * @param {discards.mojom.SiteDataEntry} b The second value being compared. * @return {number} A negative number if a < b, 0 if a === b, and a positive * number if a > b. */ @@ -107,8 +95,8 @@ function compareRowsByLoadDuration(a, b) { /** * @param {string} sortKey The sort key to get a function for. - * @return {function(discards.mojom.SiteCharacteristicsDatabaseEntry, - discards.mojom.SiteCharacteristicsDatabaseEntry): number} + * @return {function(discards.mojom.SiteDataEntry, + discards.mojom.SiteDataEntry): number} * A comparison function that compares two tab infos, returns * negative number if a < b, 0 if a === b, and a positive * number if a > b. @@ -196,7 +184,7 @@ Polymer({ properties: { /** * List of database rows. - * @private {?Array<!discards.mojom.SiteCharacteristicsDatabaseEntry>} + * @private {?Array<!discards.mojom.SiteDataEntry>} */ rows_: { type: Array, @@ -204,7 +192,7 @@ Polymer({ /** * The database size response. - * @private {!discards.mojom.SiteCharacteristicsDatabaseSize} + * @private {!discards.mojom.SiteDataDatabaseSize} */ size_: { type: Object, @@ -269,10 +257,9 @@ Polymer({ * @private */ updateDbRows_() { - this.siteDataProvider_ - .getSiteCharacteristicsDatabase(Object.keys(this.requestedOrigins_)) + this.siteDataProvider_.getSiteDataArray(Object.keys(this.requestedOrigins_)) .then(response => { - // Bail if the SiteCharacteristicsDatabase is turned off. + // Bail if the SiteData database is turned off. if (!response.result) { return; } @@ -325,14 +312,13 @@ Polymer({ * @private */ updateDbSizes_() { - this.siteDataProvider_.getSiteCharacteristicsDatabaseSize().then( - response => { - // Bail if the SiteCharacteristicsDatabase is turned off. - if (!response.dbSize) { - return; - } - this.size_ = response.dbSize; - }); + this.siteDataProvider_.getSiteDataDatabaseSize().then(response => { + // Bail if the SiteData database is turned off. + if (!response.dbSize) { + return; + } + this.size_ = response.dbSize; + }); }, /** @@ -402,8 +388,7 @@ Polymer({ }, /** - * @param {?discards.mojom.SiteCharacteristicsFeature} feature The feature - * in question. + * @param {?discards.mojom.SiteDataFeature} feature The feature in question. * @return {string} A human-readable string representing the feature. * @private */ diff --git a/chromium/chrome/browser/resources/downloads/item.html b/chromium/chrome/browser/resources/downloads/item.html index 9e23df600dc..380122117da 100644 --- a/chromium/chrome/browser/resources/downloads/item.html +++ b/chromium/chrome/browser/resources/downloads/item.html @@ -362,7 +362,7 @@ </cr-button> </div> </template> - <template is="dom-if" if="[[showOpenNow_]]"> + <template is="dom-if" if="[[showOpenNow_]]" restamp> <div role="gridcell"> <cr-button on-click="onOpenNowTap_" id="openNow" class="action-button" focus-row-control focus-type="open"> diff --git a/chromium/chrome/browser/resources/downloads/item.js b/chromium/chrome/browser/resources/downloads/item.js index e5d8ca93ccb..e371b926e64 100644 --- a/chromium/chrome/browser/resources/downloads/item.js +++ b/chromium/chrome/browser/resources/downloads/item.js @@ -327,24 +327,24 @@ Polymer({ if ((loadTimeData.getBoolean('requestsApVerdicts') && dangerType === DangerType.UNCOMMON_CONTENT) || dangerType === DangerType.SENSITIVE_CONTENT_WARNING) { - return 'cr:error'; + return 'cr:warning'; } - const WARNING_TYPES = [ + const ERROR_TYPES = [ DangerType.SENSITIVE_CONTENT_BLOCK, DangerType.BLOCKED_TOO_LARGE, DangerType.BLOCKED_PASSWORD_PROTECTED, ]; - if (WARNING_TYPES.includes(dangerType)) { - return 'cr:warning'; + if (ERROR_TYPES.includes(dangerType)) { + return 'cr:error'; } if (this.data.state === States.ASYNC_SCANNING) { - return 'cr:error'; + return 'cr:info'; } } if (this.isDangerous_) { - return 'cr:warning'; + return 'cr:error'; } if (!this.useFileIcon_) { return 'cr:insert-drive-file'; @@ -498,7 +498,8 @@ Polymer({ * @private */ computeShowOpenNow_() { - return this.data.state === States.ASYNC_SCANNING; + const allowOpenNow = loadTimeData.getBoolean('allowOpenNow'); + return this.data.state === States.ASYNC_SCANNING && allowOpenNow; }, /** diff --git a/chromium/chrome/browser/resources/downloads/toolbar.html b/chromium/chrome/browser/resources/downloads/toolbar.html index b87845dcdde..3ddb6312d99 100644 --- a/chromium/chrome/browser/resources/downloads/toolbar.html +++ b/chromium/chrome/browser/resources/downloads/toolbar.html @@ -20,7 +20,7 @@ } } </style> -<cr-toolbar id="toolbar" page-name="$i18n{title}" +<cr-toolbar id="toolbar" page-name="$i18n{title}" autofocus search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}" spinner-active="{{spinnerActive}}" on-search-changed="onSearchChanged_"> <cr-icon-button id="moreActions" iron-icon="cr:more-vert" diff --git a/chromium/chrome/browser/resources/extensions/BUILD.gn b/chromium/chrome/browser/resources/extensions/BUILD.gn index 53ed19cc2b6..7f06e62ed6c 100644 --- a/chromium/chrome/browser/resources/extensions/BUILD.gn +++ b/chromium/chrome/browser/resources/extensions/BUILD.gn @@ -100,10 +100,6 @@ html_to_js("web_components_local") { } js_type_check("extensions_module_resources") { - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/extensions/", - "js_module_root=./gen/chrome/browser/resources/extensions/", - ] is_polymer3 = true deps = [ ":checkup", diff --git a/chromium/chrome/browser/resources/extensions/activity_log/BUILD.gn b/chromium/chrome/browser/resources/extensions/activity_log/BUILD.gn index c0eff544781..8ceba341a71 100644 --- a/chromium/chrome/browser/resources/extensions/activity_log/BUILD.gn +++ b/chromium/chrome/browser/resources/extensions/activity_log/BUILD.gn @@ -16,10 +16,6 @@ html_to_js("web_components") { } js_type_check("closure_compile_module") { - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/extensions/", - "js_module_root=./gen/chrome/browser/resources/extensions/", - ] is_polymer3 = true deps = [ ":activity_log", diff --git a/chromium/chrome/browser/resources/extensions/detail_view.html b/chromium/chrome/browser/resources/extensions/detail_view.html index 04c47dbf7cc..fc42d3289b4 100644 --- a/chromium/chrome/browser/resources/extensions/detail_view.html +++ b/chromium/chrome/browser/resources/extensions/detail_view.html @@ -144,8 +144,8 @@ <div class="layout horizontal"> <cr-tooltip-icon hidden$="[[!data.controlledInfo]]" tooltip-text="[[data.controlledInfo.text]]" - icon-class="[[getIndicatorIcon_(data.controlledInfo.type)]]" - icon-aria-label="[[data.controlledInfo.type]]"> + icon-class="cr20:domain" + icon-aria-label="[[data.controlledInfo.text]]"> </cr-tooltip-icon> <template is="dom-if" if="[[showReloadButton_(data.state)]]"> <cr-button id="terminated-reload-button" class="action-button" diff --git a/chromium/chrome/browser/resources/extensions/detail_view.js b/chromium/chrome/browser/resources/extensions/detail_view.js index fc461db137c..36602faefa9 100644 --- a/chromium/chrome/browser/resources/extensions/detail_view.js +++ b/chromium/chrome/browser/resources/extensions/detail_view.js @@ -305,20 +305,6 @@ Polymer({ }, /** - * @param {chrome.developerPrivate.ControllerType} type - * @return {string} - * @private - */ - getIndicatorIcon_(type) { - switch (type) { - case 'POLICY': - return 'cr20:domain'; - default: - return ''; - } - }, - - /** * @return {boolean} * @private */ diff --git a/chromium/chrome/browser/resources/extensions/item.js b/chromium/chrome/browser/resources/extensions/item.js index 51eb641791c..c7d165ae75a 100644 --- a/chromium/chrome/browser/resources/extensions/item.js +++ b/chromium/chrome/browser/resources/extensions/item.js @@ -409,11 +409,18 @@ Polymer({ */ computeDevReloadButtonHidden_() { // Only display the reload spinner if the extension is unpacked and - // enabled. There's no point in reloading a disabled extension, and we'll - // show a crashed reload button if it's terminated. + // enabled or disabled for reload. If an extension fails to reload (due to + // e.g. a parsing error), it will + // remain disabled with the "reloading" reason. We show the reload button + // when it's disabled for reload to enable developers to reload the fixed + // version. (Note that trying to reload an extension that is currently + // trying to reload is a no-op.) For other + // disableReasons, there's no point in reloading a disabled extension, and + // we'll show a crashed reload button if it's terminated. const showIcon = this.data.location === chrome.developerPrivate.Location.UNPACKED && - this.data.state === chrome.developerPrivate.ExtensionState.ENABLED; + (this.data.state === chrome.developerPrivate.ExtensionState.ENABLED || + this.data.disableReasons.reloading); return !showIcon; }, diff --git a/chromium/chrome/browser/resources/extensions/item_util.js b/chromium/chrome/browser/resources/extensions/item_util.js index 83e727c2641..d1a94327062 100644 --- a/chromium/chrome/browser/resources/extensions/item_util.js +++ b/chromium/chrome/browser/resources/extensions/item_util.js @@ -79,9 +79,7 @@ export function userCanChangeEnablement(item) { * @return {SourceType} */ export function getItemSource(item) { - if (item.controlledInfo && - item.controlledInfo.type === - chrome.developerPrivate.ControllerType.POLICY) { + if (item.controlledInfo) { return SourceType.POLICY; } @@ -169,7 +167,7 @@ export function getEnableControl(data) { if (isTerminated_(data.state)) { return EnableControl.RELOAD; } - if (data.disableReasons.corruptInstall) { + if (data.disableReasons.corruptInstall && data.userMayModify) { return EnableControl.REPAIR; } return EnableControl.ENABLE_TOGGLE; diff --git a/chromium/chrome/browser/resources/extensions/runtime_host_permissions.html b/chromium/chrome/browser/resources/extensions/runtime_host_permissions.html index 390e3e8c363..37a128b2126 100644 --- a/chromium/chrome/browser/resources/extensions/runtime_host_permissions.html +++ b/chromium/chrome/browser/resources/extensions/runtime_host_permissions.html @@ -54,7 +54,8 @@ <div id="section-heading"> <span>$i18n{hostPermissionsHeading}</span> <a class="link-icon-button" aria-label="$i18n{learnMore}" - href="$i18n{hostPermissionsLearnMoreLink}" target="_blank"> + href="$i18n{hostPermissionsLearnMoreLink}" target="_blank" + on-click="onLearnMoreClick_"> <iron-icon icon="cr:help-outline"></iron-icon> </a> </div> diff --git a/chromium/chrome/browser/resources/extensions/runtime_host_permissions.js b/chromium/chrome/browser/resources/extensions/runtime_host_permissions.js index a2b743b7de0..3ebaf22c6e2 100644 --- a/chromium/chrome/browser/resources/extensions/runtime_host_permissions.js +++ b/chromium/chrome/browser/resources/extensions/runtime_host_permissions.js @@ -102,6 +102,17 @@ Polymer({ }, /** + * Indicator to track if an onHostAccessChange_ event is coming from the + * setting being automatically reverted to the previous value, after a + * change to a new value was canceled. + * @private + */ + revertingHostAccess_: { + type: Boolean, + value: false, + }, + + /** * Proxying the enum to be used easily by the html template. * @private */ @@ -119,6 +130,25 @@ Polymer({ const group = /** @type {!HTMLElement} */ (this.$['host-access']); const access = group.selected; + // Log a user action when the host access selection is changed by the user, + // but not when reverting from a canceled change to another setting. + if (!this.revertingHostAccess_) { + switch (access) { + case chrome.developerPrivate.HostAccess.ON_CLICK: + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.OnClickSelected'); + break; + case chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES: + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.OnSpecificSitesSelected'); + break; + case chrome.developerPrivate.HostAccess.ON_ALL_SITES: + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.OnAllSitesSelected'); + break; + } + } + if (access === chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES && this.permissions.hostAccess !== chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES) { @@ -169,6 +199,8 @@ Polymer({ * @private */ onAddHostClick_(e) { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.AddHostActivated'); const target = /** @type {!HTMLElement} */ (e.target); this.doShowHostDialog_(target, null); }, @@ -199,9 +231,13 @@ Polymer({ onHostDialogCancel_() { // The user canceled the dialog. Set host-access back to the old value, // if the dialog was shown when just transitioning to a new state. + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.AddHostDialogCanceled'); if (this.oldHostAccess_) { assert(this.permissions.hostAccess === this.oldHostAccess_); + this.revertingHostAccess_ = true; this.$['host-access'].selected = this.oldHostAccess_; + this.revertingHostAccess_ = false; this.oldHostAccess_ = null; } }, @@ -222,6 +258,8 @@ Polymer({ * @private */ onEditHostClick_(e) { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.ActionMenuOpened'); this.actionMenuModel_ = e.model.item; this.actionMenuAnchorElement_ = e.target; const actionMenu = @@ -231,6 +269,8 @@ Polymer({ /** @private */ onActionMenuEditClick_() { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.ActionMenuEditActivated'); // Cache the site before closing the action menu, since it's cleared. const site = this.actionMenuModel_; @@ -246,6 +286,8 @@ Polymer({ /** @private */ onActionMenuRemoveClick_() { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.ActionMenuRemoveActivated'); this.delegate.removeRuntimeHostPermission( this.itemId, assert(this.actionMenuModel_, 'Action Menu Model')); this.closeActionMenu_(); @@ -263,4 +305,10 @@ Polymer({ this.actionMenuModel_ = null; this.actionMenuAnchorElement_ = null; }, + + /** @private */ + onLearnMoreClick_() { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.LearnMoreActivated'); + } }); diff --git a/chromium/chrome/browser/resources/extensions/runtime_hosts_dialog.js b/chromium/chrome/browser/resources/extensions/runtime_hosts_dialog.js index 35fa8ad87e7..0bfaa4c1d43 100644 --- a/chromium/chrome/browser/resources/extensions/runtime_hosts_dialog.js +++ b/chromium/chrome/browser/resources/extensions/runtime_hosts_dialog.js @@ -163,6 +163,8 @@ Polymer({ * @private */ onSubmitTap_() { + chrome.metricsPrivate.recordUserAction( + 'Extensions.Settings.Hosts.AddHostDialogSubmitted'); if (this.currentSite !== null) { this.handleEdit_(); } else { diff --git a/chromium/chrome/browser/resources/extensions/toolbar.html b/chromium/chrome/browser/resources/extensions/toolbar.html index fcc00263fd8..9048d724709 100644 --- a/chromium/chrome/browser/resources/extensions/toolbar.html +++ b/chromium/chrome/browser/resources/extensions/toolbar.html @@ -75,7 +75,7 @@ </style> <cr-toolbar page-name="$i18n{toolbarTitle}" search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}" menu-label="$i18n{mainMenu}" show-menu - narrow-threshold="1000"> + autofocus narrow-threshold="1000"> <div class="more-actions"> <span id="devModeLabel">$i18n{toolbarDevMode}</span> <cr-tooltip-icon hidden="[[!shouldDisableDevMode_( diff --git a/chromium/chrome/browser/resources/feed_internals/feed_internals.html b/chromium/chrome/browser/resources/feed_internals/feed_internals.html index 809dbee88bf..7f989775d93 100644 --- a/chromium/chrome/browser/resources/feed_internals/feed_internals.html +++ b/chromium/chrome/browser/resources/feed_internals/feed_internals.html @@ -52,6 +52,10 @@ found in the LICENSE file. <td>Feed Fetch URL</td> <td id="feed-fetch-url"></td> </tr> + <tr> + <td>Feed Actions URL</td> + <td id="feed-actions-url"></td> + </tr> </table> <h2>User Classifier</h2> @@ -105,6 +109,18 @@ found in the LICENSE file. </tr> </table> + <h2>Last Action Upload</h2> + <table> + <tr> + <td>Status</td> + <td id="last-action-upload-status"></td> + </tr> + <tr> + <td>Last Upload Time</td> + <td id="last-action-upload-time"></td> + </tr> + </table> + <h2>Current Content</h2> <div id="current-content"> <template id="suggestion-template"> @@ -155,5 +171,9 @@ found in the LICENSE file. <input id="feed-host-override"> <button id="feed-host-override-apply">Apply</button> + <h2>Actions Endpoint Override (v2 only)</h2> + <input id="actions-endpoint-override"> + <button id="actions-endpoint-override-apply">Apply</button> + </body> </html> diff --git a/chromium/chrome/browser/resources/feed_internals/feed_internals.js b/chromium/chrome/browser/resources/feed_internals/feed_internals.js index 03811954c5a..be8efb6bd6c 100644 --- a/chromium/chrome/browser/resources/feed_internals/feed_internals.js +++ b/chromium/chrome/browser/resources/feed_internals/feed_internals.js @@ -25,6 +25,7 @@ function updatePageWithProperties() { $('is-prefetching-enabled').textContent = properties.isPrefetchingEnabled; $('load-stream-status').textContent = properties.loadStreamStatus; $('feed-fetch-url').textContent = properties.feedFetchUrl.url; + $('feed-actions-url').textContent = properties.feedActionsUrl.url; }); } @@ -54,6 +55,10 @@ function updatePageWithLastFetchProperties() { $('refresh-suppress-time').textContent = toDateString(properties.refreshSuppressTime); $('last-fetch-bless-nonce').textContent = properties.lastBlessNonce; + $('last-action-upload-status').textContent = + properties.lastActionUploadStatus; + $('last-action-upload-time').textContent = + toDateString(properties.lastActionUploadTime); }); } @@ -145,6 +150,10 @@ function setupEventListeners() { $('feed-host-override-apply').addEventListener('click', function() { pageHandler.overrideFeedHost({url: $('feed-host-override').value}); }); + + $('actions-endpoint-override-apply').addEventListener('click', function() { + pageHandler.overrideFeedHost({url: $('actions-endpoint-override').value}); + }); } function updatePage() { diff --git a/chromium/chrome/browser/resources/feedback/html/default.html b/chromium/chrome/browser/resources/feedback/html/default.html index 2cfa06d8d1a..4997e95b601 100644 --- a/chromium/chrome/browser/resources/feedback/html/default.html +++ b/chromium/chrome/browser/resources/feedback/html/default.html @@ -42,7 +42,7 @@ <div id="user-email" class="text-field-container" hidden> <label id="user-email-label" i18n-content="userEmail"></label> <select id="user-email-drop-down" aria-labelledby="user-email-label"> - <option id="anonymous-user-option" value="anonymous_user" + <option id="anonymous-user-option" value="" i18n-content="anonymousUser"></option> </select> </div> diff --git a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js index c641a0302dc..85fa4919dec 100644 --- a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js @@ -133,8 +133,6 @@ cr.define('cr.login', function() { 'platformVersion', // Version of the OS build. 'releaseChannel', // Installation channel. 'endpointGen', // Current endpoint generation. - 'menuGuestMode', // Enables "Guest mode" menu item - 'menuKeyboardOptions', // Enables "Keyboard options" menu item 'menuEnterpriseEnrollment', // Enables "Enterprise enrollment" menu item. 'lsbReleaseBoard', // Chrome OS Release board name 'isFirstUser', // True if this is non-enterprise device, @@ -209,6 +207,9 @@ cr.define('cr.login', function() { 'backButton'(msg) { this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); }, + 'getAccounts'(msg) { + this.dispatchEvent(new Event('getAccounts')); + }, 'showView'(msg) { this.dispatchEvent(new Event('showView')); }, @@ -597,6 +598,14 @@ cr.define('cr.login', function() { this.isLoaded_ = true; } + /** + * Called in response to 'getAccounts' event. + * @param {Array<string>} accounts list of emails + */ + getAccountsResponse(accounts) { + this.sendMessageToWebview('accountsListed', accounts); + } + constructInitialFrameUrl_(data) { if (data.doSamlRedirect) { let url = this.idpOrigin_ + SAML_REDIRECTION_PATH; @@ -639,26 +648,15 @@ cr.define('cr.login', function() { if (data.endpointGen) { url = appendParam(url, 'endpoint_gen', data.endpointGen); } - let mi = ''; - if (data.menuGuestMode) { - mi += 'gm,'; - } - if (data.menuKeyboardOptions) { - mi += 'ko,'; - } if (data.menuEnterpriseEnrollment) { - mi += 'ee,'; - } - if (mi.length) { - url = appendParam(url, 'mi', mi); + url = appendParam(url, 'mi', 'ee'); } + if (data.lsbReleaseBoard) { + url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); + } if (data.isFirstUser) { url = appendParam(url, 'is_first_user', 'true'); - - if (data.lsbReleaseBoard) { - url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); - } } if (data.obfuscatedOwnerId) { url = appendParam(url, 'obfuscated_owner_id', data.obfuscatedOwnerId); @@ -873,11 +871,22 @@ cr.define('cr.login', function() { } /** - * Invoked to send a HTML5 message to the webview element. - * @param {Object} payload Payload of the HTML5 message. + * Invoked to send a HTML5 message with attached data to the webview + * element. + * @param {string} messageType Type of the HTML5 message. + * @param {Object=} messageData Data to be attached to the message. */ - sendMessageToWebview(payload) { + sendMessageToWebview(messageType, messageData = null) { const currentUrl = this.webview_.src; + let payload = undefined; + if (messageData) { + payload = {type: messageType, data: messageData}; + } else { + // TODO(crbug.com/1116343): Use new message format when it will be + // available in production. + payload = messageType; + } + this.webview_.contentWindow.postMessage(payload, currentUrl); } diff --git a/chromium/chrome/browser/resources/history/history_toolbar.html b/chromium/chrome/browser/resources/history/history_toolbar.html index f195233e447..96cc750809e 100644 --- a/chromium/chrome/browser/resources/history/history_toolbar.html +++ b/chromium/chrome/browser/resources/history/history_toolbar.html @@ -1,7 +1,6 @@ <style include="shared-style"> :host { display: flex; - overflow: hidden; position: relative; } @@ -33,6 +32,7 @@ clear-label="$i18n{clearSearch}" search-prompt="$i18n{searchPrompt}" spinner-active="[[spinnerActive]]" + autofocus show-menu="[[hasDrawer]]" show-menu-promo="[[canShowMenuPromo_(showMenuPromo)]]" menu-label="$i18n{historyMenuButton}" diff --git a/chromium/chrome/browser/resources/identity_internals/identity_internals.js b/chromium/chrome/browser/resources/identity_internals/identity_internals.js index 5e3fd4fb82d..06c211a7475 100644 --- a/chromium/chrome/browser/resources/identity_internals/identity_internals.js +++ b/chromium/chrome/browser/resources/identity_internals/identity_internals.js @@ -34,6 +34,8 @@ cr.define('identity_internals', function() { 'Extension Name', this.data_.extensionName, 'extension-name')); tbody.appendChild(this.createEntry_( 'Extension Id', this.data_.extensionId, 'extension-id')); + tbody.appendChild(this.createEntry_( + 'Account Id', this.data_.accountId, 'account-id')); tbody.appendChild( this.createEntry_('Token Status', this.data_.status, 'token-status')); tbody.appendChild(this.createEntry_( diff --git a/chromium/chrome/browser/resources/inline_login/BUILD.gn b/chromium/chrome/browser/resources/inline_login/BUILD.gn new file mode 100644 index 00000000000..cf86b87edc5 --- /dev/null +++ b/chromium/chrome/browser/resources/inline_login/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/gaia_auth_host/", + "js_module_root=./gen/chrome/browser/resources/gaia_auth_host/", + ] + deps = [ + ":inline_login_app", + ":inline_login_browser_proxy", + ] +} + +js_library("inline_login_app") { + deps = [ + ":inline_login_browser_proxy", + "//chrome/browser/resources/gaia_auth_host:authenticator.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] + externs_list = [ "$externs_path/webview_tag.js" ] +} + +js_library("inline_login_browser_proxy") { + deps = [ + "//chrome/browser/resources/gaia_auth_host:authenticator.m", + "//ui/webui/resources/js:cr.m", + ] + externs_list = [ "$externs_path/chrome_send.js" ] +} + +html_to_js("web_components") { + js_files = [ "inline_login_app.js" ] +} diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.css b/chromium/chrome/browser/resources/inline_login/inline_login.css deleted file mode 100644 index 5e3a81b948c..00000000000 --- a/chromium/chrome/browser/resources/inline_login/inline_login.css +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -html, -body, -#contents, -#signin-frame { - height: 100%; - margin: 0; - overflow: hidden; - padding: 0; - width: 100%; -} - -#signin-frame, -#spinner-container { - background-color: var(--cr-card-background-color); - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; -} - -#spinner-container { - align-items: center; - display: flex; - justify-content: center; -} - -#contents:not(.loading) #spinner-container { - display: none; -} - -#navigation-button { - background: white; - bottom: 32px; - left: 32px; - padding-inline-start: 10px; - position: absolute; - visibility: hidden; -} - -:host-context([dir='rtl']) #navigation-button { - left: auto; - right: 32px; -} - -#navigation-button.enabled { - visibility: visible; -} - -/* On Chrome OS, we need to shift the webview a bit to accommodate the Back - * button at the bottom. - */ -<if expr="chromeos"> -#signin-frame { - top: -35px; /*dialog top border size*/ -} - -#contents, -#signin-frame { - height: calc(100% - 96px); -} - -@media (max-width: 767px) { - #contents, - #signin-frame { - height: calc(100% - 80px); - } - - #navigation-button { - bottom: 24px; - left: 24px; - } - - :host-context([dir='rtl']) #navigation-button { - left: auto; - right: 24px; - } -} -</if> diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.html b/chromium/chrome/browser/resources/inline_login/inline_login.html index ba073cef263..dfc66c307c7 100644 --- a/chromium/chrome/browser/resources/inline_login/inline_login.html +++ b/chromium/chrome/browser/resources/inline_login/inline_login.html @@ -1,37 +1,20 @@ <!doctype html> <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> - <meta charset="utf-8"> - <title>$i18n{title}</title> - <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="chrome://resources/cr_elements/icons.html"> - <link rel="stylesheet" href="chrome://resources/css/spinner.css"> - <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> - <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> - <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> - <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> - <link rel="stylesheet" href="chrome://chrome-signin/inline_login.css"> - <script src="chrome://resources/js/cr.js"></script> - <script src="chrome://resources/js/cr/event_target.js"></script> - <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://resources/js/util.js"></script> - <script src="chrome://chrome-signin/gaia_auth_host.js"></script> - <script src="chrome://chrome-signin/inline_login.js"></script> - <script src="chrome://chrome-signin/strings.js"></script> +<meta charset="utf-8"> +<title>$i18n{title}</title> +<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> </head> +<style> + html, + body { + height: 100%; + margin: 0; + padding: 0; + } +</style> <body> - <div id="contents" class="loading"> - <webview id="signin-frame" name="signin-frame" allowscaling></webview> - <div id="spinner-container"> - <div class="spinner"></div> - </div> - </div> - - <cr-button - id="navigation-button" - aria-label="$i18n{accessibleBackButtonLabel}"> - <iron-icon id="navigation-icon"></iron-icon> - $i18n{accessibleBackButtonLabel} - </cr-button> + <inline-login-app></inline-login-app> + <script type="module" src="inline_login_app.js"></script> </body> </html> diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.js b/chromium/chrome/browser/resources/inline_login/inline_login.js deleted file mode 100644 index a0988731025..00000000000 --- a/chromium/chrome/browser/resources/inline_login/inline_login.js +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Inline login UI. - */ - -cr.define('inline.login', function() { - 'use strict'; - - /** - * The auth extension host instance. - * @type {cr.login.Authenticator} - */ - let authExtHost; - - /** - * Whether the auth ready event has been fired, for testing purpose. - */ - let authReadyFired; - - /** - * Whether the login UI is loaded for signing in primary account. - */ - let isLoginPrimaryAccount; - - function onResize(e) { - chrome.send('switchToFullTab', [e.detail]); - } - - function onAuthReady(e) { - $('contents').classList.toggle('loading', false); - authReadyFired = true; - if (isLoginPrimaryAccount) { - chrome.send('metricsHandler:recordAction', ['Signin_SigninPage_Shown']); - } - chrome.send('authExtensionReady'); - } - - function onDropLink(e) { - // Navigate to the dropped link. - window.location.href = e.detail; - } - - function onNewWindow(e) { - window.open(e.detail.targetUrl, '_blank'); - e.detail.window.discard(); - } - - function onAuthCompleted(e) { - completeLogin(e.detail); - } - - function completeLogin(credentials) { - chrome.send('completeLogin', [credentials]); - $('contents').classList.toggle('loading', true); - } - - function onShowIncognito() { - chrome.send('showIncognito'); - } - - /** - * Initialize the UI. - */ - function initialize() { - $('navigation-button').addEventListener('click', navigateBackInWebview); - cr.addWebUIListener('show-back-button', showBackButton); - cr.addWebUIListener('load-auth-extension', loadAuthExtension); - cr.addWebUIListener('close-dialog', closeDialog); - - authExtHost = new cr.login.Authenticator('signin-frame'); - authExtHost.addEventListener('dropLink', onDropLink); - authExtHost.addEventListener('ready', onAuthReady); - authExtHost.addEventListener('newWindow', onNewWindow); - authExtHost.addEventListener('resize', onResize); - authExtHost.addEventListener('authCompleted', onAuthCompleted); - authExtHost.addEventListener('showIncognito', onShowIncognito); - chrome.send('initialize'); - } - - /** - * Loads auth extension. - * @param {Object} data Parameters for auth extension. - */ - function loadAuthExtension(data) { - // TODO(rogerta): in when using webview, the |completeLogin| argument - // is ignored. See addEventListener() call above. - authExtHost.load(data.authMode, data, completeLogin); - $('contents') - .classList.toggle( - 'loading', - data.authMode != cr.login.Authenticator.AuthMode.DESKTOP || - data.constrained == '1'); - isLoginPrimaryAccount = data.isLoginPrimaryAccount; - } - - /** - * Closes the inline login dialog. - */ - function closeDialog() { - chrome.send('dialogClose', ['']); - } - - /** - * Sends a message 'lstFetchResults'. This is a specific message sent when - * the inline signin is loaded with reason REASON_FETCH_LST_ONLY. Handlers of - * this message would expect a single argument a base::Dictionary value that - * contains the values fetched from the gaia sign in endpoint. - * @param {string} arg The string representation of the json data returned by - * the sign in dialog after it has finished the sign in process. - */ - function sendLSTFetchResults(arg) { - chrome.send('lstFetchResults', [arg]); - } - - /** - * Invoked when failed to get oauth2 refresh token. - */ - function handleOAuth2TokenFailure() { - // TODO(xiyuan): Show an error UI. - authExtHost.reload(); - $('contents').classList.toggle('loading', true); - } - - /** - * Returns the auth host instance, for testing purpose. - */ - function getAuthExtHost() { - return authExtHost; - } - - /** - * Returns whether the auth UI is ready, for testing purpose. - */ - function isAuthReady() { - return authReadyFired; - } - - function showBackButton() { - $('navigation-icon').icon = - isRTL() ? 'cr:chevron-right' : 'cr:chevron-left'; - $('navigation-button').classList.add('enabled'); - } - - function navigateBackInWebview() { - if ($('signin-frame').canGoBack()) { - $('signin-frame').back(); - $('signin-frame').focus(); - } else { - closeDialog(); - } - } - - return { - closeDialog: closeDialog, - sendLSTFetchResults: sendLSTFetchResults, - getAuthExtHost: getAuthExtHost, - handleOAuth2TokenFailure: handleOAuth2TokenFailure, - initialize: initialize, - isAuthReady: isAuthReady, - loadAuthExtension: loadAuthExtension, - showBackButton: showBackButton, - }; -}); - -document.addEventListener('DOMContentLoaded', inline.login.initialize); diff --git a/chromium/chrome/browser/resources/inline_login/inline_login_app.html b/chromium/chrome/browser/resources/inline_login/inline_login_app.html new file mode 100644 index 00000000000..a8f5331ca34 --- /dev/null +++ b/chromium/chrome/browser/resources/inline_login/inline_login_app.html @@ -0,0 +1,76 @@ +<style> + :host { + --dialog-top-border-size: 35px; + display: flex; + flex-direction: column; + height: 100%; + } + + .signin-frame { + height: 100%; + margin: 0; + padding: 0; + width: 100%; + } + + .container { + align-items: center; + display: flex; + flex-grow: 1; + justify-content: center; + } + +<if expr="chromeos"> + .container { + margin-top: calc(-1 * var(--dialog-top-border-size)); + } +</if> + + .signin-frame { + background-color: white; + overflow: hidden; + } + + .buttons { + display: flex; + padding: 0 32px 32px; + } + + .action-buttons { + margin-inline-start: auto; + } + + paper-spinner-lite { + --spinner-size: 24px; + display: none; + height: var(--spinner-size); + width: var(--spinner-size); + } + + paper-spinner-lite[active] { + display: inline-block; + } +</style> + +<div class="container"> + <webview id="signinFrame" name="signin-frame" class="signin-frame" + hidden$="[[loading_]]" allowscaling></webview> + <paper-spinner-lite active="[[loading_]]"> + </paper-spinner-lite> +</div> + +<if expr="chromeos"> + <div class="buttons" hidden$="[[loading_]]"> + <cr-button class="back-button" + aria-label="$i18n{accessibleBackButtonLabel}" + on-tap="handleGoBack_"> + <iron-icon icon="[[getBackButtonIcon_()]]"></iron-icon> + $i18n{accessibleBackButtonLabel} + </cr-button> + + <div class="action-buttons" hidden$="[[!enableGaiaActionButtons_]]"> + <gaia-action-buttons authenticator="[[authExtHost_]]"> + </gaia-action-buttons> + </div> + </div> +</if> diff --git a/chromium/chrome/browser/resources/inline_login/inline_login_app.js b/chromium/chrome/browser/resources/inline_login/inline_login_app.js new file mode 100644 index 00000000000..7b9d167fb6c --- /dev/null +++ b/chromium/chrome/browser/resources/inline_login/inline_login_app.js @@ -0,0 +1,227 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/cr_elements/icons.m.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; + +// <if expr="chromeos"> +import './gaia_action_buttons.js'; +// </if> + +import {isRTL} from 'chrome://resources/js/util.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {AuthCompletedCredentials, Authenticator, AuthParams} from '../gaia_auth_host/authenticator.m.js'; +import {InlineLoginBrowserProxy, InlineLoginBrowserProxyImpl} from './inline_login_browser_proxy.js'; + +/** + * @fileoverview Inline login WebUI in various signin flows for ChromeOS and + * Chrome desktop (Windows only). + */ + +Polymer({ + is: 'inline-login-app', + + _template: html`{__html_template__}`, + + behaviors: [WebUIListenerBehavior], + + properties: { + /** + * Indicates whether the page is loading. + * @private {boolean} + */ + loading_: { + type: Boolean, + value: true, + }, + + /** + * The auth extension host instance. + * @private {?Authenticator} + */ + authExtHost_: { + type: Object, + value: null, + }, + }, + + /** @private {?InlineLoginBrowserProxy} */ + browserProxy_: null, + + /** + * Whether the login UI is loaded for signing in primary account. + * @private {boolean} + */ + isLoginPrimaryAccount_: false, + + /** @private {boolean} */ + enableGaiaActionButtons_: false, + + /** @override */ + created() { + this.browserProxy_ = InlineLoginBrowserProxyImpl.getInstance(); + }, + + /** @override */ + ready() { + this.authExtHost_ = new Authenticator( + /** @type {!WebView} */ (this.$.signinFrame)); + this.addAuthExtHostListeners_(); + this.browserProxy_.initialize(); + }, + + /** @override */ + attached() { + this.addWebUIListener( + 'load-auth-extension', data => this.loadAuthExtension_(data)); + this.addWebUIListener( + 'send-lst-fetch-results', arg => this.sendLSTFetchResults_(arg)); + this.addWebUIListener('close-dialog', () => this.closeDialog_()); + }, + + /** @private */ + addAuthExtHostListeners_() { + this.authExtHost_.addEventListener( + 'dropLink', + e => this.onDropLink_( + /** @type {!CustomEvent<string>} */ (e))); + this.authExtHost_.addEventListener( + 'newWindow', + e => this.onNewWindow_( + /** @type {!CustomEvent<NewWindowProperties>} */ (e))); + this.authExtHost_.addEventListener('ready', () => this.onAuthReady_()); + this.authExtHost_.addEventListener( + 'resize', + e => this.onResize_( + /** @type {!CustomEvent<string>} */ (e))); + this.authExtHost_.addEventListener( + 'authCompleted', + e => this.onAuthCompleted_( + /** @type {!CustomEvent<!AuthCompletedCredentials>} */ (e))); + this.authExtHost_.addEventListener( + 'showIncognito', () => this.onShowIncognito_()); + this.authExtHost_.addEventListener( + 'getAccounts', () => this.onGetAccounts_()); + }, + + /** + * @param {!CustomEvent<string>} e + * @private + */ + onDropLink_(e) { + // Navigate to the dropped link. + window.location.href = e.detail; + }, + + /** + * @param {!CustomEvent<NewWindowProperties>} e + * @private + */ + onNewWindow_(e) { + window.open(e.detail.targetUrl, '_blank'); + e.detail.window.discard(); + }, + + /** @private */ + onAuthReady_() { + this.loading_ = false; + if (this.isLoginPrimaryAccount_) { + this.browserProxy_.recordAction('Signin_SigninPage_Shown'); + } + this.browserProxy_.authExtensionReady(); + }, + + /** + * @param {!CustomEvent<string>} e + * @private + */ + onResize_(e) { + this.browserProxy_.switchToFullTab(e.detail); + }, + + /** + * @param {!CustomEvent<!AuthCompletedCredentials>} e + * @private + */ + onAuthCompleted_(e) { + this.loading_ = true; + this.browserProxy_.completeLogin(e.detail); + }, + + /** @private */ + onShowIncognito_() { + this.browserProxy_.showIncognito(); + }, + + /** @private */ + onGetAccounts_() { + this.browserProxy_.getAccounts().then(result => { + this.authExtHost_.getAccountsResponse(result); + }); + }, + + /** + * Loads auth extension. + * @param {!AuthParams} data Parameters for auth extension. + * @private + */ + loadAuthExtension_(data) { + this.authExtHost_.load(data.authMode, data); + this.loading_ = true; + this.isLoginPrimaryAccount_ = data.isLoginPrimaryAccount; + this.enableGaiaActionButtons_ = data.enableGaiaActionButtons; + }, + + /** + * Sends a message 'lstFetchResults'. This is a specific message sent when + * the inline signin is loaded with reason REASON_FETCH_LST_ONLY. Handlers of + * this message would expect a single argument a base::Dictionary value that + * contains the values fetched from the gaia sign in endpoint. + * @param {string} arg The string representation of the json data returned by + * the sign in dialog after it has finished the sign in process. + * @private + */ + sendLSTFetchResults_(arg) { + this.browserProxy_.lstFetchResults(arg); + }, + + /** + * Closes the login dialog. + * @private + */ + closeDialog_() { + this.browserProxy_.dialogClose(); + }, + + /** + * Navigates back in the web view if possible. Otherwise closes the dialog. + * @private + */ + handleGoBack_() { + if (this.$.signinFrame.canGoBack()) { + this.$.signinFrame.back(); + this.$.signinFrame.focus(); + } else { + this.closeDialog_(); + } + }, + + /** + * @return {string} + * @private + */ + getBackButtonIcon_() { + return isRTL() ? 'cr:chevron-right' : 'cr:chevron-left'; + }, + + /** @param {!Authenticator} authExtHost */ + setAuthExtHostForTest(authExtHost) { + this.authExtHost_ = authExtHost; + this.addAuthExtHostListeners_(); + }, +}); diff --git a/chromium/chrome/browser/resources/inline_login/inline_login_browser_proxy.js b/chromium/chrome/browser/resources/inline_login/inline_login_browser_proxy.js new file mode 100644 index 00000000000..91bb37ddbfe --- /dev/null +++ b/chromium/chrome/browser/resources/inline_login/inline_login_browser_proxy.js @@ -0,0 +1,108 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; + +import {AuthCompletedCredentials} from '../gaia_auth_host/authenticator.m.js'; + +/** @interface */ +export class InlineLoginBrowserProxy { + /** Send 'initialize' message to prepare for starting auth. */ + initialize() {} + + /** + * Send 'authExtensionReady' message to handle tasks after auth extension + * loads. + */ + authExtensionReady() {} + + /** + * Send 'switchToFullTab' message to switch the UI from a constrained dialog + * to a full tab. + * @param {!string} url + */ + switchToFullTab(url) {} + + /** + * Send 'completeLogin' message to complete login. + * @param {!AuthCompletedCredentials} credentials + */ + completeLogin(credentials) {} + + /** + * Send 'lstFetchResults' message. + * @param {string} arg The string representation of the json data returned by + * the sign in dialog after it has finished the sign in process. + */ + lstFetchResults(arg) {} + + /** + * Send 'metricsHandler:recordAction' message. + * @param {string} metricsAction The action to be recorded. + */ + recordAction(metricsAction) {} + + /** Send 'showIncognito' message to the handler */ + showIncognito() {} + + /** + * Send 'getAccounts' message to the handler. The promise will be resolved + * with the list of emails of accounts in session. + * @return {Promise<Array<string>>} + */ + getAccounts() {} + + /** Send 'dialogClose' message to close the login dialog. */ + dialogClose() {} +} + +/** @implements {InlineLoginBrowserProxy} */ +export class InlineLoginBrowserProxyImpl { + /** @override */ + initialize() { + chrome.send('initialize'); + } + + /** @override */ + authExtensionReady() { + chrome.send('authExtensionReady'); + } + + /** @override */ + switchToFullTab(url) { + chrome.send('switchToFullTab', [url]); + } + + /** @override */ + completeLogin(credentials) { + chrome.send('completeLogin', [credentials]); + } + + /** @override */ + lstFetchResults(arg) { + chrome.send('lstFetchResults', [arg]); + } + + /** @override */ + recordAction(metricsAction) { + chrome.send('metricsHandler:recordAction', [metricsAction]); + } + + /** @override */ + showIncognito() { + chrome.send('showIncognito'); + } + + /** @override */ + getAccounts() { + return sendWithPromise('getAccounts'); + } + + /** @override */ + dialogClose() { + chrome.send('dialogClose'); + } +} + +addSingletonGetter(InlineLoginBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/inspect/OWNERS b/chromium/chrome/browser/resources/inspect/OWNERS index 13224fd71b7..82d9348f1c0 100644 --- a/chromium/chrome/browser/resources/inspect/OWNERS +++ b/chromium/chrome/browser/resources/inspect/OWNERS @@ -1,5 +1,7 @@ dgozman@chromium.org pfeldman@chromium.org yangguo@chromium.org +petermarshall@chromium.org +sigurds@chromium.org # COMPONENT: Platform>DevTools diff --git a/chromium/chrome/browser/resources/inspect/inspect.js b/chromium/chrome/browser/resources/inspect/inspect.js index 74065a6b484..540280b37ce 100644 --- a/chromium/chrome/browser/resources/inspect/inspect.js +++ b/chromium/chrome/browser/resources/inspect/inspect.js @@ -161,6 +161,8 @@ function populateLocalTargets(data) { removeChildren('service-workers-list'); removeChildrenExceptAdditional('others-list'); + data.sort((a, b) => a.name.localeCompare(b.name)); + for (let i = 0; i < data.length; i++) { if (data[i].type === 'page') { addToPagesList(data[i]); diff --git a/chromium/chrome/browser/resources/notifications_internals/BUILD.gn b/chromium/chrome/browser/resources/internals/notifications/BUILD.gn index 021f90a7b4b..99a6c91f18e 100644 --- a/chromium/chrome/browser/resources/notifications_internals/BUILD.gn +++ b/chromium/chrome/browser/resources/internals/notifications/BUILD.gn @@ -1,10 +1,11 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2020 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { + uses_js_modules = true deps = [ ":notifications_internals", ":notifications_internals_browser_proxy", @@ -14,12 +15,10 @@ js_type_check("closure_compile") { js_library("notifications_internals") { deps = [ ":notifications_internals_browser_proxy", - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:util", + "//ui/webui/resources/js:util.m", ] } js_library("notifications_internals_browser_proxy") { - deps = [ "//ui/webui/resources/js:cr" ] + deps = [ "//ui/webui/resources/js:cr.m" ] } diff --git a/chromium/chrome/browser/resources/internals/notifications/OWNERS b/chromium/chrome/browser/resources/internals/notifications/OWNERS new file mode 100644 index 00000000000..3aa5f8c90eb --- /dev/null +++ b/chromium/chrome/browser/resources/internals/notifications/OWNERS @@ -0,0 +1,3 @@ +file://chrome/browser/notifications/OWNERS +file://chrome/browser/notifications/scheduler/OWNERS +# COMPONENT: UI>Notifications diff --git a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.html b/chromium/chrome/browser/resources/internals/notifications/notifications_internals.html index ef676a97e5e..7ed87b2dd1e 100644 --- a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.html +++ b/chromium/chrome/browser/resources/internals/notifications/notifications_internals.html @@ -4,9 +4,7 @@ <meta charset="utf-8"> <title>Notifications Internals</title> <meta name="viewport" content="width=device-width"> - <link rel="stylesheet" href="chrome://resources/css/list.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> - <link rel="stylesheet" href="notifications_internals.css"> </head> <body> <h1>Notifications Internals</h1> @@ -33,10 +31,6 @@ <div> <button id="schedule-notification">Schedule</button> </div> - <script src="chrome://resources/js/cr.js"></script> - <script src="chrome://resources/js/promise_resolver.js"></script> - <script src="chrome://resources/js/util.js"></script> - <script src="notifications_internals_browser_proxy.js"></script> - <script src="notifications_internals.js"></script> + <script type="module" src="notifications_internals.js"></script> </body> </html> diff --git a/chromium/chrome/browser/resources/internals/notifications/notifications_internals.js b/chromium/chrome/browser/resources/internals/notifications/notifications_internals.js new file mode 100644 index 00000000000..ec7f06abd0f --- /dev/null +++ b/chromium/chrome/browser/resources/internals/notifications/notifications_internals.js @@ -0,0 +1,22 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {$} from 'chrome://resources/js/util.m.js'; + +import {NotificationsInternalsBrowserProxy, NotificationsInternalsBrowserProxyImpl} from './notifications_internals_browser_proxy.js'; + +function initialize() { + /** @type {!NotificationsInternalsBrowserProxy} */ + const browserProxy = NotificationsInternalsBrowserProxyImpl.getInstance(); + + // Register all event listeners. + $('schedule-notification').onclick = function() { + browserProxy.scheduleNotification( + $('notification-scheduler-url').value, + $('notification-scheduler-title').value, + $('notification-scheduler-message').value); + }; +} + +document.addEventListener('DOMContentLoaded', initialize); diff --git a/chromium/chrome/browser/resources/internals/notifications/notifications_internals_browser_proxy.js b/chromium/chrome/browser/resources/internals/notifications/notifications_internals_browser_proxy.js new file mode 100644 index 00000000000..46473cb9a59 --- /dev/null +++ b/chromium/chrome/browser/resources/internals/notifications/notifications_internals_browser_proxy.js @@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + +/** @interface */ +export class NotificationsInternalsBrowserProxy { + /** + * Schedules a notification through notification schedule service. + * @param {string} url URL to open after clicking the notification. + * @param {string} title Title of the notification. + * @param {string} message Message of the notification. + */ + scheduleNotification(url, title, message) {} +} + +/** + * @implements {NotificationsInternalsBrowserProxy} + */ +export class NotificationsInternalsBrowserProxyImpl { + /** @override */ + scheduleNotification(url, title, message) { + chrome.send('scheduleNotification', [url, title, message]); + } +} + +addSingletonGetter(NotificationsInternalsBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.html b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.html index 5b037055148..5a4d0907d49 100644 --- a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.html +++ b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.html @@ -21,6 +21,14 @@ Fetcher status: <span id="fetcher-status"></span> Database status: <span id="group-status"></span> </div> + <h4>Server address</h4> + <div> + <Label for="base-url">Base URL:</Label> + <input type="text" id="base-url" placeholder="https://chromeupboarding-pa.googleapis.com"> + <button id="prototype-server">Prototype server</button> + <button id="prod-server">Prod server</button> + <button id="set-url">Set base URL</button> + </div> <h4>Tile data</h4> Group info: <span id="group-info"></span> Tile proto: <span id="tile-proto"></span> diff --git a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.js b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.js index 3bb73548dc2..3e7875498c6 100644 --- a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.js +++ b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals.js @@ -41,6 +41,18 @@ function initialize() { browserProxy.purgeDb(); }; + $('prototype-server').onclick = function() { + $('base-url').value = + 'https://staging-gsaprototype-pa.sandbox.googleapis.com'; + }; + + $('prod-server').onclick = function() { + $('base-url').value = 'https://chromeupboarding-pa.googleapis.com'; + }; + + $('set-url').onclick = function() { + browserProxy.setServerUrl($('base-url').value); + }; // Kick off requests for the current system state. browserProxy.getServiceStatus().then(onServiceStatusChanged); browserProxy.getTileData().then(onTileDataAvailable); diff --git a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals_browser_proxy.js b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals_browser_proxy.js index ded38b10374..34022026011 100644 --- a/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals_browser_proxy.js +++ b/chromium/chrome/browser/resources/internals/query_tiles/query_tiles_internals_browser_proxy.js @@ -45,6 +45,12 @@ export class QueryTilesInternalsBrowserProxy { * is fetched. */ getTileData() {} + + /** + * Set the base URL of query tile server. + * @param {string} url of the server. + */ + setServerUrl(url) {} } /** @@ -70,6 +76,11 @@ export class QueryTilesInternalsBrowserProxyImpl { getTileData() { return sendWithPromise('getTileData'); } + + /** @override */ + setServerUrl(url) { + chrome.send('setServerUrl', [url]); + } } addSingletonGetter(QueryTilesInternalsBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/kaleidoscope/BUILD.gn b/chromium/chrome/browser/resources/kaleidoscope/BUILD.gn new file mode 100644 index 00000000000..f7a47898f66 --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/closure_args.gni") +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +html_to_js("web_components") { + js_files = [ + "side_nav_container.js", + "toolbar.js", + ] +} + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ + ":side_nav_container", + ":toolbar", + ] +} + +js_library("side_nav_container") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer.m", + ] +} + +js_library("toolbar") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} diff --git a/chromium/chrome/browser/resources/kaleidoscope/OWNERS b/chromium/chrome/browser/resources/kaleidoscope/OWNERS new file mode 100644 index 00000000000..d91fac218e9 --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/OWNERS @@ -0,0 +1,3 @@ +file://chrome/browser/media/kaleidoscope/OWNERS + +# COMPONENT: Internals>Media>UI>Kaleidoscope diff --git a/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.html b/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.html new file mode 100644 index 00000000000..b75199f178a --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.html @@ -0,0 +1,6 @@ +<style> + cr-drawer { + --cr-drawer-background-color: var(--side-nav-background-color); + } +</style> +<cr-drawer id="drawer"><slot></slot></cr-drawer> diff --git a/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.js b/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.js new file mode 100644 index 00000000000..21a1b3b167e --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/side_nav_container.js @@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '//resources/cr_elements/cr_drawer/cr_drawer.m.js'; + +import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +class KaleidoscopeSideNavContainerElement extends PolymerElement { + static get is() { + return 'kaleidoscope-side-nav-container'; + } + + static get template() { + return html`{__html_template__}`; + } + + // Toggles the CrDrawerElement. + toggle() { + /** @type {!CrDrawerElement} */ (this.$.drawer).toggle(); + } +} + +customElements.define( + KaleidoscopeSideNavContainerElement.is, + KaleidoscopeSideNavContainerElement); diff --git a/chromium/chrome/browser/resources/kaleidoscope/toolbar.html b/chromium/chrome/browser/resources/kaleidoscope/toolbar.html new file mode 100644 index 00000000000..6f46adbd9c6 --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/toolbar.html @@ -0,0 +1,11 @@ +<style> + cr-toolbar { + --cr-toolbar-background-color: var(--toolbar-background-color); + --cr-toolbar-height: var(--toolbar-height); + position: fixed; + top: 0; + width: 100%; + z-index: 1; + } +</style> +<cr-toolbar id="toolbar" show-menu show-search="[[showSearch]]"></cr-toolbar> diff --git a/chromium/chrome/browser/resources/kaleidoscope/toolbar.js b/chromium/chrome/browser/resources/kaleidoscope/toolbar.js new file mode 100644 index 00000000000..1e465e5abed --- /dev/null +++ b/chromium/chrome/browser/resources/kaleidoscope/toolbar.js @@ -0,0 +1,27 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '//resources/cr_elements/cr_toolbar/cr_toolbar.m.js'; + +import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +class KaleidoscopeToolbarElement extends PolymerElement { + static get is() { + return 'kaleidoscope-toolbar'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + // Controls whether the search field is shown. + showSearch: {type: Boolean, value: false}, + }; + } +} + +customElements.define( + KaleidoscopeToolbarElement.is, KaleidoscopeToolbarElement); diff --git a/chromium/chrome/browser/resources/local_discovery/local_discovery_warning.html b/chromium/chrome/browser/resources/local_discovery/local_discovery_warning.html new file mode 100644 index 00000000000..b94695fe579 --- /dev/null +++ b/chromium/chrome/browser/resources/local_discovery/local_discovery_warning.html @@ -0,0 +1,32 @@ +<!doctype html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> +<head> + <meta charset="utf-8"> + <title>$i18n{devicesTitle}</title> + <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> +</head> +<style> + body { + margin: 21px 10px 24px 10px; + } + + h1 { + margin: 0 0 13px 0; + } + + header { + border-bottom: 1px solid #eee; + max-width: 718px; + } + + div { + margin-top: 23px; + } +</style> +<body> + <header> + <h1>$i18n{devicesTitle}</h1> + </header> + <div>$i18nRaw{cloudPrintDeprecationWarning}</div> +</body> +</html> diff --git a/chromium/chrome/browser/resources/management/management_browser_proxy.js b/chromium/chrome/browser/resources/management/management_browser_proxy.js index 4510d679e01..4636c7db5a6 100644 --- a/chromium/chrome/browser/resources/management/management_browser_proxy.js +++ b/chromium/chrome/browser/resources/management/management_browser_proxy.js @@ -37,7 +37,11 @@ export let BrowserReportingResponse; * managed: boolean, * overview: string, * customerLogo: string, - * threatProtectionDescription: string + * threatProtectionDescription: string, + * showUpdateRequiredEol: boolean, + * eolMessage: string, + * eolAdminMessage: string, + * showProxyServerPrivacyDisclosure: boolean * }} */ let ManagedDataResponse; @@ -76,7 +80,6 @@ export const DeviceReportingType = { USERNAME: 'username', EXTENSION: 'extension', ANDROID_APPLICATION: 'android application', - PROXY_SERVER: 'proxy server' }; @@ -106,6 +109,12 @@ export class ManagementBrowserProxy { * items to display in device reporting section. */ getDeviceReportingInfo() {} + + /** + * @return {!Promise<boolean>} Boolean describing Plugin VM data collection + * enabled or not. + */ + getPluginVmDataCollectionStatus() {} // </if> /** @return {!Promise<!ManagedDataResponse>} */ @@ -138,6 +147,11 @@ export class ManagementBrowserProxyImpl { getDeviceReportingInfo() { return sendWithPromise('getDeviceReportingInfo'); } + + /** @override */ + getPluginVmDataCollectionStatus() { + return sendWithPromise('getPluginVmDataCollectionStatus'); + } // </if> /** @override */ diff --git a/chromium/chrome/browser/resources/management/management_ui.html b/chromium/chrome/browser/resources/management/management_ui.html index f2f414ce0e3..feee055794b 100644 --- a/chromium/chrome/browser/resources/management/management_ui.html +++ b/chromium/chrome/browser/resources/management/management_ui.html @@ -44,6 +44,40 @@ margin-inline-start: -10px; } + <if expr="chromeos"> + .eol-section { + border: 1px solid var(--google-grey-300); + border-radius: var(--cr-card-border-radius); + flex-direction: row; + justify-content: start; + margin-inline-end: 20px; + margin-inline-start: 20px; + padding: 16px var(--cr-section-padding); + } + + .eol-section .eol-warning-icon { + --google-yellow-50-rgb: 254, 247, 224; /* #fef7e0 */ + --google-yellow-50: rgb(var(--google-yellow-50-rgb)); + align-items: center; + background: var(--google-yellow-50); + border-radius: 50%; + display: flex; + height: 40px; + justify-content: center; + margin-inline-end: 20px; + width: 40px; + } + + .eol-section iron-icon { + height: var(--cr-icon-size); + width: var(--cr-icon-size); + } + + .eol-section .eol-admin-title { + font-weight: 500; + } + </if> + .overview-section div + div { margin-top: 16px; } @@ -159,7 +193,7 @@ } </style> - <cr-toolbar page-name="$i18n{toolbarTitle}" role="banner" + <cr-toolbar page-name="$i18n{toolbarTitle}" role="banner" autofocus on-search-changed="onSearchChanged_" clear-label="$i18n{clearSearch}" search-prompt="$i18n{searchPrompt}"> </cr-toolbar> @@ -174,6 +208,22 @@ [[subtitle_]] </h2> </section> +<if expr="chromeos"> + <section class="eol-section" hidden="[[!eolMessage_]]"> + <div class="eol-warning-icon"> + <iron-icon icon="cr20:banner-warning"></iron-icon> + </div> + <div class="eol-message"> + <div>[[eolMessage_]]</div> + <div hidden="[[isEmpty_(eolAdminMessage_)]]"> + <div class="eol-admin-title"> + $i18n{updateRequiredEolAdminMessageTitle} + </div> + <div>[[eolAdminMessage_]]</div> + </div> + </div> + </section> +</if> <section class="overview-section" hidden="[[!managementOverview_]]"> <if expr="not chromeos"> <div inner-h-t-m-l="[[managementNoticeHtml_]]"></div> @@ -225,6 +275,10 @@ if="[[showDeviceReportingInfo_(deviceReportingInfo_)]]"> <section> <h2 class="cr-title-text">$i18n{deviceReporting}</h2> + <div class="subtitle" + hidden="[[!showProxyServerPrivacyDisclosure_]]"> + $i18n{proxyServerPrivacyDisclosure} + </div> <div class="subtitle"> $i18n{deviceConfiguration} </div> @@ -237,6 +291,10 @@ </div> </template> </div> + <div class="subtitle" + hidden="[[!pluginVmDataCollectionEnabled_]]"> + $i18nRaw{pluginVmDataCollection} + </div> </section> </template> </if> diff --git a/chromium/chrome/browser/resources/management/management_ui.js b/chromium/chrome/browser/resources/management/management_ui.js index b928315c798..050271b1ca3 100644 --- a/chromium/chrome/browser/resources/management/management_ui.js +++ b/chromium/chrome/browser/resources/management/management_ui.js @@ -72,6 +72,18 @@ Polymer({ /** @private */ managementOverview_: String, + /** @private */ + pluginVmDataCollectionEnabled_: Boolean, + + /** @private */ + eolAdminMessage_: String, + + /** @private */ + eolMessage_: String, + + /** @private */ + showProxyServerPrivacyDisclosure_: Boolean, + // </if> /** @private */ @@ -107,6 +119,10 @@ Polymer({ 'browser-reporting-info-updated', reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo)); + this.addWebUIListener( + 'plugin-vm-data-collection-updated', + enabled => this.pluginVmDataCollectionEnabled_ = enabled); + this.addWebUIListener('managed_data_changed', () => { this.updateManagedFields_(); }); @@ -118,6 +134,7 @@ Polymer({ this.getExtensions_(); // <if expr="chromeos"> this.getDeviceReportingInfo_(); + this.getPluginVmDataCollectionStatus_(); this.getLocalTrustRootsInfo_(); // </if> }, @@ -196,6 +213,14 @@ Polymer({ }); }, + /** @private */ + getPluginVmDataCollectionStatus_() { + this.browserProxy_.getPluginVmDataCollectionStatus().then( + pluginVmDataCollectionEnabled => { + this.pluginVmDataCollectionEnabled_ = pluginVmDataCollectionEnabled; + }); + }, + /** * @return {boolean} True of there are device reporting info to show. * @private @@ -205,6 +230,16 @@ Polymer({ }, /** + * @param {string} eolAdminMessage The device return instructions + * @return {boolean} Whether there are device return instructions from the + * admin in case an update is required after reaching end of life. + * @private + */ + isEmpty_(eolAdminMessage) { + return !eolAdminMessage || eolAdminMessage.trim().length === 0; + }, + + /** * @param {DeviceReportingType} reportingType * @return {string} The associated icon. * @private @@ -235,8 +270,6 @@ Polymer({ return 'cr:extension'; case DeviceReportingType.ANDROID_APPLICATION: return 'management:play-store'; - case DeviceReportingType.PROXY_SERVER: - return 'management:vpn-lock'; default: return 'cr:computer'; } @@ -313,6 +346,17 @@ Polymer({ // <if expr="chromeos"> this.customerLogo_ = data.customerLogo; this.managementOverview_ = data.overview; + this.eolMessage_ = data.eolMessage; + this.showProxyServerPrivacyDisclosure_ = + data.showProxyServerPrivacyDisclosure; + try { + // Sanitizing the message could throw an error if it contains non + // supported markup. + this.eolAdminMessage_ = + loadTimeData.sanitizeInnerHtml(data.eolAdminMessage); + } catch (e) { + this.eolAdminMessage_ = ''; + } // </if> // <if expr="not chromeos"> this.managementNoticeHtml_ = data.browserManagementNotice; diff --git a/chromium/chrome/browser/resources/media_router/media_router_internals.html b/chromium/chrome/browser/resources/media_router/media_router_internals.html index 1668cf472c9..578c70c1d0e 100644 --- a/chromium/chrome/browser/resources/media_router/media_router_internals.html +++ b/chromium/chrome/browser/resources/media_router/media_router_internals.html @@ -11,5 +11,7 @@ <div id="sink-status-div" class="status"></div> <h1>Cast Media Route Provider</h1> <div id="cast-status-div" class="status"></div> + <h1>Logs</h1> + <div id="logs-div" class="status"></div> </body> </html> diff --git a/chromium/chrome/browser/resources/media_router/media_router_internals.js b/chromium/chrome/browser/resources/media_router/media_router_internals.js index 2e96359800c..b3c179ed3bc 100644 --- a/chromium/chrome/browser/resources/media_router/media_router_internals.js +++ b/chromium/chrome/browser/resources/media_router/media_router_internals.js @@ -5,14 +5,20 @@ import {sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {$} from 'chrome://resources/js/util.m.js'; +function formatJson(jsonObj) { + return JSON.stringify(jsonObj, null, /* spacing level = */ 2); +} + // Handles user events for the Media Router Internals UI. document.addEventListener('DOMContentLoaded', function() { sendWithPromise('getState').then(status => { - $('sink-status-div').textContent = - JSON.stringify(status, null, /* spacing level = */ 2); + $('sink-status-div').textContent = formatJson(status); }); sendWithPromise('getProviderState', 'CAST').then(status => { - $('cast-status-div').textContent = - JSON.stringify(status, null, /* spacing level = */ 2); + $('cast-status-div').textContent = formatJson(status); + }); + sendWithPromise('getLogs').then(logs => { + // TODO(crbug.com/687380): Present the logs in a table format. + $('logs-div').textContent = formatJson(logs); }); }); diff --git a/chromium/chrome/browser/resources/nearby_internals/.eslintrc.js b/chromium/chrome/browser/resources/nearby_internals/.eslintrc.js new file mode 100644 index 00000000000..18f6e9550ca --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/.eslintrc.js @@ -0,0 +1,11 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module.exports = { + 'env': { + 'browser': true, + 'es6': true, + }, + 'rules': {'eqeqeq': ['error', 'always', {'null': 'ignore'}]}, +}; diff --git a/chromium/chrome/browser/resources/nearby_internals/BUILD.gn b/chromium/chrome/browser/resources/nearby_internals/BUILD.gn index 71c035040b5..40719ba77c9 100644 --- a/chromium/chrome/browser/resources/nearby_internals/BUILD.gn +++ b/chromium/chrome/browser/resources/nearby_internals/BUILD.gn @@ -7,15 +7,159 @@ import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true - deps = [ ":nearby_internals" ] + deps = [ + ":contact_object", + ":contact_tab", + ":http_message_object", + ":http_tab", + ":log_object", + ":logging_tab", + ":nearby_contact_browser_proxy", + ":nearby_http_browser_proxy", + ":nearby_internals", + ":nearby_logs_browser_proxy", + ":nearby_ui_trigger_browser_proxy", + ":types", + ":ui_trigger_list_object", + ":ui_trigger_tab", + ] } js_library("nearby_internals") { deps = [ + ":contact_object", + ":contact_tab", + ":http_message_object", + ":http_tab", + ":log_object", + ":logging_tab", + ":nearby_contact_browser_proxy", + ":nearby_http_browser_proxy", + ":nearby_logs_browser_proxy", + ":nearby_ui_trigger_browser_proxy", + ":types", + ":ui_trigger_list_object", + ":ui_trigger_tab", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("logging_tab") { + deps = [ + ":log_object", + ":nearby_logs_browser_proxy", + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] +} + +js_library("log_object") { + deps = [ + ":nearby_logs_browser_proxy", + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("nearby_logs_browser_proxy") { + deps = [ + ":types", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("nearby_http_browser_proxy") { + deps = [ + ":types", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("http_tab") { + deps = [ + ":http_message_object", + ":nearby_http_browser_proxy", + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("http_message_object") { + deps = [ + ":nearby_http_browser_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] } +js_library("nearby_ui_trigger_browser_proxy") { + deps = [ + ":types", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("ui_trigger_tab") { + deps = [ + ":nearby_ui_trigger_browser_proxy", + ":types", + ":ui_trigger_list_object", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("ui_trigger_list_object") { + deps = [ + ":nearby_ui_trigger_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("types") { +} + +js_library("shared_style") { +} + +js_library("contact_tab") { + deps = [ + ":contact_object", + ":nearby_contact_browser_proxy", + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + ] +} + +js_library("contact_object") { + deps = [ + ":types", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("nearby_contact_browser_proxy") { + deps = [ + ":types", + "//ui/webui/resources/js:cr.m", + ] +} + html_to_js("web_components") { - js_files = [ "nearby_internals.js" ] + js_files = [ + "contact_object.js", + "contact_tab.js", + "http_message_object.js", + "http_tab.js", + "log_object.js", + "logging_tab.js", + "nearby_internals.js", + "shared_style.js", + "ui_trigger_list_object.js", + "ui_trigger_tab.js", + ] } diff --git a/chromium/chrome/browser/resources/nearby_internals/contact_object.html b/chromium/chrome/browser/resources/nearby_internals/contact_object.html new file mode 100644 index 00000000000..bba12bdf2b5 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/contact_object.html @@ -0,0 +1,69 @@ +<style> + :host { + --standard-border: 1px solid black; + } + + #item { + background: rgb(204, 204, 255); + border-left: var(--standard-border); + border-right: var(--standard-border); + border-top: var(--standard-border); + } + + #header { + display: flex; + padding: 6px; + } + + .expanded-element-title { + display: inline-block; + margin: 10px; + padding: 10px; + text-align: left; + white-space: pre-wrap; + width: 100%; + } + + #time { + display: flex; + font-size: 10px; + margin-bottom: 4px; + padding: 6px; + } + + #flex { + flex: 1; + } + + .expanded-element { + display: inline-block; + padding-left: 10px; + } +</style> +<div id="item"> + <div id="header"> + <span> + <p>Contacts list sent? [[item.contactsPassed]]</p> + <p>Contacts list changed? [[item.contactsListChanged]]</p> + <p> + Contacts added to allowlist? [[item.contactsAddedToAllowlist]] + </p> + <p> + Contacts removed from allowlist? [[item.contactsRemovedFromAllowlist]] + </p> + </span> + <div id="flex"></div> + <span id="time">[[formatTime_(item.time)]]</span> + <cr-expand-button id="expandContent" class="cr-row" + expanded="{{contentExpanded_}}"> + </cr-expand-button> + </div> + <iron-collapse opened="[[contentExpanded_]]"> + <p class="expanded-element-title">Contact Records: + <p class="expanded-element">[[item.contactRecords]]</p> + </p> + <p class="expanded-element-title">Allowed Contact Ids: + <p class="expanded-element">[[item.allowedIds]]</p> + </p> + </iron-collapse> +</div> diff --git a/chromium/chrome/browser/resources/nearby_internals/contact_object.js b/chromium/chrome/browser/resources/nearby_internals/contact_object.js new file mode 100644 index 00000000000..9f224fa3603 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/contact_object.js @@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ContactUpdate} from './types.js'; + +Polymer({ + is: 'contact-object', + + _template: html`{__html_template__}`, + + properties: { + /** + * Underlying ContactUpdate data for this item. Contains read-only fields + * from the NearbyShare back-end. + * Type: {!ContactUpdate} + */ + contactUpdate: { + type: Object, + }, + }, + + /** + * Sets the string representation of time. + * @private + * @param {number} time + * @return + */ + formatTime_(time) { + const d = new Date(time); + return d.toLocaleTimeString(); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/contact_tab.html b/chromium/chrome/browser/resources/nearby_internals/contact_tab.html new file mode 100644 index 00000000000..9f4ec67413f --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/contact_tab.html @@ -0,0 +1,27 @@ +<style include="shared-style"> + :host { + --standard-border: 1px solid black; + } + + #clearButton { + float: right; + } +</style> +<cr-button on-click="onDownloadContactsIfChangedClicked_" + class="internals-button"> + Download Contacts If Changed +</cr-button> +<cr-button on-click="onForceDownloadContactsClicked_" class="internals-button"> + Force Contacts Download +</cr-button> +<cr-button on-click="onClearMessagesButtonClicked_" class="internals-button" + id="clearButton" disabled="[[!contactList_.length]]"> + Clear Messages +</cr-button> +<doom-repeat items="[[contactList_]]" as="contact" id="contact-list" + hidden="[[!contactList_.length]]"> + <template> + <contact-object item="[[contact]]"> + </contact-object> + </template> +</dom-repeat> diff --git a/chromium/chrome/browser/resources/nearby_internals/contact_tab.js b/chromium/chrome/browser/resources/nearby_internals/contact_tab.js new file mode 100644 index 00000000000..d917a98691d --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/contact_tab.js @@ -0,0 +1,90 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js'; +import 'chrome://resources/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; +import './contact_object.js'; +import './shared_style.js'; + +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {NearbyContactBrowserProxy} from './nearby_contact_browser_proxy.js'; +import {ContactUpdate} from './types.js'; + +Polymer({ + is: 'contact-tab', + + _template: html`{__html_template__}`, + + behaviors: [ + WebUIListenerBehavior, + ], + + + properties: { + + /** @private {!Array<!ContactUpdate>} */ + contactList_: { + type: Array, + value: [], + }, + }, + + /** @private {?NearbyContactBrowserProxy} */ + browserProxy_: null, + + /** @override */ + created() { + this.browserProxy_ = NearbyContactBrowserProxy.getInstance(); + }, + + /** + * When the page is initialized, notify the C++ layer to allow JavaScript and + * initialize WebUI Listeners. + * @override + */ + attached() { + this.addWebUIListener( + 'contacts-updated', contact => this.onContactUpdateAdded_(contact)); + this.browserProxy_.initialize(); + }, + + /** + * Checks with the Nearby Server if contacts have changed since the last RPC + * call and downloads the contacts if they have. + * @private + */ + onDownloadContactsIfChangedClicked_() { + this.browserProxy_.downloadContacts( + /*onlyDownloadIfContactsChanged=*/true); + }, + + /** + * Downloads contacts from the Nearby Share server, regardless of whether or + * not they have changed since the last RPC call + * @private + */ + onForceDownloadContactsClicked_() { + this.browserProxy_.downloadContacts( + /*onlyDownloadIfContactsChanged=*/false); + }, + + /** + * Clears list of contact messages displayed. + * @private + */ + onClearMessagesButtonClicked_() { + this.contactList_ = []; + }, + + /** + * Adds contact sent in from WebUI listener to the list of displayed contacts. + * @param {!ContactUpdate} contact + * @private + */ + onContactUpdateAdded_(contact) { + this.unshift('contactList_', contact); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/http_message_object.html b/chromium/chrome/browser/resources/nearby_internals/http_message_object.html new file mode 100644 index 00000000000..d8eee7c4b5d --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/http_message_object.html @@ -0,0 +1,59 @@ +<style include="shared-style"> + :host { + --standard-border: 1px solid black; + } + + #item { + border-left: var(--standard-border); + border-right: var(--standard-border); + border-top: var(--standard-border); + } + + #header { + display: flex; + padding: 6px; + } + + #body { + display: inline-block; + margin: 10px; + padding: 5px; + text-align: left; + white-space: pre-wrap; + width: 100%; + } + + #time { + display: flex; + font-size: 10px; + margin-bottom: 4px; + padding: 6px; + } + + .request { + background-color: rgb(255, 230, 204); + } + + .response { + background-color: rgb(255, 255, 204); + } + + #flex { + flex: 1; + } +</style> +<div id="item"> + <div id="header"> + <span> + [[rpcToString_(item.rpc)]]:[[directionToString_(item.direction)]] + </span> + <div id="flex"></div> + <span id="time">[[formatTime_(item.time)]]</span> + <cr-expand-button id="expandContent" class="cr-row" + expanded="{{contentExpanded_}}"> + </cr-expand-button> + </div> + <iron-collapse opened="[[contentExpanded_]]"> + <p id="body">[[item.body]]</p> + </iron-collapse> +</div> diff --git a/chromium/chrome/browser/resources/nearby_internals/http_message_object.js b/chromium/chrome/browser/resources/nearby_internals/http_message_object.js new file mode 100644 index 00000000000..82e2e511fc9 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/http_message_object.js @@ -0,0 +1,93 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js'; +import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {Direction, Rpc} from './types.js'; + +Polymer({ + is: 'http-message-object', + + _template: html`{__html_template__}`, + + properties: { + /** + * Underlying HTTPMessage data for this item. Contains read-only fields + * from the NearbyShare backend, as well as fields computed by http tab. + * Type: {!HttpMessage} + */ + item: { + type: Object, + observer: 'itemChanged_', + }, + }, + + /** + * Sets the Http message style based on whether it is a response or request. + * @private + */ + itemChanged_() { + let classStyle = ''; + if (this.item.direction === Direction.REQUEST) { + classStyle = 'request'; + } else if (this.item.direction === Direction.RESPONSE) { + classStyle = 'response'; + } + this.$['item'].className = classStyle; + }, + + /** + * Sets the string representation of RPC type. + * @private + * @param {number} rpc + * @return + */ + rpcToString_(rpc) { + switch (rpc) { + case Rpc.DEVICE: + return 'UpdateDevice RPC'; + break; + case Rpc.CONTACT: + return 'ListContactPeople RPC'; + break; + case Rpc.CERTIFICATE: + return 'ListPublicCertificates RPC'; + break; + default: + break; + } + }, + + /** + * Returns the string representation of RPC type. + * @private + * @param {number} direction + * @return + */ + directionToString_(direction) { + switch (direction) { + case Direction.REQUEST: + return 'Request'; + break; + case Direction.RESPONSE: + return 'Response'; + break; + default: + break; + } + }, + + /** + * Sets the string representation of time. + * @private + * @param {number} time + * @return + */ + formatTime_(time) { + const d = new Date(time); + return d.toLocaleTimeString(); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/http_tab.html b/chromium/chrome/browser/resources/nearby_internals/http_tab.html new file mode 100644 index 00000000000..8f10ecf2b19 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/http_tab.html @@ -0,0 +1,29 @@ +<style include="shared-style"> + :host { + --standard-border: 1px solid black; + } + + #clearButton { + float: right; + } +</style> +<cr-button on-click="onUpdateDeviceClicked_" class="internals-button"> + Call UpdateDevice RPC +</cr-button> +<cr-button on-click="onListContactPeopleClicked_" class="internals-button"> + Call ListContactPeople RPC +</cr-button> +<cr-button on-click="onListPublicCertificatesClicked_" class="internals-button"> + Call ListPublicCertificates RPC +</cr-button> +<cr-button on-click="onClearMessagesButtonClicked_" class="internals-button" + id="clearButton" disabled="[[!httpMessageList_.length]]"> + Clear Messages +</cr-button> +<dom-repeat items="[[httpMessageList_]]" as="http-message" + hidden="[[!httpMessageList_.length]]"> + <template> + <http-message-object item="[[http-message]]"> + </http-message-object> + </template> +</dom-repeat> diff --git a/chromium/chrome/browser/resources/nearby_internals/http_tab.js b/chromium/chrome/browser/resources/nearby_internals/http_tab.js new file mode 100644 index 00000000000..73dd72aaf08 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/http_tab.js @@ -0,0 +1,99 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js'; +import 'chrome://resources/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; +import './http_message_object.js'; +import './shared_style.js'; + +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {NearbyHttpBrowserProxy} from './nearby_http_browser_proxy.js'; +import {HttpMessage} from './types.js'; + +Polymer({ + is: 'http-tab', + + _template: html`{__html_template__}`, + + behaviors: [ + WebUIListenerBehavior, + ], + + properties: { + + /** + * @private {!Array<!HttpMessage>} + */ + httpMessageList_: { + type: Array, + value: [], + }, + }, + + /** @private {?NearbyHttpBrowserProxy} */ + browserProxy_: null, + + /** + * Set |browserProxy_|. + * @override + */ + created() { + this.browserProxy_ = NearbyHttpBrowserProxy.getInstance(); + }, + + /** + * When the page is initialized, notify the C++ layer to allow JavaScript and + * initialize WebUI Listeners. + * @override + */ + attached() { + this.addWebUIListener( + 'http-message-added', message => this.onHttpMessageAdded_(message)); + this.browserProxy_.initialize(); + }, + + /** + * Triggers UpdateDevice RPC. + * @private + */ + onUpdateDeviceClicked_() { + this.browserProxy_.updateDevice(); + }, + + /** + * Triggers ListContactPeople RPC. + * @private + */ + onListContactPeopleClicked_() { + this.browserProxy_.listContactPeople(); + }, + + /** + * Triggers ListPublicCertificates RPC. + * @private + */ + onListPublicCertificatesClicked_() { + this.browserProxy_.listPublicCertificates(); + }, + + /** + * Clears the |httpMessageList_| messages displayed on the page. + * @private + */ + onClearMessagesButtonClicked_() { + this.httpMessageList_ = []; + }, + + /** + * Adds a HTTP message to the javascript message list displayed. Called from + * the C++ WebUI handler when a HTTP message is created in response to a Rpc. + * @param {!HttpMessage} message + * @private + */ + onHttpMessageAdded_(message) { + this.unshift('httpMessageList_', message); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/log_object.html b/chromium/chrome/browser/resources/nearby_internals/log_object.html new file mode 100644 index 00000000000..0a3154b458c --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/log_object.html @@ -0,0 +1,44 @@ +<style> + .warning-log { + background-color: rgb(255, 252, 239); + } + + .error-log { + background-color: rgb(255, 241, 241); + } + + .verbose-log { + background-color: rgb(235, 235, 235); + } + + .default-log { + background-color: rgb(255, 255, 255); + } + + #item-metadata { + color: #888; + display: flex; + font-size: 10px; + padding: 6px; + } + + #flex { + flex: 1; + } + + #text { + display: inline-block; + margin: 3px; + padding: 5px; + text-align: left; + width: 100%; + } +</style> +<div id="item" severity="[[item.severity]]"> + <p id="text">[[item.text]]</p> + <div id="item-metadata"> + <span>[[item.time]]</span> + <div id="flex"></div> + <span>[[item.file]]:[[item.line]]</span> + </div> +</div> diff --git a/chromium/chrome/browser/resources/nearby_internals/log_object.js b/chromium/chrome/browser/resources/nearby_internals/log_object.js new file mode 100644 index 00000000000..39d28e2388a --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/log_object.js @@ -0,0 +1,45 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {Severity} from './types.js'; + +Polymer({ + is: 'log-object', + + _template: html`{__html_template__}`, + + properties: { + /** + * Underlying LogMessage data for this item. Contains read-only fields + * from the NearbyShare backend, as well as fields computed by logging tab. + * Type: {!LogMessage} + */ + item: { + type: Object, + observer: 'itemChanged_', + }, + }, + + /** + * Sets the log message style based on severity level. + * @private + */ + itemChanged_() { + switch (this.item.severity) { + case Severity.WARNING: + this.$['item'].className = 'warning-log'; + break; + case Severity.ERROR: + this.$['item'].className = 'error-log'; + break; + case Severity.VERBOSE: + this.$['item'].className = 'verbose-log'; + break; + default: + this.$['item'].className = 'default-log'; + break; + } + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/logging_tab.html b/chromium/chrome/browser/resources/nearby_internals/logging_tab.html new file mode 100644 index 00000000000..3bfb9b62646 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/logging_tab.html @@ -0,0 +1,35 @@ +<style include="shared-style"> + :host { + --standard-border: 1px solid black; + } + + #logs-list { + display: flex; + flex-direction: column; + height: 100%; + } + + log-object { + border-top: var(--standard-border); + border-right: var(--standard-border); + border-left: var(--standard-border); + } + + log-object:last-child { + border-bottom: var(--standard-border); + } +</style> +<cr-button disabled="[[!logList_.length]]" class="internals-button" + on-click="onSaveLogsButtonClicked_"> + Save Logs +</cr-button> +<cr-button disabled="[[!logList_.length]]" class="internals-button" + on-click="onClearLogsButtonClicked_"> + Clear Logs +</cr-button> +<iron-list items="[[logList_]]" as="log" id="logs-list"> + <template> + <log-object item="[[log]]"> + </log-object> + </template> +</iron-list> diff --git a/chromium/chrome/browser/resources/nearby_internals/logging_tab.js b/chromium/chrome/browser/resources/nearby_internals/logging_tab.js new file mode 100644 index 00000000000..47ecc9a47da --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/logging_tab.js @@ -0,0 +1,164 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import './log_object.js'; +import './shared_style.js'; + +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {NearbyLogsBrowserProxy} from './nearby_logs_browser_proxy.js'; +import {LogMessage, Severity} from './types.js'; + +/** + * Converts log message to string format for saved download file. + * @param {!LogMessage} log + * @return {string} + */ +function logToSavedString_(log) { + // Convert to string value for |line.severity|. + let severity; + switch (log.severity) { + case Severity.INFO: + severity = 'INFO'; + break; + case Severity.WARNING: + severity = 'WARNING'; + break; + case Severity.ERROR: + severity = 'ERROR'; + break; + case Severity.VERBOSE: + severity = 'VERBOSE'; + break; + } + + // Reduce the file path to just the file name for logging simplification. + const file = log.file.substring(log.file.lastIndexOf('/') + 1); + + return `[${log.time} ${severity} ${file} (${log.line})] ${log.text}`; +} + +Polymer({ + is: 'logging-tab', + + _template: html`{__html_template__}`, + + behaviors: [ + WebUIListenerBehavior, + ], + + properties: { + + /** + * @private {!Array<!LogMessage>} + */ + logList_: { + type: Array, + value: [], + }, + }, + + /** @private {?NearbyLogsBrowserProxy}*/ + browserProxy_: null, + + /** + * Initialize |browserProxy_| and |logList_|. + * @override + */ + created() { + this.browserProxy_ = NearbyLogsBrowserProxy.getInstance(); + }, + + /** + * When the page is initialized, notify the C++ layer and load in the + * contents of its log buffer. Initialize WebUI Listeners. + * @override + */ + attached() { + this.addWebUIListener( + 'log-message-added', log => this.onLogMessageAdded_(log)); + this.addWebUIListener( + 'log-buffer-cleared', () => this.onWebUILogBufferCleared_()); + this.browserProxy_.getLogMessages().then( + logs => this.onGetLogMessages_(logs)); + }, + + /** + * Clears javascript logs displayed, but c++ log buffer remains. + * @private + */ + onClearLogsButtonClicked_() { + this.clearLogBuffer_(); + }, + + /** + * Saves and downloads javascript logs that appear on the page. + * @private + */ + onSaveLogsButtonClicked_() { + const blob = new Blob( + this.getSerializedLogStrings_(), {type: 'text/plain;charset=utf-8'}); + const url = URL.createObjectURL(blob); + + const anchorElement = document.createElement('a'); + anchorElement.href = url; + anchorElement.download = + 'nearby_internals_logs_' + new Date().toJSON() + '.txt'; + document.body.appendChild(anchorElement); + anchorElement.click(); + + window.setTimeout(function() { + document.body.removeChild(anchorElement); + window.URL.revokeObjectURL(url); + }, 0); + }, + + /** + * Iterates through log messages in |logList_| and prepares them for download. + * @private + * @return + */ + getSerializedLogStrings_() { + return this.logList_.map(logToSavedString_); + }, + + /** + * Adds a log message to the javascript log list displayed. Called from the + * C++ WebUI handler when a log message is added to the log buffer. + * @param {!Array<!LogMessage>} log + * @private + */ + onLogMessageAdded_(log) { + this.logList_.unshift(log); + }, + + /** + * Called in response to WebUI handler clearing log buffer. + * @private + */ + onWebUILogBufferCleared_() { + this.clearLogBuffer_(); + }, + + /** + * Parses an array of log messages and adds to the javascript list sent in + * from the initial page load. + * @param {!Array<!LogMessage>} logs + * @private + */ + onGetLogMessages_(logs) { + this.logList_ = logs.reverse().concat(this.logList_); + }, + + /** + * Clears the javascript log buffer. + * @private + */ + clearLogBuffer_() { + this.logList_ = []; + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js b/chromium/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js new file mode 100644 index 00000000000..8545af3e62f --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js @@ -0,0 +1,32 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {ContactUpdate} from './types.js'; + +/** + * JavaScript hooks into the native WebUI handler to pass Contacts to the + * Contacts tab. + */ +export class NearbyContactBrowserProxy { + /** + * Initializes web contents in the WebUI handler. + */ + initialize() { + chrome.send('initializeContacts'); + } + + /** + * Downloads the user's contact list from the Nearby Share server. We can + * force a download by passing |onlyDownloadIfContactsChanged| as false, + * or we can choose to only download contacts if they have changed since the + * last RPC call by passing in true. + * @param {boolean} onlyDownloadIfContactsChanged + */ + downloadContacts(onlyDownloadIfContactsChanged) { + chrome.send('downloadContacts', [onlyDownloadIfContactsChanged]); + } +} + +addSingletonGetter(NearbyContactBrowserProxy); diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js b/chromium/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js new file mode 100644 index 00000000000..97ea22ff1b4 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js @@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {HttpMessage} from './types.js'; + +/** + * JavaScript hooks into the native WebUI handler to pass HttpMessages to the + * Http Messages tab. + */ +export class NearbyHttpBrowserProxy { + /** + * Initializes web contents in the WebUI handler. + */ + initialize() { + chrome.send('initializeHttp'); + } + + /** + * Triggers UpdateDevice RPC. + */ + updateDevice() { + chrome.send('updateDevice'); + } + + /** + * Triggers ListContactPeople RPC. + */ + listContactPeople() { + chrome.send('listContactPeople'); + } + + /** + * Triggers ListPublicCertificates RPC. + */ + listPublicCertificates() { + chrome.send('listPublicCertificates'); + } +} + +addSingletonGetter(NearbyHttpBrowserProxy); diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_internals.html b/chromium/chrome/browser/resources/nearby_internals/nearby_internals.html index ff39aaf9aee..a392dec32f4 100644 --- a/chromium/chrome/browser/resources/nearby_internals/nearby_internals.html +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_internals.html @@ -1 +1,38 @@ -<h1>Hello, world!!</h1> +<style> + :host { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + } + + app-header { + background-color: rgb(0, 134, 179); + color: white; + font-size: 200%; + padding: 8px; + text-align: center; + } + + iron-pages { + flex: 1; + overflow: hidden; + } + + iron-pages > * { + display: block; + height: 100%; + overflow: auto; + } +</style> +<app-header> + <app-toolbar>Nearby Share Internals</app-toolbar> +</app-header> +<iron-location path="{{path_}}"></iron-location> +<cr-tabs selected="{{selectedTabIndex_}}" tab-names="[[tabNames_]]"></cr-tabs> +<iron-pages selected="[[selectedTabIndex_]]"> + <logging-tab></logging-tab> + <http-tab></http-tab> + <contact-tab></contact-tab> + <ui-trigger-tab></ui-trigger-tab> +</iron-pages> diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_internals.js b/chromium/chrome/browser/resources/nearby_internals/nearby_internals.js index a7f1da3568b..eb9b5542acd 100644 --- a/chromium/chrome/browser/resources/nearby_internals/nearby_internals.js +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_internals.js @@ -2,10 +2,82 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.m.js'; +import 'chrome://resources/polymer/v3_0/iron-location/iron-location.js'; +import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js'; +import './http_tab.js'; +import './logging_tab.js'; +import './contact_tab.js'; +import './ui_trigger_tab.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; Polymer({ is: 'nearby-internals', _template: html`{__html_template__}`, + + properties: { + /** @private */ + selectedTabIndex_: { + type: Number, + value: 0, + observer: 'selectedTabChanged_', + }, + + /** @private */ + path_: { + type: String, + value: '', + observer: 'pathChanged_', + }, + + /** @private */ + tabNames_: { + type: Array, + value: () => ['Logs', 'HTTP Messages', 'Contacts', 'UI Triggers'], + readonly: true, + }, + + }, + + /** + * Updates the current tab location to reflect selection change + * @param {number} newValue + * @param {number|undefined} oldValue + * @private + */ + selectedTabChanged_(newValue, oldValue) { + if (!oldValue) { + return; + } + const defaultTab = this.tabNames_[0].toLowerCase(); + const lowerCaseTabName = this.tabNames_[newValue].toLowerCase(); + this.path_ = + '/' + (lowerCaseTabName === defaultTab ? '' : lowerCaseTabName); + }, + + /** + * Returns the index of the currently selected tab corresponding to the + * path or zero if no match. + * @param {string} path + * @return {number} + * @private + */ + selectedTabFromPath_(path) { + const index = this.tabNames_.findIndex(tab => path === tab.toLowerCase()); + if (index < 0){ + return 0; + } + return index; + }, + + /** + * Updates the selection property on path change. + * @param {string} newValue + * @param {string|undefined} oldValue + * @private + */ + pathChanged_(newValue, oldValue) { + this.selectedTabIndex_ = this.selectedTabFromPath_(newValue.substr(1)); + }, }); diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_internals_resources.grd b/chromium/chrome/browser/resources/nearby_internals/nearby_internals_resources.grd index d7477df60d6..6254bf1f328 100644 --- a/chromium/chrome/browser/resources/nearby_internals/nearby_internals_resources.grd +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_internals_resources.grd @@ -11,14 +11,65 @@ <output filename="nearby_internals_resources.pak" type="data_package" /> </outputs> <release seq="1"> - <includes> + <includes> + <include name="IDR_NEARBY_INTERNALS_TYPES_JS" + file="types.js" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_HTTP_MESSAGE_OBJECT_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\http_message_object.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_HTTP_TAB_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\http_tab.js" + use_base_dir="false" + type="BINDATA"/> <include name="IDR_NEARBY_INTERNALS_INDEX_HTML" file="index.html" type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_LOG_OBJECT_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\log_object.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_LOGGING_TAB_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\logging_tab.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_UI_TRIGGER_TAB_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\ui_trigger_tab.js" + use_base_dir="false" + type="BINDATA"/> <include name="IDR_NEARBY_INTERNALS_NEARBY_INTERNALS_JS" file="${root_gen_dir}\chrome\browser\resources\nearby_internals\nearby_internals.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_NEARBY_HTTP_BROWSER_PROXY_JS" + file="nearby_http_browser_proxy.js" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_NEARBY_LOGS_BROWSER_PROXY_JS" + file="nearby_logs_browser_proxy.js" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_NEARBY_UI_TRIGGER_BROWSER_PROXY_JS" + file="nearby_ui_trigger_browser_proxy.js" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_SHARED_STYLE_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\shared_style.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_CONTACT_OBJECT_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\contact_object.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_CONTACT_TAB_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\contact_tab.js" + use_base_dir="false" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_NEARBY_CONTACT_BROWSER_PROXY_JS" + file="nearby_contact_browser_proxy.js" + type="BINDATA"/> + <include name="IDR_NEARBY_INTERNALS_UI_TRIGGER_LIST_OBJECT_JS" + file="${root_gen_dir}\chrome\browser\resources\nearby_internals\ui_trigger_list_object.js" + use_base_dir="false" + type="BINDATA"/> </includes> </release> </grit> diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_logs_browser_proxy.js b/chromium/chrome/browser/resources/nearby_internals/nearby_logs_browser_proxy.js new file mode 100644 index 00000000000..d962138aad6 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_logs_browser_proxy.js @@ -0,0 +1,21 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {LogMessage} from './types.js'; + +/** + * JavaScript hooks into the native WebUI handler to pass LogMessages to the + * logging tab. + */ +export class NearbyLogsBrowserProxy { + /** + * @return {!Promise<!Array<!LogMessage>>} + */ + getLogMessages() { + return sendWithPromise('getLogMessages'); + } +} + +addSingletonGetter(NearbyLogsBrowserProxy); diff --git a/chromium/chrome/browser/resources/nearby_internals/nearby_ui_trigger_browser_proxy.js b/chromium/chrome/browser/resources/nearby_internals/nearby_ui_trigger_browser_proxy.js new file mode 100644 index 00000000000..b17eb159980 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/nearby_ui_trigger_browser_proxy.js @@ -0,0 +1,114 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {StatusCode} from './types.js'; + +/** + * JavaScript hooks into the native WebUI handler to pass information to the + * UI Trigger tab. + */ +export class NearbyUiTriggerBrowserProxy { + /** + * Initializes web contents in the WebUI handler. + */ + initialize() { + chrome.send('initializeUiTrigger'); + } + + /** + * Invokes the NearbyShare service's SendText() method for the input + * ShareTarget |id| + * @param {string} id + */ + sendText(id) { + chrome.send('sendText', [id]); + } + + /** + * Invokes the NearbyShare service's Cancel() method for the input + * ShareTarget |id| + * @param {string} id + */ + cancel(id) { + chrome.send('cancel', [id]); + } + + /** + * Invokes the NearbyShare service's Accept() method for the input + * ShareTarget |id| + * @param {string} id + */ + accept(id) { + chrome.send('accept', [id]); + } + + /** + * Invokes the NearbyShare service's Reject() method for the input + * ShareTarget |id| + * @param {string} id + */ + reject(id) { + chrome.send('reject', [id]); + } + + /** + * Invokes the NearbyShare service's Open() method for the input + * ShareTarget |id| + * @param {string} id + */ + open(id) { + chrome.send('open', [id]); + } + + /** + * Registers the UI trigger handler instance as a foreground send surface. + * @return {!Promise<!StatusCode>} + */ + registerSendSurfaceForeground() { + return sendWithPromise('registerSendSurfaceForeground'); + } + + /** + * Registers the UI trigger handler instance as a background send surface. + * @return {!Promise<!StatusCode>} + */ + registerSendSurfaceBackground() { + return sendWithPromise('registerSendSurfaceBackground'); + } + + /** + * Unregisters the send surface UI trigger handler instance. + * @return {!Promise<!StatusCode>} + */ + unregisterSendSurface() { + return sendWithPromise('unregisterSendSurface'); + } + + /** + * Registers the UI trigger handler instance as a foreground receive surface. + * @return {!Promise<!StatusCode>} + */ + registerReceiveSurfaceForeground() { + return sendWithPromise('registerReceiveSurfaceForeground'); + } + + /** + * Registers the UI trigger handler instance as a background receive surface. + * @return {!Promise<!StatusCode>} + */ + registerReceiveSurfaceBackground() { + return sendWithPromise('registerReceiveSurfaceBackground'); + } + + /** + * Unregisters the receive surface UI trigger handler instance. + * @return {!Promise<!StatusCode>} + */ + unregisterReceiveSurface() { + return sendWithPromise('unregisterReceiveSurface'); + } +} + +addSingletonGetter(NearbyUiTriggerBrowserProxy); diff --git a/chromium/chrome/browser/resources/nearby_internals/shared_style.html b/chromium/chrome/browser/resources/nearby_internals/shared_style.html new file mode 100644 index 00000000000..cb589e372ec --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/shared_style.html @@ -0,0 +1,16 @@ +<template> + <style include="cr-shared-style"> + :host { + cursor: default; + font-family: monospace; + font-size: 12px; + } + + .internals-button { + background-color: rgb(0, 134, 179); + color: white; + font-family: Roboto; + margin: 5px; + } + </style> +</template> diff --git a/chromium/chrome/browser/resources/nearby_internals/shared_style.js b/chromium/chrome/browser/resources/nearby_internals/shared_style.js new file mode 100644 index 00000000000..ce15f9678d6 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/shared_style.js @@ -0,0 +1,10 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/shared_style_css.m.js'; +const template = document.createElement('template'); +template.innerHTML = ` +<dom-module id="shared-style">{__html_template__}</dom-module> +`; +document.body.appendChild(template.content.cloneNode(true)); diff --git a/chromium/chrome/browser/resources/nearby_internals/types.js b/chromium/chrome/browser/resources/nearby_internals/types.js new file mode 100644 index 00000000000..6d6d6a539f0 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/types.js @@ -0,0 +1,127 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Severity enum based on LogMessage format. Needs to stay in sync with the + * NearbyInternalsLogsHandler. + * @enum {number} + */ +export const Severity = { + VERBOSE: -1, + INFO: 0, + WARNING: 1, + ERROR: 2, +}; + +/** + * The type of log message object. The definition is based on + * chrome/browser/ui/webui/nearby_internals/nearby_internals_logs_handler.cc: + * LogMessageToDictionary() + * @typedef {{text: string, + * time: string, + * file: string, + * line: number, + * severity: Severity}} + */ +export let LogMessage; + +/** + * RPC enum based on the HTTP request/response object. Needs to stay in sync + * with the NearbyInternalsHttpHandler C++ code, defined in + * chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc. + * @enum {number} + */ +export const Rpc = { + CERTIFICATE: 0, + CONTACT: 1, + DEVICE: 2 +}; + +/** + * Direction enum based on the HTTP request/response object. Needs to stay in + * sync with the NearbyInternalsHttpHandler C++ code, defined in + * chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc. + * @enum {number} + */ +export const Direction = { + REQUEST: 0, + RESPONSE: 1 +}; + +/** + * The HTTP request/response object, sent by NearbyInternalsHttpHandler + * chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc. + * @typedef {{body: string, + * time: number, + * rpc: !Rpc, + * direction: !Direction}} + */ +export let HttpMessage; + +/** + * The ContactUpdate message object sent by NearbyInternalsContactsHandler + * chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc. + * @typedef {{time: number, + * contactsPassed: boolean, + * contactsListChanged: boolean, + * contactsAddedToAllowlist: boolean, + * contactsRemovedFromAllowlist: boolean, + * allowedIds: string, + * contactRecords: string}} + */ +export let ContactUpdate; + +/** + * The StatusCode callback object, sent by NearbyInternalsUiTriggerHandler + * chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc. + * @typedef {{statusCode: string, + * time: number, + * triggerEvent: string}} + */ +export let StatusCode; + +/** + * The TransferMetadata callback object, sent by NearbyInternalsUiTriggerHandler + * chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc. + * @typedef {{transferMetadataStatus: string, + * time: number, + * deviceName: string, + * shareTargetId: string}} + */ +export let TransferMetadataStatus; + +/** + * Timestamped message object that allows us to display information passed in + * from the WebUIHandler in the list of the UI trigger tab. + * @typedef {{message: string, + * time: number}} + */ +export let TimestampedMessage; + +/** + * Share Target object sent by NearbyInternalsUiTriggerHandler on discovery or + * lost. + * @typedef {{deviceName: string, + * shareTargetId: string, + * time: number}} + */ +export let ShareTarget; + +/** + * ShareTargetDiscoveryChange enum for display when ShareTarget is lost or + * discovered. + * @enum {number} + */ +export const ShareTargetDiscoveryChange = { + DISCOVERED: 0, + LOST: 1 +}; + +/** + * Select object for displaying passed in ShareTargets in selection list. + * @typedef {{name: string, + * selected: boolean, + * value: string}} + */ +export let ShareTargetSelectOption; diff --git a/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.html b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.html new file mode 100644 index 00000000000..7af6d27041d --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.html @@ -0,0 +1,25 @@ +<style> + #generic-object { + left: 0; + padding-left: 5px; + position: absolute; + text-align: left; + width: 100%; + } + + #time { + font-size: 10px; + padding: 5px; + position: absolute; + right: 0; + } + + #item { + margin: 10px; + padding: 10px; + } +</style> +<div id="item"> + <span id="generic-object">[[item.message]]</span> + <span id="time">[[formatTime_(item.time)]]</span> +</div> diff --git a/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.js b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.js new file mode 100644 index 00000000000..cd770a6498a --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_list_object.js @@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {TimestampedMessage} from './types.js'; + +Polymer({ + is: 'ui-trigger-object', + + _template: html`{__html_template__}`, + + properties: { + /** + * Underlying StatusCode data for this item. Contains read-only fields + * from the NearbyShare back-end. + * Type: {!TimestampedMessage} + */ + timestampedMessage: { + type: Object, + }, + }, + + /** + * Sets the string representation of time. + * @private + * @param {number} time + * @return {string} + */ + formatTime_(time) { + const d = new Date(time); + return d.toLocaleTimeString(); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.html b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.html new file mode 100644 index 00000000000..cd99dd76ad1 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.html @@ -0,0 +1,102 @@ +<style include="shared-style"> + :host { + --standard-border: 1px solid black; + } + + ui-trigger-object:last-child { + border-bottom: var(--standard-border); + } + + ui-trigger-object { + border-left: var(--standard-border); + border-right: var(--standard-border); + border-top: var(--standard-border); + } + + .buttons { + display: flex; + } + + #logging-section { + width: 100%; + } + + #share-select { + padding-right: 10px; + } + + #flex { + flex: 1; + } + + cr-button { + height: 35px; + padding: 5px; + width: 150px; + } +</style> +<div> + <div class="buttons"> + <cr-button class="internals-button" + on-click="onRegisterSendSurfaceBackgroundClicked_"> + Register Background SendSurface + </cr-button> + <cr-button class="internals-button" + on-click="onRegisterSendSurfaceForegroundClicked_"> + Register Foreground SendSurface + </cr-button> + <cr-button class="internals-button" + on-click="onUnregisterSendSurfaceClicked_"> + Unregister Current SendSurface + </cr-button> + <span id="flex"></span> + <cr-button on-click="onAcceptClicked_" class="internals-button" + class="trigger-button" disabled="[[!shareTargetSelectOptionList_.length]]"> + Accept + </cr-button> + <cr-button on-click="onRejectClicked_" class="internals-button" + class="trigger-button" disabled="[[!shareTargetSelectOptionList_.length]]"> + Reject + </cr-button> + <cr-button on-click="onOpenClicked_" class="internals-button" + class="trigger-button" disabled="[[!shareTargetSelectOptionList_.length]]"> + Open + </cr-button> + </div> + <div class="buttons"> + <cr-button class="internals-button" + on-click="onRegisterReceiveSurfaceBackgroundClicked_"> + Register Background ReceiveSurface + </cr-button> + <cr-button class="internals-button" + on-click="onRegisterReceiveSurfaceForegroundClicked_"> + Register Foreground ReceiveSurface + </cr-button> + <cr-button class="internals-button" + on-click="onUnregisterReceiveSurfaceClicked_"> + Unregister Current ReceiveSurface + </cr-button> + <span id="flex"></span> + <select id="share-select" on-change="onSelectChange_"> + <template is="dom-repeat" items="[[shareTargetSelectOptionList_]]"> + <option value="[[item.value]]" selected="[[item.selected]]"> + [[item.name]] + </option> + </template> + </select> + <cr-button on-click="onSendTextClicked_" class="internals-button" + class="trigger-button" disabled="[[!shareTargetSelectOptionList_.length]]"> + Send Text + </cr-button> + <cr-button on-click="onCancelClicked_" class="internals-button" + class="trigger-button" disabled="[[!shareTargetSelectOptionList_.length]]"> + Cancel + </cr-button> + </div> +</div> +<iron-list items="[[uiTriggerObjectList_]]" as="generic-object" id="logging-section"> + <template> + <ui-trigger-object item="[[generic-object]]"> + </ui-trigger-object> + </template> +</iron-listt> diff --git a/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.js b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.js new file mode 100644 index 00000000000..fd10bc54f08 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_internals/ui_trigger_tab.js @@ -0,0 +1,300 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import './ui_trigger_list_object.js'; +import './shared_style.js'; + +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {NearbyUiTriggerBrowserProxy} from './nearby_ui_trigger_browser_proxy.js'; +import {ShareTarget, ShareTargetDiscoveryChange, ShareTargetSelectOption, StatusCode, TimestampedMessage, TransferMetadataStatus} from './types.js'; + +Polymer({ + is: 'ui-trigger-tab', + + _template: html`{__html_template__}`, + + behaviors: [ + WebUIListenerBehavior, + ], + + properties: { + + /** @private {!Array<!TimestampedMessage>} */ + uiTriggerObjectList_: { + type: Array, + value: [], + }, + + /** @private {!Array<!ShareTargetSelectOption>} */ + shareTargetSelectOptionList_: { + type: Array, + value: [], + }, + + /** @private {string} ID of the selected ShareTarget or ''*/ + selectedShareTargetId_: String, + }, + + /** @private {?NearbyUiTriggerBrowserProxy}*/ + browserProxy_: null, + + /** + * Initialize |browserProxy_|,|selectedShareTargetId_|, and + * |shareTargetSelectOptionList_|. + * @override + */ + created() { + this.browserProxy_ = NearbyUiTriggerBrowserProxy.getInstance(); + }, + + /** + * When the page is initialized, notify the C++ layer to allow JavaScript and + * initialize WebUI Listeners. + * @override + */ + attached() { + this.addWebUIListener( + 'transfer-updated', + transferUpdate => this.onTransferUpdateAdded_(transferUpdate)); + this.addWebUIListener( + 'share-target-discovered', + shareTarget => this.onShareTargetDiscovered_(shareTarget)); + this.addWebUIListener( + 'share-target-lost', + shareTarget => this.onShareTargetLost_(shareTarget)); + this.addWebUIListener( + 'on-status-code-returned', + statusCode => this.onStatusCodeReturned_(statusCode)); + this.addWebUIListener( + 'share-target-map-updated', + shareTargetMapUpdate => + this.onShareTargetMapChanged_(shareTargetMapUpdate)); + this.browserProxy_.initialize(); + }, + + /** + * Triggers RegisterSendSurface with Foreground as Send state. + * @private + */ + onRegisterSendSurfaceForegroundClicked_() { + this.browserProxy_.registerSendSurfaceForeground().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Triggers RegisterSendSurface with Background as Send state. + * @private + */ + onRegisterSendSurfaceBackgroundClicked_() { + this.browserProxy_.registerSendSurfaceBackground().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Triggers UnregisterSendSurface. + * @private + */ + onUnregisterSendSurfaceClicked_() { + this.browserProxy_.unregisterSendSurface().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Triggers RegisterReceiveSurface with Foreground as Receive state. + * @private + */ + onRegisterReceiveSurfaceForegroundClicked_() { + this.browserProxy_.registerReceiveSurfaceForeground().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Triggers RegisterReceiveSurface with Background as Receive state. + * @private + */ + onRegisterReceiveSurfaceBackgroundClicked_() { + this.browserProxy_.registerReceiveSurfaceBackground().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Triggers UnregisterReceiveSurface. + * @private + */ + onUnregisterReceiveSurfaceClicked_() { + this.browserProxy_.unregisterReceiveSurface().then( + statusCode => this.onStatusCodeReturned_(statusCode)); + }, + + /** + * Logs status code returned by triggered events. + * @param {!StatusCode} statusCode + * @private + */ + onStatusCodeReturned_(statusCode) { + const message = + statusCode.triggerEvent + ' Result: ' + statusCode.statusCode; + const time = statusCode.time; + this.unshift('uiTriggerObjectList_', {'message': message, 'time': time}); + }, + + /** + * Triggers sendText with selected |shareTargetId|. + * @private + */ + onSendTextClicked_() { + this.browserProxy_.sendText(this.selectedShareTargetId_); + }, + + /** + * Triggers Accept with selected |shareTargetId|. + * @private + */ + onAcceptClicked_() { + this.browserProxy_.accept(this.selectedShareTargetId_); + }, + + /** + * Triggers Reject with selected |shareTargetId|. + * @private + */ + onRejectClicked_() { + this.browserProxy_.reject(this.selectedShareTargetId_); + }, + + /** + * Triggers Cancel with selected |shareTargetId|. + * @private + */ + onCancelClicked_() { + this.browserProxy_.cancel(this.selectedShareTargetId_); + }, + + /** + * Triggers Open with selected |shareTargetId|. + * @private + */ + onOpenClicked_() { + this.browserProxy_.open(this.selectedShareTargetId_); + }, + + /** + * Updates |selectedShareTargetId_| with the new selected option. + * @private + */ + onSelectChange_() { + this.selectedShareTargetId_ = + this.shadowRoot.querySelector('#share-select').selectedOptions[0].value; + }, + + /** + * Parses an array of ShareTargets and adds to the JavaScript list + * |shareTargetSelectOptionList_| to be displayed in select list. + * @param {!Array<!ShareTarget>} shareTargetMapUpdate + * @private + */ + onShareTargetMapChanged_(shareTargetMapUpdate) { + this.shareTargetSelectOptionList_ = []; + shareTargetMapUpdate.forEach((shareTarget) => { + const name = `${shareTarget.deviceName} (${shareTarget.shareTargetId})`; + const value = shareTarget.shareTargetId; + const selected = value === this.selectedShareTargetId_; + this.push( + 'shareTargetSelectOptionList_', + {'name': name, 'selected': selected, 'value': value}); + }); + }, + + /** + * Handles ShareTargets when they are discovered in the C++. + * @param {!ShareTarget} shareTarget + * @private + */ + onShareTargetDiscovered_(shareTarget) { + this.convertShareTargetToTimestampedMessageAndAppendToList_( + shareTarget, ShareTargetDiscoveryChange.DISCOVERED); + }, + + /** + * Handles ShareTargets when they are lost in the C++. + * @param {!ShareTarget} shareTarget + * @private + */ + onShareTargetLost_(shareTarget) { + this.convertShareTargetToTimestampedMessageAndAppendToList_( + shareTarget, ShareTargetDiscoveryChange.LOST); + }, + + /** + * Adds |transferUpdate| sent in from WebUI listener to the displayed list. + * @param {!TransferMetadataStatus} transferUpdate + * @private + */ + onTransferUpdateAdded_(transferUpdate) { + this.convertTransferUpdateTimestampedMessageAndAppendToList_( + transferUpdate); + }, + + /** + * Converts |transferUpdate| sent in to a generic object to be displayed. + * @param {!TransferMetadataStatus} transferUpdate + * @private + */ + convertTransferUpdateTimestampedMessageAndAppendToList_(transferUpdate) { + const time = transferUpdate.time; + const message = + `${transferUpdate.deviceName} (${transferUpdate.shareTargetId}): ${ + transferUpdate.transferMetadataStatus}`; + this.unshift('uiTriggerObjectList_', {'message': message, 'time': time}); + }, + + /** + * Converts |statusCode| sent in to a generic object to be displayed. + * @param {!StatusCode} statusCode + * @private + */ + convertStatusCodeToTimestampedMessageAndAppendToList_(statusCode) { + const time = statusCode.time; + const message = `${statusCode.triggerEvent} ${statusCode.statusCode}`; + this.unshift('uiTriggerObjectList_', {'message': message, 'time': time}); + }, + + /** + * Converts |shareTarget| sent in to when discovered/lost a generic object to + * be displayed. + * @private + * @param {!ShareTarget} shareTarget + * @param {!ShareTargetDiscoveryChange} discoveryChange + */ + convertShareTargetToTimestampedMessageAndAppendToList_( + shareTarget, discoveryChange) { + const time = shareTarget.time; + const message = `${shareTarget.deviceName} (${shareTarget.shareTargetId}) ${ + this.shareTargetDirectionToString_(discoveryChange)}`; + this.unshift('uiTriggerObjectList_', {'message': message, 'time': time}); + }, + + /** + * Sets the string representation of ShareTargetDiscoveryChange + * |discoveryChange|. + * @private + * @param {!ShareTargetDiscoveryChange} discoveryChange + * @return + */ + shareTargetDirectionToString_(discoveryChange) { + switch (discoveryChange) { + case ShareTargetDiscoveryChange.DISCOVERED: + return 'discovered'; + break; + case ShareTargetDiscoveryChange.LOST: + return 'lost'; + break; + default: + break; + } + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/BUILD.gn b/chromium/chrome/browser/resources/nearby_share/BUILD.gn index 543394e5aaf..60b67b314a9 100644 --- a/chromium/chrome/browser/resources/nearby_share/BUILD.gn +++ b/chromium/chrome/browser/resources/nearby_share/BUILD.gn @@ -7,22 +7,93 @@ import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/nearby_share/", + "js_module_root=./gen/chrome/browser/resources/nearby_share/", + ] deps = [ ":app", + ":discovery_manager", + ":nearby_confirmation_page", + ":nearby_device", + ":nearby_device_icon", ":nearby_discovery_page", + ":nearby_preview", + ":nearby_progress", ] } js_library("app") { deps = [ + ":nearby_confirmation_page", ":nearby_discovery_page", + "./shared:nearby_onboarding_page.m", + "./shared:nearby_share_settings_behavior.m", + "./shared:nearby_visibility_page.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m", ] + extra_deps = [ "./shared:modulize" ] +} + +js_library("discovery_manager") { + deps = + [ "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile" ] +} + +js_library("nearby_confirmation_page") { + deps = [ + ":nearby_preview", + ":nearby_progress", + "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", + "//ui/webui/resources/js:i18n_behavior.m", + ] +} + +js_library("nearby_device") { + deps = [ + ":nearby_device_icon", + "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile", + "//third_party/polymer/v3_0/components-chromium/iron-icon", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("nearby_device_icon") { + deps = [ + "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile", + "//third_party/polymer/v3_0/components-chromium/iron-icon", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] } js_library("nearby_discovery_page") { deps = [ + ":discovery_manager", + ":nearby_device", + ":nearby_preview", + "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile", + "//third_party/polymer/v3_0/components-chromium/iron-list", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/js:assert.m", + ] +} + +js_library("nearby_preview") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("nearby_progress") { + deps = [ + ":nearby_device_icon", + "//chrome/browser/ui/webui/nearby_share:mojom_js_library_for_compile", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] } @@ -30,6 +101,12 @@ js_library("nearby_discovery_page") { html_to_js("web_components") { js_files = [ "app.js", + "icons.js", + "nearby_confirmation_page.js", + "nearby_device.js", + "nearby_device_icon.js", "nearby_discovery_page.js", + "nearby_preview.js", + "nearby_progress.js", ] } diff --git a/chromium/chrome/browser/resources/nearby_share/app.html b/chromium/chrome/browser/resources/nearby_share/app.html index e16336c4164..d671fcd6b9c 100644 --- a/chromium/chrome/browser/resources/nearby_share/app.html +++ b/chromium/chrome/browser/resources/nearby_share/app.html @@ -1,4 +1,18 @@ <cr-view-manager id="viewManager"> - <nearby-discovery-page id="[[Page.DISCOVERY]]" slot="view" class="active"> + <nearby-confirmation-page id="[[Page.CONFIRMATION]]" slot="view" + confirmation-manager="[[confirmationManager_]]" + confirmation-token="[[confirmationToken_]]" + share-target="[[selectedShareTarget_]]"> + </nearby-confirmation-page> + <nearby-discovery-page id="[[Page.DISCOVERY]]" slot="view" + confirmation-manager="{{confirmationManager_}}" + confirmation-token="{{confirmationToken_}}" + selected-share-target="{{selectedShareTarget_}}"> </nearby-discovery-page> + <nearby-onboarding-page id="[[Page.ONBOARDING]]" settings="{{settings}}" + slot="view"> + </nearby-onboarding-page> + <nearby-visibility-page id="[[Page.VISIBILITY]]" settings="{{settings}}" + slot="view"> + </nearby-visibility-page> </cr-view-manager> diff --git a/chromium/chrome/browser/resources/nearby_share/app.js b/chromium/chrome/browser/resources/nearby_share/app.js index fc77eb7ac2a..eb252ea174d 100644 --- a/chromium/chrome/browser/resources/nearby_share/app.js +++ b/chromium/chrome/browser/resources/nearby_share/app.js @@ -9,19 +9,27 @@ */ import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js'; +import './shared/nearby_onboarding_page.m.js'; +import './shared/nearby_visibility_page.m.js'; +import './nearby_confirmation_page.js'; import './nearby_discovery_page.js'; -import './strings.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {NearbyShareSettingsBehavior} from './shared/nearby_share_settings_behavior.m.js'; /** @enum {string} */ const Page = { + CONFIRMATION: 'confirmation', DISCOVERY: 'discovery', + ONBOARDING: 'onboarding', + VISIBILITY: 'visibility', }; Polymer({ is: 'nearby-share-app', + behaviors: [NearbyShareSettingsBehavior], + _template: html`{__html_template__}`, properties: { @@ -30,5 +38,80 @@ Polymer({ type: Object, value: Page, }, + + /** + * Set by the nearby-discovery-page component when switching to the + * nearby-confirmation-page. + * @type {?nearbyShare.mojom.ConfirmationManagerInterface} + * @private + */ + confirmationManager_: { + type: Object, + value: null, + }, + + /** + * Set by the nearby-discovery-page component when switching to the + * nearby-confirmation-page. + * @type {?String} + * @private + */ + confirmationToken_: { + type: String, + value: null, + }, + + /** + * The currently selected share target set by the nearby-discovery-page + * component when the user selects a device. + * @type {?nearbyShare.mojom.ShareTarget} + * @private + */ + selectedShareTarget_: { + type: Object, + value: null, + }, }, + + listeners: { + 'change-page': 'onChangePage_', + 'close': 'onClose_', + }, + + /** + * @return {!CrViewManagerElement} the view manager + * @private + */ + getViewManager_() { + return /** @type {!CrViewManagerElement} */ (this.$.viewManager); + }, + + /** + * Called when all settings values have been retrieved. + */ + onSettingsRetrieved() { + if (this.settings.enabled) { + this.getViewManager_().switchView(Page.DISCOVERY); + } else { + this.getViewManager_().switchView(Page.ONBOARDING); + } + }, + + /** + * Handler for the change-page event. + * @param {!CustomEvent<!{page: Page}>} event + * @private + */ + onChangePage_(event) { + this.getViewManager_().switchView(event.detail.page); + }, + + /** + * Handler for the close event. + * @param {!Event} event + * @private + */ + onClose_(event) { + // TODO(vecore): handle closing when share sheet is hooked up + } }); diff --git a/chromium/chrome/browser/resources/nearby_share/discovery_manager.js b/chromium/chrome/browser/resources/nearby_share/discovery_manager.js new file mode 100644 index 00000000000..ab684330f21 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/discovery_manager.js @@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Provides methods to get or set an instance of a + * DiscoveryManager which allows interaction with native code. + */ + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; + +/** @type {?nearbyShare.mojom.DiscoveryManagerInterface} */ +let discoveryManager = null; + +/** + * @param {!nearbyShare.mojom.DiscoveryManagerInterface} + * testDiscoveryManager A test discovery manager. + */ +export function setDiscoveryManagerForTesting(testDiscoveryManager) { + discoveryManager = testDiscoveryManager; +} + +/** + * @return {!nearbyShare.mojom.DiscoveryManagerInterface} Discovery manager. + */ +export function getDiscoveryManager() { + if (discoveryManager) { + return discoveryManager; + } + + discoveryManager = nearbyShare.mojom.DiscoveryManager.getRemote(); + discoveryManager.onConnectionError.addListener(() => discoveryManager = null); + return discoveryManager; +} diff --git a/chromium/chrome/browser/resources/nearby_share/icons.html b/chromium/chrome/browser/resources/nearby_share/icons.html new file mode 100644 index 00000000000..019a3e8e4d6 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/icons.html @@ -0,0 +1,16 @@ +<iron-iconset-svg name="nearby-share" size="24"> + <svg> + <defs> + <!-- Nearby Share icons --> + <g id="done"><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"></path></g> + + <!-- + These icons are copied from Polymer's iron-icons and kept in sorted order. + See http://goo.gl/Y1OdAq for instructions on adding additional icons. + --> + <g id="laptop"><path d="M20 18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"></path></g> + <g id="smartphone"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"></path></g> + <g id="tablet"><path d="M21 4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 1.99-.9 1.99-2L23 6c0-1.1-.9-2-2-2zm-2 14H5V6h14v12z"></path></g> + </defs> + </svg> +</iron-iconset-svg> diff --git a/chromium/chrome/browser/resources/nearby_share/icons.js b/chromium/chrome/browser/resources/nearby_share/icons.js new file mode 100644 index 00000000000..dd8c63d1990 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/icons.js @@ -0,0 +1,10 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; + +import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +const template = html`{__html_template__}`; +document.head.appendChild(template.content); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.html b/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.html new file mode 100644 index 00000000000..6ff74f3a780 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.html @@ -0,0 +1,103 @@ +<style> + #actions { + margin-inline-start: auto; + margin-top: auto; + } + + #add-contacts { + margin-top: 32px; + } + + #add-contacts-label { + color: rgb(32, 33, 36); + line-height: 138%; + } + + #add-contacts-label-secondary { + color: rgb(95, 99, 104); + line-height: 138%; + } + + #confirmation-token { + border-top: 1px dashed rgba(151, 151, 151, 0.74); + color: rgba(0, 0, 0, 0.4); + flex-grow: 1; + font-size: 90%; + letter-spacing: 0.3px; + margin-inline-end: -15px; + margin-top: 55px; + padding-top: 6px; + text-align: center; + } + + nearby-preview { + margin-inline-end: 10px; + margin-inline-start: 10px; + } + + nearby-progress { + margin-top: 15px; + width: 126px; + } + + #page-content { + box-sizing: border-box; + display: flex; + flex-direction: column; + height: 100%; + padding: 27px 32px 25px 37px; + } + + #process-row { + display: flex; + margin-top: 48px; + } + + #subtitle { + color: rgb(32, 33, 36); + font-size: 100%; + font-weight: normal; + line-height: 154%; + margin: 0; + } + + #title { + color: rgb(32, 33, 36); + font-size: 123%; + font-weight: normal; + letter-spacing: 0.27px; + line-height: 150%; + margin: 0; + } +</style> + +<div id="page-content"> + <h1 id="title">Share with this device...</h1> + <h2 id="subtitle">Your Chromebook is ready to share</h2> + + <div id="process-row"> + <nearby-preview title="Doggo.jpg"></nearby-preview> + <div id="confirmation-token"> + [[i18n('secureConnectionId', confirmationToken)]] + </div> + <nearby-progress share-target="[[shareTarget]]"></nearby-progress> + </div> + + <cr-checkbox id="add-contacts"> + <div id="add-contacts-label"> + Add Richard to contacts + </div> + <div id="add-contacts-label-secondary"> + Adding this contact will remember the next time you share + </div> + </cr-checkbox> + + <div id="actions"> + <cr-button id="cancel-button" class="cancel-button" on-click="onCancelTap_"> + Cancel + </cr-button> + <cr-button id="accept-button" class="action-button" on-click="onAcceptTap_"> + Confirm + </cr-button> + </div> +</div> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.js b/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.js new file mode 100644 index 00000000000..de2d74c7913 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_confirmation_page.js @@ -0,0 +1,80 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-confirmation-page' component shows a confirmation + * screen when sending data to a stranger. Strangers are devices of people that + * are not currently in the contacts of this user. + */ + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import './nearby_preview.js'; +import './nearby_progress.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; +import './strings.m.js'; + +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-confirmation-page', + + behaviors: [I18nBehavior], + + _template: html`{__html_template__}`, + + properties: { + /** + * ConfirmationManager interface for the currently selected share target. + * Expected to start as null, then change to a valid object before this + * component is shown. + * @type {?nearbyShare.mojom.ConfirmationManagerInterface} + */ + confirmationManager: { + type: Object, + value: null, + }, + + /** + * Token to show to the user to confirm the selected share target. Expected + * to start as null, then change to a valid object before this component is + * shown. + * @type {?string} + */ + confirmationToken: { + type: String, + value: null, + }, + + /** + * The selected share target to confirm the transfer for. Expected to start + * as null, then change to a valid object before this component is shown. + * @type {?nearbyShare.mojom.ShareTarget} + */ + shareTarget: { + type: Object, + value: null, + }, + }, + + /** @private */ + onAcceptTap_() { + this.confirmationManager.accept().then( + result => { + // TODO(knollr): Close dialog as send is now in progress. + }); + }, + + /** @private */ + onCancelTap_() { + this.confirmationManager.reject().then( + result => { + // TODO(knollr): Close dialog or go back to device discovery. + }); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_device.html b/chromium/chrome/browser/resources/nearby_share/nearby_device.html new file mode 100644 index 00000000000..71de158ac96 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_device.html @@ -0,0 +1,64 @@ +<style> + :host { + align-items: center; + border: 1px solid rgba(216, 216, 216, 0.76); + border-radius: 8px; + box-sizing: border-box; + display: flex; + height: 40px; + margin-block-end: 6px; + padding-block-end: 6px; + padding-block-start: 6px; + padding-inline-end: 9px; + padding-inline-start: 9px; + } + + :host(:focus) { + border-color: rgb(95, 99, 104); + outline: none; + } + + :host([is-selected]) { + border-color: rgb(66, 133, 244); + } + + :host([is-selected]) > #done { + display: flex; + } + + :host([is-selected]) > #name { + color: rgb(26, 115, 232); + } + + #done { + color: rgb(26, 115, 232); + display: none; + flex-shrink: 0; + height: 17px; + width: 17px; + } + + #icon { + --nearby-device-icon-size: 15px; + flex-shrink: 0; + height: 26px; + width: 26px; + } + + #name { + color: rgb(95, 99, 104); + flex-grow: 1; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.3px; + margin-inline-start: 11px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +</style> + +<nearby-device-icon id="icon" share-target="[[shareTarget]]"> +</nearby-device-icon> +<div id="name">[[shareTarget.name]]</div> +<iron-icon id="done" icon="nearby-share:done"></iron-icon> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_device.js b/chromium/chrome/browser/resources/nearby_share/nearby_device.js new file mode 100644 index 00000000000..13e560b094a --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_device.js @@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-device' component shows details of a remote device. + */ + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import './icons.js'; +import './nearby_device_icon.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-device', + + _template: html`{__html_template__}`, + + properties: { + /** + * Expected to start as null, then change to a valid object before this + * component is shown. + * @type {?nearbyShare.mojom.ShareTarget} + */ + shareTarget: { + type: Object, + value: null, + }, + + /** + * Whether this share target is selected. + * @type {boolean} + */ + isSelected: { + type: Boolean, + reflectToAttribute: true, + }, + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.html b/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.html new file mode 100644 index 00000000000..21bed52eff1 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.html @@ -0,0 +1,16 @@ +<style> + :host { + background-color: rgb(232, 240, 254); + border-radius: 50%; + display: flex; + } + + #icon { + color: rgb(26, 115, 232); + height: var(--nearby-device-icon-size, 24px); + margin: auto; + width: var(--nearby-device-icon-size, 24px); + } +</style> + +<iron-icon id="icon" icon="[[getShareTargetIcon_(shareTarget)]]"></iron-icon> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.js b/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.js new file mode 100644 index 00000000000..134864604e1 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_device_icon.js @@ -0,0 +1,56 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-device-icon' component shows an icon for a nearby + * device. This might be a user defined image or a generic icon based on device + * type. + */ + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import './icons.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-device-icon', + + _template: html`{__html_template__}`, + + properties: { + /** + * The share target to show the icon for. Expected to start as null, then + * change to a valid object before this component is shown. + * @type {?nearbyShare.mojom.ShareTarget} + */ + shareTarget: { + type: Object, + value: null, + }, + }, + + /** + * @return {string} + * @private + */ + getShareTargetIcon_() { + if (!this.shareTarget) { + return 'nearby-share:laptop'; + } + switch (this.shareTarget.type) { + case nearbyShare.mojom.ShareTargetType.kPhone: + return 'nearby-share:smartphone'; + case nearbyShare.mojom.ShareTargetType.kTablet: + return 'nearby-share:tablet'; + case nearbyShare.mojom.ShareTargetType.kLaptop: + return 'nearby-share:laptop'; + default: + return 'nearby-share:laptop'; + } + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.html b/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.html index cea179efa55..6c57f3e05ba 100644 --- a/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.html +++ b/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.html @@ -1 +1,125 @@ -<h1>Nearby Discovery Page</h1> +<style> + :host { + --nearby-page-space-block: 26px; + --nearby-page-space-inline: 32px; + --nearby-page-space-large-inline: 42px; + } + + #actions { + margin-block-end: var(--nearby-page-space-block); + margin-block-start: 17px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + text-align: end; + } + + #center-content { + background: radial-gradient(160% 50% at 0 100%, rgba(138, 180, 248, 0.25), + rgba(255, 255, 255, 0)); + box-sizing: border-box; + display: flex; + flex-direction: column; + flex-grow: 1; + overflow: hidden; + } + + #deviceList { + overflow: auto; + padding-inline-end: var(--nearby-page-space-large-inline); + padding-inline-start: var(--nearby-page-space-large-inline); + width: 191px; + } + + nearby-preview { + margin-inline-end: var(--nearby-page-space-large-inline); + margin-inline-start: var(--nearby-page-space-large-inline); + } + + #help { + color: rgb(95, 99, 104); + font-size: 9px; + line-height: 12px; + margin-block-end: 12px; + margin-block-start: 12px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + } + + #page-content { + display: flex; + flex-direction: column; + height: 100%; + } + + #process-row { + display: flex; + flex-grow: 1; + justify-content: space-between; + margin-block-start: 48px; + overflow: hidden; + } + + #subtitle { + color: rgb(32, 33, 36); + font-size: 100%; + font-weight: normal; + line-height: 154%; + margin-block-end: 0; + margin-block-start: 0; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + } + + #title { + color: rgb(32, 33, 36); + font-size: 123%; + font-weight: normal; + letter-spacing: 0.27px; + line-height: 150%; + margin-block-end: 0; + margin-block-start: var(--nearby-page-space-block); + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + } +</style> + +<div id="page-content"> + <h1 id="title">Nearby Share</h1> + <h2 id="subtitle">Select people you would like to share with</h2> + + <div id="center-content"> + + <div id="process-row"> + <nearby-preview title="Doggo.jpg"></nearby-preview> + <iron-list items="[[shareTargets_]]" id="deviceList" + selected-item="{{selectedShareTarget}}" + on-selected-item-changed="onSelectedShareTargetChanged_" + aria-rowcount$="[[shareTargets_.length]]" preserve-focus + selection-enabled> + <template> + <nearby-device tabindex$="[[tabIndex]]" share-target="[[item]]" + is-selected="[[isShareTargetSelected_( + item, selectedShareTarget)]]"> + </nearby-device> + </template> + </iron-list> + </div> + + <div id="help"> + Make sure both devices are unlocked, close together (within 1 ft), and + have Bluetooth turned on. If you’re sharing with a Chromebook make sure + Nearby Share is turned on from quick settings. + </div> + + </div> + + <div id="actions"> + <cr-button class="cancel-button"> + Cancel + </cr-button> + <cr-button id="next-button" class="action-button" on-click="onNextTap_" + disabled="[[!selectedShareTarget]]"> + Next + </cr-button> + </div> +</div> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.js b/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.js index 9b3308669a4..62cea756ea6 100644 --- a/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.js +++ b/chromium/chrome/browser/resources/nearby_share/nearby_discovery_page.js @@ -7,10 +7,232 @@ * the Nearby Share flow. It shows a list of devices to select from. */ +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; +import './nearby_device.js'; +import './nearby_preview.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; + +import {assert} from 'chrome://resources/js/assert.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {getDiscoveryManager} from './discovery_manager.js'; + +/** + * Converts an unguessable token to a string. + * @param {!mojoBase.mojom.UnguessableToken} token + * @return {!string} + */ +function tokenToString(token) { + return `${token.high.toString()}#${token.low.toString()}`; +} + +/** + * Compares two unguessable tokens. + * @param {!mojoBase.mojom.UnguessableToken} a + * @param {!mojoBase.mojom.UnguessableToken} b + */ +function tokensEqual(a, b) { + return a.high === b.high && a.low === b.low; +} + Polymer({ is: 'nearby-discovery-page', _template: html`{__html_template__}`, + + properties: { + /** + * ConfirmationManager interface for the currently selected share target. + * @type {?nearbyShare.mojom.ConfirmationManagerInterface} + */ + confirmationManager: { + notify: true, + type: Object, + value: null, + }, + + /** + * Token to show to the user to confirm the selected share target. + * @type {?string} + */ + confirmationToken: { + notify: true, + type: String, + value: null, + }, + + /** + * The currently selected share target. + * @type {?nearbyShare.mojom.ShareTarget} + */ + selectedShareTarget: { + notify: true, + type: Object, + value: null, + }, + + /** + * A list of all discovered nearby share targets. + * @private {!Array<!nearbyShare.mojom.ShareTarget>} + */ + shareTargets_: { + type: Array, + value: [], + }, + }, + + /** @private {nearbyShare.mojom.ShareTargetListenerCallbackRouter} */ + mojoEventTarget_: null, + + /** @private {Array<number>} */ + listenerIds_: null, + + /** @private {Map<!string,!nearbyShare.mojom.ShareTarget>} */ + shareTargetMap_: null, + + /** @private {?nearbyShare.mojom.ShareTarget} */ + lastSelectedShareTarget_: null, + + /** @override */ + attached() { + // TODO(knollr): Remove this once prototyping is done. + this.shareTargets_ = [ + { + id: {high: 0, low: 1}, + name: 'Alyssa\'s Pixel', + type: nearbyShare.mojom.ShareTargetType.kTablet, + }, + { + id: {high: 0, low: 2}, + name: 'Shangela\'s Pixel 2XL', + type: nearbyShare.mojom.ShareTargetType.kPhone, + }, + { + id: {high: 0, low: 3}, + name: 'Mira\'s Chromebook', + type: nearbyShare.mojom.ShareTargetType.kLaptop, + } + ]; + this.shareTargetMap_ = new Map(); + + this.mojoEventTarget_ = + new nearbyShare.mojom.ShareTargetListenerCallbackRouter(); + + this.listenerIds_ = [ + this.mojoEventTarget_.onShareTargetDiscovered.addListener( + this.onShareTargetDiscovered_.bind(this)), + this.mojoEventTarget_.onShareTargetLost.addListener( + this.onShareTargetLost_.bind(this)), + ]; + + // TODO(knollr): Only do this when the discovery page is actually shown. + getDiscoveryManager() + .startDiscovery(this.mojoEventTarget_.$.bindNewPipeAndPassRemote()) + .then(response => { + if (!response.success) { + // TODO(knollr): Show error. + return; + } + }); + }, + + /** @override */ + detached() { + this.listenerIds_.forEach( + id => assert(this.mojoEventTarget_.removeListener(id))); + this.mojoEventTarget_.$.close(); + }, + + /** + * @private + * @param {!nearbyShare.mojom.ShareTarget} shareTarget The discovered device. + */ + onShareTargetDiscovered_(shareTarget) { + const shareTargetId = tokenToString(shareTarget.id); + if (!this.shareTargetMap_.has(shareTargetId)) { + this.push('shareTargets_', shareTarget); + } else { + const index = this.shareTargets_.findIndex( + (target) => tokensEqual(target.id, shareTarget.id)); + assert(index !== -1); + this.splice('shareTargets_', index, 1, shareTarget); + this.updateSelectedShareTarget_(shareTarget.id, shareTarget); + } + this.shareTargetMap_.set(shareTargetId, shareTarget); + }, + + /** + * @private + * @param {!nearbyShare.mojom.ShareTarget} shareTarget The lost device. + */ + onShareTargetLost_(shareTarget) { + const index = this.shareTargets_.findIndex( + (target) => tokensEqual(target.id, shareTarget.id)); + assert(index !== -1); + this.splice('shareTargets_', index, 1); + this.shareTargetMap_.delete(tokenToString(shareTarget.id)); + this.updateSelectedShareTarget_(shareTarget.id, /*shareTarget=*/ null); + }, + + /** @private */ + onNextTap_() { + if (!this.selectedShareTarget) { + return; + } + + getDiscoveryManager() + .selectShareTarget(this.selectedShareTarget.id) + .then(response => { + const {result, token, confirmationManager} = response; + if (result !== nearbyShare.mojom.SelectShareTargetResult.kOk) { + // TODO(knollr): Show error. + return; + } + + if (confirmationManager) { + this.confirmationManager = confirmationManager; + this.confirmationToken = token; + this.fire('change-page', {page: 'confirmation'}); + } else { + // TODO(knollr): Close dialog as send is now in progress. + } + }); + }, + + /** @private */ + onSelectedShareTargetChanged_() { + // <iron-list> causes |this.$.deviceList.selectedItem| to be null if tapped + // a second time. Manually reselect the last item to preserve selection. + if (!this.$.deviceList.selectedItem && this.lastSelectedShareTarget_) { + this.$.deviceList.selectItem(this.lastSelectedShareTarget_); + } + this.lastSelectedShareTarget_ = this.$.deviceList.selectedItem; + }, + + /** + * @param {!nearbyShare.mojom.ShareTarget} shareTarget + * @return {boolean} + * @private + */ + isShareTargetSelected_(shareTarget) { + return this.selectedShareTarget === shareTarget; + }, + + /** + * Updates the selected share tagrget to |shareTarget| if its id matches |id|. + * @param {!mojoBase.mojom.UnguessableToken} id + * @param {?nearbyShare.mojom.ShareTarget} shareTarget + * @private + */ + updateSelectedShareTarget_(id, shareTarget) { + if (this.selectedShareTarget && + tokensEqual(this.selectedShareTarget.id, id)) { + this.lastSelectedShareTarget_ = shareTarget; + this.selectedShareTarget = shareTarget; + } + } }); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_preview.html b/chromium/chrome/browser/resources/nearby_share/nearby_preview.html new file mode 100644 index 00000000000..947755cedc2 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_preview.html @@ -0,0 +1,34 @@ +<style> + #background { + fill: rgb(232, 240, 254) + } + + #placeholder { + clip-rule: evenodd; + fill: rgb(28, 116, 233); + fill-opacity: 0.3; + fill-rule: evenodd; + } + + #svg { + display: block; + height: 110px; + margin: 0 auto; + width: 90px; + } + + #title { + color: rgb(95, 99, 104); + font-size: 13px; + letter-spacing: 0.2px; + line-height: 20px; + margin-top: 6px; + text-align: center; + } +</style> + +<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 110"> + <rect id="background" width="90" height="110" rx="4"></rect> + <path id="placeholder" d="M33 31v12a18 18 0 1020 22h14V31zm20 34a18 18 0 00-20-22v22h20z"></path> +</svg> +<div id="title">[[title]]</div> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_preview.js b/chromium/chrome/browser/resources/nearby_share/nearby_preview.js new file mode 100644 index 00000000000..d4373222dac --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_preview.js @@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-preview' component shows a preview of data to be + * sent to a remote device. The data might be some plain text, a URL or a file. + */ + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-preview', + + _template: html`{__html_template__}`, + + properties: { + /** The title to show below the preview graphic. */ + title: { + type: String, + value: '', + }, + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_progress.html b/chromium/chrome/browser/resources/nearby_share/nearby_progress.html new file mode 100644 index 00000000000..b05ab9c106f --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_progress.html @@ -0,0 +1,75 @@ +<style> + #device-name { + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + color: rgba(0, 0, 0, 0.87); + display: -webkit-box; + letter-spacing: 0.25px; + line-height: 154%; + margin-top: 10px; + overflow: hidden; + text-align: center; + } + + #icon { + height: 70px; + margin: auto; + width: 70px; + } + + #progress-container { + display: flex; + height: 80px; + margin: 0 auto; + position: relative; + width: 80px; + } + + #spinner { + animation: 1.4s ease-in-out infinite both spinner-animation; + fill: none; + stroke: rgb(26, 115, 232); + stroke-dasharray: 283; + stroke-linecap: round; + stroke-width: 2px; + transform-origin: 50% 50%; + } + + #svg { + animation: 2s linear infinite svg-animation; + left: 0; + position: absolute; + top: 0; + } + + @keyframes spinner-animation { + 0%, + 25% { + stroke-dashoffset: 280; + transform: rotate(0); + } + 50%, + 75% { + stroke-dashoffset: 75; + transform: rotate(45deg); + } + 100% { + stroke-dashoffset: 280; + transform: rotate(360deg); + } + } + + @keyframes svg-animation { + 0% { transform: rotateZ(0deg); } + 100% { transform: rotateZ(360deg); } + } +</style> + +<div id="progress-container"> + <svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80"> + <circle id="spinner" cx="40" cy="40" r="39"></circle> + </svg> + <nearby-device-icon id="icon" share-target="[[shareTarget]]"> + </nearby-device-icon> +</div> +<div id="device-name">[[shareTarget.name]]</div> diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_progress.js b/chromium/chrome/browser/resources/nearby_share/nearby_progress.js new file mode 100644 index 00000000000..ad2bf23c8f0 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/nearby_progress.js @@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-progress' component shows a progress indicator for + * a Nearby Share transfer to a remote device. It shows device icon and name, + * and a circular progress bar that only supports an indeterminate status for + * now. + */ + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import './nearby_device_icon.js'; +import './nearby_share_target_types.mojom-lite.js'; +import './nearby_share.mojom-lite.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-progress', + + _template: html`{__html_template__}`, + + properties: { + /** + * The share target to show the progress for. Expected to start as null, + * then change to a valid object before this component is shown. + * @type {?nearbyShare.mojom.ShareTarget} + */ + shareTarget: { + type: Object, + value: null, + }, + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd b/chromium/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd index 96a629ef628..0556aada067 100644 --- a/chromium/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd +++ b/chromium/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd @@ -16,13 +16,94 @@ file="nearby_share_dialog.html" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_MOJO_JS" + file="${root_gen_dir}/chrome/browser/ui/webui/nearby_share/nearby_share.mojom-lite.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_TARGET_TYPES_MOJO_JS" + file="${root_gen_dir}/chrome/browser/ui/webui/nearby_share/nearby_share_target_types.mojom-lite.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_MOJOM_LITE_JS" + file="${root_gen_dir}/chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom-lite.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_DISCOVERY_MANAGER_JS" + file="discovery_manager.js" + type="BINDATA"/> + + <!-- Shared Polymer 2 pages--> + <include name="IDR_NEARBY_CONTACT_VISIBILITY_HTML" + file="shared/nearby_contact_visibility.html" type="BINDATA"/> + <include name="IDR_NEARBY_CONTACT_VISIBILITY_JS" + file="shared/nearby_contact_visibility.js" type="BINDATA"/> + <include name="IDR_NEARBY_ONBOARDING_PAGE_HTML" + file="shared/nearby_onboarding_page.html" type="BINDATA"/> + <include name="IDR_NEARBY_ONBOARDING_PAGE_JS" + file="shared/nearby_onboarding_page.js" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_HTML" + file="shared/nearby_share_settings.html" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_JS" + file="shared/nearby_share_settings.js" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_BEHAVIOR_HTML" + file="shared/nearby_share_settings_behavior.html" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_BEHAVIOR_JS" + file="shared/nearby_share_settings_behavior.js" type="BINDATA"/> + <include name="IDR_NEARBY_SHARED_ICONS_HTML" + file="shared/nearby_shared_icons.html" type="BINDATA"/> + <include name="IDR_NEARBY_VISIBILITY_PAGE_HTML" + file="shared/nearby_visibility_page.html" type="BINDATA"/> + <include name="IDR_NEARBY_VISIBILITY_PAGE_JS" + file="shared/nearby_visibility_page.js" type="BINDATA"/> + + <!-- Shared images --> + <include name="IDR_NEARBY_SHARE_ONBOARDING_SPLASH_SVG" + file="shared/nearby_onboarding_splash.svg" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_DEVICE_VISIBILITY_SVG" + file="shared/nearby_device_visibility.svg" type="BINDATA"/> + <!-- Generated Polymer 3 elements --> <include name="IDR_NEARBY_SHARE_APP_JS" file="${root_gen_dir}/chrome/browser/resources/nearby_share/app.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_ICONS_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/icons.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_CONFIRMATION_PAGE_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_confirmation_page.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_DEVICE_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_device.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_DEVICE_ICON_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_device_icon.js" + use_base_dir="false" type="BINDATA"/> <include name="IDR_NEARBY_SHARE_NEARBY_DISCOVERY_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_discovery_page.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_PREVIEW_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_preview.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_PROGRESS_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_progress.js" + use_base_dir="false" type="BINDATA"/> + + <!-- Generated Polymer 2 to 3 elements --> + <include name="IDR_NEARBY_CONTACT_VISIBILITY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.m.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_ONBOARDING_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.m.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_share_settings.m.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_SETTINGS_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.m.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARED_ICONS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.m.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_VISIBILITY_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.m.js" + use_base_dir="false" type="BINDATA"/> </includes> </release> </grit> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/BUILD.gn b/chromium/chrome/browser/resources/nearby_share/shared/BUILD.gn new file mode 100644 index 00000000000..64d7acd0a2d --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/BUILD.gn @@ -0,0 +1,186 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") + +js_type_check("closure_compile") { + deps = [ + ":nearby_contact_visibility", + ":nearby_onboarding_page", + ":nearby_share_settings", + ":nearby_share_settings_behavior", + ":nearby_visibility_page", + ] + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/nearby_share/shared/", + "js_module_root=./gen/chrome/browser/resources/nearby_share/shared/", + ] +} + +js_library("nearby_contact_visibility") { + deps = [ + ":nearby_share_settings_behavior", + "//third_party/polymer/v1_0/components-chromium/iron-list:iron-list-extracted", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_card_radio_button", + "//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("nearby_onboarding_page") { + deps = [ + ":nearby_share_settings_behavior", + "//ui/webui/resources/cr_elements/cr_link_row", + ] +} + +js_library("nearby_share_settings") { + deps = [ + "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile", + "//ui/webui/resources/js:cr", + ] +} + +js_library("nearby_share_settings_behavior") { + deps = [ + ":nearby_share_settings", + "//ui/webui/resources/js:cr", + ] +} + +js_library("nearby_visibility_page") { + deps = [ + ":nearby_contact_visibility", + ":nearby_share_settings_behavior", + ] +} + +js_type_check("closure_compile_module") { + is_polymer3 = true + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/nearby_share/shared/", + "js_module_root=./gen/chrome/browser/resources/nearby_share/shared/", + ] + + deps = [ + ":nearby_contact_visibility.m", + ":nearby_onboarding_page.m", + ":nearby_share_settings.m", + ":nearby_share_settings_behavior.m", + ":nearby_visibility_page.m", + ] +} + +group("polymer3_elements") { + public_deps = [ + ":modulize", + ":nearby_contact_visibility_module", + ":nearby_onboarding_page_module", + ":nearby_shared_icons_module", + ":nearby_visibility_page_module", + "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js", + ] +} + +js_library("nearby_contact_visibility.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.m.js" ] + deps = [ + ":nearby_share_settings_behavior.m", + "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_card_radio_button.m", + "//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group.m", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":nearby_contact_visibility_module" ] +} + +js_library("nearby_onboarding_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.m.js" ] + deps = [ + ":nearby_share_settings_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_link_row:cr_link_row.m", + ] + extra_deps = [ ":nearby_onboarding_page_module" ] +} + +js_library("nearby_share_settings_behavior.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.m.js" ] + deps = [ + ":nearby_share_settings.m", + "//ui/webui/resources/js:cr.m", + ] + extra_deps = [ ":modulize" ] +} + +js_library("nearby_share_settings.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_share_settings.m.js" ] + deps = [ + "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile", + "//ui/webui/resources/js:cr.m", + ] + extra_deps = [ ":modulize" ] +} + +js_library("nearby_visibility_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.m.js" ] + deps = [ + ":nearby_contact_visibility.m", + ":nearby_share_settings_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] + extra_deps = [ ":nearby_visibility_page_module" ] +} + +nearby_shared_auto_imports = [ "chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.html|NearbyShareSettingsBehavior,NearbySettings" ] +nearby_shared_namespace_rewrites = [ + "nearby_share.NearbySettings|NearbySettings", + "nearby_share.NearbyShareSettingsBehavior|NearbyShareSettingsBehavior", + "nearby_share.getNearbyShareSettings|getNearbyShareSettings", + "nearby_share.observeNearbyShareSettings|observeNearbyShareSettings", + "nearby_share.setNearbyShareSettingsForTesting|setNearbyShareSettingsForTesting", +] + +polymer_modulizer("nearby_contact_visibility") { + js_file = "nearby_contact_visibility.js" + html_file = "nearby_contact_visibility.html" + html_type = "dom-module" + auto_imports = nearby_shared_auto_imports + namespace_rewrites = nearby_shared_namespace_rewrites +} + +polymer_modulizer("nearby_onboarding_page") { + js_file = "nearby_onboarding_page.js" + html_file = "nearby_onboarding_page.html" + html_type = "dom-module" + auto_imports = nearby_shared_auto_imports + namespace_rewrites = nearby_shared_namespace_rewrites +} + +polymer_modulizer("nearby_shared_icons") { + js_file = "nearby_shared_icons.m.js" + html_file = "nearby_shared_icons.html" + html_type = "iron-iconset" +} + +polymer_modulizer("nearby_visibility_page") { + js_file = "nearby_visibility_page.js" + html_file = "nearby_visibility_page.html" + html_type = "dom-module" + auto_imports = nearby_shared_auto_imports + namespace_rewrites = nearby_shared_namespace_rewrites +} + +js_modulizer("modulize") { + input_files = [ + "nearby_share_settings.js", + "nearby_share_settings_behavior.js", + ] + namespace_rewrites = nearby_shared_namespace_rewrites +} diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html new file mode 100644 index 00000000000..0dfe440b398 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html @@ -0,0 +1,299 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_card_radio_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> +<link rel="import" href="nearby_share_settings_behavior.html"> +<link rel="import" href="nearby_shared_icons.html"> + +<dom-module id="nearby-contact-visibility"> + <template> + <style include="cr-icons cr-shared-style"> + :host { + --card-border-color: var(--google-grey-300); + --cr-card-radio-button-padding: 8px 16px 8px 16px; + --iron-icon-height: var(--cr-icon-size); + --iron-icon-width: var(--cr-icon-size); + } + + .grey-icon { + color: var(--google-grey-refresh-700); + } + + #main { + display: flex; + flex-direction: column; + } + + #visibilityRadioGroup { + display: flex; + justify-content: center; + margin-block-end: 8px; + } + + cr-card-radio-button { + border: 1px solid var(--card-border-color); + box-shadow: none; + flex: 1; + margin-inline-end: 5px; + margin-inline-start: 5px; + padding: 0; + width: auto; + } + + cr-card-radio-button[checked] { + border: 2px solid var(--cr-checked-color); + } + + cr-card-radio-button:first-child { + margin-inline-start: 0; + } + + cr-card-radio-button:last-child { + margin-inline-end: 0; + } + + .card-contents { + color: var(--google-blue-600); + } + .card-icon { + margin-block-end: 8px; + } + + #zeroStateContainer { + display: flex; + justify-content: center; + margin: 8px; + } + + #zeroStateImageContainer { + flex-basis: 50%; + margin-inline-end: 24px; + margin-inline-start: auto; + text-align: end; + } + + #zeroStateTextContainer { + display: flex; + flex-basis: 50%; + flex-direction: column; + justify-content: center; + margin-inline-end: 8px; + margin-inline-start: 8px; + } + + #zeroStateText { + margin-block-end: 12px; + } + + #zeroStateInfoContainer { + align-items: center; + display: flex; + } + + #zeroStateIcon { + color: var(--cr-secondary-text-color); + margin-inline-end: 8px; + } + + .viz-description-section div { + margin-block-end: 8px; + } + + .explanation-section { + display: flex; + margin-block-end: 8px; + margin-block-start: 8px; + } + + .padded-icon { + margin-inline-end: 16px; + margin-inline-start: 12px; + min-height: var(--cr-icon-size); + min-width: var(--cr-icon-size); + } + + #contactsWrapper { + border-bottom: var(--cr-separator-line); + border-top: var(--cr-separator-line); + padding-block-start: 16px; + } + + #contactsHeading { + font-size: 1.2rem; + } + + #contactList { + height: 150px; + margin-block-end: 8px; + margin-block-start: 8px; + } + + .contact-item { + display: flex; + height: 50px; + padding-block-end: 8px; + padding-block-start: 8px; + } + + .contact-item[disabled] { + opacity: var(--cr-disabled-opacity); + } + + .contact-toggle { + align-self: center; + margin-inline-end: 12px; + margin-inline-start: auto; + } + + .contact-icon { + align-self: center; + } + + #noContactsContainer { + align-items: center; + display: flex; + flex-direction: column; + } + </style> + <div id="main"> + + <cr-radio-group id="visibilityRadioGroup" + selected="{{selectedVisibility}}"> + <cr-card-radio-button id="allContacts" class="flex" name="all"> + <div class="card-contents"> + <iron-icon icon="nearby20:contact-all" class="card-icon"> + </iron-icon> + <div class="card-label"> + All Contacts + </div> + </div> + </cr-card-radio-button> + <cr-card-radio-button id="someContacts" class="flex" name="some"> + <div class="card-contents"> + <iron-icon icon="nearby20:contact-group" class="card-icon"> + </iron-icon> + <div class="card-label"> + Some Contacts + </div> + </div> + </cr-card-radio-button> + <cr-card-radio-button id="noContacts" class="flex" name="none"> + <div class="card-contents"> + <iron-icon icon="nearby20:visibility-off" class="card-icon"> + </iron-icon> + <div class="card-label"> + Hidden + </div> + </div> + </cr-card-radio-button> + </cr-radio-group> + + <!-- Zero state is shown only when no selection has been made yet. --> + <template is="dom-if" if="[[!isVisibilitySelected_(selectedVisibility)]]"> + <div id="zeroStateContainer"> + <div id="zeroStateImageContainer"> + <img id="zeroStateImage" width="200" height="200" + src="/shared/nearby_device_visibility.svg"> + </div> + <div id="zeroStateTextContainer"> + <div id="zeroStateText" class="cr-title-text"> + Your device visibility controls who can share with you while your + screen is unlocked. + </div> + <div id="zeroStateInfoContainer"> + <iron-icon id="zeroStateIcon" icon="cr:info"></iron-icon> + <div class="cr-secondary-text"> + Learn more about device visibility + </div> + </div> + </div> + </div> + </template> + + <template is="dom-if" if="[[isVisibilitySelected_(selectedVisibility)]]"> + <div id="explanation"> + + <div class="explanation-section"> + <iron-icon icon="nearby20:radar" class="padded-icon grey-icon"> + </iron-icon> + <div class="viz-description-section"> + <div class="cr-title-text">Who you see</div> + <div class="cr-secondary-text"> + Nearby sharing users who are temporarily visible to everyone or + have chosen to always be visible to you + </div> + </div> + </div> + + <div class="explanation-section"> + <iron-icon icon="nearby20:visibility" class="padded-icon grey-icon"> + </iron-icon> + <div class="viz-description-section"> + <div class="cr-title-text">Who sees you</div> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'all')]]"> + <div class="cr-secondary-text"> + Current and future contacts who have Nearby Share turned on + </div> + </template> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'some')]]"> + <div class="cr-secondary-text"> + Selected contacts who have Nearby Share turned on + </div> + </template> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'none')]]"> + <div class="cr-secondary-text">Nobody!</div> + </template> + </div> + </div> + + </div> + + <div id="contactsWrapper"> + <div id="contactsHeading">Contacts</div> + + <!-- Show when the user has one or more contacts--> + <template is="dom-if" if="[[showContactsList_(contacts)]]"> + <iron-list id="contactList" items="[[contacts]]"> + <template> + <div class="contact-item" + disabled$="[[isVisibility_(selectedVisibility,'none')]]"> + <iron-icon icon="cr:person" + class="padded-icon grey-icon contact-icon"> + </iron-icon> + <div> + <div class="cr-title-text">[[item.name]]</div> + <div class="cr-secondary-text">[[item.email]]</div> + </div> + <template is="dom-if" + if="[[showContactCheckBoxes_(selectedVisibility)]]"> + <cr-toggle class="contact-toggle" checked="{{item.checked}}" + disabled="[[!isVisibility_(selectedVisibility,'some')]]" + > + </cr-toggle> + </template> + </div> + </template> + </iron-list> + </template> + + <!-- Show when the user has no contacts available --> + <template is="dom-if" if="[[!showContactsList_(contacts)]]"> + <div id="noContactsContainer"> + <div class="cr-title-text">No Reachable Contacts</div> + <div class="cr-secondary-text">No Reachable Contacts Subtext</div> + </div> + </template> + </div> + </div> + </template> + </template> + <script src="nearby_contact_visibility.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js b/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js new file mode 100644 index 00000000000..d549f5a7857 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js @@ -0,0 +1,209 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-contact-visibility' component allows users to + * set the preferred visibility to contacts for Nearby Share. This component is + * embedded in the nearby_visibility_page as well as the settings pop-up dialog. + */ + +'use strict'; +(function() { + +/** + * Maps visibility string to the mojo enum + * @param {?string} visibilityString + * @return {?nearbyShare.mojom.Visibility} + */ +const visibilityStringToValue = function(visibilityString) { + switch (visibilityString) { + case 'all': + return nearbyShare.mojom.Visibility.kAllContacts; + case 'some': + return nearbyShare.mojom.Visibility.kSelectedContacts; + case 'none': + return nearbyShare.mojom.Visibility.kNoOne; + default: + return null; + } +}; + +/** + * Maps visibility mojo enum to a string for the radio button selection + * @param {?nearbyShare.mojom.Visibility} visibility + * @return {?string} + */ +const visibilityValueToString = function(visibility) { + switch (visibility) { + case nearbyShare.mojom.Visibility.kAllContacts: + return 'all'; + case nearbyShare.mojom.Visibility.kSelectedContacts: + return 'some'; + case nearbyShare.mojom.Visibility.kNoOne: + return 'none'; + default: + return null; + } +}; + +/** + * @typedef {{ + * name:string, + * email:string, + * checked:boolean, + * }} + */ +/* #export */ let NearbyVisibilityContact; + +Polymer({ + is: 'nearby-contact-visibility', + + behaviors: [I18nBehavior], + + properties: { + /** @type {?nearby_share.NearbySettings} */ + settings: { + type: Object, + notify: true, + }, + + /** + * @type {?string} Which of visibility setting is selected as a string or + * null for no selection. ('all', 'some', 'none', null). + */ + selectedVisibility: { + type: String, + value: null, + notify: true, + }, + + /** + * @type {Array<NearbyVisibilityContact>} The user's GAIA contacts + * formatted for binding. + */ + contacts: { + type: Array, + value: [ + { + name: 'Jane Doe', + email: 'jane@google.com', + checked: true, + }, + { + name: 'John Smith', + email: 'smith@gmail.com', + checked: false, + }, + { + name: 'Testy Tester', + email: 'test@test.com', + checked: true, + } + ], + }, + }, + + observers: [ + 'settingsChanged_(settings.visibility)', + 'selectedVisibilityChanged_(selectedVisibility)', + ], + + /** @type {ResizeObserver} used to observer size changes to this element */ + resizeObserver_: null, + + /** @override */ + attached() { + // This is a required work around to get the iron-list to display on first + // view. Currently iron-list won't generate item elements on attach if the + // element is not visible. Because we are hosted in a cr-view-manager for + // on-boarding, this component is not visible when the items are bound. To + // fix this issue, we listen for resize events (which happen when display is + // switched from none to block by the view manager) and manually call + // notifyResize on the iron-list + this.resizeObserver_ = new ResizeObserver(entries => { + const contactList = + /** @type {IronListElement} */ (this.$$('#contactList')); + if (contactList) { + contactList.notifyResize(); + } + }); + this.resizeObserver_.observe(this); + }, + + /** @override */ + detached() { + this.resizeObserver_.disconnect(); + }, + + /** + * Used to show/hide parts of the UI based on current visibility selection. + * @param {?string} selectedVisibility + * @return {boolean} Returns true when the current selectedVisibility has a + * value other than null. + * @private + */ + isVisibilitySelected_(selectedVisibility) { + return this.selectedVisibility !== null; + }, + + /** + * Used to show/hide parts of the UI based on current visibility selection. + * @param {?string} selectedVisibility + * @param {string} visibilityString + * @return {boolean} returns true when the current selectedVisibility equals + * the passed arguments. + * @private + */ + isVisibility_(selectedVisibility, visibilityString) { + return this.selectedVisibility === visibilityString; + }, + + /** + * Used to show/hide parts of the UI based on current visibility selection. + * @param {?string} selectedVisibility + * @return {boolean} returns true when checkboxes should be shown for + * contacts. + * @private + */ + showContactCheckBoxes_(selectedVisibility) { + return this.selectedVisibility === 'some' || + this.selectedVisibility === 'none'; + }, + + /** + * Used to show/hide parts of the UI based on the number of contacts + * @param {?Array} contacts the currently bound contact list + * @return {boolean} returns true when checkboxes should be shown for + * contacts. + * @private + */ + showContactsList_(contacts) { + return this.contacts.length > 0; + }, + + /** + * @param {?nearby_share.NearbySettings} settings + * @private + */ + settingsChanged_(settings) { + if (this.settings && this.settings.visibility) { + this.selectedVisibility = + visibilityValueToString(this.settings.visibility); + } else { + this.selectedVisibility = null; + } + }, + + /** + * @param {string} selectedVisibility + * @private + */ + selectedVisibilityChanged_(selectedVisibility) { + const visibility = visibilityStringToValue(this.selectedVisibility); + if (visibility) { + this.set('settings.visibility', visibility); + } + }, +}); +})(); diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_device_visibility.svg b/chromium/chrome/browser/resources/nearby_share/shared/nearby_device_visibility.svg new file mode 100644 index 00000000000..5932080f0aa --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_device_visibility.svg @@ -0,0 +1 @@ +<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M0 0h200v200H0z"/><path d="M150.441 100.728c0 26.949-21.772 48.794-48.63 48.794-26.858 0-48.63-21.845-48.63-48.794 0-26.95 21.772-48.795 48.63-48.795 26.858 0 48.63 21.845 48.63 48.795" fill="#D2E3FC"/><path d="M176.711 53.44l-12.39-3.317a1.021 1.021 0 0 1-.722-1.25l3.32-12.383a1.022 1.022 0 0 1 1.252-.722l12.39 3.317c.544.146.868.707.722 1.251l-3.32 12.383a1.022 1.022 0 0 1-1.252.722" fill="#34A853"/><path d="M31.832 148.371l-9.514 5.538c-3.553 2.068-4.77 6.644-2.72 10.223 2.053 3.584 6.603 4.813 10.161 2.742l9.514-5.538c3.48-2.026 4.718-6.454 2.844-9.998l-.124-.225c-2.053-3.584-6.603-4.813-10.161-2.742zm8.425 3.736c1.505 2.627.612 5.986-1.99 7.5l-9.514 5.539c-2.597 1.511-5.918.614-7.42-2.008-1.504-2.627-.61-5.986 1.991-7.5l9.514-5.539c2.529-1.471 5.743-.66 7.297 1.804l.122.204z" fill="#EA4335" fill-rule="nonzero"/><path d="M26.693 54.6l-5.899-5.896a2.743 2.743 0 0 1-.711-2.653l2.159-8.054a2.745 2.745 0 0 1 1.943-1.941l8.058-2.158a2.75 2.75 0 0 1 2.655.71l5.9 5.896c.693.694.965 1.705.71 2.653L39.35 51.21a2.746 2.746 0 0 1-1.943 1.942l-8.058 2.158a2.751 2.751 0 0 1-2.655-.71" fill="#FBBC05"/><path d="M26.536 141.312l-5.553-4.145a.552.552 0 0 1-.113-.773l4.149-5.55a.552.552 0 0 1 .773-.112l5.554 4.145a.552.552 0 0 1 .112.773l-4.149 5.55a.552.552 0 0 1-.773.112" fill="#F882FF"/><path d="M102.004 29.332c-39.453 0-71.437 31.965-71.437 71.396 0 39.43 31.984 71.395 71.437 71.395 39.453 0 71.437-31.965 71.437-71.395 0-39.431-31.983-71.396-71.437-71.396zm0 2c38.35 0 69.437 31.07 69.437 69.396s-31.088 69.395-69.437 69.395-69.437-31.07-69.437-69.395c0-38.326 31.088-69.396 69.437-69.396z" fill="#4285F4" fill-rule="nonzero"/><path d="M104.18 73.085a8.864 8.864 0 0 0-4.738 0l-19.099 7.12c-1.232.342-2.075 1.387-2.075 2.572v14.13c0 11.668 5.686 22.805 15.688 29.978 3.332 2.39 6.297 3.737 7.855 3.737 1.558 0 4.523-1.348 7.855-3.737 10.003-7.173 15.688-18.31 15.688-29.977V82.777c0-1.185-.842-2.23-2.075-2.573l-19.099-7.12z" fill="#4285F4"/><path d="M101.768 94.59c-3.19 0-5.789 2.668-5.789 5.945 0 3.276 2.599 5.945 5.79 5.945 3.19 0 5.789-2.669 5.789-5.945 0-3.277-2.6-5.945-5.79-5.945zm-.193 9.115c-1.81 0-3.28-1.51-3.28-3.368 0-1.86 1.47-3.37 3.28-3.37 1.81 0 3.281 1.51 3.281 3.37 0 1.859-1.47 3.368-3.28 3.368zm.193-12.682c-6.14 0-11.384 3.944-13.508 9.512 2.124 5.567 7.368 9.512 13.508 9.512 6.14 0 11.384-3.945 13.509-9.512-2.125-5.568-7.368-9.512-13.509-9.512zm-.193 16.646c-4.726 0-8.942-2.763-11-7.134 2.058-4.371 6.274-7.134 11-7.134 4.727 0 8.942 2.763 11 7.134-2.058 4.37-6.273 7.134-11 7.134z" fill="#FFF" fill-rule="nonzero"/></g></svg>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html new file mode 100644 index 00000000000..afcd40f6e81 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.html @@ -0,0 +1,111 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> +<link rel="import" href="./nearby_share_settings_behavior.html"> + +<dom-module id="nearby-onboarding-page"> + <template> + <style include="cr-icons cr-shared-style"></style> + <style> + :host { + --nearby-page-space-block: 26px; + --nearby-page-space-inline: 32px; + --nearby-page-space-large-inline: 42px; + } + + #page-container { + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + padding: 30px; + } + + #center-content { + box-sizing: border-box; + display: flex; + flex-grow: 1; + justify-content: center; + overflow: hidden; + } + + #page-title { + font-size: 125%; + font-weight: normal; + } + + #page-sub-title { + font-weight: normal; + } + + #splash-image-column { + margin: 10px; + } + + #device-name-column { + margin: 10px; + } + + #link-row { + border: 1px solid lightgray; + border-radius: 5px; + } + + #device-name-desc-group { + margin-inline-start: 10px; + padding: 10px; + } + + #device-name-group { + padding-inline-end: 10px; + padding-inline-start: 10px; + } + + #actions { + margin-block-end: var(--nearby-page-space-block); + margin-block-start: 17px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + text-align: end; + } + </style> + <div id="page-container"> + <div id="header"> + <h1 id="page-title">Turn on Nearby Share</h1> + <h4 id="page-sub-title"> + Nearby allows you to send and receive files from people nearby + </h4> + </div> + + <div id=center-content> + <img id="splash-image-column" width="200" height="200" + src="/shared/nearby_onboarding_splash.svg"> + <div id="device-name-column"> + <div id="device-name-desc-group"> + <div>Device Name</div> + <div class="cr-secondary-text"> + Visible to people you share with + </div> + </div> + <cr-link-row id="link-row" label="[[settings.deviceName]]" + sub-label="Your device name" on-click="onDeviceNameTap_" + start-icon="cr:person" external=true> + </cr-link-row> + </div> + </div> + + <div id="actions"> + <cr-button class="cancel-button" on-click="onCloseTap_"> + Cancel + </cr-button> + <cr-button id="next-button" class="action-button" on-click="onNextTap_"> + Next + </cr-button> + </div> + </div> + </template> + <script src="nearby_onboarding_page.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js new file mode 100644 index 00000000000..83c2a560d0f --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_page.js @@ -0,0 +1,31 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-onboarding-page' component handles the Nearby Share + * onboarding flow. It is embedded in chrome://os-settings, chrome://settings + * and as a standalone dialog via chrome://nearby. + */ +Polymer({ + is: 'nearby-onboarding-page', + + properties: { + /** @type {?nearby_share.NearbySettings} */ + settings: { + type: Object, + } + }, + + onNextTap_() { + this.fire('change-page', {page: 'visibility'}); + }, + + onCloseTap_() { + this.fire('close'); + }, + + onDeviceNameTap_() { + window.open('chrome://os-settings/multidevice/nearbyshare?deviceName'); + }, +}); diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_splash.svg b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_splash.svg new file mode 100644 index 00000000000..3d8679ed20f --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_onboarding_splash.svg @@ -0,0 +1 @@ +<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="M.008.144h30.71v26.652H.007z"/><path d="M3.798.549A5.982 5.982 0 0 0 .812 8.458l5.764 12.741a5.97 5.97 0 0 0 7.9 2.99 5.982 5.982 0 0 0 2.987-7.909L11.697 3.54A5.96 5.96 0 0 0 3.798.55" id="c"/><path d="M1.258 10.212c-1.955 7.205 1.886 14.751 8.58 16.855l.196.063c6.694 2.104 13.705-2.03 15.66-9.234C27.65 10.691 23.81 3.145 17.117 1.04L16.92.978a11.78 11.78 0 0 0-3.546-.549C7.907.43 2.868 4.28 1.258 10.212z" id="e"/><path id="g" d="M0 .13h36.463v36.73H0z"/><path d="M25.094.245L.89 9.568c-.687.265-1.037 1.056-.782 1.769l8.985 25.114c.255.712 1.018 1.075 1.704.811L35 27.939c.687-.265 1.037-1.056.782-1.769L26.798 1.056A1.329 1.329 0 0 0 25.555.16c-.153 0-.31.028-.461.086" id="i"/></defs><g fill="none" fill-rule="evenodd"><path d="M0 0h200v200H0z"/><path d="M110.893 164.142l-6.065 12.062c1.606.235 2.96.506 4.06.814 4.544 1.27 10.262 2.852 15.561 5.64 7.226 3.802 10.566 4.087 10.02.856-3.964-3.923-4.913-5.674-2.848-5.254 2.065.42 5.403 1.107 10.015 2.062.624-.243.804-.791.539-1.644-.208-.67-3.266-2.054-4.064-3.237-.146-.216.396-.215 1.624.003 2.632.41 4.12.547 4.465.41 1.163-.466-.097-2.017-.003-2.827.054-.468.801-.549 1.216-.806.288-.179.267-.554.36-.741.42-.842-3.068-1.44-2.8-2.494.274-1.075 4.274-2.606 1.607-3.406-5.282-1.583-10.813.808-16.629.56-3.877-.166-9.563-.832-17.058-1.998z" fill="#D2E3FC"/><path d="M141.354 171.58l.57.095 1.311.246c1.522.274 1.905.19 2.129-.434.02-.056-.109-.25-.638-.581-.664-.415-1.721-.839-3.074-1.237a.805.805 0 1 1 .454-1.543l.57.174c3.14.992 4.78 2.126 4.204 3.732-.561 1.563-1.636 1.851-3.696 1.512l-1.341-.249c-.275-.05-.504-.09-.735-.126a12.992 12.992 0 0 0-2.067-.174 32.862 32.862 0 0 0-4.908.396.806.806 0 0 1-.92-.672.803.803 0 0 1 .673-.918 34.47 34.47 0 0 1 5.148-.414c.753-.002 1.497.064 2.32.193z" fill="#4682F4" fill-rule="nonzero"/><path d="M134.892 176.05a.803.803 0 1 1 .003-1.609l1.163.008c.546.006.966.015 1.232.028l.092.005a18.507 18.507 0 0 1 2.379.322l.654.138c.519.115 1.48.336 1.707.384l.395.079c1.162.217 1.48.119 1.591-.306.206-.791-.878-1.532-3.807-2.045a.804.804 0 1 1 .276-1.585c3.753.658 5.634 1.944 5.09 4.037-.428 1.64-1.63 1.868-3.876 1.394l-1.942-.436a18.28 18.28 0 0 0-2.16-.345l-.401-.031-.424-.016a88.28 88.28 0 0 0-1.972-.022z" fill="#4682F4" fill-rule="nonzero"/><path d="M141.644 179.567c.18-.31.013-.618-.823-1.159-1.14-.736-3.19-1.51-6.125-2.293a.806.806 0 0 1-.571-.986.803.803 0 0 1 .984-.57c3.084.825 5.27 1.649 6.583 2.498 1.565 1.01 2.102 2.273 1.225 3.504-.514.722-1.262.731-2.752.368l-.552-.143c-.57-.153-1.557-.428-1.585-.435a32.331 32.331 0 0 0-2.211-.532 19.356 19.356 0 0 0-1.642-.258c-1.193-.132-2.08-.185-2.641-.16l-.234.016-.035.06a.798.798 0 0 1-.223.222l-.095.054a.805.805 0 0 1-1.075-.374c-.503-1.04.296-1.495 1.408-1.576.672-.05 1.687.005 3.07.158.58.065 1.169.158 1.778.28.61.12 1.21.262 1.896.443l2.295.625c.494.126.85.198 1.108.22l.186.012c.018.002.028.006.031.013v.013zm-13.848-1.352a.806.806 0 0 1-1.006-.534c-.452-1.475-.264-2.833.571-3.995.9-1.253 2.656-2.153 5.813-3.27l3.54-1.22.187-.068c.695-.257 1.397-.438 2.698-.713l1.718-.36c1.35-.292 2.061-.494 2.677-.773.748-.34.941-.604.836-.965-.172-.587-3.21-.75-7.838-.247l-.935.106c-.32.038-.647.079-.985.122l-5.142.7c-.596.077-1.065.135-1.254.15-2.193.181-7.982-.704-17.529-2.658a.804.804 0 1 1 .323-1.576l2.02.409c8.168 1.631 13.228 2.373 15.054 2.223l.305-.033c1.269-.15 5.264-.712 5.497-.742l1.029-.132c.332-.04.656-.08.973-.116l1.221-.13c5.403-.544 8.286-.313 8.807 1.474.376 1.29-.324 2.248-1.715 2.88l-.285.122c-.624.255-1.323.45-2.45.7l-2.466.52c-.771.17-1.286.304-1.735.454l-1.52.534c-1.005.347-2.173.743-2.13.728-3.045 1.058-4.745 1.9-5.405 2.818-.533.743-.649 1.579-.34 2.588a.804.804 0 0 1-.534 1.004z" fill="#4682F4" fill-rule="nonzero"/><path d="M135.161 182.503c.791 1.153.728 2.38-.312 3.488-1.426 1.52-4.087.752-10.188-2.074l-3.96-1.853a66.2 66.2 0 0 0-2.227-.987c-3.772-1.591-8.276-2.854-13.51-3.787a.806.806 0 0 1-.652-.933.803.803 0 0 1 .932-.652c5.064.903 9.474 2.113 13.233 3.632l.62.257c.83.349 1.486.641 2.657 1.185l3.215 1.507 1.046.481c4.608 2.09 7.048 2.774 7.66 2.122.511-.545.531-.935.16-1.477-.356-.519-.985-1.053-2.102-1.825l-.786-.532c-1.524-1.024-2.835-2.028-3.934-3.013a.805.805 0 1 1 1.072-1.198 33.243 33.243 0 0 0 3.277 2.548l1.027.695c1.343.913 2.13 1.548 2.662 2.262l.11.154z" fill="#4682F4" fill-rule="nonzero"/><path d="M92.163 196.078c.982.182 2.643.273 3.633.406.83.112 1.619-.175 2.423-.405.803-.232.747-.847.919-1.664.695-.113 1.406-.232 2.02-.574.616-.342 1.125-.96 1.137-1.661.007-.395-.558-.19-.444-.568.073-.236.66-1.04.785-1.255.527-.906.161-2.213-.76-2.716.363-.226.476-.726.358-1.135-.118-.409-.42-.74-.742-1.018-2.532-2.183-6.36-1.812-9.443-3.116.583-.446 1.347-.564 2.022-.851.675-.287 1.338-.898 1.241-1.624-.073-.554-.585-.969-1.125-1.117-.542-.148-1.115-.088-1.674-.049-3.745.265-7.532-.417-11.249.108-.252.037-.515.083-.717.238-.27.21-3.883-1.106-3.963-.774-.482 1.974-7.031-4.966-7.839-4.154-.807.812-11.512 9.186-11.706 10.15-.164.811 14.052 7.893 15.264 8.424 2.096.917 12.76 2.606 14.612 2.948 1.548.287 3.7.12 5.248.407z" fill="#D2E3FC"/><path d="M87.628 192.91a.806.806 0 0 1 .445-1.548c4.335 1.25 7.827 1.874 10.84 1.8.923-.021 1.458-.12 1.76-.356.22-.172.26-.694.048-.846a.806.806 0 0 1-.184-1.124.803.803 0 0 1 1.122-.185c1.153.829 1.014 2.634.003 3.425-.67.523-1.447.667-2.71.697-3.209.078-6.845-.572-11.324-1.863zm-.619-10.486a.806.806 0 0 1 .433-1.551l.341.091c1.706.442 6.23 1.446 7.773 1.731.713.132 1.388.288 2.361.538l.836.219c1.116.292 1.938.623 2.638 1.14.524.388.923.874 1.114 1.442.183.543.153 1.141-.125 1.632-.527.932-1.542 1.258-2.914 1.245a10.974 10.974 0 0 1-1.039-.064l-1.324-.156c-.403-.053-.82-.12-1.435-.226l-1.496-.259-1.511-.258a35.12 35.12 0 0 1-3.64-.82.806.806 0 0 1 .433-1.552c1.282.359 2.228.567 3.841.848l3.05.523c.51.085.867.137 1.248.183l.719.084c.47.055.826.083 1.169.086.843.008 1.344-.153 1.5-.428.038-.067.044-.192 0-.324-.074-.22-.266-.454-.545-.66-.445-.328-1.011-.573-1.789-.795l-.8-.214-.913-.233c-.55-.136-1-.238-1.446-.324l-.639-.122c-2.01-.396-6.554-1.415-7.84-1.776z" fill="#4285F4" fill-rule="nonzero"/><path d="M88.364 189.969a.806.806 0 0 1 .423-1.554c2.262.617 6.487 1.543 8.684 1.896 1.54.248 2.447.295 3.257.092.322-.081.51-.183.722-.395.12-.119.2-.406.171-.674-.037-.348-.215-.568-.462-.665l-.096-.03a.806.806 0 0 1 .39-1.563c.924.232 1.649.99 1.767 2.084.078.723-.14 1.497-.636 1.99-.425.423-.87.666-1.466.815-1.087.273-2.155.217-3.902-.064-2.255-.362-6.536-1.3-8.852-1.932zm-20.049-15.742a.806.806 0 0 1-.207-1.12.803.803 0 0 1 1.118-.207l.719.491c5.425 3.677 8.916 5.295 10.089 4.886 1.98-.69 3.677-.83 6.624-.68l4.398.28.608.03.294-.001.671-.012c.994-.007 1.669.11 2.315.521.71.453 1.16 1.257 1.056 2.078-.074.587-.414 1.102-.902 1.477-.446.344-1.076.6-1.943.84l-.503.13c-.52.126-1.46.338-1.569.365a.805.805 0 0 1-.394-1.562l1.556-.361.211-.052c.82-.212 1.391-.428 1.662-.637.172-.132.272-.284.287-.401.02-.154-.107-.38-.325-.518-.287-.183-.648-.259-1.235-.268l-.204-.001-.804.013c-.117 0-.213 0-.312-.004l-1.364-.076-2.767-.185c-3.14-.198-4.788-.125-6.595.465l-.237.08c-1.954.681-5.89-1.188-12.247-5.571zm-11.4 11.051a.806.806 0 0 1 .89-1.342c5.989 3.979 11.392 6.766 16.202 8.364l.532.172c3.514 1.113 6.104 1.57 11.318 2.09l4.4.419c1.719.173 2.897.325 4.1.538l.242.044c1.209.22 1.785.266 2.39.132.619-.137 1.118-.537 1.264-.985l.028-.113a.804.804 0 1 1 1.581.295c-.221 1.193-1.273 2.098-2.527 2.376-.756.167-1.398.149-2.457-.022l-1.265-.22c-1.168-.191-2.397-.337-4.238-.513l-2.742-.256c-5.96-.571-8.723-1.028-12.579-2.25-5.1-1.614-10.81-4.525-17.139-8.73z" fill="#4285F4" fill-rule="nonzero"/><g fill-rule="nonzero"><path d="M78.868 136.46l-.531.008c-.323.008-.621.021-.894.039l-.49.038-.12.016-9.915.101-.382-.018c-3.068-.115-6.78.197-10.366 1.302-2.21.682-4.172 1.626-5.815 2.868-3.822 2.89-5.187 7.466-6.244 17.638-.966 9.309 1.07 16.723 5.068 22.384a24.107 24.107 0 0 0 3.667 4.132c.76.675 1.36 1.117 1.72 1.34.266.167.602.16.861-.005l.093-.07 14.23-12.368c.335-.292.37-.8.078-1.135a.806.806 0 0 0-1.049-.144l-.087.066-13.753 11.953-.117-.088c-.21-.16-.432-.341-.667-.542l-.24-.209a22.505 22.505 0 0 1-3.42-3.857c-3.777-5.348-5.707-12.376-4.781-21.291l.161-1.49c.988-8.676 2.303-12.65 5.453-15.032 1.481-1.12 3.276-1.983 5.318-2.613 3.194-.985 6.534-1.306 9.34-1.247l.704.024.18.009 10.07-.106.264-.026.102-.008c.311-.025.67-.044 1.071-.054a25.64 25.64 0 0 1 3.7.18c3.7.447 7.071 1.653 9.76 3.825 1.895 1.531 3.246 3.777 4.756 7.685l.373.991c.454 1.273 3.058 8.852 4.112 11.6a.805.805 0 0 0 .544.49l.109.02 8.336 1.035-7.493 14.353-.253-.054c-2.408-.554-5.444-2.118-9.083-4.702l-.422-.302c-4.065-2.937-5.343-7.106-3.845-12.686a.806.806 0 0 0-1.556-.416c-1.663 6.198-.174 11.06 4.457 14.405 4.444 3.21 8.108 5.03 11.03 5.445a.81.81 0 0 0 .77-.329l.058-.096 8.3-15.901a.804.804 0 0 0-.513-1.15l-.101-.02-9.004-1.117-.494-1.347a368.1 368.1 0 0 1-.94-2.636l-2.547-7.277c-1.739-4.697-3.268-7.372-5.58-9.24-2.953-2.386-6.604-3.692-10.58-4.173a27.422 27.422 0 0 0-3.403-.198z" fill="#4285F4"/><path d="M61.551 153.314l-.1.002a.805.805 0 0 0-.742.764l.002.1 1.185 15.019a.802.802 0 0 0 .285.552l.087.064 6.522 4.123a.803.803 0 1 0 .95-1.294l-.088-.065-6.18-3.908-1.156-14.617a.805.805 0 0 0-.657-.728l-.108-.012z" fill="#4682F4"/><path d="M63.276 165.48a.805.805 0 0 0-.101 1.601l.101.007h22.233a.805.805 0 0 0 .101-1.602l-.1-.006H63.275z" fill="#4682F4"/></g><path d="M69.765 131.356h5.865l1.533 6.908c-.569 1.266-2.293 2.186-4.332 2.186-2.094 0-3.855-.97-4.376-2.287l1.31-6.807z" fill="#CFE3FF"/><path d="M75.63 130.552h-5.865a.805.805 0 0 0-.791.652l-1.31 6.807a.803.803 0 0 0 .042.447c.666 1.684 2.762 2.796 5.125 2.796 2.296 0 4.343-1.05 5.067-2.661a.803.803 0 0 0 .051-.503l-1.533-6.908a.805.805 0 0 0-.786-.63zm-.647 1.608l1.329 5.987-.027.046c-.557.839-1.897 1.453-3.454 1.453l-.228-.004c-1.506-.058-2.771-.69-3.272-1.52l-.036-.065 1.135-5.897h4.553z" fill="#4285F4" fill-rule="nonzero"/><path d="M76.445 122.877a6.147 6.147 0 0 1 .694 8.688 6.202 6.202 0 0 1-8.72.692 6.147 6.147 0 0 1-.694-8.689 6.202 6.202 0 0 1 8.72-.69z" fill="#CFE3FF"/><path d="M67.112 123.046a6.95 6.95 0 0 0 .785 9.823 7.008 7.008 0 0 0 9.855-.781 6.95 6.95 0 0 0-.785-9.823 7.008 7.008 0 0 0-9.855.781zm8.811.444a5.344 5.344 0 0 1 .604 7.553 5.396 5.396 0 0 1-7.587.601 5.344 5.344 0 0 1-.603-7.553 5.396 5.396 0 0 1 7.586-.601z" fill="#4285F4" fill-rule="nonzero"/><path fill="#4285F4" d="M66.246 124.853h11.057l-.299-2.25-4.155-1.117-2.297.041-2.571 1.65z"/><path d="M81.62 121.472c-.335.523-.8 1.009-1.21 1.469l-1.697 1.912h-6.757l2.306-2.545c1.127-1.244 1.971-2.238 3.384-3.065 1.483-.869 3.377-1.116 4.163.034l.024.037c.355.55.274 1.401-.212 2.158" fill="#0F3EC1"/><path d="M69.625 127.974c.4-.082.79.147.921.52l.03.106c.083.405.424.766.824.886l.121.03a.804.804 0 1 1-.275 1.584 2.827 2.827 0 0 1-2.249-2.178.804.804 0 0 1 .628-.948z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(87.766 169.167)"><path d="M0 12.79L2.687 1.536A2 2 0 0 1 4.632 0h11.823a2 2 0 0 1 1.928 2.533l-3.88 14.02L0 12.79z" fill="#4682F4"/><ellipse fill="#FFF" cx="6.285" cy="2.818" rx="1.007" ry="1.001"/></g><path d="M89.666 149.902c.488.11.795.595.685 1.082l-.412 1.874a39.22 39.22 0 0 0-.172.87 23.414 23.414 0 0 0-.372 2.834c-.129 2.02-.374 3.896-.757 5.674-.484 2.245-1.087 3.591-2.423 4.63a.907.907 0 0 1-1.271-.159.904.904 0 0 1 .158-1.27c.909-.706 1.363-1.72 1.764-3.582.318-1.475.537-3.028.67-4.69l.05-.72c.053-.81.153-1.625.303-2.51l.154-.84c.123-.641.252-1.23.54-2.509a.906.906 0 0 1 .97-.702l.113.018zM159.996 35.664h-5.559a.805.805 0 0 0-.737.48l-1.71 3.862a.804.804 0 0 0 .734 1.13l9.034.036a.804.804 0 0 0 .737-1.135l-1.765-3.9a.805.805 0 0 0-.734-.473zm-.522 1.608l1.036 2.286-6.55-.027 1.001-2.26h4.513z" fill="#4285F4" fill-rule="nonzero"/><path d="M161.948 41.21l-.376-.071-1.578.03c-2.899.047-5.226.04-6.982-.021l-.323-.012c-12.927-.517-20.131 5.42-29.147 22.158a.804.804 0 0 1-.397.36l-.105.036-19.632 5.21 5.93 13.082.087.008c7.582.697 14.44-1.076 20.608-5.325l.439-.308c6.424-4.572 10.44-10.685 12.07-18.37a.805.805 0 0 1 1.576.333c-1.714 8.08-5.959 14.541-12.71 19.347-6.75 4.804-14.327 6.763-22.696 5.868a.806.806 0 0 1-.599-.374l-.05-.094-6.515-14.37a.803.803 0 0 1 .427-1.074l.1-.034 20.214-5.364.112-.206c8.97-16.498 16.507-22.78 29.546-22.514l1.744.054c1.767.045 4.052.043 6.855-.007l1.075-.021.147.01.31.056.39.08c.139.028.286.06.443.096.888.203 1.871.466 2.924.799 3.008.95 5.976 2.264 8.694 4.002 7.825 5.004 12.045 12.458 10.865 22.73-1.18 10.273-7.632 17.093-17.468 21.09-3.416 1.388-7.007 2.33-10.556 2.913a49.07 49.07 0 0 1-3.42.443l-.511.043-.742.049a.806.806 0 0 1-.826-.478l-.037-.104-5.588-19.616a.806.806 0 1 1 1.512-.542l.038.103 5.41 18.992.344-.026.251-.023a47.465 47.465 0 0 0 3.307-.428c3.438-.564 6.915-1.477 10.21-2.816 9.339-3.794 15.371-10.171 16.475-19.784 1.105-9.613-2.793-16.499-10.132-21.192-2.588-1.655-5.43-2.913-8.311-3.823a36.183 36.183 0 0 0-2.365-.662l-.431-.102a25.57 25.57 0 0 0-.606-.13z" fill="#4285F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M152.34 90.536c.23.38.11.875-.27 1.106l-3.443 2.127-.68.406-.49.283c-1.488.848-3.158 1.685-5.746 2.87l-.569.254c-1.158.505-1.873.71-2.765.739-1.447.046-2.845-.649-3.411-1.88a.804.804 0 1 1 1.408-.77l.053.096c.268.583 1.048.97 1.899.944.696-.022 1.31-.216 2.46-.732l.256-.116c2.689-1.231 4.354-2.072 5.857-2.94l.451-.265.52-.312c.554-.34 2.592-1.611 3.366-2.081a.803.803 0 0 1 1.104.27z"/><path d="M145.072 91.074a.806.806 0 0 1-.333 1.09l-3.63 1.972c-.836.448-1.504.79-2.17 1.108-1.928.919-3.64 1.517-5.47 1.857-1.122.208-2.188.11-3.06-.383-1.26-.711-1.826-2.492-.811-3.658a.803.803 0 0 1 1.134-.078c.335.292.37.8.078 1.136-.266.306-.063.942.388 1.197.502.283 1.196.347 1.977.202 1.68-.312 3.263-.865 5.073-1.727l.484-.236a59.293 59.293 0 0 0 1.936-1.01l2.845-1.551.471-.253a.804.804 0 0 1 1.088.334z"/><path d="M143.99 88.052a.806.806 0 0 1-.31 1.095l-.713.41-1.405.829c-.92.536-1.538.866-2.245 1.187-1.85.84-3.59 1.482-5.303 1.933l-.75.186-.715.166c-.634.14-1.054.204-1.551.231-1.406.08-2.565-.275-3.268-1.278-.648-.92-.53-2.234.165-3.135 1.224-1.586 3.911-2.467 7.583-2.904a.805.805 0 0 1 .19 1.6c-3.254.387-5.635 1.168-6.501 2.289-.288.373-.336.919-.122 1.224.318.453.954.647 1.863.596.446-.025.84-.09 1.529-.249l.633-.15c1.79-.428 3.615-1.083 5.583-1.976l.35-.164c.58-.278 1.156-.598 2.01-1.1l.97-.575c.368-.217.627-.366.912-.526a.803.803 0 0 1 1.094.31zm4.263-12.866a.805.805 0 0 1-.813.795c-3.483-.04-7.396.654-12.402 2.014l-.606.167c-1.284.355-1.901.552-2.54.843l-.138.064c-.477.225-.785.44-.974.692-.176.233-.227.516-.15.683.127.274.612.423 1.446.41l.718-.03 6.73-.366a.805.805 0 0 1 .068 1.609l-2.754.145-3.532.2c-.362.018-.663.033-.963.046-1.563.066-2.662-.23-3.172-1.338-.347-.75-.185-1.651.324-2.328.377-.501.881-.854 1.572-1.18.695-.329 1.291-.536 2.39-.85l.546-.153c5.433-1.507 9.646-2.283 13.456-2.238.444.005.8.37.794.815z"/><path d="M142.915 84.726c.21.392.062.88-.33 1.09-4.438 2.373-7.59 3.063-12.93 2.921-.825-.022-1.339-.085-1.886-.289-.766-.285-1.391-.839-1.654-1.57-.431-1.202.238-2.558 1.377-3.236.584-.347 1.188-.525 2.052-.654l.856-.11c4.22-.512 6.293-1.111 10.039-2.917a.806.806 0 0 1 .698 1.451c-3.594 1.733-5.781 2.42-9.528 2.935l-1.56.197c-.827.107-1.321.237-1.736.483-.531.317-.826.913-.685 1.306.088.243.348.474.7.605.337.125.71.171 1.37.189 5.07.134 7.946-.495 12.13-2.732a.804.804 0 0 1 1.087.33z"/></g><path d="M142.765 48.928a.806.806 0 0 1 1.475.646c-.578 1.314-.63 2.915-.27 4.932l.073.382c.063.317.123.59.218 1.007l.38 1.656c.312 1.414.436 2.243.471 3.256l.007.314c.002.16 0 .333-.002.54l-.016 1.037c-.001.648.026 1.024.106 1.448.173.915.67 1.642 1.244 1.851l.059.017 7.962.085c7.285.062 11.603.047 12.686-.037l.063-.006.01-.03c.035-.143.06-.348.067-.61l.003-.166c.003-.9-.166-2.256-.508-4.05a.804.804 0 0 1 1.582-.301l.12.645c.697 3.868.621 5.743-.748 6.057l-.131.023c-1.028.134-5.758.155-14.565.071l-6.666-.073-.17-.02c-1.35-.31-2.299-1.612-2.59-3.158l-.054-.314c-.067-.462-.086-.912-.08-1.618l.017-1.052c.002-.173.001-.319-.002-.46l-.004-.138c-.035-1.026-.18-1.875-.58-3.608l-.273-1.183c-.063-.279-.11-.498-.157-.728l-.028-.14c-.498-2.492-.473-4.516.301-6.275z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(161.459 2.303)"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><path d="M.031 21.66c.255-2.568 2.554-4.442 5.135-4.182a4.682 4.682 0 0 1 3.421 2.037 4.695 4.695 0 0 1-.024-1.107c.255-2.568 2.554-4.442 5.13-4.181l.028.003c.964.097 1.783-.638 1.842-1.6.008-.125.02-.251.038-.378.31-2.172 2.166-3.863 4.365-4a4.6 4.6 0 0 1 1.472.143c.975.258 1.933-.483 1.994-1.484l.21-3.452c.163-2.651 3.1-4.178 5.379-2.795 2.277 1.383 2.258 4.683-.036 6.04l-3.811 2.254a1.61 1.61 0 0 0-.644 2.053c.325.718.47 1.527.384 2.366-.256 2.563-2.555 4.436-5.13 4.181l-.03-.003c-.942-.095-1.791.605-1.839 1.546a4.692 4.692 0 0 1-5.151 4.419 4.692 4.692 0 0 1-3.423-2.037c.05.36.064.73.026 1.107-.256 2.563-2.556 4.436-5.135 4.183-2.575-.26-4.457-2.55-4.201-5.113" fill="#4285F4" mask="url(#b)"/></g><path d="M161.475 26.911a6.484 6.484 0 0 1 .733 9.17c-2.341 2.733-6.464 3.06-9.21.73a6.486 6.486 0 0 1-.733-9.17 6.554 6.554 0 0 1 9.21-.73" fill="#FFF"/><path d="M151.653 27.118a7.289 7.289 0 0 0 .823 10.305c3.084 2.618 7.715 2.25 10.344-.82a7.288 7.288 0 0 0-.823-10.305c-3.084-2.617-7.714-2.25-10.344.82zm9.3.406a5.681 5.681 0 0 1 .643 8.034 5.747 5.747 0 0 1-8.076.64 5.683 5.683 0 0 1-.643-8.035 5.748 5.748 0 0 1 7.884-.796l.193.157z" fill="#4285F4" fill-rule="nonzero"/><path d="M163.92 32.616c.85-1.668-2.037-5.655-4.051-6.672-2.014-1.018-6.642-.056-7.493 1.612 1.71 1.768 8.243 4.389 10.677 4.884l.866.176z" fill="#4285F4"/><path d="M150.526 32.93a.806.806 0 0 1 1.043.18l.063.09c.277.454.758.755 1.199.755.442 0 .862-.225 1.05-.542l.05-.098a.806.806 0 0 1 1.485.623c-.418.994-1.478 1.625-2.585 1.625-1.034 0-2.02-.616-2.575-1.529a.803.803 0 0 1 .27-1.104z" fill="#4285F4" fill-rule="nonzero"/><path d="M167.507 66.135a.805.805 0 0 1 .433 1.546l-.106.029-20.582 4.257a.805.805 0 0 1-.432-1.546l.105-.029 20.582-4.257z" fill="#4682F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M95.347 77.103a.806.806 0 0 1 .962-.61.803.803 0 0 1 .609.96c-.48 2.136-1.868 4.347-3.66 5.503l-.812.482c-.59.355-.932.637-1.146.966-.101.156-.136.288-.122.348.017.073.188.191.419.21.282.025.594-.046 1.156-.249l.903-.328c5.416-1.995 8.043-3.418 9.986-5.892.551-.702.944-1.426 1.083-2.05a.806.806 0 0 1 .961-.61.803.803 0 0 1 .61.959c-.199.893-.7 1.818-1.388 2.693-2.248 2.863-5.135 4.386-11.143 6.572l-.469.17c-.768.277-1.258.389-1.84.339-.864-.074-1.65-.615-1.845-1.443-.129-.545.019-1.102.34-1.595.335-.515.773-.902 1.414-1.312l.474-.287.375-.218c1.483-.863 2.725-2.788 3.133-4.608z"/><path d="M83.987 77.326c1.354-2.038 3.087-3.135 6.81-4.776l.392-.172c4.907-2.135 8.03-3.214 11.302-3.63a.803.803 0 1 1 .201 1.596c-3.076.39-6.09 1.432-10.862 3.509l-.714.315c-3.208 1.434-4.7 2.408-5.788 4.047-.354.533-.485 1.327-.337 2.025l.664 3.258c.478 2.406.985 5.058 1.1 5.804l.012.086c.109.792.274 1.145.438 1.154.259.015.718-.6 1.018-1.502.282-.847.3-1.733.109-3.212l-.21-1.433-.089-.5c-.05-.3-.087-.59-.11-.867-.137-1.667.196-2.735.589-3.205.616-.928 1.614-1.338 3.586-1.714l1.785-.313c.724-.13 1.088-.217 1.48-.347a.804.804 0 1 1 .505 1.527l-.233.074c-.464.14-.93.237-1.847.396l-.827.142-.537.098c-1.44.277-2.2.563-2.56 1.01l-.06.081c-.175.213-.379.866-.276 2.117.013.154.03.314.054.48l.143.835.16 1.09c.265 1.893.265 3.047-.135 4.247-.517 1.553-1.354 2.675-2.64 2.602-1.18-.067-1.645-.843-1.877-2.15l-.11-.699c-.251-1.478-1.239-6.519-1.707-8.723-.234-1.107-.032-2.343.57-3.25z"/><path d="M83.462 78.295a.803.803 0 1 1 1.388.814l-1.39 2.38c-1.383 2.392-2.463 4.338-3.33 6.014l-.114.229c-.108.233-.136.355-.118.421.018.067.257.263.373.279.19.026.441-.035.728-.184.611-.317 1.142-.857 1.777-1.744.438-.611.923-1.447 1.451-2.462a.803.803 0 1 1 1.428.74c-.56 1.078-1.077 1.97-1.57 2.658-.77 1.075-1.46 1.776-2.346 2.236-.558.29-1.125.427-1.689.35-.734-.1-1.514-.737-1.707-1.45-.165-.611-.026-1.073.357-1.811l.34-.65c1.108-2.1 2.53-4.606 4.422-7.82z"/></g><path d="M57.963 76.556a1.512 1.512 0 0 1 2.027-.102l.108.098 17.27 17.198 24.354-7.42a1.51 1.51 0 0 1 1.835.866l.049.136a1.51 1.51 0 0 1-.869 1.834l-.137.049-25.22 7.683a1.51 1.51 0 0 1-1.394-.273l-.112-.101-17.91-17.836a1.506 1.506 0 0 1-.001-2.132z" fill="#4285F4" fill-rule="nonzero"/><g><path d="M73.735 27.798a.957.957 0 0 1-.899-1.087 9.21 9.21 0 0 1 9.562-7.95c4.828.22 8.699 4.061 9.082 8.793a.922.922 0 0 1-.96 1.004l-16.785-.76z" fill="#F882FF"/><path d="M46.537 44.15l-7.78 3.522c-1.1.499-1.249 1.981-.268 2.67l6.939 4.87c.98.69 2.354.068 2.473-1.118l.842-8.396c.12-1.187-1.107-2.047-2.206-1.549" fill="#D2E3FC"/><path d="M45.335 46.642c-2.101-2.484-1.676-6.184.948-8.262l11.107-8.82c2.625-2.08 6.456-1.752 8.557.732s1.677 6.184-.948 8.263l-11.106 8.82c-2.625 2.08-6.456 1.75-8.558-.733" fill="#FABD04"/><g transform="rotate(-102 42.988 6.811)"><mask id="d" fill="#fff"><use xlink:href="#c"/></mask><path d="M3.01-6.275c-.34 0-.687.118-.977.375L-4.024-.53c-.856.758-.57 2.16.514 2.523L4.162 4.56c.16.053.32.078.476.078.896 0 1.644-.83 1.45-1.785L4.472-5.084a1.484 1.484 0 0 0-1.461-1.19M2.817-4.19l1.398 6.865-6.638-2.22 5.24-4.645" fill="#FFF" mask="url(#d)"/></g><path d="M43.26 66.655l-3.847-6.7a2.573 2.573 0 0 0-2.228-1.28l-7.868-.026a2.63 2.63 0 0 0-2.261 1.264l-4.022 6.673a2.504 2.504 0 0 0-.032 2.543l3.847 6.7a2.572 2.572 0 0 0 2.228 1.28l7.868.026a2.632 2.632 0 0 0 2.262-1.264l4.02-6.672a2.503 2.503 0 0 0 .033-2.544" fill="#38A953"/><path d="M42.107 102.465h0v-.002a8.461 8.461 0 0 0-1.253-1.538l-1.343-1.65a6.942 6.942 0 0 1-1.515-5.197l.28-2.386.122-1.045-.055-.007a5.94 5.94 0 0 0-.06-.752c-.492-3.26-3.588-5.485-6.915-4.972-3.328.513-5.628 3.571-5.135 6.83.037.252.097.496.165.735l-.05.024.424.96.97 2.194a6.96 6.96 0 0 1 .088 5.417l-.795 1.98a8.491 8.491 0 0 0-.741 1.845l-.001.002h0a8.374 8.374 0 0 0-.038 4.236c1.006 4.032 4.942 6.764 9.169 6.373 5.048-.468 8.615-4.991 7.886-9.824a8.323 8.323 0 0 0-1.203-3.223z" stroke="#D2E3FC" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M40.532 135.356c-7.25-.375-12.761-6.448-12.311-13.564l.013-.21c.449-7.116 6.69-12.581 13.939-12.206 7.25.375 12.761 6.448 12.311 13.564l-.013.21c-.45 7.117-6.69 12.581-13.939 12.206" fill="#EA4335"/><g transform="rotate(-103 70.313 56.882)"><mask id="f" fill="#fff"><use xlink:href="#e"/></mask><path d="M28.924.89c-4.53.083-8.37 3.754-8.984 8.531-.727 5.66 3.137 10.797 8.463 11.23a8.667 8.667 0 0 0 3.378-.392l.274-.097.373-.145c.485-.2.925-.425 1.339-.683l.258-.17 1.826-.942a5.58 5.58 0 0 1 4.559-.274l3.188 1.201.11.034c.11.026.223.031.331.016l.02-.004.258.04c.092.013.183.022.275.03 3.737.304 6.968-2.686 7.245-6.64.278-3.947-2.488-7.413-6.216-7.717l-.31-.016h-.227l-.028-.01a.899.899 0 0 0-.324-.035l-.156.024-3.276.663-.275.048c-1.467.221-2.962-.153-4.2-1.061l-1.68-1.235-.225-.203a9.26 9.26 0 0 0-1.183-.869l-.317-.186A8.772 8.772 0 0 0 29.265.889h-.341zm.35 1.81a6.957 6.957 0 0 1 2.96.745l.296.157c.515.29.993.642 1.427 1.049l.083.068 1.714 1.26c1.723 1.265 3.848 1.744 5.905 1.328l3.01-.61.078.011.055.002.056-.001a4.46 4.46 0 0 1 .615.002c2.71.22 4.77 2.8 4.56 5.787-.21 2.979-2.592 5.184-5.294 4.964a4.622 4.622 0 0 1-.611-.097l-.111-.017-.079-.003-2.89-1.09a7.39 7.39 0 0 0-6.029.36l-1.87.968-.095.056a7.217 7.217 0 0 1-1.55.802l-.298.103a6.838 6.838 0 0 1-2.657.304c-4.266-.347-7.413-4.532-6.814-9.196.502-3.911 3.616-6.887 7.222-6.954l.316.001z" fill="#FFF" fill-rule="nonzero" mask="url(#f)"/></g></g><g><g transform="rotate(9 44.073 633.419)"><mask id="h" fill="#fff"><use xlink:href="#g"/></mask><path d="M35.644 27.522l-24.76 9.258a1.253 1.253 0 0 1-1.614-.745L.079 11.095a1.268 1.268 0 0 1 .74-1.627L25.58.21c.65-.243 1.372.09 1.614.745l9.191 24.94a1.268 1.268 0 0 1-.74 1.627" fill="#4285F4" mask="url(#h)"/></g><path d="M121.048 11.073a4.033 4.033 0 0 0-1.246.577l-.217.161c-.247.196-.47.42-.664.668l-.548.544a2.164 2.164 0 0 1-1.531.64h-1.374l-.094.007a.686.686 0 0 0-.177.052l-.072.014-.12.03a3.055 3.055 0 0 0-2.149 3.73 3.024 3.024 0 0 0 3.71 2.157l.2-.064.06-.007a.65.65 0 0 0 .13-.042l.178-.099 1.076-.625a2.152 2.152 0 0 1 1.64-.217l.815.22c.218.091.522.173.835.22.667.097 1.35.027 2-.215 1.854-.691 2.95-2.67 2.562-4.618-.461-2.313-2.759-3.742-5.014-3.133zm3.732 3.388c.263 1.322-.485 2.672-1.737 3.139a2.723 2.723 0 0 1-1.965-.019l-.888-.244a3.459 3.459 0 0 0-2.636.35l-1.052.609-.072.024a1.717 1.717 0 0 1-2.31-1.157 1.748 1.748 0 0 1 1.224-2.136l.065-.016c.045-.01.094-.018.15-.025l.069-.016 1.215-.001a3.47 3.47 0 0 0 2.456-1.024l.598-.601.106-.127a3.04 3.04 0 0 1 .4-.388l.16-.117a2.734 2.734 0 0 1 4.217 1.749zm-21.012-1.449a3.139 3.139 0 0 0-2.443 3.69 3.11 3.11 0 0 0 3.669 2.451 3.139 3.139 0 0 0 2.442-3.689 3.111 3.111 0 0 0-3.668-2.452zm2.387 2.706a1.832 1.832 0 0 1-1.422 2.155 1.803 1.803 0 0 1-2.126-1.426 1.833 1.833 0 0 1 1.422-2.155 1.803 1.803 0 0 1 2.09 1.281l.036.145z" fill="#FFF" fill-rule="nonzero"/><g transform="rotate(9 43.883 633.603)"><mask id="j" fill="#fff"><use xlink:href="#i"/></mask><path d="M13.402 18.342a.654.654 0 0 1 .782-.355l.09.035 25.268 11.894a.653.653 0 0 1-.467 1.217l-.09-.035-24.67-11.613-6.724 14.77a.654.654 0 0 1-.775.357l-.09-.033a.653.653 0 0 1-.358-.775l.034-.09 7-15.372z" fill="#FFF" fill-rule="nonzero" mask="url(#j)"/></g></g></g></svg>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.html new file mode 100644 index 00000000000..cfea57c627a --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.html @@ -0,0 +1,5 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html"> + +<script src="../mojo/nearby_share_settings.mojom-lite.js"></script> +<script src="nearby_share_settings.js"></script> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.js b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.js new file mode 100644 index 00000000000..78b66d96202 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings.js @@ -0,0 +1,64 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +// #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +// #import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; +// #import '../mojo/nearby_share_settings.mojom-lite.js'; +// clang-format on + +cr.define('nearby_share', function() { + /** @type {?nearbyShare.mojom.NearbyShareSettingsInterface} */ + let nearbyShareSettings = null; + /** @type {boolean} */ + let isTesting = false; + + /** + * @param {!nearbyShare.mojom.NearbyShareSettingsInterface} + * testNearbyShareSettings A test nearby share settings impl. + */ + /* #export */ function setNearbyShareSettingsForTesting( + testNearbyShareSettings) { + nearbyShareSettings = testNearbyShareSettings; + isTesting = true; + } + + /** + * @return {!nearbyShare.mojom.NearbyShareSettingsInterface} + * the Nearby Share settings interface + */ + /* #export */ function getNearbyShareSettings() { + if (!nearbyShareSettings) { + nearbyShareSettings = nearbyShare.mojom.NearbyShareSettings.getRemote(); + } + return nearbyShareSettings; + } + + /** + * @param {!nearbyShare.mojom.NearbyShareSettingsObserverInterface} observer + * @return {?nearbyShare.mojom.NearbyShareSettingsObserverReceiver} the mojo + * receiver. + */ + /* #export */ function observeNearbyShareSettings(observer) { + if (isTesting) { + getNearbyShareSettings().addSettingsObserver( + /** @type {!nearbyShare.mojom.NearbyShareSettingsObserverRemote} */ ( + observer)); + return null; + } + + const receiver = + new nearbyShare.mojom.NearbyShareSettingsObserverReceiver(observer); + getNearbyShareSettings().addSettingsObserver( + receiver.$.bindNewPipeAndPassRemote()); + return receiver; + } + + // #cr_define_end + return { + setNearbyShareSettingsForTesting, + getNearbyShareSettings, + observeNearbyShareSettings, + }; +}); diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.html new file mode 100644 index 00000000000..411071d8685 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.html @@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="./nearby_share_settings.html"> +<script src="./nearby_share_settings_behavior.js"></script> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.js b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.js new file mode 100644 index 00000000000..aa0431433bf --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_share_settings_behavior.js @@ -0,0 +1,150 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +// #import {getNearbyShareSettings, observeNearbyShareSettings} from './nearby_share_settings.m.js'; +// clang-format on + +/** + * @fileoverview NearbyShareSettingsBehavior wraps up talking to the settings + * mojo to get values and keeps them in sync by observing for changes + */ +cr.define('nearby_share', function() { + /** + * @typedef {{ + * enabled:boolean, + * deviceName:string, + * dataUsage:nearbyShare.mojom.DataUsage, + * visibility:nearbyShare.mojom.Visibility, + * allowedContacts:Array<string> + * }} + */ + /* #export */ let NearbySettings; + + /** @polymerBehavior */ + /* #export */ const NearbyShareSettingsBehavior = { + properties: { + /** @type {?NearbySettings} */ + settings: { + type: Object, + notify: true, + value: {}, + }, + }, + + observers: ['settingsChanged_(settings.*)'], + + /** @private {?nearbyShare.mojom.NearbyShareSettingsInterface} */ + nearbyShareSettings_: null, + + /** @private {?nearbyShare.mojom.NearbyShareSettingsObserverReceiver} */ + observerReceiver_: null, + + attached() { + this.nearbyShareSettings_ = nearby_share.getNearbyShareSettings(); + this.observerReceiver_ = nearby_share.observeNearbyShareSettings( + /** @type {!nearbyShare.mojom.NearbyShareSettingsObserverInterface} */ + (this)); + // Request the initial values and trigger onSettingsRetrieved when they + // are all retrieved. + Promise + .all([ + this.nearbyShareSettings_.getEnabled(), + this.nearbyShareSettings_.getDeviceName(), + this.nearbyShareSettings_.getDataUsage(), + this.nearbyShareSettings_.getVisibility(), + this.nearbyShareSettings_.getAllowedContacts(), + ]) + .then((results) => { + this.set('settings.enabled', results[0].enabled); + this.set('settings.deviceName', results[1].deviceName); + this.set('settings.dataUsage', results[2].dataUsage); + this.set('settings.visibility', results[3].visibility); + this.set('settings.allowedContacts', results[4].allowedContacts); + this.onSettingsRetrieved(); + }); + }, + + detached() { + if (this.observerReceiver_) { + this.observerReceiver_.$.close(); + } + if (this.nearbyShareSettings_) { + /** @type {nearbyShare.mojom.NearbyShareSettingsRemote} */ + (this.nearbyShareSettings_).$.close(); + } + }, + + /** + * @param {!boolean} enabled + */ + onEnabledChanged(enabled) { + this.set('settings.enabled', enabled); + }, + + /** + * @param {!string} deviceName + */ + onDeviceNameChanged(deviceName) { + this.set('settings.deviceName', deviceName); + }, + + /** + * @param {!nearbyShare.mojom.DataUsage} dataUsage + */ + onDataUsageChanged(dataUsage) { + this.set('settings.dataUsage', dataUsage); + }, + + /** + * @param {!nearbyShare.mojom.Visibility} visibility + */ + onVisibilityChanged(visibility) { + this.set('settings.visibility', visibility); + }, + + /** + * @param {!Array<!string>} allowedContacts + */ + onAllowedContactsChanged(allowedContacts) { + this.set('settings.allowedContacts', allowedContacts); + }, + + /** + * TODO(vecore): Type is actually PolymerDeepPropertyChange but the externs + * definition needs to be fixed so the value can be cast to primitive + * types. + * @param {Object} change + * @private + */ + settingsChanged_(change) { + switch (change.path) { + case 'settings.enabled': + this.nearbyShareSettings_.setEnabled(change.value); + break; + case 'settings.deviceName': + this.nearbyShareSettings_.setDeviceName(change.value); + break; + case 'settings.dataUsage': + this.nearbyShareSettings_.setDataUsage(change.value); + break; + case 'settings.visibility': + this.nearbyShareSettings_.setVisibility(change.value); + break; + case 'settings.allowedContacts': + this.nearbyShareSettings_.setAllowedContacts(change.value); + break; + } + }, + + /** Override in polymer element to process the initial values */ + onSettingsRetrieved() {}, + + }; + // #cr_define_end + return { + NearbyShareSettingsBehavior, + NearbySettings, + }; +}); diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html new file mode 100644 index 00000000000..7c1563f8aba --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html @@ -0,0 +1,33 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html"> + +<iron-iconset-svg name="nearby20" size="20"> + <svg> + <defs> + <!-- + Keep these in sorted order by id="". See also http://goo.gl/Y1OdAq + --> + <g id="checked"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M10 18C14.4183 18 18 14.4183 18 10C18 5.58172 14.4183 2 10 2C5.58172 2 2 5.58172 2 10C2 14.4183 5.58172 18 10 18ZM6.16667 9.40426L8.33333 11.617L13.8333 6L15 7.19149L8.33333 14L5 10.5957L6.16667 9.40426Z"></path> + </g> + <g id="contact-all"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M12.9981 6C12.9981 4.935 12.6229 3.9525 12 3.18C12.3152 3.075 12.6454 3 12.9981 3C14.6567 3 16 4.3425 16 6C16 7.6575 14.6567 9 12.9981 9C12.6754 9 12.3677 8.9325 12.075 8.8425C12.0525 8.835 12.03 8.8275 12 8.82C12.6229 8.0475 12.9981 7.065 12.9981 6ZM13.6602 10.1309C15.0302 11.0609 16.0002 12.3209 16.0002 14.0009V17.0009H20.0002V14.0009C20.0002 11.8209 16.4202 10.5309 13.6602 10.1309ZM7.5 5C6.675 5 6 5.675 6 6.5C6 7.325 6.675 8 7.5 8C8.325 8 9 7.325 9 6.5C9 5.675 8.325 5 7.5 5V5ZM7.5 13C5.475 13 3.15 13.86 3 14.34V15H12V14.3333C11.85 13.86 9.525 13 7.5 13V13ZM7.5 3C9.43375 3 11 4.56625 11 6.5C11 8.43375 9.43375 10 7.5 10C5.56625 10 4 8.43375 4 6.5C4 4.56625 5.56625 3 7.5 3ZM7.5 11C9.66938 11 14 12.1486 14 14.4286V17H1V14.4286C1 12.1486 5.33062 11 7.5 11Z"></path> + </g> + <g id="contact-group"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 3C9.425 3 11 4.575 11 6.5C11 8.425 9.425 10 7.5 10C5.575 10 4 8.425 4 6.5C4 4.575 5.575 3 7.5 3ZM7.5 5C6.67957 5 6 5.67957 6 6.5C6 7.32043 6.67957 8 7.5 8C8.32043 8 9 7.32043 9 6.5C9 5.67957 8.32043 5 7.5 5Z"></path> + <path d="M15 6H17V8H19V10H17V12H15V10H13V8H15V6Z"></path> + <path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 11C9.60583 11 13.7789 12.0336 13.9916 14.0859L14 14.25V17H1V14.25C1 12.0887 5.33875 11 7.5 11ZM11.9947 14.3433C11.9867 14.3476 11.9693 14.3346 11.9329 14.3011L11.8432 14.2246C11.6159 14.0441 11.2636 13.85 10.8172 13.6713C9.79154 13.2607 8.42752 13 7.5 13C6.57248 13 5.20846 13.2607 4.18279 13.6713C3.73641 13.85 3.38414 14.0441 3.15679 14.2246L3.0671 14.3011C3.01855 14.3458 3.00384 14.3539 3 14.3335V15H12V14.3335L11.9947 14.3433Z"></path> + </g> + <g id="radar"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M14.0353 15.096C12.9268 15.975 11.5247 16.5 10 16.5C6.41015 16.5 3.5 13.5899 3.5 10C3.5 6.41015 6.41015 3.5 10 3.5C13.5899 3.5 16.5 6.41015 16.5 10C16.5 11.5247 15.975 12.9268 15.096 14.0354L14.0261 12.9654C14.6382 12.1358 15 11.1101 15 10C15 7.23858 12.7614 5 10 5C7.23858 5 5 7.23858 5 10C5 12.7614 7.23858 15 10 15C11.1101 15 12.1358 14.6382 12.9654 14.0261L14.0353 15.096ZM12.948 11.8874C13.2974 11.3428 13.5 10.6951 13.5 10C13.5 8.067 11.933 6.5 10 6.5C8.067 6.5 6.5 8.067 6.5 10C6.5 11.933 8.067 13.5 10 13.5C10.6951 13.5 11.3428 13.2974 11.8874 12.948L10.3885 11.4492C10.2646 11.4823 10.1344 11.5 10 11.5C9.17157 11.5 8.5 10.8284 8.5 10C8.5 9.17157 9.17157 8.5 10 8.5C10.8284 8.5 11.5 9.17157 11.5 10C11.5 10.1344 11.4823 10.2646 11.4492 10.3885L12.948 11.8874ZM18 10C18 14.4183 14.4183 18 10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10Z"></path> + </g> + <g id="visibility"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M13 10C13 11.6569 11.6569 13 10 13C8.34315 13 7 11.6569 7 10C7 8.34315 8.34315 7 10 7C11.6569 7 13 8.34315 13 10ZM11 10C11 10.5523 10.5523 11 10 11C9.44772 11 9 10.5523 9 10C9 9.44772 9.44772 9 10 9C10.5523 9 11 9.44772 11 10ZM10 16C14.3333 16 17.3333 14 19 10C17 6 14 4 10 4C6 4 3 6 1 10C2.66667 14 5.66667 16 10 16ZM10 6C12.9373 6 15.1315 7.29402 16.7641 10.0695C15.3775 12.7465 13.2078 14 10 14C6.79225 14 4.6225 12.7465 3.2359 10.0695C4.8685 7.29402 7.06265 6 10 6Z"></path> + </g> + <g id="visibility-off"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M17.3897 18.0247L1.9895 2.62442L2.01413 2.59979L2.00015 2.58582L0.585938 4.00003L3.29316 6.70725C2.42105 7.5893 1.65672 8.6869 1.00015 10C2.66682 14 5.66682 16 10.0002 16C10.8372 16 11.6245 15.9254 12.3621 15.7761L16.0002 19.4142L17.3897 18.0247ZM3.23605 10.0696C3.68277 9.31012 4.17153 8.66159 4.70605 8.12014L7.03328 10.4474C7.22745 11.7461 8.25408 12.7727 9.55281 12.9669L10.5721 13.9862C10.3852 13.9954 10.1946 14 10.0002 14C6.7924 14 4.62265 12.7465 3.23605 10.0696Z"></path> + <path d="M16.1839 13.9904C17.3593 13.0152 18.298 11.6851 19.0002 10C17.0002 6.00003 14.0002 4.00003 10.0002 4.00003C8.81854 4.00003 7.7242 4.17455 6.71711 4.5236L8.34623 6.15272C8.86951 6.05045 9.42035 6.00003 10.0002 6.00003C12.9375 6.00003 15.1317 7.29405 16.7643 10.0696C16.2217 11.117 15.5593 11.9465 14.7617 12.5682L16.1839 13.9904Z" fill="#1A73E8"></path> + <path d="M12.9133 10.7198L9.28043 7.08692C9.511 7.03014 9.75206 7.00003 10.0002 7.00003C11.657 7.00003 13.0002 8.34317 13.0002 10C13.0002 10.2481 12.97 10.4892 12.9133 10.7198Z" fill="#1A73E8"></path> + </g> + </svg> +</iron-iconset-svg> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html b/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html new file mode 100644 index 00000000000..a32fdf98208 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html @@ -0,0 +1,88 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> +<link rel="import" href="nearby_share_settings_behavior.html"> +<link rel="import" href="nearby_contact_visibility.html"> + +<dom-module id="nearby-visibility-page"> + <template> + <style include="cr-icons cr-shared-style"></style> + <style> + :host { + --nearby-page-space-block: 26px; + --nearby-page-space-inline: 32px; + --nearby-page-space-large-inline: 42px; + } + + #page-container { + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + padding: 30px; + } + + #center-content { + box-sizing: border-box; + display: flex; + flex-grow: 1; + justify-content: center; + margin-inline-end: 24px; + margin-inline-start: 24px; + overflow: hidden; + } + + #page-title { + font-size: 125%; + font-weight: normal; + } + + #page-sub-title { + font-weight: normal; + } + + #actions { + display: flex; + margin-block-end: var(--nearby-page-space-block); + margin-block-start: 17px; + margin-inline-end: var(--nearby-page-space-inline); + margin-inline-start: var(--nearby-page-space-inline); + text-align: end; + } + + #manage-contacts-button { + margin-inline-end: auto; + } + </style> + <div id="page-container"> + <div id="header"> + <h1 id="page-title">Device Visibility</h1> + <h4 id="page-sub-title"> + Select who you want this device to be visible to + </h4> + </div> + + <div id=center-content> + <nearby-contact-visibility id="contactVisibility" + settings="{{settings}}"> + </nearby-contact-visibility> + </div> + + <div id="actions"> + <cr-button id="manage-contacts-button" on-click="onManageContactsTap_"> + Manage Contacts + </cr-button> + <cr-button id="cancel-button" class="cancel-button" + on-click="onCloseTap_"> + Cancel + </cr-button> + <cr-button id="next-button" class="action-button" on-click="onNextTap_"> + Confirm + </cr-button> + </div> + </div> + </template> + <script src="nearby_visibility_page.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js b/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js new file mode 100644 index 00000000000..16599a15107 --- /dev/null +++ b/chromium/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.js @@ -0,0 +1,39 @@ + +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-visibility-page' component is part of the Nearby + * Share onboarding flow. It allows users to setup their visibility preference + * while enabling the feature for the first time. + * + * It is embedded in chrome://os-settings, chrome://settings and as a standalone + * dialog via chrome://nearby. + */ +Polymer({ + is: 'nearby-visibility-page', + + properties: { + /** @type {?nearby_share.NearbySettings} */ + settings: { + type: Object, + notify: true, + } + }, + + onNextTap_() { + this.set('settings.enabled', true); + this.fire('change-page', {page: 'discovery'}); + }, + + onCloseTap_() { + this.fire('close'); + }, + + onManageContactsTap_() { + // TODO(vecore): this is not a final link + window.open('https://contacts.google.com'); + }, + +}); diff --git a/chromium/chrome/browser/resources/new_tab_page/BUILD.gn b/chromium/chrome/browser/resources/new_tab_page/BUILD.gn index ded22388136..c83b365eb56 100644 --- a/chromium/chrome/browser/resources/new_tab_page/BUILD.gn +++ b/chromium/chrome/browser/resources/new_tab_page/BUILD.gn @@ -16,9 +16,13 @@ js_type_check("closure_compile") { ":customize_dialog", ":doodle_share_dialog", ":fakebox", - ":grid", ":iframe", ":logo", + ":module_descriptor", + ":module_registry", + ":modules", + ":one_google_bar_api", + ":promo_browser_command_proxy", ":realbox", ":realbox_button", ":realbox_dropdown", @@ -38,20 +42,30 @@ js_library("browser_proxy") { "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:cr.m", ] - externs_list = [ "externs.js" ] } js_library("app") { deps = [ ":background_manager", ":browser_proxy", + ":module_wrapper", + ":modules", ":most_visited", + ":one_google_bar_api", + ":promo_browser_command_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:event_tracker.m", "//ui/webui/resources/js:load_time_data.m", ] } +js_library("promo_browser_command_proxy") { + deps = [ + "//chrome/browser/promo_browser_command:mojo_bindings_js_library_for_compile", + "//ui/webui/resources/js:cr.m", + ] +} + js_library("most_visited") { deps = [ ":browser_proxy", @@ -86,9 +100,9 @@ js_library("customize_backgrounds") { js_library("customize_themes") { deps = [ - ":grid", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_grid", "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", ] } @@ -114,12 +128,6 @@ js_library("theme_icon") { ] } -js_library("grid") { - deps = [ - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - js_library("voice_search_overlay") { deps = [ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", @@ -210,7 +218,37 @@ js_library("background_manager") { deps = [ ":utils" ] } -html_to_js("web_components") { +js_library("one_google_bar_api") { +} + +js_library("module_descriptor") { + sources = [ "modules/module_descriptor.js" ] +} + +js_library("modules") { + sources = [ "modules/modules.js" ] + deps = [ + ":module_registry", + "modules/dummy:module", + "modules/kaleidoscope:module", + ] +} + +js_library("module_wrapper") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("module_registry") { + sources = [ "modules/module_registry.js" ] + deps = [ + ":module_descriptor", + "//ui/webui/resources/js:cr.m", + ] +} + +html_to_js("web_components_local") { js_files = [ "app.js", "customize_backgrounds.js", @@ -219,7 +257,6 @@ html_to_js("web_components") { "customize_themes.js", "doodle_share_dialog.js", "fakebox.js", - "grid.js", "logo.js", "mini_page.js", "most_visited.js", @@ -231,6 +268,14 @@ html_to_js("web_components") { "theme_icon.js", "iframe.js", "voice_search_overlay.js", + "module_wrapper.js", + ] +} + +group("web_components") { + public_deps = [ + ":web_components_local", + "modules/dummy:web_components", ] } @@ -239,6 +284,7 @@ if (optimize_webui) { source = "new_tab_page_resources.grd" deps = [ + "//chrome/browser/promo_browser_command:mojo_bindings_js", "//chrome/browser/resources/new_tab_page:web_components", "//chrome/browser/ui/webui/new_tab_page:mojo_bindings_js", "//skia/public/mojom:mojom_js", @@ -264,6 +310,7 @@ if (optimize_webui) { deps = [ ":unoptimized_resources" ] excludes = [ + "../../promo_browser_command/promo_browser_command.mojom-lite.js", "../../ui/webui/new_tab_page/new_tab_page.mojom-lite.js", "../../../common/search/omnibox.mojom-lite.js", "../../../../skia/public/mojom/skcolor.mojom-lite.js", @@ -286,10 +333,13 @@ if (optimize_webui) { "chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js", "chrome://resources/mojo/mojo/public/mojom/base/text_direction.mojom-lite.js", "chrome://resources/mojo/mojo/public/mojom/base/time.mojom-lite.js", + "chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js", "chrome://resources/mojo/skia/public/mojom/skcolor.mojom-lite.js", + "chrome://resources/mojo/url/mojom/origin.mojom-lite.js", "chrome://resources/mojo/url/mojom/url.mojom-lite.js", "new_tab_page.mojom-lite.js", "omnibox.mojom-lite.js", + "promo_browser_command.mojom-lite.js", ] } } diff --git a/chromium/chrome/browser/resources/new_tab_page/app.html b/chromium/chrome/browser/resources/new_tab_page/app.html index 5758e8a6d49..d1f83b7271d 100644 --- a/chromium/chrome/browser/resources/new_tab_page/app.html +++ b/chromium/chrome/browser/resources/new_tab_page/app.html @@ -4,6 +4,19 @@ --ntp-theme-text-color: var(--google-grey-800); --ntp-theme-text-shadow: none; --ntp-one-google-bar-height: 56px; + --ntp-search-box-width: 337px; + } + + @media (min-width: 560px) { + :host { + --ntp-search-box-width: 449px; + } + } + + @media (min-width: 672px) { + :host { + --ntp-search-box-width: 561px; + } } @media (prefers-color-scheme: dark) { @@ -51,7 +64,7 @@ } #logo { - margin-bottom: 8px; + margin-bottom: 38px; z-index: 1; /* Needed so it layers on top of OneGoogleBar. */ } @@ -61,6 +74,12 @@ margin-bottom: 32px; } + ntp-fakebox, + ntp-realbox, + ntp-module-wrapper { + width: var(--ntp-search-box-width); + } + ntp-realbox { visibility: hidden; } @@ -84,6 +103,10 @@ width: 100%; } + ntp-module-wrapper + ntp-module-wrapper { + margin-top: 24px; + } + #customizeButtonSpacer { flex-grow: 1; } @@ -154,7 +177,7 @@ #themeAttribution { align-self: flex-start; bottom: 16px; - color: var(--ntp-secondary-text-color); + color: var(--cr-secondary-text-color); margin-inline-start: 16px; position: fixed; } @@ -255,11 +278,14 @@ use-white-add-icon$="[[theme_.shortcutUseWhiteAddIcon]]" use-title-pill$="[[theme_.shortcutUseTitlePill]]"> </ntp-most-visited> - <dom-if if="[[lazyRender_]]"> + <dom-if if="[[lazyRender_]]" on-dom-change="onLazyRendered_"> <template> <ntp-iframe id="promo" hidden$="[[!promoLoaded_]]" src="chrome-untrusted://new-tab-page/promo"> </ntp-iframe> + <template is="dom-repeat" items="[[moduleDescriptors_]]" id="modules"> + <ntp-module-wrapper descriptor="[[item]]"></ntp-module-wrapper> + </template> <a id="backgroundImageAttribution" href="[[backgroundImageAttributionUrl_]]" hidden="[[!backgroundImageAttribution1_]]"> diff --git a/chromium/chrome/browser/resources/new_tab_page/app.js b/chromium/chrome/browser/resources/new_tab_page/app.js index 121633a3d00..e76bdf54447 100644 --- a/chromium/chrome/browser/resources/new_tab_page/app.js +++ b/chromium/chrome/browser/resources/new_tab_page/app.js @@ -10,10 +10,13 @@ import './iframe.js'; import './fakebox.js'; import './realbox.js'; import './logo.js'; +import './module_wrapper.js'; +import './modules/modules.js'; // Registers module descriptors. import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/shared_style_css.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; +import {hexColorToSkColor, skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; @@ -22,7 +25,19 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/poly import {BackgroundManager} from './background_manager.js'; import {BrowserProxy} from './browser_proxy.js'; import {BackgroundSelection, BackgroundSelectionType} from './customize_dialog.js'; -import {$$, hexColorToSkColor, skColorToRgba} from './utils.js'; +import {ModuleDescriptor} from './modules/module_descriptor.js'; +import {ModuleRegistry} from './modules/module_registry.js'; +import {oneGoogleBarApi} from './one_google_bar_api.js'; +import {PromoBrowserCommandProxy} from './promo_browser_command_proxy.js'; +import {$$} from './utils.js'; + +/** + * @typedef {{ + * commandId: promoBrowserCommand.mojom.Command<number>, + * clickInfo: !promoBrowserCommand.mojom.ClickInfo + * }} + */ +let CommandData; class AppElement extends PolymerElement { static get is() { @@ -187,6 +202,9 @@ class AppElement extends PolymerElement { * @private */ lazyRender_: Boolean, + + /** @private {!Array<!ModuleDescriptor>} */ + moduleDescriptors_: Object, }; } @@ -225,7 +243,9 @@ class AppElement extends PolymerElement { performance.measure('theme-set'); this.theme_ = theme; }); - this.eventTracker_.add(window, 'message', ({data}) => { + this.eventTracker_.add(window, 'message', (event) => { + /** @type {!Object} */ + const data = event.data; // Something in OneGoogleBar is sending a message that is received here. // Need to ignore it. if (typeof data !== 'object') { @@ -233,9 +253,9 @@ class AppElement extends PolymerElement { } if ('frameType' in data) { if (data.frameType === 'promo') { - this.handlePromoMessage_(data); + this.handlePromoMessage_(event); } else if (data.frameType === 'one-google-bar') { - this.handleOneGoogleBarMessage_(data); + this.handleOneGoogleBarMessage_(event); } } }); @@ -344,10 +364,11 @@ class AppElement extends PolymerElement { document.body.appendChild(endOfBodyScript); this.pageHandler_.onOneGoogleBarRendered(BrowserProxy.getInstance().now()); + oneGoogleBarApi.trackDarkModeChanges(); } /** @private */ - async onOneGoogleBarDarkThemeEnabledChange_() { + onOneGoogleBarDarkThemeEnabledChange_() { if (!this.oneGoogleBarLoaded_) { return; } @@ -358,16 +379,7 @@ class AppElement extends PolymerElement { }); return; } - const {gbar} = /** @type {{gbar}} */ (window); - if (!gbar) { - return; - } - const oneGoogleBar = - await /** @type {!{a: {bf: function(): !Promise<{pc: !Function}>}}} */ ( - gbar) - .a.bf(); - oneGoogleBar.pc.call( - oneGoogleBar, this.oneGoogleBarDarkThemeEnabled_ ? 1 : 0); + oneGoogleBarApi.setForegroundLight(this.oneGoogleBarDarkThemeEnabled_); } /** @@ -443,10 +455,19 @@ class AppElement extends PolymerElement { } /** @private */ + async onLazyRendered_() { + if (!loadTimeData.getBoolean('modulesEnabled')) { + return; + } + this.moduleDescriptors_ = + await ModuleRegistry.getInstance().initializeModules(); + } + + /** @private */ onOpenVoiceSearch_() { this.showVoiceSearchOverlay_ = true; this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.ACTIVATE_SEARCH_BOX); + newTabPage.mojom.VoiceSearchAction.kActivateSearchBox); } /** @private */ @@ -478,7 +499,7 @@ class AppElement extends PolymerElement { if (ctrlKeyPressed && e.code === 'Period' && e.shiftKey) { this.showVoiceSearchOverlay_ = true; this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.ACTIVATE_KEYBOARD); + newTabPage.mojom.VoiceSearchAction.kActivateKeyboard); } } @@ -584,7 +605,7 @@ class AppElement extends PolymerElement { computeDoodleAllowed_() { return loadTimeData.getBoolean('themeModeDoodlesEnabled') || !this.showBackgroundImage_ && this.theme_ && - this.theme_.type === newTabPage.mojom.ThemeType.DEFAULT && + this.theme_.type === newTabPage.mojom.ThemeType.kDefault && !this.theme_.isDark; } @@ -634,6 +655,32 @@ class AppElement extends PolymerElement { } /** + * Sends the command and the accompanying mouse click info received from the + * promo of the given source and origin to the browser. Relays the execution + * status response back to the source promo frame. |commandSource| and + * |commandOrigin| are used only to send the execution status response back to + * the source promo frame and should not be used for anything else. + * @param {!CommandData} commandData Command and mouse click info. + * @param {Window} commandSource Source promo frame. + * @param {string} commandOrigin Origin of the source promo frame. + * @private + */ + executePromoBrowserCommand_(commandData, commandSource, commandOrigin) { + // Make sure we don't send unsupported commands to the browser. + /** @type {!promoBrowserCommand.mojom.Command} */ + const commandId = Object.values(promoBrowserCommand.mojom.Command) + .includes(commandData.commandId) ? + commandData.commandId : + promoBrowserCommand.mojom.Command.kUnknownCommand; + + PromoBrowserCommandProxy.getInstance() + .handler.executeCommand(commandId, commandData.clickInfo) + .then(({commandExecuted}) => { + commandSource.postMessage(commandExecuted, commandOrigin); + }); + } + + /** * Handles messages from the OneGoogleBar iframe. The messages that are * handled include show bar on load and overlay updates. * @@ -643,10 +690,12 @@ class AppElement extends PolymerElement { * When modal overlays are enabled, activate/deactivate controls if the * OneGoogleBar is layered on top of #content with a backdrop. This would * happen when OneGoogleBar has an overlay open. - * @param {!Object} data + * @param {!MessageEvent} event * @private */ - handleOneGoogleBarMessage_(data) { + handleOneGoogleBarMessage_(event) { + /** @type {!Object} */ + const data = event.data; if (data.messageType === 'loaded') { if (!this.oneGoogleBarModalOverlaysEnabled_) { const oneGoogleBar = $$(this, '#oneGoogleBar'); @@ -677,6 +726,9 @@ class AppElement extends PolymerElement { } else if (data.messageType === 'deactivate') { this.$.oneGoogleBarOverlayBackdrop.toggleAttribute('show', false); $$(this, '#oneGoogleBar').style.zIndex = '0'; + } else if (data.messageType === 'execute-browser-command') { + this.executePromoBrowserCommand_( + /** @type {!CommandData} */ (data.data), event.source, event.origin); } } @@ -684,10 +736,12 @@ class AppElement extends PolymerElement { * Handle messages from promo iframe. This shows the promo on load and sets * up the show/hide logic (in case there is an overlap with most-visited * tiles). - * @param {!Object} data + * @param {!MessageEvent} event * @private */ - handlePromoMessage_(data) { + handlePromoMessage_(event) { + /** @type {!Object} */ + const data = event.data; if (data.messageType === 'loaded') { this.promoLoaded_ = true; const onResize = () => { @@ -700,6 +754,9 @@ class AppElement extends PolymerElement { this.pageHandler_.onPromoRendered(BrowserProxy.getInstance().now()); } else if (data.messageType === 'link-clicked') { this.pageHandler_.onPromoLinkClicked(); + } else if (data.messageType === 'execute-browser-command') { + this.executePromoBrowserCommand_( + /** @type {!CommandData} */ (data), event.source, event.origin); } } diff --git a/chromium/chrome/browser/resources/new_tab_page/background_manager.js b/chromium/chrome/browser/resources/new_tab_page/background_manager.js index 5ce42ef901a..eda3617ec45 100644 --- a/chromium/chrome/browser/resources/new_tab_page/background_manager.js +++ b/chromium/chrome/browser/resources/new_tab_page/background_manager.js @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {BrowserProxy} from './browser_proxy.js'; -import {skColorToRgba} from './utils.js'; /** * @fileoverview The background manager brokers access to background related @@ -61,6 +61,8 @@ export class BackgroundManager { this.backgroundImage_ = document.body.querySelector('#backgroundImage'); /** @private {LoadTimeResolver} */ this.loadTimeResolver_ = null; + /** @private {string} */ + this.url_ = this.backgroundImage_.src; } /** @@ -105,14 +107,19 @@ export class BackgroundManager { if (image.positionY) { url.searchParams.append('positionY', image.positionY); } - if (url.href === this.backgroundImage_.src) { + if (url.href === this.url_) { return; } if (this.loadTimeResolver_) { this.loadTimeResolver_.reject(); this.loadTimeResolver_ = null; } - this.backgroundImage_.src = url.href; + // We use |contentWindow.location.replace| because reloading the iframe by + // setting its |src| adds a history entry. + this.backgroundImage_.contentWindow.location.replace(url.href); + // We track the URL separately because |contentWindow.location.replace| does + // not update the iframe's src attribute. + this.url_ = url.href; } /** diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.html b/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.html index f7e131a8742..555716f0113 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.html +++ b/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.html @@ -7,8 +7,8 @@ padding: 4px; } - ntp-grid { - --ntp-grid-gap: 8px; + cr-grid { + --cr-grid-gap: 8px; } .tile { @@ -32,7 +32,7 @@ } .label { - color: var(--ntp-primary-text-color); + color: var(--cr-primary-text-color); margin-bottom: 4px; margin-top: 3px; min-height: 30px; @@ -138,7 +138,7 @@ -webkit-mask-image: url(chrome://resources/images/business.svg); -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100%; - background-color: var(--ntp-primary-text-color); + background-color: var(--cr-primary-text-color); height: 48px; margin: auto; width: 48px; @@ -166,7 +166,7 @@ <div id="backgroundsDisabledIcon"></div> <div id="backgroundsDisabledTitle">$i18n{customBackgroundDisabled}</div> </div> -<ntp-grid id="collections" columns="3" hidden="[[!showBackgroundSelection_]]"> +<cr-grid id="collections" columns="3" hidden="[[!showBackgroundSelection_]]"> <div id="uploadFromDevice" class="tile" role="button" on-click="onUploadFromDeviceClick_" tabindex="0"> <div class$="[[getCustomBackgroundClass_(theme, backgroundSelection)]]"> @@ -203,8 +203,8 @@ </div> </template> </dom-repeat> -</ntp-grid> -<ntp-grid id="images" columns="3" hidden="[[!selectedCollection]]"> +</cr-grid> +<cr-grid id="images" columns="3" hidden="[[!selectedCollection]]"> <dom-repeat id="imagesRepeat" items="[[images_]]"> <template> <div @@ -220,4 +220,4 @@ </div> </template> </dom-repeat> -</ntp-grid> +</cr-grid> diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.js b/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.js index 4f99d35e938..2717fe8d8ba 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.js +++ b/chromium/chrome/browser/resources/new_tab_page/customize_backgrounds.js @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'chrome://resources/cr_elements/hidden_style_css.m.js'; -import './grid.js'; +import 'chrome://resources/cr_elements/cr_grid/cr_grid.js'; import './mini_page.js'; import './iframe.js'; @@ -153,14 +153,14 @@ class CustomizeBackgroundsElement extends PolymerElement { onCollectionClick_(e) { this.selectedCollection = this.$.collectionsRepeat.itemForElement(e.target); this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.BACKGROUNDS_COLLECTION_OPENED); + newTabPage.mojom.CustomizeDialogAction.kBackgroundsCollectionOpened); } /** @private */ async onUploadFromDeviceClick_() { this.pageHandler_.onCustomizeDialogAction( newTabPage.mojom.CustomizeDialogAction - .BACKGROUNDS_UPLOAD_FROM_DEVICE_CLICKED); + .kBackgroundsUploadFromDeviceClicked); const {success} = await this.pageHandler_.chooseLocalCustomBackground(); if (success) { // The theme update is asynchronous. Close the dialog and allow ntp-app @@ -175,7 +175,7 @@ class CustomizeBackgroundsElement extends PolymerElement { BackgroundSelectionType.NO_BACKGROUND) { this.pageHandler_.onCustomizeDialogAction( newTabPage.mojom.CustomizeDialogAction - .BACKGROUNDS_NO_BACKGROUND_SELECTED); + .kBackgroundsNoBackgroundSelected); } this.backgroundSelection = {type: BackgroundSelectionType.NO_BACKGROUND}; } @@ -189,7 +189,7 @@ class CustomizeBackgroundsElement extends PolymerElement { if (this.backgroundSelection.type !== BackgroundSelectionType.IMAGE || this.backgroundSelection.image !== image) { this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.BACKGROUNDS_IMAGE_SELECTED); + newTabPage.mojom.CustomizeDialogAction.kBackgroundsImageSelected); } this.backgroundSelection = { type: BackgroundSelectionType.IMAGE, diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_dialog.html b/chromium/chrome/browser/resources/new_tab_page/customize_dialog.html index 231ac1f603c..143f56f1bdd 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_dialog.html +++ b/chromium/chrome/browser/resources/new_tab_page/customize_dialog.html @@ -15,10 +15,11 @@ div[slot=title] { align-items: center; - color: var(--ntp-primary-text-color); + color: var(--cr-primary-text-color); display: flex; flex-direction: row; - height: 58px; + height: 64px; + margin-top: 16px; padding: 0; } @@ -90,7 +91,7 @@ .menu-item { align-items: center; border-radius: 0 16px 16px 0; - color: var(--ntp-primary-text-color); + color: var(--cr-primary-text-color); cursor: pointer; display: flex; flex-direction: row; @@ -126,7 +127,7 @@ .menu-item-icon { -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100%; - background-color: var(--ntp-primary-text-color); + background-color: var(--cr-primary-text-color); height: 20px; margin-inline-end: 16px; margin-inline-start: 24px; @@ -150,7 +151,7 @@ } #backButton { - --cr-icon-button-fill-color: var(--ntp-primary-text-color); + --cr-icon-button-fill-color: var(--cr-primary-text-color); margin-inline-end: 4px; /* So that the arrow aligns with the grid. */ margin-inline-start: -12px; diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_dialog.js b/chromium/chrome/browser/resources/new_tab_page/customize_dialog.js index 8429868e232..f5fc6471819 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_dialog.js +++ b/chromium/chrome/browser/resources/new_tab_page/customize_dialog.js @@ -124,7 +124,7 @@ class CustomizeDialogElement extends PolymerElement { this.$.bottomPageScrollBorder, 'show-2'), ]; this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.OPEN_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kOpenClicked); } /** @private */ @@ -136,7 +136,7 @@ class CustomizeDialogElement extends PolymerElement { /** @private */ onCancelClick_() { this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.CANCEL_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kCancelClicked); this.$.dialog.cancel(); } @@ -168,7 +168,7 @@ class CustomizeDialogElement extends PolymerElement { assert(this.backgroundSelection.dailyRefreshCollectionId)); } this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.DONE_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kDoneClicked); this.$.dialog.close(); } @@ -221,7 +221,7 @@ class CustomizeDialogElement extends PolymerElement { onBackClick_() { this.selectedCollection_ = null; this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction.BACKGROUNDS_BACK_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kBackgroundsBackClicked); } /** @private */ @@ -236,7 +236,7 @@ class CustomizeDialogElement extends PolymerElement { } this.pageHandler_.onCustomizeDialogAction( newTabPage.mojom.CustomizeDialogAction - .BACKGROUNDS_REFRESH_TOGGLE_CLICKED); + .kBackgroundsRefreshToggleClicked); } } diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.html b/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.html index 1c414c9b89d..d3a645c9d9e 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.html +++ b/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.html @@ -43,7 +43,7 @@ width: 144px; } - html[dir=rtl] .option-mini { + :host-context([dir='rtl']) .option-mini { left: 40px; right: unset; } @@ -88,7 +88,7 @@ -webkit-mask-image: url(icons/generic_globe.svg); } - html[dir=rtl] .option-icon { + :host-context([dir='rtl']) .option-icon { right: 16px; } @@ -111,7 +111,7 @@ width: 22px; } - html[dir=rtl] .option-image .selected-circle { + :host-context([dir='rtl']) .option-image .selected-circle { left: 0; right: 209px; } @@ -122,7 +122,7 @@ top: 6px; } - html[dir=rtl] .option-image .selected-check { + :host-context([dir='rtl']) .option-image .selected-check { left: 32px; right: initial; } @@ -182,7 +182,7 @@ width: 22px; } - html[dir=rtl] .selected-circle { + :host-context([dir='rtl']) .selected-circle { left: auto; right: 66px; } @@ -202,7 +202,7 @@ display: block; } - html[dir=rtl] .selected-check { + :host-context([dir='rtl']) .selected-check { left: auto; right: 63px; } diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.js b/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.js index f442964666d..0e54ab45b8e 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.js +++ b/chromium/chrome/browser/resources/new_tab_page/customize_shortcuts.js @@ -112,8 +112,7 @@ class CustomizeShortcutsElement extends PolymerElement { onCustomLinksClick_() { if (!this.customLinksEnabled_) { this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction - .SHORTCUTS_CUSTOM_LINKS_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kShortcutsCustomLinksClicked); } this.customLinksEnabled_ = true; this.hide_ = false; @@ -126,7 +125,7 @@ class CustomizeShortcutsElement extends PolymerElement { onHideChange_(e) { this.pageHandler_.onCustomizeDialogAction( newTabPage.mojom.CustomizeDialogAction - .SHORTCUTS_VISIBILITY_TOGGLE_CLICKED); + .kShortcutsVisibilityToggleClicked); this.hide_ = e.detail; } @@ -135,8 +134,7 @@ class CustomizeShortcutsElement extends PolymerElement { onMostVisitedClick_() { if (this.customLinksEnabled_) { this.pageHandler_.onCustomizeDialogAction( - newTabPage.mojom.CustomizeDialogAction - .SHORTCUTS_MOST_VISITED_CLICKED); + newTabPage.mojom.CustomizeDialogAction.kShortcutsMostVisitedClicked); } this.customLinksEnabled_ = false; this.hide_ = false; diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_themes.html b/chromium/chrome/browser/resources/new_tab_page/customize_themes.html index 3fccbcba6b9..b8cd8134486 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_themes.html +++ b/chromium/chrome/browser/resources/new_tab_page/customize_themes.html @@ -6,9 +6,9 @@ #thirdPartyTheme { align-items: center; - border-radius: 5px; border: 1px solid var(--ntp-border-color); - color: var(--ntp-primary-text-color); + border-radius: 5px; + color: var(--cr-primary-text-color); display: flex; flex-direction: row; margin-bottom: 24px; @@ -19,7 +19,7 @@ -webkit-mask-image: url(icons/brush.svg); -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100%; - background-color: var(--ntp-primary-text-color); + background-color: var(--cr-primary-text-color); height: 24px; margin-inline-end: 20px; width: 24px; @@ -35,7 +35,7 @@ } #thirdPartyLink { - --cr-icon-button-fill-color: var(--ntp-primary-text-color); + --cr-icon-button-fill-color: var(--cr-primary-text-color); margin-inline-end: 24px; } @@ -44,7 +44,7 @@ } #themesContainer { - --ntp-grid-gap: 20px; + --cr-grid-gap: 20px; } #themesContainer > * { @@ -114,7 +114,7 @@ <input id="colorPicker" type="color" on-change="onCustomFrameColorChange_" hidden> </input> -<ntp-grid id="themesContainer" columns="6"> +<cr-grid id="themesContainer" columns="6"> <div id="autogeneratedThemeContainer" tabindex="0" on-click="onAutogeneratedThemeClick_"> <ntp-theme-icon id="autogeneratedTheme" title="$i18n{colorPickerLabel}" @@ -138,4 +138,4 @@ </ntp-theme-icon> </template> </dom-repeat> -</ntp-grid> +</cr-grid> diff --git a/chromium/chrome/browser/resources/new_tab_page/customize_themes.js b/chromium/chrome/browser/resources/new_tab_page/customize_themes.js index a6987bdedba..e09868ff78a 100644 --- a/chromium/chrome/browser/resources/new_tab_page/customize_themes.js +++ b/chromium/chrome/browser/resources/new_tab_page/customize_themes.js @@ -4,13 +4,13 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; -import './grid.js'; +import 'chrome://resources/cr_elements/cr_grid/cr_grid.js'; import './theme_icon.js'; +import {hexColorToSkColor, skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BrowserProxy} from './browser_proxy.js'; -import {hexColorToSkColor, skColorToRgba} from './utils.js'; /** Element that lets the user configure the theme. */ class CustomizeThemesElement extends PolymerElement { @@ -74,7 +74,7 @@ class CustomizeThemesElement extends PolymerElement { /** private */ onThemeChange_() { - if (this.theme.type !== newTabPage.mojom.ThemeType.AUTOGENERATED) { + if (this.theme.type !== newTabPage.mojom.ThemeType.kAutogenerated) { return; } const rgbaFrameColor = @@ -110,11 +110,11 @@ class CustomizeThemesElement extends PolymerElement { return false; } if (id === 'autogenerated') { - return this.theme.type === newTabPage.mojom.ThemeType.AUTOGENERATED; + return this.theme.type === newTabPage.mojom.ThemeType.kAutogenerated; } else if (id === 'default') { - return this.theme.type === newTabPage.mojom.ThemeType.DEFAULT; + return this.theme.type === newTabPage.mojom.ThemeType.kDefault; } else { - return this.theme.type === newTabPage.mojom.ThemeType.CHROME && + return this.theme.type === newTabPage.mojom.ThemeType.kChrome && id === this.theme.info.chromeThemeId; } } @@ -124,7 +124,7 @@ class CustomizeThemesElement extends PolymerElement { * @private */ isThirdPartyTheme_() { - return this.theme.type === newTabPage.mojom.ThemeType.THIRD_PARTY; + return this.theme.type === newTabPage.mojom.ThemeType.kThirdParty; } /** @private */ diff --git a/chromium/chrome/browser/resources/new_tab_page/doodle_share_dialog.js b/chromium/chrome/browser/resources/new_tab_page/doodle_share_dialog.js index e59bc37d06a..efb31ab9e71 100644 --- a/chromium/chrome/browser/resources/new_tab_page/doodle_share_dialog.js +++ b/chromium/chrome/browser/resources/new_tab_page/doodle_share_dialog.js @@ -49,7 +49,7 @@ class DoodleShareDialogElement extends PolymerElement { `&href=${encodeURIComponent(this.url.url)}` + `&hashtag=${encodeURIComponent('#GoogleDoodle')}`; BrowserProxy.getInstance().open(url); - this.notifyShare_(newTabPage.mojom.DoodleShareChannel.FACEBOOK); + this.notifyShare_(newTabPage.mojom.DoodleShareChannel.kFacebook); } /** @private */ @@ -57,7 +57,7 @@ class DoodleShareDialogElement extends PolymerElement { const url = 'https://twitter.com/intent/tweet' + `?text=${encodeURIComponent(`${this.title}\n${this.url.url}`)}`; BrowserProxy.getInstance().open(url); - this.notifyShare_(newTabPage.mojom.DoodleShareChannel.TWITTER); + this.notifyShare_(newTabPage.mojom.DoodleShareChannel.kTwitter); } /** @private */ @@ -65,14 +65,14 @@ class DoodleShareDialogElement extends PolymerElement { const url = `mailto:?subject=${encodeURIComponent(this.title)}` + `&body=${encodeURIComponent(this.url.url)}`; BrowserProxy.getInstance().navigate(url); - this.notifyShare_(newTabPage.mojom.DoodleShareChannel.EMAIL); + this.notifyShare_(newTabPage.mojom.DoodleShareChannel.kEmail); } /** @private */ onCopyClick_() { this.$.url.select(); navigator.clipboard.writeText(this.url.url); - this.notifyShare_(newTabPage.mojom.DoodleShareChannel.LINK_COPY); + this.notifyShare_(newTabPage.mojom.DoodleShareChannel.kLinkCopy); } /** @private */ diff --git a/chromium/chrome/browser/resources/new_tab_page/externs.js b/chromium/chrome/browser/resources/new_tab_page/externs.js deleted file mode 100644 index 126dbec4056..00000000000 --- a/chromium/chrome/browser/resources/new_tab_page/externs.js +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Externs for objects sent from C++ to JS for - * chrome://new-tab-page. - * @externs - */ - -// eslint-disable-next-line no-var -var newTabPage = {}; diff --git a/chromium/chrome/browser/resources/new_tab_page/fakebox.html b/chromium/chrome/browser/resources/new_tab_page/fakebox.html index 8603b202d88..d29e4fe4a90 100644 --- a/chromium/chrome/browser/resources/new_tab_page/fakebox.html +++ b/chromium/chrome/browser/resources/new_tab_page/fakebox.html @@ -6,19 +6,6 @@ box-shadow: 0 1px 6px 0 rgba(32, 33, 36, .28); height: var(--ntp-fakebox-height); position: relative; - width: 337px; - } - - @media (min-width: 560px) { - :host { - width: 449px; - } - } - - @media (min-width: 672px) { - :host { - width: 561px; - } } :host([hidden_]) { @@ -53,7 +40,7 @@ -webkit-mask-image: url(chrome://resources/images/icon_search.svg); -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100%; - background-color: var(--ntp-secondary-text-color); + background-color: var(--cr-secondary-text-color); height: 21px; width: 21px; } @@ -68,7 +55,7 @@ } #fakeCursor { - background-color: var(--ntp-secondary-text-color); + background-color: var(--cr-secondary-text-color); height: 1rem; margin-inline-start: 11px; visibility: hidden; @@ -85,7 +72,7 @@ } #hint { - color: var(--ntp-secondary-text-color); + color: var(--cr-secondary-text-color); flex-grow: 1; font-size: 1rem; margin-inline-start: 3px; diff --git a/chromium/chrome/browser/resources/new_tab_page/grid.html b/chromium/chrome/browser/resources/new_tab_page/grid.html deleted file mode 100644 index 92119115c0a..00000000000 --- a/chromium/chrome/browser/resources/new_tab_page/grid.html +++ /dev/null @@ -1,21 +0,0 @@ -<style> - :host { - --ntp-grid-gap: 0px; - } - - #grid { - display: grid; - grid-column-gap: var(--ntp-grid-gap); - grid-row-gap: var(--ntp-grid-gap); - grid-template-columns: repeat(var(--columns), auto); - width: fit-content; - } - - ::slotted(*) { - align-self: center; - justify-self: center; - } -</style> -<div id="grid" on-keydown="onKeyDown_" style="--columns: [[columns]];"> - <slot id="items"></slot> -</div> diff --git a/chromium/chrome/browser/resources/new_tab_page/grid.js b/chromium/chrome/browser/resources/new_tab_page/grid.js deleted file mode 100644 index 7d7aa357eb2..00000000000 --- a/chromium/chrome/browser/resources/new_tab_page/grid.js +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -// Displays children in a two-dimensional grid and supports focusing children -// with arrow keys. -class GridElement extends PolymerElement { - static get is() { - return 'ntp-grid'; - } - - static get template() { - return html`{__html_template__}`; - } - - static get properties() { - return { - /** @type {number} */ - columns: { - type: Number, - value: 1, - }, - }; - } - - /** - * @param {!Event} e - * @private - */ - onKeyDown_(e) { - if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(e.key)) { - e.preventDefault(); - const items = this.$.items.assignedElements().filter( - (el) => - (!!(el.offsetWidth || el.offsetHeight || - el.getClientRects().length))); - const currentIndex = items.indexOf(e.target); - const isRtl = window.getComputedStyle(this)['direction'] === 'rtl'; - const bottomRowColumns = items.length % this.columns; - const direction = ['ArrowRight', 'ArrowDown'].includes(e.key) ? 1 : -1; - const inEdgeRow = direction === 1 ? - currentIndex >= items.length - bottomRowColumns : - currentIndex < this.columns; - let delta = 0; - switch (e.key) { - case 'ArrowLeft': - case 'ArrowRight': - delta = direction * (isRtl ? -1 : 1); - break; - case 'ArrowUp': - case 'ArrowDown': - delta = direction * (inEdgeRow ? bottomRowColumns : this.columns); - break; - } - // Handle cases where we move to an empty space in a non-full bottom row - // and have to jump to the next row. - if (e.key === 'ArrowUp' && inEdgeRow && - currentIndex >= bottomRowColumns) { - delta -= this.columns; - } else if ( - e.key === 'ArrowDown' && !inEdgeRow && - currentIndex + delta >= items.length) { - delta += bottomRowColumns; - } - const mod = function(m, n) { - return ((m % n) + n) % n; - }; - const newIndex = mod(currentIndex + delta, items.length); - items[newIndex].focus(); - } - - if (['Enter', ' '].includes(e.key)) { - e.preventDefault(); - e.stopPropagation(); - e.target.click(); - } - } -} - -customElements.define(GridElement.is, GridElement); diff --git a/chromium/chrome/browser/resources/new_tab_page/iframe.html b/chromium/chrome/browser/resources/new_tab_page/iframe.html index 212f6d13acb..c73245901f4 100644 --- a/chromium/chrome/browser/resources/new_tab_page/iframe.html +++ b/chromium/chrome/browser/resources/new_tab_page/iframe.html @@ -1,12 +1,14 @@ <style> :host(:not([hidden])) { - display: inline-block; + display: block; } #iframe { border: none; border-radius: inherit; height: inherit; + max-height: inherit; + max-width: inherit; width: inherit; } </style> diff --git a/chromium/chrome/browser/resources/new_tab_page/logo.html b/chromium/chrome/browser/resources/new_tab_page/logo.html index f9f1fe7e008..ea4bdcbce84 100644 --- a/chromium/chrome/browser/resources/new_tab_page/logo.html +++ b/chromium/chrome/browser/resources/new_tab_page/logo.html @@ -1,40 +1,33 @@ <style include="cr-hidden-style"> :host { - --ntp-logo-height: 230px; - display: inline-block; + --ntp-logo-height: 200px; + display: flex; + flex-direction: column; flex-shrink: 0; + justify-content: flex-end; min-height: var(--ntp-logo-height); } - #singleColoredLogo, - #multiColoredLogo { + :host([doodle-boxed_]) { + justify-content: flex-end; + } + + #logo { height: 92px; - margin-top: 108px; width: 272px; } - #singleColoredLogo { + :host([single-colored]) #logo { -webkit-mask-image: url(chrome://resources/images/google_logo.svg); -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100%; background-color: var(--ntp-logo-color); } - #multiColoredLogo { + :host(:not([single-colored])) #logo { background-image: url(chrome://resources/images/google_logo.svg); } - #doodle { - display: flex; - flex-direction: column; - height: 100%; - justify-content: center; - } - - :host([doodle-boxed_]) #doodle { - justify-content: flex-end; - } - #imageDoodle { cursor: pointer; outline: none; @@ -43,7 +36,6 @@ :host([doodle-boxed_]) #imageDoodle { background-color: var(--ntp-logo-box-color); border-radius: 20px; - margin-bottom: 30px; padding: 16px 24px; } @@ -99,53 +91,50 @@ #iframe { border: none; - height: var(--height, --ntp-logo-height); + height: var(--height, var(--ntp-logo-height)); transition-duration: var(--duration, 100ms); transition-property: height, width; width: var(--width, 100%); } + + #iframe:not([expanded]) { + max-height: var(--ntp-logo-height); + } </style> -<dom-if if="[[showLogo_]]" restamp> - <template> - <div id="logo"> - <div id="singleColoredLogo" hidden="[[!singleColored]]"></div> - <div id="multiColoredLogo" hidden="[[singleColored]]"></div> - </div> - </template> -</dom-if> -<dom-if if="[[showDoodle_]]" restamp> - <template> - <div id="doodle" title="[[doodle_.description]]"> - <div id="imageDoodle" hidden="[[!imageDoodle_]]" - tabindex="0" on-click="onImageClick_" on-keydown="onImageKeydown_"> - <div id="imageContainer"> - <!-- The static image is always visible and the animated image is - stacked on top of the static image so that there is no flicker - when starting the animation. --> - <img id="image" src="[[imageUrl_]]" on-load="onImageLoad_"> + +<template is="dom-if" if="[[showLogo_]]" restamp> + <div id="logo"></div> +</template> +<template is="dom-if" if="[[showDoodle_]]" restamp> + <div id="doodle" title="[[doodle_.description]]"> + <div id="imageDoodle" hidden="[[!imageDoodle_]]" + tabindex="0" on-click="onImageClick_" on-keydown="onImageKeydown_"> + <div id="imageContainer"> + <!-- The static image is always visible and the animated image is + stacked on top of the static image so that there is no flicker + when starting the animation. --> + <img id="image" src="[[imageUrl_]]" on-load="onImageLoad_"></img> + <ntp-iframe id="animation" src="[[animationUrl_]]" + hidden="[[!showAnimation_]]"> + </ntp-iframe> + <cr-button id="shareButton" title="$i18n{shareDoodle}" + on-click="onShareButtonClick_" + hidden="[[!imageDoodle_.shareButton]]"> + <img id="shareButtonImage" + src="[[imageDoodle_.shareButton.iconUrl.url]]"> </img> - <ntp-iframe id="animation" src="[[animationUrl_]]" - hidden="[[!showAnimation_]]"> - </ntp-iframe> - <cr-button id="shareButton" title="$i18n{shareDoodle}" - on-click="onShareButtonClick_"> - <img id="shareButtonImage" - src="[[imageDoodle_.shareButton.iconUrl.url]]"> - </img> - </cr-button> - </div> + </cr-button> </div> - <template is="dom-if" if="[[iframeUrl_]]" restamp> - <ntp-iframe id="iframe" src="[[iframeUrl_]]"></ntp-iframe> - </template> </div> - </template> -</dom-if> -<dom-if if="[[showShareDialog_]]" restamp> - <template> - <ntp-doodle-share-dialog title="[[doodle_.description]]" - url="[[doodle_.content.imageDoodle.shareUrl]]" - on-close="onShareDialogClose_" on-share="onShare_"> - </ntp-doodle-share-dialog> - </template> -</dom-if> + <template is="dom-if" if="[[iframeUrl_]]" restamp> + <ntp-iframe id="iframe" src="[[iframeUrl_]]" expanded$="[[expanded_]]"> + </ntp-iframe> + </template> + </div> +</template> +<template is="dom-if" if="[[showShareDialog_]]" restamp> + <ntp-doodle-share-dialog title="[[doodle_.description]]" + url="[[doodle_.image.shareUrl]]" + on-close="onShareDialogClose_" on-share="onShare_"> + </ntp-doodle-share-dialog> +</template> diff --git a/chromium/chrome/browser/resources/new_tab_page/logo.js b/chromium/chrome/browser/resources/new_tab_page/logo.js index 78987000940..9adb68cf226 100644 --- a/chromium/chrome/browser/resources/new_tab_page/logo.js +++ b/chromium/chrome/browser/resources/new_tab_page/logo.js @@ -8,12 +8,13 @@ import './iframe.js'; import './doodle_share_dialog.js'; import {assert} from 'chrome://resources/js/assert.m.js'; +import {skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BrowserProxy} from './browser_proxy.js'; -import {$$, skColorToRgba} from './utils.js'; +import {$$} from './utils.js'; /** @type {number} */ const SHARE_BUTTON_SIZE_PX = 26; @@ -147,6 +148,9 @@ class LogoElement extends PolymerElement { }, /** @private */ + expanded_: Boolean, + + /** @private */ showShareDialog_: Boolean, }; } @@ -161,9 +165,9 @@ class LogoElement extends PolymerElement { this.pageHandler_.getDoodle().then(({doodle}) => { this.doodle_ = doodle; this.loaded_ = true; - if (this.doodle_ && this.doodle_.content.interactiveDoodle) { - this.width_ = `${this.doodle_.content.interactiveDoodle.width}px`; - this.height_ = `${this.doodle_.content.interactiveDoodle.height}px`; + if (this.doodle_ && this.doodle_.interactive) { + this.width_ = `${this.doodle_.interactive.width}px`; + this.height_ = `${this.doodle_.interactive.height}px`; } }); /** @private {?string} */ @@ -182,6 +186,7 @@ class LogoElement extends PolymerElement { this.duration_ = assert(data.duration); this.height_ = assert(data.height); this.width_ = assert(data.width); + this.expanded_ = true; } else if (data['cmd'] === 'sendMode') { this.sendMode_(); } @@ -204,8 +209,8 @@ class LogoElement extends PolymerElement { /** @private */ onImageDoodleChange_() { - if (this.imageDoodle_) { - const shareButton = this.imageDoodle_.shareButton; + const shareButton = this.imageDoodle_ && this.imageDoodle_.shareButton; + if (shareButton) { const height = this.imageDoodle_.height; const width = this.imageDoodle_.width; this.updateStyles({ @@ -217,8 +222,6 @@ class LogoElement extends PolymerElement { `${SHARE_BUTTON_SIZE_PX / width * 100}%`, '--ntp-logo-share-button-x': `${shareButton.x / width * 100}%`, '--ntp-logo-share-button-y': `${shareButton.y / height * 100}%`, - '--ntp-logo-box-color': - skColorToRgba(this.imageDoodle_.backgroundColor), }); } else { this.updateStyles({ @@ -227,6 +230,15 @@ class LogoElement extends PolymerElement { '--ntp-logo-share-button-width': null, '--ntp-logo-share-button-x': null, '--ntp-logo-share-button-y': null, + }); + } + if (this.imageDoodle_) { + this.updateStyles({ + '--ntp-logo-box-color': + skColorToRgba(this.imageDoodle_.backgroundColor), + }); + } else { + this.updateStyles({ '--ntp-logo-box-color': null, }); } @@ -243,9 +255,8 @@ class LogoElement extends PolymerElement { * @private */ computeImageDoodle_() { - return this.doodle_ && this.doodle_.content.imageDoodle && - (this.dark ? this.doodle_.content.imageDoodle.dark : - this.doodle_.content.imageDoodle.light) || + return this.doodle_ && this.doodle_.image && + (this.dark ? this.doodle_.image.dark : this.doodle_.image.light) || null; } @@ -257,8 +268,7 @@ class LogoElement extends PolymerElement { return !!this.imageDoodle_ || /* We hide interactive doodles when offline. Otherwise, the iframe would show an ugly error page. */ - !!this.doodle_ && !!this.doodle_.content.interactiveDoodle && - window.navigator.onLine; + !!this.doodle_ && !!this.doodle_.interactive && window.navigator.onLine; } /** @@ -297,7 +307,7 @@ class LogoElement extends PolymerElement { if (this.isCtaImageShown_()) { this.showAnimation_ = true; this.pageHandler_.onDoodleImageClicked( - newTabPage.mojom.DoodleImageType.CTA, this.interactionLogUrl_); + newTabPage.mojom.DoodleImageType.kCta, this.interactionLogUrl_); // TODO(tiborg): This is technically not correct since we don't know if // the animation has loaded yet. However, since the animation is loaded @@ -305,17 +315,17 @@ class LogoElement extends PolymerElement { // practice this should be good enough but we could improve that in the // future. this.logImageRendered_( - newTabPage.mojom.DoodleImageType.ANIMATION, + newTabPage.mojom.DoodleImageType.kAnimation, /** @type {!url.mojom.Url} */ (this.imageDoodle_.animationImpressionLogUrl)); return; } this.pageHandler_.onDoodleImageClicked( - this.showAnimation_ ? newTabPage.mojom.DoodleImageType.ANIMATION : - newTabPage.mojom.DoodleImageType.STATIC, + this.showAnimation_ ? newTabPage.mojom.DoodleImageType.kAnimation : + newTabPage.mojom.DoodleImageType.kStatic, null); - const onClickUrl = new URL(this.doodle_.content.imageDoodle.onClickUrl.url); + const onClickUrl = new URL(this.doodle_.image.onClickUrl.url); if (this.imageClickParams_) { for (const param of new URLSearchParams(this.imageClickParams_)) { onClickUrl.searchParams.append(param[0], param[1]); @@ -327,8 +337,8 @@ class LogoElement extends PolymerElement { /** @private */ onImageLoad_() { this.logImageRendered_( - this.isCtaImageShown_() ? newTabPage.mojom.DoodleImageType.CTA : - newTabPage.mojom.DoodleImageType.STATIC, + this.isCtaImageShown_() ? newTabPage.mojom.DoodleImageType.kCta : + newTabPage.mojom.DoodleImageType.kStatic, this.imageDoodle_.imageImpressionLogUrl); } @@ -361,8 +371,8 @@ class LogoElement extends PolymerElement { * @private */ onShare_(e) { - const doodleId = new URL(this.doodle_.content.imageDoodle.onClickUrl.url) - .searchParams.get('ct'); + const doodleId = + new URL(this.doodle_.image.onClickUrl.url).searchParams.get('ct'); if (!doodleId) { return; } @@ -421,8 +431,8 @@ class LogoElement extends PolymerElement { * @private */ computeIframeUrl_() { - if (this.doodle_ && this.doodle_.content.interactiveDoodle) { - const url = new URL(this.doodle_.content.interactiveDoodle.url.url); + if (this.doodle_ && this.doodle_.interactive) { + const url = new URL(this.doodle_.interactive.url.url); if (loadTimeData.getBoolean('themeModeDoodlesEnabled')) { url.searchParams.append('theme_messages', '0'); } diff --git a/chromium/chrome/browser/resources/new_tab_page/module_wrapper.html b/chromium/chrome/browser/resources/new_tab_page/module_wrapper.html new file mode 100644 index 00000000000..aa8249e1a09 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/module_wrapper.html @@ -0,0 +1,32 @@ +<style> + :host { + background-color: var(--ntp-background-override-color); + border: solid var(--ntp-border-color) 1px; + border-radius: 5px; + } + + #header { + margin: 10px; + } + + #title { + color: var(--cr-primary-text-color); + } + + #name { + color: var(--cr-secondary-text-color); + } + + #moduleElement { + align-items: center; + display: flex; + height: 150px; + justify-content: center; + overflow: hidden; + } +</style> +<div id="header"> + <span id="title">[[descriptor.title]]</span> + <span id="name"> • [[descriptor.name]]</span> +</div> +<div id="moduleElement"></div> diff --git a/chromium/chrome/browser/resources/new_tab_page/module_wrapper.js b/chromium/chrome/browser/resources/new_tab_page/module_wrapper.js new file mode 100644 index 00000000000..894efafe3b0 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/module_wrapper.js @@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ModuleDescriptor} from './modules/module_descriptor.js'; + +/** @fileoverview Element that implements the common module UI. */ + +class ModuleWrapperElement extends PolymerElement { + static get is() { + return 'ntp-module-wrapper'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** @type {!ModuleDescriptor} */ + descriptor: { + observer: 'onDescriptorChange_', + type: Object, + }, + }; + } + + /** @private */ + onDescriptorChange_() { + this.$.moduleElement.innerHTML = ''; + this.$.moduleElement.appendChild(this.descriptor.element); + } +} + +customElements.define(ModuleWrapperElement.is, ModuleWrapperElement); diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/dummy/BUILD.gn b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/BUILD.gn new file mode 100644 index 00000000000..b20d7fb51d4 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_library("module") { + deps = [ + "../..:module_descriptor", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_grid", + ] +} + +html_to_js("web_components") { + js_files = [ "module.js" ] +} diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.html b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.html new file mode 100644 index 00000000000..7d79bb63a93 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.html @@ -0,0 +1,20 @@ +<style> +.tile-item { + background-color: var(--ntp-active-background-color); + border-color: var(--ntp-border-color); + border-radius: 8px; + border-style: solid; + border-width: thin; + color: var(--cr-primary-text-color); + height: 85px; + line-height: 85px; + margin: 10px; + text-align: center; + width: 170px; + } +</style> +<cr-grid id="tiles" columns="3"> + <template id="tileList" is="dom-repeat" items="[[tiles]]"> + <div class="tile-item" title="[[item.label]]">[[item.value]]</div> + </template> +</cr-grid> diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.js b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.js new file mode 100644 index 00000000000..44165519302 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/dummy/module.js @@ -0,0 +1,55 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_grid/cr_grid.js'; + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {ModuleDescriptor} from '../module_descriptor.js'; + +/** + * @fileoverview A dummy module, which serves as an example and a helper to + * build out the NTP module framework. + */ + +class DummyModuleElement extends PolymerElement { + static get is() { + return 'ntp-dummy-module'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + tiles: { + type: Array, + value: () => ([ + {label: 'item1', value: 'foo'}, + {label: 'item2', value: 'bar'}, + {label: 'item3', value: 'baz'}, + ]), + } + }; + } +} + +customElements.define(DummyModuleElement.is, DummyModuleElement); + +/** @type {!ModuleDescriptor} */ +export const dummyDescriptor = new ModuleDescriptor( + 'dummy', loadTimeData.getString('modulesDummyName'), () => Promise.resolve({ + element: new DummyModuleElement(), + title: loadTimeData.getString('modulesDummyTitle'), + })); + +/** @type {!ModuleDescriptor} */ +export const dummyDescriptor2 = new ModuleDescriptor( + 'dummy2', loadTimeData.getString('modulesDummy2Name'), + () => Promise.resolve({ + element: new DummyModuleElement(), + title: loadTimeData.getString('modulesDummy2Title'), + })); diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/BUILD.gn b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/BUILD.gn new file mode 100644 index 00000000000..67fb3b3e63b --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/BUILD.gn @@ -0,0 +1,5 @@ +import("//third_party/closure_compiler/compile_js.gni") + +js_library("module") { + deps = [ "//chrome/browser/resources/new_tab_page:module_descriptor" ] +} diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/OWNERS b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/OWNERS new file mode 100644 index 00000000000..d91fac218e9 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/OWNERS @@ -0,0 +1,3 @@ +file://chrome/browser/media/kaleidoscope/OWNERS + +# COMPONENT: Internals>Media>UI>Kaleidoscope diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/module.js b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/module.js new file mode 100644 index 00000000000..669b542a0d7 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/kaleidoscope/module.js @@ -0,0 +1,72 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; +import 'chrome://resources/mojo/url/mojom/origin.mojom-lite.js'; + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {ModuleDescriptor} from '../module_descriptor.js'; + +/** + * @typedef {{ + * url: (string), + * module: (?boolean) + * }} + */ +const Resource = {}; + +/** + * TODO(beccahughes): use import for these. + * @type {Array<Resource>} + */ +const KALEIDOSCOPE_RESOURCES = [ + {url: 'chrome://kaleidoscope/geometry.mojom-lite.js'}, + { + url: + 'chrome://kaleidoscope/chrome/browser/media/feeds/media_feeds_store.mojom-lite.js' + }, + {url: 'chrome://kaleidoscope/kaleidoscope.mojom-lite.js'}, + {url: 'chrome://kaleidoscope/messages.js'}, + {url: 'chrome://kaleidoscope/kaleidoscope.js'}, + {url: 'chrome://kaleidoscope/content.js'}, + {url: 'chrome://kaleidoscope/resources/_locales/strings.js'}, + {url: 'chrome://kaleidoscope/module.js', module: true}, +]; + +/** + * Loads a script resource and returns a promise that will resolve when the + * loading is complete. + * @param {Resource} resource + * @returns {Promise} + */ +function loadResource(resource) { + return new Promise((resolve) => { + const script = document.createElement('script'); + + if (resource.module) { + script.type = 'module'; + } + + script.src = resource.url; + script.addEventListener('load', resolve, {once: true}); + document.body.appendChild(script); + }); +} + +/** @type {!ModuleDescriptor} */ +export const kaleidoscopeDescriptor = new ModuleDescriptor( + 'kaleidoscope', + loadTimeData.getString('modulesKaleidoscopeName'), + () => { + // Load all the Kaleidoscope resources into the NTP and return the module + // once the loading is complete. + return Promise.all(KALEIDOSCOPE_RESOURCES.map((r) => loadResource(r))) + .then(() => { + return { + element: document.createElement('ntp-kaleidoscope-module'), + title: loadTimeData.getString('modulesKaleidoscopeTitle'), + }; + }); + }, +); diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/module_descriptor.js b/chromium/chrome/browser/resources/new_tab_page/modules/module_descriptor.js new file mode 100644 index 00000000000..169f19f74b2 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/module_descriptor.js @@ -0,0 +1,56 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Provides the module descriptor. Each module must create a + * module descriptor and register it at the NTP. + */ + +/** + * @typedef {function(): !Promise<?{ + * element: !HTMLElement, + * title: string, + * }>} + */ +let InitializeModuleCallback; + +export class ModuleDescriptor { + /** + * @param {string} id + * @param {string} name + * @param {!InitializeModuleCallback} initializeCallback + */ + constructor(id, name, initializeCallback) { + this.id_ = id; + this.name_ = name; + this.title_ = null; + this.element_ = null; + this.initializeCallback_ = initializeCallback; + } + + get id() { + return this.id_; + } + + get name() { + return this.name_; + } + + get title() { + return this.title_; + } + + get element() { + return this.element_; + } + + async initialize() { + const info = await this.initializeCallback_(); + if (!info) { + return; + } + this.title_ = info.title; + this.element_ = info.element; + } +} diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/module_registry.js b/chromium/chrome/browser/resources/new_tab_page/modules/module_registry.js new file mode 100644 index 00000000000..7d85d5929be --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/module_registry.js @@ -0,0 +1,40 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + +import {ModuleDescriptor} from './module_descriptor.js'; + +/** + * @fileoverview The module registry holds the descriptors of NTP modules and + * provides management function such as instantiating the local module UIs. + */ + +export class ModuleRegistry { + constructor() { + /** @private {!Array<!ModuleDescriptor>} */ + this.descriptors_ = []; + } + + /** + * Registers modules via their descriptors. + * @param {!Array<!ModuleDescriptor>} descriptors + */ + registerModules(descriptors) { + /** @type {!Array<!ModuleDescriptor>} */ + this.descriptors_ = descriptors; + } + + /** + * Initializes the modules previously set via |registerModules| and returns + * the initialized descriptors. + * @return {!Promise<!Array<!ModuleDescriptor>>} + */ + async initializeModules() { + await Promise.all(this.descriptors_.map(d => d.initialize())); + return this.descriptors_.filter(descriptor => !!descriptor.element); + } +} + +addSingletonGetter(ModuleRegistry); diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/modules.js b/chromium/chrome/browser/resources/new_tab_page/modules/modules.js new file mode 100644 index 00000000000..01fa392fd99 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/modules.js @@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Registers all NTP modules given their respective descriptors. + */ + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; + +import {dummyDescriptor, dummyDescriptor2} from './dummy/module.js'; +import {kaleidoscopeDescriptor} from './kaleidoscope/module.js'; +import {ModuleDescriptor} from './module_descriptor.js'; +import {ModuleRegistry} from './module_registry.js'; + +/** @type {!Array<!ModuleDescriptor>} */ +const descriptors = [dummyDescriptor, dummyDescriptor2]; + +if (loadTimeData.getBoolean('kaleidoscopeModuleEnabled')) { + descriptors.push(kaleidoscopeDescriptor); +} + +ModuleRegistry.getInstance().registerModules(descriptors); diff --git a/chromium/chrome/browser/resources/new_tab_page/modules/modules_resources.grdp b/chromium/chrome/browser/resources/new_tab_page/modules/modules_resources.grdp new file mode 100644 index 00000000000..67c4e16cc89 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/modules/modules_resources.grdp @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit-part> + <include name="IDR_NEW_TAB_PAGE_MODULES_DUMMY_MODULE_JS" + file="${root_gen_dir}/chrome/browser/resources/new_tab_page/modules/dummy/module.js" + use_base_dir="false" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_MODULES_KALEIDOSCOPE_MODULE_JS" + file="modules/kaleidoscope/module.js" + type="BINDATA" compress="false" /> +</grit-part> diff --git a/chromium/chrome/browser/resources/new_tab_page/most_visited.html b/chromium/chrome/browser/resources/new_tab_page/most_visited.html index 0b16023d29a..3777af018d0 100644 --- a/chromium/chrome/browser/resources/new_tab_page/most_visited.html +++ b/chromium/chrome/browser/resources/new_tab_page/most_visited.html @@ -237,7 +237,7 @@ </div> <cr-toast id="toast" duration="10000"> <div>[[toastContent_]]</div> - <dom-if if="showToastButtons_"> + <dom-if if="[[showToastButtons_]]"> <template> <cr-button id="undo" aria-label="$i18n{undoDescription}" on-click="onUndoClick_"> diff --git a/chromium/chrome/browser/resources/new_tab_page/most_visited.js b/chromium/chrome/browser/resources/new_tab_page/most_visited.js index 92b0f5ae097..182e9e92a5c 100644 --- a/chromium/chrome/browser/resources/new_tab_page/most_visited.js +++ b/chromium/chrome/browser/resources/new_tab_page/most_visited.js @@ -113,7 +113,10 @@ class MostVisitedElement extends PolymerElement { dialogTileTitle_: String, /** @private */ - dialogTileUrl_: String, + dialogTileUrl_: { + type: String, + observer: 'onDialogTileUrlChange_', + }, /** @private */ dialogTileUrlInvalid_: { @@ -540,6 +543,11 @@ class MostVisitedElement extends PolymerElement { this.adding_ = false; } + /** @private */ + onDialogTileUrlChange_() { + this.dialogTileUrlInvalid_ = false; + } + /** * @param {!KeyboardEvent} e * @private diff --git a/chromium/chrome/browser/resources/new_tab_page/new_tab_page.js b/chromium/chrome/browser/resources/new_tab_page/new_tab_page.js index e4639f76b5d..c4e1a13157b 100644 --- a/chromium/chrome/browser/resources/new_tab_page/new_tab_page.js +++ b/chromium/chrome/browser/resources/new_tab_page/new_tab_page.js @@ -15,5 +15,9 @@ import './app.js'; export {BackgroundManager} from './background_manager.js'; export {BrowserProxy} from './browser_proxy.js'; export {BackgroundSelectionType} from './customize_dialog.js'; -export {NO_SUGGESTION_GROUP_ID} from './realbox_dropdown.js'; -export {$$, createScrollBorders, decodeString16, hexColorToSkColor, mojoString16, skColorToRgba} from './utils.js'; +export {dummyDescriptor} from './modules/dummy/module.js'; +export {kaleidoscopeDescriptor} from './modules/kaleidoscope/module.js'; +export {ModuleDescriptor} from './modules/module_descriptor.js'; +export {ModuleRegistry} from './modules/module_registry.js'; +export {PromoBrowserCommandProxy} from './promo_browser_command_proxy.js'; +export {$$, createScrollBorders, decodeString16, mojoString16} from './utils.js'; diff --git a/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources.grd b/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources.grd index ac16ff94bcf..871c434711b 100644 --- a/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources.grd +++ b/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources.grd @@ -39,9 +39,6 @@ <include name="IDR_NEW_TAB_PAGE_THEME_ICON_JS" file="${root_gen_dir}/chrome/browser/resources/new_tab_page/theme_icon.js" use_base_dir="false" type="BINDATA" compress="false" /> - <include name="IDR_NEW_TAB_PAGE_GRID_JS" - file="${root_gen_dir}/chrome/browser/resources/new_tab_page/grid.js" - use_base_dir="false" type="BINDATA" compress="false" /> <include name="IDR_NEW_TAB_IFRAME_JS" file="${root_gen_dir}/chrome/browser/resources/new_tab_page/iframe.js" use_base_dir="false" type="BINDATA" compress="false" /> @@ -72,13 +69,23 @@ <include name="IDR_NEW_TAB_PAGE_REALBOX_MATCH_JS" file="${root_gen_dir}/chrome/browser/resources/new_tab_page/realbox_match.js" use_base_dir="false" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_MODULE_WRAPPER_JS" + file="${root_gen_dir}/chrome/browser/resources/new_tab_page/module_wrapper.js" + use_base_dir="false" type="BINDATA" compress="false" /> <include name="IDR_NEW_TAB_PAGE_BROWSER_PROXY_JS" file="browser_proxy.js" type="BINDATA" compress="false" /> <include name="IDR_NEW_TAB_PAGE_UTILS_JS" file="utils.js" type="BINDATA" compress="false" /> <include name="IDR_NEW_TAB_PAGE_BACKGROUND_MANAGER_JS" file="background_manager.js" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_MODULES_MODULE_DESCRIPTOR_JS" + file="modules/module_descriptor.js" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_MODULES_MODULES_JS" + file="modules/modules.js" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_MODULES_MODULE_REGISTRY_JS" + file="modules/module_registry.js" type="BINDATA" compress="false" /> <part file="new_tab_page_resources_common.grdp" /> + <part file="modules/modules_resources.grdp" /> </includes> </release> </grit> diff --git a/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources_common.grdp b/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources_common.grdp index 13fbac2c00f..8d0effd3b45 100644 --- a/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources_common.grdp +++ b/chromium/chrome/browser/resources/new_tab_page/new_tab_page_resources_common.grdp @@ -6,6 +6,9 @@ <include name="IDR_NEW_TAB_PAGE_OMNIBOX_MOJO_LITE_JS" file="${root_gen_dir}/chrome/common/search/omnibox.mojom-lite.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_NEW_TAB_PAGE_PROMO_BROWSER_COMMAND_MOJO_LITE_JS" + file="${root_gen_dir}/chrome/browser/promo_browser_command/promo_browser_command.mojom-lite.js" + use_base_dir="false" type="BINDATA" /> <include name="IDR_NEW_TAB_PAGE_ACCOUNT_CIRCLE_SVG" file="icons/account_circle.svg" type="BINDATA" /> <include name="IDR_NEW_TAB_PAGE_BRUSH_ICON_SVG" @@ -62,4 +65,8 @@ file="untrusted/background_image.html" type="BINDATA" /> <include name="IDR_NEW_TAB_PAGE_UNTRUSTED_BACKGROUND_IMAGE_JS" file="untrusted/background_image.js" type="BINDATA" /> + <include name="IDR_NEW_TAB_PAGE_ONE_GOOGLE_BAR_API_JS" + file="one_google_bar_api.js" type="BINDATA" compress="false" /> + <include name="IDR_NEW_TAB_PAGE_PROMO_BROWSER_COMMAND_PROXY_JS" + file="promo_browser_command_proxy.js" type="BINDATA" compress="false" /> </grit-part> diff --git a/chromium/chrome/browser/resources/new_tab_page/one_google_bar_api.js b/chromium/chrome/browser/resources/new_tab_page/one_google_bar_api.js new file mode 100644 index 00000000000..8e902211294 --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/one_google_bar_api.js @@ -0,0 +1,92 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview This file provides a way to update the OneGoogleBar by using + * the underlying API exposed by the OneGoogleBar. + */ + +/** + * @param {string} apiName + * @param {string} fnName + * @param {...*} args + * @return {!Promise} + */ +const callApi = async (apiName, fnName, ...args) => { + const {gbar} = /** @type {!{gbar}} */ (window); + if (!gbar) { + return; + } + const api = await gbar.a[apiName](); + return api[fnName].apply(api, args); +}; + +/** + * @type {!{ + * bar: !{ + * setForegroundStyle: function(number): !Promise, + * setBackgroundColor: function(string): !Promise, + * setDarkMode: function(boolean): !Promise, + * }, + * }} + */ +const api = [{ + name: 'bar', + apiName: 'bf', + fns: [ + ['setForegroundStyle', 'pc'], + ['setBackgroundColor', 'pd'], + ['setDarkMode', 'pp'], + ], + }].reduce((topLevelApi, def) => { + topLevelApi[def.name] = def.fns.reduce((apiPart, [name, fnName]) => { + apiPart[name] = callApi.bind(null, def.apiName, fnName); + return apiPart; + }, {}); + return topLevelApi; +}, {}); + +/** @return {!Promise} */ +const updateDarkMode = async () => { + await api.bar.setDarkMode( + window.matchMedia('(prefers-color-scheme: dark)').matches); + // |setDarkMode(toggle)| updates the background color and foreground style. + // The background color should always be 'transparent'. + api.bar.setBackgroundColor('transparent'); + // The foreground style is set based on NTP theme and not dark mode. + api.bar.setForegroundStyle(foregroundLight ? 1 : 0); +}; + +/** @type {boolean} */ +let foregroundLight = false; + +export const oneGoogleBarApi = { + /** + * Returns the last argument value passed into |setForegroundLight(enabled)|. + * @return {boolean} + */ + isForegroundLight: () => foregroundLight, + + /** + * Updates the foreground on the OneGoogleBar to provide contrast against the + * background. + * @param {boolean} enabled + */ + setForegroundLight: enabled => { + foregroundLight = enabled; + api.bar.setForegroundStyle(foregroundLight ? 1 : 0); + }, + + /** + * Updates the OneGoogleBar dark mode when called as well as any time dark + * mode is updated. + * @type {!function()} + */ + trackDarkModeChanges: () => { + window.matchMedia('(prefers-color-scheme: dark)').addListener(() => { + updateDarkMode(); + }); + updateDarkMode(); + }, +}; diff --git a/chromium/chrome/browser/resources/new_tab_page/promo_browser_command_proxy.js b/chromium/chrome/browser/resources/new_tab_page/promo_browser_command_proxy.js new file mode 100644 index 00000000000..2abad05a86c --- /dev/null +++ b/chromium/chrome/browser/resources/new_tab_page/promo_browser_command_proxy.js @@ -0,0 +1,22 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './promo_browser_command.mojom-lite.js'; + +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + +/** + * @fileoverview This file provides a class that exposes the Mojo handler + * interface used for sending the NTP promos browser commands to the browser and + * receiving the browser response. + */ + +export class PromoBrowserCommandProxy { + constructor() { + /** @type {!promoBrowserCommand.mojom.CommandHandlerRemote} */ + this.handler = promoBrowserCommand.mojom.CommandHandler.getRemote(); + } +} + +addSingletonGetter(PromoBrowserCommandProxy); diff --git a/chromium/chrome/browser/resources/new_tab_page/realbox.html b/chromium/chrome/browser/resources/new_tab_page/realbox.html index cd67dd14290..29a73fa0aec 100644 --- a/chromium/chrome/browser/resources/new_tab_page/realbox.html +++ b/chromium/chrome/browser/resources/new_tab_page/realbox.html @@ -4,25 +4,12 @@ border-radius: calc(0.5 * var(--ntp-realbox-height)); box-shadow: 0 1px 6px 0 rgba(32, 33, 36, .28); height: var(--ntp-realbox-height); - width: 337px; } :host([matches-are-visible]) { box-shadow: none; } - @media (min-width: 560px) { - :host { - width: 449px; - } - } - - @media (min-width: 672px) { - :host { - width: 561px; - } - } - #inputWrapper { height: 100%; position: relative; @@ -30,8 +17,8 @@ input { background-color: var(--search-box-bg, white); - border-radius: calc(0.5 * var(--ntp-realbox-height)); border: none; + border-radius: calc(0.5 * var(--ntp-realbox-height)); color: var(--search-box-text); font-size: 16px; height: 100%; diff --git a/chromium/chrome/browser/resources/new_tab_page/realbox.js b/chromium/chrome/browser/resources/new_tab_page/realbox.js index aa9fc080dd0..b610dc49f72 100644 --- a/chromium/chrome/browser/resources/new_tab_page/realbox.js +++ b/chromium/chrome/browser/resources/new_tab_page/realbox.js @@ -7,11 +7,12 @@ import './realbox_dropdown.js'; import './realbox_icon.js'; import {assert} from 'chrome://resources/js/assert.m.js'; +import {skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BrowserProxy} from './browser_proxy.js'; -import {decodeString16, mojoString16, mojoTimeDelta, skColorToRgba} from './utils.js'; +import {decodeString16, mojoString16, mojoTimeDelta} from './utils.js'; /** @typedef {{text: string, inline: string,}} */ let Input; diff --git a/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.html b/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.html index 6c088c96d3a..e963cb22406 100644 --- a/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.html +++ b/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.html @@ -23,7 +23,6 @@ .header { align-items: center; display: flex; - justify-content: space-between; margin-top: 8px; outline: none; padding-bottom: 6px; @@ -33,7 +32,7 @@ } .header .text { - color: var(--google-grey-refresh-700); + color: var(--search-box-results-dim, var(--google-grey-refresh-700)); cursor: default; font-size: 14px; font-weight: 500; @@ -64,14 +63,15 @@ <template is="dom-if" if="[[groupHasHeader_(groupId)]]"> <!-- Header cannot be tabbed into but gets focus when clicked. This stops the dropdown from losing focus and closing as a result. --> - <div class="header" tabindex="-1" on-focusin="onHeaderFocusin_" + <div class="header" data-id$="[[groupId]]" tabindex="-1" + on-focusin="onHeaderFocusin_" on-click="onHeaderClick_" aria-hidden="true" group-is-hidden$="[[groupIsHidden_(groupId, hiddenGroupIds_.*)]]"> <span class="text">[[headerForGroup_(groupId)]]</span> - <ntp-realbox-button data-id$="[[groupId]]" tabindex="0" role="button" + <ntp-realbox-button tabindex="0" role="button" title="[[toggleButtonTitleForGroup_(groupId, hiddenGroupIds_.*)]]" aria-label$="[[toggleButtonA11yLabelForGroup_(groupId, hiddenGroupIds_.*)]]" - on-click="onToggleButtonClick_" on-keydown="onToggleButtonKeydown_"> + on-keydown="onToggleButtonKeydown_"> </ntp-realbox-button> </div> </template> diff --git a/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.js b/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.js index 7d7ab9e272f..3c7f09fab22 100644 --- a/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.js +++ b/chromium/chrome/browser/resources/new_tab_page/realbox_dropdown.js @@ -7,18 +7,12 @@ import './realbox_button.js'; import './realbox_match.js'; import {assert} from 'chrome://resources/js/assert.m.js'; +import {skColorToRgba} from 'chrome://resources/js/color_utils.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BrowserProxy} from './browser_proxy.js'; -import {decodeString16, skColorToRgba} from './utils.js'; - -/** - * Indicates a missing suggestion group Id. Based on - * SearchSuggestionParser::kNoSuggestionGroupId. - * @type {string} - */ -export const NO_SUGGESTION_GROUP_ID = '-1'; +import {decodeString16} from './utils.js'; // A dropdown element that contains autocomplete matches. Provides an API for // the embedder (i.e., <ntp-realbox>) to change the selection. @@ -68,7 +62,7 @@ class RealboxDropdownElement extends PolymerElement { /** * The list of suggestion group IDs matches belong to. - * @type {!Array<string>} + * @type {!Array<number>} * @private */ groupIds_: { @@ -78,7 +72,7 @@ class RealboxDropdownElement extends PolymerElement { /** * The list of suggestion group IDs whose matches should be hidden. - * @type {!Array<string>} + * @type {!Array<number>} * @private */ hiddenGroupIds_: { @@ -285,8 +279,8 @@ class RealboxDropdownElement extends PolymerElement { * @param {!Event} e * @private */ - onToggleButtonClick_(e) { - const groupId = e.target.dataset.id; + onHeaderClick_(e) { + const groupId = Number(e.currentTarget.dataset.id); // Tell the backend to toggle visibility of the given suggestion group ID. this.pageHandler_.toggleSuggestionGroupIdVisibility(groupId); @@ -309,7 +303,7 @@ class RealboxDropdownElement extends PolymerElement { return; } - // Simulate a click so that it gets handled by |onToggleButtonClick_|. + // Simulate a click so that it gets handled by |onHeaderClick_|. e.target.click(); e.preventDefault(); // Prevents default browser action. } @@ -332,21 +326,23 @@ class RealboxDropdownElement extends PolymerElement { } /** - * @returns {!Array<string>} + * @returns {!Array<number>} * @private */ computeGroupIds_() { - if (!this.result) { + if (!this.result || !this.result.matches) { return []; } - // Add |NO_SUGGESTION_GROUP_ID| to the list of suggestion group IDs. - return [NO_SUGGESTION_GROUP_ID].concat( - Object.keys(this.result.suggestionGroupsMap)); + // Extract the suggestion group IDs from autocomplete matches and return the + // unique IDs while preserving the order. Autocomplete matches are the + // ultimate source of truth for suggestion groups IDs matches belong to. + return [...new Set( + this.result.matches.map(match => match.suggestionGroupId))]; } /** - * @returns {!Array<string>} + * @returns {!Array<number>} * @private */ computeHiddenGroupIds_() { @@ -355,13 +351,14 @@ class RealboxDropdownElement extends PolymerElement { } return Object.keys(this.result.suggestionGroupsMap) + .map(groupId => Number(groupId)) .filter((groupId => { return this.result.suggestionGroupsMap[groupId].hidden; }).bind(this)); } /** - * @param {string} groupId + * @param {number} groupId * @returns {!function(!search.mojom.AutocompleteMatch):boolean} The filter * function to filter matches that belong to the given suggestion group * ID. @@ -369,21 +366,21 @@ class RealboxDropdownElement extends PolymerElement { */ computeMatchBelongsToGroup_(groupId) { return (match) => { - return match.suggestionGroupId === Number(groupId); + return match.suggestionGroupId === groupId; }; } /** - * @param {string} groupId + * @param {number} groupId * @returns {boolean} Whether the given suggestion group ID has a header. * @private */ groupHasHeader_(groupId) { - return groupId !== NO_SUGGESTION_GROUP_ID; + return !!this.headerForGroup_(groupId); } /** - * @param {string} groupId + * @param {number} groupId * @returns {boolean} Whether matches with the given suggestion group ID * should be hidden. * @private @@ -393,15 +390,12 @@ class RealboxDropdownElement extends PolymerElement { } /** - * @param {string} groupId + * @param {number} groupId * @returns {string} The header for the given suggestion group ID. * @private * @suppress {checkTypes} */ headerForGroup_(groupId) { - if (!this.groupHasHeader_(groupId)) { - return ''; - } return (this.result && this.result.suggestionGroupsMap && this.result.suggestionGroupsMap[groupId]) ? decodeString16(this.result.suggestionGroupsMap[groupId].header) : @@ -409,7 +403,7 @@ class RealboxDropdownElement extends PolymerElement { } /** - * @param {string} groupId + * @param {number} groupId * @returns {string} Tooltip for suggestion group show/hide toggle button. * @private */ @@ -422,7 +416,7 @@ class RealboxDropdownElement extends PolymerElement { } /** - * @param {string} groupId + * @param {number} groupId * @returns {string} A11y label for suggestion group show/hide toggle button. * @private */ diff --git a/chromium/chrome/browser/resources/new_tab_page/realbox_match.html b/chromium/chrome/browser/resources/new_tab_page/realbox_match.html index cef7e228029..16e2ff35784 100644 --- a/chromium/chrome/browser/resources/new_tab_page/realbox_match.html +++ b/chromium/chrome/browser/resources/new_tab_page/realbox_match.html @@ -58,20 +58,20 @@ :host([has-image]) #description, .dim { - color: var(--search-box-results-dim, var(--google-grey-600)); + color: var(--search-box-results-dim, var(--google-grey-refresh-700)); } :host-context(ntp-realbox-match:-webkit-any(:focus-within, .selected)):host([has-image]) #description, :host-context(ntp-realbox-match:-webkit-any(:focus-within, .selected)) .dim { - color: var(--search-box-results-dim-selected, var(--google-grey-600)); + color: var(--search-box-results-dim-selected, var(--google-grey-refresh-700)); } .url { - color: var(--search-box-results-url, var(--google-grey-600)); + color: var(--search-box-results-url, var(--google-blue-refresh-700)); } :host-context(ntp-realbox-match:-webkit-any(:focus-within, .selected)) .url { - color: var(--search-box-results-url-selected, var(--google-grey-600)); + color: var(--search-box-results-url-selected, var(--google-blue-refresh-700)); } </style> diff --git a/chromium/chrome/browser/resources/new_tab_page/shared_vars.css b/chromium/chrome/browser/resources/new_tab_page/shared_vars.css index 11cd6f1239e..94b0ebed3d9 100644 --- a/chromium/chrome/browser/resources/new_tab_page/shared_vars.css +++ b/chromium/chrome/browser/resources/new_tab_page/shared_vars.css @@ -14,9 +14,6 @@ html { --ntp-border-color: var(--google-grey-refresh-300); --ntp-focus-shadow-color: rgba(var(--google-blue-600-rgb), .4); --ntp-hover-background-color: rgba(var(--google-grey-900-rgb), .1); - --ntp-primary-text-color: var(--google-grey-refresh-700); - --ntp-secondary-text-color: var(--google-grey-600); - --ntp-secondary-text-hover-color: var(--google-grey-refresh-700); --ntp-selected-background-color: rgba(var(--google-blue-refresh-700-rgb), .16); --ntp-selected-border-color: var(--google-blue-600); --ntp-selected-light-background-color: rgba(var(--google-blue-600-rgb), .24); @@ -34,9 +31,6 @@ html { --ntp-border-color: var(--google-grey-refresh-700); --ntp-focus-shadow-color: rgba(var(--google-blue-refresh-300-rgb), .5); --ntp-hover-background-color: rgba(var(--google-grey-200-rgb), .1); - --ntp-primary-text-color: var(--google-grey-refresh-300); - --ntp-secondary-text-color: var(--google-grey-refresh-500); - --ntp-secondary-text-hover-color: var(--google-grey-200); --ntp-selected-background-color: rgba(var(--google-blue-refresh-300-rgb), .16); --ntp-selected-border-color: var(--google-blue-refresh-300); --ntp-selected-light-background-color: rgba(var(--google-blue-refresh-300-rgb), .24); diff --git a/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.html b/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.html index 20e4c9ecdeb..a7f3719e2f2 100644 --- a/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.html +++ b/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.html @@ -8,6 +8,19 @@ overflow: hidden; } + .fade-in { + animation: fadeIn 200ms; + } + + @keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + $i18nRaw{inHeadStyle} </style> <script>$i18nRaw{inHeadScript}</script> @@ -17,6 +30,6 @@ <script>$i18nRaw{afterBarScript}</script> $i18nRaw{endOfBodyHtml} <script>$i18nRaw{endOfBodyScript}</script> - <script src="one_google_bar.js"></script> + <script type="module" src="one_google_bar.js"></script> </body> </html> diff --git a/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.js b/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.js index a6bbf5c0de2..dc341007b47 100644 --- a/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.js +++ b/chromium/chrome/browser/resources/new_tab_page/untrusted/one_google_bar.js @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {oneGoogleBarApi} from './one_google_bar_api.js'; + /** * The following |messageType|'s are sent to the parent frame: * - loaded: sent on initial load. @@ -24,36 +26,16 @@ function postMessage(messageType, data) { 'chrome://new-tab-page'); } -// Object that exposes: -// - |getEnabled()|: returns whether dark theme is enabled. -// - |setEnabled(value)|: updates whether dark theme is enabled using the -// OneGoogleBar API. -const darkTheme = (() => { - let enabled = false; - - /** @return {boolean} */ - const getEnabled = () => enabled; - - /** - * @param {boolean} value - * @return {!Promise} - */ - const setEnabled = async value => { - if (!window.gbar) { - return; - } - enabled = value; - const ogb = await window.gbar.a.bf(); - ogb.pc.call(ogb, enabled ? 1 : 0); - }; - - return {getEnabled, setEnabled}; -})(); - -// Object that exposes: -// - |track()|: sets up MutationObserver to track element visibility changes. -// - |update(potentialNewOverlays)|: determines visibility of tracked elements -// and sends an update to the top frame about element visibility. +/** + * Object that exposes: + * - |track()|: sets up MutationObserver to track element visibility changes. + * - |update(potentialNewOverlays)|: determines visibility of tracked elements + * and sends an update to the top frame about element visibility. + * @type {!{ + * track: !function(), + * update: !function(!Array<!Element>), + * }} + */ const overlayUpdater = (() => { const modalOverlays = document.documentElement.hasAttribute('modal-overlays'); let shouldUndoDarkTheme = false; @@ -90,6 +72,9 @@ const overlayUpdater = (() => { /** @param {!Element} potentialNewOverlays */ const addOverlay = overlay => { + if (overlays.has(overlay)) { + return; + } // If an overlay starts a transition, the updated bounding rects need to // be sent to the top frame during the transition. The MutationObserver // will only handle new elements and changes to the element attributes. @@ -107,6 +92,23 @@ const overlayUpdater = (() => { el.target = '_top'; } }); + if (!modalOverlays) { + const {transition} = getComputedStyle(overlay); + const opacityTransition = 'opacity 0.1s ease 0.02s'; + // Check if the transition is the default computed transition style. If it + // is not, append to the existing transitions. + if (transition === 'all 0s ease 0s') { + overlay.style.transition = opacityTransition; + } else if (!transition.includes('opacity')) { + overlay.style.transition = transition + ', ' + opacityTransition; + } + } + // The element has an initial opacity of 1. If the element is being added to + // |overlays| and shown in the same |update()| call, the opacity transition + // will not work since the opacity is already 1. For this reason the + // 'fade-in' class is added to the element which runs an initial fade-in + // animation. + overlay.classList.add('fade-in'); overlays.add(overlay); }; @@ -144,10 +146,15 @@ const overlayUpdater = (() => { overlays.forEach(overlay => { const {display, visibility} = window.getComputedStyle(overlay); const rect = overlay.getBoundingClientRect(); - if (display !== 'none' && visibility !== 'hidden' && - rect.bottom > barRect.bottom) { + const shown = display !== 'none' && visibility !== 'hidden' && + rect.bottom > barRect.bottom; + if (shown) { overlayRects.push(rect); } + if (!modalOverlays) { + // Setting the style here avoids triggering the mutation observer. + overlay.style.opacity = shown ? '1' : '0'; + } }); if (!modalOverlays) { overlayRects.push(barRect); @@ -170,13 +177,13 @@ const overlayUpdater = (() => { // OneGoogleBar iframe. The dark theme for the OneGoogleBar is then enabled // for better visibility. if (overlayShown) { - if (!darkTheme.getEnabled()) { + if (!oneGoogleBarApi.isForegroundLight()) { shouldUndoDarkTheme = true; - darkTheme.setEnabled(true); + oneGoogleBarApi.setForegroundLight(true); } } else if (shouldUndoDarkTheme) { shouldUndoDarkTheme = false; - darkTheme.setEnabled(false); + oneGoogleBarApi.setForegroundLight(false); } }; @@ -209,7 +216,7 @@ const overlayUpdater = (() => { window.addEventListener('message', ({data}) => { if (data.type === 'enableDarkTheme') { - darkTheme.setEnabled(data.enabled); + oneGoogleBarApi.setForegroundLight(data.enabled); } }); @@ -233,7 +240,7 @@ document.addEventListener('DOMContentLoaded', () => { el.target = '_top'; } }); - modalOverlays = document.documentElement.hasAttribute('modal-overlays'); postMessage('loaded'); overlayUpdater.track(); + oneGoogleBarApi.trackDarkModeChanges(); }); diff --git a/chromium/chrome/browser/resources/new_tab_page/untrusted/promo.js b/chromium/chrome/browser/resources/new_tab_page/untrusted/promo.js index 454df0f2dc9..18a61902671 100644 --- a/chromium/chrome/browser/resources/new_tab_page/untrusted/promo.js +++ b/chromium/chrome/browser/resources/new_tab_page/untrusted/promo.js @@ -16,7 +16,27 @@ document.addEventListener('DOMContentLoaded', () => { if (el.target !== '_blank') { el.target = '_top'; } - el.addEventListener('click', () => { + el.addEventListener('click', (event) => { + const browserCommandFound = + event.target.getAttribute('href').match(/^command:(\d+)$/); + if (browserCommandFound) { + event.preventDefault(); // Prevent navigation attempt. + window.parent.postMessage( + { + frameType: 'promo', + messageType: 'execute-browser-command', + commandId: parseInt(browserCommandFound[1], 10), + clickInfo: { + middleButton: event.button === 1, + altKey: event.altKey, + ctrlKey: event.ctrlKey, + metaKey: event.metaKey, + shiftKey: event.shiftKey + } + }, + 'chrome://new-tab-page'); + } + window.parent.postMessage( {frameType: 'promo', messageType: 'link-clicked'}, 'chrome://new-tab-page'); diff --git a/chromium/chrome/browser/resources/new_tab_page/utils.js b/chromium/chrome/browser/resources/new_tab_page/utils.js index 9d335347372..2b2e750a7fd 100644 --- a/chromium/chrome/browser/resources/new_tab_page/utils.js +++ b/chromium/chrome/browser/resources/new_tab_page/utils.js @@ -3,35 +3,6 @@ // found in the LICENSE file. /** - * Converts an SkColor object to a string in the form - * "rgba(<red>, <green>, <blue>, <alpha>)". - * @param {skia.mojom.SkColor} skColor The input color. - * @return {string} The rgba string. - */ -export function skColorToRgba(skColor) { - const a = (skColor.value >> 24) & 0xff; - const r = (skColor.value >> 16) & 0xff; - const g = (skColor.value >> 8) & 0xff; - const b = skColor.value & 0xff; - return `rgba(${r}, ${g}, ${b}, ${(a / 255).toFixed(2)})`; -} - -/** - * Converts a string of the form "#rrggbb" to an SkColor object. - * @param {string} hexColor The color string. - * @return {!skia.mojom.SkColor} The SkColor object, - */ -export function hexColorToSkColor(hexColor) { - if (!/^#[0-9a-f]{6}$/.test(hexColor)) { - return {value: 0}; - } - const r = parseInt(hexColor.substring(1, 3), 16); - const g = parseInt(hexColor.substring(3, 5), 16); - const b = parseInt(hexColor.substring(5, 7), 16); - return {value: 0xff000000 + (r << 16) + (g << 8) + b}; -} - -/** * Given a |container| that has scrollable content, <div>'s before and after the * |container| are created with an attribute "scroll-border". These <div>'s are * updated to have an attribute "show" when there is more content in the diff --git a/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.html b/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.html index bd8484300bc..aa95925039d 100644 --- a/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.html +++ b/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.html @@ -28,7 +28,7 @@ } #closeButton { - --cr-icon-button-fill-color: var(--ntp-secondary-text-color); + --cr-icon-button-fill-color: var(--cr-secondary-text-color); margin: 0; position: absolute; top: 16px; @@ -50,7 +50,7 @@ } #texts { - color: var(--ntp-secondary-text-color); + color: var(--cr-secondary-text-color); flex-grow: 1; font-size: 32px; text-align: start; @@ -92,7 +92,7 @@ } #finalResult { - color: var(--ntp-primary-text-color); + color: var(--cr-primary-text-color); } #errors, diff --git a/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.js b/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.js index 6db0f40b9ea..bc7a0c06658 100644 --- a/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.js +++ b/chromium/chrome/browser/resources/new_tab_page/voice_search_overlay.js @@ -105,23 +105,23 @@ const Error = newTabPage.mojom.VoiceSearchError; function toError(webkitError) { switch (webkitError) { case 'aborted': - return Error.ABORTED; + return Error.kAborted; case 'audio-capture': - return Error.AUDIO_CAPTURE; + return Error.kAudioCapture; case 'language-not-supported': - return Error.LANGUAGE_NOT_SUPPORTED; + return Error.kLanguageNotSupported; case 'network': - return Error.NETWORK; + return Error.kNetwork; case 'no-speech': - return Error.NO_SPEECH; + return Error.kNoSpeech; case 'not-allowed': - return Error.NOT_ALLOWED; + return Error.kNotAllowed; case 'service-not-allowed': - return Error.SERVICE_NOT_ALLOWED; + return Error.kServiceNotAllowed; case 'bad-grammar': - return Error.BAD_GRAMMAR; + return Error.kBadGrammar; default: - return Error.OTHER; + return Error.kOther; } } @@ -133,10 +133,10 @@ function toError(webkitError) { */ function getErrorTimeout(error) { switch (error) { - case Error.AUDIO_CAPTURE: - case Error.NO_SPEECH: - case Error.NOT_ALLOWED: - case Error.NO_MATCH: + case Error.kAudioCapture: + case Error.kNoSpeech: + case Error.kNotAllowed: + case Error.kNoMatch: return ERROR_TIMEOUT_LONG_MS; default: return ERROR_TIMEOUT_SHORT_MS; @@ -209,7 +209,7 @@ class VoiceSearchOverlayElement extends PolymerElement { this.onError_(toError(e.error)); }; this.voiceRecognition_.onnomatch = () => { - this.onError_(Error.NO_MATCH); + this.onError_(Error.kNoMatch); }; /** @private {number|undefined} */ this.timerId_ = undefined; @@ -239,7 +239,7 @@ class VoiceSearchOverlayElement extends PolymerElement { onOverlayClick_() { this.$.dialog.close(); this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.CLOSE_OVERLAY); + newTabPage.mojom.VoiceSearchAction.kCloseOverlay); } /** @@ -274,7 +274,7 @@ class VoiceSearchOverlayElement extends PolymerElement { /** @private */ onLearnMoreClick_() { this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.SUPPORT_LINK_CLICKED); + newTabPage.mojom.VoiceSearchAction.kSupportLinkClicked); } /** @@ -286,7 +286,7 @@ class VoiceSearchOverlayElement extends PolymerElement { e.stopPropagation(); this.start(); this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.TRY_AGAIN_LINK); + newTabPage.mojom.VoiceSearchAction.kTryAgainLink); } /** @@ -295,14 +295,14 @@ class VoiceSearchOverlayElement extends PolymerElement { */ onMicClick_(e) { if (this.state_ !== State.ERROR_RECEIVED || - this.error_ !== Error.NO_MATCH) { + this.error_ !== Error.kNoMatch) { return; } // Otherwise, we close the overlay. e.stopPropagation(); this.start(); this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.TRY_AGAIN_MIC_BUTTON); + newTabPage.mojom.VoiceSearchAction.kTryAgainMicButton); } /** @private */ @@ -324,7 +324,7 @@ class VoiceSearchOverlayElement extends PolymerElement { return; } this.voiceRecognition_.abort(); - this.onError_(Error.NO_MATCH); + this.onError_(Error.kNoMatch); } /** @@ -412,7 +412,7 @@ class VoiceSearchOverlayElement extends PolymerElement { /** @private */ onFinalResult_() { if (!this.finalResult_) { - this.onError_(Error.NO_MATCH); + this.onError_(Error.kNoMatch); return; } this.state_ = State.RESULT_FINAL; @@ -425,7 +425,7 @@ class VoiceSearchOverlayElement extends PolymerElement { new URL('/search', loadTimeData.getString('googleBaseUrl')); queryUrl.search = searchParams.toString(); this.pageHandler_.onVoiceSearchAction( - newTabPage.mojom.VoiceSearchAction.QUERY_SUBMITTED); + newTabPage.mojom.VoiceSearchAction.kQuerySubmitted); BrowserProxy.getInstance().navigate(queryUrl.href); } @@ -433,20 +433,20 @@ class VoiceSearchOverlayElement extends PolymerElement { onEnd_() { switch (this.state_) { case State.STARTED: - this.onError_(Error.AUDIO_CAPTURE); + this.onError_(Error.kAudioCapture); return; case State.AUDIO_RECEIVED: - this.onError_(Error.NO_SPEECH); + this.onError_(Error.kNoSpeech); return; case State.SPEECH_RECEIVED: case State.RESULT_RECEIVED: - this.onError_(Error.NO_MATCH); + this.onError_(Error.kNoMatch); return; case State.ERROR_RECEIVED: case State.RESULT_FINAL: return; default: - this.onError_(Error.OTHER); + this.onError_(Error.kOther); return; } } @@ -457,7 +457,7 @@ class VoiceSearchOverlayElement extends PolymerElement { */ onError_(error) { this.pageHandler_.onVoiceSearchError(error); - if (error === Error.ABORTED) { + if (error === Error.kAborted) { // We are in the process of closing voice search. return; } @@ -510,21 +510,21 @@ class VoiceSearchOverlayElement extends PolymerElement { */ getErrorText_() { switch (this.error_) { - case Error.NO_SPEECH: + case Error.kNoSpeech: return 'no-speech'; - case Error.AUDIO_CAPTURE: + case Error.kAudioCapture: return 'audio-capture'; - case Error.NETWORK: + case Error.kNetwork: return 'network'; - case Error.NOT_ALLOWED: - case Error.SERVICE_NOT_ALLOWED: + case Error.kNotAllowed: + case Error.kServiceNotAllowed: return 'not-allowed'; - case Error.LANGUAGE_NOT_SUPPORTED: + case Error.kLanguageNotSupported: return 'language-not-supported'; - case Error.NO_MATCH: + case Error.kNoMatch: return 'no-match'; - case Error.ABORTED: - case Error.OTHER: + case Error.kAborted: + case Error.kOther: default: return 'other'; } @@ -536,13 +536,13 @@ class VoiceSearchOverlayElement extends PolymerElement { */ getErrorLink_() { switch (this.error_) { - case Error.NO_SPEECH: - case Error.AUDIO_CAPTURE: + case Error.kNoSpeech: + case Error.kAudioCapture: return 'learn-more'; - case Error.NOT_ALLOWED: - case Error.SERVICE_NOT_ALLOWED: + case Error.kNotAllowed: + case Error.kServiceNotAllowed: return 'details'; - case Error.NO_MATCH: + case Error.kNoMatch: return 'try-again'; default: return 'none'; diff --git a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.css b/chromium/chrome/browser/resources/notifications_internals/notifications_internals.css deleted file mode 100644 index aa7e8f93e4b..00000000000 --- a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.css +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright 2019 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -h1 { - color: rgb(74, 142, 230); - margin: 0; - padding: 0; -}
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.js b/chromium/chrome/browser/resources/notifications_internals/notifications_internals.js deleted file mode 100644 index 1fc271771f6..00000000000 --- a/chromium/chrome/browser/resources/notifications_internals/notifications_internals.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('notificationsInternals', function() { - 'use strict'; - - const browserProxy = - notificationsInternals.NotificationsInternalsBrowserProxyImpl - .getInstance(); - - function initialize() { - // Register all event listeners. - $('schedule-notification').onclick = function() { - browserProxy.scheduleNotification( - $('notification-scheduler-url').value, - $('notification-scheduler-title').value, - $('notification-scheduler-message').value); - }; - } - - return { - initialize: initialize, - }; -}); - -document.addEventListener( - 'DOMContentLoaded', notificationsInternals.initialize); diff --git a/chromium/chrome/browser/resources/notifications_internals/notifications_internals_browser_proxy.js b/chromium/chrome/browser/resources/notifications_internals/notifications_internals_browser_proxy.js deleted file mode 100644 index 0c30a8e30d3..00000000000 --- a/chromium/chrome/browser/resources/notifications_internals/notifications_internals_browser_proxy.js +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('notificationsInternals', function() { - /** @interface */ - class NotificationsInternalsBrowserProxy { - /** - * Schedules a notification through notification schedule service. - * @param {string} url URL to open after clicking the notification. - * @param {string} title Title of the notification. - * @param {string} message Message of the notification. - */ - scheduleNotification(url, title, message) {} - } - - /** - * @implements {notificationsInternals.NotificationsInternalsBrowserProxy} - */ - class NotificationsInternalsBrowserProxyImpl { - /** @override */ - scheduleNotification(url, title, message) { - return cr.sendWithPromise('scheduleNotification', url, title, message); - } - } - - cr.addSingletonGetter(NotificationsInternalsBrowserProxyImpl); - - return { - NotificationsInternalsBrowserProxy: NotificationsInternalsBrowserProxy, - NotificationsInternalsBrowserProxyImpl: - NotificationsInternalsBrowserProxyImpl - }; -}); diff --git a/chromium/chrome/browser/resources/ntp4/BUILD.gn b/chromium/chrome/browser/resources/ntp4/BUILD.gn index 25c15b8a758..8efe057fdda 100644 --- a/chromium/chrome/browser/resources/ntp4/BUILD.gn +++ b/chromium/chrome/browser/resources/ntp4/BUILD.gn @@ -38,7 +38,6 @@ js_library("apps_page") { "//ui/webui/resources/js/util.js", "apps_page.js", "dot_list.js", - "logging.js", "nav_dot.js", "new_tab.js", "page_list_view.js", diff --git a/chromium/chrome/browser/resources/ntp4/OWNERS b/chromium/chrome/browser/resources/ntp4/OWNERS index 690a9f1a025..a5d6768c771 100644 --- a/chromium/chrome/browser/resources/ntp4/OWNERS +++ b/chromium/chrome/browser/resources/ntp4/OWNERS @@ -1,3 +1,4 @@ +file://components/search/OWNERS estade@chromium.org rbyers@chromium.org diff --git a/chromium/chrome/browser/resources/ntp4/apps_page.js b/chromium/chrome/browser/resources/ntp4/apps_page.js index 8ec435a9cea..2c0c872b6ae 100644 --- a/chromium/chrome/browser/resources/ntp4/apps_page.js +++ b/chromium/chrome/browser/resources/ntp4/apps_page.js @@ -30,6 +30,17 @@ cr.define('ntp', function() { const APP_IMG_SIZE_FRACTION = 4 / 5; /** + * This policy maps a given string to a `TrustedHTML` object + * without performing any validation. Callsites must ensure + * that the resulting object will only be used in inert + * documents. + * + * @type {!TrustedTypePolicy} + */ + const unsanitizedPolicy = trustedTypes.createPolicy( + 'apps-page-js', {createHTML: untrustedHTML => untrustedHTML}); + + /** * App context menu. The class is designed to be used as a singleton with * the app that is currently showing a context menu stored in this.app_. * @constructor @@ -752,7 +763,7 @@ cr.define('ntp', function() { // It's important that we don't attach this node to the document // because it might contain scripts. const doc = document.implementation.createHTMLDocument(); - doc.body.innerHTML = html; + doc.body.innerHTML = unsanitizedPolicy.createHTML(html); title = doc.body.textContent; } diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.html b/chromium/chrome/browser/resources/ntp4/incognito_tab.html index b666b0c65a4..8b1818575fb 100644 --- a/chromium/chrome/browser/resources/ntp4/incognito_tab.html +++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.html @@ -8,14 +8,15 @@ <meta charset="utf-8"> <title>$i18n{title}</title> <meta name="viewport" content="width=device-width"> -<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> -<link rel="stylesheet" href="incognito_tab.css"> +<link id="incognitothemecss" rel="stylesheet"> +<script src="chrome://resources/js/util.js"></script> <script> // Until themes can clear the cache, force-reload the theme stylesheet. -document.write('<link id="incognitothemecss" rel="stylesheet" ' + - 'href="chrome://theme/css/incognito_tab_theme.css?' + - Date.now() + '">'); +$('incognitothemecss').href = + 'chrome://theme/css/incognito_tab_theme.css?' + Date.now(); </script> +<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> +<link rel="stylesheet" href="incognito_tab.css"> </head> <body> <div class="content"> @@ -30,7 +31,7 @@ document.write('<link id="incognitothemecss" rel="stylesheet" ' + <div class="bulletpoints first">$i18nRaw{incognitoTabFeatures}</div> <div class="bulletpoints">$i18nRaw{incognitoTabWarning}</div> </div> - <div id="cookie-controls" $i18n{hideCookieControls}> + <div id="cookie-controls"> <div id="cookie-controls-description"> <em>$i18n{cookieControlsTitle}</em> $i18n{cookieControlsDescription} @@ -48,7 +49,6 @@ document.write('<link id="incognitothemecss" rel="stylesheet" ' + <a class="learn-more-button" href="$i18n{learnMoreLink}">$i18n{learnMore}</a> </div> <script src="chrome://resources/js/cr.js"></script> -<script src="chrome://resources/js/util.js"></script> <script src="incognito_tab.js"></script> <!-- Lazy-load cr_elements to avoid performance penalty introduced by loading Polymer --> <script type="module" src="chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js" async></script> diff --git a/chromium/chrome/browser/resources/ntp4/logging.js b/chromium/chrome/browser/resources/ntp4/logging.js deleted file mode 100644 index 91776084074..00000000000 --- a/chromium/chrome/browser/resources/ntp4/logging.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * Logging info for benchmarking purposes. Should be the first js file included. - */ - -/* Stack of events that has been logged. */ -const eventLog = []; - -/** - * Logs an event. - * @param {string} name The name of the event (can be any string). - * @param {boolean=} opt_shouldLogTime If true, the event is used for - * benchmarking and the time is logged. Otherwise, just push the event on - * the event stack. - */ -function logEvent(name, opt_shouldLogTime) { - if (opt_shouldLogTime) { - chrome.send('metricsHandler:logEventTime', [name]); - } - eventLog.push([name, Date.now()]); -} - -logEvent('Tab.NewTabScriptStart', true); -window.addEventListener('load', function(e) { - logEvent('Tab.NewTabOnload', true); -}); -document.addEventListener('DOMContentLoaded', function(e) { - logEvent('Tab.NewTabDOMContentLoaded', true); -}); diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.html b/chromium/chrome/browser/resources/ntp4/new_tab.html index 2b60f4a75a6..2423932caec 100644 --- a/chromium/chrome/browser/resources/ntp4/new_tab.html +++ b/chromium/chrome/browser/resources/ntp4/new_tab.html @@ -13,9 +13,12 @@ <meta name="viewport" content="user-scalable=no, width=device-width, maximum-scale=1.0"> -<!-- It's important that this be the first script loaded. --> -<script src="logging.js"></script> - +<link id="themecss" rel="stylesheet"> +<script src="../../../../ui/webui/resources/js/util.js"></script> +<script> +// Until themes can clear the cache, force-reload the theme stylesheet. +$('themecss').href = 'chrome://theme/css/new_tab_theme.css?' + Date.now(); +</script> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="../../../../ui/webui/resources/css/bubble.css"> <link rel="stylesheet" href="../../../../ui/webui/resources/css/menu.css"> @@ -26,14 +29,9 @@ <link rel="stylesheet" href="new_tab.css"> <link rel="stylesheet" href="tile_page.css"> <link rel="stylesheet" href="trash.css"> -<script> -// Until themes can clear the cache, force-reload the theme stylesheet. -document.write('<link id="themecss" rel="stylesheet" ' + - 'href="chrome://theme/css/new_tab_theme.css?' + Date.now() + '">'); -</script> <script src="../../../../ui/webui/resources/js/action_link.js"></script> <script src="../../../../ui/webui/resources/js/event_tracker.js"></script> -<script src="../../../../ui/webui/resources/js/util.js"></script> +<script src="../../../../ui/webui/resources/js/parse_html_subset.js"></script> <script src="../../../../ui/webui/resources/js/cr.js"></script> <script src="../../../../ui/webui/resources/js/cr/event_target.js"></script> diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.js b/chromium/chrome/browser/resources/ntp4/new_tab.js index d6f7b960b48..f99ea7bbd2a 100644 --- a/chromium/chrome/browser/resources/ntp4/new_tab.js +++ b/chromium/chrome/browser/resources/ntp4/new_tab.js @@ -246,9 +246,14 @@ cr.define('ntp', function() { $('card-slider-frame').classList.toggle('showing-login-area', !!showLogin); if (showLogin) { - // TODO(dbeam): we should use .textContent instead to mitigate XSS. - $('login-status-header').innerHTML = loginHeader; - $('login-status-sub-header').innerHTML = loginSubHeader; + $('login-status-header').innerHTML = trustedTypes.emptyHTML; + $('login-status-header') + .appendChild( + parseHtmlSubset(loginHeader, undefined, ['class', 'is'])); + $('login-status-sub-header').innerHTML = trustedTypes.emptyHTML; + $('login-status-sub-header') + .appendChild( + parseHtmlSubset(loginSubHeader, undefined, ['class', 'is'])); const headerContainer = $('login-status-header-container'); headerContainer.classList.toggle('login-status-icon', !!iconURL); diff --git a/chromium/chrome/browser/resources/ntp4/page_list_view.js b/chromium/chrome/browser/resources/ntp4/page_list_view.js index ec7160a65a0..4107fa647f5 100644 --- a/chromium/chrome/browser/resources/ntp4/page_list_view.js +++ b/chromium/chrome/browser/resources/ntp4/page_list_view.js @@ -321,8 +321,6 @@ cr.define('ntp', function() { * An object with all the data on available applications. */ getAppsCallback(data) { - const startTime = Date.now(); - // Remember this to select the correct card when done rebuilding. const prevCurrentCard = this.cardSlider.currentCard; @@ -409,8 +407,6 @@ cr.define('ntp', function() { this.appAdded(highlightApp, true); } - logEvent('apps.layout: ' + (Date.now() - startTime)); - // Tell the slider about the pages and mark the current page. this.updateSliderCards(); this.cardSlider.currentCardValue.navigationDot.classList.add('selected'); diff --git a/chromium/chrome/browser/resources/ntp4/tile_page.js b/chromium/chrome/browser/resources/ntp4/tile_page.js index 0b7837e8337..f924d34b91f 100644 --- a/chromium/chrome/browser/resources/ntp4/tile_page.js +++ b/chromium/chrome/browser/resources/ntp4/tile_page.js @@ -646,7 +646,7 @@ cr.define('ntp', function() { * Removes all tiles from the page. */ removeAllTiles() { - this.tileGrid_.innerHTML = ''; + this.tileGrid_.innerHTML = trustedTypes.emptyHTML; }, /** diff --git a/chromium/chrome/browser/resources/omnibox/omnibox_output.js b/chromium/chrome/browser/resources/omnibox/omnibox_output.js index 41118b01039..c41f31097bb 100644 --- a/chromium/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chromium/chrome/browser/resources/omnibox/omnibox_output.js @@ -1052,22 +1052,22 @@ const COLUMNS = [ ], OutputAnswerProperty), new Column( - ['S'], '', 'swapContentsAndDescription', false, + ['sw'], '', 'swapContentsAndDescription', false, 'Swap Contents and Description', ['swapContentsAndDescription'], OutputBooleanProperty), new Column( - ['D'], '', 'allowedToBeDefaultMatch', true, + ['df'], '', 'allowedToBeDefaultMatch', true, 'Can be Default\nA green checkmark indicates that the result can be ' + 'the default match (i.e., can be the match that pressing enter ' + 'in the omnibox navigates to).', ['allowedToBeDefaultMatch'], OutputBooleanProperty), new Column( - ['S'], '', 'starred', false, - 'Starred\nA green checkmark indicates that the result has been ' + + ['bk'], '', 'starred', false, + 'Bookmarked\nA green checkmark indicates that the result has been ' + 'bookmarked.', ['starred'], OutputBooleanProperty), new Column( - ['T'], '', 'hasTabMatch', false, + ['tb'], '', 'hasTabMatch', false, 'Has Tab Match\nA green checkmark indicates that the result URL ' + 'matches an open tab.', ['hasTabMatch'], OutputBooleanProperty), @@ -1084,12 +1084,12 @@ const COLUMNS = [ 'selection following the cursor, if this match is shown inline.', ['fillIntoEdit', 'inlineAutocompletion'], OutputOverlappingPairProperty), new Column( - ['D'], '', 'deletable', false, + ['dl'], '', 'deletable', false, 'Deletable\nA green checkmark indicates that the result can be ' + 'deleted from the visit history.', ['deletable'], OutputBooleanProperty), new Column( - ['P'], '', 'fromPrevious', false, + ['pr'], '', 'fromPrevious', false, 'From Previous\nTrue if this match is from a previous result.', ['fromPrevious'], OutputBooleanProperty), new Column( @@ -1099,7 +1099,7 @@ const COLUMNS = [ 'transition', false, 'Transition\nHow the user got to the result.', ['transition'], OutputTextProperty), new Column( - ['D'], '', 'providerDone', false, + ['dn'], '', 'providerDone', false, 'Done\nA green checkmark indicates that the provider is done looking ' + 'for more results.', ['providerDone'], OutputBooleanProperty), @@ -1113,7 +1113,7 @@ const COLUMNS = [ 'Keyword\nThe keyword of the search engine to be used.', ['keyword'], OutputTextProperty), new Column( - ['D'], '', 'duplicates', false, + ['dp'], '', 'duplicates', false, 'Duplicates\nThe number of matches that have been marked as ' + 'duplicates of this match.', ['duplicates'], OutputTextProperty), diff --git a/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css b/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css index 45c82783cde..cbb3ded07b1 100644 --- a/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css +++ b/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css @@ -44,5 +44,6 @@ .header-from-previous, .header-provider-done, .header-duplicates { + font-size: .75rem; width: 18px; } diff --git a/chromium/chrome/browser/resources/optimize_webui.gni b/chromium/chrome/browser/resources/optimize_webui.gni index 01db4694669..dad606df822 100644 --- a/chromium/chrome/browser/resources/optimize_webui.gni +++ b/chromium/chrome/browser/resources/optimize_webui.gni @@ -13,7 +13,7 @@ template("node") { "//third_party/node/node_modules.tar.gz.sha1", ] - if (is_linux) { + if (is_linux || is_chromeos) { inputs += [ "//third_party/node/linux/node-linux-x64.tar.gz.sha1" ] } if (is_win) { diff --git a/chromium/chrome/browser/resources/optimize_webui.py b/chromium/chrome/browser/resources/optimize_webui.py index 30ffbf7f343..5b3b9aa1dba 100755 --- a/chromium/chrome/browser/resources/optimize_webui.py +++ b/chromium/chrome/browser/resources/optimize_webui.py @@ -72,6 +72,9 @@ for excluded_file in [ 'resources/css/text_defaults.css', 'resources/css/text_defaults_md.css', 'resources/mojo/mojo/public/js/mojo_bindings_lite.html', + 'resources/mojo/mojo/public/mojom/base/time.mojom.html', + 'resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom.html', + 'resources/mojo/services/network/public/mojom/ip_address.mojom.html', # Excludes applying only to Polymer 3. 'resources/polymer/v3_0/polymer/polymer_bundled.min.js', @@ -105,7 +108,7 @@ for (redirect_url, file_path) in [ _VULCANIZE_REDIRECT_ARGS = list(itertools.chain.from_iterable(map( - lambda m: ['--redirect', '"%s|%s"' % (m[0], m[1])], _URL_MAPPINGS))) + lambda m: ['--redirect', '%s|%s' % (m[0], m[1])], _URL_MAPPINGS))) def _undo_mapping(mappings, url): @@ -272,7 +275,7 @@ def _bundle_v2(tmp_out_dir, in_path, out_path, manifest_out_path, args, [ '--manifest-out', manifest_out_path, '--root', in_path, - '--redirect', '"chrome://%s/|%s"' % (args.host, in_path + '/'), + '--redirect', 'chrome://%s/|%s' % (args.host, in_path + '/'), '--out-dir', os.path.relpath(tmp_out_dir, _CWD).replace('\\', '/'), '--shell', args.html_in_files[0], ] + in_html_args) @@ -350,7 +353,7 @@ def _optimize(in_folder, args): for index, js_out_file in enumerate(args.js_out_files): node.RunNode([node_modules.PathToUglify(), os.path.join(tmp_out_dir, js_out_file), - '--comments', '"/Copyright|license|LICENSE|\<\/?if/"', + '--comments', '/Copyright|license|LICENSE|\<\/?if/', '--output', os.path.join(out_path, js_out_file)]) finally: shutil.rmtree(tmp_out_dir) diff --git a/chromium/chrome/browser/resources/pdf/BUILD.gn b/chromium/chrome/browser/resources/pdf/BUILD.gn index 02cef40417b..1cbb07a1080 100644 --- a/chromium/chrome/browser/resources/pdf/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/BUILD.gn @@ -48,7 +48,10 @@ js_library("constants") { } js_library("gesture_detector") { - deps = [ "//ui/webui/resources/js/cr:event_target.m" ] + deps = [ + ":constants", + "//ui/webui/resources/js/cr:event_target.m", + ] } js_library("open_pdf_params_parser") { @@ -110,10 +113,13 @@ js_library("ink_controller") { ] } +js_library("local_storage_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] +} + js_library("controller") { deps = [ ":viewport", - "elements:viewer-pdf-toolbar", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:promise_resolver.m", @@ -148,16 +154,17 @@ js_library("pdf_viewer") { ":constants", ":controller", ":ink_controller", + ":local_storage_proxy", ":metrics", ":navigator", ":pdf_scripting_api", ":pdf_viewer_base", ":pdf_viewer_utils", ":toolbar_manager", - ":viewport", "elements:viewer-error-screen", "elements:viewer-password-screen", "elements:viewer-pdf-toolbar", + "elements:viewer-pdf-toolbar-new", "elements:viewer-zoom-toolbar", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:event_tracker.m", @@ -212,6 +219,7 @@ js_type_check("pdf_resources") { ":controller", ":gesture_detector", ":ink_controller", + ":local_storage_proxy", ":main", ":metrics", ":navigator", diff --git a/chromium/chrome/browser/resources/pdf/constants.js b/chromium/chrome/browser/resources/pdf/constants.js index 475061b73ae..3e2d1f38cd3 100644 --- a/chromium/chrome/browser/resources/pdf/constants.js +++ b/chromium/chrome/browser/resources/pdf/constants.js @@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** @enum {string} */ +export const DisplayAnnotationsAction = { + DISPLAY_ANNOTATIONS: 'display-annotations', + HIDE_ANNOTATIONS: 'hide-annotations', +}; + /** * Enumeration of page fitting types. * @enum {string} @@ -14,15 +20,6 @@ export const FittingType = { }; /** - * Enumeration of two up view actions. - * @enum {string} - */ -export const TwoUpViewAction = { - TWO_UP_VIEW_ENABLE: 'two-up-view-enable', - TWO_UP_VIEW_DISABLE: 'two-up-view-disable', -}; - -/** * Enumeration of save message request types. Must Match SaveRequestType in * pdf/out_of_process_instance.h. * @enum {number} @@ -32,3 +29,6 @@ export const SaveRequestType = { ORIGINAL: 1, EDITED: 2, }; + +/** @typedef {{x: number, y: number}} */ +export let Point; diff --git a/chromium/chrome/browser/resources/pdf/controller.js b/chromium/chrome/browser/resources/pdf/controller.js index 95c02f1fa0d..5fcc87da839 100644 --- a/chromium/chrome/browser/resources/pdf/controller.js +++ b/chromium/chrome/browser/resources/pdf/controller.js @@ -7,10 +7,10 @@ import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_t import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; -import {SaveRequestType} from './constants.js'; -import {PartialPoint, Point, Viewport} from './viewport.js'; +import {Point, SaveRequestType} from './constants.js'; +import {PartialPoint, Viewport} from './viewport.js'; -/** @typedef {{ type: string }} */ +/** @typedef {{type: string, messageId: (string|undefined)}} */ export let MessageData; /** @@ -72,7 +72,16 @@ export class ContentController { /** @abstract */ rotateCounterclockwise() {} - /** @abstract */ + /** + * @param {boolean} displayAnnotations + * @abstract + */ + setDisplayAnnotations(displayAnnotations) {} + + /** + * @param {boolean} enableTwoUpView + * @abstract + */ setTwoUpView(enableTwoUpView) {} /** Triggers printing of the current document. */ @@ -142,6 +151,23 @@ export class PluginController extends ContentController { /** @private {!EventTarget} */ this.eventTarget_ = new EventTarget(); + + /** + * Counter for use with createUid + * @private {number} + */ + this.uidCounter_ = 1; + + /** @private {!Map<string, !PromiseResolver>} */ + this.requestResolverMap_ = new Map(); + } + + /** + * @return {number} A new unique ID. + * @private + */ + createUid_() { + return this.uidCounter_++; } /** @return {!EventTarget} */ @@ -150,6 +176,14 @@ export class PluginController extends ContentController { } /** + * @param {number} x + * @param {number} y + */ + updateScroll(x, y) { + this.postMessage_({type: 'updateScroll', x, y}); + } + + /** * Notify the plugin to stop reacting to scroll events while zoom is taking * place to avoid flickering. * @override @@ -212,6 +246,22 @@ export class PluginController extends ContentController { this.plugin_.postMessage(message); } + /** + * Post a message to the PPAPI plugin, for cases where direct response is + * expected from the PPAPI plugin. + * @param {!MessageData} message + * @return {!Promise} A promise holding the response from the PPAPI plugin. + * @private + */ + postMessageWithReply_(message) { + const promiseResolver = new PromiseResolver(); + message.messageId = `${message.type}_${this.createUid_()}`; + this.requestResolverMap_.set(message.messageId, promiseResolver); + this.postMessage_(message); + return promiseResolver.promise; + } + + /** @override */ rotateClockwise() { this.postMessage_({type: 'rotateClockwise'}); @@ -223,6 +273,14 @@ export class PluginController extends ContentController { } /** @override */ + setDisplayAnnotations(displayAnnotations) { + this.postMessage_({ + type: 'displayAnnotations', + display: displayAnnotations, + }); + } + + /** @override */ setTwoUpView(enableTwoUpView) { this.postMessage_({ type: 'setTwoUpView', @@ -240,7 +298,7 @@ export class PluginController extends ContentController { } getSelectedText() { - this.postMessage_({type: 'getSelectedText'}); + return this.postMessageWithReply_({type: 'getSelectedText'}); } /** @param {!PrintPreviewParams} printPreviewParams */ @@ -281,7 +339,7 @@ export class PluginController extends ContentController { /** @param {string} destination */ getNamedDestination(destination) { - this.postMessage_({ + return this.postMessageWithReply_({ type: 'getNamedDestination', namedDestination: destination, }); @@ -326,6 +384,18 @@ export class PluginController extends ContentController { */ handlePluginMessage_(messageEvent) { const messageData = /** @type {!MessageData} */ (messageEvent.data); + + // Handle case where this Plugin->Page message is a direct response + // to a previous Page->Plugin message + if (messageData.messageId !== undefined) { + const resolver = + this.requestResolverMap_.get(messageData.messageId) || null; + assert(resolver !== null); + this.requestResolverMap_.delete(messageData.messageId); + resolver.resolve(messageData); + return; + } + switch (messageData.type) { case 'email': const emailData = /** @type {!EmailMessageData} */ (messageData); diff --git a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn index 0eaa9db89f2..ae60e1fae85 100644 --- a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn +++ b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn @@ -9,18 +9,24 @@ js_type_check("closure_compile") { is_polymer3 = true deps = [ ":viewer-bookmark", + ":viewer-document-outline", + ":viewer-download-controls", ":viewer-error-screen", ":viewer-page-indicator", ":viewer-page-selector", ":viewer-password-screen", + ":viewer-pdf-sidenav", ":viewer-pdf-toolbar", ":viewer-pdf-toolbar-new", + ":viewer-thumbnail", + ":viewer-thumbnail-bar", ":viewer-toolbar-dropdown", ":viewer-zoom-button", ":viewer-zoom-toolbar", ] if (is_chromeos) { deps += [ + ":viewer-annotations-bar", ":viewer-form-warning", ":viewer-ink-host", ":viewer-pen-options", @@ -35,10 +41,37 @@ js_library("viewer-bookmark") { ] } +js_library("viewer-document-outline") { + deps = [ + ":viewer-bookmark", + "..:bookmark_type", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("viewer-download-controls") { + deps = [ + "..:constants", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + ] +} + js_library("viewer-error-screen") { deps = [ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m" ] } +js_library("viewer-annotations-bar") { + deps = [ + ":viewer-pen-options", + ":viewer-toolbar-dropdown", + "..:annotation_tool", + "..:ink_controller", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:event_tracker.m", + ] +} + if (is_chromeos) { js_library("viewer-form-warning") { deps = [ @@ -64,7 +97,6 @@ js_library("viewer-page-indicator") { } js_library("viewer-page-selector") { - deps = [ "//ui/webui/resources/cr_elements/cr_input:cr_input.m" ] } js_library("viewer-password-screen") { @@ -74,14 +106,24 @@ js_library("viewer-password-screen") { ] } +js_library("viewer-pdf-sidenav") { + deps = [ + ":viewer-document-outline", + ":viewer-thumbnail-bar", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", + ] +} + js_library("viewer-pdf-toolbar") { deps = [ + ":viewer-annotations-bar", ":viewer-bookmark", + ":viewer-download-controls", ":viewer-page-selector", ":viewer-toolbar-dropdown", - "..:annotation_tool", "..:constants", - "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "..:ink_controller", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:promise_resolver.m", @@ -91,6 +133,7 @@ js_library("viewer-pdf-toolbar") { js_library("viewer-pdf-toolbar-new") { deps = [ + ":viewer-download-controls", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] } @@ -98,6 +141,19 @@ js_library("viewer-pdf-toolbar-new") { js_library("viewer-pen-options") { } +js_library("viewer-thumbnail") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +js_library("viewer-thumbnail-bar") { + deps = [ + ":viewer-thumbnail", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + js_library("viewer-toolbar-dropdown") { deps = [] } @@ -107,6 +163,7 @@ js_library("viewer-zoom-toolbar") { ":viewer-zoom-button", "..:constants", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:util.m", ] } @@ -118,19 +175,26 @@ html_to_js("web_components") { js_files = [ "icons.js", "shared-vars.js", + "shared-css.js", "viewer-bookmark.js", + "viewer-document-outline.js", + "viewer-download-controls.js", "viewer-error-screen.js", "viewer-page-indicator.js", "viewer-page-selector.js", "viewer-password-screen.js", + "viewer-pdf-sidenav.js", "viewer-pdf-toolbar.js", "viewer-pdf-toolbar-new.js", + "viewer-thumbnail.js", + "viewer-thumbnail-bar.js", "viewer-toolbar-dropdown.js", "viewer-zoom-button.js", "viewer-zoom-toolbar.js", ] if (is_chromeos) { js_files += [ + "viewer-annotations-bar.js", "viewer-form-warning.js", "viewer-ink-host.js", "viewer-pen-options.js", diff --git a/chromium/chrome/browser/resources/pdf/elements/icons.html b/chromium/chrome/browser/resources/pdf/elements/icons.html index f24a50a97e2..183bfc71c74 100644 --- a/chromium/chrome/browser/resources/pdf/elements/icons.html +++ b/chromium/chrome/browser/resources/pdf/elements/icons.html @@ -8,14 +8,21 @@ <g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></g> <g id="bookmark"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"></path></g> <g id="bookmark-border"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"></path></g> + <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g> <g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path></g> + <g id="doc-outline"><path d="M0 0h24v24H0z" fill="none"></path><path d="M19 5v14H5V5h14m1.1-2H3.9c-.5 0-.9.4-.9.9v16.2c0 .4.4.9.9.9h16.2c.4 0 .9-.5.9-.9V3.9c0-.5-.5-.9-.9-.9zM11 7h6v2h-6V7zm0 4h6v2h-6v-2zm0 4h6v2h-6zM7 7h2v2H7zm0 4h2v2H7zm0 4h2v2H7z"></path></g> <g id="eraser"><path d="M21.41,11.33 L13.04,20 L4.73,20 L2.58,17.86 C1.8,17.08 1.8,15.83 2.58,15.04 L13.62,3.58 C14.4,2.81 15.68,2.81 16.46,3.58 L21.41,8.51 C22.2,9.29 22.2,10.55 21.41,11.33 L21.41,11.33 Z"></path><polygon points="17.26 18 15.26 20 21.96 20 21.96 18"></polygon></g> + <g id="fit-to-height"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 10l3.01-4.5L15 10H9zm0 4h6l-2.99 4.5L9 14zm-6 5.01h18V4.99H3v14.02z"></path></g> + <g id="fit-to-width"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM3.5 12.01L8 9v6l-4.5-2.99zM16 15V9l4.5 3.01L16 15zM3 19.01h18V4.99H3v14.02z"></path></g> <g id="fullscreen-exit"><path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"></path></g> <g id="highlighter"><path d="M10.22,9.49 L4.31,15.49 C3.54,16.29 3.61,17.54 4.39,18.34 L0.77,22 L6.45,22 L7.19,21.25 C7.97,22.06 9.14,22.11 9.92,21.3 L15.88,15.25 L10.22,9.49 L10.22,9.49 Z"></path><path style="fill: var(--pen-tip-fill)" d="M22.68,5.49 L19.86,2.62 C19.08,1.82 17.79,1.78 17.02,2.58 L11.27,8.43 L16.93,14.18 L22.62,8.4 C23.39,7.59 23.45,6.29 22.68,5.49 L22.68,5.49 Z"></path><path style="fill: var(--pen-tip-border)" d="M18.4,3c0.3,0,0.5,0.1,0.7,0.3L22,6.2c0.4,0.4,0.4,1.1-0.1,1.5l-5,5.1l-4.3-4.3l5.1-5.2 C17.9,3.1,18.1,3,18.4,3 M18.4,2c-0.5,0-1,0.2-1.4,0.6l-5.8,5.9l5.7,5.8l5.7-5.8c0.8-0.8,0.8-2.1,0.1-2.9l-2.8-2.9 C19.5,2.2,18.9,2,18.4,2L18.4,2z"></path></g> <g id="marker"><polygon points="3 17.25 3 21 6.74 21 14.28 13.47 10.53 9.72"></polygon><path style="fill: var(--pen-tip-fill)" d="M18.37,3.3 L20.71,5.63 C21.1,6.02 21.11,6.66 20.72,7.05 L15.35,12.41 L11.59,8.65 L14.12,6.12 L13.39,5.39 L7.73,11.05 L6.33,9.65 L12.7,3.29 C13.09,2.9 13.74,2.91 14.12,3.3 L15.54,4.71 L16.96,3.3 C17.34,2.91 17.98,2.91 18.37,3.3 L18.37,3.3 Z"></path><path style="fill: var(--pen-tip-border)" d="M17.7,4L20,6.3L15.4,11L13,8.6l1.8-1.8l0.7-0.7l-0.7-0.7l-0.2-0.2l0.2,0.2l0.7,0.7l0.7-0.7L17.7,4 M13.4,3 c-0.3,0-0.5,0.1-0.7,0.3L6.3,9.6l1.4,1.4l5.7-5.7l0.7,0.7l-2.5,2.5l3.8,3.8L20.7,7c0.4-0.4,0.4-1,0-1.4l-2.3-2.3 C18.2,3.1,17.9,3,17.7,3S17.2,3.1,17,3.3l-1.4,1.4l-1.4-1.4C13.9,3.1,13.7,3,13.4,3L13.4,3z"></path></g> + <g id="open-book"><path d="M-74 29h48v48h-48V29zM0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"></path><path d="M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z"></path></g> <g id="redo"><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"></path></g> <g id="remove"><path d="M19 13H5v-2h14v2z"></path></g> + <g id="rotate-left"><path d="M0 0h24v24H0z" fill="none"></path><path d="M7.34 6.41L.86 12.9l6.49 6.48 6.49-6.48-6.5-6.49zM3.69 12.9l3.66-3.66L11 12.9l-3.66 3.66-3.65-3.66zm15.67-6.26C17.61 4.88 15.3 4 13 4V.76L8.76 5 13 9.24V6c1.79 0 3.58.68 4.95 2.05 2.73 2.73 2.73 7.17 0 9.9C16.58 19.32 14.79 20 13 20c-.97 0-1.94-.21-2.84-.61l-1.49 1.49C10.02 21.62 11.51 22 13 22c2.3 0 4.61-.88 6.36-2.64 3.52-3.51 3.52-9.21 0-12.72z"></path></g> <g id="rotate-right"><path d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"></path></g> + <g id="thumbnails"><path d="M0 0h24v24H0z" fill="none"></path><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-5.04-6.71l-2.75 3.54-1.96-2.36L6.5 17h11l-3.54-4.71z"></path></g> <g id="undo"><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></g> </defs> </svg> diff --git a/chromium/chrome/browser/resources/pdf/elements/shared-css.html b/chromium/chrome/browser/resources/pdf/elements/shared-css.html new file mode 100644 index 00000000000..365abede038 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/shared-css.html @@ -0,0 +1,30 @@ +<template> + <style> + cr-icon-button { + --cr-icon-button-fill-color: var(--pdf-toolbar-text-color); + margin: 0; + } + + cr-icon-button:hover { + background: rgba(255, 255, 255, 0.08); + border-radius: 50%; + } + + /* Dark mode styles copied from + ui/webui/resources/cr_elements/shared_vars_css.html. Unfortunately there + seems to be no great way to share styles with the + "prefers-color-scheme: dark" @media query selector. */ + :host-context([pdf-viewer-update-enabled]) cr-action-menu, + :host-context([pdf-viewer-update-enabled]) viewer-bookmark { + --cr-menu-background-color: var(--google-grey-900); + --cr-menu-shadow: rgba(0, 0, 0, .3) 0 1px 2px 0, + rgba(0, 0, 0, .15) 0 3px 6px 2px; + --cr-primary-text-color: var(--google-grey-200); + --cr-menu-background-focus-color: rgba(var(--google-grey-800-rgb), .6); + --cr-menu-background-sheen: rgba(255, 255, 255, .06); + --cr-separator-line: var(--cr-separator-height) solid + rgba(255, 255, 255, .1); + } + + </style> +</template> diff --git a/chromium/chrome/browser/resources/pdf/elements/shared-css.js b/chromium/chrome/browser/resources/pdf/elements/shared-css.js new file mode 100644 index 00000000000..4836848cf2e --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/shared-css.js @@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; + +const template = document.createElement('template'); +template.innerHTML = ` +<dom-module id="pdf-shared">{__html_template__}</dom-module> +`; +document.body.appendChild(template.content.cloneNode(true)); diff --git a/chromium/chrome/browser/resources/pdf/elements/shared-vars.html b/chromium/chrome/browser/resources/pdf/elements/shared-vars.html index 8a720055d0f..0858fafba66 100644 --- a/chromium/chrome/browser/resources/pdf/elements/shared-vars.html +++ b/chromium/chrome/browser/resources/pdf/elements/shared-vars.html @@ -4,6 +4,7 @@ --iron-icon-height: 20px; --iron-icon-width: 20px; --viewer-icon-ink-color: rgb(189, 189, 189); + --viewer-pdf-toolbar-background-color: rgb(50, 54, 57); } </style> </custom-style> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.html new file mode 100644 index 00000000000..8cc2a83c8eb --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.html @@ -0,0 +1,103 @@ +<style include="pdf-shared"> + :host { + align-items: center; + background-color: rgb(32, 33, 34); + color: var(--pdf-toolbar-text-color); + display: flex; + height: 48px; + justify-content: center; + padding: 0 16px; + } + + #pen, + #highlighter { + --dropdown-width: 346px; + } + + #pen, + #highlighter { + --dropdown-open-background: var(--pdf-viewer-background-color); + } + + #eraser { + opacity: 0.38; + } + + #eraser[selected], + #eraser:focus, + #eraser:hover { + opacity: 1; + } + + #annotation-separator { + background: white; + height: 30px; + margin-inline-end: 12px; + margin-inline-start: 12px; + opacity: 0.38; + width: 1px; + } + + #pen { + margin-inline-end: 10px; + } + + #highlighter { + margin-inline-end: 6px; + } +</style> +<viewer-toolbar-dropdown id="pen" + selected$="[[isAnnotationTool_('pen', annotationTool_.tool)]]" + open-after-select + on-click="annotationToolClicked_" + open-icon="pdf:marker" + closed-icon="pdf:marker" + dropdown-centered + hide-header + header="$i18n{annotationPen}" + style="--pen-tip-fill: #000000"> + <viewer-pen-options + selected-color="#000000" + selected-size="0.1429" + strings="[[strings]]" + on-selected-size-changed="annotationToolOptionChanged_" + on-selected-color-changed="annotationToolOptionChanged_"> + </viewer-pen-options> +</viewer-toolbar-dropdown> + +<viewer-toolbar-dropdown id="highlighter" + selected$="[[isAnnotationTool_('highlighter', annotationTool_.tool)]]" + open-after-select + on-click="annotationToolClicked_" + open-icon="pdf:highlighter" + closed-icon="pdf:highlighter" + dropdown-centered + hide-header + header="$i18n{annotationHighlighter}" + style="--pen-tip-fill: #ffbc00"> + <viewer-pen-options + selected-color="#ffbc00" + selected-size="0.7143" + strings="[[strings]]" + on-selected-size-changed="annotationToolOptionChanged_" + on-selected-color-changed="annotationToolOptionChanged_"> + </viewer-pen-options> +</viewer-toolbar-dropdown> + +<cr-icon-button id="eraser" + selected$="[[isAnnotationTool_('eraser', annotationTool_.tool)]]" + on-click="annotationToolClicked_" iron-icon="pdf:eraser" + aria-label$="$i18n{annotationEraser}" + title="$i18n{annotationEraser}"></cr-icon-button> + +<div id="annotation-separator"></div> + +<cr-icon-button id="undo" disabled="[[!canUndoAnnotation_]]" + iron-icon="pdf:undo" on-click="onUndoClick_" + aria-label$="$i18n{annotationUndo}" + title="$i18n{annotationUndo}"></cr-icon-button> + +<cr-icon-button id="redo" disabled="[[!canRedoAnnotation_]]" + iron-icon="pdf:redo" on-click="onRedoClick_" + aria-label$="$i18n{annotationRedo}" + title="$i18n{annotationRedo}"></cr-icon-button> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js new file mode 100644 index 00000000000..f502a1441be --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-annotations-bar.js @@ -0,0 +1,171 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/icons.m.js'; +import './icons.js'; +import './shared-css.js'; +import './viewer-toolbar-dropdown.js'; +import './viewer-pen-options.js'; + +import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {InkController} from '../ink_controller.js'; + +export class ViewerAnnotationsBarElement extends PolymerElement { + static get is() { + return 'viewer-annotations-bar'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + annotationMode: { + type: Boolean, + observer: 'onAnnotationModeChanged_', + }, + + /** @type {?InkController} */ + inkController: { + type: Object, + observer: 'onInkControllerSet_', + }, + + /** @private {?AnnotationTool} */ + annotationTool_: Object, + + /** @private */ + canUndoAnnotation_: Boolean, + + /** @private */ + canRedoAnnotation_: Boolean, + }; + } + + constructor() { + super(); + + /** @private {!EventTracker} */ + this.tracker_ = new EventTracker(); + } + + /** @private */ + onInkControllerSet_() { + if (!this.inkController) { + return; + } + + this.tracker_.add( + this.inkController.getEventTarget(), 'set-annotation-undo-state', + e => this.setAnnotationUndoState_(e)); + this.tracker_.add(this.inkController.getEventTarget(), 'loaded', () => { + if (this.annotationTool_) { + this.inkController.setAnnotationTool(this.annotationTool_); + } + }); + } + + /** + * @param {!CustomEvent<{canUndo: boolean, canRedo: boolean}>} e + * @private + */ + setAnnotationUndoState_(e) { + this.canUndoAnnotation_ = e.detail.canUndo; + this.canRedoAnnotation_ = e.detail.canRedo; + } + + /** @private */ + onUndoClick_() { + this.inkController.undo(); + } + + /** @private */ + onRedoClick_() { + this.inkController.redo(); + } + + /** @private */ + onAnnotationModeChanged_() { + if (this.annotationMode) { + // Select pen tool when entering annotation mode. + this.updateAnnotationTool_(/** @type {!ViewerToolbarDropdownElement} */ ( + this.shadowRoot.querySelector('#pen'))); + } + } + + /** + * @param {!Event} e + * @private + */ + annotationToolClicked_(e) { + this.updateAnnotationTool_(/** @type {!HTMLElement} */ (e.currentTarget)); + } + + /** + * @param {!Event} e + * @private + */ + annotationToolOptionChanged_(e) { + const element = e.currentTarget.parentElement; + if (!this.annotationTool_ || element.id !== this.annotationTool_.tool) { + return; + } + this.updateAnnotationTool_(e.currentTarget.parentElement); + } + + /** + * @param {!HTMLElement} element + * @private + */ + updateAnnotationTool_(element) { + const tool = element.id; + const options = element.querySelector('viewer-pen-options') || { + selectedSize: 1, + selectedColor: undefined, + }; + const attributeStyleMap = element.attributeStyleMap; + attributeStyleMap.set('--pen-tip-fill', options.selectedColor); + attributeStyleMap.set( + '--pen-tip-border', + options.selectedColor === '#000000' ? 'currentcolor' : + options.selectedColor); + this.annotationTool_ = { + tool: tool, + size: options.selectedSize, + color: options.selectedColor, + }; + this.inkController.setAnnotationTool(this.annotationTool_); + } + + /** + * @param {string} toolName + * @return {boolean} Whether the annotation tool is using tool |toolName|. + * @private + */ + isAnnotationTool_(toolName) { + return !!this.annotationTool_ && this.annotationTool_.tool === toolName; + } + + /** @return {!NodeList<!ViewerToolbarDropdownElement>} */ + getOpenDropdowns_() { + return /** @type {!NodeList<!ViewerToolbarDropdownElement>} */ ( + this.shadowRoot.querySelectorAll( + 'viewer-toolbar-dropdown[dropdown-open]')); + } + + /** @return {boolean} Whether one of the dropdowns is open. */ + hasOpenDropdown() { + return this.getOpenDropdowns_().length > 0; + } + + closeDropdowns() { + this.getOpenDropdowns_().forEach(element => element.toggleDropdown()); + } +} +customElements.define( + ViewerAnnotationsBarElement.is, ViewerAnnotationsBarElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html index 8cf60ea1aa7..91a898dc3e8 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html @@ -7,6 +7,10 @@ position: relative; } + :host-context([pdf-viewer-update-enabled]) #item { + height: initial; + } + #item:hover { background-color: var(--cr-menu-background-focus-color); } @@ -27,6 +31,10 @@ white-space: nowrap; } + :host-context([pdf-viewer-update-enabled]) #title { + white-space: initial; + } + #expand { --cr-icon-button-fill-color: var(--primary-text-color); --cr-icon-button-icon-size: 16px; diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.html b/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.html new file mode 100644 index 00000000000..775ae40ed1d --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.html @@ -0,0 +1,10 @@ +<style include="pdf-shared"> + :host { + display: block; + padding-inline-end: 20px; + padding-top: 20px; + } +</style> +<template is="dom-repeat" items="[[bookmarks]]"> + <viewer-bookmark bookmark="[[item]]" depth="0"></viewer-bookmark> +</template> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.js b/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.js new file mode 100644 index 00000000000..222d3d37f46 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-document-outline.js @@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './shared-css.js'; +import './viewer-bookmark.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Bookmark} from '../bookmark_type.js'; + +export class ViewerDocumentOutlineElement extends PolymerElement { + static get is() { + return 'viewer-document-outline'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** @type {!Array<!Bookmark>} */ + bookmarks: Array, + }; + } +} + +customElements.define( + ViewerDocumentOutlineElement.is, ViewerDocumentOutlineElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.html b/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.html new file mode 100644 index 00000000000..33845416e3b --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.html @@ -0,0 +1,23 @@ +<style include="pdf-shared"> + cr-action-menu::part(dialog) { + position: fixed; + top: 48px; + } + + :host([menu-open_]) #download { + background-color: var(--active-button-bg); + border-radius: 50%; + } +</style> +<cr-icon-button id="download" iron-icon="cr:file-download" + on-click="onDownloadClick_" aria-label$="$i18n{tooltipDownload}" + aria-haspopup$="[[downloadHasPopup_]]" + title="$i18n{tooltipDownload}"></cr-icon-button> +<cr-action-menu id="menu" on-close="onMenuClose_"> + <button class="dropdown-item" on-click="onDownloadEditedClick_"> + $i18n{downloadEdited} + </button> + <button class="dropdown-item" on-click="onDownloadOriginalClick_"> + $i18n{downloadOriginal} + </button> +</cr-action-menu> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.js b/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.js new file mode 100644 index 00000000000..e7629deaf9e --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-download-controls.js @@ -0,0 +1,190 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/icons.m.js'; +import './icons.js'; +import './shared-css.js'; + +import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {SaveRequestType} from '../constants.js'; + +export class ViewerDownloadControlsElement extends PolymerElement { + static get is() { + return 'viewer-download-controls'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + hasEdits: Boolean, + + hasEnteredAnnotationMode: Boolean, + + isFormFieldFocused: { + type: Boolean, + observer: 'onFormFieldFocusedChanged_', + }, + + pdfFormSaveEnabled: Boolean, + + downloadHasPopup_: { + type: String, + computed: 'computeDownloadHasPopup_(' + + 'pdfFormSaveEnabled, hasEdits, hasEnteredAnnotationMode)', + }, + + /** @private */ + menuOpen_: { + type: Boolean, + reflectToAttribute: true, + value: false, + }, + }; + } + + constructor() { + super(); + + // Polymer properties + /** @private {string} */ + this.downloadHasPopup_; + + /** @type {boolean} */ + this.hasEdits; + + /** @type {boolean} */ + this.hasEnteredAnnotationMode; + + /** @type {boolean} */ + this.isFormFieldFocused; + + /** @type {boolean} */ + this.pdfFormSaveEnabled; + + // Non-Polymer properties + /** @private {?PromiseResolver<boolean>} */ + this.waitForFormFocusChange_ = null; + } + + /** @return {boolean} */ + isMenuOpen() { + return this.menuOpen_; + } + + closeMenu() { + this.getDownloadMenu_().close(); + } + + /** @private */ + onMenuClose_() { + this.menuOpen_ = false; + } + + /** + * @return {boolean} + * @private + */ + hasEditsToSave_() { + return this.hasEnteredAnnotationMode || + (this.pdfFormSaveEnabled && this.hasEdits); + } + + /** + * @return {string} The value for the aria-haspopup attribute for the download + * button. + * @private + */ + computeDownloadHasPopup_() { + return this.hasEditsToSave_() ? 'menu' : 'false'; + } + + /** + * @return {!CrActionMenuElement} + * @private + */ + getDownloadMenu_() { + return /** @type {!CrActionMenuElement} */ ( + this.shadowRoot.querySelector('#menu')); + } + + /** @private */ + showDownloadMenu_() { + this.menuOpen_ = true; + this.getDownloadMenu_().showAt(this.$.download, { + anchorAlignmentX: AnchorAlignment.CENTER, + }); + // For tests + this.dispatchEvent(new CustomEvent( + 'download-menu-shown-for-testing', {bubbles: true, composed: true})); + } + + /** @private */ + onDownloadClick_() { + this.waitForEdits_().then(hasEdits => { + if (hasEdits) { + this.showDownloadMenu_(); + } else { + this.dispatchSaveEvent_(SaveRequestType.ORIGINAL); + } + }); + } + + /** + * @return {!Promise<boolean>} Promise that resolves with true if the PDF has + * edits and/or annotations, and false otherwise. + * @private + */ + waitForEdits_() { + if (this.hasEditsToSave_()) { + return Promise.resolve(true); + } + if (!this.isFormFieldFocused || !this.pdfFormSaveEnabled) { + return Promise.resolve(false); + } + this.waitForFormFocusChange_ = new PromiseResolver(); + return this.waitForFormFocusChange_.promise; + } + + /** @private */ + onFormFieldFocusedChanged_() { + if (!this.waitForFormFocusChange_) { + return; + } + + this.waitForFormFocusChange_.resolve(this.hasEdits); + this.waitForFormFocusChange_ = null; + } + + /** + * @param {!SaveRequestType} type + * @private + */ + dispatchSaveEvent_(type) { + this.dispatchEvent( + new CustomEvent('save', {detail: type, bubbles: true, composed: true})); + } + + /** @private */ + onDownloadOriginalClick_() { + this.dispatchSaveEvent_(SaveRequestType.ORIGINAL); + this.getDownloadMenu_().close(); + } + + /** @private */ + onDownloadEditedClick_() { + this.dispatchSaveEvent_( + this.hasEnteredAnnotationMode ? SaveRequestType.ANNOTATION : + SaveRequestType.EDITED); + this.getDownloadMenu_().close(); + } +} +customElements.define( + ViewerDownloadControlsElement.is, ViewerDownloadControlsElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html index 002a23ad3fc..14116b48435 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html @@ -3,6 +3,7 @@ color: #fff; display: flex; font-size: 0.81rem; + text-align: center; --page-selector-spacing: 4px; } @@ -11,7 +12,7 @@ background: rgba(255, 255, 255, 0.3); } - #pageselector::part(input), + input, #pagelength { /* --page-length-digits is set through JavaScript. 1px is added because * the unit 'ch' does not provide exact whole number pixels, and @@ -19,28 +20,23 @@ width: calc(max(2, var(--page-length-digits)) * 1ch + 1px); } - #pageselector { - --cr-input-background-color: transparent; - --cr-input-border-radius: 0; - --cr-input-color: white; - --cr-input-error-display: none; - --cr-input-focus-color: transparent; - } - - #pageselector::part(input) { + input { background: rgba(0, 0, 0, 0.5); - box-sizing: content-box; - caret-color: var(--cr-input-color); + border: none; + color: white; + font-family: inherit; + line-height: inherit; + outline: none; padding: 0 var(--page-selector-spacing); + text-align: center; } #divider { margin: 0 var(--page-selector-spacing); } </style> - <cr-input id="pageselector" value="[[pageNo]]" on-mouseup="select" - on-value-changed="onInputValueChange_" on-change="pageNoCommitted" + <input type="text" id="pageselector" value="[[pageNo]]" on-mouseup="select" + on-input="onInput_" on-change="pageNoCommitted" aria-label$="$i18n{labelPageNumber}"> - </cr-input> <span id="divider">/</span> <span id="pagelength">[[docLength]]</span> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js index 6b8b55ad3dc..8634e24aace 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; - import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; Polymer({ @@ -28,9 +26,9 @@ Polymer({ }, }, - /** @return {!CrInputElement} */ + /** @return {!HTMLInputElement} */ get pageSelector() { - return /** @type {!CrInputElement} */ (this.$.pageselector); + return /** @type {!HTMLInputElement} */ (this.$.pageselector); }, pageNoCommitted() { @@ -65,7 +63,7 @@ Polymer({ * Immediately remove any non-digit characters. * @private */ - onInputValueChange_() { + onInput_() { this.pageSelector.value = this.pageSelector.value.replace(/[^\d]/, ''); }, }); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.html new file mode 100644 index 00000000000..d134fd53e01 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.html @@ -0,0 +1,64 @@ +<style include="pdf-shared cr-hidden-style"> + :host { + --sidenav-selected-tab-color: var(--google-blue-refresh-300); + background-color: var(--viewer-pdf-toolbar-background-color); + display: flex; + height: 100%; + min-width: var(--viewer-pdf-sidenav-width); + overflow: hidden; + width: var(--viewer-pdf-sidenav-width); + } + + #icons { + display: flex; + flex-direction: column; + min-width: 48px; + } + + /* These are dummy styles currently - replace with real content. */ + #content { + color: white; + flex: 1; + overflow-x: hidden; + } + + .selected cr-icon-button { + --cr-icon-button-fill-color: var(--sidenav-selected-tab-color); + } + + .button-wrapper { + --highlight-border-width: 4px; + align-items: center; + border-inline-start: var(--highlight-border-width) solid transparent; + display: flex; + height: var(--cr-icon-button-size); + justify-content: center; + margin: 6px 0; + width: calc(100% - var(--highlight-border-width)); + } + + .button-wrapper.selected { + border-color: var(--sidenav-selected-tab-color); + } +</style> +<div id="icons"> + <div class$="button-wrapper [[thumbnailButtonClass_(thumbnailView_)]]"> + <cr-icon-button iron-icon="pdf:thumbnails" role="tab" + title="$i18n{tooltipThumbnails}" on-click="onThumbnailClick_"> + </cr-icon-button> + </div> + <div class$="button-wrapper [[outlineButtonClass_(thumbnailView_)]]" + hidden$="[[!bookmarks.length]]"> + <cr-icon-button iron-icon="pdf:doc-outline" role="tab" + title="$i18n{tooltipDocumentOutline}" on-click="onOutlineClick_"> + </cr-icon-button> + </div> +</div> +<div id="content"> + <viewer-thumbnail-bar id="thumbnail-bar" hidden="[[!thumbnailView_]]" + doc-length="[[docLength]]"> + </viewer-thumbnail-bar> + <viewer-document-outline id="outline" hidden="[[thumbnailView_]]" + bookmarks="[[bookmarks]]"> + </viewer-document-outline> +</div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.js new file mode 100644 index 00000000000..1a7fc5d1c66 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.js @@ -0,0 +1,71 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './shared-vars.js'; +import '../pdf_viewer_shared_style.js'; +import './icons.js'; +import './viewer-document-outline.js'; +import './viewer-thumbnail-bar.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/hidden_style_css.m.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Bookmark} from '../bookmark_type.js'; + +export class ViewerPdfSidenavElement extends PolymerElement { + static get is() { + return 'viewer-pdf-sidenav'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + /** @type {!Array<!Bookmark>} */ + bookmarks: { + type: Array, + value: () => [], + }, + + docLength: Number, + + /** @private */ + thumbnailView_: { + type: Boolean, + value: true, + }, + }; + } + + /** @private */ + onThumbnailClick_() { + this.thumbnailView_ = true; + } + + /** @private */ + onOutlineClick_() { + this.thumbnailView_ = false; + } + + /** + * @return {string} + * @private + */ + outlineButtonClass_() { + return this.thumbnailView_ ? '' : 'selected'; + } + + /** + * @return {string} + * @private + */ + thumbnailButtonClass_() { + return this.thumbnailView_ ? 'selected' : ''; + } +} + +customElements.define(ViewerPdfSidenavElement.is, ViewerPdfSidenavElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html index 075635defbb..245384d516c 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.html @@ -1,10 +1,233 @@ -<style> +<style include="pdf-shared"> :host { - --pdf-toolbar-background-color: rgb(50, 54, 57); - background-color: var(--pdf-toolbar-background-color); - box-shadow: var(--cr-elevation-2); + box-shadow: + 0 -2px 8px rgba(0, 0, 0, 0.09), + 0 4px 8px rgba(0, 0, 0, 0.06), + 0 1px 2px rgba(0, 0, 0, 0.3), + 0 2px 6px rgba(0, 0, 0, 0.15); + } + + #toolbar { + align-items: center; + background-color: var(--viewer-pdf-toolbar-background-color); color: white; + display: flex; height: 48px; } + + #sidenavToggle { + margin: 0 6px; + } + + #title { + font-size: 0.87rem; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + #actionMenuTrigger { + margin-inline-end: 6px; + } + + #start { + align-items: center; + display: flex; + overflow: hidden; + padding-inline-end: 20px; + } + + #start, + #end { + flex: 1; + } + + #end { + padding-inline-start: 20px; + text-align: end; + white-space: nowrap; + } + + #zoom-controls { + border-inline-end: 1px solid rgba(255, 255, 255, 0.3); + border-inline-start: 1px solid rgba(255, 255, 255, 0.3); + margin-inline-end: 12px; + margin-inline-start: 21px; + padding: 0 6px; + } + + @media(max-width: 600px) { + #title, + #zoom-controls input { + display: none; + } + } + + viewer-page-selector { + display: inline-flex; + } + + input { + background: rgba(0, 0, 0, 0.5); + border: none; + caret-color: currentColor; + color: inherit; + font-family: inherit; + line-height: inherit; + margin: 0 4px; + outline: none; + padding: 0 4px; + text-align: center; + width: 5ch; + } + + paper-progress { + --paper-progress-active-color: var(--google-blue-refresh-300); + --paper-progress-container-color: transparent; + --paper-progress-height: 3px; + bottom: 0; + position: absolute; + width: 100%; + } + + paper-progress, + #center, + #end { + transition: opacity 100ms cubic-bezier(0, 0, 0.2, 1); + } + + paper-progress, + :host([loading_]) #menuButton, + :host([loading_]) #center, + :host([loading_]) #end { + opacity: 0; + /* Ensure UI is not interactable while hidden */ + visibility: hidden; + } + + :host([loading_]) paper-progress, + #menuButton, + #center, + #end { + opacity: 1; + visibility: visible; + } + +<if expr="chromeos"> + :host([annotation-mode]) #annotate { + background-color: var(--active-button-bg); + border-radius: 50%; + } +</if> + + .dropdown-item { + padding-inline-end: 16px; + padding-inline-start: 12px; + } + + .check-container { + margin-inline-end: 12px; + width: 16px; + } + + #show-annotations-button { + border-top: var(--cr-separator-line); + } </style> -New PDF Viewer toolbar will appear here. +<!-- TODO(dpapad): Add aria-label and title for all buttons --> +<div id="toolbar"> + <div id="start"> + <cr-icon-button id="sidenavToggle" iron-icon="pdf:open-book" + on-click="onSidenavToggleClick_"> + </cr-icon-button> + <span id="title">[[docTitle]]</span> + </div> + <div id="center"> + <viewer-page-selector doc-length="[[docLength]]" page-no="[[pageNo]]"> + </viewer-page-selector> + <span id="zoom-controls"> + <cr-icon-button iron-icon="pdf:remove" title="$i18n{tooltipZoomOut}" + on-click="onZoomOutClick_"> + </cr-icon-button> + <input type="text" value="100%" on-input="onZoomInput_" + on-blur="onZoomInputBlur_"> + </input> + <cr-icon-button iron-icon="pdf:add" title="$i18n{tooltipZoomIn}" + on-click="onZoomInClick_"> + </cr-icon-button> + </span> + <cr-icon-button iron-icon="[[fitToButtonIcon_]]" + title="[[getFitToButtonTooltip_('$i18nPolymer{tooltipFitToPage}', + '$i18nPolymer{tooltipFitToWidth}', + fittingType_)]]" + on-click="onFitToButtonClick_"> + </cr-icon-button> + <cr-icon-button iron-icon="pdf:rotate-left" + disabled="[[annotationMode]]" aria-label$="$i18n{tooltipRotateCCW}" + title="$i18n{tooltipRotateCCW}" on-click="onRotateClick_"> + </cr-icon-button> + </div> + <div id="end"> + <if expr="chromeos"> + <template is="dom-if" if="[[pdfAnnotationsEnabled]]"> + <cr-icon-button id="annotate" iron-icon="pdf:create" + disabled="[[!annotationAvailable]]" on-click="toggleAnnotation" + aria-label$="$i18n{tooltipAnnotate}" + title="$i18n{tooltipAnnotate}"></cr-icon-button> + </template> + </if> + <viewer-download-controls id="downloads" + has-edits="[[hasEdits]]" + has-entered-annotation-mode="[[hasEnteredAnnotationMode]]" + is-form-field-focused="[[isFormFieldFocused]]" + pdf-form-save-enabled="[[pdfFormSaveEnabled]]"> + </viewer-download-controls> + <cr-icon-button id="print" iron-icon="cr:print" + aria-label$="$i18n{tooltipPrint}" hidden="[[!printingEnabled]]" + title="$i18n{tooltipPrint}" on-click="onPrintClick_"></cr-icon-button> + <cr-icon-button id="more" + iron-icon="cr:more-vert" on-click="onMoreClick_"></cr-icon-button> + </div> +</div> +<paper-progress id="progress" value="[[loadProgress]]" hidden="[[!loading_]]"> +</paper-progress> + +<cr-action-menu> + <button id="single-page-view-button" + class="dropdown-item" on-click="onSinglePageViewClick_" + role="radio" + aria-checked="[[getSinglePageAriaChecked_(twoUpViewEnabled_)]]"> + <span class="check-container"> + <iron-icon icon="pdf:check" hidden="[[twoUpViewEnabled_]]"></iron-icon> + </span> + $i18n{twoUpViewDisable} + </button> + <button id="two-page-view-button" + class="dropdown-item" on-click="onTwoPageViewClick_" + role="radio" + aria-checked="[[getTwoPageViewAriaChecked_(twoUpViewEnabled_)]]"> + <span class="check-container"> + <iron-icon icon="pdf:check" hidden="[[!twoUpViewEnabled_]]"></iron-icon> + </span> + $i18n{twoUpViewEnable} + </button> + + <button id="show-annotations-button" + class="dropdown-item" on-click="toggleDisplayAnnotations_" + role="checkbox" + aria-checked="[[getShowAnnotationsAriaChecked_(displayAnnotations_)]]"> + <span class="check-container"> + <iron-icon icon="pdf:check" hidden="[[!displayAnnotations_]]"></iron-icon> + </span> + $i18n{annotationsShowToggle} + </button> +</cr-action-menu> + +<if expr="chromeos"> + <template is="dom-if" if="[[showAnnotationsBar_]]"> + <viewer-annotations-bar annotation-mode="[[annotationMode]]" + ink-controller="[[inkController]]"> + </viewer-annotations-bar> + </template> +</if> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js index 06e1d118df0..dc958c82803 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar-new.js @@ -2,9 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/icons.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; +import './icons.js'; +// <if expr="chromeos"> +import './viewer-annotations-bar.js'; +// </if> +import './viewer-download-controls.js'; +import './viewer-page-selector.js'; +import './shared-css.js'; + +import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -class ViewerPdfToolbarNewElement extends PolymerElement { +import {FittingType} from '../constants.js'; +// <if expr="chromeos"> +import {InkController} from '../ink_controller.js'; +// </if> + +export class ViewerPdfToolbarNewElement extends PolymerElement { static get is() { return 'viewer-pdf-toolbar-new'; } @@ -12,6 +31,293 @@ class ViewerPdfToolbarNewElement extends PolymerElement { static get template() { return html`{__html_template__}`; } + + static get properties() { + return { + // <if expr="chromeos"> + annotationAvailable: Boolean, + // </if> + annotationMode: { + type: Boolean, + notify: true, + value: false, + reflectToAttribute: true, + }, + docTitle: String, + docLength: Number, + hasEdits: Boolean, + hasEnteredAnnotationMode: Boolean, + // <if expr="chromeos"> + /** @type {?InkController} */ + inkController: Object, + // </if> + isFormFieldFocused: Boolean, + + loadProgress: { + type: Number, + observer: 'loadProgressChanged_', + }, + + loading_: { + type: Boolean, + reflectToAttribute: true, + }, + + pageNo: Number, + pdfAnnotationsEnabled: Boolean, + pdfFormSaveEnabled: Boolean, + printingEnabled: Boolean, + viewportZoom: { + type: Number, + observer: 'viewportZoomChanged_', + }, + + twoUpViewEnabled_: Boolean, + + fittingType_: Number, + + /** @private {string} */ + fitToButtonIcon_: { + type: String, + computed: 'computeFitToButtonIcon_(fittingType_)', + }, + + // <if expr="chromeos"> + /** @private */ + showAnnotationsBar_: { + type: Boolean, + computed: 'computeShowAnnotationsBar_(' + + 'loading_, annotationMode, pdfAnnotationsEnabled)', + }, + // </if> + }; + } + + constructor() { + super(); + + /** @private {!FittingType} */ + this.fittingType_ = FittingType.FIT_TO_PAGE; + + /** @private {boolean} */ + this.loading_ = true; + + /** @private {boolean} */ + this.displayAnnotations_ = true; + + /** @private {boolean} */ + this.twoUpViewEnabled_ = false; + + /** @private {?number} */ + this.zoomTimeout_ = null; + } + + /** @private */ + onSidenavToggleClick_() { + this.dispatchEvent(new CustomEvent('sidenav-toggle-click')); + } + + /** + * @return {string} + * @private + */ + computeFitToButtonIcon_() { + return this.fittingType_ === FittingType.FIT_TO_PAGE ? 'pdf:fit-to-height' : + 'pdf:fit-to-width'; + } + + /** + * @param {string} fitToPageTooltip + * @param {string} fitToWidthTooltip + * @return {string} The appropriate tooltip for the current state + * @private + */ + getFitToButtonTooltip_(fitToPageTooltip, fitToWidthTooltip) { + return this.fittingType_ === FittingType.FIT_TO_PAGE ? fitToPageTooltip : + fitToWidthTooltip; + } + + /** @private */ + loadProgressChanged_() { + this.loading_ = this.loadProgress < 100; + } + + /** @private */ + viewportZoomChanged_() { + const zoom = Math.round(this.viewportZoom * 100); + this.getZoomInput_().value = `${zoom}%`; + } + + // <if expr="chromeos"> + /** + * @return {boolean} + * @private + */ + computeShowAnnotationsBar_() { + return this.pdfAnnotationsEnabled && !this.loading_ && this.annotationMode; + } + // </if> + + /** @private */ + onPrintClick_() { + this.dispatchEvent(new CustomEvent('print')); + } + + /** @private */ + onRotateClick_() { + this.dispatchEvent(new CustomEvent('rotate-left')); + } + + /** @private */ + toggleDisplayAnnotations_() { + this.displayAnnotations_ = !this.displayAnnotations_; + this.dispatchEvent(new CustomEvent( + 'display-annotations-changed', {detail: this.displayAnnotations_})); + + // <if expr="chromeos"> + if (!this.displayAnnotations_ && this.annotationMode) { + this.toggleAnnotation(); + } + // </if> + } + + /** + * @param {boolean} checked + * @return {string} + */ + getSinglePageAriaChecked_(checked) { + return checked ? 'false' : 'true'; + } + + /** + * @param {boolean} checked + * @return {string} + */ + getTwoPageViewAriaChecked_(checked) { + return checked ? 'true' : 'false'; + } + + /** + * @param {boolean} checked + * @return {string} + */ + getShowAnnotationsAriaChecked_(checked) { + return checked ? 'true' : 'false'; + } + + /** @private */ + onSinglePageViewClick_() { + this.twoUpViewEnabled_ = false; + this.dispatchEvent(new CustomEvent('two-up-view-changed', {detail: false})); + } + + /** @private */ + onTwoPageViewClick_() { + this.twoUpViewEnabled_ = true; + this.dispatchEvent(new CustomEvent('two-up-view-changed', {detail: true})); + } + + /** @private */ + onZoomInClick_() { + this.dispatchEvent(new CustomEvent('zoom-in')); + } + + /** @private */ + onZoomOutClick_() { + this.dispatchEvent(new CustomEvent('zoom-out')); + } + + /** @param {!FittingType} fittingType */ + forceFit(fittingType) { + // The fitting type is the new state. We want to set the button fitting type + // to the opposite value. + this.fittingType_ = fittingType === FittingType.FIT_TO_WIDTH ? + FittingType.FIT_TO_PAGE : + FittingType.FIT_TO_WIDTH; + } + + fitToggle() { + const newState = this.fittingType_ === FittingType.FIT_TO_PAGE ? + FittingType.FIT_TO_WIDTH : + FittingType.FIT_TO_PAGE; + this.dispatchEvent( + new CustomEvent('fit-to-changed', {detail: this.fittingType_})); + this.fittingType_ = newState; + } + + /** @private */ + onFitToButtonClick_() { + this.fitToggle(); + } + + /** + * @return {!HTMLInputElement} + * @private + */ + getZoomInput_() { + return /** @type {!HTMLInputElement} */ ( + this.shadowRoot.querySelector('#zoom-controls input')); + } + + /** @private */ + onZoomInput_() { + if (this.zoomTimeout_) { + clearTimeout(this.zoomTimeout_); + } + this.zoomTimeout_ = setTimeout(() => this.sendZoomChanged_(), 250); + } + + /** + * @return {boolean} Whether the zoom-changed event was sent. + * @private + */ + sendZoomChanged_() { + this.zoomTimeout_ = null; + const value = Number.parseInt(this.getZoomInput_().value, 10); + if (Number.isNaN(value)) { + return false; + } + this.dispatchEvent(new CustomEvent('zoom-changed', {detail: value})); + return true; + } + + /** @private */ + onZoomInputBlur_() { + if (this.zoomTimeout_) { + clearTimeout(this.zoomTimeout_); + } + + if (this.sendZoomChanged_()) { + return; + } + + const zoom = Math.round(this.viewportZoom * 100); + const zoomString = `${zoom}%`; + this.getZoomInput_().value = zoomString; + } + + /** @private */ + onMoreClick_() { + const menu = this.shadowRoot.querySelector('cr-action-menu'); + menu.showAt(this.shadowRoot.querySelector('#more'), { + anchorAlignmentX: AnchorAlignment.CENTER, + anchorAlignmentY: AnchorAlignment.AFTER_END, + noOffset: true, + }); + } + + // <if expr="chromeos"> + toggleAnnotation() { + this.annotationMode = !this.annotationMode; + this.dispatchEvent(new CustomEvent( + 'annotation-mode-toggled', {detail: this.annotationMode})); + + if (this.annotationMode && !this.displayAnnotations_) { + this.toggleDisplayAnnotations_(); + } + } + // </if> } + customElements.define( ViewerPdfToolbarNewElement.is, ViewerPdfToolbarNewElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.html index 51c7bc66cb5..20d8dc13637 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.html @@ -1,4 +1,4 @@ - <style include="cr-hidden-style"> + <style include="pdf-shared cr-hidden-style"> :host { --pdf-toolbar-background-color: rgb(50, 54, 57); --pdf-toolbar-text-color: rgb(241, 241, 241); @@ -27,7 +27,6 @@ } #pageselector-container { - text-align: center; /* The container resizes according to the width of the toolbar. On small * screens with large numbers of pages, overflow page numbers without * wrapping. */ @@ -40,16 +39,6 @@ user-select: none; } - cr-icon-button { - --cr-icon-button-fill-color: var(--pdf-toolbar-text-color); - margin: 6px; - } - - cr-icon-button:hover { - background: rgba(255, 255, 255, 0.08); - border-radius: 50%; - } - paper-progress { --paper-progress-active-color: var(--google-blue-300); --paper-progress-container-color: transparent; @@ -61,21 +50,11 @@ #toolbar { background-color: var(--pdf-toolbar-background-color); box-shadow: var(--cr-elevation-2); - position: relative; - } - - #annotations-bar { - align-items: center; - background-color: rgb(32, 33, 34); - justify-content: center; - } - - #toolbar, - #annotations-bar { color: var(--pdf-toolbar-text-color); display: flex; height: 48px; padding: 0 16px; + position: relative; } #progress-container { @@ -88,37 +67,8 @@ width: auto; } - #pen, - #highlighter { - --dropdown-width: 346px; - } - - #pen, - #highlighter { - --dropdown-open-background: var(--pdf-viewer-background-color); - } - - #eraser { - opacity: 0.38; - } - - #eraser[selected], - #eraser:focus, - #eraser:hover { - opacity: 1; - } - - #annotation-separator { - background: white; - height: 30px; - margin-inline-end: 12px; - margin-inline-start: 12px; - opacity: 0.38; - width: 1px; - } - :host([annotation-mode]) #annotate { - background-color: rgba(255, 255, 255, 0.24); + background-color: var(--active-button-bg); border-radius: 50%; } @@ -126,21 +76,12 @@ margin-inline-start: 8px; } - #pen { - margin-inline-end: 10px; - } - - #highlighter { - margin-inline-end: 6px; - } - .invisible { visibility: hidden; } @media(max-width: 675px) { - #bookmarks, - #rotate-left { + #bookmarks { display: none; } } @@ -157,11 +98,6 @@ display: none; } } - - cr-action-menu::part(dialog) { - position: fixed; - top: 48px; - } </style> <div id="toolbar"> <div id="aligner"> @@ -177,7 +113,7 @@ <div id="buttons" class="invisible"> <if expr="chromeos"> - <template is="dom-if" if="[[pdfAnnotationsEnabled_]]"> + <template is="dom-if" if="[[pdfAnnotationsEnabled]]"> <cr-icon-button id="annotate" iron-icon="pdf:create" disabled="[[!annotationAvailable]]" on-click="toggleAnnotation" aria-label$="$i18n{tooltipAnnotate}" @@ -189,22 +125,15 @@ disabled="[[annotationMode]]" on-click="rotateRight" aria-label$="$i18n{tooltipRotateCW}" title="$i18n{tooltipRotateCW}"></cr-icon-button> - - <cr-icon-button id="download" iron-icon="cr:file-download" - on-click="onDownloadClick_" aria-label$="$i18n{tooltipDownload}" - aria-haspopup$="[[downloadHasPopup_]]" - title="$i18n{tooltipDownload}"></cr-icon-button> - <cr-action-menu id="downloadMenu"> - <button class="dropdown-item" on-click="onDownloadEditedClick_"> - $i18n{downloadEdited} - </button> - <button class="dropdown-item" on-click="onDownloadOriginalClick_"> - $i18n{downloadOriginal} - </button> - </cr-action-menu> + <viewer-download-controls id="downloads" + has-edits="[[hasEdits]]" + has-entered-annotation-mode="[[hasEnteredAnnotationMode]]" + is-form-field-focused="[[isFormFieldFocused]]" + pdf-form-save-enabled="[[pdfFormSaveEnabled]]"> + </viewer-download-controls> <cr-icon-button id="print" iron-icon="cr:print" on-click="print" - hidden="[[!printingEnabled_]]" title="$i18n{tooltipPrint}" + hidden="[[!printingEnabled]]" title="$i18n{tooltipPrint}" aria-label$="$i18n{tooltipPrint}"></cr-icon-button> <viewer-toolbar-dropdown id="bookmarks" @@ -228,61 +157,7 @@ </div> <if expr="chromeos"> - <div id="annotations-bar" hidden> - <viewer-toolbar-dropdown id="pen" - selected$="[[isAnnotationTool_('pen', annotationTool.tool)]]" - open-after-select - on-click="annotationToolClicked_" - open-icon="pdf:marker" - closed-icon="pdf:marker" - dropdown-centered - hide-header - header="$i18n{annotationPen}" - style="--pen-tip-fill: #000000"> - <viewer-pen-options - selected-color="#000000" - selected-size="0.1429" - strings="[[strings]]" - on-selected-size-changed="annotationToolOptionChanged_" - on-selected-color-changed="annotationToolOptionChanged_"> - </viewer-pen-options> - </viewer-toolbar-dropdown> - - <viewer-toolbar-dropdown id="highlighter" - selected$="[[isAnnotationTool_('highlighter', annotationTool.tool)]]" - open-after-select - on-click="annotationToolClicked_" - open-icon="pdf:highlighter" - closed-icon="pdf:highlighter" - dropdown-centered - hide-header - header="$i18n{annotationHighlighter}" - style="--pen-tip-fill: #ffbc00"> - <viewer-pen-options - selected-color="#ffbc00" - selected-size="0.7143" - strings="[[strings]]" - on-selected-size-changed="annotationToolOptionChanged_" - on-selected-color-changed="annotationToolOptionChanged_"> - </viewer-pen-options> - </viewer-toolbar-dropdown> - - <cr-icon-button id="eraser" - selected$="[[isAnnotationTool_('eraser', annotationTool.tool)]]" - on-click="annotationToolClicked_" iron-icon="pdf:eraser" - aria-label$="$i18n{annotationEraser}" - title="$i18n{annotationEraser}"></cr-icon-button> - - <div id="annotation-separator"></div> - - <cr-icon-button id="undo" disabled="[[!canUndoAnnotation]]" - iron-icon="pdf:undo" on-click="undo" - aria-label$="$i18n{annotationUndo}" - title="$i18n{annotationUndo}"></cr-icon-button> - - <cr-icon-button id="redo" disabled="[[!canRedoAnnotation]]" - iron-icon="pdf:redo" on-click="redo" - aria-label$="$i18n{annotationRedo}" - title="$i18n{annotationRedo}"></cr-icon-button> - </div> + <viewer-annotations-bar annotation-mode="[[annotationMode]]" + ink-controller="[[inkController]]" hidden> + </viewer-annotations-bar> </if> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js index defc20f57bb..7be214611af 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js @@ -7,22 +7,22 @@ import 'chrome://resources/cr_elements/hidden_style_css.m.js'; import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; import 'chrome://resources/cr_elements/icons.m.js'; import './icons.js'; +import './shared-css.js'; import './viewer-bookmark.js'; +import './viewer-download-controls.js'; import './viewer-page-selector.js'; import './viewer-toolbar-dropdown.js'; -// <if expr="chromeos"> -import './viewer-pen-options.js'; - -// </if> import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Bookmark} from '../bookmark_type.js'; -import {SaveRequestType} from '../constants.js'; +// <if expr="chromeos"> +import {InkController} from '../ink_controller.js'; +import {ViewerAnnotationsBarElement} from './viewer-annotations-bar.js'; +// </if> Polymer({ is: 'viewer-pdf-toolbar', @@ -45,12 +45,6 @@ Polymer({ reflectToAttribute: true, }, - /** @type {?AnnotationTool} */ - annotationTool: { - type: Object, - notify: true, - }, - /** * Tree of PDF bookmarks (empty if the document has no bookmarks). * @type {!Array<!Bookmark>} @@ -60,17 +54,6 @@ Polymer({ value: () => [], }, - canRedoAnnotation: { - type: Boolean, - value: false, - }, - - canUndoAnnotation: { - type: Boolean, - value: false, - }, - - /** The number of pages in the PDF document. */ docLength: Number, /** The title of the PDF document. */ @@ -80,10 +63,12 @@ Polymer({ hasEnteredAnnotationMode: Boolean, - isFormFieldFocused: { - type: Boolean, - observer: 'onFormFieldFocusedChanged_', - }, + // <if expr="chromeos"> + /** @type {?InkController} */ + inkController: Object, + // </if> + + isFormFieldFocused: Boolean, /** The current loading progress of the PDF document (0 - 100). */ loadProgress: { @@ -97,55 +82,21 @@ Polymer({ value: true, }, - /** The number of the page being viewed (1-based). */ pageNo: Number, - /** - * Whether the PDF Annotations feature is enabled. - * @private - */ - pdfAnnotationsEnabled_: { - type: Boolean, - value: false, - }, + /** Whether the PDF Annotations feature is enabled. */ + pdfAnnotationsEnabled: Boolean, - /** - * Whether the Printing feature is enabled. - * @private - */ - printingEnabled_: { - type: Boolean, - value: false, - }, - - /** @private */ - downloadHasPopup_: { - type: String, - computed: 'computeDownloadHasPopup_(' + - 'pdfFormSaveEnabled_, hasEdits, hasEnteredAnnotationMode)', - }, + /** Whether the Printing feature is enabled. */ + printingEnabled: Boolean, - strings: { - type: Object, - observer: 'onStringsSet_', - }, - - /** - * Whether the PDF Form save feature is enabled. - * @private - */ - pdfFormSaveEnabled_: { - type: Boolean, - value: false, - }, + /** Whether the PDF Form save feature is enabled. */ + pdfFormSaveEnabled: Boolean, }, /** @type {?Object} */ animation_: null, - /** @private {?PromiseResolver<boolean>} */ - waitForFormFocusChange_: null, - /** * @param {number} newProgress * @param {number} oldProgress @@ -159,7 +110,8 @@ Polymer({ this.$.buttons.classList.toggle('invisible', !loaded); this.$.progress.style.opacity = loaded ? 0 : 1; // <if expr="chromeos"> - this.$['annotations-bar'].hidden = !loaded || !this.annotationMode; + this.$$('viewer-annotations-bar').hidden = + !loaded || !this.annotationMode; // </if> } }, @@ -210,7 +162,7 @@ Polymer({ shouldKeepOpen() { return this.$.bookmarks.dropdownOpen || this.loadProgress < 100 || this.$.pageselector.isActive() || this.annotationMode || - this.$.downloadMenu.open; + this.$.downloads.isMenuOpen(); }, /** @return {boolean} Whether a dropdown was open and was hidden. */ @@ -220,13 +172,15 @@ Polymer({ this.$.bookmarks.toggleDropdown(); result = true; } - // <if expr="chromeos"> - if (this.$.pen.dropdownOpen) { - this.$.pen.toggleDropdown(); + if (this.$.downloads.isMenuOpen()) { + this.$.downloads.closeMenu(); result = true; } - if (this.$.highlighter.dropdownOpen) { - this.$.highlighter.toggleDropdown(); + // <if expr="chromeos"> + const annotationBar = /** @type {!ViewerAnnotationsBarElement} */ ( + this.$$('viewer-annotations-bar')); + if (annotationBar.hasOpenDropdown()) { + annotationBar.closeDropdowns(); result = true; } // </if> @@ -242,171 +196,15 @@ Polymer({ this.fire('rotate-right'); }, - /** @private */ - showDownloadMenu_() { - this.$.downloadMenu.showAt(this.$.download, { - anchorAlignmentX: AnchorAlignment.CENTER, - anchorAlignmentY: AnchorAlignment.AFTER_END, - noOffset: true, - }); - // For tests - this.fire('download-menu-shown-for-testing'); - }, - - /** @private */ - onDownloadClick_() { - this.waitForEdits_().then(hasEdits => { - if (hasEdits) { - this.showDownloadMenu_(); - } else { - this.fire('save', SaveRequestType.ORIGINAL); - } - }); - }, - - /** - * @return {!Promise<boolean>} Promise that resolves with true if the PDF has - * edits and/or annotations, and false otherwise. - * @private - */ - waitForEdits_() { - if (this.hasEditsToSave_()) { - return Promise.resolve(true); - } - if (!this.isFormFieldFocused || !this.pdfFormSaveEnabled_) { - return Promise.resolve(false); - } - this.waitForFormFocusChange_ = new PromiseResolver(); - return this.waitForFormFocusChange_.promise; - }, - - /** @private */ - onFormFieldFocusedChanged_() { - if (!this.waitForFormFocusChange_) { - return; - } - - this.waitForFormFocusChange_.resolve(this.hasEdits); - this.waitForFormFocusChange_ = null; - }, - - /** @private */ - onDownloadOriginalClick_() { - this.fire('save', SaveRequestType.ORIGINAL); - this.$.downloadMenu.close(); - }, - - /** @private */ - onDownloadEditedClick_() { - this.fire( - 'save', - this.hasEnteredAnnotationMode ? SaveRequestType.ANNOTATION : - SaveRequestType.EDITED); - this.$.downloadMenu.close(); - }, - print() { this.fire('print'); }, - undo() { - this.fire('undo'); - }, - - redo() { - this.fire('redo'); - }, - + // <if expr="chromeos"> toggleAnnotation() { this.annotationMode = !this.annotationMode; - if (this.annotationMode) { - // Select pen tool when entering annotation mode. - this.updateAnnotationTool_(/** @type {!HTMLElement} */ (this.$.pen)); - } - this.dispatchEvent(new CustomEvent('annotation-mode-toggled', { - detail: { - value: this.annotationMode, - }, - })); - }, - - /** - * @param {!Event} e - * @private - */ - annotationToolClicked_(e) { - this.updateAnnotationTool_(/** @type {!HTMLElement} */ (e.currentTarget)); - }, - - /** - * @param {!Event} e - * @private - */ - annotationToolOptionChanged_(e) { - const element = e.currentTarget.parentElement; - if (!this.annotationTool || element.id !== this.annotationTool.tool) { - return; - } - this.updateAnnotationTool_(e.currentTarget.parentElement); - }, - - /** - * @param {!HTMLElement} element - * @private - */ - updateAnnotationTool_(element) { - const tool = element.id; - const options = element.querySelector('viewer-pen-options') || { - selectedSize: 1, - selectedColor: undefined, - }; - const attributeStyleMap = element.attributeStyleMap; - attributeStyleMap.set('--pen-tip-fill', options.selectedColor); - attributeStyleMap.set( - '--pen-tip-border', - options.selectedColor === '#000000' ? 'currentcolor' : - options.selectedColor); - this.annotationTool = { - tool: tool, - size: options.selectedSize, - color: options.selectedColor, - }; - }, - - /** - * @param {string} toolName - * @return {boolean} Whether the annotation tool is using tool |toolName|. - * @private - */ - isAnnotationTool_(toolName) { - return !!this.annotationTool && this.annotationTool.tool === toolName; - }, - - /** - * @return {boolean} - * @private - */ - hasEditsToSave_() { - return this.hasEnteredAnnotationMode || - (this.pdfFormSaveEnabled_ && this.hasEdits); - }, - - /** - * @return {string} The value for the aria-haspopup attribute for the download - * button. - * @private - */ - computeDownloadHasPopup_() { - return this.hasEditsToSave_() ? 'menu' : 'false'; - }, - - /** @private */ - onStringsSet_() { - assert(this.strings); - - this.pdfAnnotationsEnabled_ = - loadTimeData.getBoolean('pdfAnnotationsEnabled'); - this.pdfFormSaveEnabled_ = loadTimeData.getBoolean('pdfFormSaveEnabled'); - this.printingEnabled_ = loadTimeData.getBoolean('printingEnabled'); + this.dispatchEvent(new CustomEvent( + 'annotation-mode-toggled', {detail: this.annotationMode})); }, + // </if> }); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html new file mode 100644 index 00000000000..878bcb2bc9e --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.html @@ -0,0 +1,14 @@ +<style> + #thumbnails { + box-sizing: border-box; + height: 100%; + overflow: auto; + padding-bottom: 24px; + text-align: center; + } +</style> +<div id="thumbnails"> + <template is="dom-repeat" items="[[pageNumbers_]]"> + <viewer-thumbnail page-number="[[item]]"></viewer-thumbnail> + </template> +</div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js new file mode 100644 index 00000000000..7d09310713e --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js @@ -0,0 +1,39 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './viewer-thumbnail.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +export class ViewerThumbnailBarElement extends PolymerElement { + static get is() { + return 'viewer-thumbnail-bar'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + docLength: Number, + + /** @private {Array<number>} */ + pageNumbers_: { + type: Array, + computed: 'computePageNumbers_(docLength)', + }, + }; + } + + /** + * @return {!Array<number>} The array of page numbers. + * @private + */ + computePageNumbers_() { + return Array.from({length: this.docLength}, (_, i) => i + 1); + } +} + +customElements.define(ViewerThumbnailBarElement.is, ViewerThumbnailBarElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html new file mode 100644 index 00000000000..4e9f8ffbd00 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.html @@ -0,0 +1,23 @@ +<style> + #content { + margin-top: 24px; + } + + #pageNumber { + line-height: 1; + } + + #thumbnail { + /* TODO(crbug.com/652400): Remove background color and div size. */ + background-color: white; + height: 140px; + margin-bottom: 12px; + margin-inline-end: auto; + margin-inline-start: auto; + width: 108px; + } +</style> +<div id="content"> + <div id="thumbnail"></div> + <div id="pageNumber">[[pageNumber]]</div> +</div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js new file mode 100644 index 00000000000..cefb83d0d53 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-thumbnail.js @@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './shared-css.js'; + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +export class ViewerThumbnailElement extends PolymerElement { + static get is() { + return 'viewer-thumbnail'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return { + pageNumber: Number, + }; + } +} + +customElements.define(ViewerThumbnailElement.is, ViewerThumbnailElement); diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.html b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.html index ff49695f629..161078acd52 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.html @@ -65,7 +65,7 @@ } :host([dropdown-open]) #button { - background-color: rgba(255, 255, 255, 0.24); + background-color: var(--active-button-bg); } h1 { diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js index 3182b901947..7aea3a34cbf 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js @@ -45,8 +45,7 @@ Polymer({ reflectToAttribute: true, }, - /** @type {?Array<string>} */ - tooltips: Array, + tooltips: String, /** @private */ closed_: { @@ -67,6 +66,12 @@ Polymer({ computed: 'computeIconsArray_(icons)', }, + /** @private {!Array<string>} */ + tooltips_: { + type: Array, + computed: 'computeTooltipsArray_(tooltips)', + }, + /** * Icon currently being displayed on the FAB. * @private @@ -79,37 +84,40 @@ Polymer({ /** @private */ visibleTooltip_: { type: String, - computed: 'computeVisibleTooltip_(tooltips, activeIndex)', - } + computed: 'computeVisibleTooltip_(tooltips_, activeIndex)', + }, }, /** - * @param {string} icons Icon names in a string, delimited by spaces * @return {!Array<string>} Array of icon name strings * @private */ - computeIconsArray_(icons) { - return icons.split(' '); + computeIconsArray_() { + return this.icons.split(' '); + }, + + /** + * @return {!Array<string>} Array of tooltip strings + * @private + */ + computeTooltipsArray_() { + return this.tooltips.split(','); }, /** - * @param {!Array<string>} icons Array of icon name strings. - * @param {number} activeIndex Index of the currently active icon. * @return {string} Icon name for the currently visible icon. * @private */ - computeVisibleIcon_(icons, activeIndex) { - return icons[activeIndex]; + computeVisibleIcon_() { + return this.icons_[this.activeIndex]; }, /** - * @param {?Array<string>} tooltips Array of tooltip strings. - * @param {number} activeIndex Index of the currently active icon. * @return {string} Tooltip for the currently visible icon. * @private */ - computeVisibleTooltip_(tooltips, activeIndex) { - return tooltips === undefined ? '' : tooltips[activeIndex]; + computeVisibleTooltip_() { + return this.tooltips_ === undefined ? '' : this.tooltips_[this.activeIndex]; }, /** @private */ diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html index 341f6bbf4c7..a20b91f7e18 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html @@ -44,11 +44,7 @@ display: block; } - /* - * A larger gap between the fit button and the two-up view button - * and above the bottom two zoom buttons. - */ - #two-up-view-button, + /* A larger gap between the fit button and the bottom two zoom buttons. */ #zoom-in-button { margin-top: 24px; } @@ -60,21 +56,17 @@ </style> <div id="zoom-buttons"> <viewer-zoom-button id="fit-button" on-fabclick="fitToggle" - delay="[[fitButtonDelay_]]" + delay="100" + tooltips="$i18n{tooltipFitToPage},$i18n{tooltipFitToWidth}" keyboard-navigation-active="[[keyboardNavigationActive_]]" icons="pdf:fullscreen-exit cr:fullscreen"> </viewer-zoom-button> - <!-- TODO(crbug.com/51472): Change icons for two-up-view-button --> - <!-- once they are finalized. --> - <viewer-zoom-button id="two-up-view-button" delay="100" - disabled="[[annotationMode]]" hidden$="[[!twoUpViewEnabled_]]" - on-fabclick="twoUpViewToggle_" - keyboard-navigation-active="[[keyboardNavigationActive_]]" - icons="pdf:create pdf:eraser"></viewer-zoom-button> <viewer-zoom-button id="zoom-in-button" icons="pdf:add" + tooltips="$i18n{tooltipZoomIn}" keyboard-navigation-active="[[keyboardNavigationActive_]]" on-fabclick="zoomIn" delay="50"></viewer-zoom-button> <viewer-zoom-button id="zoom-out-button" icons="pdf:remove" + tooltips="$i18n{tooltipZoomOut}" keyboard-navigation-active="[[keyboardNavigationActive_]]" on-fabclick="zoomOut" delay="0"></viewer-zoom-button> </div> diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js index f3bab8c69e1..0120b7491a2 100644 --- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js +++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js @@ -7,19 +7,11 @@ import 'chrome://resources/cr_elements/icons.m.js'; import './icons.js'; import './viewer-zoom-button.js'; -import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {isRTL} from 'chrome://resources/js/util.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {FittingType, TwoUpViewAction} from '../constants.js'; - -/** - * @typedef {{ - * fittingType: !FittingType, - * userInitiated: boolean, - * }} - */ -export let FitToChangedEvent; +import {FittingType} from '../constants.js'; const FIT_TO_PAGE_BUTTON_STATE = 0; const FIT_TO_WIDTH_BUTTON_STATE = 1; @@ -33,28 +25,11 @@ Polymer({ _template: html`{__html_template__}`, properties: { - /** Whether the viewer is currently in annotation mode. */ - annotationMode: Boolean, - isPrintPreview: { type: Boolean, value: false, }, - strings: { - type: Object, - observer: 'onStringsSet_', - }, - - /** @private */ - twoUpViewEnabled_: Boolean, - - /** @private */ - fitButtonDelay_: { - type: Number, - computed: 'computeFitButtonDelay_(twoUpViewEnabled_)', - }, - /** @private */ keyboardNavigationActive_: { type: Boolean, @@ -62,14 +37,6 @@ Polymer({ }, }, - /** - * @return {number} Delay for the fit button. - * @private - */ - computeFitButtonDelay_() { - return this.twoUpViewEnabled_ ? 150 : 100; - }, - listeners: { 'focus': 'onFocus_', 'keyup': 'onKeyUp_', @@ -86,13 +53,14 @@ Polymer({ /** @private */ onFocus_() { - // This can only happen when the plugin is shown within Print Preview using - // keyboard navigation. - if (!this.visible_) { - assert(this.isPrintPreview); - this.fire('keyboard-navigation-active', true); - this.show(); + if (this.visible_ || !this.isPrintPreview) { + return; } + + // For Print Preview, ensure the parent element knows that keyboard + // navigation is now active and show the toolbar. + this.fire('keyboard-navigation-active', true); + this.show(); }, /** @private */ @@ -111,38 +79,12 @@ Polymer({ this.keyboardNavigationActive_ = false; }, - /** - * Change button tooltips to match any changes to localized strings. - * @private - */ - onStringsSet_() { - const strings = - /** - * @type {{tooltipFitToPage: string, - * tooltipFitToWidth: string, - * tooltipTwoUpViewEnable: string, - * tooltipTwoUpViewDisable: string, - * tooltipZoomIn: string, - * tooltipZoomOut: string}} - */ - (this.strings); - this.$['fit-button'].tooltips = - [strings.tooltipFitToPage, strings.tooltipFitToWidth]; - this.$['two-up-view-button'].tooltips = - [strings.tooltipTwoUpViewEnable, strings.tooltipTwoUpViewDisable]; - this.$['zoom-in-button'].tooltips = [strings.tooltipZoomIn]; - this.$['zoom-out-button'].tooltips = [strings.tooltipZoomOut]; - this.twoUpViewEnabled_ = - loadTimeData.getBoolean('pdfTwoUpViewEnabled') && !this.isPrintPreview; - }, - /** Handle clicks of the fit-button. */ fitToggle() { this.fireFitToChangedEvent_( this.$['fit-button'].activeIndex === FIT_TO_WIDTH_BUTTON_STATE ? FittingType.FIT_TO_WIDTH : - FittingType.FIT_TO_PAGE, - true); + FittingType.FIT_TO_PAGE); }, /** Handle the keyboard shortcut equivalent of fit-button clicks. */ @@ -162,8 +104,6 @@ Polymer({ * @param {!FittingType} fittingType Page fitting type to force. */ forceFit(fittingType) { - this.fireFitToChangedEvent_(fittingType, false); - // Set the button state since there was no mouse click. const nextButtonState = (fittingType === FittingType.FIT_TO_WIDTH ? FIT_TO_PAGE_BUTTON_STATE : @@ -174,28 +114,10 @@ Polymer({ /** * Fire a 'fit-to-changed' {CustomEvent} with the given FittingType as detail. * @param {!FittingType} fittingType to include as payload. - * @param {boolean} userInitiated whether the event was initiated by a user - * action. - * @private - */ - fireFitToChangedEvent_(fittingType, userInitiated) { - this.fire( - 'fit-to-changed', - {fittingType: fittingType, userInitiated: userInitiated}); - }, - - /** - * Handle clicks of the two-up-view button. * @private */ - twoUpViewToggle_: function() { - assert(this.twoUpViewEnabled_); - const twoUpViewAction = this.$['two-up-view-button'].activeIndex === - TWO_UP_VIEW_DISABLED_STATE ? - TwoUpViewAction.TWO_UP_VIEW_ENABLE : - TwoUpViewAction.TWO_UP_VIEW_DISABLE; - - this.fire('two-up-view-changed', twoUpViewAction); + fireFitToChangedEvent_(fittingType) { + this.fire('fit-to-changed', fittingType); }, /** Handle clicks of the zoom-in-button. */ @@ -212,7 +134,6 @@ Polymer({ if (!this.visible_) { this.visible_ = true; this.$['fit-button'].show(); - this.$['two-up-view-button'].show(); this.$['zoom-in-button'].show(); this.$['zoom-out-button'].show(); } @@ -222,9 +143,35 @@ Polymer({ if (this.visible_) { this.visible_ = false; this.$['fit-button'].hide(); - this.$['two-up-view-button'].hide(); this.$['zoom-in-button'].hide(); this.$['zoom-out-button'].hide(); } }, + + /** + * Offsets the toolbar position so that it doesn't move if scrollbars appear. + * @param {!{horizontal: boolean, vertical: boolean}} hasScrollbars + * @param {number} scrollbarWidth + */ + shiftForScrollbars(hasScrollbars, scrollbarWidth) { + const verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0; + const horizontalScrollbarWidth = + hasScrollbars.horizontal ? scrollbarWidth : 0; + + // Shift the zoom toolbar to the left by half a scrollbar width. This + // gives a compromise: if there is no scrollbar visible then the toolbar + // will be half a scrollbar width further left than the spec but if there + // is a scrollbar visible it will be half a scrollbar width further right + // than the spec. In RTL layout normally, the zoom toolbar is on the left + // left side, but the scrollbar is still on the right, so this is not + // necessary. + if (!isRTL()) { + this.style.right = -verticalScrollbarWidth + (scrollbarWidth / 2) + 'px'; + } + // Having a horizontal scrollbar is much rarer so we don't offset the + // toolbar from the bottom any more than what the spec says. This means + // that when there is a scrollbar visible, it will be a full scrollbar + // width closer to the bottom of the screen than usual, but this is ok. + this.style.bottom = -horizontalScrollbarWidth + 'px'; + } }); diff --git a/chromium/chrome/browser/resources/pdf/gesture_detector.js b/chromium/chrome/browser/resources/pdf/gesture_detector.js index 6755d76b9b0..a259d31dae5 100644 --- a/chromium/chrome/browser/resources/pdf/gesture_detector.js +++ b/chromium/chrome/browser/resources/pdf/gesture_detector.js @@ -3,10 +3,11 @@ // found in the LICENSE file. import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; +import {Point} from './constants.js'; /** * @typedef {{ - * center: !{x: number, y: number}, + * center: !Point, * direction: (string|undefined), * scaleRatio: (?number|undefined), * startScaleRatio: (?number|undefined), @@ -249,7 +250,7 @@ export class GestureDetector { /** * Computes the midpoint between fingers. * @param {!TouchEvent} event Touch event with at least 2 touch points. - * @return {!{x: number, y: number}} Midpoint between touch[0] and touch[1]. + * @return {!Point} Midpoint between touch[0] and touch[1]. * @private */ static center_(event) { diff --git a/chromium/chrome/browser/resources/pdf/index.html b/chromium/chrome/browser/resources/pdf/index.html index bce88410976..c7290e53ee3 100644 --- a/chromium/chrome/browser/resources/pdf/index.html +++ b/chromium/chrome/browser/resources/pdf/index.html @@ -6,6 +6,17 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="stylesheet" href="index.css"> + + <style> + html, + body { + height: 100%; + } + + html[pdf-viewer-update-enabled] body { + width: 100%; + } + </style> </head> <body> <pdf-viewer id="viewer"></pdf-viewer> diff --git a/chromium/chrome/browser/resources/pdf/index_pp.html b/chromium/chrome/browser/resources/pdf/index_pp.html index fd18cd50280..2f4cfc16dca 100644 --- a/chromium/chrome/browser/resources/pdf/index_pp.html +++ b/chromium/chrome/browser/resources/pdf/index_pp.html @@ -5,6 +5,13 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="stylesheet" href="index.css"> + + <style> + html, + body { + height: 100%; + } + </style> </head> <body> <pdf-viewer-pp id="viewer"></pdf-viewer-pp> diff --git a/chromium/chrome/browser/resources/pdf/ink_controller.js b/chromium/chrome/browser/resources/pdf/ink_controller.js index 276b6ab686b..02e10aeff5b 100644 --- a/chromium/chrome/browser/resources/pdf/ink_controller.js +++ b/chromium/chrome/browser/resources/pdf/ink_controller.js @@ -78,6 +78,9 @@ export class InkController extends ContentController { } /** @override */ + setDisplayAnnotations(displayAnnotations) {} + + /** @override */ setTwoUpView(enableTwoUpView) { // TODO(dstockwell): Implement two up view. } @@ -117,7 +120,9 @@ export class InkController extends ContentController { new CustomEvent('set-annotation-undo-state', {detail: e.detail})); }); } - return this.inkHost_.load(filename, data); + return this.inkHost_.load(filename, data).then(() => { + this.eventTarget_.dispatchEvent(new CustomEvent('loaded')); + }); } /** @override */ diff --git a/chromium/chrome/browser/resources/pdf/local_storage_proxy.js b/chromium/chrome/browser/resources/pdf/local_storage_proxy.js new file mode 100644 index 00000000000..92b36c31e46 --- /dev/null +++ b/chromium/chrome/browser/resources/pdf/local_storage_proxy.js @@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + +/** @interface */ +class LocalStorageProxy { + /** + * @param {string} key + * @return {?string} + */ + getItem(key) {} + + /** + * @param {string} key + * @param {string} value + */ + setItem(key, value) {} +} + +/** @implements {LocalStorageProxy} */ +export class LocalStorageProxyImpl { + /** @override */ + getItem(key) { + return window.localStorage.getItem(key); + } + + /** @override */ + setItem(key, value) { + window.localStorage.setItem(key, value); + } +} + +addSingletonGetter(LocalStorageProxyImpl); diff --git a/chromium/chrome/browser/resources/pdf/metrics.js b/chromium/chrome/browser/resources/pdf/metrics.js index 42384c4b0db..a3d11d86e52 100644 --- a/chromium/chrome/browser/resources/pdf/metrics.js +++ b/chromium/chrome/browser/resources/pdf/metrics.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {FittingType, TwoUpViewAction} from './constants.js'; +import {FittingType} from './constants.js'; // Handles events specific to the PDF viewer and logs the corresponding metrics. export class PDFMetrics { @@ -22,13 +22,12 @@ export class PDFMetrics { /** * Records when the two up view mode is enabled or disabled. - * @param {TwoUpViewAction} twoUpViewAction the new TwoUpViewAction. + * @param {boolean} enabled True when two up view mode is enabled. */ - static recordTwoUpView(twoUpViewAction) { + static recordTwoUpViewEnabled(enabled) { PDFMetrics.record( - twoUpViewAction === TwoUpViewAction.TWO_UP_VIEW_ENABLE ? - PDFMetrics.UserAction.TWO_UP_VIEW_ENABLE : - PDFMetrics.UserAction.TWO_UP_VIEW_DISABLE); + enabled ? PDFMetrics.UserAction.TWO_UP_VIEW_ENABLE : + PDFMetrics.UserAction.TWO_UP_VIEW_DISABLE); } /** @@ -178,7 +177,11 @@ PDFMetrics.UserAction = { ZOOM_OUT_FIRST: 41, ZOOM_OUT: 42, - NUMBER_OF_ACTIONS: 43, + // Recorded when the custom zoom input field is modified. + ZOOM_CUSTOM_FIRST: 43, + ZOOM_CUSTOM: 44, + + NUMBER_OF_ACTIONS: 45, }; // Map from UserAction to the 'FIRST' action. These metrics are recorded @@ -269,4 +272,8 @@ PDFMetrics.firstMap_ = new Map([ PDFMetrics.UserAction.ZOOM_OUT, PDFMetrics.UserAction.ZOOM_OUT_FIRST, ], + [ + PDFMetrics.UserAction.ZOOM_CUSTOM, + PDFMetrics.UserAction.ZOOM_CUSTOM_FIRST, + ], ]); diff --git a/chromium/chrome/browser/resources/pdf/navigator.js b/chromium/chrome/browser/resources/pdf/navigator.js index 8aa2c1e3fd6..6b501b8b803 100644 --- a/chromium/chrome/browser/resources/pdf/navigator.js +++ b/chromium/chrome/browser/resources/pdf/navigator.js @@ -7,8 +7,33 @@ import {Viewport} from './viewport.js'; // NavigatorDelegate for calling browser-specific functions to do the actual // navigating. +/** @interface */ export class NavigatorDelegate { /** + * Called when navigation should happen in the current tab. + * @param {string} url The url to be opened in the current tab. + */ + navigateInCurrentTab(url) {} + + /** + * Called when navigation should happen in the new tab. + * @param {string} url The url to be opened in the new tab. + * @param {boolean} active Indicates if the new tab should be the active tab. + */ + navigateInNewTab(url, active) {} + + /** + * Called when navigation should happen in the new window. + * @param {string} url The url to be opened in the new window. + */ + navigateInNewWindow(url) {} +} + +// NavigatorDelegate for calling browser-specific functions to do the actual +// navigating. +/** @implements {NavigatorDelegate} */ +export class NavigatorDelegateImpl { + /** * @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is * not displayed in a tab. */ @@ -17,10 +42,7 @@ export class NavigatorDelegate { this.tabId_ = tabId; } - /** - * Called when navigation should happen in the current tab. - * @param {string} url The url to be opened in the current tab. - */ + /** @override */ navigateInCurrentTab(url) { // When the PDFviewer is inside a browser tab, prefer the tabs API because // it can navigate from one file:// URL to another. @@ -31,11 +53,7 @@ export class NavigatorDelegate { } } - /** - * Called when navigation should happen in the new tab. - * @param {string} url The url to be opened in the new tab. - * @param {boolean} active Indicates if the new tab should be the active tab. - */ + /** @override */ navigateInNewTab(url, active) { // Prefer the tabs API because it guarantees we can just open a new tab. // window.open doesn't have this guarantee. @@ -46,10 +64,7 @@ export class NavigatorDelegate { } } - /** - * Called when navigation should happen in the new window. - * @param {string} url The url to be opened in the new window. - */ + /** @override */ navigateInNewWindow(url) { // Prefer the windows API because it guarantees we can just open a new // window. window.open with '_blank' argument doesn't have this guarantee. diff --git a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js index 858a62b47fd..62a6479714c 100644 --- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js +++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js @@ -2,7 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {FittingType} from './constants.js'; +import {FittingType, Point} from './constants.js'; + +/** + * @typedef {{ + * url: (string|undefined), + * zoom: (number|undefined), + * view: (!FittingType|undefined), + * viewPosition: (!Point|undefined) + * }} + */ +let OpenPdfParams; // Parses the open pdf parameters passed in the url to set initial viewport // settings for opening the pdf. @@ -23,7 +33,7 @@ export class OpenPdfParamsParser { * Parse zoom parameter of open PDF parameters. The PDF should be opened at * the specified zoom level. * @param {string} paramValue zoom value. - * @return {Object} Map with zoom parameters (zoom and position). + * @return {!OpenPdfParams} Map with zoom parameters (zoom and position). * @private */ parseZoomParam_(paramValue) { @@ -55,7 +65,7 @@ export class OpenPdfParamsParser { * Parse view parameter of open PDF parameters. The PDF should be opened at * the specified fitting type mode and position. * @param {string} paramValue view value. - * @return {Object} Map with view parameters (view and viewPosition). + * @return {!OpenPdfParams} Map with view parameters (view and viewPosition). * @private */ parseViewParam_(paramValue) { @@ -128,7 +138,8 @@ export class OpenPdfParamsParser { * See http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/ * pdfs/pdf_open_parameters.pdf for details. * @param {string} url that needs to be parsed. - * @param {Function} callback function to be called with viewport info. + * @param {function(!OpenPdfParams)} callback function to be called with + * viewport info. */ getViewportFromUrlParams(url, callback) { const params = {}; diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.html b/chromium/chrome/browser/resources/pdf/pdf_viewer.html index a56670db71c..853b0dd7653 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer.html +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.html @@ -1,6 +1,44 @@ -<style include="pdf-viewer-shared-style"> +<style include="pdf-viewer-shared-style cr-hidden-style"> + :host { + --viewer-pdf-sidenav-width: 300px; + } + + viewer-pdf-sidenav, + viewer-pdf-toolbar-new { + --pdf-toolbar-text-color: rgb(241, 241, 241); + } + viewer-pdf-toolbar, viewer-pdf-toolbar-new { + --active-button-bg: rgba(255, 255, 255, 0.24); + } + + #sidenav-container { + overflow: hidden; + transition: width 250ms cubic-bezier(.6, 0, 0, 1), visibility 250ms; + visibility: visible; + width: var(--viewer-pdf-sidenav-width); + } + + #sidenav-container[closed] { + transition: width 200ms cubic-bezier(.6, 0, 0, 1), visibility 200ms; + visibility: hidden; + width: 0; + } + + #content-focus-rectangle { + border: 2px solid var(--google-grey-600); + border-radius: 2px; + box-sizing: border-box; + height: 100%; + pointer-events: none; + position: fixed; + width: 100%; + /* z-index for this should be higher than toolbar. */ + z-index: 5; + } + + viewer-pdf-toolbar { position: fixed; width: 100%; z-index: 4; @@ -17,39 +55,137 @@ display: none; } } + + /* Styles only applying when the pdfViewerUpdateEnabled flag is on. */ + + viewer-pdf-toolbar-new { + z-index: 1; + } + + :host-context([pdf-viewer-update-enabled]):host { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + } + + #container { + display: flex; + flex: 1; + overflow: hidden; + } + + :host-context([pdf-viewer-update-enabled]) #plugin { + position: initial; + } + + :host-context([pdf-viewer-update-enabled]) #content { + height: 100%; + left: 0; + position: sticky; + top: 0; + z-index: initial; + } + + :host-context([pdf-viewer-update-enabled]) #sizer { + top: 0; + width: 100%; + z-index: initial; + } + + #main { + flex: 1; + overflow: auto; + position: relative; + } </style> <template is="dom-if" if="[[!pdfViewerUpdateEnabled_]]"> <viewer-pdf-toolbar id="toolbar" strings="[[strings]]" - annotation-available="[[annotationAvailable_]]" bookmarks="[[bookmarks_]]" doc-title="[[title_]]" has-edits="[[hasEdits_]]" has-entered-annotation-mode="[[hasEnteredAnnotationMode_]]" + pdf-form-save-enabled="[[pdfFormSaveEnabled_]]" + printing-enabled="[[printingEnabled_]]" is-form-field-focused="[[isFormFieldFocused_]]" + doc-length="[[docLength_]]" page-no="[[pageNo_]]" + load-progress="[[loadProgress_]]" +<if expr="chromeos"> + annotation-available="[[annotationAvailable_]]" + ink-controller="[[inkController_]]" + pdf-annotations-enabled="[[pdfAnnotationsEnabled_]]" +</if> + on-change-page-and-xy="onChangePageAndXy_" + on-change-page="onChangePage_" + on-dropdown-opened="onDropdownOpened_" + on-navigate="onNavigate_" on-save="onToolbarSave_" on-print="onPrint_" +<if expr="chromeos"> on-annotation-mode-toggled="onAnnotationModeToggled_" - on-annotation-tool-changed="onAnnotationToolChanged_" - on-rotate-right="rotateClockwise" on-undo="onUndo_" on-redo="onRedo_" - hidden> +</if> + on-rotate-right="rotateClockwise" hidden> </viewer-pdf-toolbar> </template> <template is="dom-if" if="[[pdfViewerUpdateEnabled_]]"> - <viewer-pdf-toolbar-new id="toolbar" hidden> + <viewer-pdf-toolbar-new id="toolbar" + doc-title="[[title_]]" doc-length="[[docLength_]]" page-no="[[pageNo_]]" + load-progress="[[loadProgress_]]" has-edits="[[hasEdits_]]" + has-entered-annotation-mode="[[hasEnteredAnnotationMode_]]" + pdf-form-save-enabled="[[pdfFormSaveEnabled_]]" + printing-enabled="[[printingEnabled_]]" + is-form-field-focused="[[isFormFieldFocused_]]" + viewport-zoom="[[viewportZoom_]]" +<if expr="chromeos"> + annotation-available="[[annotationAvailable_]]" + ink-controller="[[inkController_]]" + pdf-annotations-enabled="[[pdfAnnotationsEnabled_]]" +</if> + on-change-page="onChangePage_" + on-display-annotations-changed="onDisplayAnnotationsChanged_" + on-dropdown-opened="onDropdownOpened_" + on-fit-to-changed="onFitToChanged" + on-sidenav-toggle-click="onSidenavToggleClick_" + on-two-up-view-changed="onTwoUpViewChanged_" + on-zoom-changed="onZoomChanged" on-zoom-in="onZoomIn" + on-zoom-out="onZoomOut" on-rotate-left="rotateCounterclockwise" +<if expr="chromeos"> + on-annotation-mode-toggled="onAnnotationModeToggled_" +</if> + on-print="onPrint_" on-save="onToolbarSave_" hidden> </viewer-pdf-toolbar-new> </template> -<div id="sizer"></div> +<template is="dom-if" if="[[pdfViewerUpdateEnabled_]]"> + <div id="container"> + <div id="sidenav-container" closed$="[[sidenavCollapsed_]]"> + <viewer-pdf-sidenav id="sidenav" + bookmarks="[[bookmarks_]]" doc-length="[[docLength_]]" + on-change-page="onChangePage_" + on-change-page-and-xy="onChangePageAndXy_" + on-navigate="onNavigate_"> + </viewer-pdf-sidenav> + </div> + <div id="main" on-scroll="onScroll_"> + <div id="sizer"></div> + <div id="content"></div> + </div> + </div> +</template> + +<template is="dom-if" if="[[!pdfViewerUpdateEnabled_]]"> + <div id="sizer"></div> +</template> + <viewer-password-screen id="password-screen" on-password-submitted="onPasswordSubmitted_"> </viewer-password-screen> -<viewer-zoom-toolbar id="zoom-toolbar" strings="[[strings]]" - annotation-mode="[[annotationMode_]]" - on-fit-to-changed="onFitToChanged" - on-two-up-view-changed="onTwoUpViewChanged_" - on-zoom-in="onZoomIn" on-zoom-out="onZoomOut" - hidden> -</viewer-zoom-toolbar> +<template is="dom-if" if="[[!pdfViewerUpdateEnabled_]]"> + <viewer-zoom-toolbar id="zoom-toolbar" + on-fit-to-changed="onFitToChanged" + on-zoom-in="onZoomIn" on-zoom-out="onZoomOut"> + </viewer-zoom-toolbar> +</template> <viewer-error-screen id="error-screen"></viewer-error-screen> @@ -57,5 +193,8 @@ <viewer-form-warning id="form-warning"></viewer-form-warning> </if> -<div id="content"></div> +<template is="dom-if" if="[[!pdfViewerUpdateEnabled_]]"> + <div id="content"></div> +</template> +<div id="content-focus-rectangle" hidden$="[[!documentHasFocus_]]"></div> diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.js b/chromium/chrome/browser/resources/pdf/pdf_viewer.js index e23b4b41e48..d2300291684 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.js @@ -4,35 +4,38 @@ import './elements/viewer-error-screen.js'; import './elements/viewer-password-screen.js'; +import './elements/viewer-pdf-sidenav.js'; import './elements/viewer-pdf-toolbar.js'; -import './elements/viewer-pdf-toolbar-new.js'; +import './elements/viewer-zoom-toolbar.js'; import './elements/shared-vars.js'; // <if expr="chromeos"> import './elements/viewer-ink-host.js'; import './elements/viewer-form-warning.js'; // </if> import './pdf_viewer_shared_style.js'; +import 'chrome://resources/cr_elements/hidden_style_css.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {hasKeyModifiers, isRTL} from 'chrome://resources/js/util.m.js'; +import {hasKeyModifiers} from 'chrome://resources/js/util.m.js'; import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Bookmark} from './bookmark_type.js'; import {BrowserApi} from './browser_api.js'; -import {FittingType, SaveRequestType, TwoUpViewAction} from './constants.js'; +import {FittingType, Point, SaveRequestType} from './constants.js'; +import {ViewerPdfToolbarNewElement} from './elements/viewer-pdf-toolbar-new.js'; +// <if expr="chromeos"> +import {InkController} from './ink_controller.js'; +//</if> +import {LocalStorageProxyImpl} from './local_storage_proxy.js'; import {PDFMetrics} from './metrics.js'; -import {NavigatorDelegate, PdfNavigator} from './navigator.js'; +import {NavigatorDelegateImpl, PdfNavigator} from './navigator.js'; import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; import {DeserializeKeyEvent, LoadState, SerializeKeyEvent} from './pdf_scripting_api.js'; import {PDFViewerBaseElement} from './pdf_viewer_base.js'; import {DestinationMessageData, DocumentDimensionsMessageData, shouldIgnoreKeyEvents} from './pdf_viewer_utils.js'; import {ToolbarManager} from './toolbar_manager.js'; -import {Point} from './viewport.js'; - -// <if expr="chromeos"> -import {InkController} from './ink_controller.js'; -// </if> /** @@ -84,7 +87,10 @@ export function getFilenameFromURL(url) { } } -class PDFViewerElement extends PDFViewerBaseElement { +/** @type {string} */ +const LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY = 'sidenavCollapsed'; + +export class PDFViewerElement extends PDFViewerBaseElement { static get is() { return 'pdf-viewer'; } @@ -108,6 +114,11 @@ class PDFViewerElement extends PDFViewerBaseElement { bookmarks_: Array, + documentHasFocus_: { + type: Boolean, + value: false, + }, + hasEdits_: { type: Boolean, value: false, @@ -128,14 +139,18 @@ class PDFViewerElement extends PDFViewerBaseElement { isFormFieldFocused_: Boolean, - /** @private */ - pdfViewerUpdateEnabled_: { - type: Boolean, - value: function() { - return document.documentElement.hasAttribute( - 'pdf-viewer-update-enabled'); - }, - }, + pdfViewerUpdateEnabled_: Boolean, + + docLength_: Number, + // <if expr="chromeos"> + inkController_: Object, + // </if> + loadProgress_: Number, + pageNo_: Number, + pdfFormSaveEnabled_: Boolean, + pdfAnnotationsEnabled_: Boolean, + printingEnabled_: Boolean, + viewportZoom_: Number, }; } @@ -153,6 +168,9 @@ class PDFViewerElement extends PDFViewerBaseElement { this.bookmarks_ = []; /** @private {boolean} */ + this.documentHasFocus_ = false; + + /** @private {boolean} */ this.hasEdits_ = false; /** @private {boolean} */ @@ -173,10 +191,27 @@ class PDFViewerElement extends PDFViewerBaseElement { /** @private {boolean} */ this.isFormFieldFocused_ = false; - // Non-Polymer properties + // <if expr="chromeos"> + /** @private {?InkController} */ + this.inkController_ = null; + // </if> + + /** @private {boolean} */ + this.pdfAnnotationsEnabled_ = false; + + /** @private {boolean} */ + this.pdfFormSaveEnabled_ = false; + + /** @private {boolean} */ + this.printingEnabled_ = false; /** @private {number} */ - this.beepCount_ = 0; + this.viewportZoom_ = 1; + + // Non-Polymer properties + + /** @type {number} */ + this.beepCount = 0; /** @private {boolean} */ this.hadPassword_ = false; @@ -184,11 +219,6 @@ class PDFViewerElement extends PDFViewerBaseElement { /** @private {boolean} */ this.toolbarEnabled_ = false; - // <if expr="chromeos"> - /** @private {?InkController} */ - this.inkController_ = null; - // </if> - /** @private {?ToolbarManager} */ this.toolbarManager_ = null; @@ -198,8 +228,38 @@ class PDFViewerElement extends PDFViewerBaseElement { /** @private {string} */ this.title_ = ''; + /** + * The number of pages in the PDF document. + * @private {number} + */ + this.docLength_; + + /** + * The number of the page being viewed (1-based). + * @private {number} + */ + this.pageNo_; + + /** + * The current loading progress of the PDF document (0 - 100). + * @private {number} + */ + this.loadProgress_; + /** @private {boolean} */ - this.pdfViewerUpdateEnabled_; + this.pdfViewerUpdateEnabled_ = + document.documentElement.hasAttribute('pdf-viewer-update-enabled'); + + /** @private {boolean} */ + this.sidenavCollapsed_ = false; + + if (this.pdfViewerUpdateEnabled_) { + // TODO(dpapad): Add tests after crbug.com/1111459 is fixed. + this.sidenavCollapsed_ = Boolean(Number.parseInt( + LocalStorageProxyImpl.getInstance().getItem( + LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY), + 10)); + } } /** @override */ @@ -207,10 +267,22 @@ class PDFViewerElement extends PDFViewerBaseElement { assert(this.paramsParser); this.toolbarEnabled_ = this.paramsParser.shouldShowToolbar(this.originalUrl); + + // The toolbar does not need to be manually accounted in the + // PDFViewerUpdate UI. + if (this.pdfViewerUpdateEnabled_) { + return 0; + } + return this.toolbarEnabled_ ? MATERIAL_TOOLBAR_HEIGHT : 0; } /** @override */ + hasFixedToolbar() { + return this.pdfViewerUpdateEnabled_; + } + + /** @override */ getContent() { return /** @type {!HTMLDivElement} */ (this.$$('#content')); } @@ -221,11 +293,6 @@ class PDFViewerElement extends PDFViewerBaseElement { } /** @override */ - getZoomToolbar() { - return /** @type {!ViewerZoomToolbarElement} */ (this.$$('#zoom-toolbar')); - } - - /** @override */ getErrorScreen() { return /** @type {!ViewerErrorScreenElement} */ (this.$$('#error-screen')); } @@ -238,6 +305,23 @@ class PDFViewerElement extends PDFViewerBaseElement { return /** @type {!ViewerPdfToolbarElement} */ (this.$$('#toolbar')); } + /** + * @return {!ViewerPdfToolbarNewElement} + * @private + */ + getToolbarNew_() { + assert(this.pdfViewerUpdateEnabled_); + return /** @type {!ViewerPdfToolbarNewElement} */ (this.$$('#toolbar')); + } + + /** + * @return {!ViewerZoomToolbarElement} + * @private + */ + getZoomToolbar_() { + return /** @type {!ViewerZoomToolbarElement} */ (this.$$('#zoom-toolbar')); + } + /** @override */ getBackgroundColor() { return BACKGROUND_COLOR; @@ -251,11 +335,8 @@ class PDFViewerElement extends PDFViewerBaseElement { this.inkController_ = new InkController( this.viewport, /** @type {!HTMLDivElement} */ (this.getContent())); this.tracker.add( - this.inkController_.getEventTarget(), 'stroke-added', + this.inkController_.getEventTarget(), 'has-unsaved-changes', () => chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(true)); - this.tracker.add( - this.inkController_.getEventTarget(), 'set-annotation-undo-state', - e => this.setAnnotationUndoState_(e)); // </if> this.title_ = getFilenameFromURL(this.originalUrl); @@ -263,36 +344,10 @@ class PDFViewerElement extends PDFViewerBaseElement { this.getToolbar_().hidden = false; } - document.body.addEventListener('change-page', e => { - this.viewport.goToPage(e.detail.page); - if (e.detail.origin === 'bookmark') { - PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK); - } else if (e.detail.origin === 'pageselector') { - PDFMetrics.record(PDFMetrics.UserAction.PAGE_SELECTOR_NAVIGATE); - } - }); - - document.body.addEventListener('change-page-and-xy', e => { - const point = this.viewport.convertPageToScreen(e.detail.page, e.detail); - this.goToPageAndXY_(e.detail.origin, e.detail.page, point); - }); - - document.body.addEventListener('navigate', e => { - const disposition = e.detail.newtab ? - PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB : - PdfNavigator.WindowOpenDisposition.CURRENT_TAB; - this.navigator_.navigate(e.detail.uri, disposition); - }); - - document.body.addEventListener('dropdown-opened', e => { - if (e.detail === 'bookmarks') { - PDFMetrics.record(PDFMetrics.UserAction.OPEN_BOOKMARKS_PANEL); - } - }); - - this.toolbarManager_ = new ToolbarManager( - window, this.pdfViewerUpdateEnabled_ ? null : this.getToolbar_(), - this.getZoomToolbar()); + if (!this.pdfViewerUpdateEnabled_) { + this.toolbarManager_ = new ToolbarManager( + window, this.getToolbar_(), this.getZoomToolbar_()); + } // Setup the keyboard event listener. document.addEventListener( @@ -303,7 +358,7 @@ class PDFViewerElement extends PDFViewerBaseElement { this.navigator_ = new PdfNavigator( this.originalUrl, this.viewport, /** @type {!OpenPdfParamsParser} */ (this.paramsParser), - new NavigatorDelegate(tabId)); + new NavigatorDelegateImpl(tabId)); // Listen for save commands from the browser. if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) { @@ -312,6 +367,47 @@ class PDFViewerElement extends PDFViewerBaseElement { } /** + * Helper for handleKeyEvent_ dealing with events that control toolbars. + * @param {!KeyboardEvent} e the event to handle. + * @private + */ + handleToolbarKeyEvent_(e) { + if (this.pdfViewerUpdateEnabled_) { + if (e.key === '\\' && e.ctrlKey) { + this.getToolbarNew_().fitToggle(); + } + // TODO: Add handling for additional relevant hotkeys for the new unified + // toolbar. + return; + } + + switch (e.key) { + case 'Tab': + this.toolbarManager_.showToolbarsForKeyboardNavigation(); + return; + case 'Escape': + this.toolbarManager_.hideSingleToolbarLayer(); + return; + case 'g': + if (this.toolbarEnabled_ && (e.ctrlKey || e.metaKey) && e.altKey) { + this.toolbarManager_.showToolbars(); + this.getToolbar_().selectPageNumber(); + } + return; + case '\\': + if (e.ctrlKey) { + this.getZoomToolbar_().fitToggleFromHotKey(); + } + return; + } + + // Show toolbars as a fallback. + if (!(e.shiftKey || e.ctrlKey || e.altKey)) { + this.toolbarManager_.showToolbars(); + } + } + + /** * Handle key events. These may come from the user directly or via the * scripting API. * @param {!KeyboardEvent} e the event to handle. @@ -322,7 +418,9 @@ class PDFViewerElement extends PDFViewerBaseElement { return; } - this.toolbarManager_.hideToolbarsAfterTimeout(); + if (!this.pdfViewerUpdateEnabled_) { + this.toolbarManager_.hideToolbarsAfterTimeout(); + } // Let the viewport handle directional key events. if (this.viewport.handleDirectionalKeyEvent(e, this.isFormFieldFocused_)) { @@ -330,12 +428,6 @@ class PDFViewerElement extends PDFViewerBaseElement { } switch (e.key) { - case 'Tab': - this.toolbarManager_.showToolbarsForKeyboardNavigation(); - return; - case 'Escape': - this.toolbarManager_.hideSingleToolbarLayer(); - return; case 'a': if (e.ctrlKey || e.metaKey) { this.pluginController.selectAll(); @@ -343,22 +435,11 @@ class PDFViewerElement extends PDFViewerBaseElement { e.preventDefault(); } return; - case 'g': - if (this.toolbarEnabled_ && (e.ctrlKey || e.metaKey) && e.altKey) { - this.toolbarManager_.showToolbars(); - this.getToolbar_().selectPageNumber(); - } - return; case '[': if (e.ctrlKey) { this.rotateCounterclockwise(); } return; - case '\\': - if (e.ctrlKey) { - this.getZoomToolbar().fitToggleFromHotKey(); - } - return; case ']': if (e.ctrlKey) { this.rotateClockwise(); @@ -366,19 +447,18 @@ class PDFViewerElement extends PDFViewerBaseElement { return; } - // Show toolbars as a fallback. - if (!(e.shiftKey || e.ctrlKey || e.altKey)) { - this.toolbarManager_.showToolbars(); - } + // Handle toolbar related key events. + this.handleToolbarKeyEvent_(e); } + // <if expr="chromeos"> /** * Handles the annotation mode being toggled on or off. - * @param {!CustomEvent<{value: boolean}>} e + * @param {!CustomEvent<boolean>} e * @private */ async onAnnotationModeToggled_(e) { - const annotationMode = e.detail.value; + const annotationMode = e.detail; this.annotationMode_ = annotationMode; if (annotationMode) { // Enter annotation mode. @@ -407,8 +487,6 @@ class PDFViewerElement extends PDFViewerBaseElement { // TODO(dstockwell): feed real progress data from the Ink component this.updateProgress(50); await this.inkController_.load(result.fileName, result.dataToSave); - this.inkController_.setAnnotationTool( - assert(this.getToolbar_().annotationTool)); this.currentController = this.inkController_; this.pluginController.unload(); this.updateProgress(100); @@ -447,13 +525,34 @@ class PDFViewerElement extends PDFViewerBaseElement { this.annotationMode_ = false; await this.loaded; } + // </if> + + /** + * @param {!Event} e + * @private + */ + onDisplayAnnotationsChanged_(e) { + this.currentController.setDisplayAnnotations(e.detail); + } + + /** + * @param {!Event} e + * @private + */ + onScroll_(e) { + this.pluginController.updateScroll(e.target.scrollLeft, e.target.scrollTop); + } /** @override */ onFitToChanged(e) { super.onFitToChanged(e); - if (e.detail.fittingType === FittingType.FIT_TO_PAGE || - e.detail.fittingType === FittingType.FIT_TO_HEIGHT) { + if (this.pdfViewerUpdateEnabled_) { + return; + } + + if (e.detail === FittingType.FIT_TO_PAGE || + e.detail === FittingType.FIT_TO_HEIGHT) { this.toolbarManager_.forceHideTopToolbar(); } } @@ -461,17 +560,17 @@ class PDFViewerElement extends PDFViewerBaseElement { /** * Changes two up view mode for the controller. Controller will trigger * layout update later, which will update the viewport accordingly. - * @param {!CustomEvent<!TwoUpViewAction>} e + * @param {!CustomEvent<boolean>} e * @private */ onTwoUpViewChanged_(e) { - this.currentController.setTwoUpView( - e.detail === TwoUpViewAction.TWO_UP_VIEW_ENABLE); - this.toolbarManager_.forceHideTopToolbar(); - this.getToolbar_().annotationAvailable = - (e.detail !== TwoUpViewAction.TWO_UP_VIEW_ENABLE); - - PDFMetrics.recordTwoUpView(e.detail); + const twoUpViewEnabled = e.detail; + this.currentController.setTwoUpView(twoUpViewEnabled); + if (!this.pdfViewerUpdateEnabled_) { + this.toolbarManager_.forceHideTopToolbar(); + } + this.getToolbar_().annotationAvailable = !twoUpViewEnabled; + PDFMetrics.recordTwoUpViewEnabled(twoUpViewEnabled); } /** @@ -511,10 +610,10 @@ class PDFViewerElement extends PDFViewerBaseElement { /** @override */ updateProgress(progress) { if (this.toolbarEnabled_) { - this.getToolbar_().loadProgress = progress; + this.loadProgress_ = progress; } super.updateProgress(progress); - if (progress === 100) { + if (progress === 100 && !this.pdfViewerUpdateEnabled_) { this.toolbarManager_.hideToolbarsAfterTimeout(); } } @@ -531,41 +630,31 @@ class PDFViewerElement extends PDFViewerBaseElement { /** @override */ updateUIForViewportChange() { - // Offset the toolbar position so that it doesn't move if scrollbars appear. - const hasScrollbars = this.viewport.documentHasScrollbars(); - const scrollbarWidth = this.viewport.scrollbarWidth; - const verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0; - const horizontalScrollbarWidth = - hasScrollbars.horizontal ? scrollbarWidth : 0; - - // Shift the zoom toolbar to the left by half a scrollbar width. This - // gives a compromise: if there is no scrollbar visible then the toolbar - // will be half a scrollbar width further left than the spec but if there - // is a scrollbar visible it will be half a scrollbar width further right - // than the spec. In RTL layout normally, the zoom toolbar is on the left - // left side, but the scrollbar is still on the right, so this is not - // necessary. - const zoomToolbar = this.getZoomToolbar(); - if (!isRTL()) { - zoomToolbar.style.right = - -verticalScrollbarWidth + (scrollbarWidth / 2) + 'px'; - } - // Having a horizontal scrollbar is much rarer so we don't offset the - // toolbar from the bottom any more than what the spec says. This means - // that when there is a scrollbar visible, it will be a full scrollbar - // width closer to the bottom of the screen than usual, but this is ok. - zoomToolbar.style.bottom = -horizontalScrollbarWidth + 'px'; + if (!this.pdfViewerUpdateEnabled_) { + this.getZoomToolbar_().shiftForScrollbars( + this.viewport.documentHasScrollbars(), this.viewport.scrollbarWidth); + } // Update the page indicator. - const visiblePage = this.viewport.getMostVisiblePage(); if (this.toolbarEnabled_) { - this.getToolbar_().pageNo = visiblePage + 1; + const visiblePage = this.viewport.getMostVisiblePage(); + this.pageNo_ = visiblePage + 1; } this.currentController.viewportChanged(); } /** @override */ + handleStrings(strings) { + super.handleStrings(strings); + + this.pdfAnnotationsEnabled_ = + loadTimeData.getBoolean('pdfAnnotationsEnabled'); + this.pdfFormSaveEnabled_ = loadTimeData.getBoolean('pdfFormSaveEnabled'); + this.printingEnabled_ = loadTimeData.getBoolean('printingEnabled'); + } + + /** @override */ handleScriptingMessage(message) { super.handleScriptingMessage(message); @@ -575,7 +664,8 @@ class PDFViewerElement extends PDFViewerBaseElement { switch (message.data.type.toString()) { case 'getSelectedText': - this.pluginController.getSelectedText(); + this.pluginController.getSelectedText().then( + this.handleSelectedTextReply.bind(this)); break; case 'print': this.pluginController.print(); @@ -600,10 +690,6 @@ class PDFViewerElement extends PDFViewerBaseElement { case 'getPassword': this.handlePasswordRequest_(); return; - case 'getSelectedTextReply': - this.handleSelectedTextReply( - /** @type {{ selectedText: string }} */ (data).selectedText); - return; case 'loadProgress': this.updateProgress( /** @type {{ progress: number }} */ (data).progress); @@ -631,10 +717,6 @@ class PDFViewerElement extends PDFViewerBaseElement { this.viewportScroller.setEnableScrolling( /** @type {{ isSelecting: boolean }} */ (data).isSelecting); return; - case 'getNamedDestinationReply': - this.paramsParser.onNamedDestinationReceived( - /** @type {{ pageNumber: number }} */ (data).pageNumber); - return; case 'formFocusChange': this.isFormFieldFocused_ = /** @type {{ focused: boolean }} */ (data).focused; @@ -645,13 +727,32 @@ class PDFViewerElement extends PDFViewerBaseElement { }); return; case 'documentFocusChanged': - // TODO(crbug.com/1069370): Draw a focus rect around plugin. + this.documentHasFocus_ = + /** @type {{ hasFocus: boolean }} */ (data).hasFocus; return; } assertNotReached('Unknown message type received: ' + data.type); } /** @override */ + forceFit(view) { + if (!this.pdfViewerUpdateEnabled_) { + if (view === FittingType.FIT_TO_PAGE || + view === FittingType.FIT_TO_HEIGHT) { + this.toolbarManager_.forceHideTopToolbar(); + } + this.getZoomToolbar_().forceFit(view); + } else { + this.getToolbarNew_().forceFit(view); + } + } + + /** @override */ + afterZoom(viewportZoom) { + this.viewportZoom_ = viewportZoom; + } + + /** @override */ setDocumentDimensions(documentDimensions) { super.setDocumentDimensions(documentDimensions); // If we received the document dimensions, the password was good so we @@ -662,8 +763,7 @@ class PDFViewerElement extends PDFViewerBaseElement { } if (this.toolbarEnabled_) { - this.getToolbar_().docLength = - this.documentDimensions.pageDimensions.length; + this.docLength_ = this.documentDimensions.pageDimensions.length; } } @@ -673,7 +773,7 @@ class PDFViewerElement extends PDFViewerBaseElement { */ handleBeep_() { // Beeps are annoying, so just track count for now. - this.beepCount_ += 1; + this.beepCount += 1; } /** @@ -750,6 +850,58 @@ class PDFViewerElement extends PDFViewerBaseElement { } /** + * @param {!CustomEvent<!{page: number, origin: string}>} e + * @private + */ + onChangePage_(e) { + this.viewport.goToPage(e.detail.page); + if (e.detail.origin === 'bookmark') { + PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK); + } else if (e.detail.origin === 'pageselector') { + PDFMetrics.record(PDFMetrics.UserAction.PAGE_SELECTOR_NAVIGATE); + } + } + + /** + * @param {!CustomEvent<!{ + * page: number, origin: string, x: number, y: number}>} e + * @private + */ + onChangePageAndXy_(e) { + const point = this.viewport.convertPageToScreen(e.detail.page, e.detail); + this.goToPageAndXY_(e.detail.origin, e.detail.page, point); + } + + /** + * @param {!CustomEvent<string>} e + * @private + */ + onDropdownOpened_(e) { + if (e.detail === 'bookmarks') { + PDFMetrics.record(PDFMetrics.UserAction.OPEN_BOOKMARKS_PANEL); + } + } + + /** + * @param {!CustomEvent<!{newtab: boolean, uri: string}>} e + * @private + */ + onNavigate_(e) { + const disposition = e.detail.newtab ? + PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB : + PdfNavigator.WindowOpenDisposition.CURRENT_TAB; + this.navigator_.navigate(e.detail.uri, disposition); + } + + /** @private */ + onSidenavToggleClick_() { + assert(this.pdfViewerUpdateEnabled_); + this.sidenavCollapsed_ = !this.sidenavCollapsed_; + LocalStorageProxyImpl.getInstance().setItem( + LOCAL_STORAGE_SIDENAV_COLLAPSED_KEY, this.sidenavCollapsed_ ? 1 : 0); + } + + /** * Saves the current PDF document to disk. * @param {SaveRequestType} requestType The type of save request. * @private @@ -770,11 +922,13 @@ class PDFViewerElement extends PDFViewerBaseElement { if (requestType !== SaveRequestType.ORIGINAL || !this.annotationMode_) { result = await this.currentController.save(requestType); } else { + // <if expr="chromeos"> // Request type original in annotation mode --> need to exit annotation // mode before saving. See https://crbug.com/919364. await this.exitAnnotationMode_(); assert(!this.annotationMode_); result = await this.currentController.save(SaveRequestType.ORIGINAL); + // </if> } if (result == null) { // The content controller handled the save internally. @@ -811,14 +965,18 @@ class PDFViewerElement extends PDFViewerBaseElement { }); }); + // <if expr="chromeos"> // Saving in Annotation mode is destructive: crbug.com/919364 this.exitAnnotationMode_(); + // </if> } /** @private */ async onPrint_() { PDFMetrics.record(PDFMetrics.UserAction.PRINT); + // <if expr="chromeos"> await this.exitAnnotationMode_(); + // </if> this.currentController.print(); } @@ -832,35 +990,6 @@ class PDFViewerElement extends PDFViewerBaseElement { return this.canSerializeDocument_ && !this.rotated_ && !this.hadPassword_; } - /** @private */ - onUndo_() { - this.currentController.undo(); - } - - /** @private */ - onRedo_() { - this.currentController.redo(); - } - - /** - * @param {!CustomEvent<{value: AnnotationTool}>} e - * @private - */ - onAnnotationToolChanged_(e) { - this.inkController_.setAnnotationTool(e.detail.value); - } - - // <if expr="chromeos"> - /** - * @param {!CustomEvent<{canUndo: boolean, canRedo: boolean}>} e - * @private - */ - setAnnotationUndoState_(e) { - this.getToolbar_().canUndoAnnotation = e.detail.canUndo; - this.getToolbar_().canRedoAnnotation = e.detail.canRedo; - } - // </if> - /** @override */ rotateClockwise() { super.rotateClockwise(); diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js b/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js index bb0c9a91d12..a398e2293a3 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer_base.js @@ -9,14 +9,13 @@ import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BrowserApi} from './browser_api.js'; -import {FittingType} from './constants.js'; +import {FittingType, Point} from './constants.js'; import {ContentController, MessageData, PluginController} from './controller.js'; -import {FitToChangedEvent} from './elements/viewer-zoom-toolbar.js'; import {PDFMetrics} from './metrics.js'; import {OpenPdfParamsParser} from './open_pdf_params_parser.js'; import {LoadState} from './pdf_scripting_api.js'; import {DocumentDimensionsMessageData, MessageObject} from './pdf_viewer_utils.js'; -import {Point, Viewport} from './viewport.js'; +import {Viewport} from './viewport.js'; import {ViewportScroller} from './viewport_scroller.js'; import {ZoomManager} from './zoom_manager.js'; @@ -121,6 +120,11 @@ export class PDFViewerBaseElement extends PolymerElement { return 0; } + /** @return {boolean} Whether the top toolbar is fixed (does not auto-hide) */ + hasFixedToolbar() { + return false; + } + /** * @return {!HTMLDivElement} * @protected @@ -134,16 +138,22 @@ export class PDFViewerBaseElement extends PolymerElement { getSizer() {} /** - * @return {!ViewerZoomToolbarElement} + * @return {!ViewerErrorScreenElement} * @protected */ - getZoomToolbar() {} + getErrorScreen() {} /** - * @return {!ViewerErrorScreenElement} + * @param {!FittingType} view * @protected */ - getErrorScreen() {} + forceFit(view) {} + + /** + * @param {number} viewportZoom + * @protected + */ + afterZoom(viewportZoom) {} /** * @param {string} query @@ -212,8 +222,12 @@ export class PDFViewerBaseElement extends PolymerElement { PDFMetrics.record(PDFMetrics.UserAction.DOCUMENT_OPENED); // Parse open pdf parameters. - this.paramsParser = new OpenPdfParamsParser( - destination => this.pluginController_.getNamedDestination(destination)); + this.paramsParser = new OpenPdfParamsParser(destination => { + this.pluginController_.getNamedDestination(destination).then(data => { + this.paramsParser.onNamedDestinationReceived( + /** @type {{ pageNumber: number }} */ (data).pageNumber); + }); + }); // Can only reload if we are in a normal tab. if (chrome.tabs && this.browserApi.getStreamInfo().tabId !== -1) { @@ -222,19 +236,30 @@ export class PDFViewerBaseElement extends PolymerElement { }; } + // Determine the scrolling container. + const pdfViewerUpdateEnabled = + document.documentElement.hasAttribute('pdf-viewer-update-enabled'); + const scrollContainer = pdfViewerUpdateEnabled ? + /** @type {!HTMLElement} */ (this.getSizer().offsetParent) : + document.documentElement; + // Create the viewport. const defaultZoom = this.browserApi.getZoomBehavior() === BrowserApi.ZoomBehavior.MANAGE ? this.browserApi.getDefaultZoom() : 1.0; + this.viewport_ = new Viewport( - window, this.getSizer(), this.getContent(), getScrollbarWidth(), - defaultZoom, this.getToolbarHeight()); + scrollContainer, this.getSizer(), this.getContent(), + getScrollbarWidth(), defaultZoom, this.getToolbarHeight(), + this.hasFixedToolbar()); this.viewport_.setViewportChangedCallback(() => this.viewportChanged_()); this.viewport_.setBeforeZoomCallback( () => this.currentController.beforeZoom()); - this.viewport_.setAfterZoomCallback( - () => this.currentController.afterZoom()); + this.viewport_.setAfterZoomCallback(() => { + this.currentController.afterZoom(); + this.afterZoom(this.viewport_.getZoom()); + }); this.viewport_.setUserInitiatedCallback( userInitiated => this.setUserInitiated_(userInitiated)); window.addEventListener('beforeunload', () => this.resetTrackers_()); @@ -475,10 +500,6 @@ export class PDFViewerBaseElement extends PolymerElement { this.viewport_.setZoomFactorRange(presetZoomFactors); this.strings = strings; - - // Display the zoom toolbar after the UI text direction is set, to ensure it - // appears on the correct side of the PDF viewer. - this.getZoomToolbar().hidden = false; } /** @@ -502,7 +523,8 @@ export class PDFViewerBaseElement extends PolymerElement { if (params.view) { this.isUserInitiatedEvent = false; - this.getZoomToolbar().forceFit(params.view); + this.updateViewportFit(params.view); + this.forceFit(params.view); if (params.viewPosition) { const zoomedPositionShift = params.viewPosition * this.viewport_.getZoom(); @@ -562,22 +584,27 @@ export class PDFViewerBaseElement extends PolymerElement { } /** - * Request to change the viewport fitting type. - * @param {!CustomEvent<FitToChangedEvent>} e + * @param {!FittingType} fittingType * @protected */ - onFitToChanged(e) { - if (e.detail.fittingType === FittingType.FIT_TO_PAGE) { + updateViewportFit(fittingType) { + if (fittingType === FittingType.FIT_TO_PAGE) { this.viewport_.fitToPage(); - } else if (e.detail.fittingType === FittingType.FIT_TO_WIDTH) { + } else if (fittingType === FittingType.FIT_TO_WIDTH) { this.viewport_.fitToWidth(); - } else if (e.detail.fittingType === FittingType.FIT_TO_HEIGHT) { + } else if (fittingType === FittingType.FIT_TO_HEIGHT) { this.viewport_.fitToHeight(); } + } - if (e.detail.userInitiated) { - PDFMetrics.recordFitTo(e.detail.fittingType); - } + /** + * Request to change the viewport fitting type. + * @param {!CustomEvent<!FittingType>} e + * @protected + */ + onFitToChanged(e) { + this.updateViewportFit(e.detail); + PDFMetrics.recordFitTo(e.detail); } /** @protected */ @@ -586,6 +613,15 @@ export class PDFViewerBaseElement extends PolymerElement { PDFMetrics.recordZoomAction(/*isZoomIn=*/ true); } + /** + * @param {!CustomEvent<number>} e + * @protected + */ + onZoomChanged(e) { + this.viewport_.setZoom(e.detail / 100); + PDFMetrics.record(PDFMetrics.UserAction.ZOOM_CUSTOM); + } + /** @protected */ onZoomOut() { this.viewport_.zoomOut(); @@ -594,14 +630,10 @@ export class PDFViewerBaseElement extends PolymerElement { /** * Handles a selected text reply from the current controller. - * @param {string} selectedText + * @param {!Object} message * @protected */ - handleSelectedTextReply(selectedText) { - const message = { - type: 'getSelectedTextReply', - selectedText: selectedText, - }; + handleSelectedTextReply(message) { if (this.overrideSendScriptingMessageForTest_) { this.overrideSendScriptingMessageForTest_ = false; try { diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.html b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.html index dac20fda069..339c41449e8 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.html +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.html @@ -8,10 +8,9 @@ <div id="sizer"></div> -<viewer-zoom-toolbar id="zoom-toolbar" strings="[[strings]]" +<viewer-zoom-toolbar id="zoom-toolbar" on-fit-to-changed="onFitToChanged" is-print-preview - on-zoom-in="onZoomIn" on-zoom-out="onZoomOut" - hidden> + on-zoom-in="onZoomIn" on-zoom-out="onZoomOut"> </viewer-zoom-toolbar> <viewer-error-screen id="error-screen"></viewer-error-screen> diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js index 6fa9a6f3e3c..a719346fca3 100644 --- a/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js +++ b/chromium/chrome/browser/resources/pdf/pdf_viewer_pp.js @@ -4,6 +4,7 @@ import './elements/viewer-error-screen.js'; import './elements/viewer-page-indicator.js'; +import './elements/viewer-zoom-toolbar.js'; import './elements/shared-vars.js'; import './pdf_viewer_shared_style.js'; @@ -56,11 +57,6 @@ class PDFViewerPPElement extends PDFViewerBaseElement { } /** @override */ - getZoomToolbar() { - return /** @type {!ViewerZoomToolbarElement} */ (this.$$('#zoom-toolbar')); - } - - /** @override */ getErrorScreen() { return /** @type {!ViewerErrorScreenElement} */ (this.$$('#error-screen')); } @@ -70,12 +66,20 @@ class PDFViewerPPElement extends PDFViewerBaseElement { return PRINT_PREVIEW_BACKGROUND_COLOR; } + /** + * @return {!ViewerZoomToolbarElement} + * @private + */ + getZoomToolbar_() { + return /** @type {!ViewerZoomToolbarElement} */ (this.$$('#zoom-toolbar')); + } + /** @param {!BrowserApi} browserApi */ init(browserApi) { super.init(browserApi); this.toolbarManager_ = - new ToolbarManager(window, null, this.getZoomToolbar()); + new ToolbarManager(window, null, this.getZoomToolbar_()); // Setup the keyboard event listener. document.addEventListener( @@ -120,7 +124,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { return; case '\\': if (e.ctrlKey) { - this.getZoomToolbar().fitToggleFromHotKey(); + this.getZoomToolbar_().fitToggleFromHotKey(); } return; case ']': @@ -165,7 +169,7 @@ class PDFViewerPPElement extends PDFViewerBaseElement { // than the spec. In LTR layout, the zoom toolbar is on the left // left side, but the scrollbar is still on the right, so this is not // necessary. - const zoomToolbar = this.getZoomToolbar(); + const zoomToolbar = this.getZoomToolbar_(); if (isRTL()) { zoomToolbar.style.right = -verticalScrollbarWidth + (scrollbarWidth / 2) + 'px'; @@ -205,7 +209,8 @@ class PDFViewerPPElement extends PDFViewerBaseElement { switch (message.data.type.toString()) { case 'getSelectedText': - this.pluginController.getSelectedText(); + this.pluginController.getSelectedText().then( + this.sendScriptingMessage.bind(this)); break; case 'selectAll': this.pluginController.selectAll(); @@ -234,7 +239,8 @@ class PDFViewerPPElement extends PDFViewerBaseElement { if (!this.inPrintPreviewMode_) { this.inPrintPreviewMode_ = true; this.isUserInitiatedEvent = false; - this.getZoomToolbar().forceFit(FittingType.FIT_TO_PAGE); + this.forceFit(FittingType.FIT_TO_PAGE); + this.updateViewportFit(FittingType.FIT_TO_PAGE); this.isUserInitiatedEvent = true; } @@ -284,10 +290,6 @@ class PDFViewerPPElement extends PDFViewerBaseElement { this.setDocumentDimensions( /** @type {!DocumentDimensionsMessageData} */ (data)); return; - case 'getSelectedTextReply': - this.handleSelectedTextReply( - /** @type {{ selectedText: string }} */ (data).selectedText); - return; case 'loadProgress': this.updateProgress( /** @type {{ progress: number }} */ (data).progress); @@ -305,10 +307,6 @@ class PDFViewerPPElement extends PDFViewerBaseElement { this.viewportScroller.setEnableScrolling( /** @type {{ isSelecting: boolean }} */ (data).isSelecting); return; - case 'getNamedDestinationReply': - this.paramsParser.onNamedDestinationReceived( - /** @type {{ pageNumber: number }} */ (data).pageNumber); - return; case 'touchSelectionOccurred': this.sendScriptingMessage({ type: 'touchSelectionOccurred', @@ -345,9 +343,13 @@ class PDFViewerPPElement extends PDFViewerBaseElement { } /** @override */ + forceFit(view) { + this.getZoomToolbar_().forceFit(view); + } + + /** @override */ handleStrings(strings) { super.handleStrings(strings); - if (!strings) { return; } diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js index 3e68d39f673..bf0a8e73511 100644 --- a/chromium/chrome/browser/resources/pdf/viewport.js +++ b/chromium/chrome/browser/resources/pdf/viewport.js @@ -6,7 +6,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {$, hasKeyModifiers} from 'chrome://resources/js/util.m.js'; -import {FittingType} from './constants.js'; +import {FittingType, Point} from './constants.js'; import {GestureDetector, PinchEventDetail} from './gesture_detector.js'; import {InactiveZoomManager, ZoomManager} from './zoom_manager.js'; @@ -28,9 +28,6 @@ let DocumentDimensions; */ export let LayoutOptions; -/** @typedef {{x: number, y: number}} */ -export let Point; - /** @typedef {{x: (number|undefined), y: (number|undefined)}} */ export let PartialPoint; @@ -69,7 +66,7 @@ function vectorDelta(p1, p2) { export class Viewport { /** - * @param {!Window} window + * @param {!HTMLElement} scrollParent * @param {!HTMLDivElement} sizer The element which represents the size of the * document in the viewport * @param {!HTMLDivElement} content The element which is the parent of the @@ -78,11 +75,14 @@ export class Viewport { * @param {number} defaultZoom The default zoom level. * @param {number} topToolbarHeight The number of pixels that should initially * be left blank above the document for the toolbar. + * @param {boolean} topToolbarFixed True if the top toolbar is fixed and does + * not automatically disappear in fit to page mode. */ constructor( - window, sizer, content, scrollbarWidth, defaultZoom, topToolbarHeight) { - /** @private {!Window} */ - this.window_ = window; + scrollParent, sizer, content, scrollbarWidth, defaultZoom, + topToolbarHeight, topToolbarFixed) { + /** @private {!HTMLElement} */ + this.window_ = scrollParent; /** @private {!HTMLDivElement} */ this.sizer_ = sizer; @@ -99,6 +99,9 @@ export class Viewport { /** @private {number} */ this.topToolbarHeight_ = topToolbarHeight; + /** @private {boolean} */ + this.topToolbarFixed_ = topToolbarFixed; + /** @private {function():void} */ this.viewportChangedCallback_ = function() {}; @@ -185,8 +188,19 @@ export class Viewport { // Set to a default zoom manager - used in tests. this.setZoomManager(new InactiveZoomManager(this.getZoom.bind(this), 1)); - window.addEventListener('scroll', this.updateViewport_.bind(this)); + if (this.window_ === document.documentElement) { + window.addEventListener('scroll', this.updateViewport_.bind(this)); + // The following line is only used in tests, since they expect + // |scrollCallback| to be called on the mock |window_| object (legacy). + this.window_.scrollCallback = this.updateViewport_.bind(this); + } else { + this.window_.addEventListener('scroll', this.updateViewport_.bind(this)); + } + window.addEventListener('resize', this.resizeWrapper_.bind(this)); + // The following line is only used in tests, since they expect + // |resizeCallback| to be called on the mock |window_| object (legacy). + this.window_.resizeCallback = this.resizeWrapper_.bind(this); document.body.addEventListener( 'change-zoom', e => this.setZoom(e.detail.zoom)); @@ -373,18 +387,10 @@ export class Viewport { return {horizontal: false, vertical: false}; } - // If scrollbars are required for one direction, expand the document in the - // other direction to take the width of the scrollbars into account when - // deciding whether the other direction needs scrollbars. - if (zoomedDimensions.width > this.window_.innerWidth) { - zoomedDimensions.height += this.scrollbarWidth_; - } else if (zoomedDimensions.height > this.window_.innerHeight) { - zoomedDimensions.width += this.scrollbarWidth_; - } return { - horizontal: zoomedDimensions.width > this.window_.innerWidth, + horizontal: zoomedDimensions.width > this.window_.offsetWidth, vertical: zoomedDimensions.height + this.topToolbarHeight_ > - this.window_.innerHeight + this.window_.offsetHeight }; } @@ -462,8 +468,8 @@ export class Viewport { /** @return {!Point} The scroll position of the viewport. */ get position() { return { - x: this.window_.pageXOffset, - y: this.window_.pageYOffset - this.topToolbarHeight_ + x: this.window_.scrollLeft, + y: this.window_.scrollTop - this.topToolbarHeight_ }; } @@ -477,13 +483,9 @@ export class Viewport { /** @return {!Size} the size of the viewport excluding scrollbars. */ get size() { - const needsScrollbars = this.documentNeedsScrollbars(this.getZoom()); - const scrollbarWidth = needsScrollbars.vertical ? this.scrollbarWidth_ : 0; - const scrollbarHeight = - needsScrollbars.horizontal ? this.scrollbarWidth_ : 0; return { - width: this.window_.innerWidth - scrollbarWidth, - height: this.window_.innerHeight - scrollbarHeight + width: this.window_.offsetWidth, + height: this.window_.offsetHeight, }; } @@ -798,8 +800,12 @@ export class Viewport { 'true.'); // First compute the zoom without scrollbars. + let height = this.window_.offsetHeight; + if (this.topToolbarFixed_) { + height -= this.topToolbarHeight_; + } let zoom = this.computeFittingZoomGivenDimensions_( - fitWidth, fitHeight, this.window_.innerWidth, this.window_.innerHeight, + fitWidth, fitHeight, this.window_.offsetWidth, height, pageDimensions.width, pageDimensions.height); // Check if there needs to be any scrollbars. @@ -815,18 +821,18 @@ export class Viewport { // Check if adding a scrollbar will result in needing the other scrollbar. const scrollbarWidth = this.scrollbarWidth_; if (needsScrollbars.horizontal && - zoomedDimensions.height > this.window_.innerHeight - scrollbarWidth) { + zoomedDimensions.height > this.window_.offsetHeight - scrollbarWidth) { needsScrollbars.vertical = true; } if (needsScrollbars.vertical && - zoomedDimensions.width > this.window_.innerWidth - scrollbarWidth) { + zoomedDimensions.width > this.window_.offsetWidth - scrollbarWidth) { needsScrollbars.horizontal = true; } // Compute available window space. const windowWithScrollbars = { - width: this.window_.innerWidth, - height: this.window_.innerHeight + width: this.window_.offsetWidth, + height: height, }; if (needsScrollbars.horizontal) { windowWithScrollbars.height -= scrollbarWidth; @@ -922,9 +928,10 @@ export class Viewport { }; this.setZoomInternal_(this.computeFittingZoom_(dimensions, false, true)); if (scrollToTopOfPage) { + const offset = this.topToolbarFixed_ ? this.topToolbarHeight_ : 0; this.position = { x: 0, - y: this.pageDimensions_[page].y * this.getZoom() + y: this.pageDimensions_[page].y * this.getZoom() - offset, }; } this.updateViewport_(); @@ -957,9 +964,10 @@ export class Viewport { }; this.setZoomInternal_(this.computeFittingZoom_(dimensions, true, true)); if (scrollToTopOfPage) { + const offset = this.topToolbarFixed_ ? this.topToolbarHeight_ : 0; this.position = { x: 0, - y: this.pageDimensions_[page].y * this.getZoom() + y: this.pageDimensions_[page].y * this.getZoom() - offset, }; } this.updateViewport_(); @@ -1219,7 +1227,7 @@ export class Viewport { // Unless we're in fit to page or fit to height mode, scroll above the // page by |this.topToolbarHeight_| so that the toolbar isn't covering it // initially. - if (!this.isPagedMode_()) { + if (!this.isPagedMode_() || this.topToolbarFixed_) { toolbarOffset = this.topToolbarHeight_; } this.position = { @@ -1297,8 +1305,8 @@ export class Viewport { spaceOnLeft = Math.max(spaceOnLeft, 0); return { - x: x * zoom + spaceOnLeft - this.window_.pageXOffset, - y: insetDimensions.y * zoom - this.window_.pageYOffset, + x: x * zoom + spaceOnLeft - this.window_.scrollLeft, + y: insetDimensions.y * zoom - this.window_.scrollTop, width: insetDimensions.width * zoom, height: insetDimensions.height * zoom }; @@ -1383,7 +1391,7 @@ export class Viewport { } this.sentPinchEvent_ = true; - this.window_.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { this.sentPinchEvent_ = false; this.mightZoom_(() => { const {direction, center, startScaleRatio} = e.detail; @@ -1411,8 +1419,8 @@ export class Viewport { // using the gesture center. if (!needsScrollbars.horizontal) { this.pinchCenter_ = { - x: this.window_.innerWidth / 2, - y: this.window_.innerHeight / 2 + x: this.window_.offsetWidth / 2, + y: this.window_.offsetHeight / 2 }; } else if (this.keepContentCentered_) { this.oldCenterInContent_ = @@ -1436,7 +1444,7 @@ export class Viewport { onPinchEnd_(e) { // Using rAF for pinch end prevents pinch updates scheduled by rAF getting // sent after the pinch end. - this.window_.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { this.mightZoom_(() => { const {center, startScaleRatio} = e.detail; this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; @@ -1463,7 +1471,7 @@ export class Viewport { onPinchStart_(e) { // We also use rAF for pinch start, so that if there is a pinch end event // scheduled by rAF, this pinch start will be sent after. - this.window_.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { this.pinchPhase_ = Viewport.PinchPhase.PINCH_START; this.prevScale_ = 1; this.oldCenterInContent_ = diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.js b/chromium/chrome/browser/resources/print_preview/data/destination.js index a6938175df1..5a4870ff2f9 100644 --- a/chromium/chrome/browser/resources/print_preview/data/destination.js +++ b/chromium/chrome/browser/resources/print_preview/data/destination.js @@ -408,6 +408,13 @@ export class Destination { this.certificateStatus_ = opt_params && opt_params.certificateStatus || DestinationCertificateStatus.NONE; + /** + * Whether cloud print deprecation warnings are suppressed. + * @private {boolean} + */ + this.cloudPrintDeprecationWarningsSuppressed_ = + loadTimeData.getBoolean('cloudPrintDeprecationWarningsSuppressed'); + // <if expr="chromeos"> /** * EULA url for printer's PPD. Empty string indicates no provided EULA. @@ -525,7 +532,9 @@ export class Destination { * if it was not provided. */ get description() { - return this.description_; + return this.shouldShowSaveToDriveWarning ? + loadTimeData.getString('destinationNotSupportedWarning') : + this.description_; } /** @@ -648,6 +657,16 @@ export class Destination { } /** + * @return {boolean} Whether the destination's description and icon should + * warn that it is a deprecated printer. + */ + get shouldShowDeprecatedPrinterWarning() { + return !this.cloudPrintDeprecationWarningsSuppressed_ && + this.id_ !== Destination.GooglePromotedId.DOCS && + (this.isPrivet || CloudOrigins.includes(this.origin_)); + } + + /** * @return {boolean} Whether the destination should display an invalid * certificate UI warning in the selection dialog and cause a UI * warning to appear in the preview area when selected. @@ -657,6 +676,20 @@ export class Destination { !loadTimeData.getBoolean('isEnterpriseManaged'); } + /** + * @return {boolean} Whether this destination's description and icon should + * warn that "Save to Drive" is deprecated. + */ + get shouldShowSaveToDriveWarning() { + let shouldShowSaveToDriveWarning = false; + // <if expr="not chromeos"> + shouldShowSaveToDriveWarning = + this.id_ === Destination.GooglePromotedId.DOCS && + !this.cloudPrintDeprecationWarningsSuppressed_; + // </if> + return shouldShowSaveToDriveWarning; + } + /** @return {boolean} Whether the destination is considered offline. */ get isOffline() { return [ @@ -713,6 +746,12 @@ export class Destination { /** @return {string} Path to the SVG for the destination's icon. */ get icon() { + if (this.shouldShowSaveToDriveWarning) { + return 'print-preview:save-to-drive-not-supported'; + } + if (this.shouldShowDeprecatedPrinterWarning) { + return 'print-preview:printer-not-supported'; + } if (this.id_ === Destination.GooglePromotedId.DOCS) { return 'print-preview:save-to-drive'; } @@ -790,7 +829,7 @@ export class Destination { } /** - * @return (Object} Copies capability of this destination. + * @return {Object} Copies capability of this destination. * @private */ copiesCapability_() { @@ -971,9 +1010,19 @@ Destination.LOCATION_TAG_PREFIXES = */ Destination.GooglePromotedId = { DOCS: '__google__docs', - SAVE_AS_PDF: 'Save as PDF' + SAVE_AS_PDF: 'Save as PDF', + // <if expr="chromeos"> + SAVE_TO_DRIVE_CROS: 'Save to Drive CrOS', + // </if> }; /** @type {string} Unique identifier for the Save as PDF destination */ export const PDF_DESTINATION_KEY = `${Destination.GooglePromotedId.SAVE_AS_PDF}/${DestinationOrigin.LOCAL}/`; + +// <if expr="chromeos"> +/** @type {string} Unique identifier for the Save to Drive CrOS destination */ +export const SAVE_TO_DRIVE_CROS_DESTINATION_KEY = + `${Destination.GooglePromotedId.SAVE_TO_DRIVE_CROS}/${ + DestinationOrigin.LOCAL}/`; +// </if> diff --git a/chromium/chrome/browser/resources/print_preview/data/destination_store.js b/chromium/chrome/browser/resources/print_preview/data/destination_store.js index 2844928fe10..4304239ea6b 100644 --- a/chromium/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chromium/chrome/browser/resources/print_preview/data/destination_store.js @@ -279,6 +279,11 @@ export class DestinationStore extends EventTarget { this.useSystemDefaultAsDefault_ = loadTimeData.getBoolean('useSystemDefaultPrinter'); + // <if expr="chromeos"> + /** @private */ + this.saveToDriveFlagEnabled_ = loadTimeData.getBoolean('printSaveToDrive'); + // </if> + addListenerCallback('printers-added', this.onPrintersAdded_.bind(this)); } @@ -348,6 +353,11 @@ export class DestinationStore extends EventTarget { this.pdfPrinterEnabled_ = !pdfPrinterDisabled; this.systemDefaultDestinationId_ = systemDefaultDestinationId; this.createLocalPdfPrintDestination_(); + // <if expr="chromeos"> + if (this.saveToDriveFlagEnabled_) { + this.createLocalDrivePrintDestination_(); + } + // </if> let destinationSelected = false; // System default printer policy takes priority. @@ -1127,6 +1137,19 @@ export class DestinationStore extends EventTarget { } } + // <if expr="chromeos"> + /** + * Creates a local Drive print destination. + * @private + */ + createLocalDrivePrintDestination_() { + this.insertDestination_(new Destination( + Destination.GooglePromotedId.SAVE_TO_DRIVE_CROS, DestinationType.LOCAL, + DestinationOrigin.LOCAL, loadTimeData.getString('printToGoogleDrive'), + DestinationConnectionStatus.ONLINE)); + } + // </if> + /** * Starts a timeout to select the default destination. * @private @@ -1135,7 +1158,7 @@ export class DestinationStore extends EventTarget { clearTimeout(this.autoSelectTimeout_); this.autoSelectTimeout_ = setTimeout( this.selectDefaultDestination.bind(this), - DestinationStore.AUTO_SELECT_TIMEOUT_); + DestinationStore.AUTO_SELECT_TIMEOUT); } /** @@ -1370,10 +1393,10 @@ DestinationStore.EventType = { * Delay in milliseconds before the destination store ignores the initial * destination ID and just selects any printer (since the initial destination * was not found). - * @private {number} - * @const + * Public and non-const so that it can be overridden in tests. + * @type {number} */ -DestinationStore.AUTO_SELECT_TIMEOUT_ = 15000; +DestinationStore.AUTO_SELECT_TIMEOUT = 15000; /** * Maximum amount of time spent searching for extension destinations, in diff --git a/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js b/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js index 0cc0c513121..dc597c08aa9 100644 --- a/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js +++ b/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js @@ -8,23 +8,22 @@ * @enum {number} */ export const PrinterStatusReason = { - CONNECTING_TO_DEVICE: 0, - DEVICE_ERROR: 1, - DOOR_OPEN: 2, - LOW_ON_INK: 3, - LOW_ON_PAPER: 4, - NO_ERROR: 5, - OUT_OF_INK: 6, - OUT_OF_PAPER: 7, - OUTPUT_ALMOST_FULL: 8, - OUTPUT_FULL: 9, - PAPER_JAM: 10, - PAUSED: 11, - PRINTER_QUEUE_FULL: 12, - PRINTER_UNREACHABLE: 13, - STOPPED: 14, - TRAY_MISSING: 15, - UNKNOWN_REASON: 16, + DEVICE_ERROR: 0, + DOOR_OPEN: 1, + LOW_ON_INK: 2, + LOW_ON_PAPER: 3, + NO_ERROR: 4, + OUT_OF_INK: 5, + OUT_OF_PAPER: 6, + OUTPUT_ALMOST_FULL: 7, + OUTPUT_FULL: 8, + PAPER_JAM: 9, + PAUSED: 10, + PRINTER_QUEUE_FULL: 11, + PRINTER_UNREACHABLE: 12, + STOPPED: 13, + TRAY_MISSING: 14, + UNKNOWN_REASON: 15, }; /** @@ -33,7 +32,7 @@ export const PrinterStatusReason = { * @enum {number} */ export const PrinterStatusSeverity = { - UNKOWN_SEVERITY: 0, + UNKNOWN_SEVERITY: 0, REPORT: 1, WARNING: 2, ERROR: 3, @@ -54,3 +53,21 @@ export const PrinterStatusSeverity = { * }} */ export let PrinterStatus; + +/** @const {!Map<!PrinterStatusReason, string>} */ +export const ERROR_STRING_KEY_MAP = new Map([ + [PrinterStatusReason.DEVICE_ERROR, 'printerStatusDeviceError'], + [PrinterStatusReason.DOOR_OPEN, 'printerStatusDoorOpen'], + [PrinterStatusReason.LOW_ON_INK, 'printerStatusLowOnInk'], + [PrinterStatusReason.LOW_ON_PAPER, 'printerStatusLowOnPaper'], + [PrinterStatusReason.OUT_OF_INK, 'printerStatusOutOfInk'], + [PrinterStatusReason.OUT_OF_PAPER, 'printerStatusOutOfPaper'], + [PrinterStatusReason.OUTPUT_ALMOST_FULL, 'printerStatusOutputAlmostFull'], + [PrinterStatusReason.OUTPUT_FULL, 'printerStatusOutputFull'], + [PrinterStatusReason.PAPER_JAM, 'printerStatusPaperJam'], + [PrinterStatusReason.PAUSED, 'printerStatusPaused'], + [PrinterStatusReason.PRINTER_QUEUE_FULL, 'printerStatusPrinterQueueFull'], + [PrinterStatusReason.PRINTER_UNREACHABLE, 'printerStatusPrinterUnreachable'], + [PrinterStatusReason.STOPPED, 'printerStatusStopped'], + [PrinterStatusReason.TRAY_MISSING, 'printerStatusTrayMissing'], +]); diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js index a7f13fc56bb..f9dbfafba28 100644 --- a/chromium/chrome/browser/resources/print_preview/native_layer.js +++ b/chromium/chrome/browser/resources/print_preview/native_layer.js @@ -9,9 +9,11 @@ import {Cdd, Destination} from './data/destination.js'; import {PrinterType} from './data/destination_match.js'; // <if expr="chromeos"> import {DestinationPolicies} from './data/destination_policies.js'; -import {PrinterStatus} from './data/printer_status_cros.js'; // </if> import {MeasurementSystemUnitType} from './data/measurement_system.js'; +// <if expr="chromeos"> +import {PrinterStatus, PrinterStatusReason} from './data/printer_status_cros.js'; +// </if> /** * @typedef {{selectSaveAsPdfDestination: boolean, @@ -266,10 +268,8 @@ export class NativeLayer { /** * Opens the Google Cloud Print sign-in tab. If the user signs in * successfully, the user-accounts-updated event will be sent in response. - * @param {boolean} addAccount Whether to open an 'add a new account' or - * default sign in page. */ - signIn(addAccount) {} + signIn() {} // <if expr="chromeos"> /** @@ -278,6 +278,16 @@ export class NativeLayer { * @return {!Promise<!PrinterStatus>} */ requestPrinterStatusUpdate(printerId) {} + + /** + * Records the histogram to capture the printer status of the current + * destination and whether the user chose to print or cancel. + * @param {!PrinterStatusReason} statusReason Current destination printer + * status + * @param {boolean} didUserAttemptPrint True if user printed, false if user + * canceled. + */ + recordPrinterStatusHistogram(statusReason, didUserAttemptPrint) {} // </if> /** @@ -381,8 +391,8 @@ export class NativeLayerImpl { } /** @override */ - signIn(addAccount) { - chrome.send('signIn', [addAccount]); + signIn() { + chrome.send('signIn'); } // <if expr="chromeos"> @@ -390,6 +400,26 @@ export class NativeLayerImpl { requestPrinterStatusUpdate(printerId) { return sendWithPromise('requestPrinterStatus', printerId); } + + /** @override */ + recordPrinterStatusHistogram(statusReason, didUserAttemptPrint) { + let histogram; + switch (statusReason) { + case (PrinterStatusReason.NO_ERROR): + histogram = 'PrintPreview.PrinterStatus.AttemptedPrintWithGoodStatus'; + break; + case (PrinterStatusReason.UNKNOWN_REASON): + histogram = + 'PrintPreview.PrinterStatus.AttemptedPrintWithUnknownStatus'; + break; + default: + histogram = 'PrintPreview.PrinterStatus.AttemptedPrintWithErrorStatus'; + break; + } + chrome.send( + 'metricsHandler:recordBooleanHistogram', + [histogram, didUserAttemptPrint]); + } // </if> /** @override */ diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.js b/chromium/chrome/browser/resources/print_preview/print_preview.js index 10d3ac4aae4..b8a5e080852 100644 --- a/chromium/chrome/browser/resources/print_preview/print_preview.js +++ b/chromium/chrome/browser/resources/print_preview/print_preview.js @@ -7,12 +7,13 @@ import './ui/app.js'; export {PluralStringProxyImpl as PrintPreviewPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js'; export {CloudPrintInterface, CloudPrintInterfaceEventType} from './cloud_print_interface.js'; export {CloudPrintInterfaceImpl} from './cloud_print_interface_impl.js'; -export {ColorMode, createDestinationKey, Destination, DestinationCertificateStatus, DestinationConnectionStatus, DestinationOrigin, DestinationType, makeRecentDestination, RecentDestination} from './data/destination.js'; +export {Cdd, ColorMode, createDestinationKey, Destination, DestinationCertificateStatus, DestinationConnectionStatus, DestinationOrigin, DestinationType, makeRecentDestination, RecentDestination} from './data/destination.js'; +// <if expr="chromeos"> +export {SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from './data/destination.js'; +// </if> export {PrinterType} from './data/destination_match.js'; // <if expr="chromeos"> export {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from './data/destination_policies.js'; -export {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js'; -export {PrinterState} from './ui/printer_status_icon_cros.js'; // </if> export {DestinationErrorType, DestinationStore} from './data/destination_store.js'; export {PageLayoutInfo} from './data/document_info.js'; @@ -20,6 +21,9 @@ export {InvitationStore} from './data/invitation_store.js'; export {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './data/margins.js'; export {MeasurementSystem, MeasurementSystemUnitType} from './data/measurement_system.js'; export {DuplexMode, DuplexType, getInstance, whenReady} from './data/model.js'; +// <if expr="chromeos"> +export {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js'; +// </if> export {ScalingType} from './data/scaling.js'; export {Size} from './data/size.js'; export {Error, State} from './data/state.js'; @@ -27,7 +31,10 @@ export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, LocalDestinatio export {getSelectDropdownBackground} from './print_preview_utils.js'; export {DEFAULT_MAX_COPIES} from './ui/copies_settings.js'; export {DestinationState} from './ui/destination_settings.js'; -export {PluginProxy} from './ui/plugin_proxy.js'; +export {PDFPlugin, PluginProxy, PluginProxyImpl} from './ui/plugin_proxy.js'; export {PreviewAreaState} from './ui/preview_area.js'; +// <if expr="chromeos"> +export {PrinterState} from './ui/printer_status_icon_cros.js'; +// </if> export {SelectBehavior} from './ui/select_behavior.js'; export {SelectOption} from './ui/settings_select.js'; diff --git a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn index d95c0bb6565..4954831e379 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn +++ b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn @@ -309,9 +309,11 @@ js_library("duplex_settings") { ":settings_behavior", "..:print_preview_utils", "../data:model", + "//third_party/polymer/v3_0/components-chromium/iron-collapse:iron-collapse", "//third_party/polymer/v3_0/components-chromium/iron-iconset-svg:iron-iconset-svg", "//third_party/polymer/v3_0/components-chromium/iron-meta:iron-meta", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", ] } diff --git a/chromium/chrome/browser/resources/print_preview/ui/app.js b/chromium/chrome/browser/resources/print_preview/ui/app.js index 5c7b6601686..b638a9d5b36 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/app.js +++ b/chromium/chrome/browser/resources/print_preview/ui/app.js @@ -18,7 +18,7 @@ import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bun import {CloudPrintInterface, CloudPrintInterfaceErrorEventDetail, CloudPrintInterfaceEventType} from '../cloud_print_interface.js'; import {CloudPrintInterfaceImpl} from '../cloud_print_interface_impl.js'; -import {Destination} from '../data/destination.js'; +import {Destination, DestinationOrigin} from '../data/destination.js'; import {DocumentSettings} from '../data/document_info.js'; import {Margins} from '../data/margins.js'; import {MeasurementSystem} from '../data/measurement_system.js'; @@ -217,6 +217,14 @@ Polymer({ this.close_(); e.preventDefault(); } + + // <if expr="chromeos"> + if (this.destination_ && + this.destination_.origin === DestinationOrigin.CROS) { + this.nativeLayer_.recordPrinterStatusHistogram( + this.destination_.printerStatusReason, false); + } + // </if> return; } @@ -466,12 +474,26 @@ Polymer({ this.printRequested_ = true; return; } + // <if expr="chromeos"> + if (this.destination_ && + this.destination_.origin === DestinationOrigin.CROS) { + this.nativeLayer_.recordPrinterStatusHistogram( + this.destination_.printerStatusReason, true); + } + // </if> this.$.state.transitTo( this.$.previewArea.previewLoaded() ? State.PRINTING : State.HIDDEN); }, /** @private */ onCancelRequested_() { + // <if expr="chromeos"> + if (this.destination_ && + this.destination_.origin === DestinationOrigin.CROS) { + this.nativeLayer_.recordPrinterStatusHistogram( + this.destination_.printerStatusReason, false); + } + // </if> this.cancelled_ = true; this.$.state.transitTo(State.CLOSING); }, diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html index 56a6a8d8ee6..bc7f30dba38 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html @@ -62,33 +62,12 @@ } } - #dialog .promo { + #invitationPromo { align-items: center; color: var(--cr-primary-text-color); display: flex; - padding: 16px 20px; - } - - #cloudprintPromo .promo-text { - flex: 1; - } - - #cloudprintPromo iron-icon { - margin-inline-end: 16px; - width: 20px; - } - - #cloudPrintClose { - --cr-icon-button-size: 20px; - --cr-icon-button-icon-size: 16px; - margin-inline-start: 16px; - min-height: 14px; - min-width: 14px; - padding: 0; - } - - #invitationPromo { flex-direction: column; + padding: 16px 20px; text-align: center; } @@ -112,6 +91,24 @@ font-size: calc(10 / 13 * 1em); font-weight: 500; } + + .destinations-status { + align-items: center; + display: flex; + margin-bottom: 16px; + } + + iron-icon { + --google-orange-600: rgb(232, 113, 10); /* e8710a */ + fill: var(--google-orange-600); + flex-shrink: 0; + padding-inline-end: 8px; + padding-inline-start: 4px; + } + + #warning-message { + color: var(--cr-primary-text-color); + } </style> <cr-dialog id="dialog" on-close="onCloseOrCancel_"> <div slot="title" id="header">$i18n{destinationSearchTitle}</div> @@ -126,6 +123,13 @@ <option value="">$i18n{addAccountTitle}</option> </select> </div> + <div class="destinations-status" hidden$="[[!showCloudPrintWarning_]]"> + <iron-icon icon="cr:warning" aria-label="$i18n{warningIconAriaLabel}"> + </iron-icon> + <span id="warning-message"> + $i18nRaw{cloudPrintingNotSupportedWarning} + </span> + </div> <print-preview-search-box id="searchBox" label="$i18n{searchBoxPlaceholder}" search-query="{{searchQuery_}}" autofocus> @@ -148,16 +152,8 @@ $i18n{cancel} </cr-button> </div> - <div id="promos" slot="footer" hidden="[[!shouldShowFooter_( - shouldShowCloudPrintPromo_, invitation_)]]"> - <div class="promo" id="cloudprintPromo" - hidden$="[[!shouldShowCloudPrintPromo_]]"> - <iron-icon icon="print-preview:cloud-queue" alt=""></iron-icon> - <div class="promo-text"></div> - <cr-icon-button id="cloudPrintClose" class="icon-clear" - on-click="onCloudPrintPromoDismissed_"></cr-icon-button> - </div> - <div class="promo" id="invitationPromo" hidden="[[!invitation_]]"> + <div id="promos" slot="footer" hidden="[[!invitation_]]"> + <div id="invitationPromo"> <div inner-h-t-m-l="[[getInvitationText_(invitation_)]]"></div> <div class="invitation-buttons"> <cr-button on-click="onInvitationAcceptClick_"> diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js index c3b9f5bbd2c..986d90919d8 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js @@ -4,15 +4,13 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; -import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; import 'chrome://resources/cr_elements/hidden_style_css.m.js'; -import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/js/action_link.js'; import 'chrome://resources/cr_elements/action_link_css.m.js'; import 'chrome://resources/cr_elements/md_select_css.m.js'; +import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import './icons.js'; import '../print_preview_utils.js'; import './destination_list.js'; import './print_preview_search_box.js'; @@ -71,14 +69,6 @@ Polymer({ value: null, }, - cloudPrintDisabled: Boolean, - - /** @private */ - cloudPrintPromoDismissed_: { - type: Boolean, - value: false, - }, - /** @private {!Array<!Destination>} */ destinations_: { type: Array, @@ -91,19 +81,18 @@ Polymer({ value: false, }, + /** @private {boolean} */ + showCloudPrintWarning_: { + type: Boolean, + computed: 'computeShowCloudPrintWarning_(destinations_.splices)', + value: false, + }, + /** @private {?RegExp} */ searchQuery_: { type: Object, value: null, }, - - /** @private {boolean} */ - shouldShowCloudPrintPromo_: { - type: Boolean, - computed: 'computeShouldShowCloudPrintPromo_(' + - 'cloudPrintDisabled, activeUser, cloudPrintPromoDismissed_)', - observer: 'onShouldShowCloudPrintPromoChanged_', - }, }, listeners: { @@ -125,26 +114,23 @@ Polymer({ initialized_: false, /** @override */ - ready() { - this.$$('.promo-text').innerHTML = - this.i18nAdvanced('cloudPrintPromotion', { - substitutions: ['<a is="action-link" class="sign-in">', '</a>'], - attrs: ['is', 'class', 'tabindex', 'role'], - }); - }, - - /** @override */ - attached() { - this.tracker_.add( - assert(this.$$('.sign-in')), 'click', this.onSignInClick_.bind(this)); - }, - - /** @override */ detached() { this.tracker_.removeAll(); }, /** + * @return {boolean} Whether the destinations dialog should show a Cloud Print + * deprecation warning. + * @private + */ + computeShowCloudPrintWarning_() { + return this.destinations_.some(destination => { + return destination.shouldShowSaveToDriveWarning || + destination.shouldShowDeprecatedPrinterWarning; + }); + }, + + /** * @param {!KeyboardEvent} e Event containing the key * @private */ @@ -332,17 +318,6 @@ Polymer({ return this.$.dialog.hasAttribute('open'); }, - /** @private */ - onSignInClick_() { - this.metrics_.record(Metrics.DestinationSearchBucket.SIGNIN_TRIGGERED); - NativeLayerImpl.getInstance().signIn(false); - }, - - /** @private */ - onCloudPrintPromoDismissed_() { - this.cloudPrintPromoDismissed_ = true; - }, - /** * Updates printer sharing invitations UI. * @private @@ -421,40 +396,12 @@ Polymer({ this.metrics_.record(Metrics.DestinationSearchBucket.ACCOUNT_CHANGED); } else { select.value = this.activeUser; - NativeLayerImpl.getInstance().signIn(true); + NativeLayerImpl.getInstance().signIn(); this.metrics_.record( Metrics.DestinationSearchBucket.ADD_ACCOUNT_SELECTED); } }, - /** - * @return {boolean} Whether to show the cloud print promo. - * @private - */ - computeShouldShowCloudPrintPromo_() { - return !this.activeUser && !this.cloudPrintDisabled && - !this.cloudPrintPromoDismissed_; - }, - - /** @private */ - onShouldShowCloudPrintPromoChanged_() { - if (this.shouldShowCloudPrintPromo_) { - this.metrics_.record(Metrics.DestinationSearchBucket.SIGNIN_PROMPT); - } else { - // Since the sign in link/dismiss promo button is disappearing, focus the - // search box. - this.$.searchBox.focus(); - } - }, - - /** - * @return {boolean} Whether to show the footer. - * @private - */ - shouldShowFooter_() { - return this.shouldShowCloudPrintPromo_ || !!this.invitation_; - }, - /** @private */ onOpenSettingsPrintPage_() { this.metrics_.record(Metrics.DestinationSearchBucket.MANAGE_BUTTON_CLICKED); diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html index c20bcbae4a6..42d687b895d 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html @@ -1,18 +1,17 @@ -<style include="cr-shared-style cr-hidden-style md-select"> - :host([opened_]) cr-input { - --cr-input-border-radius: 4px 4px 0 0; +<style include="cr-shared-style cr-hidden-style"> + #destination-dropdown { + outline: none; + position: relative; } - iron-dropdown, - cr-input { - width: var(--md-select-width); + #destination-dropdown:focus { + border-radius: 4px; + box-shadow: 0 0 0 2px rgba(var(--google-blue-600-rgb), .4); } - cr-input::part(input) { - opacity: 1; - padding-inline-end: 32px; - padding-inline-start: 8px; - text-overflow: clip; + #destination-dropdown, + iron-dropdown { + width: var(--print-preview-dropdown-width); } iron-dropdown { @@ -23,27 +22,14 @@ iron-dropdown [slot='dropdown-content'] { background-color: white; box-shadow: 0 2px 6px var(--google-grey-600); - min-width: var(--md-select-width); padding: 8px 0; } - #input-overlay { - border-radius: 4px; - height: 100%; - left: 0; - overflow: hidden; - pointer-events: none; - position: absolute; - top: 0; - width: 100%; - } - #dropdown-icon { - --iron-icon-height: 20px; - --iron-icon-width: 20px; - margin-top: -10px; - padding-inline-end: 6px; - position: absolute; + --iron-icon-height: 24px; + --iron-icon-width: 44px; + align-items: center; + margin-inline-start: -4px; right: 0; top: 50%; } @@ -53,20 +39,15 @@ right: unset; } - cr-input:focus-within #dropdown-icon { - --iron-icon-fill-color: var(--google-blue-600); - } - - #input-box { + #dropdown-box { + border-radius: 4px; height: 100%; left: 0; - pointer-events: none; - top: 0; - width: 100%; - } - - #dropdown-box { + margin-top: 24px; + overflow: hidden; pointer-events: initial; + position: absolute; + top: 0; width: 100%; } @@ -74,6 +55,7 @@ background: none; border: none; box-sizing: border-box; + cursor: pointer; font: inherit; min-height: 32px; padding: 0 8px; @@ -85,66 +67,107 @@ outline: none; } - .list-item[selected_] { + .list-item.highlighted { background-color: var(--google-blue-refresh-100); } - .dot { - background-color: #bbb; - border-radius: 50%; - display: inline-block; - height: 10px; - width: 10px; + #destination-icon-box, + .printer-display-name { + padding-inline-start: 8px; + } + + #destination-display-container { + align-items: center; + background-color: var(--google-grey-refresh-100); + border-radius: 4px; + cursor: pointer; + display: flex; + width: 100%; } - #pre-input-box, - .printer-display-name { + :host([disabled]) #destination-display-container { + cursor: default; + opacity: var(--cr-disabled-opacity); + } + + #destination-display { + box-sizing: border-box; + overflow: hidden; + padding-inline-end: 32px; padding-inline-start: 8px; + text-overflow: clip; + white-space: nowrap; + width: 100%; } </style> -<cr-input id="dropdownInput" on-keydown="onKeyDown_" - value="[[value.displayName]]" disabled="[[disabled]]" readonly> - <div id="pre-input-overlay" slot="inline-prefix"> - <div id="pre-input-box"> - <iron-icon icon="[[destinationIcon]]"></iron-icon> +<div id="destination-dropdown" on-keydown="onKeyDown_" tabindex="0" + on-blur="onBlur_" on-click="onClick_" role="button" aria-haspopup="true" + aria-label="$i18n{destinationLabel} [[value.displayName]]" + aria-description$="[[destinationStatusText]]"> + <div id="destination-display-container"> + <div id="destination-icon-box"> + <iron-icon icon="[[destinationIcon]]" + hidden="[[isCurrentDestinationCrosLocal]]"> + </iron-icon> + <printer-status-icon-cros id="destination-badge" + hidden="[[!isCurrentDestinationCrosLocal]]" + icon-location="[[IconLocation.DISPLAY]]" + printer-state="[[computePrinterState_( value.printerStatusReason)]]"> + </printer-status-icon-cros> </div> + <div id="destination-display">[[value.displayName]]</div> + <iron-icon id="dropdown-icon" icon="cr:arrow-drop-down"></iron-icon> </div> - <div id="input-overlay" slot="suffix"> - <div id="input-box"> - <iron-icon id="dropdown-icon" icon="cr:arrow-drop-down"></iron-icon> - </div> - <div id="dropdown-box"> - <iron-dropdown horizontal-align="left" vertical-align="top" - vertical-offset="0" no-cancel-on-outside-click - no-cancel-on-esc-key> - <div slot="dropdown-content"> - <template is="dom-repeat" items="[[itemList]]"> - <button id="[[item.key]]" class="list-item" on-click="onSelect_" - tabindex="-1" value="[[item.key]]"> - <printer-status-icon-cros background="white" - state$="[[computePrinterState_(item.printerStatusReason)]]"> - </printer-status-icon-cros> - <span class="printer-display-name">[[item.displayName]]</span> - </button> - </template> - <button class="list-item" on-click="onSelect_" tabindex="-1" - value="[[pdfDestinationKey]]" hidden$="[[pdfPrinterDisabled]]"> - $i18n{printToPDF} - </button> - <button class="list-item" on-click="onSelect_" tabindex="-1" - value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]"> - $i18n{printToGoogleDrive} - </button> - <button class="list-item" on-click="onSelect_" tabindex="-1" - value="noDestinations" hidden$="[[!noDestinations]]"> - $i18n{noDestinationsMessage} + <div id="dropdown-box"> + <iron-dropdown horizontal-align="left" vertical-align="top" + vertical-offset="0" no-cancel-on-outside-click + no-cancel-on-esc-key> + <div slot="dropdown-content"> + <template is="dom-repeat" items="[[itemList]]"> + <button id="[[item.key]]" tabindex="-1" value="[[item.key]]" + on-click="onSelect_" on-blur="onBlur_" role="menuitem" + aria-setsize$="[[dropdownLength_]]" + class$="list-item [[getHighlightedClass_(item.key, + highlightedIndex_)]]" + aria-description$="[[getPrinterStatusErrorString_( + item.printerStatusReason)]]"> + <printer-status-icon-cros icon-location="[[IconLocation.DROPDOWN]]" + printer-state="[[computePrinterState_( + item.printerStatusReason)]]" + class$="[[getHighlightedClass_(item.key, highlightedIndex_)]]"> + </printer-status-icon-cros> + <span class="printer-display-name">[[item.displayName]]</span> </button> - <button class="list-item" on-click="onSelect_" tabindex="-1" - value="seeMore" aria-label$="[[i18n(seeMoreDestinationsLabel)]]"> - $i18n{seeMore} - </button> - </div> - </iron-dropdown> - </div> + </template> + <button on-click="onSelect_" tabindex="-1" value="[[pdfDestinationKey]]" + hidden$="[[pdfPrinterDisabled]]" on-blur="onBlur_" role="menuitem" + aria-setsize$="[[dropdownLength_]]" + class$="list-item [[getHighlightedClass_(pdfDestinationKey, + highlightedIndex_)]]"> + $i18n{printToPDF} + </button> + <button on-click="onSelect_" tabindex="-1" on-blur="onBlur_" + value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]" + role="menuitem" aria-setsize$="[[dropdownLength_]]" + class$="list-item [[getHighlightedClass_(driveDestinationKey, + highlightedIndex_)]]"> + $i18n{printToGoogleDrive} + </button> + <button on-click="onSelect_" tabindex="-1" value="noDestinations" + hidden$="[[!noDestinations]]" on-blur="onBlur_" role="menuitem" + aria-setsize$="[[dropdownLength_]]" + class$="list-item [[getHighlightedClass_('noDestinations', + highlightedIndex_)]]"> + $i18n{noDestinationsMessage} + </button> + <button on-click="onSelect_" tabindex="-1" value="seeMore" + aria-label="$i18n{seeMoreDestinationsLabel}" on-blur="onBlur_" + role="menuitem" aria-setsize$="[[dropdownLength_]]" + class$="list-item [[getHighlightedClass_('seeMore', + highlightedIndex_)]]"> + $i18n{seeMore} + </button> + </div> + </iron-dropdown> </div> -</cr-input> +</div> diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js index 3d95796c331..7a5cbc57f04 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js @@ -2,26 +2,29 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import 'chrome://resources/cr_elements/hidden_style_css.m.js'; -import 'chrome://resources/cr_elements/md_select_css.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; // TODO(gavinwill): Remove iron-dropdown dependency https://crbug.com/1082587. import 'chrome://resources/polymer/v3_0/iron-dropdown/iron-dropdown.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import './print_preview_vars_css.js'; + +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {Destination} from '../data/destination.js'; -import {PrinterStatusReason} from '../data/printer_status_cros.js'; +import {Destination, DestinationOrigin} from '../data/destination.js'; +import {ERROR_STRING_KEY_MAP, PrinterStatusReason} from '../data/printer_status_cros.js'; -import {PrinterState} from './printer_status_icon_cros.js'; +import {IconLocation, PrinterState} from './printer_status_icon_cros.js'; Polymer({ is: 'print-preview-destination-dropdown-cros', _template: html`{__html_template__}`, + behaviors: [I18nBehavior], + properties: { /** @type {!Destination} */ value: Object, @@ -36,6 +39,8 @@ Polymer({ disabled: { type: Boolean, value: false, + observer: 'updateTabIndex_', + reflectToAttribute: true, }, driveDestinationKey: String, @@ -47,6 +52,26 @@ Polymer({ pdfDestinationKey: String, destinationIcon: String, + + isCurrentDestinationCrosLocal: Boolean, + + /** + * Index of the highlighted item in the dropdown. + * @private + */ + highlightedIndex_: Number, + + /** Mirroring the enum so that it can be used from HTML bindings. */ + IconLocation: Object, + + /** @private */ + dropdownLength_: { + type: Number, + computed: + 'computeDropdownLength_(itemList, pdfPrinterDisabled, driveDestinationKey, noDestinations, )', + }, + + destinationStatusText: String, }, listeners: { @@ -55,13 +80,8 @@ Polymer({ /** @override */ attached() { - this.pointerDownListener_ = event => this.onPointerDown_(event); - document.addEventListener('pointerdown', this.pointerDownListener_); - }, - - /** @override */ - detached() { - document.removeEventListener('pointerdown', this.pointerDownListener_); + this.updateTabIndex_(); + this.IconLocation = IconLocation; }, /** @@ -85,6 +105,8 @@ Polymer({ return; } + this.highlightedIndex_ = this.getButtonListFromDropdown_().findIndex( + item => item.value === this.value.key); this.$$('iron-dropdown').open(); this.opened_ = true; }, @@ -93,68 +115,49 @@ Polymer({ closeDropdown_() { this.$$('iron-dropdown').close(); this.opened_ = false; - - const selectedItem = this.findSelectedItem_(); - if (selectedItem) { - selectedItem.removeAttribute('selected_'); - } + this.highlightedIndex_ = -1; }, /** + * Highlight the item the mouse is hovering over. If the user uses the + * keyboard, the highlight will shift. But once the user moves the mouse, + * the highlight should be updated based on the location of the mouse + * cursor. * @param {!Event} event * @private */ onMouseMove_(event) { - const item = event.composedPath().find( - elm => elm.classList && elm.classList.contains('list-item')); + const item = /** @type {!Element} */ (event.composedPath().find( + elm => elm.classList && elm.classList.contains('list-item'))); if (!item) { return; } - - // Select the item the mouse is hovering over. If the user uses the - // keyboard, the selection will shift. But once the user moves the mouse, - // selection should be updated based on the location of the mouse cursor. - const selectedItem = this.findSelectedItem_(); - if (item === selectedItem) { - return; - } - - if (selectedItem) { - selectedItem.removeAttribute('selected_'); - } - item.setAttribute('selected_', ''); + this.highlightedIndex_ = this.getButtonListFromDropdown_().indexOf(item); }, - /** - * @param {!Event} event - * @private - */ - onPointerDown_(event) { - const paths = event.composedPath(); + /** @private */ + onClick_(event) { const dropdown = /** @type {!IronDropdownElement} */ (this.$$('iron-dropdown')); - const dropdownInput = - /** @type {!CrInputElement} */ (this.$$('#dropdownInput')); - // Exit if path includes |dropdown| because event will be handled by // onSelect_. - if (paths.includes(dropdown)) { + if (event.composedPath().includes(dropdown)) { return; } - if (!paths.includes(dropdownInput) || dropdown.opened) { + if (dropdown.opened) { this.closeDropdown_(); return; } - this.openDropdown_(); }, - /** @private */ - onSelect_() { - const selectedItem = this.findSelectedItem_(); - this.closeDropdown_(); - this.fire('dropdown-value-selected', selectedItem); + /** + * @param {!Event} event + * @private + */ + onSelect_(event) { + this.dropdownValueSelected_(/** @type {!Element} */ (event.currentTarget)); }, /** @@ -165,21 +168,14 @@ Polymer({ event.stopPropagation(); const dropdown = this.$$('iron-dropdown'); switch (event.code) { - case 'Tab': - this.closeDropdown_(); - break; case 'ArrowUp': - case 'ArrowDown': { - const items = dropdown.getElementsByClassName('list-item'); - if (items.length === 0) { - break; - } - this.updateSelected_(event.code === 'ArrowDown'); + case 'ArrowDown': + this.onArrowKeyPress_(event.code); break; - } case 'Enter': { if (dropdown.opened) { - this.onSelect_(); + this.dropdownValueSelected_( + this.getButtonListFromDropdown_()[this.highlightedIndex_]); break; } this.openDropdown_(); @@ -196,52 +192,62 @@ Polymer({ }, /** - * Updates the currently selected element based on keyboard up/down movement. - * @param {boolean} moveDown + * @param {string} eventCode * @private */ - updateSelected_(moveDown) { + onArrowKeyPress_(eventCode) { + const dropdown = this.$$('iron-dropdown'); const items = this.getButtonListFromDropdown_(); - const numItems = items.length; - if (numItems === 0) { + if (items.length === 0) { + return; + } + + // If the dropdown is open, use the arrow key press to change which item is + // highlighted in the dropdown. If the dropdown is closed, use the arrow key + // press to change the selected destination. + if (dropdown.opened) { + const nextIndex = this.getNextItemIndexInList_( + eventCode, this.highlightedIndex_, items.length); + if (nextIndex === -1) { + return; + } + this.highlightedIndex_ = nextIndex; + items[this.highlightedIndex_].focus(); return; } - let nextIndex = 0; - const currentIndex = this.findSelectedItemIndex_(); - if (currentIndex === -1) { - nextIndex = moveDown ? 0 : numItems - 1; - } else { - const delta = moveDown ? 1 : -1; - nextIndex = (numItems + currentIndex + delta) % numItems; - items[currentIndex].removeAttribute('selected_'); + const currentIndex = items.findIndex(item => item.value === this.value.key); + const nextIndex = + this.getNextItemIndexInList_(eventCode, currentIndex, items.length); + if (nextIndex === -1) { + return; } - items[nextIndex].setAttribute('selected_', ''); - // The newly selected item might not be visible because the dropdown needs - // to be scrolled. So scroll the dropdown if necessary. - items[nextIndex].scrollIntoViewIfNeeded(); + this.fire('dropdown-value-selected', items[nextIndex]); }, /** - * Finds the currently selected dropdown item. - * @return {Element|undefined} Currently selected dropdown item, or undefined - * if no item is selected. + * @param {string} eventCode + * @param {number} currentIndex + * @param {number} numItems + * @return {number} Returns -1 when the next item would be outside the list. * @private */ - findSelectedItem_() { - const items = this.getButtonListFromDropdown_(); - return items.find(item => item.hasAttribute('selected_')); + getNextItemIndexInList_(eventCode, currentIndex, numItems) { + const nextIndex = + eventCode === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1; + return nextIndex >= 0 && nextIndex < numItems ? nextIndex : -1; }, /** - * Finds the index of currently selected dropdown item. - * @return {number} Index of the currently selected dropdown item, or -1 if - * no item is selected. + * @param {Element|undefined} dropdownItem * @private */ - findSelectedItemIndex_() { - const items = this.getButtonListFromDropdown_(); - return items.findIndex(item => item.hasAttribute('selected_')); + dropdownValueSelected_(dropdownItem) { + this.closeDropdown_(); + if (dropdownItem) { + this.fire('dropdown-value-selected', dropdownItem); + } + this.$$('#destination-dropdown').focus(); }, /** @@ -270,4 +276,76 @@ Polymer({ } return PrinterState.ERROR; }, + + /** + * Sets tabindex to -1 when dropdown is disabled to prevent the dropdown from + * being focusable. + * @private + */ + updateTabIndex_() { + this.$$('#destination-dropdown') + .setAttribute('tabindex', this.disabled ? '-1' : '0'); + }, + + /** + * Determines if an item in the dropdown should be highlighted based on the + * current value of |highlightedIndex_|. + * @param {string} itemValue + * @return {string} + * @private + */ + getHighlightedClass_(itemValue) { + const itemToHighlight = + this.getButtonListFromDropdown_()[this.highlightedIndex_]; + return itemToHighlight && itemValue === itemToHighlight.value ? + 'highlighted' : + ''; + }, + + /** + * Close the dropdown when focus is lost except when an item in the dropdown + * is the element that received the focus. + * @param {!Event} event + * @private + */ + onBlur_(event) { + if (!this.getButtonListFromDropdown_().includes( + /** @type {!Element} */ (event.relatedTarget))) { + this.closeDropdown_(); + } + }, + + /** + * @return {number} + * @private + */ + computeDropdownLength_() { + if (this.noDestinations) { + return 1; + } + + if (!this.itemList) { + return 0; + } + + // + 1 for "See more" + let length = this.itemList.length + 1; + if (!this.pdfPrinterDisabled) { + length++; + } + if (this.driveDestinationKey) { + length++; + } + return length; + }, + + /** + * @param {!PrinterStatusReason} printerStatusReason + * @return {string} + * @private + */ + getPrinterStatusErrorString_: function(printerStatusReason) { + const errorStringKey = ERROR_STRING_KEY_MAP.get(printerStatusReason); + return errorStringKey ? this.i18n(errorStringKey) : ''; + }, }); diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select.html b/chromium/chrome/browser/resources/print_preview/ui/destination_select.html index 4ec05c3fe7b..6d3d49c902e 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_select.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select.html @@ -1,4 +1,5 @@ -<style include="print-preview-shared throbber md-select destination-select cr-hidden-style"> +<style include="print-preview-shared throbber md-select destination-select + cr-hidden-style"> </style> <print-preview-settings-section> <span slot="title">$i18n{destinationLabel}</span> @@ -37,6 +38,6 @@ hidden$="[[!statusText_]]"> <div slot="title"></div> <div slot="controls"> - <div class="destination-status">[[statusText_]]</div> + <div class="destination-status"></div> </div> </print-preview-settings-section> diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select.js b/chromium/chrome/browser/resources/print_preview/ui/destination_select.js index 3232ecbedcd..2038919abc4 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_select.js +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select.js @@ -21,6 +21,7 @@ import './throbber_css.js'; import '../strings.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {Base, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination} from '../data/destination.js'; @@ -66,6 +67,7 @@ Polymer({ statusText_: { type: String, computed: 'computeStatusText_(destination)', + observer: 'onStatusTextSet_' }, }, @@ -103,6 +105,9 @@ Polymer({ // Check for the Docs or Save as PDF ids first. const keyParams = this.selectedValue.split('/'); if (keyParams[0] === Destination.GooglePromotedId.DOCS) { + if (!loadTimeData.getBoolean('cloudPrintDeprecationWarningsSuppressed')) { + return 'print-preview:save-to-drive-not-supported'; + } return 'print-preview:save-to-drive'; } if (keyParams[0] === Destination.GooglePromotedId.SAVE_AS_PDF) { @@ -158,8 +163,36 @@ Polymer({ return ''; } - return this.destination.shouldShowInvalidCertificateError ? - this.i18n('noLongerSupportedFragment') : - this.destination.connectionStatusText; + if (this.destination.shouldShowInvalidCertificateError) { + return this.i18n('noLongerSupportedFragment'); + } + + if (this.destination.shouldShowSaveToDriveWarning) { + return this.i18nAdvanced('saveToDriveNotSupportedWarning'); + } + + // Give preference to connection status. + if (this.destination.connectionStatusText) { + return this.destination.connectionStatusText; + } + + if (this.destination.shouldShowDeprecatedPrinterWarning) { + return this.i18nAdvanced('printerNotSupportedWarning'); + } + + return ''; + }, + + /** @private */ + onStatusTextSet_() { + this.$$('.destination-status').innerHTML = this.statusText_; }, + + /** + * Return the options currently visible to the user for testing purposes. + * @return {!NodeList<!Element>} + */ + getVisibleItemsForTest: function() { + return this.shadowRoot.querySelectorAll('option:not([hidden])'); + } }); diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html index 9ef6b0878c1..5d532695d67 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html @@ -1,4 +1,12 @@ <style include="print-preview-shared throbber md-select destination-select cr-hidden-style"> + :host([is-current-destination-cros-local_]) #statusText { + color: var(--google-red-600); + font-size: calc(10 / 13 * 1em); + overflow: hidden; + padding: 0; + text-overflow: ellipsis; + white-space: nowrap; + } </style> <print-preview-settings-section> <span slot="title">$i18n{destinationLabel}</span> @@ -8,7 +16,7 @@ </div> <template is="dom-if" if="[[!printerStatusFlagEnabled_]]"> <select id="dropdown" class="md-select" - aria-label$="[[i18n(destinationLabel)]]" hidden$="[[!loaded]]" + aria-label="$i18n{destinationLabel}" hidden$="[[!loaded]]" style="background-image:[[backgroundImages_]];" disabled$="[[disabled]]" value="{{selectedValue::change}}"> @@ -18,8 +26,8 @@ <option value="[[pdfDestinationKey_]]" hidden$="[[pdfPrinterDisabled]]"> $i18n{printToPDF} </option> - <option value="[[driveDestinationKey]]" - hidden$="[[!driveDestinationKey]]"> + <option value="[[driveDestinationKeyCros_]]" + hidden$="[[!driveDestinationKeyCros_]]"> $i18n{printToGoogleDrive} </option> <option value="noDestinations" @@ -27,7 +35,7 @@ $i18n{noDestinationsMessage} </option> <option value="seeMore" - aria-label$="[[i18n(seeMoreDestinationsLabel)]]"> + aria-label="$i18n{seeMoreDestinationsLabel}"> $i18n{seeMore} </option> </select> @@ -37,11 +45,13 @@ value="[[destination]]" hidden$="[[!loaded]]" item-list="[[recentDestinationList]]" pdf-destination-key="[[pdfDestinationKey_]]" - drive-destination-key="[[driveDestinationKey]]" + drive-destination-key="[[driveDestinationKeyCros_]]" no-destinations="[[noDestinations]]" pdf-printer-disabled="[[pdfPrinterDisabled]]" destination-icon="[[destinationIcon_]]" disabled="[[disabled]]" - on-dropdown-value-selected="onDropdownValueSelected_"> + is-current-destination-cros-local="[[isCurrentDestinationCrosLocal_]]" + on-dropdown-value-selected="onDropdownValueSelected_" + destination-status-text="[[statusText_]]"> </print-preview-destination-dropdown-cros> </template> </div> @@ -50,7 +60,9 @@ hidden$="[[!statusText_]]"> <div slot="title"></div> <div slot="controls"> - <div class="destination-status">[[statusText_]]</div> + <div id="statusText" class="destination-status" title="[[statusText_]]" + aria-hidden="[[isCurrentDestinationCrosLocal_]]"> + </div> </div> </print-preview-settings-section> <print-preview-settings-section class="destination-additional-info" diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js index 9eab3a242b4..0c0cceed6d6 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js @@ -21,32 +21,13 @@ import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {Base, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {CloudOrigins, Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination} from '../data/destination.js'; -import {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from '../data/printer_status_cros.js'; +import {CloudOrigins, Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination, SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from '../data/destination.js'; +import {ERROR_STRING_KEY_MAP, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from '../data/printer_status_cros.js'; import {NativeLayer, NativeLayerImpl} from '../native_layer.js'; import {getSelectDropdownBackground} from '../print_preview_utils.js'; import {SelectBehavior} from './select_behavior.js'; -/** @const {!Map<!PrinterStatusReason, string>} */ -const ERROR_STRING_KEY_MAP = new Map([ - [PrinterStatusReason.CONNECTING_TO_DEVICE, 'printerStatusConnectingToDevice'], - [PrinterStatusReason.DEVICE_ERROR, 'printerStatusDeviceError'], - [PrinterStatusReason.DOOR_OPEN, 'printerStatusDoorOpen'], - [PrinterStatusReason.LOW_ON_INK, 'printerStatusLowOnInk'], - [PrinterStatusReason.LOW_ON_PAPER, 'printerStatusLowOnPaper'], - [PrinterStatusReason.OUT_OF_INK, 'printerStatusOutOfInk'], - [PrinterStatusReason.OUT_OF_PAPER, 'printerStatusOutOfPaper'], - [PrinterStatusReason.OUTPUT_ALMOST_FULL, 'printerStatusOutputAlmostFull'], - [PrinterStatusReason.OUTPUT_FULL, 'printerStatusOutputFull'], - [PrinterStatusReason.PAPER_JAM, 'printerStatusPaperJam'], - [PrinterStatusReason.PAUSED, 'printerStatusPaused'], - [PrinterStatusReason.PRINTER_QUEUE_FULL, 'printerStatusPrinterQueueFull'], - [PrinterStatusReason.PRINTER_UNREACHABLE, 'printerStatusPrinterUnreachable'], - [PrinterStatusReason.STOPPED, 'printerStatusStopped'], - [PrinterStatusReason.TRAY_MISSING, 'printerStatusTrayMissing'], -]); - Polymer({ is: 'print-preview-destination-select-cros', @@ -60,11 +41,7 @@ Polymer({ dark: Boolean, /** @type {!Destination} */ - destination: { - type: Object, - observer: 'updateStatusText_', - }, - + destination: Object, disabled: Boolean, @@ -88,8 +65,13 @@ Polymer({ value: PDF_DESTINATION_KEY, }, - /** @private */ - statusText_: String, + /** @private {string} */ + statusText_: { + type: String, + computed: + 'computeStatusText_(destination, destination.printerStatusReason)', + observer: 'onStatusTextSet_', + }, /** @private {string} */ backgroundImages_: { @@ -121,6 +103,29 @@ Polymer({ * @private {!Map<string, string>} */ statusRequestedMap_: Map, + + /** @private */ + isCurrentDestinationCrosLocal_: { + type: Boolean, + computed: 'computeIsCurrentDestinationCrosLocal_(destination)', + reflectToAttribute: true, + }, + + /** @private */ + saveToDriveFlagEnabled_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('printSaveToDrive'); + }, + readOnly: true, + }, + + /** @private */ + driveDestinationKeyCros_: { + type: String, + computed: + 'computeDriveDestinationKeyCros_(driveDestinationKey, saveToDriveFlagEnabled_)', + }, }, /** @private {!IronMetaElement} */ @@ -137,7 +142,11 @@ Polymer({ }, focus() { - this.$$('#dropdown').focus(); + if (this.printerStatusFlagEnabled_) { + this.$$('#dropdown').$$('#destination-dropdown').focus(); + return; + } + this.$$('.md-select').focus(); }, /** Sets the select to the current value of |destination|. */ @@ -284,10 +293,11 @@ Polymer({ // dropdown printer status icons to recalculate their badge color. this.notifyPath(`recentDestinationList.${indexFound}.printerStatusReason`); - // Update the status text if this printer status is for the - // currently selected printer. + // If |printerStatus| is for the currently selected printer, use notifyPath + // to trigger the destination printer status icon to recalculate its badge + // color and the destination error status text. if (this.destination && this.destination.key === destinationKey) { - this.updateStatusText_(); + this.notifyPath(`destination.printerStatusReason`); } }, @@ -330,41 +340,51 @@ Polymer({ }, /** - * Check the current destination for an error status then set |statusText_| - * appropriately. If no error status exists, unset |statusText_|. + * @return {string} An error status for the current destination. If no error + * status exists, an empty string. * @private */ - updateStatusText_: function() { + computeStatusText_: function() { // |destination| can be either undefined, or null here. if (!this.destination) { - this.statusText_ = ''; - return; + return ''; } // Cloudprint destinations contain their own status text. if (CloudOrigins.some(origin => origin === this.destination.origin)) { - this.statusText_ = this.destination.shouldShowInvalidCertificateError ? - this.i18n('noLongerSupportedFragment') : - this.destination.connectionStatusText; - return; + if (this.destination.shouldShowInvalidCertificateError) { + return this.i18n('noLongerSupportedFragment'); + } + if (this.destination.connectionStatusText) { + return this.destination.connectionStatusText; + } + } + + if (this.destination.origin !== DestinationOrigin.CROS) { + return this.destination.shouldShowDeprecatedPrinterWarning ? + this.i18nAdvanced('printerNotSupportedWarning') : + ''; } // Only when the flag is enabled do we need to fetch a local printer status // error string. if (!this.printerStatusFlagEnabled_) { - this.statusText_ = ''; - return; + return ''; } const printerStatusReason = this.destination.printerStatusReason; if (!printerStatusReason || printerStatusReason === PrinterStatusReason.NO_ERROR || printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) { - this.statusText_ = ''; - return; + return ''; } - this.statusText_ = this.getErrorString_(printerStatusReason); + return this.getErrorString_(printerStatusReason); + }, + + /** @private */ + onStatusTextSet_() { + this.$$('#statusText').innerHTML = this.statusText_; }, /** @@ -373,17 +393,37 @@ Polymer({ * @private */ getErrorString_: function(printerStatusReason) { - const errorTextKey = ERROR_STRING_KEY_MAP.get(printerStatusReason); - return errorTextKey ? - this.i18n(errorTextKey, this.destination.displayName) : - ''; + const errorStringKey = ERROR_STRING_KEY_MAP.get(printerStatusReason); + return errorStringKey ? this.i18n(errorStringKey) : ''; }, /** - * @return {!boolean} + * True when the currently selected destination is a CrOS local printer. + * @return {boolean} * @private */ - shouldShowStatus_: function() { - return !!this.statusText_; + computeIsCurrentDestinationCrosLocal_: function() { + return this.destination && + this.destination.origin === DestinationOrigin.CROS; }, + + /** + * Return the options currently visible to the user for testing purposes. + * @return {!Array<!Element>} + */ + getVisibleItemsForTest: function() { + return this.printerStatusFlagEnabled_ ? + this.$$('#dropdown') + .shadowRoot.querySelectorAll('.list-item:not([hidden])') : + this.shadowRoot.querySelectorAll('option:not([hidden])'); + }, + + /** + * @return {string} + * @private + */ + computeDriveDestinationKeyCros_: function() { + return this.saveToDriveFlagEnabled_ ? SAVE_TO_DRIVE_CROS_DESTINATION_KEY : + this.driveDestinationKey; + } }); diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select_css.html b/chromium/chrome/browser/resources/print_preview/ui/destination_select_css.html index 1d00c9f5f16..19fc6427d41 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_select_css.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select_css.html @@ -32,10 +32,7 @@ .destination-status { color: var(--cr-secondary-text-color); font-size: calc(12/13 * 1em); - overflow: hidden; - padding-top: 4px; - text-overflow: ellipsis; - white-space: nowrap; + padding: 4px 0; } </style> </template> diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.html b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.html index 9d9e3e3ca3d..d0ed0f5dda9 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.html +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.html @@ -42,7 +42,6 @@ <cr-lazy-render id="destinationDialog"> <template> <print-preview-destination-dialog - cloud-print-disabled="[[cloudPrintDisabled_]]" destination-store="[[destinationStore_]]" invitation-store="[[invitationStore_]]" recent-destination-list="[[recentDestinationList_]]" diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js index 4dce6653ae7..bdc1874cca4 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js +++ b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js @@ -22,6 +22,7 @@ import '../strings.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {beforeNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -152,6 +153,17 @@ Polymer({ /** @private {!Array<string>} */ users_: Array, + + // <if expr="chromeos"> + /** @private */ + saveToDriveFlagEnabled_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('printSaveToDrive'); + }, + readOnly: true, + }, + // </if> }, /** @private {string} */ @@ -371,6 +383,13 @@ Polymer({ * Drive. */ destinationIsDriveOrPdf_(destination) { + // <if expr="chromeos"> + if (this.saveToDriveFlagEnabled_ && + destination.id === Destination.GooglePromotedId.SAVE_TO_DRIVE_CROS) { + return true; + } + // </if> + return destination.id === Destination.GooglePromotedId.SAVE_AS_PDF || destination.id === Destination.GooglePromotedId.DOCS; }, diff --git a/chromium/chrome/browser/resources/print_preview/ui/header.js b/chromium/chrome/browser/resources/print_preview/ui/header.js index e441b03788d..8f90333a07a 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/header.js +++ b/chromium/chrome/browser/resources/print_preview/ui/header.js @@ -37,7 +37,6 @@ Polymer({ managed: Boolean, - /** @private {number} */ sheetCount: Number, /** @private {?string} */ diff --git a/chromium/chrome/browser/resources/print_preview/ui/icons.html b/chromium/chrome/browser/resources/print_preview/ui/icons.html index 0f81773514c..bfa7a18e093 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/icons.html +++ b/chromium/chrome/browser/resources/print_preview/ui/icons.html @@ -1,7 +1,7 @@ <iron-iconset-svg name="print-preview" size="24"> <svg> <defs> - <!-- Custom svgs (namratakannan). --> + <!-- Custom SVGs (namratakannan) --> <g id="printer-shared" viewBox="0 0 106 96"> <path d="M44 59H32v26h12v11H21.2V74.462H0V42.154C0 33.215 7.102 26 15.9 26h74.2c8.798 0 15.9 7.215 15.9 16.154V59H91.393A15.943 15.943 0 0 0 93 52c0-8.84-7.16-16-16-16s-16 7.16-16 16c0 2.51.578 4.886 1.607 7H44zM84 0H21v22h63V0z"></path> <path d="M77 68c-9.679 0-29 6.253-29 18.667V96h58v-9.333C106 74.253 86.679 68 77 68zM77 64c6.63 0 12-5.37 12-12s-5.37-12-12-12-12 5.37-12 12 5.37 12 12 12z" fill="#4A93F9"></path> @@ -15,6 +15,17 @@ <path d="M-5-5h32v32H-5z"> </g> + <!-- Custom SVGs (shuom) --> + <g id="printer-not-supported" viewBox="0 0 20 18" aria-label="$i18n{destinationNotSupportedWarning}"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M8 18H19.5L14 8L8 18ZM14.5453 16.6616H13.4544V15.5789H14.5453V16.6616ZM13.4544 14.4962H14.5453V12.3308H13.4544V14.4962Z" fill="#E8710A"></path> + <path d="M3 5H17C18.66 5 20 6.34 20 8V14H18.5L14 6L11 11H6V16H8L6.8 18H4V14H0V8C0 6.34 1.34 5 3 5Z"></path> + <path d="M16 0H4V4H16V0Z"></path> + </g> + <g id="save-to-drive-not-supported" viewBox="0 0 19 15"> + <path d="M6.8 0H1.7C0.765 0 0.0085 0.7875 0.0085 1.75L0 12.25C0 13.2125 0.765 14 1.7 14H6.2L13 3L17 9.5V3.5C17 2.5375 16.235 1.75 15.3 1.75H8.5L6.8 0Z"></path> + <path fill-rule="evenodd" clip-rule="evenodd" d="M19 15L13 5L7 15H19ZM13.5453 13.6616H12.4544V12.5789H13.5453V13.6616ZM12.4544 11.4962H13.5453V9.33075H12.4544V11.4962Z" fill="#E8710A"></path> + </g> + <!-- Icon from http://icons/ --> <g id="save-to-drive"> <path fill="none" d="M0 0h24v24H0z"></path> @@ -27,7 +38,6 @@ --> <g id="business"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"></path></g> <g id="smartphone"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"></path></g> - <g id="cloud-queue"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z"></path></g> <g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g> </defs> </svg> diff --git a/chromium/chrome/browser/resources/print_preview/ui/media_size_settings.js b/chromium/chrome/browser/resources/print_preview/ui/media_size_settings.js index 5b432c2755e..17ca89ed0e4 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/media_size_settings.js +++ b/chromium/chrome/browser/resources/print_preview/ui/media_size_settings.js @@ -31,11 +31,13 @@ Polymer({ if (!this.capability) { return; } - const valueToSet = JSON.stringify(this.getSettingValue('mediaSize')); + const value = this.getSettingValue('mediaSize'); for (const option of /** @type {!Array<!SelectOption>} */ (this.capability.option)) { - if (JSON.stringify(option) === valueToSet) { - this.$$('print-preview-settings-select').selectValue(valueToSet); + if (option.height_microns === value.height_microns && + option.width_microns === value.width_microns) { + this.$$('print-preview-settings-select') + .selectValue(JSON.stringify(option)); return; } } diff --git a/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js b/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js index c145fccf79f..bc1e07da0b7 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js +++ b/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js @@ -3,6 +3,8 @@ // found in the LICENSE file. import {assert} from 'chrome://resources/js/assert.m.js'; +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + import {PDFCreateOutOfProcessPlugin} from '../pdf/pdf_scripting_api.js'; /** @@ -20,36 +22,80 @@ export let PDFPlugin; /** * An interface to the PDF plugin. + * @interface */ export class PluginProxy { /** - * Creates a new PluginProxy if the current instance is not set. - * @return {!PluginProxy} The singleton instance. + * @param {!Element} oopCompatObj The out of process compatibility element. + * @return {boolean} Whether the plugin exists and is compatible. */ - static getInstance() { - if (instance === null) { - instance = new PluginProxy(); - } - return assert(instance); - } + checkPluginCompatibility(oopCompatObj) {} + + /** @return {boolean} Whether the plugin is ready. */ + pluginReady() {} /** - * @param {!PluginProxy} newInstance The PluginProxy - * instance to set for print preview construction. + * Creates the PDF plugin. + * @param {number} previewUid The unique ID of the preview UI. + * @param {number} index The preview index to load. + * @return {!PDFPlugin} The created plugin. */ - static setInstance(newInstance) { - instance = newInstance; - } + createPlugin(previewUid, index) {} + + /** + * @param {number} previewUid Unique identifier of preview. + * @param {number} index Page index for plugin. + * @param {boolean} color Whether the preview should be color. + * @param {!Array<number>} pages Page indices to preview. + * @param {boolean} modifiable Whether the document is modifiable. + */ + resetPrintPreviewMode(previewUid, index, color, pages, modifiable) {} + + /** + * @param {number} scrollX The amount to horizontally scroll in pixels. + * @param {number} scrollY The amount to vertically scroll in pixels. + */ + scrollPosition(scrollX, scrollY) {} + + /** @param {!KeyboardEvent} e Keyboard event to forward to the plugin. */ + sendKeyEvent(e) {} + + hideToolbars() {} + + /** + * @param {boolean} eventsEnabled Whether pointer events should be captured + * by the plugin. + */ + setPointerEvents(eventsEnabled) {} + + /** + * @param {number} previewUid The unique ID of the preview UI. + * @param {number} pageIndex The page index to load. + * @param {number} index The preview index. + */ + loadPreviewPage(previewUid, pageIndex, index) {} + + /** @param {?Function} keyEventCallback */ + setKeyEventCallback(keyEventCallback) {} + + /** @param {?Function} loadCompleteCallback */ + setLoadCompleteCallback(loadCompleteCallback) {} + /** @param {?Function} viewportChangedCallback */ + setViewportChangedCallback(viewportChangedCallback) {} + + /** @param {boolean} darkMode Whether the page is in dark mode. */ + darkModeChanged(darkMode) {} +} + +/** @implements {PluginProxy} */ +export class PluginProxyImpl { constructor() { /** @private {?PDFPlugin} */ this.plugin_ = null; } - /** - * @param {!Element} oopCompatObj The out of process compatibility element. - * @return {boolean} Whether the plugin exists and is compatible. - */ + /** @override */ checkPluginCompatibility(oopCompatObj) { const isOOPCompatible = oopCompatObj.postMessage; oopCompatObj.parentElement.removeChild(oopCompatObj); @@ -57,17 +103,12 @@ export class PluginProxy { return isOOPCompatible; } - /** @return {boolean} Whether the plugin is ready. */ + /** @override */ pluginReady() { return !!this.plugin_; } - /** - * Creates the PDF plugin. - * @param {number} previewUid The unique ID of the preview UI. - * @param {number} index The preview index to load. - * @return {!PDFPlugin} The created plugin. - */ + /** @override */ createPlugin(previewUid, index) { assert(!this.plugin_); const srcUrl = this.getPreviewUrl_(previewUid, index); @@ -94,73 +135,57 @@ export class PluginProxy { return `chrome://print/${previewUid}/${index}/print.pdf`; } - /** - * @param {number} previewUid Unique identifier of preview. - * @param {number} index Page index for plugin. - * @param {boolean} color Whether the preview should be color. - * @param {!Array<number>} pages Page indices to preview. - * @param {boolean} modifiable Whether the document is modifiable. - */ + /** @override */ resetPrintPreviewMode(previewUid, index, color, pages, modifiable) { this.plugin_.resetPrintPreviewMode( this.getPreviewUrl_(previewUid, index), color, pages, modifiable); } - /** - * @param {number} scrollX The amount to horizontally scroll in pixels. - * @param {number} scrollY The amount to vertically scroll in pixels. - */ + /** @override */ scrollPosition(scrollX, scrollY) { this.plugin_.scrollPosition(scrollX, scrollY); } - /** @param {!KeyboardEvent} e Keyboard event to forward to the plugin. */ + /** @override */ sendKeyEvent(e) { this.plugin_.sendKeyEvent(e); } + /** @override */ hideToolbars() { this.plugin_.hideToolbars(); } - /** - * @param {boolean} eventsEnabled Whether pointer events should be captured - * by the plugin. - */ + /** @override */ setPointerEvents(eventsEnabled) { this.plugin_.style.pointerEvents = eventsEnabled ? 'auto' : 'none'; } - /** - * @param {number} previewUid The unique ID of the preview UI. - * @param {number} pageIndex The page index to load. - * @param {number} index The preview index. - */ + /** @override */ loadPreviewPage(previewUid, pageIndex, index) { this.plugin_.loadPreviewPage( this.getPreviewUrl_(previewUid, pageIndex), index); } - /** @param {?Function} keyEventCallback */ + /** @override */ setKeyEventCallback(keyEventCallback) { this.plugin_.setKeyEventCallback(keyEventCallback); } - /** @param {?Function} loadCompleteCallback */ + /** @override */ setLoadCompleteCallback(loadCompleteCallback) { this.plugin_.setLoadCompleteCallback(loadCompleteCallback); } - /** @param {?Function} viewportChangedCallback */ + /** @override */ setViewportChangedCallback(viewportChangedCallback) { this.plugin_.setViewportChangedCallback(viewportChangedCallback); } - /** @param {boolean} darkMode Whether the page is in dark mode. */ + /** @override */ darkModeChanged(darkMode) { this.plugin_.darkModeChanged(darkMode); } } -/** @type {?PluginProxy} */ -let instance = null; +addSingletonGetter(PluginProxyImpl); diff --git a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js index feb0ebf3849..450bf8ad674 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js +++ b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js @@ -29,7 +29,7 @@ import {NativeLayer, NativeLayerImpl} from '../native_layer.js'; import {areRangesEqual} from '../print_preview_utils.js'; import {MARGIN_KEY_MAP} from './margin_control_container.js'; -import {PluginProxy} from './plugin_proxy.js'; +import {PluginProxy, PluginProxyImpl} from './plugin_proxy.js'; import {SettingsBehavior} from './settings_behavior.js'; /** @@ -153,7 +153,7 @@ Polymer({ /** @override */ created() { - this.pluginProxy_ = PluginProxy.getInstance(); + this.pluginProxy_ = PluginProxyImpl.getInstance(); }, /** diff --git a/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html b/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html index 6ecd94cd733..ec2cdaf0e8a 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html +++ b/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html @@ -53,6 +53,6 @@ <div slot="inline-prefix" id="icon" class="cr-icon icon-search" alt=""></div> <cr-icon-button id="clearSearch" class="icon-cancel" hidden$="[[!hasSearchText]]" slot="suffix" on-click="onClearClick_" - title="[[clearLabel]]"> + title="$i18n{clearSearch}"> </cr-icon-button> </cr-input> diff --git a/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html b/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html index 2208774d52e..0f0d0763340 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html +++ b/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html @@ -5,6 +5,10 @@ --print-preview-sidebar-width: 384px; --print-preview-title-width: 120px; --print-preview-sidebar-margin: 24px; + /* Controls width = total width - title width - start/middle/end margin */ + --print-preview-dropdown-width: calc(var(--print-preview-sidebar-width) + - var(--print-preview-title-width) + - 3 * var(--print-preview-sidebar-margin)); --print-preview-settings-border: 1px solid var(--google-grey-200); --print-preview-dialog-margin: 34px; @@ -20,9 +24,6 @@ @media (prefers-color-scheme: dark) { html { --preview-area-background-color: var(--google-grey-refresh-700); - --print-preview-disabled-label: { - opacity: var(--cr-disabled-opacity); - } --print-preview-settings-border: var(--cr-separator-line); --iron-icon-fill-color: var(--google-grey-refresh-500); } diff --git a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html index 450956a6557..542255b67df 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html +++ b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html @@ -25,15 +25,15 @@ width: var(--status-badge-radius); } - :host-context([state='0']) #status-badge { + :host([printer-state='0']) #status-badge { background-color: var(--google-green-700); } - :host-context([state='1']) #status-badge { + :host([printer-state='1']) #status-badge { background-color: var(--google-red-600); } - :host-context([state='2']) #status-badge { + :host([printer-state='2']) #status-badge { background-color: var(--google-grey-500); } @@ -48,17 +48,21 @@ width: var(--background-badge-radius); } - :host-context([background='grey']) #background-badge { + :host([icon-location='0']) #background-badge { background-color: var(--google-grey-refresh-100); } - :host-context([background='white']) #background-badge { + :host([icon-location='1']) #background-badge { background-color: white; } :host-context([dir='rtl']) #background-badge { right: var(--background-badge-left); } + + :host-context(.highlighted) #background-badge { + background-color: var(--google-blue-refresh-100); + } </style> <div> <iron-icon icon="print-preview:print"></iron-icon> diff --git a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js index 3ae2dc8a7de..2b62096ced1 100644 --- a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js +++ b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js @@ -18,6 +18,16 @@ export const PrinterState = { UNKNOWN: 2, }; +/** + * Enumeration used to choose styling based on whether this icon is located in + * the destination display or the destination dropdown. + * @enum {number} + */ +export const IconLocation = { + DISPLAY: 0, + DROPDOWN: 1, +}; + Polymer({ is: 'printer-status-icon-cros', @@ -29,10 +39,19 @@ Polymer({ * State of the associated printer. Determines color of the status badge. * @type {!PrinterState} */ - state: { + printerState: { + type: Number, + reflectToAttribute: true, + }, + + /** + * Location of this icon. Determines color of the background badge. + * @type {!IconLocation} + */ + iconLocation: { type: Number, reflectToAttribute: true, - } + }, }, _template: html`{__html_template__}`, diff --git a/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn b/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn index edf3d6e60e0..848e430a40e 100644 --- a/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn +++ b/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn @@ -8,7 +8,7 @@ js_type_check("closure_compile") { if (is_win) { deps = [ ":sandbox_internals_win" ] } - if (is_android || is_linux) { + if (is_android || is_linux || is_chromeos) { deps = [ ":sandbox_internals" ] } } diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html index c5c269faa9c..7aa201edfc9 100644 --- a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html +++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html @@ -12,6 +12,7 @@ #sandbox-status td { border: 1px solid gray; padding: 3px; + vertical-align: top; } #evaluation { font-weight: bold; @@ -28,6 +29,16 @@ .info { background-color: rgb(169, 217, 239); } +<if expr="is_win"> + .expander { + display: inline; + padding-right: 1em; + } + .mitigations { + display: inline; + font-family: monospace; + } +</if> </style> <script src="chrome://resources/js/cr.js"></script> <if expr="is_linux"> diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js index 3797fb87e4d..d810731ea82 100644 --- a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js +++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js @@ -42,19 +42,313 @@ let PolicyDiagnostic; let SandboxDiagnostics; /** + * Represents a mitigation field from the PROCESS_CREATION_MITITAGION_POLICY* + * series in Winbase.h. + * @typedef {{ + * mitigation: !string, + * value: !number, + * mask: !number, + * offset: !number + * }} + */ +class MitigationField { + /** + * mask & value must be 0<=x<=255. + * @param {string} mitigation human name of mitigation. + * @param {number} value value to match within mask. + * @param {number} mask applied before matching. + * @param {number} offset within PC section. + */ + constructor(mitigation, value, mask, offset) { + this.mitigation = mitigation; + this.value = value; + this.mask = mask; + this.offset = offset; + } + + /** + * Each PC field overrides this as they know where their data is. + * @param {Uint8Array} platform mitigations data. + * @return {Uint8Array} chunk containing this field or null. + */ + getFieldData(bytes) { + assertNotReached(); + } + + /** + * Are all the bits of this field set in the mitigations represented by + * |bytes|. + * @param {Uint8Array} platform mitigations. + * @return {boolean} + */ + isFieldSet(bytes) { + if (bytes.length != 4 && bytes.length != 8 && bytes.length != 16) { + throw ('Platform mitigations has unexpected size'); + } + const subfield = this.getFieldData(bytes); + if (subfield == null || this.offset > subfield.length * 8) { + return false; + } + const idx = subfield.length - 1 - Math.floor(this.offset / 8); + const ibit = this.offset % 8; + return (subfield[idx] & (this.mask << ibit)) == (this.value << ibit); + } +} + +/** + * PROCESS_CREATION_MITIGATION_POLICY legacy bits. + */ +class PC0Field extends MitigationField { + /** + * @param {Uint8Array} platform mitigations data. + * @return {Uint8Array} chunk containing this field or null. + */ + getFieldData(bytes) { + if (bytes.length == 4) { + // Win32 only 4 bytes of fields. + return bytes; + } else if (bytes.length == 8) { + return bytes; + } else { + return bytes.slice(0, 8); + } + } +} + +/** + * PROCESS_CREATION_MITIGATION_POLICY_* + */ +class PC1Field extends MitigationField { + /** @override */ + getFieldData(bytes) { + if (bytes.length == 4) { + return null; + } else if (bytes.length == 8) { + return bytes; + } else if (bytes.length == 16) { + return bytes.slice(0, 8); + } + } +} + +/** + * PROCESS_CREATION_MITIGATION_POLICY2_* + */ +class PC2Field extends MitigationField { + /** @override */ + getFieldData(bytes) { + if (bytes.length == 4) { + return null; + } else if (bytes.length == 8) { + return null; + } else if (bytes.length == 16) { + return bytes.slice(8, 16); + } + } +} + +/** + * Helper to show enabled mitigations from a stringified hex + representation of PROCESS_CREATION_MITIGATION_POLICY_* entries. + */ +class DecodeMitigations { + constructor() { + /* @typedef {{Array<MitigationField>}} */ + this.fields = [ + // Defined in Windows.h from Winbase.h + // basic (pc0) mitigations in {win7},{lsb of pc1}. + new PC0Field('DEP_ENABLE', 0x1, 0x01, 0), + new PC0Field('DEP_ATL_THUNK_ENABLE', 0x2, 0x02, 0), + new PC0Field('SEHOP_ENABLE', 0x4, 0x04, 0), + + // pc1 mitigations in {lsb of pc1}. + new PC1Field('FORCE_RELOCATE_IMAGES', 0x1, 0x03, 8), + new PC1Field('FORCE_RELOCATE_IMAGES_ALWAYS_OFF', 0x2, 0x03, 8), + new PC1Field('FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS', 0x3, 0x03, 8), + new PC1Field('HEAP_TERMINATE', 0x1, 0x03, 12), + new PC1Field('HEAP_TERMINATE_ALWAYS_OFF', 0x2, 0x03, 12), + new PC1Field('HEAP_TERMINATE_RESERVED', 0x3, 0x03, 12), + new PC1Field('BOTTOM_UP_ASLR', 0x1, 0x03, 16), + new PC1Field('BOTTOM_UP_ASLR_ALWAYS_OFF', 0x2, 0x03, 16), + new PC1Field('BOTTOM_UP_ASLR_RESERVED', 0x3, 0x03, 16), + new PC1Field('HIGH_ENTROPY_ASLR', 0x1, 0x03, 20), + new PC1Field('HIGH_ENTROPY_ASLR_ALWAYS_OFF', 0x2, 0x03, 20), + new PC1Field('HIGH_ENTROPY_ASLR_RESERVED', 0x3, 0x03, 20), + new PC1Field('STRICT_HANDLE_CHECKS', 0x1, 0x03, 24), + new PC1Field('STRICT_HANDLE_CHECKS_ALWAYS_OFF', 0x2, 0x03, 24), + new PC1Field('STRICT_HANDLE_CHECKS_RESERVED', 0x3, 0x03, 24), + new PC1Field('WIN32K_SYSTEM_CALL_DISABLE', 0x1, 0x03, 28), + new PC1Field('WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_OFF', 0x2, 0x03, 28), + new PC1Field('WIN32K_SYSTEM_CALL_DISABLE_RESERVED', 0x3, 0x03, 28), + new PC1Field('EXTENSION_POINT_DISABLE', 0x1, 0x03, 32), + new PC1Field('EXTENSION_POINT_DISABLE_ALWAYS_OFF', 0x2, 0x03, 32), + new PC1Field('EXTENSION_POINT_DISABLE_RESERVED', 0x3, 0x03, 32), + new PC1Field('PROHIBIT_DYNAMIC_CODE', 0x1, 0x03, 36), + new PC1Field('PROHIBIT_DYNAMIC_CODE_ALWAYS_OFF', 0x2, 0x03, 36), + new PC1Field( + 'PROHIBIT_DYNAMIC_CODE_ALWAYS_ON_ALLOW_OPT_OUT', 0x3, 0x03, 36), + new PC1Field('CONTROL_FLOW_GUARD', 0x1, 0x03, 40), + new PC1Field('CONTROL_FLOW_GUARD_ALWAYS_OFF', 0x2, 0x03, 40), + new PC1Field('CONTROL_FLOW_GUARD_EXPORT_SUPPRESSION', 0x3, 0x03, 40), + new PC1Field('BLOCK_NON_MICROSOFT_BINARIES', 0x1, 0x03, 44), + new PC1Field('BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_OFF', 0x2, 0x03, 44), + new PC1Field('BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE', 0x3, 0x03, 44), + new PC1Field('FONT_DISABLE', 0x1, 0x03, 48), + new PC1Field('FONT_DISABLE_ALWAYS_OFF', 0x2, 0x03, 48), + new PC1Field('AUDIT_NONSYSTEM_FONTS', 0x3, 0x03, 48), + new PC1Field('IMAGE_LOAD_NO_REMOTE', 0x1, 0x03, 52), + new PC1Field('IMAGE_LOAD_NO_REMOTE_ALWAYS_OFF', 0x2, 0x03, 52), + new PC1Field('IMAGE_LOAD_NO_REMOTE_RESERVED', 0x3, 0x03, 52), + new PC1Field('IMAGE_LOAD_NO_LOW_LABEL', 0x1, 0x03, 56), + new PC1Field('IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_OFF', 0x2, 0x03, 56), + new PC1Field('IMAGE_LOAD_NO_LOW_LABEL_RESERVED', 0x3, 0x03, 56), + new PC1Field('IMAGE_LOAD_PREFER_SYSTEM32', 0x1, 0x03, 60), + new PC1Field('IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_OFF', 0x2, 0x03, 60), + new PC1Field('IMAGE_LOAD_PREFER_SYSTEM32_RESERVED', 0x3, 0x03, 60), + + // pc2: in second 64bit block only. + new PC2Field('LOADER_INTEGRITY_CONTINUITY', 0x1, 0x03, 4), + new PC2Field('LOADER_INTEGRITY_CONTINUITY_ALWAYS_OFF', 0x2, 0x03, 4), + new PC2Field('LOADER_INTEGRITY_CONTINUITY_AUDIT', 0x3, 0x03, 4), + new PC2Field('STRICT_CONTROL_FLOW_GUARD', 0x1, 0x03, 8), + new PC2Field('STRICT_CONTROL_FLOW_GUARD_ALWAYS_OFF', 0x2, 0x03, 8), + new PC2Field('STRICT_CONTROL_FLOW_GUARD_RESERVED', 0x3, 0x03, 8), + new PC2Field('MODULE_TAMPERING_PROTECTION', 0x1, 0x03, 12), + new PC2Field('MODULE_TAMPERING_PROTECTION_ALWAYS_OFF', 0x2, 0x03, 12), + new PC2Field('MODULE_TAMPERING_PROTECTION_NOINHERIT', 0x3, 0x03, 12), + new PC2Field('RESTRICT_INDIRECT_BRANCH_PREDICTION', 0x1, 0x03, 16), + new PC2Field( + 'RESTRICT_INDIRECT_BRANCH_PREDICTION_ALWAYS_OFF', 0x2, 0x03, 16), + new PC2Field( + 'RESTRICT_INDIRECT_BRANCH_PREDICTION_RESERVED', 0x3, 0x03, 16), + new PC2Field('ALLOW_DOWNGRADE_DYNAMIC_CODE_POLICY', 0x1, 0x03, 20), + new PC2Field( + 'ALLOW_DOWNGRADE_DYNAMIC_CODE_POLICY_ALWAYS_OFF', 0x2, 0x03, 20), + new PC2Field( + 'ALLOW_DOWNGRADE_DYNAMIC_CODE_POLICY_RESERVED', 0x3, 0x03, 20), + new PC2Field('SPECULATIVE_STORE_BYPASS_DISABLE', 0x1, 0x03, 24), + new PC2Field( + 'SPECULATIVE_STORE_BYPASS_DISABLE_ALWAYS_OFF', 0x2, 0x03, 24), + new PC2Field('SPECULATIVE_STORE_BYPASS_DISABLE_RESERVED', 0x3, 0x03, 24), + new PC2Field('CET_USER_SHADOW_STACKS', 0x1, 0x03, 28), + new PC2Field('CET_USER_SHADOW_STACKS_ALWAYS_OFF', 0x2, 0x03, 28), + new PC2Field('CET_USER_SHADOW_STACKS_RESERVED', 0x3, 0x03, 28) + ]; + } + + /** + * @param {string} str Hex encoded data. + * @return {Uint8Array} bytes Decoded bytes. + */ + parseHexString(str) { + assert((str.length % 2 == 0), 'str must have even length'); + const bytes = new Uint8Array(str.length / 2); + for (let idx = 0; idx < str.length / 2; idx++) { + bytes[idx] = parseInt(str.slice(idx * 2, idx * 2 + 2), 16); + } + return bytes; + } + + /** + * Return a list of platform mitigation which are set in |mitigations|. + * Mitigations will be in the same order as Winbase.h. + * @param {string} str Hex encoded process mitigation flags. + * @return {Array<string>} Matched mitigation values. + */ + enabledMitigations(mitigations) { + const bytes = this.parseHexString(mitigations); + const output = []; + for (const item of this.fields) { + if (item.isFieldSet(bytes)) { + output.push(item.mitigation); + } + } + return output; + } +} + +const DECODE_MITIGATIONS = new DecodeMitigations(); + +/** * Adds a row to the sandbox-status table. - * @param {!Array<string>} args + * @param {!Array<Node>} args */ function addRow(args) { const row = document.createElement('tr'); - for (const text of args) { - const col = row.appendChild(document.createElement('td')); - col.textContent = text; + for (const td of args) { + row.appendChild(td); } $('sandbox-status').appendChild(row); } /** + * Makes a <td> containing arg as textContent. + * @param {string} textContent + * @return {Node} + */ +function makeTextEntry(textContent) { + const col = document.createElement('td'); + col.textContent = textContent; + return col; +} + +/** + * Makes an expandable <td> containing arg as textContent. + * @param {string} mainEntry is always shown + * @param {Object} expandable + * @return {Node} + */ +function makeExpandableEntry(mainEntry, expandable) { + const button = document.createElement('div'); + const expand = document.createElement('div'); + button.innerText = '\u2795'; // (+) + button.classList.add('expander'); + button.addEventListener('click', function() { + if (expandable.onClick(expand)) { + button.innerText = '\u2796'; // (-) + } else { + button.innerText = '\u2795'; // (+) + } + }); + const fixed = document.createElement('div'); + fixed.classList.add('mitigations'); + fixed.innerText = mainEntry; + + const col = document.createElement('td'); + col.appendChild(button); + col.appendChild(fixed); + col.appendChild(expand); + return col; +} + +/** + * Adds a mitigations entry that can expand to show friendly names of the + * mitigations. + * @param {string} platformMitigations + * @return {Node} + */ +function makeMitigationEntry(platformMitigations) { + const expander = { + expanded: false, + mitigations: platformMitigations, + onClick: function(col) { + this.expanded = !this.expanded; + col.innerText = this.getText(); + return this.expanded; + }, + getText: function() { + if (this.expanded) { + return DECODE_MITIGATIONS.enabledMitigations(this.mitigations) + .join('\n'); + } else { + return ''; + } + } + }; + return makeExpandableEntry(platformMitigations, expander); +} + +/** * Adds policy information for a process to the sandbox-status table. * @param {number} pid * @param {string} type @@ -64,12 +358,16 @@ function addRow(args) { */ function addRowForProcess(pid, type, name, sandbox, policy) { if (policy) { - addRow([ + // Text-only items. + const entries = [ pid, type, name, sandbox, policy.lockdownLevel, - policy.desiredIntegrityLevel, policy.platformMitigations - ]); + policy.desiredIntegrityLevel + ].map(makeTextEntry); + // Clickable mitigations item. + entries.push(makeMitigationEntry(policy.platformMitigations)); + addRow(entries); } else { - addRow([pid, type, name, 'Not Sandboxed', '', '', '']); + addRow([pid, type, name, 'Not Sandboxed', '', '', ''].map(makeTextEntry)); } } @@ -87,7 +385,7 @@ function onGetSandboxDiagnostics(results) { // Titles. addRow([ 'Process', 'Type', 'Name', 'Sandbox', 'Lockdown', 'Integrity', 'Mitigations' - ]); + ].map(makeTextEntry)); // Browser Processes. for (const process of results.browser) { diff --git a/chromium/chrome/browser/resources/settings/BUILD.gn b/chromium/chrome/browser/resources/settings/BUILD.gn index a0a669d3b12..80ce6474e7b 100644 --- a/chromium/chrome/browser/resources/settings/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/BUILD.gn @@ -94,6 +94,7 @@ js_type_check("settings_resources") { ":lifetime_browser_proxy", ":router", ":search_settings", + ":setting_id_param_util", ] } @@ -135,6 +136,13 @@ js_library("search_settings") { externs_list = [ "$externs_path/pending_polymer.js" ] } +js_library("setting_id_param_util") { + deps = [ + ":router", + "//ui/webui/resources/js:load_time_data", + ] +} + # Polymer 3 related rules. group("closure_compile_module") { @@ -201,6 +209,7 @@ js_type_check("closure_compile_local_module") { ":route", ":router.m", ":search_settings.m", + ":setting_id_param_util.m", ":settings", ":settings_routes", ":site_favicon", @@ -253,8 +262,11 @@ js_library("lazy_load") { deps = [ "autofill_page:autofill_section", "autofill_page:payments_section", + "chrome_cleanup_page:chrome_cleanup_proxy", + "languages_page:languages_browser_proxy.m", + "languages_page:languages_metrics_proxy", + "languages_page:languages_page", "privacy_page:cookies_page", - "privacy_page:safe_browsing_browser_proxy", "privacy_page:security_page", "site_settings:local_data_browser_proxy", "site_settings:protocol_handlers", @@ -314,6 +326,15 @@ js_library("search_settings.m") { extra_deps = [ ":modulize" ] } +js_library("setting_id_param_util.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/setting_id_param_util.m.js" ] + deps = [ + ":router.m", + "//ui/webui/resources/js:load_time_data.m", + ] + extra_deps = [ ":modulize" ] +} + js_library("settings_routes") { deps = [ ":router.m" ] } @@ -412,6 +433,7 @@ js_modulizer("modulize") { "lifetime_browser_proxy.js", "router.js", "search_settings.js", + "setting_id_param_util.js", ] namespace_rewrites = settings_namespace_rewrites + [ "cr.search_highlight_utils.createEmptySearchBubble|createEmptySearchBubble", diff --git a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn index f74ab14757f..8f06869a570 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn @@ -13,6 +13,7 @@ js_type_check("closure_compile_module") { ":address_edit_dialog", ":autofill_page", ":autofill_section", + ":avatar_icon", ":blocking_request_manager", ":credit_card_edit_dialog", ":credit_card_list_entry", @@ -84,6 +85,14 @@ js_library("autofill_section") { ] } +js_library("avatar_icon") { + deps = [ + "../people_page:sync_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] +} + js_library("blocking_request_manager") { } @@ -221,8 +230,10 @@ js_library("passwords_list_handler") { js_library("password_move_to_account_dialog") { deps = [ + ":avatar_icon", ":multi_store_password_ui_entry", ":password_manager_proxy", + "//third_party/polymer/v3_0/components-chromium/iron-icon", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", @@ -239,12 +250,15 @@ js_library("password_manager_proxy") { js_library("password_remove_dialog") { deps = [ + ":avatar_icon", ":multi_store_password_ui_entry", + "../people_page:sync_browser_proxy.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", ] } @@ -257,6 +271,7 @@ js_library("passwords_export_dialog") { js_library("passwords_section") { deps = [ + ":avatar_icon", ":merge_exceptions_store_copies_behavior", ":merge_passwords_store_copies_behavior", ":multi_store_exception_entry", @@ -286,6 +301,7 @@ js_library("passwords_section") { js_library("passwords_device_section") { deps = [ + ":avatar_icon", ":merge_passwords_store_copies_behavior", ":multi_store_password_ui_entry", ":password_list_item", @@ -294,10 +310,9 @@ js_library("passwords_device_section") { "..:i18n_setup", "..:open_window_proxy", "..:route", - "../people_page:profile_info_browser_proxy.m", + "../people_page:sync_browser_proxy.m", "//third_party/polymer/v3_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:icon.m", "//ui/webui/resources/js:util.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] @@ -367,6 +382,7 @@ html_to_js("web_components") { js_files = [ "address_edit_dialog.js", "autofill_page.js", + "avatar_icon.js", "autofill_section.js", "passwords_list_handler.js", "credit_card_edit_dialog.js", diff --git a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn index 21924f68c30..0c4de06b615 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn @@ -22,7 +22,7 @@ js_library("basic_page") { "../prefs:prefs_behavior.m", "../safety_check_page:safety_check_page", "../search_page", - "../settings_page:main_page_behavior.m", + "../settings_page:main_page_behavior", "//ui/webui/resources/js:load_time_data.m", ] } diff --git a/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn index 9a49bb22976..6fa59625436 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn @@ -36,7 +36,8 @@ if (optimize_webui) { ] excludes = [ # TODO(calamity): Update optimize_webui to handle generated files. - "chrome://resources/css/cros_colors.generated.css", + "chrome://resources/chromeos/colors/cros_colors.generated.css", + "chrome://resources/mojo/chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.html", "chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom.html", "chrome://os-settings/app-management/app_management.mojom-lite.js", "chrome://os-settings/app-management/file_path.mojom-lite.js", @@ -53,6 +54,8 @@ if (optimize_webui) { "chrome://resources/mojo/skia/public/mojom/bitmap.mojom-lite.js", "chrome://resources/mojo/skia/public/mojom/image_info.mojom-lite.js", "chrome://resources/mojo/url/mojom/url.mojom-lite.js", + "shared/nearby_share_settings.html", + "shared/nearby_share_settings_behavior.html", ] deps = [ ":unpak" ] @@ -61,16 +64,27 @@ if (optimize_webui) { optimize_webui("build_polymer3") { host = "os-settings" input = rebase_path("$target_gen_dir/$unpak_folder_v3", root_build_dir) - js_out_files = [ "os_settings.rollup.js" ] - js_module_in_files = [ "chromeos/os_settings.js" ] + js_module_in_files = [ + "chromeos/os_settings.js", + "chromeos/lazy_load.js", + ] + js_out_files = [ + "os_settings.rollup.js", + "lazy_load.rollup.js", + "shared.rollup.js", + ] deps = [ ":unpak_v3", "../../../../../ui/webui/resources:modulize", ] excludes = [ + "chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js", + "chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-lite.js", + "chrome://resources/mojo/services/network/public/mojom/ip_address.mojom-lite.js", + "chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js", "chrome://resources/js/cr.m.js", - "chrome://resources/css/cros_colors.generated.css", + "chrome://resources/chromeos/colors/cros_colors.generated.css", "chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js", "chrome://resources/mojo/url/mojom/url.mojom-lite.js", "app-management/app_management.mojom-lite.js", @@ -84,6 +98,8 @@ if (optimize_webui) { "search/search.mojom-lite.js", "search/search_result_icon.mojom-lite.js", "search/user_action_recorder.mojom-lite.js", + "shared/nearby_share_settings.m.js", + "shared/nearby_share_settings_behavior.m.js", ] } @@ -142,6 +158,7 @@ if (optimize_webui) { group("closure_compile") { deps = [ + ":deep_linking_behavior", ":metrics_recorder", ":os_page_visibility", ":os_route", @@ -181,6 +198,16 @@ group("closure_compile") { ] } +js_library("deep_linking_behavior") { + deps = [ + "..:router", + "..:setting_id_param_util", + "//chrome/browser/ui/webui/settings/chromeos/constants:mojom_js_library_for_compile", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:load_time_data", + ] +} + js_library("os_page_visibility") { deps = [ "//ui/webui/resources/js:cr", @@ -232,37 +259,39 @@ group("closure_compile_module") { deps = [ # TODO: Uncomment as the Polymer3 migration makes progress. #":closure_compile_local_module", - #"ambient_mode_page:closure_compile_module", + "ambient_mode_page:closure_compile_module", "bluetooth_page:closure_compile_module", #"crostini_page:closure_compile_module", - #"date_time_page:closure_compile_module", + "date_time_page:closure_compile_module", + #"device_page:closure_compile_module", #"google_assistant_page:closure_compile_module", #"internet_page:closure_compile_module", "localized_link:closure_compile_module", + "multidevice_page:closure_compile_module", - #"multidevice_page:closure_compile_module", #"os_a11y_page:closure_compile_module", #"os_about_page:closure_compile_module", #"os_apps_page:closure_compile_module", #"os_apps_page/app_management_page/plugin_vm_page:closure_compile_module", - #"os_files_page:closure_compile_module", - #"os_languages_page:closure_compile_module", - #"os_people_page:closure_compile_module", - #"os_printing_page:closure_compile_module", - #"os_privacy_page:closure_compile_module", + "os_files_page:closure_compile_module", + "os_languages_page:closure_compile_module", + "os_people_page:closure_compile_module", + "os_printing_page:closure_compile_module", + "os_privacy_page:closure_compile_module", "os_reset_page:closure_compile_module", #"os_search_page:closure_compile_module", #"os_settings_main:closure_compile_module", #"os_settings_menu:closure_compile_module", - #"os_settings_page:closure_compile_module", + "os_settings_page:closure_compile_module", + #"os_settings_search_box:closure_compile_module", #"os_settings_ui:closure_compile_module", #"os_toolbar:closure_compile_module", #"parental_controls_page:closure_compile_module", - #"personalization_page:closure_compile_module", + "personalization_page:closure_compile_module", ] } @@ -272,16 +301,28 @@ js_type_check("closure_compile_local_module") { ":metrics_recorder.m", # ":os_icons.m", - # ":os_page_visibility.m", + ":os_page_visibility.m", ":os_route.m", # ":os_settings.m", # ":os_settings_icons_css.m", ":os_settings_routes.m", + ":route_origin_behavior.m", + + #":search_handler.m", + ] +} - # ":route_origin_behavior.m", - # ":search_handler.m", +js_library("deep_linking_behavior.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/deep_linking_behavior.m.js" ] + deps = [ + "..:router.m", + "..:setting_id_param_util.m", + "//chrome/browser/ui/webui/settings/chromeos/constants:mojom_js_library_for_compile", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", ] + extra_deps = [ ":modulize" ] } js_library("metrics_recorder.m") { @@ -302,10 +343,8 @@ js_library("os_icons.m") { js_library("os_page_visibility.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_page_visibility.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":os_page_visibility_module" ] + deps = [ "//ui/webui/resources/js:load_time_data.m" ] + extra_deps = [ ":modulize" ] } js_library("os_route.m") { @@ -339,7 +378,8 @@ js_library("os_settings_routes.m") { js_library("route_origin_behavior.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/route_origin_behavior.m.js" ] deps = [ - # TODO: Fill those in. + ":os_route.m", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } @@ -389,7 +429,6 @@ group("polymer3_elements") { # Local targets ":modulize", ":os_icons_module", - ":os_page_visibility_module", ":os_settings_icons_css_module", # Shared with browser settings @@ -410,12 +449,6 @@ polymer_modulizer("os_icons") { html_type = "iron-iconset" } -polymer_modulizer("os_page_visibility") { - js_file = "os_page_visibility.js" - html_file = "os_page_visibility.html" - html_type = "dom-module" -} - polymer_modulizer("os_settings_icons_css") { js_file = "os_settings_icons_css.m.js" html_file = "os_settings_icons_css.html" @@ -429,6 +462,8 @@ js_modulizer("modulize") { "route_origin_behavior.js", "search_handler.js", "os_route.js", + "os_page_visibility.js", + "deep_linking_behavior.js", ] namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/ambient_mode_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/ambient_mode_page/BUILD.gn index 71795b20191..a32163145d0 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/ambient_mode_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/ambient_mode_page/BUILD.gn @@ -3,13 +3,20 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ + ":album_item", + ":album_list", ":ambient_mode_browser_proxy", ":ambient_mode_page", ":ambient_mode_photos_page", ":constants", + ":topic_source_item", + ":topic_source_list", ] } @@ -40,8 +47,11 @@ js_library("ambient_mode_photos_page") { ":constants", "..:os_route", "../..:router", + "../localized_link:localized_link", + "//ui/webui/resources/js:assert", "//ui/webui/resources/js:cr", "//ui/webui/resources/js:i18n_behavior", + "//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js:web_ui_listener_behavior", ] } @@ -49,28 +59,72 @@ js_library("ambient_mode_photos_page") { js_library("constants") { } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":ambient_mode_browser_proxy.m", -# ":ambient_mode_page.m", -# ":ambient_mode_photos_page.m", -# ] -#} +js_library("topic_source_item") { + deps = [ + ":constants", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:i18n_behavior", + ] +} -js_library("ambient_mode_browser_proxy.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_browser_proxy.m.js" ] +js_library("topic_source_list") { deps = [ - # TODO: Fill those in. + ":constants", + "//ui/webui/resources/js:cr", ] +} + +js_library("album_item") { + deps = [ + ":constants", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("album_list") { + deps = [ + ":constants", + "//ui/webui/resources/js:cr", + ] +} + +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":album_item.m", + ":album_list.m", + ":ambient_mode_browser_proxy.m", + ":ambient_mode_page.m", + ":ambient_mode_photos_page.m", + ":topic_source_item.m", + ":topic_source_list.m", + ] +} + +js_library("constants.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/constants.m.js" ] + extra_deps = [ ":modulize" ] +} + +js_library("ambient_mode_browser_proxy.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_browser_proxy.m.js" ] + deps = [ ":constants.m" ] + externs_list = [ "$externs_path/chrome_send.js" ] extra_deps = [ ":modulize" ] } js_library("ambient_mode_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.m.js" ] deps = [ - # TODO: Fill those in. + ":ambient_mode_browser_proxy.m", + ":constants.m", + "..:os_route.m", + "../..:router.m", + "../../prefs:prefs_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":ambient_mode_page_module" ] } @@ -78,18 +132,66 @@ js_library("ambient_mode_page.m") { js_library("ambient_mode_photos_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.m.js" ] deps = [ - # TODO: Fill those in. + ":ambient_mode_browser_proxy.m", + ":constants.m", + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":ambient_mode_photos_page_module" ] } -import("//tools/polymer/polymer.gni") +js_library("topic_source_item.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.m.js" ] + deps = [ + ":constants.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":topic_source_item_module" ] +} + +js_library("topic_source_list.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.m.js" ] + deps = [ + ":constants.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] + extra_deps = [ ":topic_source_list_module" ] +} + +js_library("album_item.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_item.m.js" ] + deps = [ + ":constants.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":album_item_module" ] +} + +js_library("album_list.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.m.js" ] + deps = [ + ":constants", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] + extra_deps = [ ":album_list_module" ] +} group("polymer3_elements") { public_deps = [ + ":album_item_module", + ":album_list_module", ":ambient_mode_page_module", ":ambient_mode_photos_page_module", ":modulize", + ":topic_source_item_module", + ":topic_source_list_module", ] } @@ -97,19 +199,61 @@ polymer_modulizer("ambient_mode_page") { js_file = "ambient_mode_page.js" html_file = "ambient_mode_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("ambient_mode_photos_page") { js_file = "ambient_mode_photos_page.js" html_file = "ambient_mode_photos_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports + + [ "ui/webui/resources/html/assert.html|assertNotReached" ] } -import("//ui/webui/resources/tools/js_modulizer.gni") +polymer_modulizer("topic_source_item") { + js_file = "topic_source_item.js" + html_file = "topic_source_item.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("topic_source_list") { + js_file = "topic_source_list.js" + html_file = "topic_source_list.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("album_item") { + js_file = "album_item.js" + html_file = "album_item.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("album_list") { + js_file = "album_list.js" + html_file = "album_list.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} js_modulizer("modulize") { input_files = [ "ambient_mode_browser_proxy.js", "constants.js", ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/bluetooth_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/bluetooth_page/BUILD.gn index 9d36108f851..b89d99a0649 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/bluetooth_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/bluetooth_page/BUILD.gn @@ -16,6 +16,7 @@ js_type_check("closure_compile") { js_library("bluetooth_page") { deps = [ + "..:deep_linking_behavior", "..:os_route", "../..:router", "../../prefs:prefs_behavior", @@ -36,6 +37,7 @@ js_library("bluetooth_page") { js_library("bluetooth_subpage") { deps = [ + "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", "../..:router", @@ -91,6 +93,7 @@ js_library("bluetooth_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.m.js" ] deps = [ ":bluetooth_subpage.m", + "..:deep_linking_behavior.m", "..:os_route.m", "../..:router.m", "../../prefs:prefs_behavior.m", @@ -109,6 +112,7 @@ js_library("bluetooth_page.m") { js_library("bluetooth_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_subpage.m.js" ] deps = [ + "..:deep_linking_behavior.m", "..:metrics_recorder.m", "..:os_route.m", "../..:router.m", diff --git a/chromium/chrome/browser/resources/settings/chromeos/date_time_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/date_time_page/BUILD.gn index 3bfa5759c96..50fff49ef46 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/date_time_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/date_time_page/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -21,7 +22,6 @@ js_library("date_time_page") { "..:os_route", "../..:router", "../../prefs:prefs_behavior", - "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior", "//ui/webui/resources/js:cr", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:load_time_data", @@ -39,11 +39,9 @@ js_library("timezone_browser_proxy") { js_library("timezone_selector") { deps = [ - ":date_time_types", "../../controls:settings_dropdown_menu", "../../prefs:prefs_behavior", "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:i18n_behavior", ] } @@ -57,22 +55,28 @@ js_library("timezone_subpage") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":date_time_page.m", -# ":date_time_types.m", -# ":timezone_browser_proxy.m", -# ":timezone_selector.m", -# ":timezone_subpage.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":date_time_page.m", + ":date_time_types.m", + ":timezone_browser_proxy.m", + ":timezone_selector.m", + ":timezone_subpage.m", + ] +} js_library("date_time_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/date_time_page/date_time_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_settings_routes.m", + "../../prefs:prefs_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m", + "//ui/webui/resources/cr_elements/policy:cr_policy_pref_indicator.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":date_time_page_module" ] } @@ -80,15 +84,16 @@ js_library("date_time_page.m") { js_library("date_time_types.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/date_time_page/date_time_types.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] - extra_deps = [ ":date_time_types_module" ] + extra_deps = [ ":modulize" ] } js_library("timezone_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/date_time_page/timezone_browser_proxy.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } @@ -96,7 +101,11 @@ js_library("timezone_browser_proxy.m") { js_library("timezone_selector.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/date_time_page/timezone_selector.m.js" ] deps = [ - # TODO: Fill those in. + "../../controls:settings_dropdown_menu.m", + "../../prefs:prefs_behavior.m", + "../../prefs:prefs_types.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":timezone_selector_module" ] } @@ -104,7 +113,14 @@ js_library("timezone_selector.m") { js_library("timezone_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/date_time_page/timezone_subpage.m.js" ] deps = [ - # TODO: Fill those in. + ":date_time_types.m", + ":timezone_browser_proxy.m", + "..:os_settings_routes.m", + "../../prefs:prefs_behavior.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":timezone_subpage_module" ] } @@ -114,7 +130,6 @@ import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ ":date_time_page_module", - ":date_time_types_module", ":modulize", ":timezone_selector_module", ":timezone_subpage_module", @@ -125,28 +140,40 @@ polymer_modulizer("date_time_page") { js_file = "date_time_page.js" html_file = "date_time_page.html" html_type = "dom-module" -} - -polymer_modulizer("date_time_types") { - js_file = "date_time_types.js" - html_file = "date_time_types.html" - html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("timezone_selector") { js_file = "timezone_selector.js" html_file = "timezone_selector.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("timezone_subpage") { js_file = "timezone_subpage.js" html_file = "timezone_subpage.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + + [ "settings.TimeZoneBrowserProxy|TimeZoneBrowserProxy" ] + auto_imports = os_settings_auto_imports + [ + "chrome/browser/resources/settings/chromeos/date_time_page/date_time_types.html|TimeZoneAutoDetectMethod", + "chrome/browser/resources/settings/chromeos/date_time_page/timezone_browser_proxy.html|TimeZoneBrowserProxyImpl,TimeZoneBrowserProxy", + ] } import("//ui/webui/resources/tools/js_modulizer.gni") js_modulizer("modulize") { - input_files = [ "timezone_browser_proxy.js" ] + input_files = [ + "date_time_types.js", + "timezone_browser_proxy.js", + ] + namespace_rewrites = os_settings_namespace_rewrites + + [ "settings.TimeZoneBrowserProxy|TimeZoneBrowserProxy" ] } diff --git a/chromium/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn index 56c8f9e9eab..8f82d9031d3 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/device_page/BUILD.gn @@ -11,7 +11,6 @@ js_type_check("closure_compile") { ":display", ":display_layout", ":display_overscan_dialog", - ":dlc_subpage", ":drag_behavior", ":keyboard", ":layout_behavior", @@ -109,10 +108,6 @@ js_library("display_overscan_dialog") { extra_sources = [ "$interfaces_path/system_display_interface.js" ] } -js_library("dlc_subpage") { - deps = [ ":device_page_browser_proxy" ] -} - js_library("drag_behavior") { deps = [ "//ui/webui/resources/js:cr" ] } @@ -165,7 +160,6 @@ js_library("storage") { # ":display.m", # ":display_layout.m", # ":display_overscan_dialog.m", -# ":dlc_subpage.m", # ":drag_behavior.m", # ":keyboard.m", # ":layout_behavior.m", @@ -219,14 +213,6 @@ js_library("display_overscan_dialog.m") { extra_deps = [ ":display_overscan_dialog_module" ] } -js_library("dlc_subpage.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/device_page/dlc_subpage.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":dlc_subpage_module" ] -} - js_library("drag_behavior.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/device_page/drag_behavior.m.js" ] deps = [ @@ -315,7 +301,6 @@ group("polymer3_elements") { ":display_layout_module", ":display_module", ":display_overscan_dialog_module", - ":dlc_subpage_module", ":keyboard_module", ":modulize", ":night_light_slider_module", @@ -352,12 +337,6 @@ polymer_modulizer("display_overscan_dialog") { html_type = "dom-module" } -polymer_modulizer("dlc_subpage") { - js_file = "dlc_subpage.js" - html_file = "dlc_subpage.html" - html_type = "dom-module" -} - polymer_modulizer("keyboard") { js_file = "keyboard.js" html_file = "keyboard.html" diff --git a/chromium/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn index c09ff76361b..b48ce0b0edf 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn @@ -6,6 +6,7 @@ import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { deps = [ + ":cellular_setup_dialog", ":internet_config", ":internet_detail_page", ":internet_known_networks_page", @@ -21,8 +22,10 @@ js_type_check("closure_compile") { js_library("internet_page") { deps = [ + ":cellular_setup_dialog", ":internet_config", ":internet_page_browser_proxy", + "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", "../..:router", @@ -65,12 +68,19 @@ js_library("internet_config") { js_library("internet_detail_page") { deps = [ ":internet_page_browser_proxy", + ":network_proxy_section", + ":network_summary", ":tether_connection_dialog", + "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", "../..:router", + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", + "//ui/webui/resources/cr_components/chromeos/network:network_apnlist", + "//ui/webui/resources/cr_components/chromeos/network:network_ip_config", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", + "//ui/webui/resources/cr_components/chromeos/network:network_nameservers", + "//ui/webui/resources/cr_components/chromeos/network:network_siminfo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", ] @@ -83,10 +93,13 @@ js_library("internet_detail_page") { js_library("internet_known_networks_page") { deps = [ + "..:deep_linking_behavior", "..:metrics_recorder", + "..:os_route", + "../..:router", + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", ] externs_list = [ "$externs_path/networking_private.js" ] @@ -96,14 +109,15 @@ js_library("internet_known_networks_page") { js_library("internet_subpage") { deps = [ ":internet_page_browser_proxy", + "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", "..:route_origin_behavior", "../..:router", "../localized_link:localized_link", + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", ] @@ -117,9 +131,9 @@ js_library("network_proxy_section") { "../..:router", "../../controls:settings_toggle_button", "../../prefs:prefs_behavior", + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:network_proxy", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js/cr/ui:focus_without_ink", @@ -137,8 +151,8 @@ js_library("network_summary") { js_library("network_summary_item") { deps = [ + "//ui/webui/resources/cr_components/chromeos/network:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", - "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", ] @@ -154,10 +168,15 @@ js_library("tether_connection_dialog") { ] } +js_library("cellular_setup_dialog") { + deps = [ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog" ] +} + # TODO: Uncomment as the Polymer3 migration makes progress. #js_type_check("closure_compile_module") { # is_polymer3 = true # deps = [ +# ":cellular_setup_dialog.m" # ":internet_config.m", # ":internet_detail_page.m", # ":internet_known_networks_page.m", @@ -260,10 +279,19 @@ js_library("tether_connection_dialog.m") { extra_deps = [ ":tether_connection_dialog_module" ] } +js_library("cellular_setup_dialog.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.m.js" ] + deps = [ + # TODO: Fill those in. + ] + extra_deps = [ ":cellular_setup_dialog_module" ] +} + import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ + ":cellular_setup_dialog_module", ":internet_config_module", ":internet_detail_page_module", ":internet_known_networks_page_module", @@ -338,6 +366,12 @@ polymer_modulizer("tether_connection_dialog") { html_type = "dom-module" } +polymer_modulizer("cellular_setup_dialog") { + js_file = "cellular_setup_dialog.js" + html_file = "cellular_setup_dialog.html" + html_type = "dom-module" +} + import("//ui/webui/resources/tools/js_modulizer.gni") js_modulizer("modulize") { diff --git a/chromium/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn index fb41281d966..0453afeeb30 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn @@ -3,6 +3,9 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -88,13 +91,16 @@ js_library("multidevice_smartlock_subpage") { "..:os_settings_routes", "../../prefs:prefs_behavior", "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button", + "//ui/webui/resources/js:web_ui_listener_behavior", "//ui/webui/resources/js:cr", ] } js_library("multidevice_subpage") { deps = [ + ":multidevice_browser_proxy", ":multidevice_constants", + ":multidevice_feature_behavior", "..:os_route", "..:os_settings_routes", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", @@ -108,6 +114,7 @@ js_library("multidevice_tether_item") { ":multidevice_feature_behavior", "..:os_route", "..:os_settings_routes", + "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", ] @@ -115,43 +122,43 @@ js_library("multidevice_tether_item") { extra_sources = [ "$interfaces_path/networking_private_interface.js" ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":multidevice_browser_proxy.m", -# ":multidevice_constants.m", -# ":multidevice_feature_behavior.m", -# ":multidevice_feature_item.m", -# ":multidevice_feature_toggle.m", -# ":multidevice_page.m", -# ":multidevice_radio_button.m", -# ":multidevice_smartlock_subpage.m", -# ":multidevice_subpage.m", -# ":multidevice_tether_item.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":multidevice_browser_proxy.m", + ":multidevice_constants.m", + ":multidevice_feature_behavior.m", + ":multidevice_feature_item.m", + ":multidevice_feature_toggle.m", + ":multidevice_page.m", + ":multidevice_radio_button.m", + ":multidevice_smartlock_subpage.m", + ":multidevice_subpage.m", + ":multidevice_tether_item.m", + ] +} js_library("multidevice_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. + deps = [ + ":multidevice_constants.m", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } js_library("multidevice_constants.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":multidevice_constants_module" ] + deps = [] + extra_deps = [ ":modulize" ] } js_library("multidevice_feature_behavior.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_constants.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":modulize" ] } @@ -159,7 +166,13 @@ js_library("multidevice_feature_behavior.m") { js_library("multidevice_feature_item.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_constants.m", + ":multidevice_feature_behavior.m", + "..:os_route.m", + "..:route_origin_behavior.m", + "../..:router.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_feature_item_module" ] } @@ -167,7 +180,9 @@ js_library("multidevice_feature_item.m") { js_library("multidevice_feature_toggle.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_constants.m", + ":multidevice_feature_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_feature_toggle_module" ] } @@ -175,7 +190,18 @@ js_library("multidevice_feature_toggle.m") { js_library("multidevice_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_browser_proxy.m", + ":multidevice_constants.m", + ":multidevice_feature_behavior.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:router.m", + "../../controls:password_prompt_dialog.m", + "../../prefs:prefs_behavior.m", + "../localized_link:localized_link.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + "//ui/webui/resources/js:assert.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_page_module" ] } @@ -183,7 +209,9 @@ js_library("multidevice_page.m") { js_library("multidevice_radio_button.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button_behavior.m", + "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m", ] extra_deps = [ ":multidevice_radio_button_module" ] } @@ -191,33 +219,52 @@ js_library("multidevice_radio_button.m") { js_library("multidevice_smartlock_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_constants.m", + ":multidevice_feature_behavior.m", + "..:metrics_recorder.m", + "..:os_route.m", + "..:os_settings_routes.m", + "../../prefs:prefs_behavior.m", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_smartlock_subpage_module" ] + externs_list = [ "$externs_path/quick_unlock_private.js" ] } js_library("multidevice_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_browser_proxy.m", + ":multidevice_constants.m", + "..:os_route.m", + "..:os_settings_routes.m", + "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] + extra_deps = [ + ":multidevice_subpage_module" ] - extra_deps = [ ":multidevice_subpage_module" ] } js_library("multidevice_tether_item.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.m.js" ] deps = [ - # TODO: Fill those in. + ":multidevice_feature_behavior.m", + "..:os_route.m", + "..:os_settings_routes.m", + "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m", + "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", + "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":multidevice_tether_item_module" ] } -import("//tools/polymer/polymer.gni") - group("polymer3_elements") { public_deps = [ ":modulize", - ":multidevice_constants_module", ":multidevice_feature_item_module", ":multidevice_feature_toggle_module", ":multidevice_page_module", @@ -228,59 +275,77 @@ group("polymer3_elements") { ] } -polymer_modulizer("multidevice_constants") { - js_file = "multidevice_constants.js" - html_file = "multidevice_constants.html" - html_type = "dom-module" -} - polymer_modulizer("multidevice_feature_item") { js_file = "multidevice_feature_item.js" html_file = "multidevice_feature_item.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_feature_toggle") { js_file = "multidevice_feature_toggle.js" html_file = "multidevice_feature_toggle.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_page") { js_file = "multidevice_page.js" html_file = "multidevice_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports + [ + "ui/webui/resources/html/polymer.html|Polymer,html,beforeNextRender", + "ui/webui/resources/html/assert.html|assert", + ] } polymer_modulizer("multidevice_radio_button") { js_file = "multidevice_radio_button.js" html_file = "multidevice_radio_button.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_smartlock_subpage") { js_file = "multidevice_smartlock_subpage.js" html_file = "multidevice_smartlock_subpage.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_subpage") { js_file = "multidevice_subpage.js" html_file = "multidevice_subpage.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("multidevice_tether_item") { js_file = "multidevice_tether_item.js" html_file = "multidevice_tether_item.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } -import("//ui/webui/resources/tools/js_modulizer.gni") - js_modulizer("modulize") { input_files = [ "multidevice_browser_proxy.js", "multidevice_feature_behavior.js", + "multidevice_constants.js", ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn index e9d2407632d..1f156d1f628 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn @@ -9,6 +9,7 @@ js_type_check("closure_compile") { ":externs", ":manage_a11y_page", ":os_a11y_page", + ":switch_access_constants", ":switch_access_subpage", ":tts_subpage", "../../a11y_page:captions_subpage", @@ -38,8 +39,12 @@ js_library("manage_a11y_page") { externs_list = [ "$externs_path/settings_private.js" ] } +js_library("switch_access_constants") { +} + js_library("switch_access_subpage") { deps = [ + ":switch_access_constants", "../..:router", "../../prefs:prefs_behavior", "//ui/webui/resources/js:i18n_behavior", diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn index bec2d536c33..a4df43cc0fd 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -27,19 +28,19 @@ js_library("os_files_page") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":os_files_page.m", -# ":smb_shares_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":os_files_page.m", + ":smb_shares_page.m", + ] +} js_library("os_files_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:router.m", ] extra_deps = [ ":os_files_page_module" ] } @@ -47,7 +48,9 @@ js_library("os_files_page.m") { js_library("smb_shares_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":smb_shares_page_module" ] } @@ -58,6 +61,7 @@ group("polymer3_elements") { public_deps = [ ":os_files_page_module", ":smb_shares_page_module", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] } @@ -65,10 +69,14 @@ polymer_modulizer("os_files_page") { js_file = "os_files_page.js" html_file = "os_files_page.html" html_type = "dom-module" + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("smb_shares_page") { js_file = "smb_shares_page.js" html_file = "smb_shares_page.html" html_type = "dom-module" + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn index 6f55d8d266b..24422d5eed7 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn @@ -10,10 +10,14 @@ js_type_check("closure_compile") { deps = [ ":input_method_options_page", ":input_method_util", + ":input_page", + ":languages_metrics_proxy", ":manage_input_methods_page", ":os_add_languages_dialog", ":os_languages_page", + ":os_languages_page_v2", ":os_languages_section", + ":smart_inputs_page", "../../languages_page:languages", "../../languages_page:languages_browser_proxy", "../../languages_page:languages_types", @@ -34,6 +38,22 @@ js_library("input_method_util") { deps = [ "//ui/webui/resources/js:cr" ] } +js_library("input_page") { + deps = [ + ":input_method_util", + ":languages_metrics_proxy", + "..:os_route", + "../..:router", + "//ui/webui/resources/js:i18n_behavior", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("languages_metrics_proxy") { + deps = [ "//ui/webui/resources/js:cr" ] + externs_list = [ "$externs_path/metrics_private.js" ] +} + js_library("manage_input_methods_page") { deps = [ "../../languages_page:languages_types", @@ -63,6 +83,7 @@ js_library("os_languages_section") { js_library("os_languages_page") { deps = [ ":input_method_util", + ":languages_metrics_proxy", "..:metrics_recorder", "..:os_route", "../..:lifetime_browser_proxy", @@ -80,6 +101,25 @@ js_library("os_languages_page") { ] } +js_library("os_languages_page_v2") { + deps = [ + ":languages_metrics_proxy", + "..:metrics_recorder", + "..:os_route", + "../..:router", + "../../languages_page:languages_types", + "../../settings_page:settings_animated_pages", + "../localized_link:localized_link", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:load_time_data", + "//ui/webui/resources/js/cr/ui:focus_without_ink", + ] +} + js_library("os_add_languages_dialog") { deps = [ "../../languages_page:languages", @@ -89,47 +129,80 @@ js_library("os_add_languages_dialog") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":input_method_options_page.m", -# ":input_method_util.m", -# ":manage_input_methods_page.m", -# ":os_add_languages_dialog.m", -# ":os_languages_page.m", -# ":os_languages_section.m" -# ] -#} +js_library("smart_inputs_page") { + deps = [ + "../../prefs:prefs_behavior", + "//ui/webui/resources/js:load_time_data", + ] +} -js_library("input_method_util.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.m.js" ] +js_type_check("closure_compile_module") { + is_polymer3 = true deps = [ - # TODO: Fill those in. + ":input_method_options_page.m", + ":input_method_util.m", + ":input_page.m", + ":languages_metrics_proxy.m", + ":manage_input_methods_page.m", + ":os_add_languages_dialog.m", + ":os_languages_page.m", + ":os_languages_page_v2.m", + ":os_languages_section.m", + ":smart_inputs_page.m", ] +} + +js_library("input_method_util.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.m.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] extra_deps = [ ":modulize" ] } js_library("input_method_options_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.m.js" ] deps = [ - # TODO: Fill those in. + ":input_method_util.m", + "../../prefs:prefs.m", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":input_method_options_page_module" ] } -js_library("manage_input_methods_page.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.m.js" ] +js_library("input_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.m.js" ] deps = [ - # TODO: Fill those in. + ":input_method_util.m", + ":languages_metrics_proxy.m", + "..:os_route.m", + "../..:i18n_setup", + "../..:router.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", ] + extra_deps = [ ":input_page_module" ] +} + +js_library("languages_metrics_proxy.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/languages_metrics_proxy.m.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] + extra_deps = [ ":modulize" ] + externs_list = [ "$externs_path/metrics_private.js" ] +} + +js_library("manage_input_methods_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.m.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] extra_deps = [ ":manage_input_methods_page_module" ] } js_library("os_add_languages_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_add_languages_dialog.m.js" ] deps = [ - # TODO: Fill those in. + "../../languages_page:languages.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m", + "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field.m", + "//ui/webui/resources/js:find_shortcut_behavior.m", ] extra_deps = [ ":os_add_languages_dialog_module" ] } @@ -137,29 +210,89 @@ js_library("os_add_languages_dialog.m") { js_library("os_languages_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.m.js" ] deps = [ - # TODO: Fill those in. + ":input_method_util.m", + ":languages_metrics_proxy.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:i18n_setup", + "../..:lifetime_browser_proxy.m", + "../..:router.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":os_languages_page_module" ] } +js_library("os_languages_page_v2.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.m.js" ] + deps = [ + ":input_method_util.m", + ":languages_metrics_proxy.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:i18n_setup", + "../..:router.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", + ] + extra_deps = [ ":os_languages_page_v2_module" ] +} + js_library("os_languages_section.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.m.js" ] deps = [ - # TODO: Fill those in. + ":input_method_options_page.m", + ":manage_input_methods_page.m", + ":os_languages_page.m", + "..:os_route.m", + "../..:router.m", + "../../languages_page:languages.m", + "../../settings_page:settings_animated_pages.m", + "../../settings_page:settings_subpage.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":os_languages_section_module" ] } +js_library("smart_inputs_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/smart_inputs_page.m.js" ] + deps = [ + "../../prefs:prefs_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + ] + extra_deps = [ ":smart_inputs_page_module" ] +} + import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ ":input_method_options_page_module", + ":input_page_module", ":manage_input_methods_page_module", ":modulize", ":os_add_languages_dialog_module", ":os_languages_page_module", + ":os_languages_page_v2_module", ":os_languages_section_module", + ":smart_inputs_page_module", + "../../languages_page:languages_module", + "../../languages_page:modulize", ] } @@ -167,33 +300,78 @@ polymer_modulizer("manage_input_methods_page") { js_file = "manage_input_methods_page.js" html_file = "manage_input_methods_page.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_add_languages_dialog") { js_file = "os_add_languages_dialog.js" html_file = "os_add_languages_dialog.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_languages_page") { js_file = "os_languages_page.js" html_file = "os_languages_page.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("os_languages_page_v2") { + js_file = "os_languages_page_v2.js" + html_file = "os_languages_page_v2.html" + html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_languages_section") { js_file = "os_languages_section.js" html_file = "os_languages_section.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("input_method_options_page") { js_file = "input_method_options_page.js" html_file = "input_method_options_page.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("input_page") { + js_file = "input_page.js" + html_file = "input_page.html" + html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("smart_inputs_page") { + js_file = "smart_inputs_page.js" + html_file = "smart_inputs_page.html" + html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } js_modulizer("modulize") { - input_files = [ "input_method_util.js" ] + input_files = [ + "input_method_util.js", + "languages_metrics_proxy.js", + ] namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn index 23cc34fa5db..bd257f78b22 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn @@ -3,6 +3,9 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -30,6 +33,7 @@ js_type_check("closure_compile") { js_library("account_manager") { deps = [ + "../..:router", "../../people_page:account_manager_browser_proxy", "../localized_link:localized_link", "//ui/webui/resources/js:cr", @@ -160,7 +164,7 @@ js_library("os_sync_controls") { ":os_sync_browser_proxy", "..:metrics_recorder", "../../:router", - "../localized_link", + "../localized_link:localized_link", "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:web_ui_listener_behavior", @@ -214,34 +218,41 @@ js_library("users_page") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":account_manager.m", -# ":fingerprint_browser_proxy.m", -# ":fingerprint_list.m", -# ":kerberos_accounts.m", -# ":kerberos_accounts_browser_proxy.m", -# ":kerberos_add_account_dialog.m", -# ":lock_screen.m", -# ":lock_screen_password_prompt_dialog.m", -# ":lock_state_behavior.m", -# ":os_people_page.m", -# ":os_sync_browser_proxy.m", -# ":os_sync_controls.m", -# ":setup_fingerprint_dialog.m", -# ":setup_pin_dialog.m", -# ":user_list.m", -# ":users_add_user_dialog.m", -# ":users_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":account_manager.m", + ":fingerprint_browser_proxy.m", + ":fingerprint_list.m", + ":kerberos_accounts.m", + ":kerberos_accounts_browser_proxy.m", + ":kerberos_add_account_dialog.m", + ":lock_screen.m", + ":lock_screen_password_prompt_dialog.m", + ":lock_state_behavior.m", + ":os_people_page.m", + ":os_sync_browser_proxy.m", + ":os_sync_controls.m", + ":setup_fingerprint_dialog.m", + ":setup_pin_dialog.m", + ":user_list.m", + ":users_add_user_dialog.m", + ":users_page.m", + ] +} js_library("account_manager.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.m.js" ] deps = [ - # TODO: Fill those in. + "../..:router.m", + "../../people_page:account_manager_browser_proxy.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:icon.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":account_manager_module" ] } @@ -249,7 +260,8 @@ js_library("account_manager.m") { js_library("fingerprint_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } @@ -257,7 +269,18 @@ js_library("fingerprint_browser_proxy.m") { js_library("fingerprint_list.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.m.js" ] deps = [ - # TODO: Fill those in. + ":fingerprint_browser_proxy.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior", + "//third_party/polymer/v3_0/components-chromium/paper-ripple:paper-ripple", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":fingerprint_list_module" ] } @@ -265,7 +288,14 @@ js_library("fingerprint_list.m") { js_library("kerberos_accounts.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_accounts.m.js" ] deps = [ - # TODO: Fill those in. + ":kerberos_accounts_browser_proxy.m", + "..:metrics_recorder.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:icon.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":kerberos_accounts_module" ] } @@ -273,7 +303,8 @@ js_library("kerberos_accounts.m") { js_library("kerberos_accounts_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_accounts_browser_proxy.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } @@ -281,7 +312,15 @@ js_library("kerberos_accounts_browser_proxy.m") { js_library("kerberos_add_account_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_add_account_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":kerberos_accounts_browser_proxy.m", + "..:metrics_recorder.m", + "//chrome/browser/resources/settings/controls:settings_textarea.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_input:cr_input.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":kerberos_add_account_dialog_module" ] } @@ -289,7 +328,20 @@ js_library("kerberos_add_account_dialog.m") { js_library("lock_screen.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.m.js" ] deps = [ - # TODO: Fill those in. + ":fingerprint_browser_proxy.m", + ":lock_screen_password_prompt_dialog.m", + ":lock_state_behavior.m", + "..:os_route.m", + "../..:router.m", + "../../controls:settings_dropdown_menu.m", + "../../controls:settings_toggle_button.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/quick_unlock:lock_screen_constants.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":lock_screen_module" ] } @@ -297,7 +349,10 @@ js_library("lock_screen.m") { js_library("lock_screen_password_prompt_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen_password_prompt_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":lock_state_behavior.m", + "../../controls:password_prompt_dialog.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/quick_unlock:lock_screen_constants.m", ] extra_deps = [ ":lock_screen_password_prompt_dialog_module" ] } @@ -305,15 +360,40 @@ js_library("lock_screen_password_prompt_dialog.m") { js_library("lock_state_behavior.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/lock_state_behavior.m.js" ] deps = [ - # TODO: Fill those in. + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":modulize" ] + externs_list = [ "$externs_path/quick_unlock_private.js" ] + extra_sources = [ "$interfaces_path/quick_unlock_private_interface.js" ] } js_library("os_people_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.m.js" ] deps = [ - # TODO: Fill those in. + ":lock_screen.m", + ":lock_state_behavior.m", + ":os_sync_controls.m", + "..:os_page_visibility.m", + "..:os_route.m", + "../..:router.m", + "../../settings_page:settings_animated_pages.m", + "../localized_link:localized_link.m", + "//chrome/browser/resources/settings/people_page:profile_info_browser_proxy.m", + "//chrome/browser/resources/settings/people_page:signout_dialog.m", + "//chrome/browser/resources/settings/people_page:sync_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/quick_unlock:lock_screen_constants.m", + "//ui/webui/resources/cr_elements/chromeos/cr_picture:png.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:icon.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":os_people_page_module" ] } @@ -321,7 +401,9 @@ js_library("os_people_page.m") { js_library("os_sync_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":modulize" ] } @@ -329,7 +411,14 @@ js_library("os_sync_browser_proxy.m") { js_library("os_sync_controls.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.m.js" ] deps = [ - # TODO: Fill those in. + ":os_sync_browser_proxy.m", + "..:metrics_recorder.m", + "../../:router.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":os_sync_controls_module" ] } @@ -337,7 +426,13 @@ js_library("os_sync_controls.m") { js_library("setup_fingerprint_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":fingerprint_browser_proxy.m", + "..:metrics_recorder.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc.m", + "//ui/webui/resources/cr_elements/cr_lottie:cr_lottie.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":setup_fingerprint_dialog_module" ] } @@ -345,7 +440,11 @@ js_library("setup_fingerprint_dialog.m") { js_library("setup_pin_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/setup_pin_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":lock_screen_password_prompt_dialog.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/quick_unlock:setup_pin_keyboard.m", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":setup_pin_dialog_module" ] } @@ -353,23 +452,38 @@ js_library("setup_pin_dialog.m") { js_library("user_list.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/user_list.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":user_list_module" ] + externs_list = [ + "$externs_path/settings_private.js", + "$externs_path/users_private.js", + ] } js_library("users_add_user_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/users_add_user_dialog.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":users_add_user_dialog_module" ] + externs_list = [ "$externs_path/users_private.js" ] } js_library("users_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_people_page/users_page.m.js" ] deps = [ - # TODO: Fill those in. + ":user_list.m", + ":users_add_user_dialog.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":users_page_module" ] } @@ -387,11 +501,15 @@ group("polymer3_elements") { ":modulize", ":os_people_page_module", ":os_sync_controls_module", + ":pin_autosubmit_dialog_module", ":setup_fingerprint_dialog_module", ":setup_pin_dialog_module", ":user_list_module", ":users_add_user_dialog_module", ":users_page_module", + "../../people_page:polymer3_elements", + "../../privacy_page:polymer3_elements", + "../../:icons_module", ] } @@ -399,82 +517,127 @@ polymer_modulizer("account_manager") { js_file = "account_manager.js" html_file = "account_manager.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("fingerprint_list") { js_file = "fingerprint_list.js" html_file = "fingerprint_list.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("kerberos_accounts") { js_file = "kerberos_accounts.js" html_file = "kerberos_accounts.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("kerberos_add_account_dialog") { js_file = "kerberos_add_account_dialog.js" html_file = "kerberos_add_account_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = + os_settings_auto_imports + + [ "ui/webui/resources/html/assert.html|assert,assertNotReached" ] } polymer_modulizer("lock_screen") { js_file = "lock_screen.js" html_file = "lock_screen.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("lock_screen_password_prompt_dialog") { js_file = "lock_screen_password_prompt_dialog.js" html_file = "lock_screen_password_prompt_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_people_page") { js_file = "os_people_page.js" html_file = "os_people_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_sync_controls") { js_file = "os_sync_controls.js" html_file = "os_sync_controls.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("setup_fingerprint_dialog") { js_file = "setup_fingerprint_dialog.js" html_file = "setup_fingerprint_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + +polymer_modulizer("pin_autosubmit_dialog") { + js_file = "pin_autosubmit_dialog.js" + html_file = "pin_autosubmit_dialog.html" + html_type = "dom-module" } polymer_modulizer("setup_pin_dialog") { js_file = "setup_pin_dialog.js" html_file = "setup_pin_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("user_list") { js_file = "user_list.js" html_file = "user_list.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("users_add_user_dialog") { js_file = "users_add_user_dialog.js" html_file = "users_add_user_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("users_page") { js_file = "users_page.js" html_file = "users_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } -import("//ui/webui/resources/tools/js_modulizer.gni") - js_modulizer("modulize") { input_files = [ "fingerprint_browser_proxy.js", @@ -482,4 +645,5 @@ js_modulizer("modulize") { "lock_state_behavior.js", "os_sync_browser_proxy.js", ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn index 5a9af5bd713..cefc7b8cabf 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn @@ -3,6 +3,8 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -15,6 +17,7 @@ js_type_check("closure_compile") { ":cups_printer_dialog_util", ":cups_printers", ":cups_printers_browser_proxy", + ":cups_printers_entry_manager", ":cups_settings_add_printer_dialog", ":os_printing_page", ] @@ -170,35 +173,36 @@ js_library("os_printing_page") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":cups_settings_add_printer_dialog.m", -# ":cups_add_print_server_dialog.m", -# ":cups_add_printer_manually_dialog.m", -# ":cups_add_printer_dialog.m", -# ":cups_add_printer_manufacturer_model_dialog", -# ":cups_printer_dialog_error.m" -# ":cups_edit_printer_dialog.m", -# ":cups_nearby_printers.m", -# ":cups_printer_dialog_util.m", -# ":cups_printer_shared_css.m", -# ":cups_printer_types.m", -# ":cups_printers.m", -# ":cups_printers_browser_proxy.m", -# ":cups_printers_entry.m", -# ":cups_printers_entry_list_behavior.m", -# ":cups_printers_entry_manager.m", -# ":cups_saved_printers.m", -# ":os_printing_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":cups_add_print_server_dialog.m", + ":cups_add_printer_dialog.m", + ":cups_add_printer_manually_dialog.m", + ":cups_add_printer_manufacturer_model_dialog.m", + ":cups_edit_printer_dialog.m", + ":cups_nearby_printers.m", + ":cups_printer_dialog_error.m", + ":cups_printer_dialog_util.m", + ":cups_printer_shared_css.m", + ":cups_printer_types.m", + ":cups_printers.m", + ":cups_printers_browser_proxy.m", + ":cups_printers_entry.m", + ":cups_printers_entry_list_behavior.m", + ":cups_printers_entry_manager.m", + ":cups_saved_printers.m", + ":cups_settings_add_printer_dialog.m", + ":os_printing_page.m", + ] +} js_library("cups_settings_add_printer_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_settings_add_printer_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printers_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":cups_settings_add_printer_dialog_module" ] } @@ -206,7 +210,8 @@ js_library("cups_settings_add_printer_dialog.m") { js_library("cups_add_print_server_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_print_server_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printer_dialog_util.m", + ":cups_printers_browser_proxy.m", ] extra_deps = [ ":cups_add_print_server_dialog_module" ] } @@ -214,7 +219,8 @@ js_library("cups_add_print_server_dialog.m") { js_library("cups_add_printer_manufacturer_model_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_manufacturer_model_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printers_browser_proxy.m", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":cups_add_printer_manufacturer_model_dialog_module" ] } @@ -222,7 +228,8 @@ js_library("cups_add_printer_manufacturer_model_dialog.m") { js_library("cups_add_printer_manually_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_manually_dialog.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printers_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":cups_add_printer_manually_dialog_module" ] } @@ -230,63 +237,62 @@ js_library("cups_add_printer_manually_dialog.m") { js_library("cups_add_printer_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_dialog.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":cups_add_printer_dialog_module" ] } js_library("cups_printer_dialog_error.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_dialog_error.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":cups_printer_dialog_error_module" ] } js_library("cups_edit_printer_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.m.js" ] - deps = [ - # TODO: Fill those in. - ] + deps = [ ":cups_printer_dialog_util.m" ] extra_deps = [ ":cups_edit_printer_dialog_module" ] } js_library("cups_nearby_printers.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_nearby_printers.m.js" ] - deps = [ - # TODO: Fill those in. - ] + deps = [ ":cups_printer_dialog_util.m" ] extra_deps = [ ":cups_nearby_printers_module" ] } js_library("cups_printer_dialog_util.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_dialog_util.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printer_types.m", + "//ui/webui/resources/js:load_time_data.m", ] - extra_deps = [ ":cups_printer_dialog_util_module" ] + extra_deps = [ ":modulize" ] } js_library("cups_printer_shared_css.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_shared_css.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":cups_printer_shared_css_module" ] } js_library("cups_printer_types.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_types.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":cups_printer_types_module" ] + deps = [ ":cups_printers_browser_proxy.m" ] + extra_deps = [ ":modulize" ] } js_library("cups_printers.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printer_types.m", + ":cups_printers_browser_proxy.m", + ":cups_settings_add_printer_dialog.m", + "..:os_route.m", + "../..:router.m", + "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", + "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":cups_printers_module" ] } @@ -294,39 +300,40 @@ js_library("cups_printers.m") { js_library("cups_printers_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_browser_proxy.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:cr.m", ] extra_deps = [ ":modulize" ] } js_library("cups_printers_entry.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.m.js" ] - deps = [ - # TODO: Fill those in. - ] + deps = [ ":cups_printer_types.m" ] extra_deps = [ ":cups_printers_entry_module" ] } js_library("cups_printers_entry_list_behavior.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_list_behavior.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printer_types.m", + ":cups_printers_entry_manager.m", ] extra_deps = [ ":modulize" ] } js_library("cups_printers_entry_manager.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":cups_printers_entry_manager_module" ] + extra_deps = [ ":modulize" ] } js_library("cups_saved_printers.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printer_types.m", + ":cups_printers_browser_proxy.m", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/js:list_property_update_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":cups_saved_printers_module" ] } @@ -334,7 +341,11 @@ js_library("cups_saved_printers.m") { js_library("os_printing_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.m.js" ] deps = [ - # TODO: Fill those in. + ":cups_printers_browser_proxy.m", + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", ] extra_deps = [ ":os_printing_page_module" ] } @@ -343,21 +354,18 @@ import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ - ":cups_add_print_server_dialog", - ":cups_add_printer_dialog", + ":cups_add_print_server_dialog_module", ":cups_add_printer_dialog_module", - ":cups_add_printer_manually_dialog", - ":cups_add_printer_manufacturer_model_dialog", + ":cups_add_printer_manually_dialog_module", + ":cups_add_printer_manufacturer_model_dialog_module", ":cups_edit_printer_dialog_module", ":cups_nearby_printers_module", ":cups_printer_dialog_error_module", - ":cups_printer_dialog_util_module", ":cups_printer_shared_css_module", - ":cups_printer_types_module", - ":cups_printers_entry_manager_module", ":cups_printers_entry_module", ":cups_printers_module", ":cups_saved_printers_module", + ":cups_settings_add_printer_dialog_module", ":modulize", ":os_printing_page_module", ] @@ -367,96 +375,117 @@ polymer_modulizer("cups_settings_add_printer_dialog") { js_file = "cups_settings_add_printer_dialog.js" html_file = "cups_settings_add_printer_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_add_print_server_dialog") { js_file = "cups_add_print_server_dialog.js" html_file = "cups_add_print_server_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_add_printer_manufacturer_model_dialog") { js_file = "cups_add_printer_manufacturer_model_dialog.js" html_file = "cups_add_printer_manufacturer_model_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_add_printer_manually_dialog") { js_file = "cups_add_printer_manually_dialog.js" html_file = "cups_add_printer_manually_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_add_printer_dialog") { js_file = "cups_add_printer_dialog.js" html_file = "cups_add_printer_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_printer_dialog_error") { js_file = "cups_printer_dialog_error.js" html_file = "cups_printer_dialog_error.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_edit_printer_dialog") { js_file = "cups_edit_printer_dialog.js" html_file = "cups_edit_printer_dialog.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_nearby_printers") { js_file = "cups_nearby_printers.js" html_file = "cups_nearby_printers.html" html_type = "dom-module" -} - -polymer_modulizer("cups_printer_dialog_util") { - js_file = "cups_printer_dialog_util.js" - html_file = "cups_printer_dialog_util.html" - html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_printer_shared_css") { js_file = "cups_printer_shared_css.m.js" html_file = "cups_printer_shared_css.html" html_type = "style-module" -} - -polymer_modulizer("cups_printer_types") { - js_file = "cups_printer_types.js" - html_file = "cups_printer_types.html" - html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_printers") { js_file = "cups_printers.js" html_file = "cups_printers.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_printers_entry") { js_file = "cups_printers_entry.js" html_file = "cups_printers_entry.html" html_type = "dom-module" -} - -polymer_modulizer("cups_printers_entry_manager") { - js_file = "cups_printers_entry_manager.js" - html_file = "cups_printers_entry_manager.html" - html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("cups_saved_printers") { js_file = "cups_saved_printers.js" html_file = "cups_saved_printers.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_printing_page") { js_file = "os_printing_page.js" html_file = "os_printing_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } import("//ui/webui/resources/tools/js_modulizer.gni") @@ -465,5 +494,9 @@ js_modulizer("modulize") { input_files = [ "cups_printers_browser_proxy.js", "cups_printers_entry_list_behavior.js", + "cups_printer_types.js", + "cups_printers_entry_manager.js", + "cups_printer_dialog_util.js", ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn index 32e7bbe7959..9cfadf7b298 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_privacy_page/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ ":os_privacy_page" ] @@ -15,18 +16,16 @@ js_library("os_privacy_page") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":os_privacy_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ ":os_privacy_page.m" ] +} js_library("os_privacy_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.m.js" ] deps = [ - # TODO: Fill those in. + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":os_privacy_page_module" ] } @@ -41,4 +40,6 @@ polymer_modulizer("os_privacy_page") { js_file = "os_privacy_page.js" html_file = "os_privacy_page.html" html_type = "dom-module" + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn index e05a9896a07..a363496a9ce 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn @@ -26,9 +26,11 @@ js_library("os_powerwash_dialog") { js_library("os_reset_page") { deps = [ + "..:deep_linking_behavior", + "..:os_route", + "../..:router", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js/cr/ui:focus_without_ink", ] } @@ -71,9 +73,11 @@ js_library("os_reset_browser_proxy.m") { js_library("os_reset_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_page.m.js" ] deps = [ + "..:deep_linking_behavior.m", + "..:os_route.m", + "../..:router.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":os_reset_page_module" ] diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings.gni b/chromium/chrome/browser/resources/settings/chromeos/os_settings.gni index 400b8e0059e..8fe43f9c02c 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings.gni @@ -3,22 +3,123 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//ui/webui/resources/cr_components/chromeos/os_cr_components.gni") +import("//ui/webui/resources/cr_elements/chromeos/os_cr_elements.gni") import("../settings.gni") -os_settings_namespace_rewrites = - settings_namespace_rewrites + [ - "settings.OsResetBrowserProxy|OsResetBrowserProxy", - "settings.recordSettingChange|recordSettingChange", - ] +os_settings_namespace_rewrites = settings_namespace_rewrites + + cr_components_chromeos_namespace_rewrites + + cr_elements_chromeos_namespace_rewrites + [ + "// #polymer3 |", + "parental_controls.ParentalControlsBrowserProxy|ParentalControlsBrowserProxy", + "settings.AccountManagerBrowserProxy|AccountManagerBrowserProxy", + "settings.AmbientModeBrowserProxy|AmbientModeBrowserProxy", + "settings.ChangePictureBrowserProxy|ChangePictureBrowserProxy", + "settings.DefaultImage|DefaultImage", + "settings.FingerprintAttempt|FingerprintAttempt", + "settings.FingerprintBrowserProxy|FingerprintBrowserProxy", + "settings.FingerprintInfo|FingerprintInfo", + "settings.FingerprintResultType|FingerprintResultType", + "settings.FingerprintScan|FingerprintScan", + "settings.FingerprintSetupStep|FingerprintSetupStep", + "settings.input_method_util.generateOptions|generateOptions", + "settings.input_method_util.getFirstPartyInputMethodEngineId|getFirstPartyInputMethodEngineId", + "settings.input_method_util.getOptionLabelName|getOptionLabelName", + "settings.input_method_util.getOptionMenuItems|getOptionMenuItems", + "settings.input_method_util.getOptionUiType|getOptionUiType", + "settings.input_method_util.getOptionUrl|getOptionUrl", + "settings.input_method_util.hasOptionsPageInSettings|hasOptionsPageInSettings", + "settings.input_method_util.InputToolCode|InputToolCode", + "settings.input_method_util.isNumberValue|isNumberValue", + "settings.input_method_util.OPTION_DEFAULT|OPTION_DEFAULT", + "settings.input_method_util.OptionType|OptionType", + "settings.input_method_util.UiType|UiType", + "settings.KerberosAccount|KerberosAccount", + "settings.KerberosAccountsBrowserProxy|KerberosAccountsBrowserProxy", + "settings.KerberosConfigErrorCode|KerberosConfigErrorCode", + "settings.KerberosErrorType|KerberosErrorType", + "settings.kMenuCloseDelay|kMenuCloseDelay", + "settings.LanguagesMetricsProxy|LanguagesMetricsProxy", + "settings.LanguagesPageInteraction|LanguagesPageInteraction", + "settings.MultiDeviceBrowserProxy|MultiDeviceBrowserProxy", + "settings.MultiDeviceFeature|MultiDeviceFeature", + "settings.MultiDeviceFeatureState|MultiDeviceFeatureState", + "settings.MultiDevicePageContentData|MultiDevicePageContentData", + "settings.MultiDeviceSettingsMode|MultiDeviceSettingsMode", + "settings.OsResetBrowserProxy|OsResetBrowserProxy", + "settings.OsSyncBrowserProxy|OsSyncBrowserProxy", + "settings.OsSyncPrefs|OsSyncPrefs", + "settings.recordLockScreenProgress|recordLockScreenProgress", + "settings.recordSettingChange|recordSettingChange", + "settings.Route|Route", + "settings.RouteObserverBehavior|RouteObserverBehavior", + "settings.Router|Router", + "settings.routes|routes", + "settings.SmartLockSignInEnabledState|SmartLockSignInEnabledState", + "settings.TimeZoneAutoDetectMethod|TimeZoneAutoDetectMethod", + "settings.TimeZoneBrowserProxyImpl|TimeZoneBrowserProxyImpl", + "settings.ValidateKerberosConfigResult|ValidateKerberosConfigResult", + "settings.WallpaperBrowserProxy|WallpaperBrowserProxy", + "smb_shares.SmbBrowserProxy|SmbBrowserProxy", + "settings.CupsPrintersBrowserProxy|CupsPrintersBrowserProxy", + "settings.CupsPrintersBrowserProxyImpl|CupsPrintersBrowserProxyImpl", + "settings.printing.alphabeticalSort|alphabeticalSort", + "settings.printing.CupsPrintersEntryManager|CupsPrintersEntryManager", + "settings.printing.matchesSearchTerm|matchesSearchTerm", + "settings.printing.sortPrinters|sortPrinters", + "settings.printing.findDifference|findDifference", + "settings.printing.getBaseName|getBaseName", + "settings.printing.getErrorText|getErrorText", + "settings.printing.isNetworkProtocol|isNetworkProtocol", + "settings.printing.isNameAndAddressValid|isNameAndAddressValid", + "settings.printing.isPPDInfoValid|isPPDInfoValid", + "settings.printing.getPrintServerErrorText|getPrintServerErrorText", + ] -os_settings_auto_imports = settings_auto_imports + [ - "chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_browser_proxy.html|OsResetBrowserProxy,OsResetBrowserProxyImpl", +os_settings_auto_imports = settings_auto_imports + + cr_components_chromeos_auto_imports + + cr_elements_chromeos_auto_imports + [ + "chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_browser_proxy.html|AmbientModeBrowserProxy,AmbientModeBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/ambient_mode_page/constants.html|AmbientModeTopicSource,AmbientModeTemperatureUnit,AmbientModeAlbum,AmbientModeSettings,TopicSourceItem", + "chrome/browser/resources/settings/chromeos/deep_linking_behavior.html|DeepLinkingBehavior", "chrome/browser/resources/settings/chromeos/metrics_recorder.html|recordSettingChange", - "chrome/browser/resources/settings/lifetime_browser_proxy.html|LifetimeBrowserProxy,LifetimeBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html|MultiDeviceBrowserProxy,MultiDeviceBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.html|MultiDeviceSettingsMode,MultiDeviceFeature,MultiDeviceFeatureState,MultiDevicePageContentData,SmartLockSignInEnabledState", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.html|MultiDeviceFeatureBehavior", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html|MultiDeviceBrowserProxy,MultiDeviceBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.html|generateOptions,getFirstPartyInputMethodEngineId,getOptionLabelName,getOptionMenuItems,getOptionUiType,getOptionUrl,hasOptionsPageInSettings,InputToolCode,isNumberValue,OPTION_DEFAULT,OptionType,UiType", + "chrome/browser/resources/settings/chromeos/os_languages_page/languages_metrics_proxy.html|LanguagesMetricsProxy, LanguagesMetricsProxyImpl, LanguagesPageInteraction", + "chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.html|FingerprintInfo,FingerprintBrowserProxy,FingerprintResultType,FingerprintBrowserProxyImpl,FingerprintAttempt,FingerprintScan", + "chrome/browser/resources/settings/chromeos/os_people_page/kerberos_accounts_browser_proxy.html|KerberosAccount,KerberosAccountsBrowserProxyImpl,KerberosAccountsBrowserProxy,KerberosErrorType,KerberosConfigErrorCode,ValidateKerberosConfigResult", + "chrome/browser/resources/settings/chromeos/os_people_page/lock_state_behavior.html|LockScreenUnlockType,LockStateBehaviorImpl,LockStateBehavior", + "chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.html|OsSyncBrowserProxy,OsSyncBrowserProxyImpl,OsSyncPrefs", + "chrome/browser/resources/settings/chromeos/os_page_visibility.html|OSPageVisibility", + "chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_browser_proxy.html|OsResetBrowserProxy,OsResetBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/os_route.html|routes", + "chrome/browser/resources/settings/chromeos/os_settings_routes.html|OsSettingsRoutes", + "chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.html|ChangePictureBrowserProxy,ChangePictureBrowserProxyImpl,DefaultImage", + "chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.html|WallpaperBrowserProxy,WallpaperBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_browser_proxy.html|ParentalControlsBrowserProxy,ParentalControlsBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/route_origin_behavior.html|RouteOriginBehaviorImpl,RouteOriginBehavior", + "chrome/browser/resources/settings/controls/settings_dropdown_menu.html|DropdownMenuOptionList", + "chrome/browser/resources/settings/lifetime_browser_proxy.html|LifetimeBrowserProxy,LifetimeBrowserProxyImpl", + "chrome/browser/resources/settings/people_page/account_manager_browser_proxy.html|AccountManagerBrowserProxy,AccountManagerBrowserProxyImpl,Account", + "chrome/browser/resources/settings/people_page/profile_info_browser_proxy.html|ProfileInfoBrowserProxyImpl,ProfileInfoBrowserProxy,ProfileInfo", + "chrome/browser/resources/settings/people_page/sync_browser_proxy.html|SyncBrowserProxyImpl,SyncBrowserProxy,StatusAction,SyncStatus", "chrome/browser/resources/settings/route.html|routes", "chrome/browser/resources/settings/router.html|Router,Route,RouteObserverBehavior", - "ui/webui/resources/html/polymer.html|Polymer,html,flush", + "ui/webui/resources/html/assert.html|assert,assertNotReached", + "ui/webui/resources/html/cr.html|sendWithPromise,removeWebUIListener,addWebUIListener,WebUIListener", + "ui/webui/resources/html/icon.html|getImage", + "ui/webui/resources/html/polymer.html|afterNextRender,Polymer,html,flush", + "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_browser_proxy.html|CupsPrintersBrowserProxy,CupsPrintersBrowserProxyImpl,CupsPrinterInfo,PrinterSetupResult,CupsPrintersList,PrinterPpdMakeModel,ManufacturersInfo,ModelsInfo,PrintServerResult,PrinterMakeModel", + "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_list_behavior.html|CupsPrintersEntryListBehavior", + "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.html|CupsPrintersEntryManager", + "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_dialog_util.html|sortPrinters,matchesSearchTerm,getBaseName,getErrorText,isNetworkProtocol,isNameAndAddressValid,isPPDInfoValid,getPrintServerErrorText", + "ui/webui/resources/html/list_property_update_behavior.html|ListPropertyUpdateBehavior", + "ui/webui/resources/html/web_ui_listener_behavior.html|WebUIListenerBehavior", + "ui/webui/resources/cr_components/chromeos/network/network_listener_behavior.html|NetworkListenerBehavior", + "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_types.html|PrinterListEntry,PrinterType", ] os_settings_migrated_imports = settings_migrated_imports diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn index 8d7c32450f0..f410fc1e9ba 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn @@ -13,7 +13,7 @@ js_library("os_settings_main") { "..:os_page_visibility", "../..:router", "../..:search_settings", - "../../settings_page:main_page_behavior", + "../os_settings_page:main_page_behavior", "../os_settings_page:os_settings_page", "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted", "//ui/webui/resources/js:assert", diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_menu/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_settings_menu/BUILD.gn index 1521e8cee6d..bd4ebade611 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_menu/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_menu/BUILD.gn @@ -10,6 +10,7 @@ js_type_check("closure_compile") { js_library("os_settings_menu") { deps = [ + "..:os_route", "../..:router", "//third_party/polymer/v1_0/components-chromium/iron-collapse:iron-collapse-extracted", "//third_party/polymer/v1_0/components-chromium/paper-ripple:paper-ripple-extracted", diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn index 7afa56ffe1d..9a3f7f9a532 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn @@ -3,18 +3,24 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { - deps = [ ":os_settings_page" ] + deps = [ + ":main_page_behavior", + ":os_settings_page", + ":settings_idle_load", + ] } js_library("os_settings_page") { deps = [ + ":main_page_behavior", "..:os_page_visibility", "..:os_route", "../..:router", "../..:search_settings", - "../../settings_page:main_page_behavior", "../os_apps_page:android_apps_browser_proxy", "//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js:web_ui_listener_behavior", @@ -22,13 +28,30 @@ js_library("os_settings_page") { externs_list = [ "$externs_path/pending.js" ] } +js_library("main_page_behavior") { + deps = [ + "../..:router", + "../../settings_page:settings_section", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:util", + ] + externs_list = [ "$externs_path/pending.js" ] +} + +js_library("settings_idle_load") { + deps = [ "//ui/webui/resources/js:assert" ] + externs_list = [ "$externs_path/pending_polymer.js" ] +} + # TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":os_settings_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + # ":os_settings_page.m", + ":main_page_behavior.m", + ":settings_idle_load.m", + ] +} js_library("os_settings_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.m.js" ] @@ -38,10 +61,35 @@ js_library("os_settings_page.m") { extra_deps = [ ":os_settings_page_module" ] } +js_library("main_page_behavior.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.m.js" ] + deps = [ + "../..:router.m", + "../../settings_page:settings_section.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:util.m", + ] + extra_deps = [ ":modulize" ] +} + +js_library("settings_idle_load.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_settings_page/settings_idle_load.m.js" ] + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + ] + extra_deps = [ ":settings_idle_load_module" ] +} + import("//tools/polymer/polymer.gni") group("polymer3_elements") { - public_deps = [ ":os_settings_page_module" ] + public_deps = [ + ":modulize", + ":os_settings_page_module", + ":settings_idle_load_module", + ] } polymer_modulizer("os_settings_page") { @@ -49,3 +97,22 @@ polymer_modulizer("os_settings_page") { html_file = "os_settings_page.html" html_type = "dom-module" } + +polymer_modulizer("settings_idle_load") { + js_file = "settings_idle_load.js" + html_file = "settings_idle_load.html" + html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + auto_imports = [ + "chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.html|ensureLazyLoaded", + "ui/webui/resources/html/assert.html|assert", + "ui/webui/resources/html/polymer.html|Polymer,html,templatize,TemplateInstanceBase", + ] + namespace_rewrites = os_settings_namespace_rewrites + + [ "Polymer.Templatize.templatize|templatize" ] +} + +js_modulizer("modulize") { + input_files = [ "main_page_behavior.js" ] + namespace_rewrites = os_settings_namespace_rewrites +} diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chromium/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp index c764effbb47..cbdc3f43636 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp @@ -1,7 +1,298 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> - <include name="IDR_OS_SETTINGS_RESET_BROWSER_PROXY_M_JS" - file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_browser_proxy.m.js" + <include name="IDR_OS_SETTINGS_ALBUM_ITEM_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_item.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_ALBUM_LIST_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_TOPIC_SOURCE_ITEM_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_TOPIC_SOURCE_LIST_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_AMBIENT_MODE_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_AMBIENT_MODE_PHOTOS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PERSONALIZATION_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_WALLPAPER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PERSONALIZATION_PAGE_CHANGE_PICTURE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/personalization_page/change_picture.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PERSONALIZATION_PAGE_CHANGE_PICTURE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_AMBIENT_MODE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_AMBIENT_MODE_CONSTANTS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/ambient_mode_page/constants.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_RADIO_GROUP_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_radio_group.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_TEXTAREA_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_textarea.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DROPDOWN_MENU_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_dropdown_menu.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_LANGUAGES_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages_browser_proxy.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_LANGUAGES_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_ADD_LANGUAGES_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_add_languages_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_METHOD_OPTIONS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_METHOD_UTIL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_MANAGE_INPUT_METHODS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_LANGUAGES_METRICS_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/languages_metrics_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_SECTION_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_SMART_INPUTS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/smart_inputs_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_ACCOUNT_MANAGER_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_PROFILE_INFO_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/profile_info_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SYNC_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SYNC_ACCOUNT_CONTROL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_account_control.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SYNC_ENCRYPTION_OPTIONS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_encryption_options.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SIGNOUT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/signout_dialog.m.js" + use_base_dir="false" + preprocess="true" + compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SYNC_CONTROLS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_controls.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SYNC_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/people_page/sync_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_PRIVACY_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.m.js" + use_base_dir="false" + preprocess="true" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PRIVACY_PAGE_PERSONALIZATION_OPTIONS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/personalization_options.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PARENTAL_CONTROLS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PARENTAL_CONTROLS_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_KERBEROS_ACCOUNTS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_accounts.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_KERBEROS_ACCOUNTS_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_accounts_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_KERBEROS_ADD_ACCOUNT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/kerberos_add_account_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_ACCOUNT_MANAGER_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_FINGERPRINT_LIST_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_LOCK_SCREEN_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_LOCK_SCREEN_PASSWORD_PROMPT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen_password_prompt_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_LOCK_STATE_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/lock_state_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_OS_SYNC_CONTROLS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_USERS_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/users_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_USERS_ADD_USER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/users_add_user_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_OS_SYNC_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_USERS_LIST_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/user_list.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_FINGERPRINT_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SETUP_FINGERPRINT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/setup_fingerprint_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_PIN_AUTOSUBMIT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/pin_autosubmit_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_SETUP_PIN_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/setup_pin_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PEOPLE_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.m.js" use_base_dir="false" compress="false" type="BINDATA" /> @@ -15,6 +306,111 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_RESET_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_ADD_PRINT_SERVER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_print_server_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_ADD_PRINTER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_ADD_PRINTER_MANUALLY_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_manually_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_ADD_PRINTER_MANUFACTURER_MODEL_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_add_printer_manufacturer_model_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_EDIT_PRINTER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_NEARBY_PRINTERS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_nearby_printers.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTER_DIALOG_ERROR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_dialog_error.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTER_DIALOG_UTIL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_dialog_util.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTER_SHARED_CSS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_shared_css.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTER_TYPES_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_types.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTERS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTERS_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTERS_ENTRY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_list_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_PRINTERS_ENTRY_MANAGER_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_SAVED_PRINTERS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CUPS_SETTINGS_ADD_PRINTER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/cups_settings_add_printer_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_OS_PRINTING_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_printing_page/os_printing_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_FILES_PAGE_OS_FILES_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_FILES_PAGE_SMB_SHARES_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_BLUETOOTH_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.m.js" use_base_dir="false" @@ -30,6 +426,11 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_DEEP_LINKING_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/deep_linking_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_LOCALIZED_LINK_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/localized_link/localized_link.m.js" use_base_dir="false" @@ -40,11 +441,90 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PAGE_VISIBILITY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_page_visibility.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_PAGE_VISIBILITY_JS" + file="page_visibility.js" + preprocess="true" + compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_SUBPAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_CONSTANTS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_FEATURE_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_FEATURE_ITEM_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_TETHER_ITEM_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_FEATURE_TOGGLE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_SMARTLOCK_SUBPAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_MULTIDEVICE_RADIO_BUTTON_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_ROUTE_ORIGIN_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/route_origin_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_SETTINGS_CONTROLS_PASSWORD_PROMPT_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/controls/password_prompt_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_SETTINGS_CONTROLS_CONTROLLED_RADIO_BUTTON_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/controls/controlled_radio_button.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_OS_ICONS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_icons.m.js" use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_ICONS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/icons.m.js" + use_base_dir="false" + compress="false" type="BINDATA" + preprocess="true" /> <include name="IDR_OS_SETTINGS_SETTINGS_OS_ROUTE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_route.m.js" use_base_dir="false" @@ -91,6 +571,10 @@ use_base_dir="false" compress="false" type="BINDATA"/> + <include name="IDR_OS_SETTINGS_PREFS_PREF_UTIL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/prefs/pref_util.m.js" + use_base_dir="false" + compress="false" type="BINDATA" /> <include name="IDR_OS_SETTINGS_PREFS_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/prefs/prefs_behavior.m.js" use_base_dir="false" @@ -106,11 +590,30 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/nearby_share_page/nearby_share_device_name_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/nearby_share_page/nearby_share_data_usage_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_NEARBY_SHARE_TYPES_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/nearby_share_page/types.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_ROUTER_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/router.m.js" use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_SETTINGS_SETTING_ID_PARAM_UTIL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/setting_id_param_util.m.js" + use_base_dir="false" + compress="false" type="BINDATA" /> <include name="IDR_OS_SETTINGS_SETTINGS_SHARED_CSS_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_shared_css.m.js" use_base_dir="false" @@ -126,12 +629,45 @@ file="i18n_setup.js" compress="false" type="BINDATA" /> - <include name="IDR_OS_SETTINGS_SETTINGS_V3_HTML" + <include name="IDR_OS_SETTINGS_ENSURE_LAZY_LOADED_JS" + file="chromeos/ensure_lazy_loaded.m.js" + preprocess="true" + compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LAZY_LOAD_V3_JS" + file="chromeos/lazy_load.js" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML" file="chromeos/os_settings_v3.html" compress="false" type="BINDATA" /> - <include name="IDR_OS_SETTINGS_SETTINGS_V3_JS" + <include name="IDR_OS_SETTINGS_OS_SETTINGS_V3_JS" file="chromeos/os_settings.js" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DATE_TIME_PAGE_DATE_TIME_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/date_time_page/date_time_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DATE_TIME_PAGE_DATE_TIME_TYPES_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/date_time_page/date_time_types.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DATE_TIME_PAGE_TIMEZONE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/date_time_page/timezone_browser_proxy.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DATE_TIME_PAGE_TIMEZONE_SELECTOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/date_time_page/timezone_selector.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_SETTINGS_DATE_TIME_PAGE_TIMEZONE_SUBPAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/date_time_page/timezone_subpage.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> </grit-part> diff --git a/chromium/chrome/browser/resources/settings/chromeos/parental_controls_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/parental_controls_page/BUILD.gn index 9c9e665523a..e423491690e 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/parental_controls_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/parental_controls_page/BUILD.gn @@ -3,6 +3,9 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ ":parental_controls_page" ] @@ -22,33 +25,30 @@ js_library("parental_controls_page") { ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":parental_controls_browser_proxy.m", -# ":parental_controls_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":parental_controls_browser_proxy.m", + ":parental_controls_page.m", + ] +} js_library("parental_controls_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":modulize" ] } js_library("parental_controls_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_page.m.js" ] deps = [ - # TODO: Fill those in. + ":parental_controls_browser_proxy.m", + "../..:router.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":parental_controls_page_module" ] } -import("//tools/polymer/polymer.gni") - group("polymer3_elements") { public_deps = [ ":modulize", @@ -60,10 +60,12 @@ polymer_modulizer("parental_controls_page") { js_file = "parental_controls_page.js" html_file = "parental_controls_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } -import("//ui/webui/resources/tools/js_modulizer.gni") - js_modulizer("modulize") { input_files = [ "parental_controls_browser_proxy.js" ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn index 766826b0561..dddafc39f27 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn @@ -3,6 +3,9 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -17,14 +20,15 @@ js_library("change_picture") { ":change_picture_browser_proxy", "..:metrics_recorder", "..:os_route", + "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted", "//third_party/polymer/v1_0/components-chromium/iron-selector:iron-selector-extracted", "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_list", "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_pane", "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_types", "//ui/webui/resources/cr_elements/chromeos/cr_picture:png", + "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:load_time_data", - "//ui/webui/resources/js:util", "//ui/webui/resources/js:web_ui_listener_behavior", ] } @@ -50,51 +54,65 @@ js_library("wallpaper_browser_proxy") { externs_list = [ "$externs_path/chrome_send.js" ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":change_picture.m", -# ":change_picture_browser_proxy.m", -# ":personalization_page.m", -# ":wallpaper_browser_proxy.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":change_picture.m", + ":change_picture_browser_proxy.m", + ":personalization_page.m", + ":wallpaper_browser_proxy.m", + ] +} js_library("change_picture.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/personalization_page/change_picture.m.js" ] deps = [ - # TODO: Fill those in. + ":change_picture_browser_proxy.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer", + "//third_party/polymer/v3_0/components-chromium/iron-selector:iron-selector", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_list.m", + "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_pane.m", + "//ui/webui/resources/cr_elements/chromeos/cr_picture:cr_picture_types.m", + "//ui/webui/resources/cr_elements/chromeos/cr_picture:png.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:util.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":change_picture_module" ] } js_library("change_picture_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":modulize" ] } js_library("personalization_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.m.js" ] deps = [ - # TODO: Fill those in. + ":wallpaper_browser_proxy.m", + "..:os_route.m", + "../..:router.m", + "../../prefs:prefs.m", + "../../settings_page:settings_animated_pages.m", + "../ambient_mode_page:ambient_mode_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":personalization_page_module" ] } js_library("wallpaper_browser_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. - ] + externs_list = [ "$externs_path/chrome_send.js" ] extra_deps = [ ":modulize" ] } -import("//tools/polymer/polymer.gni") - group("polymer3_elements") { public_deps = [ ":change_picture_module", @@ -107,19 +125,28 @@ polymer_modulizer("change_picture") { js_file = "change_picture.js" html_file = "change_picture.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + + [ "Polymer.IronA11yAnnouncer|IronA11yAnnouncer" ] + auto_imports = os_settings_auto_imports + [ + "ui/webui/resources/html/assert.html|assertNotReached", + "ui/webui/resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.html|IronA11yAnnouncer", + ] } polymer_modulizer("personalization_page") { js_file = "personalization_page.js" html_file = "personalization_page.html" html_type = "dom-module" + migrated_imports = os_settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } -import("//ui/webui/resources/tools/js_modulizer.gni") - js_modulizer("modulize") { input_files = [ "change_picture_browser_proxy.js", "wallpaper_browser_proxy.js", ] + namespace_rewrites = os_settings_namespace_rewrites } diff --git a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/BUILD.gn b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/BUILD.gn index c39c2fc34fd..e073a1efea4 100644 --- a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/BUILD.gn @@ -14,6 +14,7 @@ js_type_check("closure_compile_module") { ":clear_browsing_data_dialog", ":history_deletion_dialog", ":installed_app_checkbox", + ":passwords_deletion_dialog", ] } @@ -41,6 +42,13 @@ js_library("history_deletion_dialog") { ] } +js_library("passwords_deletion_dialog") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", + ] +} + js_library("installed_app_checkbox") { deps = [ ":clear_browsing_data_browser_proxy", @@ -53,5 +61,6 @@ html_to_js("web_components") { "clear_browsing_data_dialog.js", "history_deletion_dialog.js", "installed_app_checkbox.js", + "passwords_deletion_dialog.js", ] } diff --git a/chromium/chrome/browser/resources/settings/controls/BUILD.gn b/chromium/chrome/browser/resources/settings/controls/BUILD.gn index 506ca163505..414bda04140 100644 --- a/chromium/chrome/browser/resources/settings/controls/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/controls/BUILD.gn @@ -17,7 +17,6 @@ js_type_check("closure_compile") { ":pref_control_behavior", ":settings_boolean_control_behavior", ":settings_dropdown_menu", - ":settings_idle_load", ":settings_radio_group", ":settings_slider", ":settings_textarea", @@ -88,11 +87,6 @@ js_library("settings_dropdown_menu") { externs_list = [ "$externs_path/settings_private.js" ] } -js_library("settings_idle_load") { - deps = [ "//ui/webui/resources/js:assert" ] - externs_list = [ "$externs_path/pending_polymer.js" ] -} - js_library("settings_radio_group") { deps = [ ":pref_control_behavior", @@ -133,7 +127,7 @@ js_type_check("closure_compile_module") { ":settings_boolean_control_behavior.m", ":settings_checkbox", ":settings_dropdown_menu.m", - ":settings_idle_load.m", + ":settings_idle_load", ":settings_radio_group.m", ":settings_slider.m", ":settings_textarea.m", @@ -228,13 +222,11 @@ js_library("settings_dropdown_menu.m") { extra_deps = [ ":settings_dropdown_menu_module" ] } -js_library("settings_idle_load.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/controls/settings_idle_load.m.js" ] +js_library("settings_idle_load") { deps = [ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", ] - extra_deps = [ ":settings_idle_load_module" ] } js_library("settings_radio_group.m") { @@ -287,7 +279,6 @@ group("polymer3_elements") { ":modulize", ":password_prompt_dialog_module", ":settings_dropdown_menu_module", - ":settings_idle_load_module", ":settings_radio_group_module", ":settings_slider_module", ":settings_textarea_module", @@ -350,20 +341,6 @@ polymer_modulizer("settings_dropdown_menu") { namespace_rewrites = settings_namespace_rewrites } -polymer_modulizer("settings_idle_load") { - js_file = "settings_idle_load.js" - html_file = "settings_idle_load.html" - html_type = "dom-module" - migrated_imports = settings_migrated_imports - auto_imports = [ - "chrome/browser/resources/settings/ensure_lazy_loaded.html|ensureLazyLoaded", - "ui/webui/resources/html/assert.html|assert", - "ui/webui/resources/html/polymer.html|Polymer,html,templatize,TemplateInstanceBase", - ] - namespace_rewrites = settings_namespace_rewrites + - [ "Polymer.Templatize.templatize|templatize" ] -} - polymer_modulizer("settings_radio_group") { js_file = "settings_radio_group.js" html_file = "settings_radio_group.html" diff --git a/chromium/chrome/browser/resources/settings/languages_page/BUILD.gn b/chromium/chrome/browser/resources/settings/languages_page/BUILD.gn index 95ebf73a699..2ebe0331628 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/languages_page/BUILD.gn @@ -61,6 +61,7 @@ js_type_check("closure_compile_module") { ":edit_dictionary_page", ":languages.m", ":languages_browser_proxy.m", + ":languages_metrics_proxy", ":languages_page", ":languages_types", ] @@ -130,9 +131,15 @@ js_library("languages_browser_proxy.m") { extra_deps = [ ":modulize" ] } +js_library("languages_metrics_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/metrics_private.js" ] +} + js_library("languages_page") { deps = [ ":languages.m", + ":languages_metrics_proxy", "..:lifetime_browser_proxy.m", "..:route", "..:router.m", diff --git a/chromium/chrome/browser/resources/settings/nearby_share_page/BUILD.gn b/chromium/chrome/browser/resources/settings/nearby_share_page/BUILD.gn index 81c2a5030f6..1a52410d6da 100644 --- a/chromium/chrome/browser/resources/settings/nearby_share_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/nearby_share_page/BUILD.gn @@ -4,51 +4,161 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") import("../settings.gni") js_type_check("closure_compile") { - deps = [ ":nearby_share_subpage" ] + deps = [ + ":nearby_share_data_usage_dialog", + ":nearby_share_device_name_dialog", + ":nearby_share_subpage", + ":types", + ] +} + +js_library("nearby_share_data_usage_dialog") { + deps = [ + ":types", + "../prefs", + "../prefs:prefs_behavior", + "../prefs:prefs_types", + "//ui/webui/resources/cr_elements/cr_button:cr_button", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button", + "//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("nearby_share_device_name_dialog") { + deps = [ + "../prefs", + "../prefs:prefs_behavior", + "../prefs:prefs_types", + "//ui/webui/resources/cr_elements/cr_button:cr_button", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/cr_elements/cr_input:cr_input", + "//ui/webui/resources/js:i18n_behavior", + ] } js_library("nearby_share_subpage") { deps = [ + ":nearby_share_data_usage_dialog", + ":nearby_share_device_name_dialog", + ":types", + "..:router", "../prefs", "../prefs:prefs_behavior", "../prefs:prefs_types", + "//chrome/browser/resources/nearby_share/shared:nearby_share_settings", "//ui/webui/resources/js:cr", "//ui/webui/resources/js:i18n_behavior", ] } +js_library("types") { +} + group("polymer3_elements") { public_deps = [ + ":modulize", + ":nearby_share_data_usage_dialog_module", + ":nearby_share_device_name_dialog_module", + ":nearby_share_subpage_module", "../controls:polymer3_elements", "../prefs:polymer3_elements", - ":nearby_share_subpage_module", ] } js_type_check("closure_compile_module") { is_polymer3 = true - deps = [ ":nearby_share_subpage.m" ] + deps = [ + ":nearby_share_data_usage_dialog.m", + ":nearby_share_device_name_dialog.m", + ":nearby_share_subpage.m", + ] +} + +js_library("nearby_share_data_usage_dialog.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/nearby_share_page/nearby_share_data_usage_dialog.m.js" ] + deps = [ + ":types.m", + "../prefs:prefs.m", + "../prefs:prefs_behavior.m", + "../prefs:prefs_types.m", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m", + "//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group.m", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":nearby_share_data_usage_dialog_module" ] +} + +js_library("nearby_share_device_name_dialog.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/nearby_share_page/nearby_share_device_name_dialog.m.js" ] + deps = [ + "../prefs:prefs.m", + "../prefs:prefs_behavior.m", + "../prefs:prefs_types.m", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", + "//ui/webui/resources/cr_elements/cr_input:cr_input.m", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":nearby_share_device_name_dialog_module" ] } js_library("nearby_share_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/nearby_share_page/nearby_share_subpage.m.js" ] deps = [ + ":nearby_share_data_usage_dialog.m", + ":nearby_share_device_name_dialog.m", + ":types.m", + "..:router.m", "../prefs:prefs.m", "../prefs:prefs_behavior.m", "../prefs:prefs_types.m", + "//chrome/browser/resources/nearby_share/shared:nearby_share_settings.m", "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":nearby_share_subpage_module" ] } +js_library("types.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/nearby_share_page/types.m.js" ] + extra_deps = [ ":modulize" ] +} + +js_modulizer("modulize") { + input_files = [ "types.js" ] + namespace_rewrites = settings_namespace_rewrites +} + +polymer_modulizer("nearby_share_data_usage_dialog") { + js_file = "nearby_share_data_usage_dialog.js" + html_file = "nearby_share_data_usage_dialog.html" + html_type = "dom-module" + namespace_rewrites = settings_namespace_rewrites + auto_imports = settings_auto_imports +} + +polymer_modulizer("nearby_share_device_name_dialog") { + js_file = "nearby_share_device_name_dialog.js" + html_file = "nearby_share_device_name_dialog.html" + html_type = "dom-module" + namespace_rewrites = settings_namespace_rewrites + auto_imports = settings_auto_imports +} + polymer_modulizer("nearby_share_subpage") { js_file = "nearby_share_subpage.js" html_file = "nearby_share_subpage.html" html_type = "dom-module" namespace_rewrites = settings_namespace_rewrites - auto_imports = settings_auto_imports + auto_imports = + settings_auto_imports + + [ "chrome/browser/resources/settings/chromeos/os_route.html|routes" ] } diff --git a/chromium/chrome/browser/resources/settings/os_settings_resources.grd b/chromium/chrome/browser/resources/settings/os_settings_resources.grd index 4e4138f4717..1c5b05f19b6 100644 --- a/chromium/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chromium/chrome/browser/resources/settings/os_settings_resources.grd @@ -93,6 +93,30 @@ <structure name="IDR_OS_SETTINGS_AMBIENT_CONSTANTS_HTML" file="chromeos/ambient_mode_page/constants.html" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_TOPIC_SOURCE_ITEM_JS" + file="chromeos/ambient_mode_page/topic_source_item.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_TOPIC_SOURCE_ITEM_HTML" + file="chromeos/ambient_mode_page/topic_source_item.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_TOPIC_SOURCE_LIST_JS" + file="chromeos/ambient_mode_page/topic_source_list.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_TOPIC_SOURCE_LIST_HTML" + file="chromeos/ambient_mode_page/topic_source_list.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_ALBUM_ITEM_JS" + file="chromeos/ambient_mode_page/album_item.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_ALBUM_ITEM_HTML" + file="chromeos/ambient_mode_page/album_item.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_ALBUM_LIST_JS" + file="chromeos/ambient_mode_page/album_list.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_AMBIENT_ALBUM_LIST_HTML" + file="chromeos/ambient_mode_page/album_list.html" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_APPS_PAGE_JS" file="chromeos/os_apps_page/os_apps_page.js" compress="false" type="chrome_html" /> @@ -276,7 +300,13 @@ <structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_HTML" file="chromeos/os_a11y_page/manage_a11y_page.html" compress="false" type="chrome_html" /> - <structure name="IDS_OS_SETTINGS_SWITCH_ACCESS_SUBPAGE_JS" + <structure name="IDR_OS_SETTINGS_SWITCH_ACCESS_CONSTANTS_JS" + file="chromeos/os_a11y_page/switch_access_constants.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_SWITCH_ACCESS_CONSTANTS_HTML" + file="chromeos/os_a11y_page/switch_access_constants.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_SWITCH_ACCESS_SUBPAGE_JS" file="chromeos/os_a11y_page/switch_access_subpage.js" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_SWITCH_ACCESS_SUBPAGE_HTML" @@ -344,7 +374,7 @@ file="chromeos/os_settings_page/os_settings_page.html" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_ENSURE_LAZY_LOADED_HTML" - file="ensure_lazy_loaded.html" + file="chromeos/ensure_lazy_loaded.html" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_EXTENSION_CONTROL_BROWSER_PROXY_JS" file="extension_control_browser_proxy.js" @@ -365,6 +395,12 @@ <structure name="IDR_OS_SETTINGS_SEARCH_SETTINGS_JS" file="search_settings.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_SETTING_ID_PARAM_UTIL_HTML" + file="setting_id_param_util.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_SETTING_ID_PARAM_UTIL_JS" + file="setting_id_param_util.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_CR_OS_SETTINGS_MAIN_HTML" file="chromeos/os_settings_main/os_settings_main.html" compress="false" type="chrome_html" /> @@ -394,10 +430,10 @@ file="settings_page_css.html" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_MAIN_PAGE_BEHAVIOR_HTML" - file="settings_page/main_page_behavior.html" + file="chromeos/os_settings_page/main_page_behavior.html" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_MAIN_PAGE_BEHAVIOR_JS" - file="settings_page/main_page_behavior.js" + file="chromeos/os_settings_page/main_page_behavior.js" compress="false" type="chrome_html" preprocess="true" /> <structure name="IDR_OS_SETTINGS_SETTINGS_VARS_CSS_HTML" @@ -468,12 +504,6 @@ <structure name="IDR_OS_SETTINGS_CONTROLS_RADIO_GROUP_JS" file="controls/settings_radio_group.js" compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_CONTROLS_SETTINGS_IDLE_LOAD_HTML" - file="controls/settings_idle_load.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_CONTROLS_SETTINGS_IDLE_LOAD_JS" - file="controls/settings_idle_load.js" - compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_CONTROLS_SLIDER_HTML" file="controls/settings_slider.html" compress="false" type="chrome_html" /> @@ -492,6 +522,12 @@ <structure name="IDR_OS_SETTINGS_CONTROLS_TOGGLE_BUTTON_JS" file="controls/settings_toggle_button.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_DEEP_LINKING_BEHAVIOR_HTML" + file="chromeos/deep_linking_behavior.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_DEEP_LINKING_BEHAVIOR_JS" + file="chromeos/deep_linking_behavior.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_DEVICE_BROWSER_PROXY_HTML" file="chromeos/device_page/device_page_browser_proxy.html" compress="false" type="chrome_html" /> @@ -516,12 +552,6 @@ <structure name="IDR_OS_SETTINGS_DEVICE_DISPLAY_OVERSCAN_DIALOG_JS" file="chromeos/device_page/display_overscan_dialog.js" compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_DEVICE_DLC_SUBPAGE_HTML" - file="chromeos/device_page/dlc_subpage.html" - compress="false" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_DEVICE_DLC_SUBPAGE_JS" - file="chromeos/device_page/dlc_subpage.js" - compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_DEVICE_KEYBOARD_HTML" file="chromeos/device_page/keyboard.html" compress="false" type="chrome_html" /> @@ -615,6 +645,12 @@ file="chromeos/os_settings_icons_css.html" flattenhtml="true" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_OS_SETTINGS_PAGE_SETTINGS_IDLE_LOAD_HTML" + file="chromeos/os_settings_page/settings_idle_load.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_OS_SETTINGS_PAGE_SETTINGS_IDLE_LOAD_JS" + file="chromeos/os_settings_page/settings_idle_load.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_POWERWASH_DIALOG_HTML" file="chromeos/os_reset_page/os_powerwash_dialog.html" compress="false" type="chrome_html" /> @@ -653,12 +689,30 @@ <structure name="IDR_OS_SETTINGS_LANGUAGES_ADD_LANGUAGES_DIALOG_JS" file="chromeos/os_languages_page/os_add_languages_dialog.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_METRICS_PROXY_HTML" + file="chromeos/os_languages_page/languages_metrics_proxy.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_METRICS_PROXY_JS" + file="chromeos/os_languages_page/languages_metrics_proxy.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_HTML" file="chromeos/os_languages_page/os_languages_page.html" compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_JS" file="chromeos/os_languages_page/os_languages_page.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_HTML" + file="chromeos/os_languages_page/input_page.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_JS" + file="chromeos/os_languages_page/input_page.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_HTML" + file="chromeos/os_languages_page/os_languages_page_v2.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_JS" + file="chromeos/os_languages_page/os_languages_page_v2.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_LANGUAGES_SECTION_HTML" file="chromeos/os_languages_page/os_languages_section.html" compress="false" type="chrome_html" /> @@ -911,6 +965,12 @@ <structure name="IDR_OS_SETTINGS_OS_ROUTE_HTML" file="chromeos/os_route.html" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_OS__SETTINGS_ROUTES_HTML" + file="chromeos/os_settings_routes.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_OS__SETTINGS_ROUTES_JS" + file="chromeos/os_settings_routes.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_OS_ROUTE_JS" file="chromeos/os_route.js" compress="false" type="chrome_html" /> @@ -1238,6 +1298,24 @@ <structure name="IDR_OS_SETTINGS_MULTIDEVICE_TETHER_ITEM_JS" file="chromeos/multidevice_page/multidevice_tether_item.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_DIALOG_HTML" + file="nearby_share_page/nearby_share_device_name_dialog.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_DIALOG_JS" + file="nearby_share_page/nearby_share_device_name_dialog.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DIALOG_HTML" + file="nearby_share_page/nearby_share_data_usage_dialog.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DIALOG_JS" + file="nearby_share_page/nearby_share_data_usage_dialog.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_TYPES_HTML" + file="nearby_share_page/types.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_TYPES_JS" + file="nearby_share_page/types.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_NEARBY_SHARE_SUBPAGE_HTML" file="nearby_share_page/nearby_share_subpage.html" compress="false" type="chrome_html" /> @@ -1268,6 +1346,12 @@ <structure name="IDR_OS_SETTINGS_TETHER_CONNECTION_DIALOG_JS" file="chromeos/internet_page/tether_connection_dialog.js" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CELLULAR_SETUP_DIALOG_HTML" + file="chromeos/internet_page/cellular_setup_dialog.html" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CELLULAR_SETUP_DIALOG_JS" + file="chromeos/internet_page/cellular_setup_dialog.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_PARENTAL_CONTROLS_BROWSER_PROXY_HTML" file="chromeos/parental_controls_page/parental_controls_browser_proxy.html" compress="false" type="chrome_html" /> @@ -1345,6 +1429,12 @@ file="chromeos/os_people_page/lock_state_behavior.html" compress="false" type="chrome_html" preprocess="true" /> + <structure name="IDR_OS_SETTINGS_PEOPLE_PIN_AUTOSUBMIT_DIALOG_JS" + file="chromeos/os_people_page/pin_autosubmit_dialog.js" + compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_PEOPLE_PIN_AUTOSUBMIT_DIALOG_HTML" + file="chromeos/os_people_page/pin_autosubmit_dialog.html" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_PEOPLE_SETUP_PIN_DIALOG_JS" file="chromeos/os_people_page/setup_pin_dialog.js" compress="false" type="chrome_html" /> diff --git a/chromium/chrome/browser/resources/settings/os_settings_resources_vulcanized.grd b/chromium/chrome/browser/resources/settings/os_settings_resources_vulcanized.grd index a6e99635d9f..07f8b8d5b7f 100644 --- a/chromium/chrome/browser/resources/settings/os_settings_resources_vulcanized.grd +++ b/chromium/chrome/browser/resources/settings/os_settings_resources_vulcanized.grd @@ -82,7 +82,7 @@ type="BINDATA" /> <!-- Polymer3 related files--> - <include name="IDR_OS_SETTINGS_SETTINGS_ROLLUP_JS" + <include name="IDR_OS_SETTINGS_OS_SETTINGS_ROLLUP_JS" file="${root_gen_dir}\chrome\browser\resources\settings\chromeos\os_settings.rollup.js" use_base_dir="false" preprocess="true" @@ -90,6 +90,16 @@ <include name="IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML" file="chromeos/os_settings_v3.html" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LAZY_LOAD_ROLLUP_JS" + file="${root_gen_dir}\chrome\browser\resources\settings\chromeos\lazy_load.rollup.js" + preprocess="true" + type="BINDATA" + use_base_dir="false" /> + <include name="IDR_OS_SETTINGS_SHARED_ROLLUP_JS" + file="${root_gen_dir}\chrome\browser\resources\settings\chromeos\shared.rollup.js" + preprocess="true" + type="BINDATA" + use_base_dir="false" /> </includes> </release> </grit> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn b/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn index c8b89afc3b5..c73a7c4c545 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn @@ -49,7 +49,6 @@ js_type_check("closure_compile_module") { ":personalization_options.m", ":privacy_page", ":privacy_page_browser_proxy.m", - ":safe_browsing_browser_proxy", ":secure_dns", ":secure_dns_input", ":security_keys_bio_enroll_dialog", @@ -177,13 +176,6 @@ js_library("privacy_page_browser_proxy.m") { extra_deps = [ ":modulize" ] } -js_library("safe_browsing_browser_proxy") { - deps = [ - "../site_settings:site_settings_prefs_browser_proxy", - "//ui/webui/resources/js:cr.m", - ] -} - js_library("security_keys_bio_enroll_dialog") { deps = [ ":security_keys_browser_proxy", @@ -249,7 +241,6 @@ js_library("security_page") { deps = [ ":disable_safebrowsing_dialog", ":privacy_page_browser_proxy.m", - ":safe_browsing_browser_proxy", "..:i18n_setup", "..:metrics_browser_proxy", "..:route", diff --git a/chromium/chrome/browser/resources/settings/safety_check_page/BUILD.gn b/chromium/chrome/browser/resources/settings/safety_check_page/BUILD.gn index bf337dd7635..9e29620f968 100644 --- a/chromium/chrome/browser/resources/settings/safety_check_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/safety_check_page/BUILD.gn @@ -12,13 +12,16 @@ js_type_check("closure_compile_module") { deps = [ ":safety_check_browser_proxy", ":safety_check_child", - ":safety_check_chrome_cleaner_child", ":safety_check_extensions_child", ":safety_check_page", ":safety_check_passwords_child", ":safety_check_safe_browsing_child", ":safety_check_updates_child", ] + + if (is_win) { + deps += [ ":safety_check_chrome_cleaner_child" ] + } } js_library("safety_check_browser_proxy") { @@ -39,8 +42,10 @@ js_library("safety_check_chrome_cleaner_child") { "..:metrics_browser_proxy", "..:route", "..:router.m", + "../chrome_cleanup_page:chrome_cleanup_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] } @@ -59,6 +64,9 @@ js_library("safety_check_extensions_child") { js_library("safety_check_page") { deps = [ ":safety_check_browser_proxy", + + # This element is included on all platforms to ensure it's type checked (the element itself + # only exists in Windows). ":safety_check_chrome_cleaner_child", ":safety_check_extensions_child", ":safety_check_passwords_child", @@ -116,11 +124,14 @@ js_library("safety_check_updates_child") { html_to_js("web_components") { js_files = [ "safety_check_child.js", - "safety_check_chrome_cleaner_child.js", "safety_check_extensions_child.js", "safety_check_page.js", "safety_check_passwords_child.js", "safety_check_safe_browsing_child.js", "safety_check_updates_child.js", ] + + if (is_win) { + js_files += [ "safety_check_chrome_cleaner_child.js" ] + } } diff --git a/chromium/chrome/browser/resources/settings/settings.gni b/chromium/chrome/browser/resources/settings/settings.gni index 0c82dda4fd4..daf863bcc5c 100644 --- a/chromium/chrome/browser/resources/settings/settings.gni +++ b/chromium/chrome/browser/resources/settings/settings.gni @@ -116,6 +116,7 @@ settings_namespace_rewrites = [ "settings.SystemPageBrowserProxy|SystemPageBrowserProxy", "settings.RouteObserverBehavior|RouteObserverBehavior", "settings.WebsiteUsageBrowserProxy|WebsiteUsageBrowserProxy", + "nearby_share.NearbyShareSettingsBehavior|NearbyShareSettingsBehavior", "action_link.m.js|action_link.js", @@ -133,9 +134,11 @@ settings_auto_imports = [ "chrome/browser/resources/settings/extension_control_browser_proxy.html|ExtensionControlBrowserProxyImpl,ExtensionControlBrowserProxy", "chrome/browser/resources/settings/global_scroll_target_behavior.html|GlobalScrollTargetBehavior", "chrome/browser/resources/settings/i18n_setup.html|loadTimeData", + "chrome/browser/resources/settings/nearby_share_page/types.html|NearbyShareDataUsage,dataUsageStringToEnum", "chrome/browser/resources/settings/prefs/prefs_behavior.html|PrefsBehavior", "chrome/browser/resources/settings/prefs/prefs_types.html|CrSettingsPrefs", "chrome/browser/resources/settings/printing_page/printing_browser_proxy.html|PrintingBrowserProxyImpl", + "chrome/browser/resources/settings/router.html|Router,Route,RouteObserverBehavior", ] settings_closure_flags = diff --git a/chromium/chrome/browser/resources/settings/settings_main/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_main/BUILD.gn index acd8b51d278..6b441420f80 100644 --- a/chromium/chrome/browser/resources/settings/settings_main/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_main/BUILD.gn @@ -21,7 +21,6 @@ js_library("settings_main") { "../about_page:about_page", "../about_page:about_page_browser_proxy.m", "../basic_page:basic_page", - "../settings_page:main_page_behavior.m", "//third_party/polymer/v3_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer", "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:load_time_data.m", diff --git a/chromium/chrome/browser/resources/settings/settings_menu/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_menu/BUILD.gn index c19f01c1bba..eda91b4f18e 100644 --- a/chromium/chrome/browser/resources/settings/settings_menu/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_menu/BUILD.gn @@ -18,7 +18,6 @@ js_library("settings_menu") { "..:router.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:load_time_data.m", ] } diff --git a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn index c7432bfa778..413ff291627 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn @@ -4,33 +4,23 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/polymer.gni") -import("//ui/webui/resources/tools/js_modulizer.gni") import("../settings.gni") js_type_check("closure_compile") { deps = [ - ":main_page_behavior", ":settings_animated_pages", ":settings_section", ":settings_subpage", ] } -js_library("main_page_behavior") { - deps = [ - ":settings_section", - "..:router", - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:util", - ] - externs_list = [ "$externs_path/pending.js" ] -} - js_library("settings_animated_pages") { deps = [ ":settings_subpage", "..:router", + "..:setting_id_param_util", "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js/cr/ui:focus_without_ink", ] externs_list = [ "$externs_path/pending_polymer.js" ] @@ -42,6 +32,7 @@ js_library("settings_section") { js_library("settings_subpage") { deps = [ "..:router", + "..:setting_id_param_util", "//third_party/polymer/v1_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior-extracted", "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", "//ui/webui/resources/js:assert", @@ -55,16 +46,16 @@ js_library("settings_subpage") { js_type_check("closure_compile_module") { is_polymer3 = true + closure_flags = settings_closure_flags deps = [ - ":main_page_behavior.m", + ":main_page_behavior", ":settings_animated_pages.m", ":settings_section.m", ":settings_subpage.m", ] } -js_library("main_page_behavior.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/settings_page/main_page_behavior.m.js" ] +js_library("main_page_behavior") { deps = [ ":settings_section.m", "..:router.m", @@ -72,7 +63,6 @@ js_library("main_page_behavior.m") { "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:util.m", ] - extra_deps = [ ":modulize" ] } js_library("settings_animated_pages.m") { @@ -80,8 +70,10 @@ js_library("settings_animated_pages.m") { deps = [ ":settings_subpage.m", "..:router.m", + "..:setting_id_param_util.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] extra_deps = [ ":settings_animated_pages_module" ] @@ -99,6 +91,7 @@ js_library("settings_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/settings_page/settings_subpage.m.js" ] deps = [ "..:router.m", + "..:setting_id_param_util.m", "//third_party/polymer/v3_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field.m", @@ -116,7 +109,6 @@ import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ - ":modulize", ":settings_animated_pages_module", ":settings_section_module", ":settings_subpage_module", @@ -129,6 +121,7 @@ polymer_modulizer("settings_animated_pages") { html_type = "dom-module" auto_imports = [ "chrome/browser/resources/settings/router.html|Route, Router, RouteObserverBehavior", + "chrome/browser/resources/settings/setting_id_param_util.html|getSettingIdParameter", "ui/webui/resources/html/assert.html|assert", "ui/webui/resources/html/polymer.html|afterNextRender, dom, DomIf, html, Polymer", ] @@ -151,6 +144,7 @@ polymer_modulizer("settings_subpage") { migrated_imports = settings_migrated_imports auto_imports = settings_auto_imports + [ "chrome/browser/resources/settings/router.html|RouteObserverBehavior,Router", + "chrome/browser/resources/settings/setting_id_param_util.html|getSettingIdParameter", "third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior.html|IronResizableBehavior", "ui/webui/resources/html/assert.html|assert", "ui/webui/resources/html/polymer.html|html, Polymer, afterNextRender", @@ -159,10 +153,3 @@ polymer_modulizer("settings_subpage") { namespace_rewrites = settings_namespace_rewrites + [ "Polymer.IronResizableBehavior|IronResizableBehavior" ] } - -import("//ui/webui/resources/tools/js_modulizer.gni") - -js_modulizer("modulize") { - input_files = [ "main_page_behavior.js" ] - namespace_rewrites = settings_namespace_rewrites -} diff --git a/chromium/chrome/browser/resources/settings/settings_resources_v3.grdp b/chromium/chrome/browser/resources/settings/settings_resources_v3.grdp index 72c22ccadf5..222968300ca 100644 --- a/chromium/chrome/browser/resources/settings/settings_resources_v3.grdp +++ b/chromium/chrome/browser/resources/settings/settings_resources_v3.grdp @@ -52,6 +52,11 @@ file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/autofill_page.js" use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_SETTINGS_AUTOFILL_PAGE_AVATAR_ICON_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/avatar_icon.js" + use_base_dir="false" + compress="false" type="BINDATA" + preprocess="true" /> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PAYMENTS_LIST_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/payments_list.js" use_base_dir="false" @@ -127,7 +132,8 @@ <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_LIST_ITEM_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_list_item.js" use_base_dir="false" - compress="false" type="BINDATA" /> + compress="false" type="BINDATA" + preprocess="true"/> <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_LIST_HANDLER_JS" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js" use_base_dir="false" @@ -213,6 +219,10 @@ file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/installed_app_checkbox.js" use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_SETTINGS_CLEAR_BROWSING_DATA_DIALOG_PASSWORDS_DELETION_DIALOG_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/clear_browsing_data_dialog/passwords_deletion_dialog.js" + use_base_dir="false" + compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_CONTROLLED_BUTTON_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/controlled_button.m.js" use_base_dir="false" @@ -241,9 +251,8 @@ file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_dropdown_menu.m.js" use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_SETTINGS_CONTROLS_SETTINGS_IDLE_LOAD_M_JS" - file="${root_gen_dir}/chrome/browser/resources/settings/controls/settings_idle_load.m.js" - use_base_dir="false" + <include name="IDR_SETTINGS_CONTROLS_SETTINGS_IDLE_LOAD_JS" + file="controls/settings_idle_load.js" compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_CONTROLS_PREF_CONTROL_BEHAVIOR_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/controls/pref_control_behavior.m.js" @@ -333,6 +342,11 @@ file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/add_languages_dialog.js" use_base_dir="false" compress="false" type="BINDATA" /> + <if expr="chromeos"> + <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_METRICS_PROXY_JS" + file="languages_page/languages_metrics_proxy.js" + compress="false" type="BINDATA" /> + </if> <include name="IDR_SETTINGS_LANGUAGES_PAGE_LANGUAGES_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/settings/languages_page/languages_page.js" use_base_dir="false" @@ -506,9 +520,6 @@ use_base_dir="false" preprocess="true" compress="false" type="BINDATA" /> - <include name="IDR_SETTINGS_PRIVACY_PAGE_SAFE_BROWSING_BROWSER_PROXY_JS" - file="privacy_page/safe_browsing_browser_proxy.js" - compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_PRIVACY_PAGE_SECURE_DNS_JS" file="${root_gen_dir}/chrome/browser/resources/settings/privacy_page/secure_dns.js" use_base_dir="false" @@ -585,15 +596,18 @@ file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_child.js" use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_CHROME_CLEANER_CHILD_JS" - file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js" - use_base_dir="false" - compress="false" type="BINDATA" /> + <if expr="is_win"> + <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_CHROME_CLEANER_CHILD_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js" + use_base_dir="false" + compress="false" type="BINDATA" /> + </if> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_EXTENSIONS_CHILD_JS" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js" use_base_dir="false" compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_PAGE_JS" + preprocess="true" file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_page.js" use_base_dir="false" compress="false" type="BINDATA" /> @@ -650,9 +664,8 @@ file="${root_gen_dir}/chrome/browser/resources/settings/settings_main/settings_main.js" use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_SETTINGS_SETTINGS_PAGE_MAIN_PAGE_BEHAVIOR_M_JS" - file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/main_page_behavior.m.js" - use_base_dir="false" + <include name="IDR_SETTINGS_SETTINGS_PAGE_MAIN_PAGE_BEHAVIOR_JS" + file="settings_page/main_page_behavior.js" compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_PAGE_SETTINGS_ANIMATED_PAGES_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/settings_animated_pages.m.js" @@ -672,6 +685,10 @@ use_base_dir="false" compress="false" type="BINDATA" preprocess="true" /> + <include name="IDR_SETTINGS_SETTING_ID_PARAM_UTIL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/setting_id_param_util.m.js" + use_base_dir="false" + compress="false" type="BINDATA" /> <include name="IDR_SETTINGS_SETTINGS_ROUTES_JS" file="settings_routes.js" compress="false" type="BINDATA" /> diff --git a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn index 5cc7141efdd..a4f02adff5c 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn @@ -21,6 +21,7 @@ js_library("settings_ui") { "../basic_page:basic_page", "../prefs:prefs.m", "../settings_main:settings_main", + "../settings_menu:settings_menu", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements:cr_container_shadow_behavior.m", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer.m", diff --git a/chromium/chrome/browser/resources/signin/BUILD.gn b/chromium/chrome/browser/resources/signin/BUILD.gn index f3e1f7e8491..000f2845095 100644 --- a/chromium/chrome/browser/resources/signin/BUILD.gn +++ b/chromium/chrome/browser/resources/signin/BUILD.gn @@ -8,6 +8,7 @@ group("closure_compile") { deps = [ "sync_confirmation:closure_compile" ] if (!is_chromeos) { deps += [ + "dice_web_signin_intercept:closure_compile", "profile_picker:closure_compile", "signin_email_confirmation:closure_compile", "signin_error:closure_compile", @@ -23,6 +24,7 @@ group("web_components") { ] if (!is_chromeos) { public_deps += [ + "dice_web_signin_intercept:web_components", "signin_email_confirmation:web_components", "signin_error:web_components", "signin_reauth:web_components", @@ -31,5 +33,8 @@ group("web_components") { } html_to_js("web_components_local") { - js_files = [ "signin_shared_css.js" ] + js_files = [ + "signin_shared_css.js", + "signin_vars_css.js", + ] } diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/BUILD.gn b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/BUILD.gn new file mode 100644 index 00000000000..46ceef9fe40 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ + ":dice_web_signin_intercept_app", + ":dice_web_signin_intercept_browser_proxy", + ] +} + +js_library("dice_web_signin_intercept_app") { + deps = [ + ":dice_web_signin_intercept_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/iron-icon", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] +} + +js_library("dice_web_signin_intercept_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/chrome_send.js" ] +} + +html_to_js("web_components") { + js_files = [ "dice_web_signin_intercept_app.js" ] +} diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/OWNERS b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/OWNERS new file mode 100644 index 00000000000..b2464ab5550 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/OWNERS @@ -0,0 +1,2 @@ +file://components/signin/OWNERS +# COMPONENT: Services>SignIn diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html new file mode 100644 index 00000000000..d2dfd14faa1 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html @@ -0,0 +1,24 @@ +<!doctype html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> + <head> + <meta charset="utf-8"> + <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> + <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> + <style> + body { + height: 100vh; + margin: 0; + width: 100vw; + } + @media (prefers-color-scheme: dark) { + body { + background-color: var(--md-background-color); + } + } + </style> + </head> + <body> + <dice-web-signin-intercept-app></dice-web-signin-intercept-app> + <script type="module" src="dice_web_signin_intercept_app.js"></script> + </body> +</html> diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html new file mode 100644 index 00000000000..e09c30c7d18 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html @@ -0,0 +1,124 @@ +<style include="signin-dialog-shared"> + :host { + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + background-color: var(--header-background-color); + border-radius: 4px; + color: var(--header-text-color); + margin: 8px 8px 16px; + min-height: 128px; + position: relative; + } + + #headerText { + font-size: 15px; + font-weight: bold; + line-height: 18px; + margin: 16px auto 9px; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + } + + #avatar-container { + --avatar-image-width: 60px; + --avatar-border: 2px; + --avatar-size: calc(var(--avatar-image-width) + 2 * var(--avatar-border)); + height: var(--avatar-size); + left: calc(50% - var(--avatar-size)/2); + position: absolute; + width: var(--avatar-size); + } + + #avatar { + /** The user avatar may be transparent, add a background */ + background-color: var(--md-background-color); + border: var(--avatar-border) solid var(--md-background-color); + border-radius: 50%; + height: var(--avatar-image-width); + top: 43px; + width: var(--avatar-image-width); + } + + .work-badge { + --badge-width: 20px; + --badge-offset: -4px; + background-color: var(--signin-work-badge-background-color); + border: 2px solid var(--header-background-color); + border-radius: 50%; + bottom: var(--badge-offset); + height: var(--badge-width); + position: absolute; + right: var(--badge-offset); + width: var(--badge-width); + } + + .work-badge > iron-icon { + --work-icon-size: 15px; + bottom: 0; + color: var(--signin-work-badge-foreground-color); + height: var(--work-icon-size); + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; + width: var(--work-icon-size); + } + + #body { + color: var(--cr-secondary-text-color); + flex-grow: 1; + font-size: 13px; + line-height: 20px; + margin: 0 16px; + } + + #title { + color: var(--cr-primary-text-color); + font-size: 15px; + font-weight: 500; + line-height: 22px; + margin: 0 0 8px; + } + + .action-container { + padding: 0 16px 16px; + } + + cr-button { + font-size: 12px; + } +</style> + +<div id="header"> + <div id="headerText">[[interceptionParameters_.headerText]]</div> + <div id="avatar-container"> + <img id="avatar" + src="[[interceptionParameters_.interceptedAccount.pictureUrl]]"> + <div class="work-badge" id="badge" + hidden="[[!interceptionParameters_.interceptedAccount.isManaged]]"> + <iron-icon class="icon" icon="signin:business"></iron-icon> + </div> + </div> +</div> + +<div id="body"> + <div id="title">[[interceptionParameters_.bodyTitle]]</div> + <div id="contents">[[interceptionParameters_.bodyText]]</div> +</div> + +<div class="action-container"> + <cr-button id="acceptButton" class="action-button" on-click="onAccept_" + autofocus> + $i18n{diceWebSigninInterceptAcceptLabel} + </cr-button> + <cr-button id="cancelButton" on-click="onCancel_"> + $i18n{diceWebSigninInterceptCancelLabel} + </cr-button> +</div> diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js new file mode 100644 index 00000000000..295393a9028 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js @@ -0,0 +1,75 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import './signin_icons.js'; +import './signin_shared_css.js'; +import './signin_vars_css.js'; +import './strings.m.js'; + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {AccountInfo, DiceWebSigninInterceptBrowserProxy, DiceWebSigninInterceptBrowserProxyImpl, InterceptionParameters} from './dice_web_signin_intercept_browser_proxy.js'; + +Polymer({ + is: 'dice-web-signin-intercept-app', + + _template: html`{__html_template__}`, + + behaviors: [ + WebUIListenerBehavior, + ], + + properties: { + /** @private {InterceptionParameters} */ + InterceptionParameters_: Object, + }, + + /** @private {?DiceWebSigninInterceptBrowserProxy} */ + diceWebSigninInterceptBrowserProxy_: null, + + /** @override */ + attached() { + this.setColors_(); + this.diceWebSigninInterceptBrowserProxy_ = + DiceWebSigninInterceptBrowserProxyImpl.getInstance(); + this.addWebUIListener( + 'interception-parameters-changed', + this.handleParametersChanged_.bind(this)); + this.diceWebSigninInterceptBrowserProxy_.pageLoaded().then( + parameters => this.handleParametersChanged_(parameters)); + }, + + /** @private */ + onAccept_() { + this.diceWebSigninInterceptBrowserProxy_.accept(); + }, + + /** @private */ + onCancel_() { + this.diceWebSigninInterceptBrowserProxy_.cancel(); + }, + + /** @private */ + setColors_() { + this.style.setProperty( + '--header-background-color', + loadTimeData.getString('headerBackgroundColor')); + this.style.setProperty( + '--header-text-color', loadTimeData.getString('headerTextColor')); + }, + + /** + * Called when the interception parameters are updated. + * @param {!InterceptionParameters} parameters + * @private + */ + handleParametersChanged_(parameters) { + this.interceptionParameters_ = parameters; + this.notifyPath('interceptionParameters_.interceptedAccount.isManaged'); + }, +}); diff --git a/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_browser_proxy.js b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_browser_proxy.js new file mode 100644 index 00000000000..887727f327c --- /dev/null +++ b/chromium/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_browser_proxy.js @@ -0,0 +1,63 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A helper object used by the dice web signin intercept bubble to + * interact with the browser. + */ +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; + +/** + * Account information sent from C++. + * @typedef {{ + * isManaged: boolean, + * pictureUrl: string, + * }} + */ +export let AccountInfo; + +/** + * @typedef {{ + * headerText: string, + * bodyTitle: string, + * bodyText: string, + * interceptedAccount: AccountInfo, + * }} + */ +export let InterceptionParameters; + +/** @interface */ +export class DiceWebSigninInterceptBrowserProxy { + /** Called when the user accepts the interception bubble. */ + accept() {} + + /** Called when the user cancels the interception. */ + cancel() {} + + /** + * Called when the page is loaded. + * @return {!Promise<!InterceptionParameters>} + * */ + pageLoaded() {} +} + +/** @implements {DiceWebSigninInterceptBrowserProxy} */ +export class DiceWebSigninInterceptBrowserProxyImpl { + /** @override */ + accept() { + chrome.send('accept'); + } + + /** @override */ + cancel() { + chrome.send('cancel'); + } + + /** @override */ + pageLoaded() { + return sendWithPromise('pageLoaded'); + } +} + +addSingletonGetter(DiceWebSigninInterceptBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/BUILD.gn b/chromium/chrome/browser/resources/signin/profile_picker/BUILD.gn index e27205ad0b0..833539bc13a 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/BUILD.gn +++ b/chromium/chrome/browser/resources/signin/profile_picker/BUILD.gn @@ -5,8 +5,20 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/html_to_js.gni") -js_type_check("closure_compile") { +group("closure_compile") { + deps = [ + ":profile_picker_files", + "profile_creation_flow:closure_compile", + ] +} + +js_type_check("profile_picker_files") { is_polymer3 = true + closure_flags = + default_closure_args + [ + "js_module_root=../../chrome/browser/resources/signin/profile_picker/", + "js_module_root=./gen/chrome/browser/resources/signin/profile_picker/", + ] deps = [ ":profile_picker_app", ":profile_picker_main_view", @@ -15,22 +27,84 @@ js_type_check("closure_compile") { js_library("profile_picker_main_view") { deps = [ + ":manage_profiles_browser_proxy", + ":navigation_behavior", + ":profile_card", "//third_party/polymer/v3_0/components-chromium/iron-icon", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] + externs_list = [ "$externs_path/metrics_private.js" ] +} + +js_library("navigation_behavior") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + ] + externs_list = [ "$externs_path/metrics_private.js" ] } js_library("profile_picker_app") { deps = [ + ":navigation_behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m", ] } -html_to_js("web_components") { +js_library("profile_card") { + deps = [ + ":manage_profiles_browser_proxy", + ":profile_card_menu", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + ] +} + +js_library("profile_card_menu") { + deps = [ + ":manage_profiles_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] + externs_list = [ "$externs_path/metrics_private.js" ] +} + +js_library("manage_profiles_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/chrome_send.js" ] +} + +js_library("policy_helper") { + deps = [ + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + +group("web_components") { + public_deps = [ + ":web_components_local", + "profile_creation_flow:web_components", + ] +} + +html_to_js("web_components_local") { js_files = [ "profile_picker_app.js", "profile_picker_main_view.js", + "profile_card.js", + "profile_card_menu.js", + "profile_picker_shared_css.js", ] } diff --git a/chromium/chrome/browser/resources/signin/profile_picker/icons.js b/chromium/chrome/browser/resources/signin/profile_picker/icons.js index 81d509c0c86..36372277cc9 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/icons.js +++ b/chromium/chrome/browser/resources/signin/profile_picker/icons.js @@ -1,8 +1,11 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; const element = document.createElement('iron-iconset-svg'); element.name = 'profiles'; -element.size = 74; element.innerHTML = ` <svg> <defs> @@ -10,6 +13,14 @@ element.innerHTML = ` <circle cx="37" cy="37" r="37" stroke="none"/> <path d="M36.9999 46.4349C36.1315 46.4349 35.4274 45.7309 35.4274 44.8624V38.5724H29.1374C28.269 38.5724 27.5649 37.8684 27.5649 36.9999C27.5649 36.1315 28.269 35.4274 29.1374 35.4274H35.4274V29.1374C35.4274 28.269 36.1315 27.5649 36.9999 27.5649C37.8684 27.5649 38.5724 28.269 38.5724 29.1374V35.4274H44.8624C45.7309 35.4274 46.4349 36.1315 46.4349 36.9999C46.4349 37.8684 45.7309 38.5724 44.8624 38.5724H38.5724V44.8624C38.5724 45.7309 37.8684 46.4349 36.9999 46.4349Z" fill="var(--iron-icon-stroke-color)"/> </g> + + <g id="account-circle" viewBox="0 0 24 24" fill="var(--footer-text-color)" width="18px" height="18px"> + <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/> + </g> + + <g id="customize-banner" viewBox="0 0 678 266" width="678" height="266" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M70.51 115.677c-2.425 3.218-7.276 3.053-9.621-.248-6.711-9.738-6.63-23.107.97-32.928 7.762-9.903 20.538-12.957 31.453-8.5 3.639 1.65 4.852 6.272 2.426 9.408l-25.227 32.268zM531.612 112.52c1.744-1.18 4.236-.252 4.818 1.77 1.744 6.069-.582 12.811-6.064 16.351-5.566 3.624-12.544 2.95-17.279-1.18-1.578-1.433-1.412-3.961.332-5.141l18.193-11.8zM140 128.499c0 2.519-1.98 4.498-4.5 4.498-2.52.09-4.5-1.979-4.5-4.498 0-2.52 1.98-4.499 4.5-4.499 2.43 0 4.5 1.979 4.5 4.499z" fill="var(--theme-shape-color)"/><path d="M160.541 53.57c.993-4.303 5.297-7.035 9.601-6.042l18.294 4.222c4.304.993 7.035 5.297 6.042 9.602-.993 4.304-5.297 7.036-9.602 6.042L166.5 63.173c-4.304-.91-6.953-5.298-5.959-9.602z" stroke="var(--theme-shape-color)" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M526 69c6.075 0 11-4.925 11-11s-4.925-11-11-11-11 4.925-11 11 4.925 11 11 11zM608.042 81.007L630.448 83c.944.08 1.631.876 1.545 1.753l-2.146 20.805c-.086.877-.945 1.515-1.889 1.435L605.552 105c-.944-.079-1.631-.876-1.545-1.753l2.146-20.805c.086-.877.945-1.515 1.889-1.435z" stroke="var(--theme-shape-color)" stroke-width="2"/> + </g> </defs> </svg>`; document.head.appendChild(element); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_left_banner_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_left_banner_image.svg new file mode 100644 index 00000000000..80d8d316373 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_left_banner_image.svg @@ -0,0 +1 @@ +<svg width="169" height="400" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M75.7 64.2l-16.3-5.1c-1.7-.5-3.4.4-4 2.1l-5.1 16.3c-.5 1.7.4 3.4 2.1 4l16.3 5.1c1.7.5 3.4-.4 4-2.1l5.1-16.3c.5-1.7-.5-3.4-2.1-4z" fill="#8AB4F8"/><path d="M103.8 242.1a6.9 6.9 0 100-13.8 6.9 6.9 0 000 13.8z" fill="#FDD663"/><path d="M81.3 277.3l-13 11.1c-.7.6-1 1.5-.9 2.4l3.1 16.7c.2.9.8 1.6 1.7 1.9l16.1 5.7c.9.3 1.8.1 2.5-.5l13-11.1c.7-.6 1-1.5.9-2.4l-3.1-16.7c-.2-.9-.8-1.6-1.7-1.9l-16.1-5.7c-.9-.3-1.8-.1-2.5.5zM38.9 351.3c1.6 2.1 1.2 5.2-1 6.8-2.2 1.6-5.2 1.2-6.8-1-1.6-2.1-1.2-5.2 1-6.8 2.2-1.5 5.2-1.1 6.8 1zm-10.4-5.7c-4.8 3.6-5.7 10.3-2.2 15.1 3.6 4.8 10.3 5.7 15.1 2.2 4.8-3.5 5.7-10.3 2.2-15.1-3.5-4.8-10.3-5.8-15.1-2.2z" fill="#616161"/><path d="M66.4 164l-32.2 18.6c-1.2.7-1.6 2.3-.9 3.5l7.7 13.4c.7 1.2 2.3 1.6 3.5.9l32.2-18.6c1.2-.7 1.6-2.3.9-3.5l-7.7-13.4c-.7-1.2-2.3-1.7-3.5-.9z" stroke="#81C995" stroke-width="2" stroke-miterlimit="10"/><path d="M162.1 81.9c2.8-4.9 1-11.2-3.9-14-4.9-2.8-11.2-1-14 3.9l-13.3 23.5c-2.8 4.9-1 11.2 3.9 14 4.9 2.8 11.2 1 14-3.9l13.3-23.5z" fill="#616161"/></svg> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_right_banner_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_right_banner_image.svg new file mode 100644 index 00000000000..15e35f4b07f --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/images/dark_mode_right_banner_image.svg @@ -0,0 +1 @@ +<svg width="169" height="400" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M48.5 182c-2.7 0-5.4-1-7.5-3l-19.8-18.4c-2.2-2-3.4-4.8-3.5-7.7-.1-3 .9-5.8 3-8 4.2-4.5 11.2-4.7 15.7-.6l19.8 18.4c2.2 2 3.4 4.8 3.5 7.7.1 3-.9 5.8-3 8-2.3 2.4-5.2 3.6-8.2 3.6zm-19.8-38.9c-2.5 0-5.1 1-6.9 3-1.7 1.9-2.6 4.3-2.5 6.8.1 2.5 1.2 4.9 3 6.6l19.8 18.4c3.8 3.6 9.8 3.3 13.4-.5 1.7-1.9 2.6-4.3 2.5-6.8-.1-2.5-1.2-4.9-3-6.6l-19.8-18.4c-1.8-1.7-4.1-2.5-6.5-2.5z" fill="#616161"/><path d="M75.7 257.4c5.689 0 10.3-4.612 10.3-10.3 0-5.689-4.611-10.3-10.3-10.3-5.688 0-10.3 4.611-10.3 10.3 0 5.688 4.612 10.3 10.3 10.3z" fill="#8AB4F8"/><path d="M117.201 184l-8.7 7.2c-.7.6-1 1.5-.9 2.4l1.9 11.1c.2.9.8 1.7 1.6 2l10.6 3.9c.9.3 1.8.2 2.5-.4l8.7-7.2c.7-.6 1-1.5.9-2.4l-1.9-11.1c-.2-.9-.8-1.7-1.6-2l-10.6-3.9c-.8-.3-1.8-.1-2.5.4z" fill="#FDD663"/><path d="M111.599 376.2a6.9 6.9 0 100-13.8 6.9 6.9 0 000 13.8zM141.1 282.6l-33.9 9.1c-1.9.5-2.5 2.9-1.1 4.3l24.8 24.8c1.4 1.4 3.8.8 4.3-1.1l9.1-33.9c.5-2-1.3-3.7-3.2-3.2z" fill="#616161"/><path d="M91.8 65.1c-3.4 1.8-5.5 4.8-6.2 8.2-.5 2.3-1.8 4.3-3.7 5.6l-.9.6c-1.9 1.3-4.3 1.6-6.6 1.2-3.4-.7-7 .1-10 2.5-4.4 3.5-5.8 9.9-3.2 14.9 3.3 6.601 11.5 8.601 17.5 4.701 2.8-1.8 4.6-4.6 5.2-7.6.5-2.2 1.8-4.2 3.7-5.5l.9-.6c1.9-1.3 4.2-1.7 6.5-1.2 3 .6 6.301.1 9.101-1.7 6-3.9 7.4-12.3 2.7-17.9-3.7-4.6-10-5.8-15-3.2z" stroke="#81C995" stroke-width="2" stroke-miterlimit="10"/></svg> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/images/left_banner_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/images/left_banner_image.svg new file mode 100644 index 00000000000..cda74ff4f60 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/images/left_banner_image.svg @@ -0,0 +1 @@ +<svg width="169" height="400" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M75.7 64.2l-16.3-5.1c-1.7-.5-3.4.4-4 2.1l-5.1 16.3c-.5 1.7.4 3.4 2.1 4l16.3 5.1c1.7.5 3.4-.4 4-2.1l5.1-16.3c.5-1.7-.5-3.4-2.1-4z" fill="#4285F4"/><path d="M103.8 242.101a6.9 6.9 0 100-13.8 6.9 6.9 0 000 13.8z" fill="#FBBC05"/><path d="M81.3 277.3l-13 11.1c-.7.6-1 1.5-.9 2.4l3.1 16.7c.2.9.8 1.6 1.7 1.9l16.1 5.7c.9.3 1.8.1 2.5-.5l13-11.1c.7-.6 1-1.5.9-2.4l-3.1-16.7c-.2-.9-.8-1.6-1.7-1.9l-16.1-5.7c-.9-.3-1.8-.1-2.5.5zM38.9 351.301c1.6 2.1 1.2 5.2-1 6.8-2.2 1.6-5.2 1.2-6.8-1-1.6-2.1-1.2-5.2 1-6.8 2.2-1.5 5.2-1.1 6.8 1zm-10.4-5.7c-4.8 3.6-5.7 10.3-2.2 15.1 3.6 4.8 10.3 5.7 15.1 2.2 4.8-3.5 5.7-10.3 2.2-15.1-3.5-4.8-10.3-5.8-15.1-2.2z" fill="#F1F3F4"/><path d="M66.4 164l-32.2 18.6c-1.2.7-1.6 2.3-.9 3.5l7.7 13.4c.7 1.2 2.3 1.6 3.5.9l32.2-18.6c1.2-.7 1.6-2.3.9-3.5l-7.7-13.4c-.7-1.2-2.3-1.7-3.5-.9z" stroke="#34A853" stroke-width="2" stroke-miterlimit="10"/><path d="M162.1 81.9c2.8-4.9 1-11.2-3.9-14-4.9-2.8-11.2-1-14 3.9l-13.3 23.5c-2.8 4.9-1 11.2 3.9 14 4.9 2.8 11.2 1 14-3.9l13.3-23.5z" fill="#F1F3F4"/></svg> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/images/right_banner_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/images/right_banner_image.svg new file mode 100644 index 00000000000..d188e3b8802 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/images/right_banner_image.svg @@ -0,0 +1 @@ +<svg width="169" height="400" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M48.5 181.999c-2.7 0-5.4-1-7.5-3l-19.8-18.4c-2.2-2-3.4-4.8-3.5-7.7-.1-3 .9-5.8 3-8 4.2-4.5 11.2-4.7 15.7-.6l19.8 18.4c2.2 2 3.4 4.8 3.5 7.7.1 3-.9 5.8-3 8-2.3 2.4-5.2 3.6-8.2 3.6zm-19.8-38.9c-2.5 0-5.1 1-6.9 3-1.7 1.9-2.6 4.3-2.5 6.8.1 2.5 1.2 4.9 3 6.6l19.8 18.4c3.8 3.6 9.8 3.3 13.4-.5 1.7-1.9 2.6-4.3 2.5-6.8-.1-2.5-1.2-4.9-3-6.6l-19.8-18.4c-1.8-1.7-4.1-2.5-6.5-2.5z" fill="#E8EAED"/><path d="M75.7 257.401c5.689 0 10.3-4.612 10.3-10.3 0-5.689-4.611-10.3-10.3-10.3-5.688 0-10.3 4.611-10.3 10.3 0 5.688 4.612 10.3 10.3 10.3z" fill="#4285F4"/><path d="M117.201 184l-8.7 7.2c-.7.6-1 1.5-.9 2.4l1.9 11.1c.2.9.8 1.7 1.6 2l10.6 3.9c.9.3 1.8.2 2.5-.4l8.7-7.2c.7-.6 1-1.5.9-2.4l-1.9-11.1c-.2-.9-.8-1.7-1.6-2l-10.6-3.9c-.8-.3-1.8-.1-2.5.4z" fill="#FBBC05"/><path d="M111.599 376.2a6.9 6.9 0 100-13.8 6.9 6.9 0 000 13.8zM141.1 282.6l-33.9 9.1c-1.9.5-2.5 2.9-1.1 4.3l24.8 24.8c1.4 1.4 3.8.8 4.3-1.1l9.1-33.9c.5-2-1.3-3.7-3.2-3.2z" fill="#F1F3F4"/><path d="M91.8 65.1c-3.4 1.8-5.5 4.8-6.2 8.2-.5 2.3-1.8 4.3-3.7 5.6l-.9.6c-1.9 1.3-4.3 1.6-6.6 1.2-3.4-.7-7 .1-10 2.5-4.4 3.5-5.8 9.9-3.2 14.9 3.3 6.601 11.5 8.601 17.5 4.701 2.8-1.8 4.6-4.6 5.2-7.6.5-2.2 1.8-4.2 3.7-5.5l.9-.6c1.9-1.3 4.2-1.7 6.5-1.2 3 .6 6.301.1 9.101-1.7 6-3.9 7.4-12.3 2.7-17.9-3.7-4.6-10-5.8-15-3.2z" stroke="#34A853" stroke-width="2" stroke-miterlimit="10"/></svg> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js b/chromium/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js new file mode 100644 index 00000000000..bfd7df412b2 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/manage_profiles_browser_proxy.js @@ -0,0 +1,183 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; + +/** + * This is the data structure sent back and forth between C++ and JS. + * @typedef {{ + * profilePath: string, + * localProfileName: string, + * isSyncing: boolean, + * gaiaName: string, + * userName: string, + * isManaged: boolean, + * avatarIcon: string, + * }} + */ +export let ProfileState; + +/** + * This is the data structure sent back and forth between C++ and JS. + * `colorId` has the following special values: + * - `-1` for the default theme. + * - `0` for a manually picked color theme. + * @typedef {{ + * colorId: number, + * color: number, + * themeFrameColor: string, + * themeShapeColor: string, + * themeFrameTextColor: string, + * themeGenericAvatar: string, + * }} + */ +export let AutogeneratedThemeColorInfo; + +/** + * This is the data structure sent back and forth between C++ and JS. + * `colorId` has the following special values: + * - `-1` for the default theme.. + * - `0` for a manually picked color theme + * `color` is defined only for manually picked themes. + * @typedef {{ + * colorId: number, + * color: (number|undefined), + * }} + */ +export let UserThemeChoice; + +/** @interface */ +export class ManageProfilesBrowserProxy { + /** + * Initializes profile picker main view. + */ + initializeMainView() {} + + /** + * Launches picked profile and closes the profile picker. + * @param {string} profilePath + */ + launchSelectedProfile(profilePath) {} + + /** + * Opens profile on manage profile settings sub page and closes the + * profile picker. + * @param {string} profilePath + */ + openManageProfileSettingsSubPage(profilePath) {} + + /** Launches Guest profile. */ + launchGuestProfile() {} + + /** + * Inform native the user's choice on whether to show the profile picker + * on startup or not. + * @param {boolean} shouldShow + */ + askOnStartupChanged(shouldShow) {} + + /** + * Retrieves suggested theme for the new profile. + * @return {!Promise<!AutogeneratedThemeColorInfo>} A promise firing with the + * suggested theme info, once it has been retrieved. + */ + getNewProfileSuggestedThemeInfo() {} + + /** + * Retrieves all relevant theme information for the particular theme. + * @param {!UserThemeChoice} theme A theme which info needs to be retrieved. + * @return {!Promise<!AutogeneratedThemeColorInfo>} A promise firing with the + * theme info, once it has been retrieved. + */ + getProfileThemeInfo(theme) {} + + /** + * Retrieves profile statistics to be shown in the remove profile warning. + * @param {string} profilePath + */ + getProfileStatistics(profilePath) {} + + /** + * Removes profile. + * @param {string} profilePath + */ + removeProfile(profilePath) {} + + /** Loads Google sign in page.*/ + loadSignInProfileCreationFlow() {} + + /** + * Creates local profile + * @param {string} profileName + * @param {number} profileColor + * @param {string} avatarUrl + * @param {boolean} isGeneric + * @param {boolean} createShortcut + */ + createProfile( + profileName, profileColor, avatarUrl, isGeneric, createShortcut) {} +} + +/** @implements {ManageProfilesBrowserProxy} */ +export class ManageProfilesBrowserProxyImpl { + /** @override */ + initializeMainView() { + chrome.send('mainViewInitialize'); + } + + /** @override */ + launchSelectedProfile(profilePath) { + chrome.send('launchSelectedProfile', [profilePath]); + } + + /** @override */ + openManageProfileSettingsSubPage(profilePath) { + chrome.send('openManageProfileSettingsSubPage', [profilePath]); + } + + /** @override */ + launchGuestProfile() { + chrome.send('launchGuestProfile'); + } + + /** @override */ + askOnStartupChanged(shouldShow) { + chrome.send('askOnStartupChanged', [shouldShow]); + } + + /** @override */ + getNewProfileSuggestedThemeInfo() { + return sendWithPromise('getNewProfileSuggestedThemeInfo'); + } + + /** @override */ + getProfileThemeInfo(theme) { + return sendWithPromise('getProfileThemeInfo', theme); + } + + /** @override */ + removeProfile(profilePath) { + chrome.send('removeProfile', [profilePath]); + } + + /** @override */ + getProfileStatistics(profilePath) { + chrome.send('getProfileStatistics', [profilePath]); + } + + /** @override */ + loadSignInProfileCreationFlow() { + chrome.send('loadSignInProfileCreationFlow'); + } + + /** @override */ + createProfile( + profileName, profileColor, avatarUrl, isGeneric, createShortcut) { + chrome.send( + 'createProfile', + [profileName, profileColor, avatarUrl, isGeneric, createShortcut]); + } +} + +addSingletonGetter(ManageProfilesBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/navigation_behavior.js b/chromium/chrome/browser/resources/signin/profile_picker/navigation_behavior.js new file mode 100644 index 00000000000..62c7f905b48 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/navigation_behavior.js @@ -0,0 +1,186 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; + +import {isForceSigninEnabled, isSignInProfileCreationSupported} from './policy_helper.js'; + +/** + * ProfilePickerPages enum. + * These values are persisted to logs and should not be renumbered or + * re-used. + * See tools/metrics/histograms/enums.xml. + * @enum {number} + */ +const Pages = { + MAIN_VIEW: 0, + PROFILE_TYPE_CHOICE: 1, + LOCAL_PROFILE_CUSTOMIZATION: 2, + LOAD_SIGNIN: 3, +}; + +/** + * Valid route pathnames. + * @enum {string} + */ +export const Routes = { + MAIN: 'main-view', + NEW_PROFILE: 'new-profile', +}; + +/** + * Valid profile creation flow steps. + * @enum {string} + */ +export const ProfileCreationSteps = { + PROFILE_TYPE_CHOICE: 'profileTypeChoice', + // Not supported yet + LOCAL_PROFILE_CUSTOMIZATION: 'localProfileCustomization', + // Not supported yet + LOAD_SIGNIN: 'loadSignIn', +}; + +/** + * @param {!Routes} route + */ +function computeStep(route) { + switch (route) { + case Routes.MAIN: + return 'mainView'; + case Routes.NEW_PROFILE: + // TODO(msalama): Adjust once sign in profile creation is supported. + // Check DisallowSignIn policy. + if (!isSignInProfileCreationSupported()) { + assert(!isForceSigninEnabled()); + return ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION; + } + if (isForceSigninEnabled()) { + return ProfileCreationSteps.LOAD_SIGNIN; + } + return ProfileCreationSteps.PROFILE_TYPE_CHOICE; + default: + assertNotReached(); + } +} + +// Sets up history state based on the url path, unless it's already set. +if (!history.state || !history.state.route || !history.state.step) { + const path = window.location.pathname.replace(/\/$/, ''); + switch (path) { + case `/${Routes.NEW_PROFILE}`: + history.replaceState( + { + route: Routes.NEW_PROFILE, + step: computeStep(Routes.NEW_PROFILE), + isFirst: true, + }, + '', path); + break; + default: + history.replaceState( + {route: Routes.MAIN, step: computeStep(Routes.MAIN), isFirst: true}, + '', '/'); + } + recordNavigation(); +} + + +function recordNavigation() { + let page = /** @type {!Pages} */ (Pages.MAIN_VIEW); + switch (history.state.step) { + case 'mainView': + page = Pages.MAIN_VIEW; + break; + case ProfileCreationSteps.PROFILE_TYPE_CHOICE: + page = Pages.PROFILE_TYPE_CHOICE; + break; + case ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION: + page = Pages.LOCAL_PROFILE_CUSTOMIZATION; + break; + case ProfileCreationSteps.LOAD_SIGNIN: + page = Pages.LOAD_SIGNIN; + default: + assertNotReached(); + } + chrome.metricsPrivate.recordEnumerationValue( + 'ProfilePicker.UiVisited', page, Object.keys(Pages).length); +} + +/** @type {!Set<!PolymerElement>} */ +const routeObservers = new Set(); + +// Notifies all the elements that extended NavigationBehavior. +function notifyObservers() { + const route = /** @type {!Routes} */ (history.state.route); + const step = history.state.step; + routeObservers.forEach(observer => { + (/** @type {{onRouteChange: Function}} */ (observer)) + .onRouteChange(route, step); + }); +} + +// Notifies all elements when browser history is popped. +window.addEventListener('popstate', notifyObservers); + +/** + * @param {!Routes} route + */ +export function navigateTo(route) { + assert([Routes.MAIN, Routes.NEW_PROFILE].includes(route)); + navigateToStep(route, computeStep(route)); +} + +/** + * Navigates to the previous route if it belongs to the profile picker + * otherwise to the main route. + */ +export function navigateToPreviousRoute() { + // This can happen if the profile creation flow is opened directly from the + // profile menu. + if (history.state.isFirst) { + navigateTo(Routes.MAIN); + } else { + window.history.back(); + } +} + +/** + * @param {!Routes} route + * @param {string} step + */ +export function navigateToStep(route, step) { + history.pushState( + { + route: route, + step: step, + isFirst: false, + }, + '', route === Routes.MAIN ? '/' : `/${route}`); + notifyObservers(); +} + +/** @polymerBehavior */ +export const NavigationBehavior = { + /** @override */ + attached() { + assert(!routeObservers.has(this)); + routeObservers.add(this); + + // history state was set when page loaded, so when the element first + // attaches, call the route-change handler to initialize first. + this.onRouteChange(history.state.route, history.state.step); + }, + + /** @override */ + detached: function() { + assert(routeObservers.delete(this)); + }, + + /** + * Elements can override onRouteChange to handle route changes. + * @param {Routes} route + * @param {string} step + */ + onRouteChange: function(route, step) {}, +}; diff --git a/chromium/chrome/browser/resources/signin/profile_picker/policy_helper.js b/chromium/chrome/browser/resources/signin/profile_picker/policy_helper.js new file mode 100644 index 00000000000..17cc6023dba --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/policy_helper.js @@ -0,0 +1,31 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import './strings.js'; + +/** @return {boolean} */ +export function isGuestModeEnabled() { + return loadTimeData.getBoolean('isGuestModeEnabled'); +} + +/** @return {boolean} */ +export function isProfileCreationAllowed() { + return loadTimeData.getBoolean('isProfileCreationAllowed'); +} + +/** @return {boolean} */ +export function isForceSigninEnabled() { + const enabled = loadTimeData.getBoolean('isForceSigninEnabled'); + // Force sign in policy is not supported yet. The picker should not be shown + // in case this policy exists. + assert(!enabled); + return enabled; +} + +/** @return {boolean} */ +export function isSignInProfileCreationSupported() { + return loadTimeData.getBoolean('signInProfileCreationFlowSupported'); +} diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_card.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_card.html new file mode 100644 index 00000000000..a20ba4600dd --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_card.html @@ -0,0 +1,90 @@ +<style include="profile-picker-shared"> + cr-button { + --card-background-color: var(--md-background-color); + background-color: var(--card-background-color); + border: none; + border-radius: inherit; + box-shadow: none; + flex-direction: column; + height: inherit; + padding: 0; + width: inherit; + } + + :host-context(.focus-outline-visible) cr-button:focus { + box-shadow: 0 0 0 2px rgba(var(--google-blue-600-rgb), .4); + } + + .profile-avatar { + border-radius: 37px; + flex-shrink: 0; + height: var(--avatar-icon-size); + width: var(--avatar-icon-size); + } + + #avatarContainer { + height: var(--avatar-icon-size); + position: relative; + } + + #iconContainer { + --iron-icon-height: 18px; + --iron-icon-width: 24px; + --business-icon-size: 24px; + --business-icon-border-size: 2px; + align-items: center; + background-color: white; + border: var(--business-icon-border-size) solid var(--card-background-color); + border-radius: 50%; + box-shadow: 0 0 2px rgba(60, 64, 67, 0.12), 0 0 6px rgba(60, 64, 67, 0.15); + display: flex; + height: var(--business-icon-size); + position: absolute; + right: -6px; + top: calc(var(--avatar-icon-size) - var(--business-icon-size) + - var(--business-icon-border-size)); + width: var(--business-icon-size); + } + + :host-context([dir='rtl']) #iconContainer { + left: -6px; + right: initial; + } + + #iconContainer[hidden] { + display: none; + } + + iron-icon { + --iron-icon-fill-color: var(--google-grey-refresh-700); + } + + @media (prefers-color-scheme: dark) { + cr-button { + --card-background-color: var(--google-grey-800); + } + + #iconContainer { + background-color: var(--md-background-color); + box-shadow: 0 0 2px rgba(60, 64, 67, 0.12), 0 0 6px + rgba(60, 64, 67, 0.15); + } + + iron-icon { + --iron-icon-fill-color: var(--google-grey-500); + } + } +</style> + +<cr-button on-click="onProfileClick_"> + <profile-card-menu profile-state="[[profileState]]"></profile-card-menu> + <!-- TODO(msalama): Implement editing local profile name in place --> + <div class="profile-card-info">[[profileState.localProfileName]]</div> + <div id="avatarContainer"> + <img class="profile-avatar" alt="" src="[[profileState.avatarIcon]]"> + <div id="iconContainer" hidden="[[!profileState.isManaged]]"> + <iron-icon icon="signin:business"></iron-icon> + </div> + </div> + <div class="profile-card-info">[[profileState.gaiaName]]</div> +</cr-button> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_card.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_card.js new file mode 100644 index 00000000000..879c55d9958 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_card.js @@ -0,0 +1,39 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import './signin_icons.js'; +import './profile_card_menu.js'; +import './profile_picker_shared_css.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js'; + +Polymer({ + is: 'profile-card', + + _template: html`{__html_template__}`, + + properties: { + /** @type {!ProfileState} */ + profileState: { + type: Object, + }, + }, + + /** @private {ManageProfilesBrowserProxy} */ + manageProfilesBrowserProxy_: null, + + /** @override */ + ready() { + this.manageProfilesBrowserProxy_ = + ManageProfilesBrowserProxyImpl.getInstance(); + }, + + /** @private */ + onProfileClick_() { + this.manageProfilesBrowserProxy_.launchSelectedProfile( + this.profileState.profilePath); + }, +}); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.html new file mode 100644 index 00000000000..08fc9210424 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.html @@ -0,0 +1,120 @@ +<style include="cr-icons profile-picker-shared"> + #moreActionsButton { + --cr-icon-button-icon-size: 14px; + --cr-icon-button-margin-end: 0; + --cr-icon-button-margin-start: 0; + --cr-icon-button-size: 24px; + position: absolute; + right: 4px; + top: 4px; + } + + cr-action-menu { + font-weight: normal; + } + + #removeActionMenu { + pointer-events: none; + } + + #removeConfirmation { + color: var(--cr-primary-text-color); + margin-top: 16px; + pointer-events: none; + width: 234px; + } + + #removeConfirmation > * { + margin: 0 16px 16px 16px; + } + + .header { + font-size: 1.17em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .key-text { + font-weight: 500; + } + + .statistics { + border: 1px solid var(--google-grey-refresh-100); + border-radius: 4px; + box-sizing: border-box; + padding: 12px 16px 16px 12px; + width: -webkit-fill-available; + } + + .category { + text-align: start; + } + + .count { + color: var(--google-grey-refresh-500); + text-align: end; + } + + #removeConfirmationButton { + --active-shadow-action-rgb: var(--google-red-500-rgb); + --bg-action: var(--google-red-700); + --hover-bg-action: rgba(var(--google-red-700-rgb), .9); + --hover-shadow-action-rgb: var(--google-red-500-rgb); + background-color: var(--bg-action); + border-radius: 4px; + color: var(--ink-color-action); + font-weight: 500; + left: 50%; + margin-bottom: 16px; + pointer-events: auto; + transform: translateX(-50%); + width: 111px; + } + + #removeConfirmationButton:hover { + background-color: var(--hover-bg-action); + } +</style> + +<cr-icon-button class="icon-more-vert" id="moreActionsButton" + on-click="onMoreActionsButtonClicked_" title="$i18n{profileMenuName}" + aria-label="$i18n{profileMenuName}"> +</cr-icon-button> + +<cr-action-menu id="actionMenu" role-description="$i18n{menu}"> + <button class="dropdown-item" on-click="onRemoveButtonClicked_"> + $i18n{profileMenuRemoveText} + </button> + <button class="dropdown-item" on-click="onCustomizeButtonClicked_"> + $i18n{profileMenuCustomizeText} + </button> +</cr-action-menu> + +<cr-action-menu id="removeActionMenu" role-description="$i18n{menu}"> + <div id="removeConfirmation"> + <div class="header"> + $i18n{profileMenuRemoveText} + <span class="key-text">[[profileState.localProfileName]]</span> + </div> + <div> + [[removeWarningText_]] + <span hidden$="[[!profileState.isSyncing]]" class="key-text"> + [[profileState.userName]] + </span> + </div> + <table class="statistics"> + <template is="dom-repeat" items="[[profileStatistics_]]"> + <tr> + <td class="category">[[getProfileStatisticText_(item)]]</td> + <td class="count"> + [[getProfileStatisticCount_(item, statistics_)]]</td> + <tr> + </template> + </table> + </div> + <cr-button id="removeConfirmationButton"class="dropdown-item action-button" + on-click="onRemoveComfirationClicked_"> + $i18n{profileMenuRemoveText} + </cr-button> +</cr-action-menu> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.js new file mode 100644 index 00000000000..835ae3750d3 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_card_menu.js @@ -0,0 +1,221 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; +import 'chrome://resources/cr_elements/cr_icons_css.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import './profile_picker_shared_css.js'; + +import {assertNotReached} from 'chrome://resources/js/assert.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import './strings.js'; + +import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js'; + +/** + * @typedef {{ + * BrowsingHistory: number, + * Passwords: number, + * Bookmarks: number, + * Autofill: number, + * }} + */ +let Statistics; + +/** + * This is the data structure sent back and forth between C++ and JS. + * @typedef {{ + * profilePath: string, + * statistics: Statistics, + * }} + */ +let StatisticsResult; + + +/** + * Profile statistics data types. + * @enum {string} + */ +const ProfileStatistics = { + BROWSING_HISTORY: 'BrowsingHistory', + PASSWORDS: 'Passwords', + BOOKMARKS: 'Bookmarks', + AUTOFILL: 'Autofill', +}; + +Polymer({ + is: 'profile-card-menu', + + _template: html`{__html_template__}`, + + behaviors: [I18nBehavior, WebUIListenerBehavior], + + properties: { + /** @type {!ProfileState} */ + profileState: { + type: Object, + }, + + /** + * Results of profile statistics, keyed by the suffix of the corresponding + * data type, as reported by the C++ side. + * @private {!Object<number>} + */ + statistics_: { + type: Object, + // Will be filled as results are reported. + value() { + return {}; + } + }, + + /** + * List of selected data types. + * @private {!Array<string>} + */ + profileStatistics_: { + type: Object, + value: [ + ProfileStatistics.BROWSING_HISTORY, ProfileStatistics.PASSWORDS, + ProfileStatistics.BOOKMARKS, ProfileStatistics.AUTOFILL + ], + }, + + /** @private */ + removeWarningText_: { + type: String, + computed: 'computeRemoveWarningText_(profileState)', + }, + }, + + /** @private {ManageProfilesBrowserProxy} */ + manageProfilesBrowserProxy_: null, + + /** @override */ + ready() { + this.manageProfilesBrowserProxy_ = + ManageProfilesBrowserProxyImpl.getInstance(); + }, + + /** @override */ + attached() { + this.addWebUIListener( + 'profiles-list-changed', () => this.handleProfilesUpdated_()); + this.addWebUIListener( + 'profile-removed', () => this.handleProfilesUpdated_()); + this.addWebUIListener( + 'profile-statistics-received', + this.handleProfileStatsReceived_.bind(this)); + }, + + /** + * @return {string} + * @private + */ + computeRemoveWarningText_() { + return this.i18n( + this.profileState.isSyncing ? 'removeWarningSignedInProfile' : + 'removeWarningLocalProfile'); + }, + + /** + * @param {!Event} e + * @private + */ + onMoreActionsButtonClicked_(e) { + e.stopPropagation(); + e.preventDefault(); + this.$.actionMenu.showAt(this.$.moreActionsButton); + chrome.metricsPrivate.recordUserAction( + 'ProfilePicker_ThreeDottedMenuClicked'); + }, + + /** + * @param {!Event} e + * @private + */ + onRemoveButtonClicked_(e) { + e.stopPropagation(); + e.preventDefault(); + this.dataCounters_ = {}; + this.manageProfilesBrowserProxy_.getProfileStatistics( + this.profileState.profilePath); + this.$.actionMenu.close(); + this.$.removeActionMenu.showAt(this.$.moreActionsButton); + chrome.metricsPrivate.recordUserAction('ProfilePicker_RemoveOptionClicked'); + }, + + /** + * @param {!StatisticsResult} result + * @private + */ + handleProfileStatsReceived_(result) { + if (result.profilePath !== this.profileState.profilePath) { + return; + } + this.statistics_ = result.statistics; + }, + + /** + * @param {ProfileStatistics} dataType + * @return {string} + * @private + */ + getProfileStatisticText_(dataType) { + switch (dataType) { + case ProfileStatistics.BROWSING_HISTORY: + return this.i18n('removeWarningHistory'); + case ProfileStatistics.PASSWORDS: + return this.i18n('removeWarningPasswords'); + case ProfileStatistics.BOOKMARKS: + return this.i18n('removeWarningBookmarks'); + case ProfileStatistics.AUTOFILL: + return this.i18n('removeWarningAutofill'); + default: + assertNotReached(); + } + }, + + /** + * @param {string} dataType + * @return {string} + * @private + */ + getProfileStatisticCount_(dataType) { + const count = this.statistics_[dataType]; + return (count === undefined) ? this.i18n('removeWarningCalculating') : + count.toString(); + }, + + /** + * @param {!Event} e + * @private + */ + onRemoveComfirationClicked_(e) { + e.stopPropagation(); + e.preventDefault(); + this.manageProfilesBrowserProxy_.removeProfile( + this.profileState.profilePath); + }, + + /** + * Ensure any menu is closed on profile list updated. + * @private + */ + handleProfilesUpdated_() { + this.$.actionMenu.close(); + this.$.removeActionMenu.close(); + }, + + /** @private */ + onCustomizeButtonClicked_() { + this.manageProfilesBrowserProxy_.openManageProfileSettingsSubPage( + this.profileState.profilePath); + this.$.actionMenu.close(); + }, +}); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn new file mode 100644 index 00000000000..9c3a1c9e40b --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/html_to_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + deps = [ + ":local_profile_customization", + ":profile_type_choice", + ] +} + +js_library("ensure_lazy_loaded") { +} + +js_library("profile_type_choice") { + deps = [ + "..:manage_profiles_browser_proxy", + "..:navigation_behavior", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", + ] +} + +js_library("local_profile_customization") { + deps = [ + "..:manage_profiles_browser_proxy", + "..:navigation_behavior", + "..:policy_helper", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/customize_themes", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", + "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", + "//ui/webui/resources/cr_elements/cr_input:cr_input.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] +} + +html_to_js("web_components") { + js_files = [ + "profile_type_choice.js", + "local_profile_customization.js", + "shared_css.js", + ] +} diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js new file mode 100644 index 00000000000..0bea58dc5e8 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js @@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** @type {?Promise<!Array<void>>} */ +let lazyLoadPromise = null; + +/** + * @return {!Promise<!Array<void>>} Resolves when the lazy load module is + * imported. + */ +export function ensureLazyLoaded() { + if (!lazyLoadPromise) { + const script = document.createElement('script'); + script.type = 'module'; + script.src = './profile_creation_flow/lazy_load.js'; + document.body.appendChild(script); + + lazyLoadPromise = Promise.all([ + 'profile-type-choice', + 'local-profile-customization', + ].map(name => customElements.whenDefined(name))); + } + return lazyLoadPromise; +} diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_dark_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_dark_image.svg new file mode 100644 index 00000000000..aa14c07e1a0 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_dark_image.svg @@ -0,0 +1 @@ +<svg width="1024" height="266" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 266"><path d="M657.6 168.3c4 5.8 12 7.3 17.9 3.3 5.8-4 7.3-12 3.3-17.9l-19.1-27.8c-4-5.8-12-7.3-17.9-3.3-5.8 4-7.3 12-3.3 17.9l19.1 27.8z" stroke="#5F6368" stroke-width="2" stroke-miterlimit="10"/><path d="M387.8 132c7.124 0 12.9-5.776 12.9-12.9 0-7.125-5.776-12.9-12.9-12.9-7.124 0-12.9 5.775-12.9 12.9 0 7.124 5.776 12.9 12.9 12.9z" fill="#F28B82"/><path d="M58.1 99.4l-34.4 27.3c-1.9 1.5-1.5 4.6.8 5.5l40.8 16.2c2.3.9 4.7-1 4.3-3.4l-6.4-43.4c-.3-2.6-3.2-3.7-5.1-2.2z" fill="#FDD663"/><path d="M310.5 12.7L306 28.3c-.7 2.4 1.5 4.6 3.8 4l15.8-3.9c2.4-.6 3.2-3.6 1.5-5.3l-11.3-11.7c-1.6-1.8-4.6-1.1-5.3 1.3z" fill="#8AB4F8"/><path d="M94.4 33.6L78 27.9c-1.7-.6-3.5.3-4.1 2l-5.7 16.4c-.6 1.7.3 3.5 2 4.1L86.5 56c1.7.6 3.5-.3 4.1-2l5.7-16.4c.6-1.6-.3-3.4-1.9-4z" stroke="#5F6368" stroke-width="2" stroke-miterlimit="10"/><path d="M784.2 96.3L767 93.7c-1.7-.3-3.4.9-3.6 2.7l-2.6 17.2c-.3 1.7.9 3.4 2.7 3.6l17.2 2.6c1.7.3 3.4-.9 3.6-2.7l2.6-17.2c.3-1.7-.9-3.4-2.7-3.6z" fill="#5F6368"/><path d="M258.8 56.8l-8.5 11.3c-.7.9-.8 2.1-.4 3.2l5.6 13c.4 1.1 1.4 1.8 2.6 1.9l14 1.7c1.1.1 2.3-.3 2.9-1.3l8.5-11.3c.7-.9.8-2.1.4-3.2l-5.6-13c-.4-1.1-1.4-1.8-2.6-1.9l-14-1.7c-1.1-.1-2.2.4-2.9 1.3z" fill="#81C995"/><path d="M622.1 87.6l-12.2-7.1c-1-.6-2.2-.6-3.2 0l-12.2 7.1c-1 .6-1.6 1.6-1.6 2.8v14.1c0 1.1.6 2.2 1.6 2.8l12.2 7.1c1 .6 2.2.6 3.2 0l12.2-7.1c1-.6 1.6-1.6 1.6-2.8V90.3c0-1.1-.6-2.2-1.6-2.7z" fill="#8AB4F8"/><path d="M34.9 235.4a8.6 8.6 0 0 0 8.6-8.6 8.6 8.6 0 0 0-8.6-8.6 8.6 8.6 0 0 0-8.6 8.6 8.6 8.6 0 0 0 8.6 8.6zm196.7-80.3a8.6 8.6 0 0 0 8.6-8.6 8.6 8.6 0 0 0-8.6-8.6 8.6 8.6 0 0 0-8.6 8.6 8.6 8.6 0 0 0 8.6 8.6zm330-71.3a8.6 8.6 0 0 0 8.6-8.6 8.6 8.6 0 0 0-8.6-8.6 8.6 8.6 0 0 0-8.6 8.6 8.6 8.6 0 0 0 8.6 8.6z" fill="#5F6368"/><path d="M803.5 191.6a8.6 8.6 0 0 0 8.6-8.6 8.6 8.6 0 0 0-8.6-8.6 8.6 8.6 0 0 0-8.6 8.6 8.6 8.6 0 0 0 8.6 8.6z" fill="#8AB4F8"/><path d="M447.1 84c0 6-4.9 10.9-10.9 10.9S425.3 90 425.3 84s4.9-10.9 10.9-10.9S447.1 78 447.1 84zm-10.9-24.2C422.8 59.8 412 70.7 412 84c0 13.3 10.8 24.2 24.2 24.2 13.4 0 24.2-10.8 24.2-24.2 0-13.4-10.9-24.2-24.2-24.2z" fill="#5F6368"/><path d="M995.9 199.4c3.6 4.8 2.6 11.6-2.2 15.3-4.8 3.6-11.6 2.6-15.3-2.2-3.6-4.8-2.6-11.6 2.2-15.3 4.8-3.6 11.7-2.6 15.3 2.2zm-23.3-12.9c-10.7 8-12.9 23.2-4.9 33.9s23.2 12.9 33.9 4.9 12.9-23.2 4.9-33.9-23.2-12.9-33.9-4.9z" fill="#FDE293"/><path d="M331.5 205.6L302 238.1c-1.7 1.8-.7 4.8 1.7 5.3l42.9 9.3c2.4.5 4.5-1.8 3.7-4.1L337 206.8c-.8-2.4-3.8-3-5.5-1.2z" fill="#5F6368"/><path d="M807.8 220.4l-13.3 15.8c-.8 1-.7 2.5.3 3.3l16.1 13.5c1 .8 2.5.7 3.3-.3l13.3-15.8c.8-1 .7-2.5-.3-3.3l-16.1-13.5c-1-.8-2.5-.7-3.3.3z" stroke="#81C995" stroke-width="2" stroke-miterlimit="10"/><path d="M934.2 40.2c7.125 0 12.9-5.776 12.9-12.9 0-7.124-5.775-12.9-12.9-12.9-7.124 0-12.9 5.776-12.9 12.9 0 7.125 5.776 12.9 12.9 12.9zM688 218.8c7.124 0 12.9-5.776 12.9-12.9 0-7.124-5.776-12.9-12.9-12.9-7.124 0-12.9 5.776-12.9 12.9 0 7.124 5.776 12.9 12.9 12.9z" fill="#FDD663"/><path d="M751.2 66.3c6.8-6.7 6.9-17.6.3-24.4-2.4-2.4-5.3-4-8.4-4.7l-4.3-1c-4.2-.9-7.8-3.7-9.8-7.5l-2.4-4.5c-.5-.9-1.1-1.7-1.8-2.4-4.7-4.8-12.5-4.9-17.3-.2-4.8 4.7-4.9 12.5-.2 17.3.7.7 1.5 1.4 2.4 1.9l4.5 2.5c3.8 2.1 6.5 5.8 7.3 10l.9 4.3c.7 3.1 2.2 6.1 4.5 8.5 6.6 6.8 17.5 6.9 24.3.2z" stroke="#5F6368" stroke-width="2" stroke-miterlimit="10"/><path d="M213.2 252.8c9.5.4 17.6-7 18-16.5.1-3.4-.7-6.6-2.3-9.3l-2.2-3.8c-2.2-3.7-2.7-8.2-1.2-12.3l1.6-4.9c.3-1 .5-2 .5-3 .3-6.8-5-12.5-11.7-12.8-6.8-.3-12.5 5-12.8 11.7 0 1 0 2.1.2 3l1.2 5c1.1 4.2.2 8.7-2.3 12.2l-2.5 3.6c-1.8 2.6-2.9 5.7-3.1 9.1-.3 9.6 7.1 17.6 16.6 18zM971.4 84.6c-2.3-6.7-9.6-10.3-16.3-8-6.7 2.3-10.3 9.6-8 16.3l10.9 31.9c2.3 6.7 9.6 10.3 16.3 8 6.7-2.3 10.3-9.6 8-16.3l-10.9-31.9z" fill="#5F6368"/></svg>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_light_image.svg b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_light_image.svg new file mode 100644 index 00000000000..a9d7d766ccf --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/images/banner_light_image.svg @@ -0,0 +1 @@ +<svg width="1024" height="266" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 266"><path d="M657.599 168.301c4 5.8 12 7.3 17.9 3.3 5.8-4 7.3-12 3.3-17.9l-19.1-27.8c-4-5.8-12-7.3-17.9-3.3-5.8 4-7.3 12-3.3 17.9l19.1 27.8z" stroke="#fff" stroke-width="2" stroke-miterlimit="10"/><path d="M387.8 131.999c7.125 0 12.9-5.775 12.9-12.9 0-7.124-5.775-12.9-12.9-12.9-7.124 0-12.9 5.776-12.9 12.9 0 7.125 5.776 12.9 12.9 12.9z" fill="#EA4335"/><path d="M58.1 99.4l-34.4 27.301c-1.9 1.5-1.5 4.6.8 5.5l40.8 16.2c2.3.9 4.7-1 4.3-3.4l-6.4-43.4c-.3-2.6-3.2-3.7-5.1-2.2z" fill="#FBBC05"/><path d="M310.499 12.7l-4.5 15.6c-.7 2.4 1.5 4.6 3.8 4l15.8-3.9c2.4-.6 3.2-3.6 1.5-5.3l-11.3-11.7c-1.6-1.8-4.6-1.1-5.3 1.3z" fill="#4285F4"/><path d="M94.4 33.6L78 27.9c-1.7-.6-3.5.3-4.1 2l-5.7 16.4c-.6 1.7.3 3.5 2 4.1L86.5 56c1.7.6 3.5-.3 4.1-2l5.7-16.4c.6-1.6-.3-3.4-1.9-4z" stroke="#fff" stroke-width="2" stroke-miterlimit="10"/><path d="M784.2 96.3L767 93.7c-1.7-.3-3.4.9-3.6 2.7l-2.6 17.2c-.3 1.7.9 3.4 2.7 3.6l17.2 2.6c1.7.3 3.4-.9 3.6-2.7l2.6-17.2c.3-1.7-.9-3.4-2.7-3.6z" fill="#fff"/><path d="M258.8 56.8l-8.5 11.3c-.7.9-.8 2.1-.4 3.2l5.6 13c.4 1.1 1.4 1.8 2.6 1.9l14 1.7c1.1.1 2.3-.3 2.9-1.3l8.5-11.3c.7-.9.8-2.1.4-3.2l-5.6-13c-.4-1.1-1.4-1.8-2.6-1.9l-14-1.7c-1.1-.1-2.2.4-2.9 1.3z" fill="#34A853"/><path d="M622.1 87.6l-12.2-7.1c-1-.6-2.2-.6-3.2 0l-12.2 7.1c-1 .6-1.6 1.6-1.6 2.8v14.101c0 1.1.6 2.2 1.6 2.8l12.2 7.1c1 .6 2.2.6 3.2 0l12.2-7.1c1-.6 1.6-1.6 1.6-2.8v-14.2c0-1.1-.6-2.2-1.6-2.7z" fill="#4285F4"/><path d="M34.9 235.399a8.6 8.6 0 1 0 0-17.2 8.6 8.6 0 0 0 0 17.2zM231.6 155.1a8.6 8.6 0 1 0 0-17.2 8.6 8.6 0 0 0 0 17.2zm330-71.3a8.6 8.6 0 0 0 8.6-8.6 8.6 8.6 0 0 0-8.6-8.6 8.6 8.6 0 0 0-8.6 8.6 8.6 8.6 0 0 0 8.6 8.6z" fill="#fff"/><path d="M803.5 191.6a8.6 8.6 0 1 0 0-17.2 8.6 8.6 0 0 0 0 17.2z" fill="#4285F4"/><path d="M447.1 84c0 6-4.9 10.9-10.9 10.9S425.3 90 425.3 84s4.9-10.9 10.9-10.9S447.1 78 447.1 84zm-10.9-24.2C422.8 59.8 412 70.7 412 84c0 13.3 10.8 24.201 24.2 24.201 13.4 0 24.2-10.8 24.2-24.2 0-13.4-10.9-24.2-24.2-24.2z" fill="#fff"/><path d="M995.901 199.399c3.6 4.8 2.6 11.6-2.2 15.3-4.8 3.6-11.6 2.6-15.3-2.2-3.6-4.8-2.601-11.6 2.199-15.3 4.8-3.6 11.701-2.6 15.301 2.2zm-23.301-12.9c-10.7 8-12.899 23.2-4.899 33.9 8 10.7 23.199 12.9 33.899 4.9s12.9-23.2 4.9-33.9c-7.999-10.7-23.2-12.9-33.9-4.9z" fill="#F9AB00"/><path d="M331.499 205.599l-29.5 32.5c-1.7 1.8-.7 4.8 1.7 5.3l42.9 9.3c2.4.5 4.5-1.8 3.7-4.1l-13.3-41.8c-.8-2.4-3.8-3-5.5-1.2z" fill="#fff"/><path d="M807.8 220.4l-13.3 15.8c-.8 1-.7 2.5.3 3.3l16.1 13.5c1 .8 2.5.7 3.3-.3l13.3-15.8c.8-1 .7-2.5-.3-3.3l-16.1-13.5c-1-.8-2.5-.7-3.3.3z" stroke="#34A853" stroke-width="2" stroke-miterlimit="10"/><path d="M934.201 40.2c7.124 0 12.9-5.775 12.9-12.9 0-7.124-5.776-12.9-12.9-12.9-7.125 0-12.9 5.776-12.9 12.9 0 7.125 5.775 12.9 12.9 12.9zM688 218.8c7.124 0 12.9-5.776 12.9-12.9 0-7.124-5.776-12.9-12.9-12.9-7.125 0-12.9 5.776-12.9 12.9 0 7.124 5.775 12.9 12.9 12.9z" fill="#FBBC05"/><path d="M751.199 66.3c6.8-6.7 6.9-17.6.3-24.4-2.4-2.4-5.3-4-8.4-4.7l-4.3-1c-4.2-.9-7.8-3.7-9.8-7.5l-2.4-4.5c-.5-.9-1.1-1.7-1.8-2.4-4.7-4.8-12.5-4.9-17.3-.2-4.8 4.7-4.9 12.5-.2 17.3.7.7 1.5 1.4 2.4 1.9l4.5 2.5c3.8 2.1 6.5 5.8 7.3 10l.9 4.3c.7 3.1 2.2 6.1 4.5 8.5 6.6 6.8 17.5 6.9 24.3.2z" stroke="#fff" stroke-width="2" stroke-miterlimit="10"/><path d="M213.201 252.8c9.5.4 17.6-7 18-16.5.1-3.4-.7-6.6-2.3-9.3l-2.2-3.8c-2.2-3.7-2.7-8.2-1.2-12.3l1.6-4.9c.3-1 .5-2 .5-3 .3-6.8-5-12.5-11.7-12.8-6.8-.3-12.5 5-12.8 11.7 0 1 0 2.1.2 3l1.2 5c1.1 4.2.2 8.7-2.3 12.2l-2.5 3.6c-1.8 2.6-2.9 5.7-3.1 9.1-.3 9.6 7.1 17.6 16.6 18zM971.399 84.6c-2.3-6.7-9.6-10.3-16.3-8-6.7 2.3-10.3 9.6-8 16.3l10.9 31.899c2.3 6.7 9.6 10.3 16.3 8 6.7-2.3 10.3-9.6 8-16.3l-10.9-31.9z" fill="#fff"/></svg>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js new file mode 100644 index 00000000000..ab38aa48044 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js @@ -0,0 +1,6 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './profile_type_choice.js'; +import './local_profile_customization.js';
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html new file mode 100644 index 00000000000..17e3c7f9ab7 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html @@ -0,0 +1,151 @@ +<style include="profile-creation-shared"> + :host { + --vertical-gap: 24px; + } + + #title { + color: var(--theme-text-color); + font-weight: normal; + padding-top: 84px; + text-align: center; + } + + #wrapperContainer { + align-items: center; + display: flex; + height: calc(max(100vh, var(--view-min-size)) - + (var(--banner-height) + var(--avatar-size)/2 + var(--vertical-gap) + + var(--cr-button-height) + var(--footer-margin))); + justify-content: center; + margin-bottom: var(--vertical-gap); + margin-inline-end: 16px; + margin-inline-start: 16px; + margin-top: calc(var(--avatar-size)/2); + overflow: auto; + } + + #wrapperContainer::-webkit-scrollbar { + width: var(--scrollbar-width); + } + + /* Track */ + #wrapperContainer::-webkit-scrollbar-track { + border-radius: var(--scrollbar-width); + } + + /* Handle */ + #wrapperContainer::-webkit-scrollbar-thumb { + background: var(--scrollbar-background); + border-radius: var(--scrollbar-width); + } + + #wrapper > * { + flex-grow: 0; + flex-shrink: 0; + margin-top: var(--vertical-gap); + } + + #wrapper { + align-items: center; + display: flex; + flex-direction: column; + max-height: 100%; + width: 100%; + } + + #nameInput { + --cr-input-placeholder-color: rgba(var(--google-grey-900-rgb), .5); + --cr-input-border-bottom: 1px solid var(--cr-secondary-text-color); + height: 32px; + width: 300px; + } + + #colorPickerContainer { + border: 1px solid var(--google-grey-refresh-300); + border-radius: 4px; + display: flex; + flex-direction: column; + padding: 15px 36px 23px; + } + + #colorPickerHeader { + color: var(--cr-primary-text-color); + padding-bottom: 16px; + } + + #colorPicker { + --cr-customize-themes-grid-gap: 8px; + --cr-customize-themes-icon-size: 44px; + align-self: center; + } + + cr-checkbox { + --cr-checkbox-label-color: var(--cr-secondary-text-color); + --cr-checkbox-label-padding-start: 8px; + height: 20px; + left: 0; + margin-inline-end: auto; + margin-inline-start: auto; + position: absolute; + right: 0; + width: fit-content; + } + + cr-checkbox[hidden] { + display: none; + } + + #save { + display: flex; + margin-inline-end: var(--footer-margin); + margin-inline-start: auto; + width: 111px; + } + + @media (prefers-color-scheme: dark) { + #nameInput { + --cr-input-placeholder-color: rgba(var(--google-grey-200-rgb), .5); + } + } +</style> + +<div id="headerContainer" + style$="--theme-frame-color:[[profileThemeInfo.themeFrameColor]]; + --theme-text-color:[[profileThemeInfo.themeFrameTextColor]]; + --theme-shape-color:[[profileThemeInfo.themeShapeColor]]"> + <iron-icon class="banner" icon="profiles:customize-banner"></iron-icon> + <cr-icon-button id="backButton" class="icon-arrow-back" + on-click="onClickBack_" aria-label="$i18n{backButtonLabel}"> + </cr-icon-button> + <h2 id="title">$i18n{localProfileCreationTitle}</h2> + <img class="avatar" src$="[[profileThemeInfo.themeGenericAvatar]]"> +</div> + +<div id="wrapperContainer"> + <div id="wrapper"> + <cr-input id="nameInput" value="{{profileName_}}" pattern=".*\\S.*" + placeholder="$i18n{createProfileNamePlaceholder}" + auto-validate spellcheck="false"> + </cr-input> + + <div id="colorPickerContainer"> + <div id="colorPickerHeader"> + $i18n{localProfileCreationThemeText} + </div> + <cr-customize-themes id="colorPicker" selected-theme="{{selectedTheme_}}"> + </cr-customize-themes> + </div> + </div> +</div> + +<div class="footer"> + <cr-checkbox checked="{{createShortcut_}}" + hidden="[[!isProfileShortcutsEnabled_]]"> + $i18n{createDesktopShortcutLabel} + </cr-checkbox> + + <cr-button id="save" class="action-button" on-click="onSaveClick_" + disabled="[[isSaveDisabled_(createInProgress_, profileName_)]]"> + $i18n{createProfileConfirm} + </cr-button> +</div> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js new file mode 100644 index 00000000000..98262e8ec0a --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js @@ -0,0 +1,220 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; +import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/cr_components/customize_themes/customize_themes.js'; +import 'chrome://resources/cr_components/customize_themes/customize_themes.mojom-lite.js'; +import './shared_css.js'; +import '../icons.js'; + +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {AutogeneratedThemeColorInfo, ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, UserThemeChoice} from '../manage_profiles_browser_proxy.js'; +import {navigateToPreviousRoute} from '../navigation_behavior.js'; +import {isProfileCreationAllowed} from '../policy_helper.js'; + +Polymer({ + is: 'local-profile-customization', + + _template: html`{__html_template__}`, + + behaviors: [WebUIListenerBehavior], + + properties: { + /** + * The theme info used to display colored UI elements. + * @type {!AutogeneratedThemeColorInfo} + */ + profileThemeInfo: { + type: Object, + observer: 'onProfileThemeInfoChange_', + }, + + /** + * The currently selected theme in the color picker. + * @private {!customizeThemes.mojom.Theme} + */ + selectedTheme_: { + type: Object, + observer: 'onSelectedThemeChange_', + }, + + /** + * True if `selectedTheme_` doesn't need to be updated when + * `profileThemeInfo` changes. + * @private {boolean} + */ + disableSelectedThemeUpdates_: { + type: Boolean, + value: false, + }, + + /** + * The current profile name. + * @private {string} + */ + profileName_: { + type: String, + value: '', + }, + + /** + * if true, a desktop shortcut will be created for the new profile. + * @private {boolean} + */ + createShortcut_: { + type: Boolean, + value: true, + }, + + /** + * True if the profile shortcuts feature is enabled. + * @private + */ + isProfileShortcutsEnabled_: { + type: Boolean, + value: () => loadTimeData.getBoolean('profileShortcutsEnabled'), + }, + + /** + * True if a profile is being created or imported. + * @private {boolean} + */ + createInProgress_: { + type: Boolean, + value: false, + }, + }, + + /** @private {?ManageProfilesBrowserProxy} */ + manageProfilesBrowserProxy_: null, + + /** @override */ + created() { + this.manageProfilesBrowserProxy_ = + ManageProfilesBrowserProxyImpl.getInstance(); + }, + + /** @override */ + ready() { + this.sanityCheck_(); + this.addWebUIListener( + 'create-profile-finished', () => this.handleCreateProfileFinished_()); + }, + + /** + * @return {boolean} + * @private + */ + sanityCheck_() { + if (!isProfileCreationAllowed()) { + this.onClickBack_(); + return false; + } + return true; + }, + + /** + * Determining whether 'Save' button is disabled. + * @return {boolean} + * @private + */ + isSaveDisabled_() { + return this.createInProgress_ || !this.profileName_ || + !this.$.nameInput.validate(); + }, + + /** + * Handler for the 'Save' button click event. + * @param {!Event} event + * @private + */ + onSaveClick_(event) { + if (!this.sanityCheck_()) { + return; + } + + if (this.createInProgress_) { + return; + } + this.createInProgress_ = true; + const createShortcut = + this.isProfileShortcutsEnabled_ && this.createShortcut_; + // TODO(crbug.com/1115056): Support avatar selection. + this.manageProfilesBrowserProxy_.createProfile( + this.profileName_, this.profileThemeInfo.color, '', true, + createShortcut); + }, + + /** @private */ + onClickBack_() { + navigateToPreviousRoute(); + this.reset_(); + }, + + /** @private */ + reset_() { + this.profileName_ = ''; + this.createShortcut_ = true; + this.$.wrapper.scrollTop = 0; + }, + + /** @private */ + onProfileThemeInfoChange_() { + if (this.disableSelectedThemeUpdates_) { + return; + } + + this.selectedTheme_ = { + type: customizeThemes.mojom.ThemeType.kChrome, + info: { + chromeThemeId: this.profileThemeInfo.colorId, + }, + }; + }, + + /** + * @return {!Promise} + * @private + */ + async onSelectedThemeChange_() { + /** @type {UserThemeChoice} */ + let theme; + if (this.selectedTheme_.type === + customizeThemes.mojom.ThemeType.kAutogenerated) { + theme = { + colorId: 0, + color: this.selectedTheme_.info.autogeneratedThemeColors.frame.value + }; + } else if ( + this.selectedTheme_.type === customizeThemes.mojom.ThemeType.kChrome) { + theme = { + colorId: /** @type {number} */ (this.selectedTheme_.info.chromeThemeId), + }; + } else if ( + this.selectedTheme_.type === customizeThemes.mojom.ThemeType.kDefault) { + theme = { + colorId: -1, + }; + } + + const newThemeInfo = + await this.manageProfilesBrowserProxy_.getProfileThemeInfo(theme); + this.disableSelectedThemeUpdates_ = true; + this.profileThemeInfo = newThemeInfo; + this.disableSelectedThemeUpdates_ = false; + }, + + /** @private */ + handleCreateProfileFinished_() { + this.onClickBack_(); + this.createInProgress_ = false; + } +}); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html new file mode 100644 index 00000000000..a5052e8f80c --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html @@ -0,0 +1,72 @@ +<style include="profile-creation-shared"> + #actionContainer { + align-items: center; + display: flex; + flex-direction: column; + } + + #signinPromoBanner { + background-image: url(profile_creation_flow/images/banner_light_image.svg); + } + + @media (prefers-color-scheme: dark) { + #signinPromoBanner { + background-image: + url(profile_creation_flow/images/banner_dark_image.svg); + } + } + + #bannerContainer { + height: 266px; + position: relative; + width: 100%; + } + + #notNowButton { + background: none; + border: none; + color: var(--cr-link-color); + cursor: pointer; + font-size: 1em; + font-weight: normal; + line-height: 20px; + margin-top: 18px; + outline: none; + } + + #signInButton { + font-size: 1em; + font-weight: normal; + width: 208px; + } + + .title-container { + margin: 104px auto; + margin-bottom: 48px; + text-align: center; + } +</style> + +<div id="headerContainer" + style$="--theme-frame-color:[[profileThemeInfo.themeFrameColor]]; + --theme-text-color:[[profileThemeInfo.themeFrameTextColor]];"> + <cr-icon-button id="backButton" class="icon-arrow-back" + on-click="onClickBack_" aria-label="$i18n{backButtonLabel}"> + </cr-icon-button> + <div id="signinPromoBanner" class="banner"></div> + <img class="avatar" src="[[profileThemeInfo.themeGenericAvatar]]"> +</div> +<div class="title-container"> + <h2>$i18n{profileTypeChoiceTitle}</h2> + <h3>$i18n{profileTypeChoiceSubtitle}</h3> +</div> +<div id="actionContainer"> + <cr-button id="signInButton" class="action-button fade-in" + on-click="onSignInClick_"> + $i18n{signInButtonLabel} + </cr-button> + <button id="notNowButton" class="action-link fade-in" + on-click="onNotNowClick_"> + $i18n{notNowButtonLabel} + </button> +</div> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js new file mode 100644 index 00000000000..f5ce65a624a --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js @@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import './shared_css.js'; + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {AutogeneratedThemeColorInfo} from '../manage_profiles_browser_proxy.js'; +import {navigateToPreviousRoute, navigateToStep, ProfileCreationSteps, Routes} from '../navigation_behavior.js'; + +Polymer({ + is: 'profile-type-choice', + + _template: html`{__html_template__}`, + + properties: { + /** @type {!AutogeneratedThemeColorInfo} */ + profileThemeInfo: { + type: Object, + }, + }, + + /** @private */ + onNotNowClick_() { + navigateToStep( + Routes.NEW_PROFILE, ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION); + }, + + /** @private */ + onSignInClick_() { + navigateToStep(Routes.NEW_PROFILE, ProfileCreationSteps.LOAD_SIGNIN); + }, + + /** @private */ + onClickBack_() { + navigateToPreviousRoute(); + }, +}); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html new file mode 100644 index 00000000000..28218f4d317 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.html @@ -0,0 +1,43 @@ +<template> + <style include="cr-icons profile-picker-shared"> + :host { + --avatar-size: 100px; + --banner-height: 244px; + } + + #headerContainer { + background-color: var(--theme-frame-color); + height: var(--banner-height); + position: relative; + width: 100%; + } + + .banner { + background-size: 100% 100%; + height: 100%; + position: absolute; + top: 0; + width: 100%; + } + + #backButton { + --cr-icon-button-fill-color: var(--theme-text-color); + --cr-icon-button-icon-size: 14px; + --cr-icon-button-margin-start: 4px; + --cr-icon-button-size: 25px; + margin-top: 4px; + } + + .avatar { + border: 2px solid var(--md-background-color); + border-radius: 50%; + bottom: calc(var(--avatar-size)/-2); + height: var(--avatar-size); + left: 0; + margin: auto; + position: absolute; + right: 0; + width: var(--avatar-size); + } + </style> +</template> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.js new file mode 100644 index 00000000000..2092935cadb --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.js @@ -0,0 +1,15 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/cr_elements/cr_icons_css.m.js'; + +import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import '../profile_picker_shared_css.js'; + +const template = document.createElement('template'); +template.innerHTML = ` +<dom-module id="profile-creation-shared">{__html_template__}</dom-module> +`; +document.body.appendChild(template.content.cloneNode(true)); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker.html index ce6fe52046e..50393e2a18d 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker.html +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker.html @@ -7,6 +7,10 @@ </head> <body> <style> + body { + margin: 0; + } + @media (prefers-color-scheme: dark) { html { background: var(--md-background-color); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.html index e227ef80fef..a82b68a8607 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.html +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.html @@ -1,12 +1,32 @@ -<style> +<style include="profile-picker-shared"> cr-view-manager { display: flex; font-size: 100%; margin: 0; - min-height: 100vh; + } + + cr-view-manager > [slot='view'] { + min-height: var(--view-min-size); + min-width: var(--view-min-size); } </style> -<cr-view-manager> - <profile-picker-main-view slot="view" class="active"> +<cr-view-manager id="viewManager"> + <profile-picker-main-view id="mainView" slot="view"> </profile-picker-main-view> + + <cr-lazy-render id="profileTypeChoice"> + <template> + <profile-type-choice slot="view" + profile-theme-info="[[newProfileThemeInfo]]"> + </profile-type-choice> + </template> + </cr-lazy-render> + + <cr-lazy-render id="localProfileCustomization"> + <template> + <local-profile-customization slot="view" + profile-theme-info="[[newProfileThemeInfo]]"> + </local-profile-customizatione> + </template> + </cr-lazy-render> </cr-view-manager> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.js index 83e6c76fbd6..66fa26e6471 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.js +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_app.js @@ -3,12 +3,112 @@ // found in the LICENSE file. import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js'; +import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import './profile_picker_main_view.js'; +import './profile_picker_shared_css.js'; +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {AutogeneratedThemeColorInfo, ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl} from './manage_profiles_browser_proxy.js'; +import {navigateTo, NavigationBehavior, ProfileCreationSteps, Routes} from './navigation_behavior.js'; +import {isProfileCreationAllowed} from './policy_helper.js'; +import {ensureLazyLoaded} from './profile_creation_flow/ensure_lazy_loaded.js'; + Polymer({ is: 'profile-picker-app', _template: html`{__html_template__}`, + + behaviors: [NavigationBehavior], + + properties: { + /** + * Suggested new profile theme info for the profile creation flow. + * @type {!AutogeneratedThemeColorInfo} + */ + newProfileThemeInfo: { + type: Object, + notify: true, + }, + }, + + /** @private {?Routes} */ + currentRoute_: null, + + /** @private {?ManageProfilesBrowserProxy} */ + manageProfilesBrowserProxy_: null, + + /** @override */ + ready() { + this.manageProfilesBrowserProxy_ = + ManageProfilesBrowserProxyImpl.getInstance(); + }, + + /** @override */ + attached() { + this.setMinimumSize_(); + }, + + /** + * @param {Routes} route + * @param {string} step + * @private + */ + onRouteChange(route, step) { + if (!isProfileCreationAllowed() && route === Routes.NEW_PROFILE) { + navigateTo(Routes.MAIN); + return; + } + + if (step == ProfileCreationSteps.LOAD_SIGNIN) { + this.manageProfilesBrowserProxy_.loadSignInProfileCreationFlow(); + return; + } + + const setStep = () => { + this.$.viewManager.switchView(step, 'fade-in', 'no-animation'); + }; + + // If the route changed, initialize modules for that route. + if (this.currentRoute_ !== route) { + this.currentRoute_ = route; + this.initializeModules_().then(setStep); + } else { + setStep(); + } + }, + + /** + * @return {!Promise} + * @private + */ + initializeModules_() { + switch (this.currentRoute_) { + case Routes.MAIN: + return Promise.resolve(); + case Routes.NEW_PROFILE: + return Promise.all( + [this.initializeNewProfileThemeInfo_(), ensureLazyLoaded()]); + default: + // |this.currentRoute_| should be set by now. + assertNotReached(); + } + }, + + /** + * @return {!Promise} + * @private + */ + async initializeNewProfileThemeInfo_() { + this.newProfileThemeInfo = await this.manageProfilesBrowserProxy_ + .getNewProfileSuggestedThemeInfo(); + }, + + /** @private */ + setMinimumSize_() { + this.style.setProperty( + '--view-min-size', loadTimeData.getString('minimumPickerSize')); + }, }); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html index 5700543c6d2..2c995fae231 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html @@ -1,54 +1,191 @@ -<style> - .profiles-container { - --grid-gutter: 12px; - --max-columns: 4; +<style include="profile-picker-shared"> + :host { + --avatar-icon-size: 74px; + --banner-img-height: 400px; + --banner-img-width: 169px; + } + + .banner { + height: var(--banner-img-height); + overflow: hidden; + position: absolute; + top: 0; + width: var(--banner-img-width); + z-index: -1; + } + + #leftBanner { + background: url(images/left_banner_image.svg); + left: 0; + } + + #rightBanner { + background: url(images/right_banner_image.svg); + right: 0; + } + + .title-container { + margin: 30px auto 0 auto; + padding-inline-end: calc(var(--banner-img-width) - 10px); + padding-inline-start: calc(var(--banner-img-width) - 10px); + text-align: center; + } + + #wrapper { + display: flex; + height: calc(max(100vh, var(--view-min-size)) - 290px); + margin-inline-end: 140px; + margin-inline-start: 140px; + } + + .profiles-container { + --grid-gutter: 24px; --profile-item-height:178px; --profile-item-width: 162px; align-items: center; display: grid; - height: 80%; grid-column-gap: var(--grid-gutter); grid-row-gap: var(--grid-gutter); grid-template-columns: repeat(auto-fit, var(--profile-item-width)); justify-content: center; margin: auto; - max-width: calc(var(--profile-item-width) * var(--max-columns) + - var(--grid-gutter) * var(--max-columns)); - } + max-height: 100%; + overflow-x: hidden; + overflow-y: auto; + padding-inline-end: var(--scrollbar-width); + padding-inline-start: var(--scrollbar-width); + width: 100%; + } -.profile-item { + .profiles-container::-webkit-scrollbar { + width: var(--scrollbar-width); + } + + /* Track */ + .profiles-container::-webkit-scrollbar-track { + border-radius: var(--scrollbar-width); + } + + /* Handle */ + .profiles-container::-webkit-scrollbar-thumb { + background: var(--scrollbar-background); + border-radius: var(--scrollbar-width); + } + + .profile-item { align-items: center; + border-radius: 12px; display: flex; flex-direction: column; height: var(--profile-item-height); justify-content: center; width: var(--profile-item-width); - } - - #addProfile { - border: 1px dashed; - border-color: var(--google-grey-400); - border-radius: 12px; - } - - cr-icon-button[iron-icon='profiles:add'] { - --cr-icon-button-icon-size: 74px; - --cr-icon-button-size: 84px; - --cr-icon-button-fill-color: var(--google-grey-refresh-100); - --cr-icon-button-margin-end: 0px; - --cr-icon-button-margin-start: 0px; - --cr-icon-button-stroke-color: var(--google-grey-refresh-700); - } - -@media (prefers-color-scheme: dark) { - /* TODO(msalama): Dark mode mocks not ready yet.*/ -} + } + + #addProfile { + border: 1px dashed; + border-color: var(--google-grey-400); + } + + cr-icon-button[iron-icon='profiles:add'] { + --cr-icon-button-icon-size: var(--avatar-icon-size); + --cr-icon-button-size: 84px; + --cr-icon-button-fill-color: var(--google-grey-refresh-100); + --cr-icon-button-margin-end: 0; + --cr-icon-button-margin-start: 0; + --cr-icon-button-stroke-color: var(--google-grey-refresh-700); + } + + .footer > * { + background-color: rgba(255, 255, 255, .8); + } + + #browseAsGuestButton { + margin-inline-start: var(--footer-margin); + } + + #browseAsGuestButton > iron-icon { + margin-inline-end: 8px; + } + + cr-checkbox { + --cr-checkbox-label-color: var(--cr-secondary-text-color); + --cr-checkbox-label-padding-start: 8px; + justify-content: flex-end; + margin-inline-end: var(--footer-margin); + margin-inline-start: auto; + padding-inline-end: 5px; + padding-inline-start: 5px; + } + + cr-checkbox[hidden] { + display: none; + } + + @media (prefers-color-scheme: dark) { + #leftBanner { + background: url(images/dark_mode_left_banner_image.svg); + } + + #rightBanner { + background: url(images/dark_mode_right_banner_image.svg); + } + + #addProfile { + border-color: var(--google-grey-refresh-700); + } + + cr-icon-button[iron-icon='profiles:add'] { + --cr-icon-button-fill-color: var(--google-grey-refresh-500); + --cr-icon-button-stroke-color: rgb(48, 48, 50); + color: var(--google-grey-refresh-500); + } + + .footer > * { + background-color: rgba(0, 0, 0, .5); + } + } </style> -<div class="profiles-container"> - <div id="addProfile" class="profile-item"> - <!-- TODO(msalama): Add title, aria-label once strings are ready--> - <cr-icon-button iron-icon="profiles:add" - on-click="onAddProfileClick_"> - </cr-icon-button> + +<template is="dom-if" if="[[profilesList_]]"> + <div id="leftBanner" class="banner"></div> + <div class="title-container"> + <img id="product-logo" on-click="onProductLogoTap_" + srcset="chrome://theme/current-channel-logo@1x 1x, + chrome://theme/current-channel-logo@2x 2x" + role="presentation"> + <h2>$i18n{mainViewTitle}</h2> + <h3>$i18n{mainViewSubtitle}</h3> + </div> + <div id="wrapper"> + <div class="profiles-container"> + <template is="dom-repeat" + hidden="[[!profilesList_]]" items="[[profilesList_]]"> + <profile-card + class="profile-item" profile-state="[[item]]"> + </profile-card> + </template> + <div id="addProfile" class="profile-item"> + <div class="profile-card-info">$i18n{addSpaceButton}</div> + <cr-icon-button iron-icon="profiles:add" + on-click="onAddProfileClick_" aria-label$="$i18n{addSpaceButton}"> + </cr-icon-button> + <!-- Empty div to maintain alignment with other profile cards. --> + <div class="profile-card-info"></div> + </div> + </div> + </div> + <div id="rightBanner" class="banner"></div> + + <div class="footer"> + <cr-button id="browseAsGuestButton" on-click="onLaunchGuestProfileClick_"> + <iron-icon icon="profiles:account-circle"></iron-icon> + <div>$i18n{browseAsGuestButton}</div> + </cr-button> + <cr-checkbox checked="{{askOnStartup_}}" + on-change="onAskOnStartupChangedByUser_" + hidden="[[shouldHideAskOnStartup_(profilesList_.length)]]"> + $i18n{askOnStartupCheckboxText} + </cr-checkbox> </div> -</div> +</template> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js index bde47adde55..42361060636 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js @@ -4,17 +4,134 @@ import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import './icons.js'; +import './profile_card.js'; +import './profile_picker_shared_css.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import './strings.js'; + +import {ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl, ProfileState} from './manage_profiles_browser_proxy.js'; +import {navigateTo, NavigationBehavior, Routes} from './navigation_behavior.js'; +import {isGuestModeEnabled, isProfileCreationAllowed} from './policy_helper.js'; Polymer({ is: 'profile-picker-main-view', _template: html`{__html_template__}`, + behaviors: [WebUIListenerBehavior, NavigationBehavior], + + properties: { + /** + * Profiles list supplied by ManageProfilesBrowserProxy. + * @type {!Array<!ProfileState>} + */ + profilesList_: { + type: Object, + }, + + /** @private */ + askOnStartup_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('askOnStartup'); + } + }, + }, + + /** @private {?ManageProfilesBrowserProxy} */ + manageProfilesBrowserProxy_: null, + + /** @override */ + ready() { + if (!isGuestModeEnabled()) { + this.$.browseAsGuestButton.style.display = 'none'; + } + + if (!isProfileCreationAllowed()) { + this.$.addProfile.style.display = 'none'; + } + + this.manageProfilesBrowserProxy_ = + ManageProfilesBrowserProxyImpl.getInstance(); + }, + + /** @override */ + attached() { + this.addWebUIListener( + 'profiles-list-changed', this.handleProfilesListChanged_.bind(this)); + this.addWebUIListener( + 'profile-removed', this.handleProfileRemoved_.bind(this)); + this.manageProfilesBrowserProxy_.initializeMainView(); + }, + + /** @private */ + onProductLogoTap_() { + this.$['product-logo'].animate( + { + transform: ['none', 'rotate(-10turn)'], + }, + { + duration: 500, + easing: 'cubic-bezier(1, 0, 0, 1)', + }); + }, + + /** + * Handler for when the profiles list are updated. + * @param {!Array<!ProfileState>} profilesList + * @private + */ + handleProfilesListChanged_(profilesList) { + this.profilesList_ = profilesList; + }, + + /** + * Called when the user modifies 'Ask on startup' preference. + * @private + */ + onAskOnStartupChangedByUser_() { + this.manageProfilesBrowserProxy_.askOnStartupChanged(this.askOnStartup_); + }, + /** @private */ onAddProfileClick_() { - // TODO(msalama): do something. + if (!isProfileCreationAllowed()) { + return; + } + chrome.metricsPrivate.recordUserAction('ProfilePicker_AddClicked'); + navigateTo(Routes.NEW_PROFILE); + }, + + /** @private */ + onLaunchGuestProfileClick_() { + if (!isGuestModeEnabled()) { + return; + } + this.manageProfilesBrowserProxy_.launchGuestProfile(); + }, + + /** @private */ + handleProfileRemoved_(profilePath) { + for (let i = 0; i < this.profilesList_.length; i += 1) { + if (this.profilesList_[i].profilePath === profilePath) { + // TODO(crbug.com/1063856): Add animation. + this.splice('profilesList_', i, 1); + break; + } + } + }, + + /** + * @return boolean + * @private + */ + shouldHideAskOnStartup_() { + return !this.profilesList_ || (this.profilesList_.length < 2); }, }); diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd index 244cc063482..66f0f1453c9 100644 --- a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd @@ -12,13 +12,49 @@ </outputs> <release seq="1"> <includes> - <!-- Generated Polymer 3 elements --> + <include name="IDR_PROFILE_PICKER_IMAGES_LEFT_BANNER_IMAGE" + file="images/left_banner_image.svg" + type="BINDATA" /> + <include name="IDR_PROFILE_PICKER_IMAGES_RIGHT_BANNER_IMAGE" + file="images/right_banner_image.svg" + type="BINDATA" /> + <include name="IDR_PROFILE_PICKER_IMAGES_DARK_MODE_LEFT_BANNER_IMAGE" + file="images/dark_mode_left_banner_image.svg" + type="BINDATA" /> + <include name="IDR_PROFILE_PICKER_IMAGES_DARK_MODE_RIGHT_BANNER_IMAGE" + file="images/dark_mode_right_banner_image.svg" + type="BINDATA" /> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_IMAGES_BANNER_LIGHT_IMAGE" + file="profile_creation_flow/images/banner_light_image.svg" + type="BINDATA" /> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_IMAGES_BANNER_DARK_IMAGE" + file="profile_creation_flow/images/banner_dark_image.svg" + type="BINDATA" /> + <!-- Generated Polymer 3 elements --> <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_MAIN_VIEW_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js" - use_base_dir="false" type="BINDATA" preprocess="true"/> + use_base_dir="false" type="BINDATA"/> <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_APP_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_app.js" - use_base_dir="false" type="BINDATA" preprocess="true"/> + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CARD_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_card.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CARD_MENU_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_card_menu.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_LOCAL_PROFILE_CUSTOMIZATION_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_SHARED_CSS_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js" + use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_SHARED_CSS_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/shared_css.js" + use_base_dir="false" type="BINDATA"/> </includes> <structures> <structure @@ -27,10 +63,40 @@ type="chrome_html" compress="false"/> <structure + name="IDR_PROFILE_PICKER_NAVIGATION_BEHAVIOR_JS" + file="navigation_behavior.js" + type="chrome_html" + compress="false"/> + <structure + name="IDR_PROFILE_PICKER_POLICY_HELPER_JS" + file="policy_helper.js" + type="chrome_html" + compress="false"/> + <structure name="IDR_PROFILE_PICKER_ICONS_JS" file="icons.js" type="chrome_html" compress="false"/> + <structure + name="IDR_SIGNIN_ICONS_JS" + file="../signin_icons.js" + type="chrome_html" + compress="false"/> + <structure + name="IDR_PROFILE_PICKER_LAZY_LOAD_JS" + file="profile_creation_flow/lazy_load.js" + type="chrome_html" + compress="false"/> + <structure + name="IDR_PROFILE_PICKER_ENSURE_LAZY_LOADED_JS" + file="profile_creation_flow/ensure_lazy_loaded.js" + type="chrome_html" + compress="false"/> + <structure + name="IDR_PROFILE_PICKER_MANAGE_PROFILES_BROWSER_PROXY_JS" + file="manage_profiles_browser_proxy.js" + type="chrome_html" + compress="false"/> </structures> </release> </grit> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html new file mode 100644 index 00000000000..7881c9ec265 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html @@ -0,0 +1,54 @@ +<template> + <style> + :host { + --text-font-size: 1.16em; + --scrollbar-width: 4px; + --scrollbar-background: var(--google-grey-refresh-100); + --footer-margin: 40px; + } + + @media (prefers-color-scheme: dark) { + :host { + --scrollbar-background: var(--google-grey-800); + } + } + + html { + font-family: roboto; + } + + h2 { + color: var(--cr-primary-text-color); + font-size: 1.85em; + font-weight: normal; + } + + h3 { + color: var(--cr-secondary-text-color); + font-size: var(--text-font-size); + font-weight: normal; + } + + .profile-card-info { + color: var(--cr-primary-text-color); + font-size: var(--text-font-size); + font-weight: 500; + height: 20px; + overflow: hidden; + padding: 16px; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + width: 130px; + } + + .footer { + bottom: 0; + display: flex; + font-size: var(--text-font-size); + margin-bottom: var(--footer-margin); + position: absolute; + width: 100%; + } + </style> +</template> diff --git a/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js new file mode 100644 index 00000000000..2134465c2da --- /dev/null +++ b/chromium/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js @@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; + +import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +const template = document.createElement('template'); +template.innerHTML = ` +<dom-module id="profile-picker-shared">{__html_template__}</dom-module> +`; +document.body.appendChild(template.content.cloneNode(true)); diff --git a/chromium/chrome/browser/resources/signin/signin_icons.js b/chromium/chrome/browser/resources/signin/signin_icons.js new file mode 100644 index 00000000000..cf0c4bd3e02 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/signin_icons.js @@ -0,0 +1,19 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; + +const element = document.createElement('iron-iconset-svg'); +element.name = 'signin'; +element.innerHTML = ` +<svg> + <defs> + <!-- Copied from iron-icons. --> + <g id="business"> + <path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"> + </path> + </g> + </defs> +</svg>`; +document.head.appendChild(element); diff --git a/chromium/chrome/browser/resources/signin/signin_reauth/BUILD.gn b/chromium/chrome/browser/resources/signin/signin_reauth/BUILD.gn index 5b8112b7bec..46d31bd8117 100644 --- a/chromium/chrome/browser/resources/signin/signin_reauth/BUILD.gn +++ b/chromium/chrome/browser/resources/signin/signin_reauth/BUILD.gn @@ -17,7 +17,6 @@ js_library("signin_reauth_app") { deps = [ ":signin_reauth_browser_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] diff --git a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.html b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.html index f6257f63261..c6e739c64cd 100644 --- a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.html +++ b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.html @@ -13,7 +13,7 @@ } #illustration { - background: url(./images/signin_reauth_illustration.svg); + background-image: url(./images/signin_reauth_illustration.svg); background-size: 100% 100%; height: 100%; position: absolute; @@ -23,7 +23,7 @@ @media (prefers-color-scheme: dark) { #illustration { - background: url(./images/signin_reauth_illustration_dark.svg); + background-image: url(./images/signin_reauth_illustration_dark.svg); } } @@ -61,24 +61,32 @@ padding-inline-start: 16px; } </style> + +<!-- + Use the 'consent-description' attribute to annotate all the UI elements + that are part of the text the user reads before consenting to use passwords + from their account. Similarly, use 'consent-confirmation' on the UI element on + which user clicks to indicate consent. +--> + <div id="illustrationContainer"> <div id="illustration"></div> <img src="[[accountImageSrc_]]"> </div> <div id="contentContainer"> - <h1 id="signinReauthTitle"> + <h1 id="signinReauthTitle" consent-description> $i18n{signinReauthTitle} </h1> <div class="message-container"> - <div>$i18n{signinReauthDesc}</div> + <div consent-description>$i18n{signinReauthDesc}</div> </div> </div> <div class="action-container"> <paper-spinner-lite active hidden$="[[!confirmButtonHidden_]]"> </paper-spinner-lite> <cr-button id="confirmButton" class="action-button" on-click="onConfirm_" - hidden="[[confirmButtonHidden_]]"> - [[confirmButtonLabel_]] + hidden="[[confirmButtonHidden_]]" consent-confirmation> + $i18n{signinReauthConfirmLabel} </cr-button> <cr-button id="cancelButton" on-click="onCancel_" hidden="[[cancelButtonHidden_]]"> diff --git a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.js b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.js index e2c6b4ec6d9..f5f10a601cb 100644 --- a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.js +++ b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_app.js @@ -8,7 +8,7 @@ import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; import './strings.m.js'; import './signin_shared_css.js'; -import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -20,7 +20,7 @@ Polymer({ _template: html`{__html_template__}`, - behaviors: [I18nBehavior, WebUIListenerBehavior], + behaviors: [WebUIListenerBehavior], properties: { /** @private */ @@ -32,9 +32,6 @@ Polymer({ }, /** @private */ - confirmButtonLabel_: String, - - /** @private */ confirmButtonHidden_: {type: Boolean, value: true}, /** @private */ @@ -52,9 +49,14 @@ Polymer({ this.signinReauthBrowserProxy_.initialize(); }, - /** @private */ - onConfirm_() { - this.signinReauthBrowserProxy_.confirm(); + /** + * @param {!Event} e + * @private + */ + onConfirm_(e) { + this.signinReauthBrowserProxy_.confirm( + this.getConsentDescription_(), + this.getConsentConfirmation_(e.composedPath())); }, /** @private */ @@ -70,9 +72,33 @@ Polymer({ onReauthTypeReceived_(requiresReauth) { this.confirmButtonHidden_ = false; this.$.confirmButton.focus(); - this.cancelButtonHidden_ = requiresReauth; - this.confirmButtonLabel_ = requiresReauth ? - this.i18n('signinReauthNextLabel') : - this.i18n('signinReauthConfirmLabel'); + this.cancelButtonHidden_ = false; + }, + + /** @return {!Array<string>} Text of the consent description elements. */ + getConsentDescription_() { + const consentDescription = + Array.from(this.shadowRoot.querySelectorAll('[consent-description]')) + .filter(element => element.clientWidth * element.clientHeight > 0) + .map(element => element.innerHTML.trim()); + assert(consentDescription); + return consentDescription; + }, + + /** + * @param {!Array<!HTMLElement>} path Path of the click event. Must contain + * a consent confirmation element. + * @return {string} The text of the consent confirmation element. + * @private + */ + getConsentConfirmation_(path) { + for (const element of path) { + if (element.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && + element.hasAttribute('consent-confirmation')) { + return element.innerHTML.trim(); + } + } + assertNotReached('No consent confirmation element found.'); + return ''; }, }); diff --git a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_browser_proxy.js b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_browser_proxy.js index d4a040455aa..4dfbe1ae7bc 100644 --- a/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_browser_proxy.js +++ b/chromium/chrome/browser/resources/signin/signin_reauth/signin_reauth_browser_proxy.js @@ -17,8 +17,12 @@ export class SigninReauthBrowserProxy { /** * Called when the user confirms the signin reauth dialog. + * @param {!Array<string>} description Strings that the user was presented + * with in the UI. + * @param {string} confirmation Text of the element that the user + * clicked on. */ - confirm() {} + confirm(description, confirmation) {} /** * Called when the user cancels the signin reauth. @@ -34,8 +38,8 @@ export class SigninReauthBrowserProxyImpl { } /** @override */ - confirm() { - chrome.send('confirm'); + confirm(description, confirmation) { + chrome.send('confirm', [description, confirmation]); } /** @override */ diff --git a/chromium/chrome/browser/resources/signin/signin_vars_css.html b/chromium/chrome/browser/resources/signin/signin_vars_css.html new file mode 100644 index 00000000000..ce0ba217810 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/signin_vars_css.html @@ -0,0 +1,14 @@ +<custom-style> +<style> + html { + --signin-work-badge-background-color: rgb(248, 249, 250); + --signin-work-badge-foreground-color: var(--google-grey-700); + } + @media (prefers-color-scheme: dark) { + html { + --signin-work-badge-background-color: var(--google-grey-700); + --signin-work-badge-foreground-color: white; + } + } +</style> +</custom-style> diff --git a/chromium/chrome/browser/resources/signin/signin_vars_css.js b/chromium/chrome/browser/resources/signin/signin_vars_css.js new file mode 100644 index 00000000000..35fd5175cb6 --- /dev/null +++ b/chromium/chrome/browser/resources/signin/signin_vars_css.js @@ -0,0 +1,10 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; +import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +const $_documentContainer = document.createElement('template'); +$_documentContainer.innerHTML = `{__html_template__}`; +document.head.appendChild($_documentContainer.content); diff --git a/chromium/chrome/browser/resources/sync_file_system_internals/OWNERS b/chromium/chrome/browser/resources/sync_file_system_internals/OWNERS index ae057bc68c3..0d7e100e97d 100644 --- a/chromium/chrome/browser/resources/sync_file_system_internals/OWNERS +++ b/chromium/chrome/browser/resources/sync_file_system_internals/OWNERS @@ -1,10 +1,7 @@ calvinlo@chromium.org kinuko@chromium.org nhiroki@chromium.org -pwnall@chomium.org -tzik@chromium.org - -per-file sync_file_system_internals_resources.*=tzik@chromium.org +pwnall@chromium.org # TEAM: storage-dev@chromium.org # COMPONENT: Blink>Storage>FileSystem diff --git a/chromium/chrome/browser/resources/sync_file_system_internals/dump_database.js b/chromium/chrome/browser/resources/sync_file_system_internals/dump_database.js index eec653ac7c1..40a590bf1ca 100644 --- a/chromium/chrome/browser/resources/sync_file_system_internals/dump_database.js +++ b/chromium/chrome/browser/resources/sync_file_system_internals/dump_database.js @@ -68,7 +68,7 @@ const DumpDatabase = (function() { */ DumpDatabase.onGetDatabaseDump = function(databaseDump) { const placeholder = $('dump-database-placeholder'); - placeholder.innerHTML = ''; + placeholder.innerHTML = trustedTypes.emptyHTML; for (let i = 0; i < databaseDump.length; ++i) { const div = document.createElement('div'); const table = document.createElement('table'); diff --git a/chromium/chrome/browser/resources/sync_file_system_internals/sync_service.js b/chromium/chrome/browser/resources/sync_file_system_internals/sync_service.js index 4213a5e6043..aa3f16b06a3 100644 --- a/chromium/chrome/browser/resources/sync_file_system_internals/sync_service.js +++ b/chromium/chrome/browser/resources/sync_file_system_internals/sync_service.js @@ -55,7 +55,7 @@ const SyncService = (function() { */ function clearLogs() { chrome.send('clearLogs'); - $('log-entries').innerHTML = ''; + $('log-entries').innerHTML = trustedTypes.emptyHTML; } /** diff --git a/chromium/chrome/browser/resources/tab_strip/BUILD.gn b/chromium/chrome/browser/resources/tab_strip/BUILD.gn index 47d3cb8be86..93030f62154 100644 --- a/chromium/chrome/browser/resources/tab_strip/BUILD.gn +++ b/chromium/chrome/browser/resources/tab_strip/BUILD.gn @@ -16,7 +16,6 @@ js_type_check("closure_compile") { ":tab_group", ":tab_list", ":tab_strip_embedder_proxy", - ":tab_strip_options", ":tab_swiper", ":tabs_api_proxy", ] @@ -64,7 +63,6 @@ js_library("tab") { ":alert_indicators", ":custom_element", ":tab_strip_embedder_proxy", - ":tab_strip_options", ":tab_swiper", ":tabs_api_proxy", "//ui/webui/resources/js:icon.m", @@ -90,7 +88,6 @@ js_library("tab_list") { ":tab", ":tab_group", ":tab_strip_embedder_proxy", - ":tab_strip_options", ":tabs_api_proxy", "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:load_time_data.m", @@ -103,9 +100,6 @@ js_library("tab_strip_embedder_proxy") { deps = [ "//ui/webui/resources/js:cr.m" ] } -js_library("tab_strip_options") { -} - js_library("tab_swiper") { } diff --git a/chromium/chrome/browser/resources/tab_strip/drag_manager.js b/chromium/chrome/browser/resources/tab_strip/drag_manager.js index b50733200f8..6c1604e1d69 100644 --- a/chromium/chrome/browser/resources/tab_strip/drag_manager.js +++ b/chromium/chrome/browser/resources/tab_strip/drag_manager.js @@ -9,6 +9,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {isTabElement, TabElement} from './tab.js'; import {isTabGroupElement, TabGroupElement} from './tab_group.js'; +import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; import {TabData, TabNetworkState, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; /** @const {number} */ @@ -100,6 +101,13 @@ class DragSession { /** @const {!TabElement|!TabGroupElement} */ this.element_ = element; + /** + * Flag indicating if during the drag session, the element has at least + * moved once. + * @private {boolean} + */ + this.hasMoved_ = false; + /** @const {number} */ this.srcIndex = srcIndex; @@ -108,6 +116,9 @@ class DragSession { /** @private @const {!TabsApiProxy} */ this.tabsProxy_ = TabsApiProxyImpl.getInstance(); + + /** @private {!TabStripEmbedderProxy} */ + this.tabStripEmbedderProxy_ = TabStripEmbedderProxyImpl.getInstance(); } /** @@ -226,6 +237,7 @@ class DragSession { } this.element_.setDragging(false); + this.element_.setDraggedOut(false); } /** @return {boolean} */ @@ -277,6 +289,14 @@ class DragSession { } this.element_.setDragging(false); + this.element_.setDraggedOut(false); + + if (isTabElement(this.element_) && !this.hasMoved_) { + // If the user was dragging a tab and the tab has not ever been moved, + // show a context menu instead. + this.tabStripEmbedderProxy_.showTabContextMenu( + this.element_.tab.id, event.clientX, event.clientY); + } } /** @@ -295,7 +315,7 @@ class DragSession { /** @param {!DragEvent} event */ start(event) { event.dataTransfer.effectAllowed = 'move'; - const draggedItemRect = this.element_.getBoundingClientRect(); + const draggedItemRect = event.composedPath()[0].getBoundingClientRect(); this.element_.setDragging(true); const dragImage = this.element_.getDragImage(); @@ -311,14 +331,26 @@ class DragSession { verticalOffset = 25; // </if> - const xDiffFromCenter = - event.clientX - draggedItemRect.left - (draggedItemRect.width / 2); - const yDiffFromCenter = event.clientY - draggedItemRect.top - - verticalOffset - (draggedItemRect.height / 2); + const eventXPercentage = + (event.clientX - draggedItemRect.left) / draggedItemRect.width; + const eventYPercentage = + (event.clientY - draggedItemRect.top) / draggedItemRect.height; + + // First, align the top-left corner of the drag image's center element + // to the event's coordinates. + const dragImageCenterRect = + this.element_.getDragImageCenter().getBoundingClientRect(); + let xOffset = (dragImageCenterRect.left - dragImageRect.left) * scaleFactor; + let yOffset = (dragImageCenterRect.top - dragImageRect.top) * scaleFactor; - event.dataTransfer.setDragImage( - dragImage, (dragImageRect.width / 2 + xDiffFromCenter / scaleFactor), - (dragImageRect.height / 2 + yDiffFromCenter / scaleFactor)); + // Then, offset the drag image again by using the event's coordinates + // within the dragged item itself so that the drag image appears positioned + // as closely as its state before dragging. + xOffset += dragImageCenterRect.width * eventXPercentage; + yOffset += dragImageCenterRect.height * eventYPercentage; + yOffset -= verticalOffset; + + event.dataTransfer.setDragImage(dragImage, xOffset, yOffset); if (isTabElement(this.element_)) { event.dataTransfer.setData( @@ -336,7 +368,14 @@ class DragSession { /** @param {!DragEvent} event */ update(event) { + if (event.type === 'dragleave') { + this.element_.setDraggedOut(true); + this.hasMoved_ = true; + return; + } + event.dataTransfer.dropEffect = 'move'; + this.element_.setDraggedOut(false); if (isTabGroupElement(this.element_)) { this.updateForTabGroupElement_(event); } else if (isTabElement(this.element_)) { @@ -365,6 +404,7 @@ class DragSession { dragOverIndex += this.shouldOffsetIndexForGroup_(dragOverTabElement) ? 1 : 0; this.delegate_.placeTabGroupElement(tabGroupElement, dragOverIndex); + this.hasMoved_ = true; return; } @@ -376,6 +416,7 @@ class DragSession { dragOverIndex += this.shouldOffsetIndexForGroup_(dragOverGroupElement) ? 1 : 0; this.delegate_.placeTabGroupElement(tabGroupElement, dragOverIndex); + this.hasMoved_ = true; } } @@ -407,12 +448,14 @@ class DragSession { dragOverTabGroup.isValidDragOverTarget) { this.delegate_.placeTabElement( tabElement, this.dstIndex, false, dragOverTabGroup.dataset.groupId); + this.hasMoved_ = true; return; } if (!dragOverTabGroup && previousGroupId) { this.delegate_.placeTabElement( tabElement, this.dstIndex, false, undefined); + this.hasMoved_ = true; return; } @@ -423,6 +466,7 @@ class DragSession { const dragOverIndex = this.delegate_.getIndexOfTab(dragOverTabElement); this.delegate_.placeTabElement( tabElement, dragOverIndex, tabElement.tab.pinned, previousGroupId); + this.hasMoved_ = true; } } @@ -439,14 +483,18 @@ export class DragManager { this.tabsProxy_ = TabsApiProxyImpl.getInstance(); } - /** @private */ - onDragLeave_() { - if (this.dragSession_ && !this.dragSession_.isDraggingPlaceholder()) { + /** + * @param {!DragEvent} event + * @private + */ + onDragLeave_(event) { + if (this.dragSession_ && this.dragSession_.isDraggingPlaceholder()) { + this.dragSession_.cancel(); + this.dragSession_ = null; return; } - this.dragSession_.cancel(); - this.dragSession_ = null; + this.dragSession_.update(event); } /** @param {!DragEvent} event */ @@ -488,6 +536,9 @@ export class DragManager { /** @param {!DragEvent} event */ onDragEnter_(event) { if (this.dragSession_) { + // TODO(crbug.com/843556): Do not update the drag session on dragenter. + // An incorrect event target on dragenter causes tabs to move around + // erroneously. return; } @@ -512,8 +563,9 @@ export class DragManager { this.delegate_.addEventListener( 'dragend', e => this.onDragEnd_(/** @type {!DragEvent} */ (e))); this.delegate_.addEventListener( - 'dragenter', (e) => this.onDragEnter_(/** @type {!DragEvent} */ (e))); - this.delegate_.addEventListener('dragleave', () => this.onDragLeave_()); + 'dragenter', e => this.onDragEnter_(/** @type {!DragEvent} */ (e))); + this.delegate_.addEventListener( + 'dragleave', e => this.onDragLeave_(/** @type {!DragEvent} */ (e))); this.delegate_.addEventListener( 'dragover', e => this.onDragOver_(/** @type {!DragEvent} */ (e))); this.delegate_.addEventListener( diff --git a/chromium/chrome/browser/resources/tab_strip/tab.html b/chromium/chrome/browser/resources/tab_strip/tab.html index 7bb542efb9b..ad68d93df54 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab.html +++ b/chromium/chrome/browser/resources/tab_strip/tab.html @@ -14,6 +14,10 @@ transform-origin: top right; } + :host([dragged-out_]) { + display: none; + } + #tab { background: var(--tabstrip-tab-background-color); border-radius: var(--tabstrip-tab-border-radius); @@ -291,15 +295,8 @@ :host([dragging_]) #dragImage { /* Enough padding to not crop the box shadow set on #tab below. */ --drag-image-padding: 25px; - align-items: center; - display: flex; height: 100%; - justify-content: center; - padding-block-end: var(--drag-image-padding); - padding-block-start: var(--drag-image-padding); - padding-inline-end: calc( - var(--tabstrip-tab-spacing) + var(--drag-image-padding)); - padding-inline-start: var(--drag-image-padding); + padding: var(--drag-image-padding); position: absolute; top: 100vh; width: 100%; diff --git a/chromium/chrome/browser/resources/tab_strip/tab.js b/chromium/chrome/browser/resources/tab_strip/tab.js index 61da08df076..8305c0ebc90 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab.js +++ b/chromium/chrome/browser/resources/tab_strip/tab.js @@ -12,7 +12,6 @@ import {isRTL} from 'chrome://resources/js/util.m.js'; import {AlertIndicatorsElement} from './alert_indicators.js'; import {CustomElement} from './custom_element.js'; import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; -import {tabStripOptions} from './tab_strip_options.js'; import {TabSwiper} from './tab_swiper.js'; import {CloseTabAction, TabData, TabNetworkState, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; @@ -201,6 +200,13 @@ export class TabElement extends CustomElement { return this.dragImageEl_; } + /** @return {!HTMLElement} */ + getDragImageCenter() { + // dragImageEl_ has padding, so the drag image should be centered relative + // to tabEl_, the element within the padding. + return this.tabEl_; + } + /** * @param {string} imgData */ @@ -218,9 +224,7 @@ export class TabElement extends CustomElement { this.onTabActivating_(tabId); this.tabsApi_.activateTab(tabId); - if (tabStripOptions.autoCloseEnabled) { - this.embedderApi_.closeContainer(); - } + this.embedderApi_.closeContainer(); } /** @@ -229,13 +233,6 @@ export class TabElement extends CustomElement { */ onContextMenu_(event) { event.preventDefault(); - - if (!this.tab_) { - return; - } - - this.embedderApi_.showTabContextMenu( - this.tab_.id, event.clientX, event.clientY); event.stopPropagation(); } @@ -276,6 +273,11 @@ export class TabElement extends CustomElement { this.toggleAttribute('dragging_', isDragging); } + /** @param {boolean} isDraggedOut */ + setDraggedOut(isDraggedOut) { + this.toggleAttribute('dragged-out_', isDraggedOut); + } + /** * @return {!Promise} */ diff --git a/chromium/chrome/browser/resources/tab_strip/tab_group.html b/chromium/chrome/browser/resources/tab_strip/tab_group.html index 77809c82201..fe21e147e96 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_group.html +++ b/chromium/chrome/browser/resources/tab_strip/tab_group.html @@ -9,6 +9,10 @@ display: none; } +:host([dragged-out_]) { + display: none; +} + #tabGroup { border-radius: 8px; box-shadow: 0 0 0 1px rgb(var(--tabstrip-tab-group-color-rgb)); @@ -160,7 +164,7 @@ :host([dragging]) #dragImage { /* Position the actual drag image out of view so it is not visible. */ position: absolute; - top: 100vh; + top: calc(100vh + var(--drag-image-padding)); } </style> diff --git a/chromium/chrome/browser/resources/tab_strip/tab_group.js b/chromium/chrome/browser/resources/tab_strip/tab_group.js index cfd47a53868..c49407b822a 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_group.js +++ b/chromium/chrome/browser/resources/tab_strip/tab_group.js @@ -48,6 +48,13 @@ export class TabGroupElement extends CustomElement { return /** @type {!HTMLElement} */ (this.$('#dragImage')); } + /** @return {!HTMLElement} */ + getDragImageCenter() { + // Since the drag handle is #chip, the drag image should be centered + // relatively to it. + return /** @type {!HTMLElement} */ (this.$('#chip')); + } + /** @private */ onClickChip_() { if (!this.dataset.groupId) { @@ -85,6 +92,11 @@ export class TabGroupElement extends CustomElement { }); } + /** @param {boolean} isDraggedOut */ + setDraggedOut(isDraggedOut) { + this.toggleAttribute('dragged-out_', isDraggedOut); + } + /** * @param {!TabGroupVisualData} visualData */ diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.html b/chromium/chrome/browser/resources/tab_strip/tab_list.html index f6cb511ab76..053e971babd 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_list.html +++ b/chromium/chrome/browser/resources/tab_strip/tab_list.html @@ -126,14 +126,6 @@ opacity: 0.5; width: var(--tabstrip-tab-width); } - - #demoOptions { - bottom: 15px; - display: none; - font-size: 16px; - position: fixed; - right: 15px; - } </style> <div id="tabs"> @@ -144,9 +136,3 @@ id="newTabButton" iron-icon="cr:add"> </cr-icon-button> - -<div id="demoOptions"> - <label> - <input type="checkbox" id="autoCloseCheckbox">Auto-close - </label> -</div> diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.js b/chromium/chrome/browser/resources/tab_strip/tab_list.js index 5ab5de62076..f878e2e00d4 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_list.js +++ b/chromium/chrome/browser/resources/tab_strip/tab_list.js @@ -18,7 +18,6 @@ import {DragManager, DragManagerDelegate} from './drag_manager.js'; import {isTabElement, TabElement} from './tab.js'; import {isTabGroupElement, TabGroupElement} from './tab_group.js'; import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; -import {tabStripOptions} from './tab_strip_options.js'; import {TabData, TabGroupVisualData, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; /** @@ -244,16 +243,6 @@ export class TabListElement extends CustomElement { const dragManager = new DragManager(this); dragManager.startObserving(); - - if (loadTimeData.getBoolean('showDemoOptions')) { - this.$('#demoOptions').style.display = 'block'; - - const autoCloseCheckbox = this.$('#autoCloseCheckbox'); - autoCloseCheckbox.checked = tabStripOptions.autoCloseEnabled; - autoCloseCheckbox.addEventListener('change', () => { - tabStripOptions.autoCloseEnabled = autoCloseCheckbox.checked; - }); - } } /** @@ -369,9 +358,6 @@ export class TabListElement extends CustomElement { 'tab-group-visuals-changed', (groupId, visualData) => this.onTabGroupVisualsChanged_(groupId, visualData)); - this.addWebUIListener_( - 'tab-group-id-replaced', - (oldId, newId) => this.onTabGroupIdReplaced_(oldId, newId)); }); } @@ -601,18 +587,6 @@ export class TabListElement extends CustomElement { } /** - * @param {string} oldId - * @param {string} newId - * @private - */ - onTabGroupIdReplaced_(oldId, newId) { - const tabGroupElement = this.findTabGroupElement_(oldId); - if (tabGroupElement) { - tabGroupElement.dataset.groupId = newId; - } - } - - /** * @param {number} tabId * @param {number} index * @param {string} groupId diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_options.js b/chromium/chrome/browser/resources/tab_strip/tab_strip_options.js deleted file mode 100644 index 47a5cfdf8f5..00000000000 --- a/chromium/chrome/browser/resources/tab_strip/tab_strip_options.js +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * TODO(johntlee): Remove after settling on desired behavior. - * An object of various options to test various behaviors of the Tab Strip. - * @const {!Object<string, boolean>} - */ -export const tabStripOptions = { - autoCloseEnabled: true, -}; diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd index 64fb60b1810..7f8d71a80d5 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd +++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd @@ -56,10 +56,6 @@ file="tab_strip_embedder_proxy.js" type="chrome_html"/> <structure - name="IDR_TAB_STRIP_OPTIONS_JS" - file="tab_strip_options.js" - type="chrome_html"/> - <structure name="IDR_TAB_STRIP_TAB_SWIPER_JS" file="tab_swiper.js" type="chrome_html"/> diff --git a/chromium/chrome/browser/resources/tab_strip/tab_swiper.js b/chromium/chrome/browser/resources/tab_strip/tab_swiper.js index 7a351d47764..3f518081c23 100644 --- a/chromium/chrome/browser/resources/tab_strip/tab_swiper.js +++ b/chromium/chrome/browser/resources/tab_strip/tab_swiper.js @@ -34,7 +34,7 @@ export const SWIPE_FINISH_THRESHOLD_PX = 200; * register the set of pointer events as an intended swipe. * @const {number} */ -const SWIPE_VELOCITY_THRESHOLD = 0.1; +const SWIPE_VELOCITY_THRESHOLD = 0.2; export class TabSwiper { /** @param {!HTMLElement} element */ diff --git a/chromium/chrome/browser/resources/tools/rollup_plugin.js b/chromium/chrome/browser/resources/tools/rollup_plugin.js index c70fe31f001..6cb6b2e0076 100644 --- a/chromium/chrome/browser/resources/tools/rollup_plugin.js +++ b/chromium/chrome/browser/resources/tools/rollup_plugin.js @@ -19,6 +19,7 @@ const nonGeneratedFiles = [ 'certificate_manager_types.js', 'certificate_provisioning_browser_proxy.js', 'certificates_browser_proxy.js', + 'color_utils.js', 'cr.m.js', 'cr_splitter.js', 'plural_string_proxy.js', diff --git a/chromium/chrome/browser/resources/welcome/BUILD.gn b/chromium/chrome/browser/resources/welcome/BUILD.gn index 6ceb9074db8..d67421f24f7 100644 --- a/chromium/chrome/browser/resources/welcome/BUILD.gn +++ b/chromium/chrome/browser/resources/welcome/BUILD.gn @@ -16,10 +16,6 @@ group("closure_compile") { js_type_check("welcome_files") { is_polymer3 = true - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/welcome/", - "js_module_root=./gen/chrome/browser/resources/welcome/", - ] deps = [ ":landing_view", ":signin_view", diff --git a/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn b/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn index c6b73f121ea..722f6a7efce 100644 --- a/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn +++ b/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn @@ -6,10 +6,6 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/welcome/", - "js_module_root=gen/chrome/browser/resources/welcome/", - ] is_polymer3 = true deps = [ ":google_app_proxy", diff --git a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html index c5f78a599b2..8668e4e5d2c 100644 --- a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html +++ b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html @@ -157,8 +157,8 @@ } </style> <div class="apps-ask"> - <div class="chrome-logo" alt=""></div> - <h1 tabindex="-1">$i18n{googleAppsDescription}</h1> + <div class="chrome-logo" aria-hidden="true"></div> + <h1 tabindex="-1">[[subtitle]]</h1> <div id="appChooser"> <div class="slide-in"> <template is="dom-repeat" items="[[appList_]]"> diff --git a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js index c6c6bf36b4a..c6e0fb0251d 100644 --- a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js +++ b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js @@ -14,6 +14,7 @@ import '../shared/step_indicator.js'; import '../strings.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; import {afterNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -70,6 +71,11 @@ Polymer({ notify: true, value: true, }, + + subtitle: { + type: String, + value: loadTimeData.getString('googleAppsDescription'), + }, }, /** @private {GoogleAppProxy} */ diff --git a/chromium/chrome/browser/resources/welcome/navigation_behavior.js b/chromium/chrome/browser/resources/welcome/navigation_behavior.js index 72b12866871..ea18febd078 100644 --- a/chromium/chrome/browser/resources/welcome/navigation_behavior.js +++ b/chromium/chrome/browser/resources/welcome/navigation_behavior.js @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '../strings.m.js'; + import {assert} from 'chrome://resources/js/assert.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {afterNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** @@ -79,10 +82,8 @@ function notifyObservers() { // If currentRouteElement is not null, it means there was a new route. if (currentRouteElement) { - (/** @type {{onRouteEnter: Function}} */ (currentRouteElement)) - .onRouteEnter(); - (/** @type {{updateFocusForA11y: Function}} */ (currentRouteElement)) - .updateFocusForA11y(); + (/** @type {{notifyRouteEnter: Function}} */ (currentRouteElement)) + .notifyRouteEnter(); } } @@ -137,6 +138,9 @@ export function navigateTo(route, step) { * @polymerBehavior */ export const NavigationBehavior = { + /** @type {string} */ + subtitle: '', + /** @override */ attached() { assert(!routeObservers.has(this)); @@ -154,11 +158,20 @@ export const NavigationBehavior = { // means that element is for the current route. if (this.id === `step-${step}`) { currentRouteElement = this; - this.onRouteEnter(); - this.updateFocusForA11y(); + this.notifyRouteEnter(); } }, + /** + * Notifies elements that route was entered and updates the state of the + * app based on the new route. + */ + notifyRouteEnter() { + this.onRouteEnter(); + this.updateFocusForA11y(); + this.updateTitle(); + }, + /** Called to update focus when progressing through the modules. */ updateFocusForA11y() { const header = this.$$('h1'); @@ -167,6 +180,14 @@ export const NavigationBehavior = { } }, + updateTitle() { + let title = loadTimeData.getString('headerText'); + if (this.subtitle) { + title += ' - ' + this.subtitle; + } + document.title = title; + }, + /** @override */ detached() { assert(routeObservers.delete(this)); diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn b/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn index 310c3d62908..ca4e0c5d6d7 100644 --- a/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn +++ b/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn @@ -6,10 +6,6 @@ import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/welcome/", - "js_module_root=gen/chrome/browser/resources/welcome/", - ] deps = [ ":ntp_background_metrics_proxy", ":ntp_background_proxy", diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html index f5b6ac423ee..a0ae6dc77e9 100644 --- a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html +++ b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html @@ -158,8 +158,8 @@ </div> <div class="content"> - <div class="ntp-background-logo"></div> - <h1 tabindex="-1">$i18n{ntpBackgroundDescription}</h1> + <div class="ntp-background-logo" aria-hidden="true"></div> + <h1 tabindex="-1">[[subtitle]]</h1> <div class="ntp-backgrounds-grid slide-in"> <template is="dom-repeat" items="[[backgrounds_]]"> diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js index 240b849610e..636aa80d025 100644 --- a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js +++ b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js @@ -13,6 +13,7 @@ import '../shared/step_indicator.js'; import '../strings.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -44,6 +45,11 @@ Polymer({ observer: 'onSelectedBackgroundChange_', type: Object, }, + + subtitle: { + type: String, + value: loadTimeData.getString('ntpBackgroundDescription'), + }, }, /** @private {?Array<!NtpBackgroundData>} */ diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn b/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn index eacb2b02225..93154344433 100644 --- a/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn +++ b/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn @@ -7,10 +7,6 @@ import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/welcome/", - "js_module_root=gen/chrome/browser/resources/welcome/", - ] deps = [ ":nux_set_as_default" ] } diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html index c7f2b065ef4..e89568ae8a4 100644 --- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html +++ b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html @@ -65,8 +65,8 @@ </if> </style> <div class="container"> - <div class="logo"></div> - <h1 tabindex="-1">$i18n{setDefaultHeader}</h1> + <div class="logo" aria-hidden="true"></div> + <h1 tabindex="-1">[[subtitle]]</h1> <h2>$i18n{setDefaultSubHeader}</h2> <div class="illustration slide-in" aria-hidden="true"></div> <div class="button-bar"> diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js index 9612319a626..89c6cc7ac7c 100644 --- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js +++ b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js @@ -41,6 +41,11 @@ Polymer({ value: loadTimeData.getBoolean('is_win10'), }, // </if> + + subtitle: { + type: String, + value: loadTimeData.getString('setDefaultHeader'), + }, }, /** @private {NuxSetAsDefaultProxy} */ diff --git a/chromium/chrome/browser/resources/welcome/shared/BUILD.gn b/chromium/chrome/browser/resources/welcome/shared/BUILD.gn index 4c9544a4dd7..43d7de3c881 100644 --- a/chromium/chrome/browser/resources/welcome/shared/BUILD.gn +++ b/chromium/chrome/browser/resources/welcome/shared/BUILD.gn @@ -7,10 +7,6 @@ import("//tools/polymer/html_to_js.gni") js_type_check("closure_compile") { is_polymer3 = true - closure_flags = default_closure_args + [ - "js_module_root=../../chrome/browser/resources/welcome/", - "js_module_root=gen/chrome/browser/resources/welcome/", - ] deps = [ ":bookmark_proxy", ":module_metrics_proxy", diff --git a/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html index 403ee035ba4..772ebce3148 100644 --- a/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html +++ b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html @@ -14,8 +14,7 @@ --navi-shape-red-color: rgb(233, 66, 53); /* #E94235 */ --navi-shape-yellow-dots-color: rgb(253, 214, 99); /* #FDD663 */ --navi-shape-yellow-semicircle-color: rgb(250, 207, 76); /* #FACF4C */ - --navi-step-indicator-active-color: - rgba(var(--google-blue-600-rgb), .5); + --navi-step-indicator-active-color: var(--google-blue-600); --navi-step-indicator-color: var(--google-grey-200); --navi-wallpaper-text-color: var(--google-grey-refresh-700); } |